refactoring

This commit is contained in:
anon
2024-07-16 17:11:31 +02:00
parent 88d8c1baca
commit 6fd63037a6
7 changed files with 133 additions and 89 deletions

View File

@ -2,6 +2,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h>
#include <sys/stat.h> #include <sys/stat.h>
#include "eaxhla.h" #include "eaxhla.h"
@ -14,16 +15,26 @@ unsigned int token_count = 0;
char * output_file_name = "a.out"; 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 static
void dump_variable_to_assembler(void * data) { void dump_variable_to_assembler(void * data) {
variable_t * variable = (variable_t*)data; variable_t * variable = (variable_t*)data;
append_instruction_t4(ASMDIRMEM, variable->_id, ASMDIRIMM, type2size(variable->type)); append_instructions(ASMDIRMEM, variable->_id, ASMDIRIMM, type2size(variable->type));
append_instruction_t1(variable->elements); append_instructions(variable->elements);
if (variable->elements == 1) { if (variable->elements == 1) {
append_instruction_t1(variable->value); append_instructions(variable->value);
} else { } else {
for (unsigned long long i = 0; i < variable->elements; i++) { 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; return 0;
} }
static void _append_instructions(unsigned argc, ...) {
void append_token (int t) { va_list ap;
// XXX rewrite this and use memcpy va_start(ap, argc);
token_array [token_count] = t;
token_count += 1;
}
void append_instruction_t1 (int t1) { for (unsigned i = 0; i < argc; i++) {
append_token (t1); // operation token_array [token_count] = va_arg(ap, int);
} token_count += 1;
}
void append_instruction_t4 (int t4, int w, int d, int r) { va_end(ap);
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
} }
// my_label: // my_label:
void append_label (int rel) { void append_label (int rel) {
append_instruction_t1 (ASMDIRMEM); append_instructions(ASMDIRMEM, rel);
append_instruction_t1 (rel);
} }
// procedure my_procedure ... <argv> ... begin // procedure my_procedure ... <argv> ... begin
@ -115,12 +110,12 @@ void append_label (int rel) {
// optimally, it should be number 0 ... 140. // optimally, it should be number 0 ... 140.
// for now, 140 procedures is enough, will expand later! // for now, 140 procedures is enough, will expand later!
void append_fastcall_begin (int rel) { void append_fastcall_begin (int rel) {
append_label (rel); append_label(rel);
} }
// end procedure // end procedure
void append_fastcall_end (void) { void append_fastcall_end (void) {
append_instruction_t1 (RETN); append_instructions(RETN);
} }
// append these at the end, postpone it! // 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! // it has to do with structure of every binary executable file!
// we can add it later, it's "triggered" on 'in'. // we can add it later, it's "triggered" on 'in'.
void append_fastcall_arguments (int rel, int wid, int imm) { // TODO void append_fastcall_arguments (int rel, int wid, int imm) { // TODO
append_instruction_t1 (ASMDIRMEM); append_instructions(ASMDIRMEM, rel, ASMDIRIMM, wid, imm);
append_instruction_t1 (rel);
append_instruction_t1 (ASMDIRIMM);
append_instruction_t1 (wid);
append_instruction_t1 (imm);
} }

View File

@ -6,11 +6,10 @@ extern unsigned int token_count;
extern char * output_file_name; 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 int compile(void);
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 void append_label (int rel); 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_end (void);
extern void append_fastcall_arguments (int rel, int wid, int imm); 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 #endif

View File

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

View File

@ -37,7 +37,7 @@ extern char * scope;
extern char * yyfilename; extern char * yyfilename;
extern int eaxhla_init(void); 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 char * make_scoped_name(const char * const scope, char * name);
extern int can_fit(int type, long long value); 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 // #placeholder<instruction_parser_rules> BEGIN
| ITSYSCALL { append_instruction_t1(SYSCALL); } | ITSYSCALL { append_instructions(SYSCALL); }
| ITSYSRET { append_instruction_t1(SYSRET); } | ITSYSRET { append_instructions(SYSRET); }
| ITSYSEXIT { append_instruction_t1(SYSEXIT); } | ITSYSEXIT { append_instructions(SYSEXIT); }
| ITSYSENTER { append_instruction_t1(SYSENTER); } | ITSYSENTER { append_instructions(SYSENTER); }
| ITLEAVE { append_instruction_t1(LEAVE); } | ITLEAVE { append_instructions(LEAVE); }
| ITRETF { append_instruction_t1(RETF); } | ITRETF { append_instructions(RETF); }
| ITRETN { append_instruction_t1(RETN); } | ITRETN { append_instructions(RETN); }
| ITPAUSE { append_instruction_t1(PAUSE); } | ITPAUSE { append_instructions(PAUSE); }
| ITHLT { append_instruction_t1(HLT); } | ITHLT { append_instructions(HLT); }
| ITLOCK { append_instruction_t1(LOCK); } | ITLOCK { append_instructions(LOCK); }
| ITINC register { append_instruction_t4( INC, $2.size, REG, $2.number ); } | ITINC register { append_instructions( INC, $2.size, REG, $2.number ); }
| ITDEC register { append_instruction_t4( DEC, $2.size, REG, $2.number ); } | ITDEC register { append_instructions( DEC, $2.size, REG, $2.number ); }
| ITNOT register { append_instruction_t4( NOT, $2.size, REG, $2.number ); } | ITNOT register { append_instructions( NOT, $2.size, REG, $2.number ); }
| ITNEG register { append_instruction_t4( NEG, $2.size, REG, $2.number ); } | ITNEG register { append_instructions( NEG, $2.size, REG, $2.number ); }
| ITMUL register { append_instruction_t4( MUL, $2.size, REG, $2.number ); } | ITMUL register { append_instructions( MUL, $2.size, REG, $2.number ); }
| ITIMUL register { append_instruction_t4( IMUL, $2.size, REG, $2.number ); } | ITIMUL register { append_instructions( IMUL, $2.size, REG, $2.number ); }
| ITDIV register { append_instruction_t4( DIV, $2.size, REG, $2.number ); } | ITDIV register { append_instructions( DIV, $2.size, REG, $2.number ); }
| ITIDIV register { append_instruction_t4( IDIV, $2.size, REG, $2.number ); } | ITIDIV register { append_instructions( IDIV, $2.size, REG, $2.number ); }
| ITINC memory { append_instruction_t4( INC, 0 /* ??? */, MEM, 0 /* ??? */ ); } | ITINC memory { append_instructions( INC, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITDEC memory { append_instruction_t4( DEC, 0 /* ??? */, MEM, 0 /* ??? */ ); } | ITDEC memory { append_instructions( DEC, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITNOT memory { append_instruction_t4( NOT, 0 /* ??? */, MEM, 0 /* ??? */ ); } | ITNOT memory { append_instructions( NOT, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITNEG memory { append_instruction_t4( NEG, 0 /* ??? */, MEM, 0 /* ??? */ ); } | ITNEG memory { append_instructions( NEG, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITMUL memory { append_instruction_t4( MUL, 0 /* ??? */, MEM, 0 /* ??? */ ); } | ITMUL memory { append_instructions( MUL, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITIMUL memory { append_instruction_t4( IMUL, 0 /* ??? */, MEM, 0 /* ??? */ ); } | ITIMUL memory { append_instructions( IMUL, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITDIV memory { append_instruction_t4( DIV, 0 /* ??? */, MEM, 0 /* ??? */ ); } | ITDIV memory { append_instructions( DIV, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITIDIV memory { append_instruction_t4( IDIV, 0 /* ??? */, MEM, 0 /* ??? */ ); } | ITIDIV memory { append_instructions( IDIV, 0 /* ??? */, MEM, 0 /* ??? */ ); }
| ITADD register register { append_instruction_t6( ADD, $2.size, REG, $2.number, REG, $3.number ); } | ITADD register register { append_instructions( ADD, $2.size, REG, $2.number, REG, $3.number ); }
| ITOR register register { append_instruction_t6( OR, $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_instruction_t6( ADC, $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_instruction_t6( SBB, $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_instruction_t6( AND, $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_instruction_t6( SUB, $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_instruction_t6( XOR, $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_instruction_t6( CMP, $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_instruction_t6( SAR, $2.size, REG, $2.number, $3.type, $3.value ); } | ITSAR register immediate { append_instructions( 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 register { append_instructions( 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 ); } | ITMOV register immediate { append_instructions( MOV, $2.size, REG, $2.number, $3.type, $3.value ); }
// #placeholder<instruction_parser_rules> END // #placeholder<instruction_parser_rules> END
; ;

View File

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

View File

@ -26,13 +26,13 @@ proc make_parser_rules {is} {
} }
proc make_parser_rule {i} { proc make_parser_rule {i} {
if {[llength $i] == 1} { 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]] \
[string toupper [lindex $i 0]] \ [string toupper [lindex $i 0]] \
] ]
} elseif {[llength $i] == 2} { } elseif {[llength $i] == 2} {
set arg [init_iarg [lindex $i 1] 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,\ %s,\
%s,\ %s,\
@ -49,7 +49,7 @@ proc make_parser_rules {is} {
} elseif {[llength $i] == 3} { } elseif {[llength $i] == 3} {
set arg1 [init_iarg [lindex $i 1] 2] set arg1 [init_iarg [lindex $i 1] 2]
set arg2 [init_iarg [lindex $i 2] 3] 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,\ %s,\
%s,\ %s,\