stuff
This commit is contained in:
14
Makefile
14
Makefile
@ -15,7 +15,7 @@ LIBS := $(addprefix ${OBJECT.d}/,${LIBS.source})
|
||||
GENSOURCE := eaxhla.yy.c eaxhla.tab.c
|
||||
GENSOURCE := $(addprefix ${OBJECT.d}/,${GENSOURCE})
|
||||
GENOBJECT := $(subst .c,.o,${GENSOURCE})
|
||||
PLUGLOCK := token_list.pluglock scanner_instructions.pluglock parser_rules.pluglock
|
||||
PLUGLOCK := instruction_token_list.pluglock instruction_scanner_instructions.pluglock instruction_parser_rules.pluglock register_token_list.pluglock register_scanner_instructions.pluglock register_parser_rules.pluglock
|
||||
PLUGLOCK := $(addprefix ${OBJECT.d}/,${PLUGLOCK})
|
||||
PLUGFILES := ${SOURCE.d}/eaxhla.y ${SOURCE.d}/eaxhla.l
|
||||
|
||||
@ -64,16 +64,12 @@ ${OBJECT.d}/%.tab.o: ${OBJECT.d}/%.tab.c
|
||||
${OBJECT.d}/%.o: ${SOURCE.d}/%.c
|
||||
${COMPILE.c} -o $@ $<
|
||||
|
||||
${OBJECT.d}/%.pp: tool/instruction_generator/%.tcl tool/instruction_generator/instructions.tcl
|
||||
${OBJECT.d}/%.pp: tool/generators/%.tcl tool/generators/instructions.tcl tool/generators/registers.tcl
|
||||
tclsh $< > $@
|
||||
|
||||
unplug:
|
||||
-rm ${PLUGLOCK}
|
||||
${PLUG} -u -d token_list '' -d scanner_instructions '' -d parser_rules '' source/eaxhla.l source/eaxhla.y
|
||||
|
||||
#plug: ${PLUGDEF}
|
||||
# ${PLUG} -g -e token_list ${OBJECT.d}/token_list.pp source/eaxhla.y
|
||||
# ${PLUG} -g -e scanner_instructions ${OBJECT.d}/scanner_instructions.pp source/eaxhla.l
|
||||
${PLUG} -u -a source/eaxhla.l source/eaxhla.y
|
||||
|
||||
${OBJECT.d}/%.pluglock: ${OBJECT.d}/%.pp
|
||||
${PLUG} -g -e $* $< ${PLUGFILES}
|
||||
@ -86,7 +82,9 @@ test: ${OUT}
|
||||
bootstrap:
|
||||
./library/bootstrap.sh
|
||||
|
||||
clean: unplug
|
||||
deepclean: unplug clean
|
||||
|
||||
clean:
|
||||
-rm ${OUT} ${OBJECT} ${GENOBJECT} ${GENSOURCE}
|
||||
|
||||
${OUT}: ${PLUGLOCK} ${GENSOURCE} ${GENOBJECT} ${OBJECT} ${LIB}
|
||||
|
@ -27,10 +27,10 @@ void dump_variable(void * data) {
|
||||
variable->value
|
||||
);
|
||||
} else {
|
||||
printf("{ .name = '%s', .elements = '%d', .array_value = \"%.*s\" }\n",
|
||||
printf("{ .name = '%s', .elements = '%llu', .array_value = \"%.*s\" }\n",
|
||||
variable->name,
|
||||
variable->elements,
|
||||
variable->elements,
|
||||
(int)variable->elements,
|
||||
(char*)variable->array_value
|
||||
);
|
||||
}
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include "eaxhla.tab.h"
|
||||
#include "assembler.h"
|
||||
|
||||
unsigned long long anon_variable_counter = 0;
|
||||
|
||||
tommy_hashtable variable_table;
|
||||
|
||||
int has_encountered_error = 0;
|
||||
@ -85,6 +87,14 @@ int can_fit(int type, long long value) {
|
||||
return value > 0 ? (unsigned long long)value <= max : value >= min;
|
||||
}
|
||||
|
||||
int validate_array_size(int size) {
|
||||
if (size < 1) {
|
||||
issue_error("cannot create an array of size '%d', because its less than 1", size);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char * make_scoped_name(const char * const scope, char * name) {
|
||||
if (!scope) {
|
||||
return name;
|
||||
|
@ -9,12 +9,14 @@ typedef struct {
|
||||
long value;
|
||||
void * array_value;
|
||||
};
|
||||
int elements;
|
||||
unsigned long long elements;
|
||||
char * name;
|
||||
unsigned _hash;
|
||||
tommy_node _node;
|
||||
} variable_t;
|
||||
|
||||
extern unsigned long long anon_variable_counter;
|
||||
|
||||
#define REGISTER64_MASK 0x00;
|
||||
#define REGISTER32_MASK 0x01;
|
||||
|
||||
@ -35,6 +37,7 @@ extern int eaxhla_destroy(void);
|
||||
|
||||
extern char * make_scoped_name(const char * const scope, char * name);
|
||||
extern int can_fit(int type, long long value);
|
||||
extern int validate_array_size(int size);
|
||||
|
||||
extern void add_variable(variable_t variable);
|
||||
extern variable_t * get_variable(const char * const name);
|
||||
|
183
source/eaxhla.l
183
source/eaxhla.l
@ -47,7 +47,7 @@ machine { return MACHINE; }
|
||||
library { return LIBRARY; }
|
||||
|
||||
break { return BREAK; }
|
||||
UNTIL { return UNTIL; }
|
||||
until { return UNTIL; }
|
||||
exit { return EXIT; }
|
||||
|
||||
end { BEGIN IN_END; }
|
||||
@ -55,48 +55,8 @@ end { BEGIN IN_END; }
|
||||
fast { return FAST; }
|
||||
unix { return UNIX; }
|
||||
|
||||
rax { return RAX; }
|
||||
rbx { return RBX; }
|
||||
rcx { return RCX; }
|
||||
rdx { return RDX; }
|
||||
rbp { return RBP; }
|
||||
rsp { return RSP; }
|
||||
rip { return RIP; }
|
||||
rsi { return RSI; }
|
||||
rdi { return RDI; }
|
||||
r8 { return RG8; }
|
||||
r9 { return RG9; }
|
||||
r10 { return RG10; }
|
||||
r11 { return RG11; }
|
||||
r12 { return RG12; }
|
||||
r13 { return RG13; }
|
||||
r14 { return RG14; }
|
||||
|
||||
xmm0 { return RGXMM0; }
|
||||
xmm1 { return RGXMM1; }
|
||||
xmm2 { return RGXMM2; }
|
||||
xmm3 { return RGXMM3; }
|
||||
xmm4 { return RGXMM4; }
|
||||
xmm5 { return RGXMM5; }
|
||||
xmm6 { return RGXMM6; }
|
||||
xmm7 { return RGXMM7; }
|
||||
|
||||
eax { return EAX; }
|
||||
ebx { return EBX; }
|
||||
ecx { return ECX; }
|
||||
edx { return EDX; }
|
||||
ebp { return EBP; }
|
||||
esp { return ESP; }
|
||||
eip { return EIP; }
|
||||
esi { return ESI; }
|
||||
edi { return EDI; }
|
||||
r8d { return RG8D; }
|
||||
r9d { return RG9D; }
|
||||
r10d { return RG10D; }
|
||||
r11d { return RG11D; }
|
||||
r12d { return RG12D; }
|
||||
r13d { return RG13D; }
|
||||
r14d { return RG14D; }
|
||||
/* #placeholder<register_scanner_instructions> END
|
||||
*/
|
||||
|
||||
in { return TIN; }
|
||||
\= { return '='; }
|
||||
@ -124,39 +84,112 @@ u64 { return U64; }
|
||||
|
||||
fastcall { return FASTCALL; }
|
||||
|
||||
/* --- Registers begin here --- */
|
||||
/* #placeholder<register_scanner_instructions> BEGIN
|
||||
*/
|
||||
rax { return RAX; }
|
||||
rbx { return RBX; }
|
||||
rcx { return RCX; }
|
||||
rdx { return RDX; }
|
||||
rsi { return RSI; }
|
||||
rdi { return RDI; }
|
||||
rbp { return RBP; }
|
||||
rsp { return RSP; }
|
||||
rg8 { return RG8; }
|
||||
rg9 { return RG9; }
|
||||
rg10 { return RG10; }
|
||||
rg11 { return RG11; }
|
||||
rg12 { return RG12; }
|
||||
rg13 { return RG13; }
|
||||
rg14 { return RG14; }
|
||||
rg15 { return RG15; }
|
||||
eax { return EAX; }
|
||||
ebx { return EBX; }
|
||||
ecx { return ECX; }
|
||||
edx { return EDX; }
|
||||
esi { return ESI; }
|
||||
edi { return EDI; }
|
||||
ebp { return EBP; }
|
||||
esp { return ESP; }
|
||||
rg8d { return RG8D; }
|
||||
rg9d { return RG9D; }
|
||||
rg10d { return RG10D; }
|
||||
rg11d { return RG11D; }
|
||||
rg12d { return RG12D; }
|
||||
rg13d { return RG13D; }
|
||||
rg14d { return RG14D; }
|
||||
rg15d { return RG15D; }
|
||||
ax { return AX; }
|
||||
bx { return BX; }
|
||||
cx { return CX; }
|
||||
dx { return DX; }
|
||||
si { return SI; }
|
||||
di { return DI; }
|
||||
bp { return BP; }
|
||||
sp { return SP; }
|
||||
r8w { return R8W; }
|
||||
r9w { return R9W; }
|
||||
r10w { return R10W; }
|
||||
r11w { return R11W; }
|
||||
r12w { return R12W; }
|
||||
r13w { return R13W; }
|
||||
r14w { return R14W; }
|
||||
r15w { return R15W; }
|
||||
al { return AL; }
|
||||
bl { return BL; }
|
||||
cl { return CL; }
|
||||
dl { return DL; }
|
||||
sil { return SIL; }
|
||||
dil { return DIL; }
|
||||
bpl { return BPL; }
|
||||
spl { return SPL; }
|
||||
r8b { return R8B; }
|
||||
r9b { return R9B; }
|
||||
r10b { return R10B; }
|
||||
r11b { return R11B; }
|
||||
r12b { return R12B; }
|
||||
r13b { return R13B; }
|
||||
r14b { return R14B; }
|
||||
r15b { return R15B; }
|
||||
|
||||
/* #placeholder<register_scanner_instructions> END
|
||||
*/
|
||||
/* --- Registers end here --- */
|
||||
|
||||
/* --- Instrunctions begin here --- */
|
||||
nop { return INOP; }
|
||||
/* #placeholder<scanner_instructions> BEGIN
|
||||
/* #placeholder<instruction_scanner_instructions> BEGIN
|
||||
*/
|
||||
adc { return ITADC; }
|
||||
add { return ITADD; }
|
||||
and { return ITAND; }
|
||||
cmp { return ITCMP; }
|
||||
dec { return ITDEC; }
|
||||
div { return ITDIV; }
|
||||
hlt { return ITHLT; }
|
||||
idiv { return ITIDIV; }
|
||||
imul { return ITIMUL; }
|
||||
inc { return ITINC; }
|
||||
leave { return ITLEAVE; }
|
||||
lock { return ITLOCK; }
|
||||
mov { return ITMOV; }
|
||||
mul { return ITMUL; }
|
||||
neg { return ITNEG; }
|
||||
not { return ITNOT; }
|
||||
or { return ITOR; }
|
||||
pause { return ITPAUSE; }
|
||||
retf { return ITRETF; }
|
||||
retn { return ITRETN; }
|
||||
sbb { return ITSBB; }
|
||||
sub { return ITSUB; }
|
||||
syscall { return ITSYSCALL; }
|
||||
sysenter { return ITSYSENTER; }
|
||||
sysexit { return ITSYSEXIT; }
|
||||
sysret { return ITSYSRET; }
|
||||
xor { return ITXOR; }
|
||||
adc { return ITADC; }
|
||||
add { return ITADD; }
|
||||
and { return ITAND; }
|
||||
cmp { return ITCMP; }
|
||||
dec { return ITDEC; }
|
||||
div { return ITDIV; }
|
||||
hlt { return ITHLT; }
|
||||
idiv { return ITIDIV; }
|
||||
imul { return ITIMUL; }
|
||||
inc { return ITINC; }
|
||||
leave { return ITLEAVE; }
|
||||
lock { return ITLOCK; }
|
||||
mov { return ITMOV; }
|
||||
mul { return ITMUL; }
|
||||
neg { return ITNEG; }
|
||||
not { return ITNOT; }
|
||||
or { return ITOR; }
|
||||
pause { return ITPAUSE; }
|
||||
retf { return ITRETF; }
|
||||
retn { return ITRETN; }
|
||||
sar { return ITSAR; }
|
||||
sbb { return ITSBB; }
|
||||
sub { return ITSUB; }
|
||||
syscall { return ITSYSCALL; }
|
||||
sysenter { return ITSYSENTER; }
|
||||
sysexit { return ITSYSEXIT; }
|
||||
sysret { return ITSYSRET; }
|
||||
xor { return ITXOR; }
|
||||
|
||||
/* #placeholder<scanner_instructions> END
|
||||
/* #placeholder<instruction_scanner_instructions> END
|
||||
*/
|
||||
/* --- Instrunctions end here --- */
|
||||
|
||||
@ -185,9 +218,9 @@ library { BEGIN INITIAL; return END_LIBRARY; }
|
||||
return LITERAL;
|
||||
}
|
||||
|
||||
string_literal_ensure_surplus(1);
|
||||
string_literal_buffer[string_litral_buffer_size+1] = '\0';
|
||||
yylval.strval = strdup(string_literal_buffer);
|
||||
yylval.blobval.data = malloc(string_litral_buffer_size);
|
||||
memcpy(yylval.blobval.data, string_literal_buffer, string_litral_buffer_size);
|
||||
yylval.blobval.len = string_litral_buffer_size;
|
||||
string_litral_buffer_size = 0;
|
||||
return ARRAY_LITERAL;
|
||||
}
|
||||
|
197
source/eaxhla.y
197
source/eaxhla.y
@ -20,6 +20,10 @@
|
||||
%union{
|
||||
long intval;
|
||||
char * strval;
|
||||
struct {
|
||||
unsigned long long len;
|
||||
void * data;
|
||||
} blobval;
|
||||
variable_t varval;
|
||||
cpuregister_t regval;
|
||||
}
|
||||
@ -43,12 +47,12 @@
|
||||
|
||||
%token<strval> IDENTIFIER LABEL
|
||||
|
||||
%type<intval> immediate
|
||||
%type<intval> memory dereference
|
||||
%type<intval> artimetric_block artimetric_expression artimetric_operand
|
||||
%type<intval> value
|
||||
%token<intval> LITERAL
|
||||
%token<strval> ARRAY_LITERAL
|
||||
%type<intval> immediate
|
||||
%type<intval> memory dereference
|
||||
%type<intval> artimetric_block artimetric_expression artimetric_operand
|
||||
%type<intval> value
|
||||
%token<intval> LITERAL
|
||||
%token<blobval> ARRAY_LITERAL
|
||||
|
||||
// Specifiers
|
||||
%token FAST
|
||||
@ -66,26 +70,24 @@
|
||||
%token U8 U16 U32 U64
|
||||
%type<intval> type
|
||||
%type<varval> declaration
|
||||
%type<varval> anon_variable
|
||||
|
||||
// Registers
|
||||
%type<regval> register register64 register32
|
||||
%type<regval> register register64s register32s register16s register8s
|
||||
|
||||
%token RBP RSP RIP
|
||||
%token RAX RBX RCX RDX
|
||||
%token RSI RDI
|
||||
%token RG8 RG9 RG10 RG11 RG12 RG13 RG14 RG15
|
||||
%token RGXMM0 RGXMM1 RGXMM2 RGXMM3 RGXMM4 RGXMM5 RGXMM6 RGXMM7
|
||||
// #placeholder<register_token_list> BEGIN
|
||||
%token RAX RBX RCX RDX RSI RDI RBP RSP RG8 RG9 RG10 RG11 RG12 RG13 RG14 RG15
|
||||
%token EAX EBX ECX EDX ESI EDI EBP ESP RG8D RG9D RG10D RG11D RG12D RG13D RG14D RG15D
|
||||
%token AX BX CX DX SI DI BP SP R8W R9W R10W R11W R12W R13W R14W R15W
|
||||
%token AL BL CL DL SIL DIL BPL SPL R8B R9B R10B R11B R12B R13B R14B R15B
|
||||
|
||||
%token EBP ESP EIP
|
||||
%token EAX EBX ECX EDX
|
||||
%token ESI EDI
|
||||
%token RG8D RG9D RG10D RG11D RG12D RG13D RG14D RG15D
|
||||
// #placeholder<register_token_list> END
|
||||
|
||||
// Instructions
|
||||
%token INOP
|
||||
// #placeholder<token_list> BEGIN
|
||||
%token ITADC ITADD ITAND ITCMP ITDEC ITDIV ITHLT ITIDIV ITIMUL ITINC ITLEAVE ITLOCK ITMOV ITMUL ITNEG ITNOT ITOR ITPAUSE ITRETF ITRETN ITSBB ITSUB ITSYSCALL ITSYSENTER ITSYSEXIT ITSYSRET ITXOR
|
||||
// #placeholder<token_list> END
|
||||
// #placeholder<instruction_token_list> BEGIN
|
||||
%token ITADC ITADD ITAND ITCMP ITDEC ITDIV ITHLT ITIDIV ITIMUL ITINC ITLEAVE ITLOCK ITMOV ITMUL ITNEG ITNOT ITOR ITPAUSE ITRETF ITRETN ITSAR ITSBB ITSUB ITSYSCALL ITSYSENTER ITSYSEXIT ITSYSRET ITXOR
|
||||
// #placeholder<instruction_token_list> END
|
||||
|
||||
// Instruction-likes
|
||||
%token FASTCALL
|
||||
@ -151,14 +153,29 @@ declaration:
|
||||
add_variable($$);
|
||||
}
|
||||
| variable_specifier type '<' value '>' IDENTIFIER {
|
||||
if (validate_array_size($4)) {
|
||||
break;
|
||||
}
|
||||
$$.name = make_scoped_name(scope, $6);
|
||||
$$.elements = $4;
|
||||
add_variable($$);
|
||||
}
|
||||
| variable_specifier type '<' value '>' IDENTIFIER '=' ARRAY_LITERAL {
|
||||
if (validate_array_size($4)) {
|
||||
break;
|
||||
}
|
||||
if ($4 < $8.len) {
|
||||
issue_warning("you are a nigger");
|
||||
}
|
||||
$$.name = make_scoped_name(scope, $6);
|
||||
$$.elements = $4;
|
||||
$$.array_value = $8;
|
||||
$$.array_value = $8.data;
|
||||
add_variable($$);
|
||||
}
|
||||
| variable_specifier type '<' '>' IDENTIFIER '=' ARRAY_LITERAL {
|
||||
$$.name = make_scoped_name(scope, $5);
|
||||
$$.elements = $7.len;
|
||||
$$.array_value = $7.data;
|
||||
add_variable($$);
|
||||
}
|
||||
;
|
||||
@ -183,6 +200,7 @@ immediate: LITERAL
|
||||
|
||||
memory: artimetric_block
|
||||
| dereference
|
||||
| IDENTIFIER
|
||||
;
|
||||
|
||||
dereference: '[' IDENTIFIER '+' value ']' { $$ = 0; /* XXX: how the fuck do i dereference? */ }
|
||||
@ -199,6 +217,15 @@ value: artimetric_block
|
||||
}
|
||||
;
|
||||
|
||||
anon_variable: ARRAY_LITERAL {
|
||||
$$.array_value = $1.data;
|
||||
$$.elements = $1.len;
|
||||
int ignore = asprintf(&$$.name, "_anon_%llu", anon_variable_counter++);
|
||||
(void)ignore;
|
||||
add_variable($$);
|
||||
}
|
||||
;
|
||||
|
||||
code: %empty
|
||||
| error code { /*yyerrok;*/ }
|
||||
| repeat code
|
||||
@ -259,56 +286,91 @@ arguments: %empty
|
||||
| LITERAL arguments
|
||||
| register arguments
|
||||
| artimetric_block arguments
|
||||
| anon_variable arguments
|
||||
;
|
||||
|
||||
register: register64 { $$ = $1; $$.size = D64; }
|
||||
| register32 { $$ = $1; $$.size = D32; }
|
||||
register: register64s { $$ = $1; $$.size = D64; }
|
||||
| register32s { $$ = $1; $$.size = D32; }
|
||||
| register16s { $$ = $1; $$.size = D16; }
|
||||
| register8s { $$ = $1; $$.size = D8; }
|
||||
;
|
||||
|
||||
register64: RAX { $$.number = R0; }
|
||||
| RBX { $$.number = R1; }
|
||||
| RCX { $$.number = R2; }
|
||||
| RDX { $$.number = R3; }
|
||||
| RSI { $$.number = R4; }
|
||||
| RDI { $$.number = R5; }
|
||||
| RBP { $$.number = R6; }
|
||||
| RSP { $$.number = R7; }
|
||||
| RG8 { $$.number = R8; }
|
||||
| RG9 { $$.number = R9; }
|
||||
| RG10 { $$.number = R10; }
|
||||
| RG11 { $$.number = R11; }
|
||||
| RG12 { $$.number = R12; }
|
||||
| RG13 { $$.number = R13; }
|
||||
| RG14 { $$.number = R14; }
|
||||
| RG15 { $$.number = R15; }
|
||||
| RGXMM0 { $$.number = 0; } /* XXX */
|
||||
| RGXMM1 { $$.number = 0; }
|
||||
| RGXMM2 { $$.number = 0; }
|
||||
| RGXMM3 { $$.number = 0; }
|
||||
| RGXMM4 { $$.number = 0; }
|
||||
| RGXMM5 { $$.number = 0; }
|
||||
| RGXMM6 { $$.number = 0; }
|
||||
| RGXMM7 { $$.number = 0; }
|
||||
// #placeholder<register_parser_rules> BEGIN
|
||||
register64s: RAX { $$.number = R0; }
|
||||
| RBX { $$.number = R1; }
|
||||
| RCX { $$.number = R2; }
|
||||
| RDX { $$.number = R3; }
|
||||
| RSI { $$.number = R4; }
|
||||
| RDI { $$.number = R5; }
|
||||
| RBP { $$.number = R6; }
|
||||
| RSP { $$.number = R7; }
|
||||
| RG8 { $$.number = R8; }
|
||||
| RG9 { $$.number = R9; }
|
||||
| RG10 { $$.number = R10; }
|
||||
| RG11 { $$.number = R11; }
|
||||
| RG12 { $$.number = R12; }
|
||||
| RG13 { $$.number = R13; }
|
||||
| RG14 { $$.number = R14; }
|
||||
| RG15 { $$.number = R15; }
|
||||
;
|
||||
|
||||
register32: EAX { $$.number = R0; }
|
||||
| EBX { $$.number = R3; }
|
||||
| ECX { $$.number = R1; }
|
||||
| EDX { $$.number = R2; }
|
||||
| ESI { $$.number = R6; }
|
||||
| EDI { $$.number = R7; }
|
||||
| EBP { $$.number = R5; }
|
||||
| ESP { $$.number = R4; }
|
||||
| RG8D { $$.number = R8; }
|
||||
| RG9D { $$.number = R9; }
|
||||
| RG10D { $$.number = R10; }
|
||||
| RG11D { $$.number = R11; }
|
||||
| RG12D { $$.number = R12; }
|
||||
| RG13D { $$.number = R13; }
|
||||
| RG14D { $$.number = R14; }
|
||||
| RG15D { $$.number = R15; }
|
||||
register32s: EAX { $$.number = R0; }
|
||||
| EBX { $$.number = R1; }
|
||||
| ECX { $$.number = R2; }
|
||||
| EDX { $$.number = R3; }
|
||||
| ESI { $$.number = R4; }
|
||||
| EDI { $$.number = R5; }
|
||||
| EBP { $$.number = R6; }
|
||||
| ESP { $$.number = R7; }
|
||||
| RG8D { $$.number = R8; }
|
||||
| RG9D { $$.number = R9; }
|
||||
| RG10D { $$.number = R10; }
|
||||
| RG11D { $$.number = R11; }
|
||||
| RG12D { $$.number = R12; }
|
||||
| RG13D { $$.number = R13; }
|
||||
| RG14D { $$.number = R14; }
|
||||
| RG15D { $$.number = R15; }
|
||||
;
|
||||
|
||||
register16s: AX { $$.number = R0; }
|
||||
| BX { $$.number = R1; }
|
||||
| CX { $$.number = R2; }
|
||||
| DX { $$.number = R3; }
|
||||
| SI { $$.number = R4; }
|
||||
| DI { $$.number = R5; }
|
||||
| BP { $$.number = R6; }
|
||||
| SP { $$.number = R7; }
|
||||
| R8W { $$.number = R8; }
|
||||
| R9W { $$.number = R9; }
|
||||
| R10W { $$.number = R10; }
|
||||
| R11W { $$.number = R11; }
|
||||
| R12W { $$.number = R12; }
|
||||
| R13W { $$.number = R13; }
|
||||
| R14W { $$.number = R14; }
|
||||
| R15W { $$.number = R15; }
|
||||
;
|
||||
|
||||
register8s: AL { $$.number = R0; }
|
||||
| BL { $$.number = R1; }
|
||||
| CL { $$.number = R2; }
|
||||
| DL { $$.number = R3; }
|
||||
| SIL { $$.number = R4; }
|
||||
| DIL { $$.number = R5; }
|
||||
| BPL { $$.number = R6; }
|
||||
| SPL { $$.number = R7; }
|
||||
| R8B { $$.number = R8; }
|
||||
| R9B { $$.number = R9; }
|
||||
| R10B { $$.number = R10; }
|
||||
| R11B { $$.number = R11; }
|
||||
| R12B { $$.number = R12; }
|
||||
| R13B { $$.number = R13; }
|
||||
| R14B { $$.number = R14; }
|
||||
| R15B { $$.number = R15; }
|
||||
;
|
||||
|
||||
|
||||
// #placeholder<register_parser_rules> END
|
||||
|
||||
artimetric_block: '{' artimetric_expression '}' { $$ = $2; }
|
||||
;
|
||||
|
||||
@ -329,6 +391,7 @@ artimetric_operand: LITERAL
|
||||
exit: EXIT value
|
||||
;
|
||||
|
||||
/* XXX */
|
||||
library: LIBRARY declaration_section MYBEGIN library_code END_LIBRARY
|
||||
;
|
||||
|
||||
@ -337,11 +400,7 @@ library_code: %empty
|
||||
;
|
||||
|
||||
instruction: INOP { append_instruction_t1(NOP); }
|
||||
/*
|
||||
| ISYSCALL { append_instruction_t1 (SYSCALL); }
|
||||
| IMOV register immediate { append_instruction_t6 (MOV, $2.size, REG, $2.number, IMM, (int) $3); }
|
||||
*/
|
||||
// #placeholder<parser_rules> BEGIN
|
||||
// #placeholder<instruction_parser_rules> BEGIN
|
||||
| ITSYSCALL { append_instruction_t1(SYSCALL); }
|
||||
| ITSYSRET { append_instruction_t1(SYSRET); }
|
||||
| ITSYSEXIT { append_instruction_t1(SYSEXIT); }
|
||||
@ -376,9 +435,11 @@ instruction: INOP { append_instruction_t1(NOP); }
|
||||
| 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, IMM, (int)$3 ); }
|
||||
| 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, IMM, (int)$3 ); }
|
||||
|
||||
// #placeholder<parser_rules> END
|
||||
// #placeholder<instruction_parser_rules> END
|
||||
;
|
||||
|
||||
%%
|
||||
|
@ -13,7 +13,16 @@ static void dump (const char * file_name);
|
||||
#include "unix.h"
|
||||
#include "debug.h"
|
||||
|
||||
extern void yyfree_leftovers(void);
|
||||
void free_n(void) {
|
||||
extern void yyfree_leftovers(void);
|
||||
|
||||
yyfree_leftovers();
|
||||
|
||||
eaxhla_destroy();
|
||||
|
||||
free (text_sector_byte);
|
||||
free (t_array);
|
||||
}
|
||||
|
||||
char * yyfilename;
|
||||
|
||||
@ -51,12 +60,7 @@ signed main(int argc, char * argv[]) {
|
||||
issue_warning("the input did not contain any instructions");
|
||||
}
|
||||
|
||||
yyfree_leftovers();
|
||||
|
||||
eaxhla_destroy();
|
||||
|
||||
free (text_sector_byte);
|
||||
free (t_array);
|
||||
free_n();
|
||||
|
||||
return has_encountered_error;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
program main
|
||||
u8<10> myarray
|
||||
u8<> myarray2 = "test test test\0"
|
||||
begin
|
||||
end program
|
||||
|
18
test/nop.eax
18
test/nop.eax
@ -40,6 +40,7 @@ procedure read
|
||||
in s32 file
|
||||
in u64 data
|
||||
in u64 size
|
||||
u8 <> fatal_message = "> failed to read from the file!\n\0"
|
||||
begin
|
||||
mov eax system_call_read
|
||||
mov edi file
|
||||
@ -48,7 +49,7 @@ begin
|
||||
syscall
|
||||
|
||||
if eax = -1 then
|
||||
fastcall fatal "> failed to read from the file!\n\0"
|
||||
fastcall fatal fatal_message
|
||||
end if
|
||||
end procedure
|
||||
|
||||
@ -59,6 +60,7 @@ procedure write
|
||||
in s32 file
|
||||
in u64 data
|
||||
in u64 size
|
||||
u8 <> fatal_message = "> failed to write to the file!\n\0"
|
||||
begin
|
||||
mov eax system_call_write
|
||||
mov edi file
|
||||
@ -67,7 +69,7 @@ begin
|
||||
syscall
|
||||
|
||||
if eax = -1 then
|
||||
fastcall fatal "> failed to write to the file!\n\0"
|
||||
fastcall fatal fatal_message
|
||||
end if
|
||||
end procedure
|
||||
|
||||
@ -75,9 +77,9 @@ end procedure
|
||||
|
||||
fast
|
||||
procedure open
|
||||
in u64 name
|
||||
in s32 mode
|
||||
in s32 * file
|
||||
in u64 name
|
||||
in s32 mode
|
||||
in s32 file
|
||||
begin
|
||||
mov eax system_call_open
|
||||
mov rdi name
|
||||
@ -112,7 +114,7 @@ unix program main
|
||||
s32 file = 0
|
||||
u8 byte = 0
|
||||
|
||||
s8 [] digits = '0123456789abcdef\0'
|
||||
s8 <> digits = "0123456789abcdef\0"
|
||||
s8 space = 32
|
||||
s8 new_line = 10
|
||||
begin
|
||||
@ -120,12 +122,12 @@ begin
|
||||
fastcall fatal "> argument count must be 2!\n\0"
|
||||
end if
|
||||
|
||||
fastcall open argv [1] 0 file
|
||||
fastcall open argv 1 0 file
|
||||
|
||||
until r10 = 0 repeat
|
||||
fastcall read standard_input byte 1
|
||||
// When EOF is reached 'rax', then 'r10' is 0.
|
||||
mov r10, rax
|
||||
mov r10 rax
|
||||
|
||||
if u8 [byte] = 0x90 then
|
||||
fastcall print "\n\0"
|
||||
|
@ -1,4 +1,4 @@
|
||||
source tool/instruction_generator/instructions.tcl
|
||||
source tool/generators/instructions.tcl
|
||||
|
||||
proc make_parser_rules {is} {
|
||||
proc init_iarg {a n} {
|
@ -1,8 +1,8 @@
|
||||
source tool/instruction_generator/instructions.tcl
|
||||
source tool/generators/instructions.tcl
|
||||
|
||||
proc make_scanner_instructions {is} {
|
||||
proc make_scanner_instruction {i} {
|
||||
puts [format "%s { return IT%s; }" \
|
||||
puts [format "%-12s { return IT%s; }" \
|
||||
[lindex $i 0] \
|
||||
[string toupper [lindex $i 0]]
|
||||
]
|
@ -1,4 +1,4 @@
|
||||
source tool/instruction_generator/instructions.tcl
|
||||
source tool/generators/instructions.tcl
|
||||
|
||||
proc make_token_list {is} {
|
||||
proc uniq_instl {is} {
|
@ -33,6 +33,8 @@ set instructions {
|
||||
{sub register register}
|
||||
{xor register register}
|
||||
{cmp register register}
|
||||
{sar register immediate}
|
||||
{mov register register}
|
||||
{mov register immediate}
|
||||
}
|
||||
|
26
tool/generators/register_parser_rules.tcl
Normal file
26
tool/generators/register_parser_rules.tcl
Normal file
@ -0,0 +1,26 @@
|
||||
source tool/generators/registers.tcl
|
||||
|
||||
proc register_parsing {registers} {
|
||||
proc register_parser_rule {size batch} {
|
||||
puts [format "register%ss: %s \{ \$\$.number = R0; \}"\
|
||||
$size\
|
||||
[string toupper [lindex $batch 0]]\
|
||||
]
|
||||
set accumulator 1
|
||||
foreach register [lrange $batch 1 end] {
|
||||
puts [format " | %-5s \{ \$\$.number = R%s; \}"\
|
||||
[string toupper $register]\
|
||||
$accumulator\
|
||||
]
|
||||
incr accumulator
|
||||
}
|
||||
puts " ;"
|
||||
puts ""
|
||||
}
|
||||
|
||||
foreach {key value} $registers {
|
||||
register_parser_rule $key $value
|
||||
}
|
||||
}
|
||||
|
||||
register_parsing $registers
|
13
tool/generators/register_scanner_instructions.tcl
Normal file
13
tool/generators/register_scanner_instructions.tcl
Normal file
@ -0,0 +1,13 @@
|
||||
source tool/generators/registers.tcl
|
||||
|
||||
proc scan_registers {registers} {
|
||||
foreach {key value} $registers {
|
||||
foreach {register} $value {
|
||||
puts [format "%-6s \{ return %s; \}" $register [string toupper $register]]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
puts " */"
|
||||
|
||||
scan_registers $registers
|
13
tool/generators/register_token_list.tcl
Normal file
13
tool/generators/register_token_list.tcl
Normal file
@ -0,0 +1,13 @@
|
||||
source tool/generators/registers.tcl
|
||||
|
||||
proc register_tokens {registers} {
|
||||
proc generate_register_token_batch {batch} {
|
||||
puts [format "%%token %s" [string toupper $batch]]
|
||||
}
|
||||
|
||||
foreach {key value} $registers {
|
||||
generate_register_token_batch [join $value " "]
|
||||
}
|
||||
}
|
||||
|
||||
register_tokens $registers
|
92
tool/generators/registers.tcl
Normal file
92
tool/generators/registers.tcl
Normal file
@ -0,0 +1,92 @@
|
||||
# XXX
|
||||
#
|
||||
# | RGXMM0 { $$.number = 0; } /* XXX */
|
||||
# | RGXMM1 { $$.number = 0; }
|
||||
# | RGXMM2 { $$.number = 0; }
|
||||
# | RGXMM3 { $$.number = 0; }
|
||||
# | RGXMM4 { $$.number = 0; }
|
||||
# | RGXMM5 { $$.number = 0; }
|
||||
# | RGXMM6 { $$.number = 0; }
|
||||
# | RGXMM7 { $$.number = 0; }
|
||||
|
||||
set register64s {
|
||||
rax
|
||||
rbx
|
||||
rcx
|
||||
rdx
|
||||
rsi
|
||||
rdi
|
||||
rbp
|
||||
rsp
|
||||
rg8
|
||||
rg9
|
||||
rg10
|
||||
rg11
|
||||
rg12
|
||||
rg13
|
||||
rg14
|
||||
rg15
|
||||
}
|
||||
|
||||
set register32s {
|
||||
eax
|
||||
ebx
|
||||
ecx
|
||||
edx
|
||||
esi
|
||||
edi
|
||||
ebp
|
||||
esp
|
||||
rg8d
|
||||
rg9d
|
||||
rg10d
|
||||
rg11d
|
||||
rg12d
|
||||
rg13d
|
||||
rg14d
|
||||
rg15d
|
||||
}
|
||||
|
||||
set register16s {
|
||||
ax
|
||||
bx
|
||||
cx
|
||||
dx
|
||||
si
|
||||
di
|
||||
bp
|
||||
sp
|
||||
r8w
|
||||
r9w
|
||||
r10w
|
||||
r11w
|
||||
r12w
|
||||
r13w
|
||||
r14w
|
||||
r15w
|
||||
}
|
||||
|
||||
set register8ls {
|
||||
al
|
||||
bl
|
||||
cl
|
||||
dl
|
||||
sil
|
||||
dil
|
||||
bpl
|
||||
spl
|
||||
r8b
|
||||
r9b
|
||||
r10b
|
||||
r11b
|
||||
r12b
|
||||
r13b
|
||||
r14b
|
||||
r15b
|
||||
}
|
||||
|
||||
set registers [dict create]
|
||||
dict set registers 64 $register64s
|
||||
dict set registers 32 $register32s
|
||||
dict set registers 16 $register16s
|
||||
dict set registers 8 $register8ls
|
48
tool/plug
48
tool/plug
@ -56,6 +56,7 @@ def usage():
|
||||
{C[g]}{C[B]}--color{C[n]} {C[B]}{C[b]}never{C[y]}|{C[b]}auto{C[y]}|{C[b]}always{C[n]} : set output coloring option; default: auto
|
||||
{C[g]}{C[B]}-d{C[n]} {C[b]}{C[B]}<name> <value>{C[n]} : define placeholder on the cli
|
||||
{C[g]}{C[B]}-e{C[n]} {C[b]}{C[B]}<name> <file>{C[n]} : define placeholder as the contents of <file>
|
||||
{C[g]}{C[B]}-a{C[n]} : define all undefined placeholders as empty strings
|
||||
{C[g]}{C[B]}-u{C[n]} : ungenerate placeholders (ie. collapse)
|
||||
{C[g]}{C[B]}-g{C[n]} : generate placeholders (ie. expand)
|
||||
Every argument not starting with '-' is considered a file.
|
||||
@ -72,11 +73,22 @@ def usage():
|
||||
{C[b]}@gnu-tofile-*{C[n]}
|
||||
|
||||
{C[y]}{C[B]}Example:{C[n]}
|
||||
// XXX REDO THIS WHOLE SECTION
|
||||
{C[g]}$ cat example/ex1.txt{C[n]}
|
||||
original text
|
||||
#placeholder<hw> COLLAPSED
|
||||
some more original text
|
||||
{C[g]}$ plug -g -d hw 'hello world' example/ex1.txt{C[n]}
|
||||
{C[g]}$ cat example/ex1.txt{C[n]}
|
||||
original text
|
||||
#placeholder<hw> BEGIN
|
||||
hello world
|
||||
#placeholder<hw> END
|
||||
some more original text
|
||||
'''.format(**globals(), argv0 = sys.argv[0]), end='')
|
||||
|
||||
destination_files = []
|
||||
operation = ""
|
||||
is_all = False
|
||||
|
||||
placeholders = {}
|
||||
|
||||
@ -110,6 +122,8 @@ def builtin_lookup(phl : str) -> str:
|
||||
return ''
|
||||
|
||||
def gen(s : str, phls : [str]) -> str:
|
||||
global is_all
|
||||
s = ungen(s, phls)
|
||||
for phl in phls:
|
||||
buf = ''
|
||||
l = 0
|
||||
@ -122,10 +136,20 @@ def gen(s : str, phls : [str]) -> str:
|
||||
l = m.end(0)
|
||||
buf += s[l:]
|
||||
s = buf
|
||||
|
||||
if is_all:
|
||||
buf = ''
|
||||
l = 0
|
||||
for m in re_placeholder_collapsed.finditer(s):
|
||||
buf += s[l : m.start(0)]
|
||||
buf += m.group(1) + placeholder_expanded_beginning.format(m.group(2)) + '\n'
|
||||
buf += m.group(1) + placeholder_expanded_ending.format(m.group(2))
|
||||
l = m.end(0)
|
||||
buf += s[l:]
|
||||
s = buf
|
||||
return s
|
||||
|
||||
def ungen(s : str, phls : [str]) -> str:
|
||||
global is_all
|
||||
for phl in phls:
|
||||
buf = ''
|
||||
l = 0
|
||||
@ -140,6 +164,19 @@ def ungen(s : str, phls : [str]) -> str:
|
||||
break
|
||||
buf += s[l:]
|
||||
s = buf
|
||||
if is_all:
|
||||
buf = ''
|
||||
l = 0
|
||||
for m in re_placeholder_expanded_beginning.finditer(s):
|
||||
buf += s[l : m.start(0)]
|
||||
buf += m.group(1) + placeholder_collapsed.format(m.group(2))
|
||||
l = m.end(0)
|
||||
for me in re_placeholder_expanded_ending.finditer(s[m.end(0):]):
|
||||
if(me.group(1) != m.group(2)): continue
|
||||
l = m.end(0) + me.end(0)
|
||||
break
|
||||
buf += s[l:]
|
||||
s = buf
|
||||
return s
|
||||
|
||||
def error_and_quit(e : int, argv : [str]) -> None:
|
||||
@ -159,7 +196,7 @@ def error_and_quit(e : int, argv : [str]) -> None:
|
||||
|
||||
# We need this function because getopt does not support a single flag taking 2 arguments
|
||||
def parse_args(argv : [str]) -> None:
|
||||
global destination_files, operation
|
||||
global destination_files, operation, is_all
|
||||
def get_param(argv : [str], i : int) -> str:
|
||||
try: param = argv[i]
|
||||
except: error_and_quit(Error.PARAM_MISS, [argv[i-1]])
|
||||
@ -180,6 +217,11 @@ def parse_args(argv : [str]) -> None:
|
||||
i = i + 1
|
||||
continue
|
||||
|
||||
if argv[i] == '-a':
|
||||
is_all = True
|
||||
i = i + 1
|
||||
continue
|
||||
|
||||
# 1 param opt
|
||||
if argv[i-1] == '--color':
|
||||
p = get_param(argv, i)
|
||||
|
Reference in New Issue
Block a user