summaryrefslogtreecommitdiffhomepage
path: root/dev
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-09-02 10:05:46 +0200
committerAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-09-02 10:05:46 +0200
commit0df4a5dd7b0d7e7edaf4df83797849d9e545b659 (patch)
treeceab7f5a1b7579ab7aa7af91ae6c47ace17dac74 /dev
parent2ad1ffce7a2d51feb1486efdc34b65bb31c919d3 (diff)
[ META ] Format source files.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'dev')
-rw-r--r--dev/crtdll/__ndk_defines.hxx9
-rw-r--r--dev/ndkdll/Asm/CPU/32x0.hxx6
-rw-r--r--dev/ndkdll/Asm/CPU/64x0.hxx49
-rw-r--r--dev/ndkdll/Asm/CPU/amd64.hxx27
-rw-r--r--dev/ndkdll/Asm/CPU/arm64.hxx12
-rw-r--r--dev/ndkdll/Defines.hxx10
-rw-r--r--dev/ndkdll/Macros.hxx10
-rw-r--r--dev/ndkdll/NFC/AE.hxx8
-rw-r--r--dev/ndkdll/NFC/ErrorID.hxx14
-rw-r--r--dev/ndkdll/NFC/PEF.hxx14
-rw-r--r--dev/ndkdll/NFC/Ref.hxx10
-rw-r--r--dev/ndkdll/Sources/Assembler32x0.cxx11
-rw-r--r--dev/ndkdll/Sources/Assembler64x0.cxx1764
-rw-r--r--dev/ndkdll/Sources/AssemblerPower.cxx8
-rw-r--r--dev/ndkdll/Sources/CCompiler64x0.cxx36
-rw-r--r--dev/ndkdll/Sources/CCompilerPower64.cxx32
-rw-r--r--dev/ndkdll/Sources/Linker.cxx19
-rw-r--r--dev/ndkdll/Sources/String.cxx411
18 files changed, 1334 insertions, 1116 deletions
diff --git a/dev/crtdll/__ndk_defines.hxx b/dev/crtdll/__ndk_defines.hxx
index 4af1fba..e899ef2 100644
--- a/dev/crtdll/__ndk_defines.hxx
+++ b/dev/crtdll/__ndk_defines.hxx
@@ -30,9 +30,9 @@ typedef char* caddr_t;
#ifdef __GNUC__
#include <CRT/__ndk_alloca.hxx>
#define __ndk_alloca(sz) __ndk_alloca_gcc(sz)
-#define __packed__ __attribute__((packed))
+#define __packed__ __attribute__((packed))
#elif defined(__NDK__)
-#define __packed__ __ndk_packed__
+#define __packed__ __ndk_packed__
#define __alloca(sz) __ndk_alloca(sz)
#endif
@@ -43,10 +43,9 @@ typedef char* caddr_t;
extern "C" \
{
-
#define __fini_decl() \
- }; \
-
+ } \
+ ;
#else
#define __init_decl()
diff --git a/dev/ndkdll/Asm/CPU/32x0.hxx b/dev/ndkdll/Asm/CPU/32x0.hxx
index aab07e5..4b1387e 100644
--- a/dev/ndkdll/Asm/CPU/32x0.hxx
+++ b/dev/ndkdll/Asm/CPU/32x0.hxx
@@ -43,15 +43,15 @@ struct CpuCode32x0
inline std::vector<CpuCode32x0> kOpcodes32x0 = {
kAsmOpcodeDecl("nop", 0b0100011, 0b000, kAsmNoArgs) // nothing to do. (1C)
kAsmOpcodeDecl("jmp", 0b1110011, 0b001, kAsmJump) // jump to branch (2C)
- kAsmOpcodeDecl("mov", 0b0100011, 0b101, kAsmImmediate) // move registers (3C)
+ kAsmOpcodeDecl("mov", 0b0100011, 0b101, kAsmImmediate) // move registers (3C)
kAsmOpcodeDecl("psh", 0b0111011, 0b000, kAsmImmediate) // push to sp (2C)
kAsmOpcodeDecl("pop", 0b0111011, 0b001, kAsmImmediate) // pop from sp. (1C)
kAsmOpcodeDecl("lea", 0b0111011, 0b010,
kAsmImmediate) // setup stack and call, store address to CR (1C).
kAsmOpcodeDecl("ret", 0b0111011, 0b110,
kAsmImmediate) // return from procedure (2C).
- kAsmOpcodeDecl("uc", 0b0111111, 0b000, kAsmSyscall) // user call (1C)
- kAsmOpcodeDecl("kc", 0b0111111, 0b001, kAsmSyscall) // kernel call (1C)
+ kAsmOpcodeDecl("uc", 0b0111111, 0b000, kAsmSyscall) // user call (1C)
+ kAsmOpcodeDecl("kc", 0b0111111, 0b001, kAsmSyscall) // kernel call (1C)
kAsmOpcodeDecl("int", 0b0111111, 0b010, kAsmSyscall) // raise interrupt (1C)
};
diff --git a/dev/ndkdll/Asm/CPU/64x0.hxx b/dev/ndkdll/Asm/CPU/64x0.hxx
index 52ca278..6cbed92 100644
--- a/dev/ndkdll/Asm/CPU/64x0.hxx
+++ b/dev/ndkdll/Asm/CPU/64x0.hxx
@@ -36,31 +36,30 @@ struct CpuOpcode64x0
};
inline std::vector<CpuOpcode64x0> kOpcodes64x0 = {
- kAsmOpcodeDecl("nop", 0b0000000, 0b0000000, kAsmNoArgs) // no-operation.
- kAsmOpcodeDecl("np", 0b0000000, 0b0000000, kAsmNoArgs) // no-operation.
- kAsmOpcodeDecl("jlr", 0b1110011, 0b0000111,
- kAsmJump) // jump to linked return register
- kAsmOpcodeDecl("jrl", 0b1110011, 0b0001111,
- kAsmJump) // jump from return register.
- kAsmOpcodeDecl("mv", 0b0100011, 0b101, kAsmRegToReg)
- kAsmOpcodeDecl("bg", 0b1100111, 0b111, kAsmRegToReg)
- kAsmOpcodeDecl("bl", 0b1100111, 0b011, kAsmRegToReg)
- kAsmOpcodeDecl("beq", 0b1100111, 0b000, kAsmRegToReg)
- kAsmOpcodeDecl("bne", 0b1100111, 0b001, kAsmRegToReg)
- kAsmOpcodeDecl("bge", 0b1100111, 0b101, kAsmRegToReg)
- kAsmOpcodeDecl("ble", 0b1100111, 0b100, kAsmRegToReg)
- kAsmOpcodeDecl("stw", 0b0001111, 0b100, kAsmImmediate)
- kAsmOpcodeDecl("ldw", 0b0001111, 0b100, kAsmImmediate)
- kAsmOpcodeDecl("lda", 0b0001111, 0b101, kAsmImmediate)
- kAsmOpcodeDecl("sta", 0b0001111, 0b001, kAsmImmediate)
- // add/sub without carry flag
- kAsmOpcodeDecl("add", 0b0101011, 0b100, kAsmImmediate)
- kAsmOpcodeDecl("sub", 0b0101011, 0b101, kAsmImmediate)
- // add/sub with carry flag
- kAsmOpcodeDecl("addc", 0b0101011, 0b110, kAsmImmediate)
- kAsmOpcodeDecl("subc", 0b0101011, 0b111, kAsmImmediate)
- kAsmOpcodeDecl("sc", 0b1110011, 0b00, kAsmSyscall)
-};
+ kAsmOpcodeDecl("nop", 0b0000000, 0b0000000, kAsmNoArgs) // no-operation.
+ kAsmOpcodeDecl("np", 0b0000000, 0b0000000, kAsmNoArgs) // no-operation.
+ kAsmOpcodeDecl("jlr", 0b1110011, 0b0000111,
+ kAsmJump) // jump to linked return register
+ kAsmOpcodeDecl("jrl", 0b1110011, 0b0001111,
+ kAsmJump) // jump from return register.
+ kAsmOpcodeDecl("mv", 0b0100011, 0b101, kAsmRegToReg)
+ kAsmOpcodeDecl("bg", 0b1100111, 0b111, kAsmRegToReg)
+ kAsmOpcodeDecl("bl", 0b1100111, 0b011, kAsmRegToReg)
+ kAsmOpcodeDecl("beq", 0b1100111, 0b000, kAsmRegToReg)
+ kAsmOpcodeDecl("bne", 0b1100111, 0b001, kAsmRegToReg)
+ kAsmOpcodeDecl("bge", 0b1100111, 0b101, kAsmRegToReg)
+ kAsmOpcodeDecl("ble", 0b1100111, 0b100, kAsmRegToReg)
+ kAsmOpcodeDecl("stw", 0b0001111, 0b100, kAsmImmediate)
+ kAsmOpcodeDecl("ldw", 0b0001111, 0b100, kAsmImmediate)
+ kAsmOpcodeDecl("lda", 0b0001111, 0b101, kAsmImmediate)
+ kAsmOpcodeDecl("sta", 0b0001111, 0b001, kAsmImmediate)
+ // add/sub without carry flag
+ kAsmOpcodeDecl("add", 0b0101011, 0b100, kAsmImmediate)
+ kAsmOpcodeDecl("sub", 0b0101011, 0b101, kAsmImmediate)
+ // add/sub with carry flag
+ kAsmOpcodeDecl("addc", 0b0101011, 0b110, kAsmImmediate)
+ kAsmOpcodeDecl("subc", 0b0101011, 0b111, kAsmImmediate)
+ kAsmOpcodeDecl("sc", 0b1110011, 0b00, kAsmSyscall)};
// \brief 64x0 register prefix
// example: r32, r0
diff --git a/dev/ndkdll/Asm/CPU/amd64.hxx b/dev/ndkdll/Asm/CPU/amd64.hxx
index 4067ec7..a272724 100644
--- a/dev/ndkdll/Asm/CPU/amd64.hxx
+++ b/dev/ndkdll/Asm/CPU/amd64.hxx
@@ -39,19 +39,18 @@ struct CpuOpcodeAMD64
inline std::vector<CpuOpcodeAMD64> kOpcodesAMD64 = {
kAsmOpcodeDecl("int", 0xCD)
- kAsmOpcodeDecl("into", 0xCE)
- kAsmOpcodeDecl("intd", 0xF1)
- kAsmOpcodeDecl("int3", 0xC3)
- kAsmOpcodeDecl("iret", 0xCF)
- kAsmOpcodeDecl("retf", 0xCB)
- kAsmOpcodeDecl("retn", 0xC3)
- kAsmOpcodeDecl("ret", 0xC3)
- kAsmOpcodeDecl("sti", 0xfb)
- kAsmOpcodeDecl("cli", 0xfa)
- kAsmOpcodeDecl("hlt", 0xf4)
- kAsmOpcodeDecl("nop", 0x90)
- kAsmOpcodeDecl("mov", 0x48)
- kAsmOpcodeDecl("call", 0xFF)
-};
+ kAsmOpcodeDecl("into", 0xCE)
+ kAsmOpcodeDecl("intd", 0xF1)
+ kAsmOpcodeDecl("int3", 0xC3)
+ kAsmOpcodeDecl("iret", 0xCF)
+ kAsmOpcodeDecl("retf", 0xCB)
+ kAsmOpcodeDecl("retn", 0xC3)
+ kAsmOpcodeDecl("ret", 0xC3)
+ kAsmOpcodeDecl("sti", 0xfb)
+ kAsmOpcodeDecl("cli", 0xfa)
+ kAsmOpcodeDecl("hlt", 0xf4)
+ kAsmOpcodeDecl("nop", 0x90)
+ kAsmOpcodeDecl("mov", 0x48)
+ kAsmOpcodeDecl("call", 0xFF)};
#define kAsmRegisterLimit 15
diff --git a/dev/ndkdll/Asm/CPU/arm64.hxx b/dev/ndkdll/Asm/CPU/arm64.hxx
index 85e2f75..c75735c 100644
--- a/dev/ndkdll/Asm/CPU/arm64.hxx
+++ b/dev/ndkdll/Asm/CPU/arm64.hxx
@@ -16,11 +16,11 @@ struct CpuOpcodeArm64;
/// @brief ARM64 opcode header.
struct CpuOpcodeArm64 final
{
- uint8_t fOpcode; // opcode
- uint8_t fRegisterLeft; // left register index
- uint8_t fRegisterRight; // right register index
- bool fRegisterLeftHooked;
- bool fRegisterRightHooked;
+ uint8_t fOpcode; // opcode
+ uint8_t fRegisterLeft; // left register index
+ uint8_t fRegisterRight; // right register index
+ bool fRegisterLeftHooked;
+ bool fRegisterRightHooked;
uint32_t fImmediateValue; // immediate 32-bit value
- bool fImmediateValueHooked;
+ bool fImmediateValueHooked;
};
diff --git a/dev/ndkdll/Defines.hxx b/dev/ndkdll/Defines.hxx
index 092a30f..0b7c559 100644
--- a/dev/ndkdll/Defines.hxx
+++ b/dev/ndkdll/Defines.hxx
@@ -61,19 +61,19 @@
#define rt_copy_memory(dst, src, len) memcpy(dst, src, len)
#endif
-#define NDK_COPY_DELETE(KLASS) \
+#define NDK_COPY_DELETE(KLASS) \
KLASS& operator=(const KLASS&) = delete; \
KLASS(const KLASS&) = delete;
-#define NDK_COPY_DEFAULT(KLASS) \
+#define NDK_COPY_DEFAULT(KLASS) \
KLASS& operator=(const KLASS&) = default; \
KLASS(const KLASS&) = default;
-#define NDK_MOVE_DELETE(KLASS) \
+#define NDK_MOVE_DELETE(KLASS) \
KLASS& operator=(KLASS&&) = delete; \
KLASS(KLASS&&) = delete;
-#define NDK_MOVE_DEFAULT(KLASS) \
+#define NDK_MOVE_DEFAULT(KLASS) \
KLASS& operator=(KLASS&&) = default; \
KLASS(KLASS&&) = default;
@@ -140,6 +140,6 @@ typedef char char_type;
#define NDK_MODULE(name) extern "C" int name(int argc, char** argv)
-#pragma scalar_storage_order big-endian
+#pragma scalar_storage_order big - endian
#endif /* ifndef __NDK_DEFINES_HPP__ */
diff --git a/dev/ndkdll/Macros.hxx b/dev/ndkdll/Macros.hxx
index c4666e2..96530ed 100644
--- a/dev/ndkdll/Macros.hxx
+++ b/dev/ndkdll/Macros.hxx
@@ -9,25 +9,25 @@
#ifndef _MACROS_HXX_
#define _MACROS_HXX_
-#define NDK_COPY_DELETE(KLASS) \
+#define NDK_COPY_DELETE(KLASS) \
KLASS& operator=(const KLASS&) = delete; \
KLASS(const KLASS&) = delete;
-#define NDK_COPY_DEFAULT(KLASS) \
+#define NDK_COPY_DEFAULT(KLASS) \
KLASS& operator=(const KLASS&) = default; \
KLASS(const KLASS&) = default;
-#define NDK_MOVE_DELETE(KLASS) \
+#define NDK_MOVE_DELETE(KLASS) \
KLASS& operator=(KLASS&&) = delete; \
KLASS(KLASS&&) = delete;
-#define NDK_MOVE_DEFAULT(KLASS) \
+#define NDK_MOVE_DEFAULT(KLASS) \
KLASS& operator=(KLASS&&) = default; \
KLASS(KLASS&&) = default;
/// @note xxxx is the error placeholder, in hexadecimal.
#define NDK_ERROR_PREFIX_CXX "CXXxxxx"
-#define NDK_ERROR_PREFIX_CL "CLxxxx"
+#define NDK_ERROR_PREFIX_CL "CLxxxx"
#define NDK_ERROR_PREFIX_ASM "ASMxxxx"
#endif /* ifndef _MACROS_HXX_ */
diff --git a/dev/ndkdll/NFC/AE.hxx b/dev/ndkdll/NFC/AE.hxx
index 544f199..c26d3b3 100644
--- a/dev/ndkdll/NFC/AE.hxx
+++ b/dev/ndkdll/NFC/AE.hxx
@@ -71,8 +71,8 @@ inline std::ofstream& operator<<(std::ofstream& fp, NDK::AEHeader& container)
return fp;
}
-inline std::ofstream& operator<<(std::ofstream& fp,
- NDK::AERecordHeader& container)
+inline std::ofstream& operator<<(std::ofstream& fp,
+ NDK::AERecordHeader& container)
{
fp.write((char*)&container, sizeof(NDK::AERecordHeader));
@@ -85,8 +85,8 @@ inline std::ifstream& operator>>(std::ifstream& fp, NDK::AEHeader& container)
return fp;
}
-inline std::ifstream& operator>>(std::ifstream& fp,
- NDK::AERecordHeader& container)
+inline std::ifstream& operator>>(std::ifstream& fp,
+ NDK::AERecordHeader& container)
{
fp.read((char*)&container, sizeof(NDK::AERecordHeader));
return fp;
diff --git a/dev/ndkdll/NFC/ErrorID.hxx b/dev/ndkdll/NFC/ErrorID.hxx
index c3d5729..3816bca 100644
--- a/dev/ndkdll/NFC/ErrorID.hxx
+++ b/dev/ndkdll/NFC/ErrorID.hxx
@@ -12,11 +12,11 @@
#include <ndkdll/Defines.hxx>
#include <ndkdll/NFC/ErrorOr.hxx>
-#define NDK_EXEC_ERROR -30
+#define NDK_EXEC_ERROR -30
#define NDK_FILE_NOT_FOUND -31
-#define NDK_DIR_NOT_FOUND -32
-#define NDK_FILE_EXISTS -33
-#define NDK_TOO_LONG -34
-#define NDK_INVALID_DATA -35
-#define NDK_UNIMPLEMENTED -36
-#define NDK_FAT_ERROR -37
+#define NDK_DIR_NOT_FOUND -32
+#define NDK_FILE_EXISTS -33
+#define NDK_TOO_LONG -34
+#define NDK_INVALID_DATA -35
+#define NDK_UNIMPLEMENTED -36
+#define NDK_FAT_ERROR -37
diff --git a/dev/ndkdll/NFC/PEF.hxx b/dev/ndkdll/NFC/PEF.hxx
index bbcd5a3..07ff121 100644
--- a/dev/ndkdll/NFC/PEF.hxx
+++ b/dev/ndkdll/NFC/PEF.hxx
@@ -34,7 +34,7 @@ namespace NDK
{
enum
{
- kPefArchStart = 99,
+ kPefArchStart = 99,
kPefArchIntel86S = 100,
kPefArchAMD64,
kPefArchRISCV,
@@ -106,29 +106,29 @@ namespace NDK
};
} // namespace NDK
-inline std::ofstream& operator<<(std::ofstream& fp,
+inline std::ofstream& operator<<(std::ofstream& fp,
NDK::PEFContainer& container)
{
fp.write((char*)&container, sizeof(NDK::PEFContainer));
return fp;
}
-inline std::ofstream& operator<<(std::ofstream& fp,
+inline std::ofstream& operator<<(std::ofstream& fp,
NDK::PEFCommandHeader& container)
{
fp.write((char*)&container, sizeof(NDK::PEFCommandHeader));
return fp;
}
-inline std::ifstream& operator>>(std::ifstream& fp,
- NDK::PEFContainer& container)
+inline std::ifstream& operator>>(std::ifstream& fp,
+ NDK::PEFContainer& container)
{
fp.read((char*)&container, sizeof(NDK::PEFContainer));
return fp;
}
-inline std::ifstream& operator>>(std::ifstream& fp,
- NDK::PEFCommandHeader& container)
+inline std::ifstream& operator>>(std::ifstream& fp,
+ NDK::PEFCommandHeader& container)
{
fp.read((char*)&container, sizeof(NDK::PEFCommandHeader));
return fp;
diff --git a/dev/ndkdll/NFC/Ref.hxx b/dev/ndkdll/NFC/Ref.hxx
index 6f82694..0ffcecc 100644
--- a/dev/ndkdll/NFC/Ref.hxx
+++ b/dev/ndkdll/NFC/Ref.hxx
@@ -22,10 +22,10 @@ namespace NDK
~Ref()
{
- if (m_Strong)
- {
- (*m_Class).~T();
- }
+ if (m_Strong)
+ {
+ (*m_Class).~T();
+ }
}
public:
@@ -75,7 +75,7 @@ namespace NDK
class NonNullRef final
{
public:
- explicit NonNullRef() = delete;
+ explicit NonNullRef() = delete;
explicit NonNullRef(T* ref)
: m_Ref(ref, true)
diff --git a/dev/ndkdll/Sources/Assembler32x0.cxx b/dev/ndkdll/Sources/Assembler32x0.cxx
index 7a056bc..f5d6ddd 100644
--- a/dev/ndkdll/Sources/Assembler32x0.cxx
+++ b/dev/ndkdll/Sources/Assembler32x0.cxx
@@ -35,9 +35,9 @@
/////////////////////
-#define kBlank "\e[0;30m"
-#define kRed "\e[0;31m"
-#define kWhite "\e[0;97m"
+#define kBlank "\e[0;30m"
+#define kRed "\e[0;31m"
+#define kWhite "\e[0;97m"
#define kYellow "\e[0;33m"
#define kStdOut (std::cout << kWhite)
@@ -49,4 +49,7 @@
/////////////////////////////////////////////////////////////////////////////////////////
-NDK_MODULE(ZKAAssemblerMain32000) { return 0; }
+NDK_MODULE(ZKAAssemblerMain32000)
+{
+ return 0;
+}
diff --git a/dev/ndkdll/Sources/Assembler64x0.cxx b/dev/ndkdll/Sources/Assembler64x0.cxx
index a22dae9..ce4bd15 100644
--- a/dev/ndkdll/Sources/Assembler64x0.cxx
+++ b/dev/ndkdll/Sources/Assembler64x0.cxx
@@ -36,25 +36,25 @@
/////////////////////
-#define kBlank "\e[0;30m"
-#define kRed "\e[0;31m"
-#define kWhite "\e[0;97m"
+#define kBlank "\e[0;30m"
+#define kRed "\e[0;31m"
+#define kWhite "\e[0;97m"
#define kYellow "\e[0;33m"
#define kStdOut (std::cout << kWhite)
#define kStdErr (std::cout << kRed)
-static char kOutputArch = NDK::kPefArch64000;
+static char kOutputArch = NDK::kPefArch64000;
static Boolean kOutputAsBinary = false;
-static UInt32 kErrorLimit = 10;
+static UInt32 kErrorLimit = 10;
static UInt32 kAcceptableErrors = 0;
constexpr auto c64x0IPAlignment = 0x4U;
static std::size_t kCounter = 1UL;
-static std::uintptr_t kOrigin = kPefBaseOrigin;
+static std::uintptr_t kOrigin = kPefBaseOrigin;
static std::vector<std::pair<std::string, std::uintptr_t>> kOriginLabel;
static bool kVerbose = false;
@@ -62,42 +62,49 @@ static bool kVerbose = false;
static std::vector<e64k_num_t> kBytes;
static NDK::AERecordHeader kCurrentRecord{
- .fName = "", .fKind = NDK::kPefCode, .fSize = 0, .fOffset = 0};
+ .fName = "", .fKind = NDK::kPefCode, .fSize = 0, .fOffset = 0};
static std::vector<NDK::AERecordHeader> kRecords;
-static std::vector<std::string> kUndefinedSymbols;
+static std::vector<std::string> kUndefinedSymbols;
static const std::string kUndefinedSymbol = ":UndefinedSymbol:";
-static const std::string kRelocSymbol = ":RuntimeSymbol:";
+static const std::string kRelocSymbol = ":RuntimeSymbol:";
// \brief forward decl.
-static bool asm_read_attributes(std::string &line);
+static bool asm_read_attributes(std::string& line);
-namespace detail {
-void print_error_asm(std::string reason, std::string file) noexcept {
- if (reason[0] == '\n') reason.erase(0, 1);
+namespace detail
+{
+ void print_error_asm(std::string reason, std::string file) noexcept
+ {
+ if (reason[0] == '\n')
+ reason.erase(0, 1);
- kStdErr << kRed << "[ ndk ] " << kWhite
- << ((file == "ndk") ? "internal error "
- : ("in file, " + file))
- << kBlank << std::endl;
- kStdErr << kRed << "[ ndk ] " << kWhite << reason << kBlank << std::endl;
+ kStdErr << kRed << "[ ndk ] " << kWhite
+ << ((file == "ndk") ? "internal error "
+ : ("in file, " + file))
+ << kBlank << std::endl;
+ kStdErr << kRed << "[ ndk ] " << kWhite << reason << kBlank << std::endl;
- if (kAcceptableErrors > kErrorLimit) std::exit(3);
+ if (kAcceptableErrors > kErrorLimit)
+ std::exit(3);
- ++kAcceptableErrors;
-}
+ ++kAcceptableErrors;
+ }
-void print_warning_asm(std::string reason, std::string file) noexcept {
- if (reason[0] == '\n') reason.erase(0, 1);
+ void print_warning_asm(std::string reason, std::string file) noexcept
+ {
+ if (reason[0] == '\n')
+ reason.erase(0, 1);
- if (!file.empty()) {
- kStdOut << kYellow << "[ file ] " << kWhite << file << kBlank << std::endl;
- }
+ if (!file.empty())
+ {
+ kStdOut << kYellow << "[ file ] " << kWhite << file << kBlank << std::endl;
+ }
- kStdOut << kYellow << "[ 64asm ] " << kWhite << reason << kBlank << std::endl;
-}
-} // namespace detail
+ kStdOut << kYellow << "[ 64asm ] " << kWhite << reason << kBlank << std::endl;
+ }
+} // namespace detail
/////////////////////////////////////////////////////////////////////////////////////////
@@ -105,192 +112,225 @@ void print_warning_asm(std::string reason, std::string file) noexcept {
/////////////////////////////////////////////////////////////////////////////////////////
-NDK_MODULE(ZKAAssemblerMain64000) {
- for (size_t i = 1; i < argc; ++i) {
- if (argv[i][0] == '/') {
- if (strcmp(argv[i], "/version") == 0 || strcmp(argv[i], "/v") == 0) {
- kStdOut << "64asm: 64x0 Assembler.\n64asm: v1.10\n64asm: Copyright (c) "
- "ZKA Technologies.\n";
- return 0;
- } else if (strcmp(argv[i], "/h") == 0) {
- kStdOut << "64asm: 64x0 Assembler.\n64asm: Copyright (c) 2024 Mahrouss "
- "Logic.\n";
- kStdOut << "/version: Print program version.\n";
- kStdOut << "/verbose: Print verbose output.\n";
- kStdOut << "/binary: Output as flat binary.\n";
- kStdOut << "/64xxx: Compile for a subset of the X64000.\n";
-
- return 0;
- } else if (strcmp(argv[i], "/binary") == 0) {
- kOutputAsBinary = true;
- continue;
- } else if (strcmp(argv[i], "/verbose") == 0) {
- kVerbose = true;
- continue;
- }
-
- kStdOut << "64asm: ignore " << argv[i] << "\n";
- continue;
- }
-
- if (!std::filesystem::exists(argv[i])) {
- kStdOut << "64asm: can't open: " << argv[i] << std::endl;
- goto asm_fail_exit;
- }
-
- std::string object_output(argv[i]);
-
- for (auto &ext : kAsmFileExts) {
- if (object_output.find(ext) != std::string::npos) {
- object_output.erase(object_output.find(ext), std::strlen(ext));
- }
- }
-
- object_output += kOutputAsBinary ? kBinaryFileExt : kObjectFileExt;
-
- std::ifstream file_ptr(argv[i]);
- std::ofstream file_ptr_out(object_output, std::ofstream::binary);
-
- if (file_ptr_out.bad()) {
- if (kVerbose) {
- kStdOut << "64asm: error: " << strerror(errno) << "\n";
- }
- }
-
- std::string line;
-
- NDK::AEHeader hdr{0};
-
- memset(hdr.fPad, kAEInvalidOpcode, kAEPad);
+NDK_MODULE(ZKAAssemblerMain64000)
+{
+ for (size_t i = 1; i < argc; ++i)
+ {
+ if (argv[i][0] == '/')
+ {
+ if (strcmp(argv[i], "/version") == 0 || strcmp(argv[i], "/v") == 0)
+ {
+ kStdOut << "64asm: 64x0 Assembler.\n64asm: v1.10\n64asm: Copyright (c) "
+ "ZKA Technologies.\n";
+ return 0;
+ }
+ else if (strcmp(argv[i], "/h") == 0)
+ {
+ kStdOut << "64asm: 64x0 Assembler.\n64asm: Copyright (c) 2024 Mahrouss "
+ "Logic.\n";
+ kStdOut << "/version: Print program version.\n";
+ kStdOut << "/verbose: Print verbose output.\n";
+ kStdOut << "/binary: Output as flat binary.\n";
+ kStdOut << "/64xxx: Compile for a subset of the X64000.\n";
+
+ return 0;
+ }
+ else if (strcmp(argv[i], "/binary") == 0)
+ {
+ kOutputAsBinary = true;
+ continue;
+ }
+ else if (strcmp(argv[i], "/verbose") == 0)
+ {
+ kVerbose = true;
+ continue;
+ }
+
+ kStdOut << "64asm: ignore " << argv[i] << "\n";
+ continue;
+ }
+
+ if (!std::filesystem::exists(argv[i]))
+ {
+ kStdOut << "64asm: can't open: " << argv[i] << std::endl;
+ goto asm_fail_exit;
+ }
+
+ std::string object_output(argv[i]);
+
+ for (auto& ext : kAsmFileExts)
+ {
+ if (object_output.find(ext) != std::string::npos)
+ {
+ object_output.erase(object_output.find(ext), std::strlen(ext));
+ }
+ }
+
+ object_output += kOutputAsBinary ? kBinaryFileExt : kObjectFileExt;
+
+ std::ifstream file_ptr(argv[i]);
+ std::ofstream file_ptr_out(object_output, std::ofstream::binary);
+
+ if (file_ptr_out.bad())
+ {
+ if (kVerbose)
+ {
+ kStdOut << "64asm: error: " << strerror(errno) << "\n";
+ }
+ }
+
+ std::string line;
+
+ NDK::AEHeader hdr{0};
+
+ memset(hdr.fPad, kAEInvalidOpcode, kAEPad);
+
+ hdr.fMagic[0] = kAEMag0;
+ hdr.fMagic[1] = kAEMag1;
+ hdr.fSize = sizeof(NDK::AEHeader);
+ hdr.fArch = kOutputArch;
+
+ /////////////////////////////////////////////////////////////////////////////////////////
+
+ // COMPILATION LOOP
+
+ /////////////////////////////////////////////////////////////////////////////////////////
+
+ NDK::Encoder64x0 asm64;
+
+ while (std::getline(file_ptr, line))
+ {
+ if (auto ln = asm64.CheckLine(line, argv[i]); !ln.empty())
+ {
+ detail::print_error_asm(ln, argv[i]);
+ continue;
+ }
+
+ try
+ {
+ asm_read_attributes(line);
+ asm64.WriteLine(line, argv[i]);
+ }
+ catch (const std::exception& e)
+ {
+ if (kVerbose)
+ {
+ std::string what = e.what();
+ detail::print_warning_asm("exit because of: " + what, "64asm");
+ }
+
+ std::filesystem::remove(object_output);
+ goto asm_fail_exit;
+ }
+ }
+
+ if (!kOutputAsBinary)
+ {
+ if (kVerbose)
+ {
+ kStdOut << "64asm: Writing object file...\n";
+ }
- hdr.fMagic[0] = kAEMag0;
- hdr.fMagic[1] = kAEMag1;
- hdr.fSize = sizeof(NDK::AEHeader);
- hdr.fArch = kOutputArch;
+ // this is the final step, write everything to the file.
- /////////////////////////////////////////////////////////////////////////////////////////
+ auto pos = file_ptr_out.tellp();
- // COMPILATION LOOP
+ hdr.fCount = kRecords.size() + kUndefinedSymbols.size();
- /////////////////////////////////////////////////////////////////////////////////////////
+ file_ptr_out << hdr;
- NDK::Encoder64x0 asm64;
+ if (kRecords.empty())
+ {
+ kStdErr << "64asm: At least one record is needed to write an object "
+ "file.\n64asm: Make one using `public_segment .code64 foo_bar`.\n";
- while (std::getline(file_ptr, line)) {
- if (auto ln = asm64.CheckLine(line, argv[i]); !ln.empty()) {
- detail::print_error_asm(ln, argv[i]);
- continue;
- }
+ std::filesystem::remove(object_output);
+ return -1;
+ }
- try {
- asm_read_attributes(line);
- asm64.WriteLine(line, argv[i]);
- } catch (const std::exception &e) {
- if (kVerbose) {
- std::string what = e.what();
- detail::print_warning_asm("exit because of: " + what, "64asm");
- }
+ kRecords[kRecords.size() - 1].fSize = kBytes.size();
- std::filesystem::remove(object_output);
- goto asm_fail_exit;
- }
- }
+ std::size_t record_count = 0UL;
- if (!kOutputAsBinary) {
- if (kVerbose) {
- kStdOut << "64asm: Writing object file...\n";
- }
+ for (auto& rec : kRecords)
+ {
+ if (kVerbose)
+ kStdOut << "64asm: Wrote record " << rec.fName << " to file...\n";
- // this is the final step, write everything to the file.
+ rec.fFlags |= NDK::kKindRelocationAtRuntime;
+ rec.fOffset = record_count;
+ ++record_count;
- auto pos = file_ptr_out.tellp();
+ file_ptr_out << rec;
+ }
- hdr.fCount = kRecords.size() + kUndefinedSymbols.size();
+ // increment once again, so that we won't lie about the kUndefinedSymbols.
+ ++record_count;
- file_ptr_out << hdr;
+ for (auto& sym : kUndefinedSymbols)
+ {
+ NDK::AERecordHeader _record_hdr{0};
- if (kRecords.empty()) {
- kStdErr << "64asm: At least one record is needed to write an object "
- "file.\n64asm: Make one using `public_segment .code64 foo_bar`.\n";
+ if (kVerbose)
+ kStdOut << "64asm: Wrote symbol " << sym << " to file...\n";
- std::filesystem::remove(object_output);
- return -1;
- }
+ _record_hdr.fKind = kAEInvalidOpcode;
+ _record_hdr.fSize = sym.size();
+ _record_hdr.fOffset = record_count;
- kRecords[kRecords.size() - 1].fSize = kBytes.size();
+ ++record_count;
- std::size_t record_count = 0UL;
+ memset(_record_hdr.fPad, kAEInvalidOpcode, kAEPad);
+ memcpy(_record_hdr.fName, sym.c_str(), sym.size());
- for (auto &rec : kRecords) {
- if (kVerbose)
- kStdOut << "64asm: Wrote record " << rec.fName << " to file...\n";
+ file_ptr_out << _record_hdr;
- rec.fFlags |= NDK::kKindRelocationAtRuntime;
- rec.fOffset = record_count;
- ++record_count;
+ ++kCounter;
+ }
- file_ptr_out << rec;
- }
+ auto pos_end = file_ptr_out.tellp();
- // increment once again, so that we won't lie about the kUndefinedSymbols.
- ++record_count;
+ file_ptr_out.seekp(pos);
- for (auto &sym : kUndefinedSymbols) {
- NDK::AERecordHeader _record_hdr{0};
+ hdr.fStartCode = pos_end;
+ hdr.fCodeSize = kBytes.size();
- if (kVerbose)
- kStdOut << "64asm: Wrote symbol " << sym << " to file...\n";
+ file_ptr_out << hdr;
- _record_hdr.fKind = kAEInvalidOpcode;
- _record_hdr.fSize = sym.size();
- _record_hdr.fOffset = record_count;
+ file_ptr_out.seekp(pos_end);
+ }
+ else
+ {
+ if (kVerbose)
+ {
+ kStdOut << "64asm: Write raw binary...\n";
+ }
+ }
- ++record_count;
+ // byte from byte, we write this.
+ for (auto& byte : kBytes)
+ {
+ file_ptr_out.write(reinterpret_cast<const char*>(&byte), sizeof(byte));
+ }
- memset(_record_hdr.fPad, kAEInvalidOpcode, kAEPad);
- memcpy(_record_hdr.fName, sym.c_str(), sym.size());
+ if (kVerbose)
+ kStdOut << "64asm: Wrote file with program in it.\n";
- file_ptr_out << _record_hdr;
+ file_ptr_out.flush();
+ file_ptr_out.close();
- ++kCounter;
- }
+ if (kVerbose)
+ kStdOut << "64asm: Exit succeeded.\n";
- auto pos_end = file_ptr_out.tellp();
-
- file_ptr_out.seekp(pos);
-
- hdr.fStartCode = pos_end;
- hdr.fCodeSize = kBytes.size();
-
- file_ptr_out << hdr;
-
- file_ptr_out.seekp(pos_end);
- } else {
- if (kVerbose) {
- kStdOut << "64asm: Write raw binary...\n";
- }
- }
-
- // byte from byte, we write this.
- for (auto &byte : kBytes) {
- file_ptr_out.write(reinterpret_cast<const char *>(&byte), sizeof(byte));
- }
-
- if (kVerbose) kStdOut << "64asm: Wrote file with program in it.\n";
-
- file_ptr_out.flush();
- file_ptr_out.close();
-
- if (kVerbose) kStdOut << "64asm: Exit succeeded.\n";
-
- return 0;
- }
+ return 0;
+ }
asm_fail_exit:
- if (kVerbose) kStdOut << "64asm: Exit failed.\n";
+ if (kVerbose)
+ kStdOut << "64asm: Exit failed.\n";
- return -1;
+ return -1;
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -300,149 +340,176 @@ asm_fail_exit:
/////////////////////////////////////////////////////////////////////////////////////////
-static bool asm_read_attributes(std::string &line) {
- // extern_segment is the opposite of public_segment, it signals to the ld
- // that we need this symbol.
- if (NDK::find_word(line, "extern_segment")) {
- if (kOutputAsBinary) {
- detail::print_error_asm("Invalid extern_segment directive in flat binary mode.",
- "64asm");
- throw std::runtime_error("invalid_extern_segment_bin");
- }
-
- auto name = line.substr(line.find("extern_segment") + strlen("extern_segment"));
-
- /// sanity check to avoid stupid linker errors.
- if (name.size() == 0) {
- detail::print_error_asm("Invalid extern_segment", "power-as");
- throw std::runtime_error("invalid_extern_segment");
- }
-
- std::string result = std::to_string(name.size());
- result += kUndefinedSymbol;
+static bool asm_read_attributes(std::string& line)
+{
+ // extern_segment is the opposite of public_segment, it signals to the ld
+ // that we need this symbol.
+ if (NDK::find_word(line, "extern_segment"))
+ {
+ if (kOutputAsBinary)
+ {
+ detail::print_error_asm("Invalid extern_segment directive in flat binary mode.",
+ "64asm");
+ throw std::runtime_error("invalid_extern_segment_bin");
+ }
+
+ auto name = line.substr(line.find("extern_segment") + strlen("extern_segment"));
+
+ /// sanity check to avoid stupid linker errors.
+ if (name.size() == 0)
+ {
+ detail::print_error_asm("Invalid extern_segment", "power-as");
+ throw std::runtime_error("invalid_extern_segment");
+ }
+
+ std::string result = std::to_string(name.size());
+ result += kUndefinedSymbol;
+
+ // mangle this
+ for (char& j : name)
+ {
+ if (j == ' ' || j == ',')
+ j = '$';
+ }
+
+ result += name;
+
+ if (name.find(".code64") != std::string::npos)
+ {
+ // data is treated as code.
+ kCurrentRecord.fKind = NDK::kPefCode;
+ }
+ else if (name.find(".data64") != std::string::npos)
+ {
+ // no code will be executed from here.
+ kCurrentRecord.fKind = NDK::kPefData;
+ }
+ else if (name.find(".zero64") != std::string::npos)
+ {
+ // this is a bss section.
+ kCurrentRecord.fKind = NDK::kPefZero;
+ }
+
+ // this is a special case for the start stub.
+ // we want this so that ld can find it.
+
+ if (name == kPefStart)
+ {
+ kCurrentRecord.fKind = NDK::kPefCode;
+ }
+
+ // now we can tell the code size of the previous kCurrentRecord.
+
+ if (!kRecords.empty())
+ kRecords[kRecords.size() - 1].fSize = kBytes.size();
+
+ memset(kCurrentRecord.fName, 0, kAESymbolLen);
+ memcpy(kCurrentRecord.fName, result.c_str(), result.size());
+
+ ++kCounter;
+
+ memset(kCurrentRecord.fPad, kAEInvalidOpcode, kAEPad);
+
+ kRecords.emplace_back(kCurrentRecord);
+
+ return true;
+ }
+ // public_segment is a special keyword used by 64asm to tell the AE output stage to
+ // mark this section as a header. it currently supports .code64, .data64.,
+ // .zero64
+ else if (NDK::find_word(line, "public_segment"))
+ {
+ if (kOutputAsBinary)
+ {
+ detail::print_error_asm("Invalid public_segment directive in flat binary mode.",
+ "64asm");
+ throw std::runtime_error("invalid_public_segment_bin");
+ }
+
+ auto name = line.substr(line.find("public_segment") + strlen("public_segment"));
+
+ std::string name_copy = name;
+
+ for (char& j : name)
+ {
+ if (j == ' ')
+ j = '$';
+ }
+
+ if (name.find(".code64") != std::string::npos)
+ {
+ // data is treated as code.
+
+ name_copy.erase(name_copy.find(".code64"), strlen(".code64"));
+ kCurrentRecord.fKind = NDK::kPefCode;
+ }
+ else if (name.find(".data64") != std::string::npos)
+ {
+ // no code will be executed from here.
+
+ name_copy.erase(name_copy.find(".data64"), strlen(".data64"));
+ kCurrentRecord.fKind = NDK::kPefData;
+ }
+ else if (name.find(".zero64") != std::string::npos)
+ {
+ // this is a bss section.
+
+ name_copy.erase(name_copy.find(".zero64"), strlen(".zero64"));
+ kCurrentRecord.fKind = NDK::kPefZero;
+ }
+
+ // this is a special case for the start stub.
+ // we want this so that ld can find it.
- // mangle this
- for (char &j : name) {
- if (j == ' ' || j == ',') j = '$';
- }
+ if (name == kPefStart)
+ {
+ kCurrentRecord.fKind = NDK::kPefCode;
+ }
+
+ while (name_copy.find(" ") != std::string::npos)
+ name_copy.erase(name_copy.find(" "), 1);
- result += name;
+ kOriginLabel.push_back(std::make_pair(name_copy, kOrigin));
+ ++kOrigin;
- if (name.find(".code64") != std::string::npos) {
- // data is treated as code.
- kCurrentRecord.fKind = NDK::kPefCode;
- } else if (name.find(".data64") != std::string::npos) {
- // no code will be executed from here.
- kCurrentRecord.fKind = NDK::kPefData;
- } else if (name.find(".zero64") != std::string::npos) {
- // this is a bss section.
- kCurrentRecord.fKind = NDK::kPefZero;
- }
+ // now we can tell the code size of the previous kCurrentRecord.
- // this is a special case for the start stub.
- // we want this so that ld can find it.
+ if (!kRecords.empty())
+ kRecords[kRecords.size() - 1].fSize = kBytes.size();
- if (name == kPefStart) {
- kCurrentRecord.fKind = NDK::kPefCode;
- }
+ memset(kCurrentRecord.fName, 0, kAESymbolLen);
+ memcpy(kCurrentRecord.fName, name.c_str(), name.size());
- // now we can tell the code size of the previous kCurrentRecord.
+ ++kCounter;
- if (!kRecords.empty()) kRecords[kRecords.size() - 1].fSize = kBytes.size();
+ memset(kCurrentRecord.fPad, kAEInvalidOpcode, kAEPad);
- memset(kCurrentRecord.fName, 0, kAESymbolLen);
- memcpy(kCurrentRecord.fName, result.c_str(), result.size());
+ kRecords.emplace_back(kCurrentRecord);
- ++kCounter;
+ return true;
+ }
- memset(kCurrentRecord.fPad, kAEInvalidOpcode, kAEPad);
-
- kRecords.emplace_back(kCurrentRecord);
-
- return true;
- }
- // public_segment is a special keyword used by 64asm to tell the AE output stage to
- // mark this section as a header. it currently supports .code64, .data64.,
- // .zero64
- else if (NDK::find_word(line, "public_segment")) {
- if (kOutputAsBinary) {
- detail::print_error_asm("Invalid public_segment directive in flat binary mode.",
- "64asm");
- throw std::runtime_error("invalid_public_segment_bin");
- }
-
- auto name = line.substr(line.find("public_segment") + strlen("public_segment"));
-
- std::string name_copy = name;
-
- for (char &j : name) {
- if (j == ' ') j = '$';
- }
-
- if (name.find(".code64") != std::string::npos) {
- // data is treated as code.
-
- name_copy.erase(name_copy.find(".code64"), strlen(".code64"));
- kCurrentRecord.fKind = NDK::kPefCode;
- } else if (name.find(".data64") != std::string::npos) {
- // no code will be executed from here.
-
- name_copy.erase(name_copy.find(".data64"), strlen(".data64"));
- kCurrentRecord.fKind = NDK::kPefData;
- } else if (name.find(".zero64") != std::string::npos) {
- // this is a bss section.
-
- name_copy.erase(name_copy.find(".zero64"), strlen(".zero64"));
- kCurrentRecord.fKind = NDK::kPefZero;
- }
-
- // this is a special case for the start stub.
- // we want this so that ld can find it.
-
- if (name == kPefStart) {
- kCurrentRecord.fKind = NDK::kPefCode;
- }
-
- while (name_copy.find(" ") != std::string::npos)
- name_copy.erase(name_copy.find(" "), 1);
-
- kOriginLabel.push_back(std::make_pair(name_copy, kOrigin));
- ++kOrigin;
-
- // now we can tell the code size of the previous kCurrentRecord.
-
- if (!kRecords.empty()) kRecords[kRecords.size() - 1].fSize = kBytes.size();
-
- memset(kCurrentRecord.fName, 0, kAESymbolLen);
- memcpy(kCurrentRecord.fName, name.c_str(), name.size());
-
- ++kCounter;
-
- memset(kCurrentRecord.fPad, kAEInvalidOpcode, kAEPad);
-
- kRecords.emplace_back(kCurrentRecord);
-
- return true;
- }
-
- return false;
+ return false;
}
// \brief algorithms and helpers.
-namespace detail::algorithm {
-// \brief authorize a brief set of characters.
-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 == '.'));
-}
-
-bool is_valid_64x0(const std::string &str) {
- return std::find_if(str.begin(), str.end(), is_not_alnum_space) == str.end();
-}
-} // namespace detail::algorithm
+namespace detail::algorithm
+{
+ // \brief authorize a brief set of characters.
+ 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 == '.'));
+ }
+
+ bool is_valid_64x0(const std::string& str)
+ {
+ return std::find_if(str.begin(), str.end(), is_not_alnum_space) == str.end();
+ }
+} // namespace detail::algorithm
/////////////////////////////////////////////////////////////////////////////////////////
@@ -450,214 +517,258 @@ bool is_valid_64x0(const std::string &str) {
/////////////////////////////////////////////////////////////////////////////////////////
-std::string NDK::Encoder64x0::CheckLine(std::string &line,
- const std::string &file) {
- std::string err_str;
-
- if (line.empty() || NDK::find_word(line, "extern_segment") ||
- NDK::find_word(line, "public_segment") ||
- line.find('#') != std::string::npos || NDK::find_word(line, ";")) {
- if (line.find('#') != std::string::npos) {
- line.erase(line.find('#'));
- } else if (line.find(';') != std::string::npos) {
- line.erase(line.find(';'));
- } else {
- // now check the line for validity
- if (!detail::algorithm::is_valid_64x0(line)) {
- err_str = "Line contains non alphanumeric characters.\nhere -> ";
- err_str += line;
- }
- }
-
- return err_str;
- }
-
- if (!detail::algorithm::is_valid_64x0(line)) {
- err_str = "Line contains non alphanumeric characters.\nhere -> ";
- err_str += line;
-
- return err_str;
- }
-
- // check for a valid instruction format.
-
- if (line.find(',') != std::string::npos) {
- if (line.find(',') + 1 == line.size()) {
- err_str += "\nInstruction lacks right register, here -> ";
- err_str += line.substr(line.find(','));
-
- return err_str;
- } else {
- bool nothing_on_right = true;
-
- if (line.find(',') + 1 > line.size()) {
- err_str += "\nInstruction not complete, here -> ";
- err_str += line;
-
- return err_str;
- }
-
- auto substr = line.substr(line.find(',') + 1);
-
- for (auto &ch : substr) {
- if (ch != ' ' && ch != '\t') {
- nothing_on_right = false;
- }
- }
-
- // this means we found nothing after that ',' .
- if (nothing_on_right) {
- err_str += "\nInstruction not complete, here -> ";
- err_str += line;
-
- return err_str;
- }
- }
- }
-
- // these do take an argument.
- std::vector<std::string> operands_inst = {"stw", "ldw", "lda", "sta"};
-
- // these don't.
- std::vector<std::string> filter_inst = {"jlr", "jrl", "int"};
-
- for (auto &opcode64x0 : kOpcodes64x0) {
- if (line.find(opcode64x0.fName) != std::string::npos) {
- if (opcode64x0.fFunct7 == kAsmNoArgs) return err_str;
-
- for (auto &op : operands_inst) {
- // if only the instruction was found.
- if (line == op) {
- err_str += "\nMalformed ";
- err_str += op;
- err_str += " instruction, here -> ";
- err_str += line;
- }
- }
-
- // if it is like that -> addr1, 0x0
- if (auto it = std::find(filter_inst.begin(), filter_inst.end(),
- opcode64x0.fName);
- it == filter_inst.cend()) {
- if (NDK::find_word(line, opcode64x0.fName)) {
- if (!isspace(line[line.find(opcode64x0.fName) +
- strlen(opcode64x0.fName)])) {
- err_str += "\nMissing space between ";
- err_str += opcode64x0.fName;
- err_str += " and operands.\nhere -> ";
- err_str += line;
- }
- }
- }
-
- return err_str;
- }
- }
-
- err_str += "Unrecognized instruction: " + line;
-
- return err_str;
+std::string NDK::Encoder64x0::CheckLine(std::string& line,
+ const std::string& file)
+{
+ std::string err_str;
+
+ if (line.empty() || NDK::find_word(line, "extern_segment") ||
+ NDK::find_word(line, "public_segment") ||
+ line.find('#') != std::string::npos || NDK::find_word(line, ";"))
+ {
+ if (line.find('#') != std::string::npos)
+ {
+ line.erase(line.find('#'));
+ }
+ else if (line.find(';') != std::string::npos)
+ {
+ line.erase(line.find(';'));
+ }
+ else
+ {
+ // now check the line for validity
+ if (!detail::algorithm::is_valid_64x0(line))
+ {
+ err_str = "Line contains non alphanumeric characters.\nhere -> ";
+ err_str += line;
+ }
+ }
+
+ return err_str;
+ }
+
+ if (!detail::algorithm::is_valid_64x0(line))
+ {
+ err_str = "Line contains non alphanumeric characters.\nhere -> ";
+ err_str += line;
+
+ return err_str;
+ }
+
+ // check for a valid instruction format.
+
+ if (line.find(',') != std::string::npos)
+ {
+ if (line.find(',') + 1 == line.size())
+ {
+ err_str += "\nInstruction lacks right register, here -> ";
+ err_str += line.substr(line.find(','));
+
+ return err_str;
+ }
+ else
+ {
+ bool nothing_on_right = true;
+
+ if (line.find(',') + 1 > line.size())
+ {
+ err_str += "\nInstruction not complete, here -> ";
+ err_str += line;
+
+ return err_str;
+ }
+
+ auto substr = line.substr(line.find(',') + 1);
+
+ for (auto& ch : substr)
+ {
+ if (ch != ' ' && ch != '\t')
+ {
+ nothing_on_right = false;
+ }
+ }
+
+ // this means we found nothing after that ',' .
+ if (nothing_on_right)
+ {
+ err_str += "\nInstruction not complete, here -> ";
+ err_str += line;
+
+ return err_str;
+ }
+ }
+ }
+
+ // these do take an argument.
+ std::vector<std::string> operands_inst = {"stw", "ldw", "lda", "sta"};
+
+ // these don't.
+ std::vector<std::string> filter_inst = {"jlr", "jrl", "int"};
+
+ for (auto& opcode64x0 : kOpcodes64x0)
+ {
+ if (line.find(opcode64x0.fName) != std::string::npos)
+ {
+ if (opcode64x0.fFunct7 == kAsmNoArgs)
+ return err_str;
+
+ for (auto& op : operands_inst)
+ {
+ // if only the instruction was found.
+ if (line == op)
+ {
+ err_str += "\nMalformed ";
+ err_str += op;
+ err_str += " instruction, here -> ";
+ err_str += line;
+ }
+ }
+
+ // if it is like that -> addr1, 0x0
+ if (auto it = std::find(filter_inst.begin(), filter_inst.end(),
+ opcode64x0.fName);
+ it == filter_inst.cend())
+ {
+ if (NDK::find_word(line, opcode64x0.fName))
+ {
+ if (!isspace(line[line.find(opcode64x0.fName) +
+ strlen(opcode64x0.fName)]))
+ {
+ err_str += "\nMissing space between ";
+ err_str += opcode64x0.fName;
+ err_str += " and operands.\nhere -> ";
+ err_str += line;
+ }
+ }
+ }
+
+ return err_str;
+ }
+ }
+
+ err_str += "Unrecognized instruction: " + line;
+
+ return err_str;
}
-bool NDK::Encoder64x0::WriteNumber(const std::size_t &pos,
- std::string &jump_label) {
- if (!isdigit(jump_label[pos])) return false;
-
- switch (jump_label[pos + 1]) {
- case 'x': {
- if (auto res = strtol(jump_label.substr(pos + 2).c_str(), nullptr, 16);
- !res) {
- if (errno != 0) {
- detail::print_error_asm("invalid hex number: " + jump_label, "64asm");
- throw std::runtime_error("invalid_hex_number");
- }
- }
-
- NDK::NumberCast64 num(
- strtol(jump_label.substr(pos + 2).c_str(), nullptr, 16));
-
- for (char &i : num.number) {
- kBytes.push_back(i);
- }
-
- if (kVerbose) {
- kStdOut << "64asm: found a base 16 number here: "
- << jump_label.substr(pos) << "\n";
- }
-
- return true;
- }
- case 'b': {
- if (auto res = strtol(jump_label.substr(pos + 2).c_str(), nullptr, 2);
- !res) {
- if (errno != 0) {
- detail::print_error_asm("invalid binary number: " + jump_label, "64asm");
- throw std::runtime_error("invalid_bin");
- }
- }
-
- NDK::NumberCast64 num(
- strtol(jump_label.substr(pos + 2).c_str(), nullptr, 2));
-
- if (kVerbose) {
- kStdOut << "64asm: found a base 2 number here: "
- << jump_label.substr(pos) << "\n";
- }
-
- for (char &i : num.number) {
- kBytes.push_back(i);
- }
-
- return true;
- }
- case 'o': {
- if (auto res = strtol(jump_label.substr(pos + 2).c_str(), nullptr, 7);
- !res) {
- if (errno != 0) {
- detail::print_error_asm("invalid octal number: " + jump_label, "64asm");
- throw std::runtime_error("invalid_octal");
- }
- }
-
- NDK::NumberCast64 num(
- strtol(jump_label.substr(pos + 2).c_str(), nullptr, 7));
-
- if (kVerbose) {
- kStdOut << "64asm: found a base 8 number here: "
- << jump_label.substr(pos) << "\n";
- }
-
- for (char &i : num.number) {
- kBytes.push_back(i);
- }
-
- return true;
- }
- default: {
- break;
- }
- }
-
- /* check for errno and stuff like that */
- if (auto res = strtol(jump_label.substr(pos).c_str(), nullptr, 10); !res) {
- if (errno != 0) {
- return false;
- }
- }
-
- NDK::NumberCast64 num(
- strtol(jump_label.substr(pos).c_str(), nullptr, 10));
-
- for (char &i : num.number) {
- kBytes.push_back(i);
- }
-
- if (kVerbose) {
- kStdOut << "64asm: found a base 10 number here: " << jump_label.substr(pos)
- << "\n";
- }
-
- return true;
+bool NDK::Encoder64x0::WriteNumber(const std::size_t& pos,
+ std::string& jump_label)
+{
+ if (!isdigit(jump_label[pos]))
+ return false;
+
+ switch (jump_label[pos + 1])
+ {
+ case 'x': {
+ if (auto res = strtol(jump_label.substr(pos + 2).c_str(), nullptr, 16);
+ !res)
+ {
+ if (errno != 0)
+ {
+ detail::print_error_asm("invalid hex number: " + jump_label, "64asm");
+ throw std::runtime_error("invalid_hex_number");
+ }
+ }
+
+ NDK::NumberCast64 num(
+ strtol(jump_label.substr(pos + 2).c_str(), nullptr, 16));
+
+ for (char& i : num.number)
+ {
+ kBytes.push_back(i);
+ }
+
+ if (kVerbose)
+ {
+ kStdOut << "64asm: found a base 16 number here: "
+ << jump_label.substr(pos) << "\n";
+ }
+
+ return true;
+ }
+ case 'b': {
+ if (auto res = strtol(jump_label.substr(pos + 2).c_str(), nullptr, 2);
+ !res)
+ {
+ if (errno != 0)
+ {
+ detail::print_error_asm("invalid binary number: " + jump_label, "64asm");
+ throw std::runtime_error("invalid_bin");
+ }
+ }
+
+ NDK::NumberCast64 num(
+ strtol(jump_label.substr(pos + 2).c_str(), nullptr, 2));
+
+ if (kVerbose)
+ {
+ kStdOut << "64asm: found a base 2 number here: "
+ << jump_label.substr(pos) << "\n";
+ }
+
+ for (char& i : num.number)
+ {
+ kBytes.push_back(i);
+ }
+
+ return true;
+ }
+ case 'o': {
+ if (auto res = strtol(jump_label.substr(pos + 2).c_str(), nullptr, 7);
+ !res)
+ {
+ if (errno != 0)
+ {
+ detail::print_error_asm("invalid octal number: " + jump_label, "64asm");
+ throw std::runtime_error("invalid_octal");
+ }
+ }
+
+ NDK::NumberCast64 num(
+ strtol(jump_label.substr(pos + 2).c_str(), nullptr, 7));
+
+ if (kVerbose)
+ {
+ kStdOut << "64asm: found a base 8 number here: "
+ << jump_label.substr(pos) << "\n";
+ }
+
+ for (char& i : num.number)
+ {
+ kBytes.push_back(i);
+ }
+
+ return true;
+ }
+ default: {
+ break;
+ }
+ }
+
+ /* check for errno and stuff like that */
+ if (auto res = strtol(jump_label.substr(pos).c_str(), nullptr, 10); !res)
+ {
+ if (errno != 0)
+ {
+ return false;
+ }
+ }
+
+ NDK::NumberCast64 num(
+ strtol(jump_label.substr(pos).c_str(), nullptr, 10));
+
+ for (char& i : num.number)
+ {
+ kBytes.push_back(i);
+ }
+
+ if (kVerbose)
+ {
+ kStdOut << "64asm: found a base 10 number here: " << jump_label.substr(pos)
+ << "\n";
+ }
+
+ return true;
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -666,289 +777,342 @@ bool NDK::Encoder64x0::WriteNumber(const std::size_t &pos,
/////////////////////////////////////////////////////////////////////////////////////////
-bool NDK::Encoder64x0::WriteLine(std::string &line,
- const std::string &file) {
- if (NDK::find_word(line, "public_segment ")) return true;
-
- for (auto &opcode64x0 : kOpcodes64x0) {
- // strict check here
- if (NDK::find_word(line, opcode64x0.fName) &&
- detail::algorithm::is_valid_64x0(line)) {
- std::string name(opcode64x0.fName);
- std::string jump_label, cpy_jump_label;
-
- kBytes.emplace_back(opcode64x0.fOpcode);
- kBytes.emplace_back(opcode64x0.fFunct3);
- kBytes.emplace_back(opcode64x0.fFunct7);
-
- // check funct7 type.
- switch (opcode64x0.fFunct7) {
- // reg to reg means register to register transfer operation.
- case kAsmRegToReg:
- case kAsmImmediate: {
- // \brief how many registers we found.
- std::size_t found_some = 0UL;
-
- for (size_t line_index = 0UL; line_index < line.size();
- line_index++) {
- if (line[line_index] == kAsmRegisterPrefix[0] &&
- isdigit(line[line_index + 1])) {
- std::string register_syntax = kAsmRegisterPrefix;
- register_syntax += line[line_index + 1];
-
- if (isdigit(line[line_index + 2]))
- register_syntax += line[line_index + 2];
-
- std::string reg_str;
- reg_str += line[line_index + 1];
-
- if (isdigit(line[line_index + 2]))
- reg_str += line[line_index + 2];
-
- // it ranges from r0 to r19
- // something like r190 doesn't exist in the instruction set.
- if (kOutputArch == NDK::kPefArch64000) {
- if (isdigit(line[line_index + 3]) &&
- isdigit(line[line_index + 2])) {
- reg_str += line[line_index + 3];
- detail::print_error_asm(
- "invalid register index, r" + reg_str +
- "\nnote: The 64x0 accepts registers from r0 to r20.",
- file);
- throw std::runtime_error("invalid_register_index");
- }
- }
-
- // finally cast to a size_t
- std::size_t reg_index = strtol(reg_str.c_str(), nullptr, 10);
-
- if (reg_index > kAsmRegisterLimit) {
- detail::print_error_asm("invalid register index, r" + reg_str,
- file);
- throw std::runtime_error("invalid_register_index");
- }
-
- kBytes.emplace_back(reg_index);
- ++found_some;
-
- if (kVerbose) {
- kStdOut << "64asm: Register found: " << register_syntax << "\n";
- kStdOut << "64asm: Register amount in instruction: "
- << found_some << "\n";
- }
- }
- }
-
- // we're not in immediate addressing, reg to reg.
- if (opcode64x0.fFunct7 != kAsmImmediate) {
- // remember! register to register!
- if (found_some == 1) {
- detail::print_error_asm(
- "Too few registers.\ntip: each 64asm register "
- "starts with 'r'.\nline: " +
- line,
- file);
- throw std::runtime_error("not_a_register");
- }
- }
-
- if (found_some < 1 && name != "ldw" && name != "lda" &&
- name != "stw") {
- detail::print_error_asm(
- "invalid combination of opcode and registers.\nline: " + line,
- file);
- throw std::runtime_error("invalid_comb_op_reg");
- } else if (found_some == 1 && name == "add") {
- detail::print_error_asm(
- "invalid combination of opcode and registers.\nline: " + line,
- file);
- throw std::runtime_error("invalid_comb_op_reg");
- } else if (found_some == 1 && name == "sub") {
- detail::print_error_asm(
- "invalid combination of opcode and registers.\nline: " + line,
- file);
- throw std::runtime_error("invalid_comb_op_reg");
- }
-
- if (found_some > 0 && name == "pop") {
- detail::print_error_asm(
- "invalid combination for opcode 'pop'.\ntip: it expects "
- "nothing.\nline: " +
- line,
- file);
- throw std::runtime_error("invalid_comb_op_pop");
- }
- }
- default:
- break;
- }
-
- // try to fetch a number from the name
- if (name == "stw" || name == "ldw" || name == "lda" || name == "sta") {
- auto where_string = name;
-
- // if we load something, we'd need it's symbol/literal
- if (name == "stw" || name == "sta" || name == "ldw" || name == "lda" ||
- name == "sta")
- where_string = ",";
-
- jump_label = line;
-
- auto found_sym = false;
-
- while (jump_label.find(where_string) != std::string::npos) {
- jump_label = jump_label.substr(jump_label.find(where_string) +
- where_string.size());
-
- while (jump_label.find(" ") != std::string::npos) {
- jump_label.erase(jump_label.find(" "), 1);
- }
-
- if (jump_label[0] != kAsmRegisterPrefix[0] &&
- !isdigit(jump_label[1])) {
- if (found_sym) {
- detail::print_error_asm(
- "invalid combination of opcode and operands.\nhere -> " +
- jump_label,
- file);
- throw std::runtime_error("invalid_comb_op_ops");
- } else {
- // death trap installed.
- found_sym = true;
- }
- }
- }
-
- cpy_jump_label = jump_label;
-
- // replace any spaces with $
- if (jump_label[0] == ' ') {
- while (jump_label.find(' ') != std::string::npos) {
- if (isalnum(jump_label[0]) || isdigit(jump_label[0])) break;
-
- jump_label.erase(jump_label.find(' '), 1);
- }
- }
-
- if (!this->WriteNumber(0, jump_label)) {
- // sta expects this: sta 0x000000, r0
- if (name == "sta") {
- detail::print_error_asm(
- "invalid combination of opcode and operands.\nHere ->" + line,
- file);
- throw std::runtime_error("invalid_comb_op_ops");
- }
- } else {
- if (name == "sta" &&
- cpy_jump_label.find("extern_segment ") != std::string::npos) {
- detail::print_error_asm("invalid usage extern_segment on 'sta', here: " + line,
- file);
- throw std::runtime_error("invalid_sta_usage");
- }
- }
-
- goto asm_write_label;
- }
-
- // This is the case where we jump to a label, it is also used as a goto.
- if (name == "lda" || name == "sta") {
- asm_write_label:
- if (cpy_jump_label.find('\n') != std::string::npos)
- cpy_jump_label.erase(cpy_jump_label.find('\n'), 1);
-
- if (cpy_jump_label.find("extern_segment") != std::string::npos) {
- cpy_jump_label.erase(cpy_jump_label.find("extern_segment"), strlen("extern_segment"));
-
- if (name == "sta") {
- detail::print_error_asm("extern_segment is not allowed on a sta operation.",
- file);
- throw std::runtime_error("extern_segment_sta_op");
- } else {
- goto asm_end_label_cpy;
- }
- }
-
- if (name == "lda" || name == "sta") {
- for (auto &label : kOriginLabel) {
- if (cpy_jump_label == label.first) {
- if (kVerbose) {
- kStdOut << "64asm: Replace label " << cpy_jump_label
- << " to address: " << label.second << std::endl;
- }
-
- NDK::NumberCast64 num(label.second);
-
- for (auto &num : num.number) {
- kBytes.push_back(num);
- }
-
- goto asm_end_label_cpy;
- }
- }
-
- if (cpy_jump_label[0] == '0') {
- switch (cpy_jump_label[1]) {
- case 'x':
- case 'o':
- case 'b':
- if (this->WriteNumber(0, cpy_jump_label))
- goto asm_end_label_cpy;
-
- break;
- default:
- break;
- }
-
- if (isdigit(cpy_jump_label[0])) {
- if (this->WriteNumber(0, cpy_jump_label)) goto asm_end_label_cpy;
-
- break;
- }
- }
- }
-
- if (cpy_jump_label.size() < 1) {
- detail::print_error_asm("label is empty, can't jump on it.", file);
- throw std::runtime_error("label_empty");
- }
-
- /// don't go any further if:
- /// load word (ldw) or store word. (stw)
-
- if (name == "ldw" || name == "stw") break;
-
- auto mld_reloc_str = std::to_string(cpy_jump_label.size());
- mld_reloc_str += kUndefinedSymbol;
- mld_reloc_str += cpy_jump_label;
-
- bool ignore_back_slash = false;
-
- for (auto &reloc_chr : mld_reloc_str) {
- if (reloc_chr == '\\') {
- ignore_back_slash = true;
- continue;
- }
-
- if (ignore_back_slash) {
- ignore_back_slash = false;
- continue;
- }
-
- kBytes.push_back(reloc_chr);
- }
-
- kBytes.push_back('\0');
- goto asm_end_label_cpy;
- }
-
- asm_end_label_cpy:
- kOrigin += c64x0IPAlignment;
-
- break;
- }
- }
-
- return true;
+bool NDK::Encoder64x0::WriteLine(std::string& line,
+ const std::string& file)
+{
+ if (NDK::find_word(line, "public_segment "))
+ return true;
+
+ for (auto& opcode64x0 : kOpcodes64x0)
+ {
+ // strict check here
+ if (NDK::find_word(line, opcode64x0.fName) &&
+ detail::algorithm::is_valid_64x0(line))
+ {
+ std::string name(opcode64x0.fName);
+ std::string jump_label, cpy_jump_label;
+
+ kBytes.emplace_back(opcode64x0.fOpcode);
+ kBytes.emplace_back(opcode64x0.fFunct3);
+ kBytes.emplace_back(opcode64x0.fFunct7);
+
+ // check funct7 type.
+ switch (opcode64x0.fFunct7)
+ {
+ // reg to reg means register to register transfer operation.
+ case kAsmRegToReg:
+ case kAsmImmediate: {
+ // \brief how many registers we found.
+ std::size_t found_some = 0UL;
+
+ for (size_t line_index = 0UL; line_index < line.size();
+ line_index++)
+ {
+ if (line[line_index] == kAsmRegisterPrefix[0] &&
+ isdigit(line[line_index + 1]))
+ {
+ std::string register_syntax = kAsmRegisterPrefix;
+ register_syntax += line[line_index + 1];
+
+ if (isdigit(line[line_index + 2]))
+ register_syntax += line[line_index + 2];
+
+ std::string reg_str;
+ reg_str += line[line_index + 1];
+
+ if (isdigit(line[line_index + 2]))
+ reg_str += line[line_index + 2];
+
+ // it ranges from r0 to r19
+ // something like r190 doesn't exist in the instruction set.
+ if (kOutputArch == NDK::kPefArch64000)
+ {
+ if (isdigit(line[line_index + 3]) &&
+ isdigit(line[line_index + 2]))
+ {
+ reg_str += line[line_index + 3];
+ detail::print_error_asm(
+ "invalid register index, r" + reg_str +
+ "\nnote: The 64x0 accepts registers from r0 to r20.",
+ file);
+ throw std::runtime_error("invalid_register_index");
+ }
+ }
+
+ // finally cast to a size_t
+ std::size_t reg_index = strtol(reg_str.c_str(), nullptr, 10);
+
+ if (reg_index > kAsmRegisterLimit)
+ {
+ detail::print_error_asm("invalid register index, r" + reg_str,
+ file);
+ throw std::runtime_error("invalid_register_index");
+ }
+
+ kBytes.emplace_back(reg_index);
+ ++found_some;
+
+ if (kVerbose)
+ {
+ kStdOut << "64asm: Register found: " << register_syntax << "\n";
+ kStdOut << "64asm: Register amount in instruction: "
+ << found_some << "\n";
+ }
+ }
+ }
+
+ // we're not in immediate addressing, reg to reg.
+ if (opcode64x0.fFunct7 != kAsmImmediate)
+ {
+ // remember! register to register!
+ if (found_some == 1)
+ {
+ detail::print_error_asm(
+ "Too few registers.\ntip: each 64asm register "
+ "starts with 'r'.\nline: " +
+ line,
+ file);
+ throw std::runtime_error("not_a_register");
+ }
+ }
+
+ if (found_some < 1 && name != "ldw" && name != "lda" &&
+ name != "stw")
+ {
+ detail::print_error_asm(
+ "invalid combination of opcode and registers.\nline: " + line,
+ file);
+ throw std::runtime_error("invalid_comb_op_reg");
+ }
+ else if (found_some == 1 && name == "add")
+ {
+ detail::print_error_asm(
+ "invalid combination of opcode and registers.\nline: " + line,
+ file);
+ throw std::runtime_error("invalid_comb_op_reg");
+ }
+ else if (found_some == 1 && name == "sub")
+ {
+ detail::print_error_asm(
+ "invalid combination of opcode and registers.\nline: " + line,
+ file);
+ throw std::runtime_error("invalid_comb_op_reg");
+ }
+
+ if (found_some > 0 && name == "pop")
+ {
+ detail::print_error_asm(
+ "invalid combination for opcode 'pop'.\ntip: it expects "
+ "nothing.\nline: " +
+ line,
+ file);
+ throw std::runtime_error("invalid_comb_op_pop");
+ }
+ }
+ default:
+ break;
+ }
+
+ // try to fetch a number from the name
+ if (name == "stw" || name == "ldw" || name == "lda" || name == "sta")
+ {
+ auto where_string = name;
+
+ // if we load something, we'd need it's symbol/literal
+ if (name == "stw" || name == "sta" || name == "ldw" || name == "lda" ||
+ name == "sta")
+ where_string = ",";
+
+ jump_label = line;
+
+ auto found_sym = false;
+
+ while (jump_label.find(where_string) != std::string::npos)
+ {
+ jump_label = jump_label.substr(jump_label.find(where_string) +
+ where_string.size());
+
+ while (jump_label.find(" ") != std::string::npos)
+ {
+ jump_label.erase(jump_label.find(" "), 1);
+ }
+
+ if (jump_label[0] != kAsmRegisterPrefix[0] &&
+ !isdigit(jump_label[1]))
+ {
+ if (found_sym)
+ {
+ detail::print_error_asm(
+ "invalid combination of opcode and operands.\nhere -> " +
+ jump_label,
+ file);
+ throw std::runtime_error("invalid_comb_op_ops");
+ }
+ else
+ {
+ // death trap installed.
+ found_sym = true;
+ }
+ }
+ }
+
+ cpy_jump_label = jump_label;
+
+ // replace any spaces with $
+ if (jump_label[0] == ' ')
+ {
+ while (jump_label.find(' ') != std::string::npos)
+ {
+ if (isalnum(jump_label[0]) || isdigit(jump_label[0]))
+ break;
+
+ jump_label.erase(jump_label.find(' '), 1);
+ }
+ }
+
+ if (!this->WriteNumber(0, jump_label))
+ {
+ // sta expects this: sta 0x000000, r0
+ if (name == "sta")
+ {
+ detail::print_error_asm(
+ "invalid combination of opcode and operands.\nHere ->" + line,
+ file);
+ throw std::runtime_error("invalid_comb_op_ops");
+ }
+ }
+ else
+ {
+ if (name == "sta" &&
+ cpy_jump_label.find("extern_segment ") != std::string::npos)
+ {
+ detail::print_error_asm("invalid usage extern_segment on 'sta', here: " + line,
+ file);
+ throw std::runtime_error("invalid_sta_usage");
+ }
+ }
+
+ goto asm_write_label;
+ }
+
+ // This is the case where we jump to a label, it is also used as a goto.
+ if (name == "lda" || name == "sta")
+ {
+ asm_write_label:
+ if (cpy_jump_label.find('\n') != std::string::npos)
+ cpy_jump_label.erase(cpy_jump_label.find('\n'), 1);
+
+ if (cpy_jump_label.find("extern_segment") != std::string::npos)
+ {
+ cpy_jump_label.erase(cpy_jump_label.find("extern_segment"), strlen("extern_segment"));
+
+ if (name == "sta")
+ {
+ detail::print_error_asm("extern_segment is not allowed on a sta operation.",
+ file);
+ throw std::runtime_error("extern_segment_sta_op");
+ }
+ else
+ {
+ goto asm_end_label_cpy;
+ }
+ }
+
+ if (name == "lda" || name == "sta")
+ {
+ for (auto& label : kOriginLabel)
+ {
+ if (cpy_jump_label == label.first)
+ {
+ if (kVerbose)
+ {
+ kStdOut << "64asm: Replace label " << cpy_jump_label
+ << " to address: " << label.second << std::endl;
+ }
+
+ NDK::NumberCast64 num(label.second);
+
+ for (auto& num : num.number)
+ {
+ kBytes.push_back(num);
+ }
+
+ goto asm_end_label_cpy;
+ }
+ }
+
+ if (cpy_jump_label[0] == '0')
+ {
+ switch (cpy_jump_label[1])
+ {
+ case 'x':
+ case 'o':
+ case 'b':
+ if (this->WriteNumber(0, cpy_jump_label))
+ goto asm_end_label_cpy;
+
+ break;
+ default:
+ break;
+ }
+
+ if (isdigit(cpy_jump_label[0]))
+ {
+ if (this->WriteNumber(0, cpy_jump_label))
+ goto asm_end_label_cpy;
+
+ break;
+ }
+ }
+ }
+
+ if (cpy_jump_label.size() < 1)
+ {
+ detail::print_error_asm("label is empty, can't jump on it.", file);
+ throw std::runtime_error("label_empty");
+ }
+
+ /// don't go any further if:
+ /// load word (ldw) or store word. (stw)
+
+ if (name == "ldw" || name == "stw")
+ break;
+
+ auto mld_reloc_str = std::to_string(cpy_jump_label.size());
+ mld_reloc_str += kUndefinedSymbol;
+ mld_reloc_str += cpy_jump_label;
+
+ bool ignore_back_slash = false;
+
+ for (auto& reloc_chr : mld_reloc_str)
+ {
+ if (reloc_chr == '\\')
+ {
+ ignore_back_slash = true;
+ continue;
+ }
+
+ if (ignore_back_slash)
+ {
+ ignore_back_slash = false;
+ continue;
+ }
+
+ kBytes.push_back(reloc_chr);
+ }
+
+ kBytes.push_back('\0');
+ goto asm_end_label_cpy;
+ }
+
+ asm_end_label_cpy:
+ kOrigin += c64x0IPAlignment;
+
+ break;
+ }
+ }
+
+ return true;
}
// Last rev 13-1-24
diff --git a/dev/ndkdll/Sources/AssemblerPower.cxx b/dev/ndkdll/Sources/AssemblerPower.cxx
index 365089a..c33157f 100644
--- a/dev/ndkdll/Sources/AssemblerPower.cxx
+++ b/dev/ndkdll/Sources/AssemblerPower.cxx
@@ -318,7 +318,7 @@ static bool asm_read_attributes(std::string& line)
if (kOutputAsBinary)
{
detail::print_error_asm("Invalid extern_segment directive in flat binary mode.",
- "power-as");
+ "power-as");
throw std::runtime_error("invalid_extern_segment_bin");
}
@@ -390,7 +390,7 @@ static bool asm_read_attributes(std::string& line)
if (kOutputAsBinary)
{
detail::print_error_asm("Invalid public_segment directive in flat binary mode.",
- "power-as");
+ "power-as");
throw std::runtime_error("invalid_public_segment_bin");
}
@@ -833,7 +833,7 @@ bool NDK::EncoderPowerPC::WriteLine(std::string& line,
if (reg_index > kAsmRegisterLimit)
{
detail::print_error_asm("invalid register index, r" + reg_str,
- file);
+ file);
throw std::runtime_error("invalid_register_index");
}
@@ -859,7 +859,7 @@ bool NDK::EncoderPowerPC::WriteLine(std::string& line,
if (num.number[i] > 0)
{
detail::print_warning_asm("number overflow on li operation.",
- file);
+ file);
break;
}
}
diff --git a/dev/ndkdll/Sources/CCompiler64x0.cxx b/dev/ndkdll/Sources/CCompiler64x0.cxx
index 5ea439d..9863a86 100644
--- a/dev/ndkdll/Sources/CCompiler64x0.cxx
+++ b/dev/ndkdll/Sources/CCompiler64x0.cxx
@@ -80,13 +80,13 @@ namespace detail
struct CompilerState final
{
std::vector<NDK::SyntaxLeafList> fSyntaxTreeList;
- std::vector<CompilerRegisterMap> kStackFrame;
- std::vector<CompilerStructMap> kStructMap;
- NDK::SyntaxLeafList* fSyntaxTree{nullptr};
- std::unique_ptr<std::ofstream> fOutputAssembly;
- std::string fLastFile;
- std::string fLastError;
- bool fVerbose;
+ std::vector<CompilerRegisterMap> kStackFrame;
+ std::vector<CompilerStructMap> kStructMap;
+ NDK::SyntaxLeafList* fSyntaxTree{nullptr};
+ std::unique_ptr<std::ofstream> fOutputAssembly;
+ std::string fLastFile;
+ std::string fLastError;
+ bool fVerbose;
};
} // namespace detail
@@ -132,20 +132,20 @@ static std::string kRegisterPrefix = kAsmRegisterPrefix;
/////////////////////////////////////////
-static std::vector<std::string> kFileList;
-static NDK::AssemblyFactory kFactory;
-static bool kInStruct = false;
-static bool kOnWhileLoop = false;
-static bool kOnForLoop = false;
-static bool kInBraces = false;
-static bool kIfFound = false;
-static size_t kBracesCount = 0UL;
+static std::vector<std::string> kFileList;
+static NDK::AssemblyFactory kFactory;
+static bool kInStruct = false;
+static bool kOnWhileLoop = false;
+static bool kOnForLoop = false;
+static bool kInBraces = false;
+static bool kIfFound = false;
+static size_t kBracesCount = 0UL;
/* @brief C compiler backend for C */
class CompilerBackend64x0 final : public NDK::CompilerBackend
{
public:
- explicit CompilerBackend64x0() = default;
+ explicit CompilerBackend64x0() = default;
~CompilerBackend64x0() override = default;
NDK_COPY_DEFAULT(CompilerBackend64x0);
@@ -159,7 +159,7 @@ public:
}
};
-static CompilerBackend64x0* kCompilerBackend = nullptr;
+static CompilerBackend64x0* kCompilerBackend = nullptr;
static std::vector<detail::CompilerType> kCompilerVariables;
static std::vector<std::string> kCompilerFunctions;
static std::vector<detail::CompilerType> kCompilerTypes;
@@ -404,7 +404,7 @@ bool CompilerBackend64x0::Compile(const std::string text, const std::string file
if (textBuffer[text_index] == '=' && kInStruct)
{
detail::print_error_asm("assignement of value in struct " + textBuffer,
- file);
+ file);
continue;
}
diff --git a/dev/ndkdll/Sources/CCompilerPower64.cxx b/dev/ndkdll/Sources/CCompilerPower64.cxx
index 5330ce6..80ae869 100644
--- a/dev/ndkdll/Sources/CCompilerPower64.cxx
+++ b/dev/ndkdll/Sources/CCompilerPower64.cxx
@@ -71,13 +71,13 @@ namespace detail
struct CompilerState final
{
std::vector<NDK::SyntaxLeafList> fSyntaxTreeList;
- std::vector<CompilerRegisterMap> kStackFrame;
- std::vector<CompilerStructMap> kStructMap;
- NDK::SyntaxLeafList* fSyntaxTree{nullptr};
- std::unique_ptr<std::ofstream> fOutputAssembly;
- std::string fLastFile;
- std::string fLastError;
- bool fVerbose;
+ std::vector<CompilerRegisterMap> kStackFrame;
+ std::vector<CompilerStructMap> kStructMap;
+ NDK::SyntaxLeafList* fSyntaxTree{nullptr};
+ std::unique_ptr<std::ofstream> fOutputAssembly;
+ std::string fLastFile;
+ std::string fLastError;
+ bool fVerbose;
};
} // namespace detail
@@ -123,20 +123,20 @@ static std::string kRegisterPrefix = kAsmRegisterPrefix;
/////////////////////////////////////////
-static std::vector<std::string> kFileList;
-static NDK::AssemblyFactory kFactory;
-static bool kInStruct = false;
-static bool kOnWhileLoop = false;
-static bool kOnForLoop = false;
-static bool kInBraces = false;
-static bool kIfFound = false;
-static size_t kBracesCount = 0UL;
+static std::vector<std::string> kFileList;
+static NDK::AssemblyFactory kFactory;
+static bool kInStruct = false;
+static bool kOnWhileLoop = false;
+static bool kOnForLoop = false;
+static bool kInBraces = false;
+static bool kIfFound = false;
+static size_t kBracesCount = 0UL;
/* @brief C compiler backend for C */
class CompilerBackendPower64 final : public NDK::CompilerBackend
{
public:
- explicit CompilerBackendPower64() = default;
+ explicit CompilerBackendPower64() = default;
~CompilerBackendPower64() override = default;
NDK_COPY_DEFAULT(CompilerBackendPower64);
diff --git a/dev/ndkdll/Sources/Linker.cxx b/dev/ndkdll/Sources/Linker.cxx
index c9a9184..386507e 100644
--- a/dev/ndkdll/Sources/Linker.cxx
+++ b/dev/ndkdll/Sources/Linker.cxx
@@ -54,10 +54,10 @@
enum
{
- eABIStart = 0x1010, /* Invalid ABI start of ABI list. */
- eABINewOS = 0x5046, /* PF (NewOSKrnl) */
- eABIMTL = 0x4650, /* FP (MTL firmware) */
- eABIInvalid = 1,
+ eABIStart = 0x1010, /* Invalid ABI start of ABI list. */
+ eABINewOS = 0x5046, /* PF (NewOSKrnl) */
+ eABIMTL = 0x4650, /* FP (MTL firmware) */
+ eABIInvalid = 1,
};
static std::string kOutput = "";
@@ -326,7 +326,7 @@ NDK_MODULE(ZKALinkerMain)
++ae_record_index)
{
NDK::PEFCommandHeader command_header{0};
- size_t offsetOfData = ae_records[ae_record_index].fOffset + ae_header.fSize;
+ size_t offsetOfData = ae_records[ae_record_index].fOffset + ae_header.fSize;
memcpy(command_header.Name, ae_records[ae_record_index].fName,
kPefNameLen);
@@ -563,12 +563,11 @@ NDK_MODULE(ZKALinkerMain)
commandHdrsList.push_back(abiHeader);
-
NDK::PEFCommandHeader stackHeader{0};
-
- stackHeader.Cpu = kArch;
- stackHeader.Flags = 0;
- stackHeader.Size = sizeof(uintptr_t);
+
+ stackHeader.Cpu = kArch;
+ stackHeader.Flags = 0;
+ stackHeader.Size = sizeof(uintptr_t);
stackHeader.Offset = (kMIBCount * 1024 * 1024);
memcpy(stackHeader.Name, kLinkerStackSizeSymbol, strlen(kLinkerStackSizeSymbol));
diff --git a/dev/ndkdll/Sources/String.cxx b/dev/ndkdll/Sources/String.cxx
index ccbd821..b7cfc2d 100644
--- a/dev/ndkdll/Sources/String.cxx
+++ b/dev/ndkdll/Sources/String.cxx
@@ -20,181 +20,236 @@
#include <ndkdll/NFC/String.hxx>
-namespace NDK {
-CharType *StringView::Data() { return m_Data; }
-
-const CharType *StringView::CData() const { return m_Data; }
-
-SizeType StringView::Length() const { return strlen(m_Data); }
-
-bool StringView::operator==(const StringView &rhs) const {
- if (rhs.Length() != Length()) return false;
-
- for (SizeType index = 0; index < Length(); ++index) {
- if (rhs.m_Data[index] != m_Data[index]) return false;
- }
-
- return true;
-}
-
-bool StringView::operator==(const CharType *rhs) const {
- if (string_length(rhs) != Length()) return false;
-
- for (SizeType index = 0; index < string_length(rhs); ++index) {
- if (rhs[index] != m_Data[index]) return false;
- }
-
- return true;
-}
-
-bool StringView::operator!=(const StringView &rhs) const {
- if (rhs.Length() != Length()) return false;
-
- for (SizeType index = 0; index < rhs.Length(); ++index) {
- if (rhs.m_Data[index] == m_Data[index]) return false;
- }
-
- return true;
-}
-
-bool StringView::operator!=(const CharType *rhs) const {
- if (string_length(rhs) != Length()) return false;
-
- for (SizeType index = 0; index < string_length(rhs); ++index) {
- if (rhs[index] == m_Data[index]) return false;
- }
-
- return true;
-}
-
-StringView StringBuilder::Construct(const CharType *data) {
- if (!data || *data == 0) return StringView(0);
-
- StringView view(strlen(data));
- view += data;
-
- return view;
-}
-
-const char *StringBuilder::FromInt(const char *fmt, int i) {
- if (!fmt) return ("-1");
-
- auto ret_len = 8 + string_length(fmt);
- char *ret = new char[ret_len];
-
- if (!ret) return ("-1");
-
- memset(ret, 0, ret_len);
-
- CharType result[8];
- if (!to_str(result, sizeof(int), i)) {
- delete[] ret;
- return ("-1");
- }
-
- const auto fmt_len = string_length(fmt);
- const auto res_len = string_length(result);
-
- for (SizeType idx = 0; idx < fmt_len; ++idx) {
- if (fmt[idx] == '%') {
- SizeType result_cnt = idx;
-
- for (auto y_idx = idx; y_idx < res_len; ++y_idx) {
- ret[result_cnt] = result[y_idx];
- ++result_cnt;
- }
-
- break;
- }
-
- ret[idx] = fmt[idx];
- }
-
- return ret; /* Copy that ret into a buffer, Alloca allocates to the stack */
-}
-
-const char *StringBuilder::FromBool(const char *fmt, bool i) {
- if (!fmt) return ("?");
-
- const char *boolean_expr = i ? "true" : "false";
- char *ret = new char[i ? 4 : 5 + string_length(fmt)];
-
- if (!ret) return ("?");
-
- const auto fmt_len = string_length(fmt);
- const auto res_len = string_length(boolean_expr);
-
- for (SizeType idx = 0; idx < fmt_len; ++idx) {
- if (fmt[idx] == '%') {
- SizeType result_cnt = idx;
-
- for (auto y_idx = idx; y_idx < res_len; ++y_idx) {
- ret[result_cnt] = boolean_expr[y_idx];
- ++result_cnt;
- }
-
- break;
- }
-
- ret[idx] = fmt[idx];
- }
-
- return ret;
-}
-
-bool StringBuilder::Equals(const char *lhs, const char *rhs) {
- if (string_length(rhs) != string_length(lhs)) return false;
-
- for (SizeType index = 0; index < string_length(rhs); ++index) {
- if (rhs[index] != lhs[index]) return false;
- }
-
- return true;
-}
-
-const char *StringBuilder::Format(const char *fmt, const char *fmtRight) {
- if (!fmt || !fmtRight) return ("?");
-
- char *ret = new char[string_length(fmtRight) + string_length(fmtRight)];
- if (!ret) return ("?");
-
- for (SizeType idx = 0; idx < string_length(fmt); ++idx) {
- if (fmt[idx] == '%') {
- SizeType result_cnt = idx;
-
- for (SizeType y_idx = 0; y_idx < string_length(fmtRight); ++y_idx) {
- ret[result_cnt] = fmtRight[y_idx];
- ++result_cnt;
- }
-
- break;
- }
-
- ret[idx] = fmt[idx];
- }
-
- return ret;
-}
-
-StringView &StringView::operator+=(const CharType *rhs) {
- if (strlen(rhs) > this->m_Sz) {
- throw std::runtime_error("out_of_bounds: StringView");
- }
-
- memcpy(this->m_Data + this->m_Cur, rhs, strlen(rhs));
- this->m_Cur += strlen(rhs);
-
- return *this;
-}
-
-StringView &StringView::operator+=(const StringView &rhs) {
- if (rhs.m_Cur > this->m_Sz) {
- throw std::runtime_error("out_of_bounds: StringView");
- }
-
- memcpy(this->m_Data + this->m_Cur, rhs.CData(), strlen(rhs.CData()));
- this->m_Cur += strlen(rhs.CData());
-
- return *this;
-}
-} // namespace NDK
+namespace NDK
+{
+ CharType* StringView::Data()
+ {
+ return m_Data;
+ }
+
+ const CharType* StringView::CData() const
+ {
+ return m_Data;
+ }
+
+ SizeType StringView::Length() const
+ {
+ return strlen(m_Data);
+ }
+
+ bool StringView::operator==(const StringView& rhs) const
+ {
+ if (rhs.Length() != Length())
+ return false;
+
+ for (SizeType index = 0; index < Length(); ++index)
+ {
+ if (rhs.m_Data[index] != m_Data[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ bool StringView::operator==(const CharType* rhs) const
+ {
+ if (string_length(rhs) != Length())
+ return false;
+
+ for (SizeType index = 0; index < string_length(rhs); ++index)
+ {
+ if (rhs[index] != m_Data[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ bool StringView::operator!=(const StringView& rhs) const
+ {
+ if (rhs.Length() != Length())
+ return false;
+
+ for (SizeType index = 0; index < rhs.Length(); ++index)
+ {
+ if (rhs.m_Data[index] == m_Data[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ bool StringView::operator!=(const CharType* rhs) const
+ {
+ if (string_length(rhs) != Length())
+ return false;
+
+ for (SizeType index = 0; index < string_length(rhs); ++index)
+ {
+ if (rhs[index] == m_Data[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ StringView StringBuilder::Construct(const CharType* data)
+ {
+ if (!data || *data == 0)
+ return StringView(0);
+
+ StringView view(strlen(data));
+ view += data;
+
+ return view;
+ }
+
+ const char* StringBuilder::FromInt(const char* fmt, int i)
+ {
+ if (!fmt)
+ return ("-1");
+
+ auto ret_len = 8 + string_length(fmt);
+ char* ret = new char[ret_len];
+
+ if (!ret)
+ return ("-1");
+
+ memset(ret, 0, ret_len);
+
+ CharType result[8];
+ if (!to_str(result, sizeof(int), i))
+ {
+ delete[] ret;
+ return ("-1");
+ }
+
+ const auto fmt_len = string_length(fmt);
+ const auto res_len = string_length(result);
+
+ for (SizeType idx = 0; idx < fmt_len; ++idx)
+ {
+ if (fmt[idx] == '%')
+ {
+ SizeType result_cnt = idx;
+
+ for (auto y_idx = idx; y_idx < res_len; ++y_idx)
+ {
+ ret[result_cnt] = result[y_idx];
+ ++result_cnt;
+ }
+
+ break;
+ }
+
+ ret[idx] = fmt[idx];
+ }
+
+ return ret; /* Copy that ret into a buffer, Alloca allocates to the stack */
+ }
+
+ const char* StringBuilder::FromBool(const char* fmt, bool i)
+ {
+ if (!fmt)
+ return ("?");
+
+ const char* boolean_expr = i ? "true" : "false";
+ char* ret = new char[i ? 4 : 5 + string_length(fmt)];
+
+ if (!ret)
+ return ("?");
+
+ const auto fmt_len = string_length(fmt);
+ const auto res_len = string_length(boolean_expr);
+
+ for (SizeType idx = 0; idx < fmt_len; ++idx)
+ {
+ if (fmt[idx] == '%')
+ {
+ SizeType result_cnt = idx;
+
+ for (auto y_idx = idx; y_idx < res_len; ++y_idx)
+ {
+ ret[result_cnt] = boolean_expr[y_idx];
+ ++result_cnt;
+ }
+
+ break;
+ }
+
+ ret[idx] = fmt[idx];
+ }
+
+ return ret;
+ }
+
+ bool StringBuilder::Equals(const char* lhs, const char* rhs)
+ {
+ if (string_length(rhs) != string_length(lhs))
+ return false;
+
+ for (SizeType index = 0; index < string_length(rhs); ++index)
+ {
+ if (rhs[index] != lhs[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ const char* StringBuilder::Format(const char* fmt, const char* fmtRight)
+ {
+ if (!fmt || !fmtRight)
+ return ("?");
+
+ char* ret = new char[string_length(fmtRight) + string_length(fmtRight)];
+ if (!ret)
+ return ("?");
+
+ for (SizeType idx = 0; idx < string_length(fmt); ++idx)
+ {
+ if (fmt[idx] == '%')
+ {
+ SizeType result_cnt = idx;
+
+ for (SizeType y_idx = 0; y_idx < string_length(fmtRight); ++y_idx)
+ {
+ ret[result_cnt] = fmtRight[y_idx];
+ ++result_cnt;
+ }
+
+ break;
+ }
+
+ ret[idx] = fmt[idx];
+ }
+
+ return ret;
+ }
+
+ StringView& StringView::operator+=(const CharType* rhs)
+ {
+ if (strlen(rhs) > this->m_Sz)
+ {
+ throw std::runtime_error("out_of_bounds: StringView");
+ }
+
+ memcpy(this->m_Data + this->m_Cur, rhs, strlen(rhs));
+ this->m_Cur += strlen(rhs);
+
+ return *this;
+ }
+
+ StringView& StringView::operator+=(const StringView& rhs)
+ {
+ if (rhs.m_Cur > this->m_Sz)
+ {
+ throw std::runtime_error("out_of_bounds: StringView");
+ }
+
+ memcpy(this->m_Data + this->m_Cur, rhs.CData(), strlen(rhs.CData()));
+ this->m_Cur += strlen(rhs.CData());
+
+ return *this;
+ }
+} // namespace NDK