From 6fd63037a63a8d764c949d9a8b5a295c966be0c9 Mon Sep 17 00:00:00 2001 From: anon Date: Tue, 16 Jul 2024 17:11:31 +0200 Subject: [PATCH] refactoring --- source/compile.c | 63 +++++++--------- source/compile.h | 58 +++++++++++++-- source/eaxhla.c | 2 +- source/eaxhla.h | 2 +- source/eaxhla.y | 76 ++++++++++---------- source/main.c | 15 ++-- tool/generators/instruction_parser_rules.tcl | 6 +- 7 files changed, 133 insertions(+), 89 deletions(-) diff --git a/source/compile.c b/source/compile.c index c1db655..0bd818d 100644 --- a/source/compile.c +++ b/source/compile.c @@ -2,6 +2,7 @@ #include #include +#include #include #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; - token_count += 1; -} +void _append_instructions(unsigned argc, ...) { + va_list ap; + va_start(ap, argc); -void append_instruction_t1 (int t1) { - append_token (t1); // operation -} + for (unsigned i = 0; i < argc; i++) { + token_array [token_count] = va_arg(ap, int); + token_count += 1; + } -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 ... ... begin @@ -115,12 +110,12 @@ void append_label (int rel) { // optimally, it should be number 0 ... 140. // for now, 140 procedures is enough, will expand later! void append_fastcall_begin (int rel) { - append_label (rel); + append_label(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); } diff --git a/source/compile.h b/source/compile.h index 8e1f76e..7696c11 100644 --- a/source/compile.h +++ b/source/compile.h @@ -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 diff --git a/source/eaxhla.c b/source/eaxhla.c index 7cd9562..1f3c7ec 100644 --- a/source/eaxhla.c +++ b/source/eaxhla.c @@ -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; diff --git a/source/eaxhla.h b/source/eaxhla.h index 4e15342..e6f83fc 100644 --- a/source/eaxhla.h +++ b/source/eaxhla.h @@ -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); diff --git a/source/eaxhla.y b/source/eaxhla.y index 7ae2ad1..f957c0f 100644 --- a/source/eaxhla.y +++ b/source/eaxhla.y @@ -418,45 +418,45 @@ library_code: %empty ; */ -instruction: INOP { append_instruction_t1(NOP); } +instruction: INOP { append_instructions(NOP); } // #placeholder 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 END ; diff --git a/source/main.c b/source/main.c index ba35064..a534736 100644 --- a/source/main.c +++ b/source/main.c @@ -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; } diff --git a/tool/generators/instruction_parser_rules.tcl b/tool/generators/instruction_parser_rules.tcl index 146898b..74100d3 100644 --- a/tool/generators/instruction_parser_rules.tcl +++ b/tool/generators/instruction_parser_rules.tcl @@ -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,\