This commit is contained in:
xolatile 2024-07-16 11:14:46 -04:00
commit 995bb4ce4b
7 changed files with 133 additions and 89 deletions

View File

@ -2,6 +2,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <sys/stat.h>
#include "eaxhla.h"
@ -14,16 +15,26 @@ unsigned int token_count = 0;
char * output_file_name = "a.out";
int compile_init(void) {
token_array = calloc (1440UL, sizeof (* token_array));
return 0;
}
int compile_deinit(void) {
free(token_array);
return 0;
}
static
void dump_variable_to_assembler(void * data) {
variable_t * variable = (variable_t*)data;
append_instruction_t4(ASMDIRMEM, variable->_id, ASMDIRIMM, type2size(variable->type));
append_instruction_t1(variable->elements);
append_instructions(ASMDIRMEM, variable->_id, ASMDIRIMM, type2size(variable->type));
append_instructions(variable->elements);
if (variable->elements == 1) {
append_instruction_t1(variable->value);
append_instructions(variable->value);
} else {
for (unsigned long long i = 0; i < variable->elements; i++) {
append_instruction_t1((int)*((char*)(variable->array_value + i)));
append_instructions((int)*((char*)(variable->array_value + i)));
}
}
}
@ -75,37 +86,21 @@ int compile(void) {
return 0;
}
static
void append_token (int t) {
// XXX rewrite this and use memcpy
token_array [token_count] = t;
void _append_instructions(unsigned argc, ...) {
va_list ap;
va_start(ap, argc);
for (unsigned i = 0; i < argc; i++) {
token_array [token_count] = va_arg(ap, int);
token_count += 1;
}
void append_instruction_t1 (int t1) {
append_token (t1); // operation
}
void append_instruction_t4 (int t4, int w, int d, int r) {
append_token (t4); // operation
append_token (w); // width
append_token (d); // destination
append_token (r); // register
}
void append_instruction_t6 (int t6, int w, int d, int r, int s, int i) {
append_token (t6); // operation
append_token (w); // width
append_token (d); // destination
append_token (r); // register
append_token (s); // source
append_token (i); // immediate
va_end(ap);
}
// my_label:
void append_label (int rel) {
append_instruction_t1 (ASMDIRMEM);
append_instruction_t1 (rel);
append_instructions(ASMDIRMEM, rel);
}
// procedure my_procedure ... <argv> ... begin
@ -120,7 +115,7 @@ void append_fastcall_begin (int rel) {
// end procedure
void append_fastcall_end (void) {
append_instruction_t1 (RETN);
append_instructions(RETN);
}
// append these at the end, postpone it!
@ -128,9 +123,5 @@ void append_fastcall_end (void) {
// it has to do with structure of every binary executable file!
// we can add it later, it's "triggered" on 'in'.
void append_fastcall_arguments (int rel, int wid, int imm) { // TODO
append_instruction_t1 (ASMDIRMEM);
append_instruction_t1 (rel);
append_instruction_t1 (ASMDIRIMM);
append_instruction_t1 (wid);
append_instruction_t1 (imm);
append_instructions(ASMDIRMEM, rel, ASMDIRIMM, wid, imm);
}

View File

@ -6,11 +6,10 @@ extern unsigned int token_count;
extern char * output_file_name;
extern int compile(void);
extern int compile_init(void);
extern int compile_deinit(void);
extern void append_instruction_t1 (int t1);
extern void append_instruction_t4 (int t4, int w, int d, int r);
extern void append_instruction_t6 (int t6, int w, int d, int r, int s, int i);
extern int compile(void);
extern void append_label (int rel);
@ -18,4 +17,55 @@ extern void append_fastcall_begin (int rel);
extern void append_fastcall_end (void);
extern void append_fastcall_arguments (int rel, int wid, int imm);
/* --- Token appending
* The core problem is that we want an interface where we can append {instructoin}
* tokens without modifying the counter as that gets old fast and error prone
* when doing batches.
* Many tokens are enumerated so we have to push them individually.
* A variadic argument interface would be ideal except theres not free
* value to use as a termination and i dont need to tell you why passing the count
* by hand is a terrible idea.
* Enter macro magick, the below horror beyond your comprehension will count
* the arguments and pass them explicitly, in an implicit way.
* Now:
* append_instructions(...);
* Is valid and human error resistant.
*/
#define PP_NARG(...) \
PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
#define PP_NARG_(...) \
PP_128TH_ARG(__VA_ARGS__)
#define PP_128TH_ARG( \
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
_61,_62,_63,_64,_65,_66,_67,_68,_69,_70, \
_71,_72,_73,_74,_75,_76,_77,_78,_79,_80, \
_81,_82,_83,_84,_85,_86,_87,_88,_89,_90, \
_91,_92,_93,_94,_95,_96,_97,_98,_99,_100, \
_101,_102,_103,_104,_105,_106,_107,_108,_109,_110, \
_111,_112,_113,_114,_115,_116,_117,_118,_119,_120, \
_121,_122,_123,_124,_125,_126,_127,N,...) N
#define PP_RSEQ_N() \
127,126,125,124,123,122,121,120, \
119,118,117,116,115,114,113,112,111,110, \
109,108,107,106,105,104,103,102,101,100, \
99,98,97,96,95,94,93,92,91,90, \
89,88,87,86,85,84,83,82,81,80, \
79,78,77,76,75,74,73,72,71,70, \
69,68,67,66,65,64,63,62,61,60, \
59,58,57,56,55,54,53,52,51,50, \
49,48,47,46,45,44,43,42,41,40, \
39,38,37,36,35,34,33,32,31,30, \
29,28,27,26,25,24,23,22,21,20, \
19,18,17,16,15,14,13,12,11,10, \
9,8,7,6,5,4,3,2,1,0
void _append_instructions(unsigned argc, ...);
#define append_instructions(...) _append_instructions(PP_NARG(__VA_ARGS__), __VA_ARGS__)
#endif

View File

@ -40,7 +40,7 @@ void free_variable(void * data) {
free(variable);
}
int eaxhla_destroy(void) {
int eaxhla_deinit(void) {
tommy_hashtable_foreach(&variable_table, free_variable);
tommy_hashtable_done(&variable_table);
return 0;

View File

@ -37,7 +37,7 @@ extern char * scope;
extern char * yyfilename;
extern int eaxhla_init(void);
extern int eaxhla_destroy(void);
extern int eaxhla_deinit(void);
extern char * make_scoped_name(const char * const scope, char * name);
extern int can_fit(int type, long long value);

View File

@ -418,45 +418,45 @@ library_code: %empty
;
*/
instruction: INOP { append_instruction_t1(NOP); }
instruction: INOP { append_instructions(NOP); }
// #placeholder<instruction_parser_rules> BEGIN
| ITSYSCALL { append_instruction_t1(SYSCALL); }
| ITSYSRET { append_instruction_t1(SYSRET); }
| ITSYSEXIT { append_instruction_t1(SYSEXIT); }
| ITSYSENTER { append_instruction_t1(SYSENTER); }
| ITLEAVE { append_instruction_t1(LEAVE); }
| ITRETF { append_instruction_t1(RETF); }
| ITRETN { append_instruction_t1(RETN); }
| ITPAUSE { append_instruction_t1(PAUSE); }
| ITHLT { append_instruction_t1(HLT); }
| ITLOCK { append_instruction_t1(LOCK); }
| ITINC register { append_instruction_t4( INC, $2.size, REG, $2.number ); }
| ITDEC register { append_instruction_t4( DEC, $2.size, REG, $2.number ); }
| ITNOT register { append_instruction_t4( NOT, $2.size, REG, $2.number ); }
| ITNEG register { append_instruction_t4( NEG, $2.size, REG, $2.number ); }
| ITMUL register { append_instruction_t4( MUL, $2.size, REG, $2.number ); }
| ITIMUL register { append_instruction_t4( IMUL, $2.size, REG, $2.number ); }
| ITDIV register { append_instruction_t4( DIV, $2.size, REG, $2.number ); }
| ITIDIV register { append_instruction_t4( IDIV, $2.size, REG, $2.number ); }
| ITINC memory { append_instruction_t4( INC, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITDEC memory { append_instruction_t4( DEC, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITNOT memory { append_instruction_t4( NOT, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITNEG memory { append_instruction_t4( NEG, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITMUL memory { append_instruction_t4( MUL, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITIMUL memory { append_instruction_t4( IMUL, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITDIV memory { append_instruction_t4( DIV, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITIDIV memory { append_instruction_t4( IDIV, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITADD register register { append_instruction_t6( ADD, $2.size, REG, $2.number, REG, $3.number ); }
| ITOR register register { append_instruction_t6( OR, $2.size, REG, $2.number, REG, $3.number ); }
| ITADC register register { append_instruction_t6( ADC, $2.size, REG, $2.number, REG, $3.number ); }
| ITSBB register register { append_instruction_t6( SBB, $2.size, REG, $2.number, REG, $3.number ); }
| ITAND register register { append_instruction_t6( AND, $2.size, REG, $2.number, REG, $3.number ); }
| ITSUB register register { append_instruction_t6( SUB, $2.size, REG, $2.number, REG, $3.number ); }
| ITXOR register register { append_instruction_t6( XOR, $2.size, REG, $2.number, REG, $3.number ); }
| ITCMP register register { append_instruction_t6( CMP, $2.size, REG, $2.number, REG, $3.number ); }
| ITSAR register immediate { append_instruction_t6( SAR, $2.size, REG, $2.number, $3.type, $3.value ); }
| ITMOV register register { append_instruction_t6( MOV, $2.size, REG, $2.number, REG, $3.number ); }
| ITMOV register immediate { append_instruction_t6( MOV, $2.size, REG, $2.number, $3.type, $3.value ); }
| ITSYSCALL { append_instructions(SYSCALL); }
| ITSYSRET { append_instructions(SYSRET); }
| ITSYSEXIT { append_instructions(SYSEXIT); }
| ITSYSENTER { append_instructions(SYSENTER); }
| ITLEAVE { append_instructions(LEAVE); }
| ITRETF { append_instructions(RETF); }
| ITRETN { append_instructions(RETN); }
| ITPAUSE { append_instructions(PAUSE); }
| ITHLT { append_instructions(HLT); }
| ITLOCK { append_instructions(LOCK); }
| ITINC register { append_instructions( INC, $2.size, REG, $2.number ); }
| ITDEC register { append_instructions( DEC, $2.size, REG, $2.number ); }
| ITNOT register { append_instructions( NOT, $2.size, REG, $2.number ); }
| ITNEG register { append_instructions( NEG, $2.size, REG, $2.number ); }
| ITMUL register { append_instructions( MUL, $2.size, REG, $2.number ); }
| ITIMUL register { append_instructions( IMUL, $2.size, REG, $2.number ); }
| ITDIV register { append_instructions( DIV, $2.size, REG, $2.number ); }
| ITIDIV register { append_instructions( IDIV, $2.size, REG, $2.number ); }
| ITINC memory { append_instructions( INC, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITDEC memory { append_instructions( DEC, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITNOT memory { append_instructions( NOT, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITNEG memory { append_instructions( NEG, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITMUL memory { append_instructions( MUL, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITIMUL memory { append_instructions( IMUL, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITDIV memory { append_instructions( DIV, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITIDIV memory { append_instructions( IDIV, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITADD register register { append_instructions( ADD, $2.size, REG, $2.number, REG, $3.number ); }
| ITOR register register { append_instructions( OR, $2.size, REG, $2.number, REG, $3.number ); }
| ITADC register register { append_instructions( ADC, $2.size, REG, $2.number, REG, $3.number ); }
| ITSBB register register { append_instructions( SBB, $2.size, REG, $2.number, REG, $3.number ); }
| ITAND register register { append_instructions( AND, $2.size, REG, $2.number, REG, $3.number ); }
| ITSUB register register { append_instructions( SUB, $2.size, REG, $2.number, REG, $3.number ); }
| ITXOR register register { append_instructions( XOR, $2.size, REG, $2.number, REG, $3.number ); }
| ITCMP register register { append_instructions( CMP, $2.size, REG, $2.number, REG, $3.number ); }
| ITSAR register immediate { append_instructions( SAR, $2.size, REG, $2.number, $3.type, $3.value ); }
| ITMOV register register { append_instructions( MOV, $2.size, REG, $2.number, REG, $3.number ); }
| ITMOV register immediate { append_instructions( MOV, $2.size, REG, $2.number, $3.type, $3.value ); }
// #placeholder<instruction_parser_rules> END
;

View File

@ -8,14 +8,19 @@
#include "assembler.h"
#include "debug.h"
int init(void) {
eaxhla_init();
compile_init();
return 0;
}
void deinit(void) {
extern void yyfree_leftovers(void);
yyfree_leftovers();
eaxhla_destroy();
free (token_array);
eaxhla_deinit();
compile_deinit();
}
signed main(int argc, char * argv[]) {
@ -24,8 +29,6 @@ signed main(int argc, char * argv[]) {
return 1;
}
token_array = calloc (1440UL, sizeof (* token_array));
#if DEBUG == 1
yydebug = 1;
#endif
@ -34,7 +37,7 @@ signed main(int argc, char * argv[]) {
yyin = fopen(yyfilename, "r");
if (eaxhla_init()) {
if (init()) {
puts("Initialization failed");
return 1;
}

View File

@ -26,13 +26,13 @@ proc make_parser_rules {is} {
}
proc make_parser_rule {i} {
if {[llength $i] == 1} {
set rule [format " | IT%s { append_instruction_t1(%s); }" \
set rule [format " | IT%s { append_instructions(%s); }" \
[string toupper [lindex $i 0]] \
[string toupper [lindex $i 0]] \
]
} elseif {[llength $i] == 2} {
set arg [init_iarg [lindex $i 1] 2]
set rule [format " | IT%s %s \{ append_instruction_t4(\
set rule [format " | IT%s %s \{ append_instructions(\
%s,\
%s,\
%s,\
@ -49,7 +49,7 @@ proc make_parser_rules {is} {
} elseif {[llength $i] == 3} {
set arg1 [init_iarg [lindex $i 1] 2]
set arg2 [init_iarg [lindex $i 2] 3]
set rule [format " | IT%s %s %s \{ append_instruction_t6(\
set rule [format " | IT%s %s %s \{ append_instructions(\
%s,\
%s,\
%s,\