refactoring
This commit is contained in:
@ -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);
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
;
|
;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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,\
|
||||||
|
Reference in New Issue
Block a user