From 48e2061aaad33a948c53241b3d11bc40e3b9f497 Mon Sep 17 00:00:00 2001
From: xolatile <xolatile@proton.me>
Date: Thu, 4 Jul 2024 10:18:04 -0400
Subject: [PATCH] New special instruction building...

---
 documentation/main_test.c |  10 ++-
 source/assembler.c        | 153 +++++++++-----------------------------
 source/assembler.h        |   9 ++-
 3 files changed, 45 insertions(+), 127 deletions(-)

diff --git a/documentation/main_test.c b/documentation/main_test.c
index f1ce0db..6695f5b 100644
--- a/documentation/main_test.c
+++ b/documentation/main_test.c
@@ -9,10 +9,12 @@ int main (void) {
 
 	output_array = malloc (144UL * sizeof (* output_array));
 
-	assemble (ADC, D64, REG, R1, REG, R2);
-	assemble (ADC, D32, REG, R1, MEM, 12);
-	assemble (ADC, D16, MEM, 12, REG, R10);
-	assemble (ADC, D8, REG, R3, IMM, 0X77);
+	build_regular (ADC, D64, REG, R1, REG, R2);
+	build_regular (ADC, D32, REG, R1, MEM, 12);
+	build_regular (ADC, D16, MEM, 12, REG, R10);
+	build_regular (ADC, D8, REG, R3, IMM, 0X77);
+	build_special_1 (LOCK);
+	build_special_2 (PAUSE);
 
 	for (index = 0; index < output_count; ++index) {
 		printf ("%02X \n", output_array [index]);
diff --git a/source/assembler.c b/source/assembler.c
index 50ed57c..4a9bda1 100644
--- a/source/assembler.c
+++ b/source/assembler.c
@@ -19,6 +19,15 @@ splint assembler.h:
 	-- no warnings at all.
 */
 
+#define REGULAR_START   (ADD)
+#define REGULAR_COUNT   (UMUL - REGULAR_START)
+#define IRREGULAR_START (UMUL)
+#define IRREGULAR_COUNT (NOP - IRREGULAR_START)
+#define SPECIAL_1_START (NOP)
+#define SPECIAL_1_COUNT (SYSENTER - SPECIAL_1_START)
+#define SPECIAL_2_START (SYSENTER)
+#define SPECIAL_2_COUNT (ENTER - SPECIAL_2_START)
+
 typedef signed   int  form;
 typedef unsigned int  next;
 typedef unsigned char byte;
@@ -56,7 +65,7 @@ static void build_long_prefix (form       when,
 
 static void build_register_direction (form when,
                                       form destination,
-                                      form source) {
+                                      form source) { /* LENGTH */
 	place (when, (byte) (0XC0 + 0X01 * (destination % 8) + 0X08 * (source % 8)));
 }
 
@@ -84,124 +93,12 @@ static void build_regular_instruction (form       when,
 	      + 0XC0 * ((from == IMM) && (to == REG))));
 }
 
-/* EXPERIMENTAL CODE */
-
-//~static void add      (void) { place (0XFF); } /* REGULAR */
-//~static void or       (void) { place (0XFF); }
-//~static void adc      (void) { place (0XFF); }
-//~static void sbb      (void) { place (0XFF); }
-//~static void and      (void) { place (0XFF); }
-//~static void sub      (void) { place (0XFF); }
-//~static void xor      (void) { place (0XFF); }
-//~static void cmp      (void) { place (0XFF); }
-//~static void umul     (void) { place (0XFF); } /* IRREGULAR */
-//~static void udiv     (void) { place (0XFF); } /* STDLIB CANCER FIX */
-//~static void imul     (void) { place (0XFF); }
-//~static void idiv     (void) { place (0XFF); }
-//~static void inc      (void) { place (0XFF); }
-//~static void dec      (void) { place (0XFF); }
-//~static void not      (void) { place (0XFF); }
-//~static void neg      (void) { place (0XFF); }
-
-//~static void enter (form dynamic_storage,
-                   //~form nesting_level) {
-	//~place (0XC8);
-	//~place ((byte) (dynamic_storage /   1) % 256); /* FIX LATER */
-	//~place ((byte) (dynamic_storage / 256) % 256);
-	//~place ((byte) (nesting_level   /   1) % 256);
-//~}
-
-//~static void leave (void) {
-	//~place (0XC9);
-//~}
-
-//~static void call     (void) { place (0XFF); }
-//~static void ret      (void) { place (0XC3); } /* NEAR, NOT FAR (INTERSEGMENT) */
-//~static void sysenter (void) { place (0X0F); place (0X34); }
-//~static void sysexit  (void) { place (0X0F); place (0X35); }
-//~static void syscall  (void) { place (0X0F); place (0X05); }
-//~static void sysret   (void) { place (0X0F); place (0X07); }
-//~static void jmp      (void) { place (0XFF); }
-//~static void jpe      (void) { place (0XFF); }
-//~static void js       (void) { place (0XFF); }
-//~static void jpo      (void) { place (0XFF); }
-//~static void je       (void) { place (0XFF); }
-//~static void jne      (void) { place (0XFF); }
-//~static void jz       (void) { place (0XFF); }
-//~static void jnz      (void) { place (0XFF); }
-//~static void ja       (void) { place (0XFF); }
-//~static void jna      (void) { place (0XFF); }
-//~static void jb       (void) { place (0XFF); }
-//~static void jnb      (void) { place (0XFF); }
-//~static void mov      (void) { place (0XFF); } /* EXTEND */
-//~static void cmovpe   (void) { place (0XFF); }
-//~static void cmovs    (void) { place (0XFF); }
-//~static void cmovpo   (void) { place (0XFF); }
-//~static void cmove    (void) { place (0XFF); }
-//~static void cmovne   (void) { place (0XFF); }
-//~static void cmovz    (void) { place (0XFF); }
-//~static void cmovnz   (void) { place (0XFF); }
-//~static void cmova    (void) { place (0XFF); }
-//~static void cmovna   (void) { place (0XFF); }
-//~static void cmovb    (void) { place (0XFF); }
-//~static void cmovnb   (void) { place (0XFF); }
-//~static void lock     (void) { place (0XF0); }
-//~static void hlt      (void) { place (0XF4); }
-//~static void in       (void) { place (0XFF); }
-//~static void out      (void) { place (0XFF); }
-//~static void push     (void) { place (0XFF); }
-//~static void pop      (void) { place (0XFF); }
-//~static void bswap    (void) { place (0XFF); }
-//~static void test     (void) { place (0XFF); }
-//~static void rcl      (void) { place (0XFF); }
-//~static void rcr      (void) { place (0XFF); }
-//~static void rol      (void) { place (0XFF); }
-//~static void ror      (void) { place (0XFF); }
-//~static void shl      (void) { place (0XFF); }
-//~static void shr      (void) { place (0XFF); }
-//~static void sal      (void) { place (0XFF); }
-//~static void sar      (void) { place (0XFF); }
-//~static void rep      (void) { place (0XFF); }
-//~static void repe     (void) { place (0XFF); }
-//~static void repne    (void) { place (0XFF); }
-//~static void repz     (void) { place (0XFF); }
-//~static void loop     (void) { place (0XFF); }
-//~static void loope    (void) { place (0XFF); }
-//~static void loopne   (void) { place (0XFF); }
-//~static void pause    (void) { place (0XF3); place (0X90); }
-//~static void xadd     (void) { place (0XFF); }
-//~static void xchg     (void) { place (0XFF); }
-//~static void lea      (void) { place (0XFF); }
-//~static void popcnt   (void) { place (0XFF); }
-//~static void inti     (void) { place (0XFF); }
-//~static void bsf      (void) { place (0XFF); }
-//~static void bsr      (void) { place (0XFF); }
-//~static void bound    (void) { place (0XFF); }
-//~static void fadd     (void) { place (0XFF); }
-//~static void fsub     (void) { place (0XFF); }
-//~static void fmul     (void) { place (0XFF); }
-//~static void fdiv     (void) { place (0XFF); }
-//~static void fnop     (void) { place (0XFF); }
-//~static void fxam     (void) { place (0XFF); }
-//~static void fabs     (void) { place (0XFF); }
-//~static void fscale   (void) { place (0XFF); }
-//~static void fsin     (void) { place (0XFF); }
-//~static void fcos     (void) { place (0XFF); }
-//~static void fsqrt    (void) { place (0XFF); }
-//~static void fchs     (void) { place (0XFF); }
-//~static void fxch     (void) { place (0XFF); }
-//~static void frem     (void) { place (0XFF); }
-//~static void fldpi    (void) { place (0XFF); }
-//~static void fldz     (void) { place (0XFF); }
-//~static void cpuid    (void) { place (0X0F); place (0XA2); }
-//~static void movbe    (void) { place (0XFF); } /* [48]0F38[F0-RM/F1-MR][05+8R] */
-
-static void assemble (operation_index operation,
-                      size_index      size,
-                      type_index      to,
-                      form            destination,
-                      type_index      from,
-                      form            source) {
+static void build_regular (operation_index operation,
+                           size_index      size,
+                           type_index      to,
+                           form            destination,
+                           type_index      from,
+                           form            source) {
 	build_short_prefix (size == D16);
 
 	build_long_prefix ((size == D64)
@@ -220,3 +117,21 @@ static void assemble (operation_index operation,
 	build_register_redirection ((to == REG) && (from == MEM), destination);
 	build_register_redirection ((to == MEM) && (from == REG), source);
 }
+
+static void build_special_1 (operation_index operation) {
+	const byte data [1 * SPECIAL_1_COUNT] = {
+		0X90, 0XC3, 0XCB, 0XC9, 0XF0, 0XF4
+	};
+
+	place (1, data [operation - SPECIAL_1_START]);
+}
+
+static void build_special_2 (operation_index operation) {
+	const byte data [2 * SPECIAL_2_COUNT] = {
+		0X0F, 0X0F, 0X0F, 0X0F, 0XF3, 0X0F,
+		0X34, 0X35, 0X05, 0X07, 0X90, 0XA2
+	};
+
+	place (1, data [operation - SPECIAL_2_START]);
+	place (1, data [operation - SPECIAL_2_START + SPECIAL_2_COUNT]);
+}
diff --git a/source/assembler.h b/source/assembler.h
index d9ed11c..a19cabc 100644
--- a/source/assembler.h
+++ b/source/assembler.h
@@ -14,27 +14,28 @@ typedef enum {
 	AND,              SUB,              XOR,              CMP,
 	UMUL,             UDIV,             IMUL,             IDIV,
 	INC,              DEC,              NOT,              NEG,
-	ENTER,            LEAVE,            CALL,             RET,
+	NOP,              RETN,             RETF,             LEAVE,
+	LOCK,             HLT,
 	SYSENTER,         SYSEXIT,          SYSCALL,          SYSRET,
+	PAUSE,            CPUID,
+	ENTER,            CALL,             IN,               OUT,
 	JMP,              JPE,              JS,               JPO,
 	JE,               JNE,              JZ,               JNZ,
 	JA,               JNA,              JB,               JNB,
 	MOV,              CMOVPE,           CMOVS,            CMOVPO,
 	CMOVE,            CMOVNE,           CMOVZ,            CMOVNZ,
 	CMOVA,            CMOVNA,           CMOVB,            CMOVNB,
-	LOCK,             HLT,              IN,               OUT,
 	PUSH,             POP,              BSWAP,            TEST,
 	RCL,              RCR,              ROL,              ROR,
 	SHL,              SHR,              SAL,              SAR,
 	REP,              REPE,             REPNE,            REPZ,
-	LOOP,             LOOPE,            LOOPNE,           PAUSE,
+	LOOP,             LOOPE,            LOOPNE,           MOVBE,
 	XADD,             XCHG,             LEA,              POPCNT,
 	INTI,             BSF,              BSR,              BOUND,
 	FADD,             FSUB,             FMUL,             FDIV,
 	FNOP,             FXAM,             FABS,             FSCALE,
 	FSIN,             FCOS,             FSQRT,            FCHS,
 	FXCH,             FREM,             FLDPI,            FLDZ,
-	CPUID,            MOVBE,
 } operation_index;
 
 typedef enum {