diff --git a/Makefile b/Makefile index 4bc2c17..30a141d 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/debug/instructions.tcl b/debug/instructions.tcl index b29ee6e..1e2a05f 100644 --- a/debug/instructions.tcl +++ b/debug/instructions.tcl @@ -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} diff --git a/debug/parser_rules.tcl b/debug/parser_rules.tcl index e7b158e..9ca6592 100644 --- a/debug/parser_rules.tcl +++ b/debug/parser_rules.tcl @@ -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 diff --git a/debug/scanner_instructions.tcl b/debug/scanner_instructions.tcl index fcf5d00..6cff71a 100644 --- a/debug/scanner_instructions.tcl +++ b/debug/scanner_instructions.tcl @@ -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 diff --git a/debug/token_list.tcl b/debug/token_list.tcl index e4c1c11..d26df35 100644 --- a/debug/token_list.tcl +++ b/debug/token_list.tcl @@ -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]]] } } diff --git a/source/eaxhla.l b/source/eaxhla.l index b89cc69..8d10943 100644 --- a/source/eaxhla.l +++ b/source/eaxhla.l @@ -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 BEGIN */ -add { return IADD; } -syscall { return ISYSCALL; } -mov { return IMOV; } -xor { return IXOR; } - /* #placeholder 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 END */ /* --- Instrunctions end here --- */ diff --git a/source/eaxhla.y b/source/eaxhla.y index cc106c2..af8e376 100644 --- a/source/eaxhla.y +++ b/source/eaxhla.y @@ -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 COLLAPSED +%token INOP +// #placeholder 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 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 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 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 END + ; + %%