less terrible instruction generation

This commit is contained in:
anon
2024-07-12 16:51:21 +02:00
parent 204fe84052
commit 543b4d3c8a
7 changed files with 181 additions and 90 deletions

@ -79,14 +79,14 @@ test: ${OUT}
clean:
-rm ${OUT} ${OBJECT} ${GENOBJECT} ${GENSOURCE}
${OBJECT.d}/%.pp: debug/%.tcl
${OBJECT.d}/%.pp: debug/%.tcl debug/instructions.tcl
tclsh $< > $@
plug: ${OBJECT.d}/token_list.pp ${OBJECT.d}/scanner_instructions.pp ${OBJECT.d}/parser_rules.pp
plug -u -d token_list '' -d scanner_instructions '' -d parser_rules '' source/eaxhla.l source/eaxhla.y
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 -g -e parser_rules ${OBJECT.d}/parser_rules.pp source/eaxhla.l
plug -g -e parser_rules ${OBJECT.d}/parser_rules.pp source/eaxhla.y
.PHONY: test clean bootstrap

@ -1,6 +1,5 @@
set instructions {
{syscall}
{nop}
{sysret}
{sysexit}
{sysenter}
@ -10,6 +9,30 @@ set instructions {
{pause}
{hlt}
{lock}
{inc register}
{dec register}
{not register}
{neg register}
{mul register}
{imul register}
{div register}
{idiv register}
{inc memory}
{dec memory}
{not memory}
{neg memory}
{mul memory}
{imul memory}
{div memory}
{idiv memory}
{add register register}
{or register register}
{adc register register}
{sbb register register}
{and register register}
{sub register register}
{xor register register}
{cmp register register}
}
# {mov register immediate}

@ -1,62 +1,71 @@
source debug/instructions.tcl
proc make_parser_rules {is} {
proc type_name_to_type_enum {n} {
switch $n {
"register" {
return "REG"
proc init_iarg {a n} {
set r [dict create]
switch $a {
"register" {
dict set r enum "REG"
dict set r value "\$$n.number"
dict set r size "\$$n.size"
}
"immediate" {
return "IMM"
dict set r enum "IMM"
dict set r value "(int)$e"
dict set r size "32"
}
"memory" {
return "MEM"
}
default {
malformed_instruction $n
}
}
}
proc type_name_to_type_value {n e} {
switch $n {
"register" {
return "$e.number"
}
"immediate" {
return "(int)$e"
}
"memory" {
return "???"
}
default {
malformed_instruction $n
"memory" {
dict set r enum "MEM"
dict set r value "0 /* ??? */"
dict set r size "0 /* ??? */"
}
default { malformed_instruction $n }
}
return $r
}
proc make_parser_rule {i} {
if {[llength $i] == 1} {
set rule [format " | I%s { append_instruction_t1(%s); }" \
set rule [format " | IT%s { append_instruction_t1(%s); }" \
[string toupper [lindex $i 0]] \
[string toupper [lindex $i 0]] \
[string toupper [lindex $i 0]]
]
} elseif {[llength $i] == 3} {
set rule [format " | I%s %s %s \{ append_instruction_t4(\
%s,\
\$2.size,\
} elseif {[llength $i] == 2} {
set arg [init_iarg [lindex $i 1] 2]
set rule [format " | IT%s %s \{ append_instruction_t4(\
%s,\
%s,\
%s,\
%s\
);" \
); \}" \
[string toupper [lindex $i 0]] \
[lindex $i 1] \
\
[string toupper [lindex $i 0]] \
[dict get $arg size] \
[dict get $arg enum] \
[dict get $arg value] \
]
} 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(\
%s,\
%s,\
%s,\
%s,\
%s,\
%s\
); \}" \
[string toupper [lindex $i 0]] \
[lindex $i 1] \
[lindex $i 2] \
\
[string toupper [lindex $i 0]] \
[type_name_to_type_enum [lindex $i 1]] \
[type_name_to_type_value [lindex $i 1] "\$2"] \
[type_name_to_type_enum [lindex $i 2]] \
[type_name_to_type_value [lindex $i 2] "\$3"] \
[dict get $arg1 size] \
[dict get $arg1 enum] \
[dict get $arg1 value] \
[dict get $arg2 enum] \
[dict get $arg2 value] \
]
} else {
malformed_instruction $i

@ -2,7 +2,7 @@ source debug/instructions.tcl
proc make_scanner_instructions {is} {
proc make_scanner_instruction {i} {
puts [format "%s { return I%s; }" \
puts [format "%s { return IT%s; }" \
[lindex $i 0] \
[string toupper [lindex $i 0]]
]
@ -12,4 +12,6 @@ proc make_scanner_instructions {is} {
}
}
puts " */"
make_scanner_instructions $instructions

@ -1,9 +1,16 @@
source debug/instructions.tcl
proc make_token_list {is} {
proc uniq_instl {is} {
set r []
foreach i $is {
lappend r [lindex $i 0]
}
return [lsort -unique $r]
}
puts -nonewline "%token"
foreach i $is {
puts -nonewline [format " I%s" [string toupper [lindex $i 0]]]
foreach i [uniq_instl $is] {
puts -nonewline [format " IT%s" [string toupper [lindex $i 0]]]
}
}

@ -103,8 +103,8 @@ u64 { return U64; }
\" { BEGIN IN_STRING; }
\!\= { return NEQ; }
\! { return TNOT; }
\!\= { return ITNEQ; }
\! { return ITNOT; }
\/\/ { BEGIN IN_COMMENT; }
\/\* { BEGIN IN_MULTILINE_COMMENT; }
@ -116,15 +116,45 @@ u64 { return U64; }
fastcall { return FASTCALL; }
/* --- Instrunctions begin here --- */
/*
xor{wsnl}+ { return TXOR; }
inc{wsnl}+ { return TINC; }
nop { return INOP; }
/* #placeholder<scanner_instructions> BEGIN
*/
add { return IADD; }
syscall { return ISYSCALL; }
mov { return IMOV; }
xor { return IXOR; }
/* #placeholder<scanner_instructions> COLLAPSED
syscall { return ITSYSCALL; }
sysret { return ITSYSRET; }
sysexit { return ITSYSEXIT; }
sysenter { return ITSYSENTER; }
leave { return ITLEAVE; }
retf { return ITRETF; }
retn { return ITRETN; }
pause { return ITPAUSE; }
hlt { return ITHLT; }
lock { return ITLOCK; }
inc { return ITINC; }
dec { return ITDEC; }
not { return ITNOT; }
neg { return ITNEG; }
mul { return ITMUL; }
imul { return ITIMUL; }
div { return ITDIV; }
idiv { return ITIDIV; }
inc { return ITINC; }
dec { return ITDEC; }
not { return ITNOT; }
neg { return ITNEG; }
mul { return ITMUL; }
imul { return ITIMUL; }
div { return ITDIV; }
idiv { return ITIDIV; }
add { return ITADD; }
or { return ITOR; }
adc { return ITADC; }
sbb { return ITSBB; }
and { return ITAND; }
sub { return ITSUB; }
xor { return ITXOR; }
cmp { return ITCMP; }
/* #placeholder<scanner_instructions> END
*/
/* --- Instrunctions end here --- */

@ -52,9 +52,9 @@
%token UNIX WIN64
// Logic
%token NEQ TNOT
%token ITNEQ
/*
%token TOR TXOR // these are (in)conveniently instructions too
%token ITOR ITXOR ITAND ITNOT // these are (in)conveniently instructions too
*/
// Type info
@ -79,13 +79,10 @@
%token RG8D RG9D RG10D RG11D RG12D RG13D RG14D RG15D
// Instructions
%token TADD TOR TADC TBB TXOR TAND TSUB TCMP TSYSCALL TINC
%token INOP // better temp prefix?
%token IADD
%token ISYSCALL
%token IMOV
%token IXOR
// #placeholder<token_list> COLLAPSED
%token INOP
// #placeholder<token_list> BEGIN
%token ITADC ITADD ITAND ITCMP ITDEC ITDIV ITHLT ITIDIV ITIMUL ITINC ITLEAVE ITLOCK ITMUL ITNEG ITNOT ITOR ITPAUSE ITRETF ITRETN ITSBB ITSUB ITSYSCALL ITSYSENTER ITSYSEXIT ITSYSRET ITXOR
// #placeholder<token_list> END
// Instruction-likes
%token FASTCALL
@ -208,28 +205,6 @@ code: %empty
| instruction code
;
instruction: INOP { ; }
/*
| TXOR register register code { /* assemble_xor(size_64b, type_register_register, $2, $3); * / }
| TXOR register immediate code { /* assemble_xor(size_64b, type_register_register, $2, $3); * / }
| TXOR IDENTIFIER register code { /* assemble_xor(size_64b, type_register_register, $2, $3); * / free($2); }
| TINC register code
| TINC IDENTIFIER code { free($2); }
*/
| IADD register register
| IADD register immediate
| IADD register memory
| ISYSCALL { append_instruction_t1 (SYSCALL); }
| IMOV register register
| IMOV memory register
| IMOV register memory
| IMOV register immediate { append_instruction_t6 (MOV, $2.size, REG, $2.number, IMM, (int) $3); }
| IMOV memory immediate
| IXOR register register
| IXOR register memory
// #placeholder<parser_rules> COLLAPSED
;
repeat: REPEAT code END_REPEAT
;
@ -237,13 +212,13 @@ if: IF logic THEN code END_IF
| IF logic THEN code ELSE code END_IF
;
logic: logical_operand TAND logical_operand
| logical_operand TOR logical_operand
| logical_operand TXOR logical_operand
| logical_operand '=' logical_operand
| logical_operand NEQ logical_operand
logic: logical_operand ITAND logical_operand
| logical_operand ITOR logical_operand
| logical_operand ITXOR logical_operand
| logical_operand '=' logical_operand
| logical_operand ITNEQ logical_operand
| sublogic
| TNOT logic
| ITNOT logic
;
logical_operand: sublogic
@ -345,4 +320,49 @@ artimetric_operand: LITERAL
exit: EXIT value
;
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
| 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 ); }
// #placeholder<parser_rules> END
;
%%