Merge branch 'master' of https://codeberg.org/eaxcc/eaxcc
This commit is contained in:
commit
995bb4ce4b
@ -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;
|
||||
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 ... <argv> ... 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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,\
|
||||
|
Loading…
x
Reference in New Issue
Block a user