From: Peter Johnson Date: Thu, 5 Jul 2001 09:30:04 +0000 (-0000) Subject: Enable and add support for (in gen_instr.pl) short xchg AX and EAX forms. X-Git-Tag: v0.1.0~399 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=daf5c6fd03b3d85e478196078c998d76bb643486;p=yasm Enable and add support for (in gen_instr.pl) short xchg AX and EAX forms. svn path=/trunk/yasm/; revision=112 --- diff --git a/modules/parsers/nasm/gen_instr.pl b/modules/parsers/nasm/gen_instr.pl index f041d540..3ec75f9f 100755 --- a/modules/parsers/nasm/gen_instr.pl +++ b/modules/parsers/nasm/gen_instr.pl @@ -1,5 +1,5 @@ #!/usr/bin/perl -w -# $Id: gen_instr.pl,v 1.14 2001/07/05 07:21:35 peter Exp $ +# $Id: gen_instr.pl,v 1.15 2001/07/05 09:30:04 peter Exp $ # Generates bison.y and token.l from instrs.dat for YASM # # Copyright (C) 2001 Michael Urman @@ -312,19 +312,41 @@ sub rule_footer () { return " }\n"; } -sub cond_action ( $ $ $ $ $ $ $ $ ) + +sub cond_action_if ( $ $ $ $ $ $ $ ) { - my ($rule, $tokens, $count, $regarg, $val, $func, $a_eax, $a_args) - = splice (@_); - return rule_header ($rule, $tokens, $count) . <<"EOF" . rule_footer; + my ($rule, $tokens, $count, $regarg, $val, $func, $a_eax) = splice (@_); + return rule_header ($rule, $tokens, $count) . <<"EOF"; if (\$$regarg == $val) { $func(@$a_eax); } +EOF +} +sub cond_action_elsif ( $ $ $ $ ) +{ + my ($regarg, $val, $func, $a_eax) = splice (@_); + return <<"EOF"; + else if (\$$regarg == $val) { + $func(@$a_eax); + } +EOF +} +sub cond_action_else ( $ $ ) +{ + my ($func, $a_args) = splice (@_); + return <<"EOF" . rule_footer; else { $func (@$a_args); } EOF } +sub cond_action ( $ $ $ $ $ $ $ $ ) +{ + my ($rule, $tokens, $count, $regarg, $val, $func, $a_eax, $a_args) + = splice (@_); + return cond_action_if ($rule, $tokens, $count, $regarg, $val, $func, + $a_eax) . cond_action_else ($func, $a_args); +} #sub action ( $ $ $ $ $ ) sub action ( @ $ ) @@ -400,6 +422,7 @@ sub output_yacc ($@) join( "\n | ", sort keys %$groups), "\n;\n"; my ($ONE, $AL, $AX, $EAX); # need the outer scope + my (@XCHG_AX, @XCHG_EAX); # list the arguments and actions (buildbc) #foreach my $instrname (sort keys %$instrlist) @@ -414,6 +437,8 @@ sub output_yacc ($@) # BUT, if we don't fold it in, we have to generate the # original version we would have otherwise. ($ONE, $AL, $AX, $EAX) = (0, 0, 0, 0); + # Folding for xchg (REG_E?AX,reg16 and reg16,REG_E?AX). + (@XCHG_AX, @XCHG_EAX) = ((0, 0), (0, 0)); my $count = 0; foreach my $inst (@{$groups->{$group}{rules}}) { # build the instruction in pieces. @@ -511,6 +536,22 @@ sub output_yacc ($@) { $EAX = [ $rule, $tokens, $func, \@args]; } + elsif (($inst->[OPERANDS]||"") =~ m/REG_AX,reg16/) + { + $XCHG_AX[0] = [ $rule, $tokens, $func, \@args]; + } + elsif (($inst->[OPERANDS]||"") =~ m/reg16,REG_AX/) + { + $XCHG_AX[1] = [ $rule, $tokens, $func, \@args]; + } + elsif (($inst->[OPERANDS]||"") =~ m/REG_EAX,reg32/) + { + $XCHG_EAX[0] = [ $rule, $tokens, $func, \@args]; + } + elsif (($inst->[OPERANDS]||"") =~ m/reg32,REG_EAX/) + { + $XCHG_EAX[1] = [ $rule, $tokens, $func, \@args]; + } # or if we've deferred and we match the folding version elsif ($ONE and ($inst->[OPERANDS]||"") =~ m/imm8/) @@ -541,6 +582,66 @@ sub output_yacc ($@) print GRAMMAR cond_action ($rule, $tokens, $count++, $regarg, 0, $func, $EAX->[3], \@args); } + elsif (($XCHG_AX[0] or $XCHG_AX[1]) and + ($inst->[OPERANDS]||"") =~ m/reg16,reg16/) + { + my $first = 1; + for (my $i=0; $i < @XCHG_AX; ++$i) + { + if($XCHG_AX[$i]) + { + $XCHG_AX[$i]->[4] = 1; + # This is definitely a hack. The "right" way + # to do this would be to enhance + # get_token_number to get the nth reg16 + # instead of always getting the first. + my $regarg = + get_token_number ($tokens, "reg16") + $i*2; + + if ($first) + { + print GRAMMAR cond_action_if ($rule, $tokens, $count++, $regarg, 0, $func, $XCHG_AX[$i]->[3]); + $first = 0; + } + else + { + $count++; + print GRAMMAR cond_action_elsif ($regarg, 0, $func, $XCHG_AX[$i]->[3]); + } + } + } + print GRAMMAR cond_action_else ($func, \@args); + } + elsif (($XCHG_EAX[0] or $XCHG_EAX[1]) and + ($inst->[OPERANDS]||"") =~ m/reg32,reg32/) + { + my $first = 1; + for (my $i=0; $i < @XCHG_EAX; ++$i) + { + if($XCHG_EAX[$i]) + { + $XCHG_EAX[$i]->[4] = 1; + # This is definitely a hack. The "right" way + # to do this would be to enhance + # get_token_number to get the nth reg32 + # instead of always getting the first. + my $regarg = + get_token_number ($tokens, "reg32") + $i*2; + + if ($first) + { + print GRAMMAR cond_action_if ($rule, $tokens, $count++, $regarg, 0, $func, $XCHG_EAX[$i]->[3]); + $first = 0; + } + else + { + $count++; + print GRAMMAR cond_action_elsif ($regarg, 0, $func, $XCHG_EAX[$i]->[3]); + } + } + } + print GRAMMAR cond_action_else ($func, \@args); + } # otherwise, generate the normal version else diff --git a/src/gen_instr.pl b/src/gen_instr.pl index f041d540..3ec75f9f 100755 --- a/src/gen_instr.pl +++ b/src/gen_instr.pl @@ -1,5 +1,5 @@ #!/usr/bin/perl -w -# $Id: gen_instr.pl,v 1.14 2001/07/05 07:21:35 peter Exp $ +# $Id: gen_instr.pl,v 1.15 2001/07/05 09:30:04 peter Exp $ # Generates bison.y and token.l from instrs.dat for YASM # # Copyright (C) 2001 Michael Urman @@ -312,19 +312,41 @@ sub rule_footer () { return " }\n"; } -sub cond_action ( $ $ $ $ $ $ $ $ ) + +sub cond_action_if ( $ $ $ $ $ $ $ ) { - my ($rule, $tokens, $count, $regarg, $val, $func, $a_eax, $a_args) - = splice (@_); - return rule_header ($rule, $tokens, $count) . <<"EOF" . rule_footer; + my ($rule, $tokens, $count, $regarg, $val, $func, $a_eax) = splice (@_); + return rule_header ($rule, $tokens, $count) . <<"EOF"; if (\$$regarg == $val) { $func(@$a_eax); } +EOF +} +sub cond_action_elsif ( $ $ $ $ ) +{ + my ($regarg, $val, $func, $a_eax) = splice (@_); + return <<"EOF"; + else if (\$$regarg == $val) { + $func(@$a_eax); + } +EOF +} +sub cond_action_else ( $ $ ) +{ + my ($func, $a_args) = splice (@_); + return <<"EOF" . rule_footer; else { $func (@$a_args); } EOF } +sub cond_action ( $ $ $ $ $ $ $ $ ) +{ + my ($rule, $tokens, $count, $regarg, $val, $func, $a_eax, $a_args) + = splice (@_); + return cond_action_if ($rule, $tokens, $count, $regarg, $val, $func, + $a_eax) . cond_action_else ($func, $a_args); +} #sub action ( $ $ $ $ $ ) sub action ( @ $ ) @@ -400,6 +422,7 @@ sub output_yacc ($@) join( "\n | ", sort keys %$groups), "\n;\n"; my ($ONE, $AL, $AX, $EAX); # need the outer scope + my (@XCHG_AX, @XCHG_EAX); # list the arguments and actions (buildbc) #foreach my $instrname (sort keys %$instrlist) @@ -414,6 +437,8 @@ sub output_yacc ($@) # BUT, if we don't fold it in, we have to generate the # original version we would have otherwise. ($ONE, $AL, $AX, $EAX) = (0, 0, 0, 0); + # Folding for xchg (REG_E?AX,reg16 and reg16,REG_E?AX). + (@XCHG_AX, @XCHG_EAX) = ((0, 0), (0, 0)); my $count = 0; foreach my $inst (@{$groups->{$group}{rules}}) { # build the instruction in pieces. @@ -511,6 +536,22 @@ sub output_yacc ($@) { $EAX = [ $rule, $tokens, $func, \@args]; } + elsif (($inst->[OPERANDS]||"") =~ m/REG_AX,reg16/) + { + $XCHG_AX[0] = [ $rule, $tokens, $func, \@args]; + } + elsif (($inst->[OPERANDS]||"") =~ m/reg16,REG_AX/) + { + $XCHG_AX[1] = [ $rule, $tokens, $func, \@args]; + } + elsif (($inst->[OPERANDS]||"") =~ m/REG_EAX,reg32/) + { + $XCHG_EAX[0] = [ $rule, $tokens, $func, \@args]; + } + elsif (($inst->[OPERANDS]||"") =~ m/reg32,REG_EAX/) + { + $XCHG_EAX[1] = [ $rule, $tokens, $func, \@args]; + } # or if we've deferred and we match the folding version elsif ($ONE and ($inst->[OPERANDS]||"") =~ m/imm8/) @@ -541,6 +582,66 @@ sub output_yacc ($@) print GRAMMAR cond_action ($rule, $tokens, $count++, $regarg, 0, $func, $EAX->[3], \@args); } + elsif (($XCHG_AX[0] or $XCHG_AX[1]) and + ($inst->[OPERANDS]||"") =~ m/reg16,reg16/) + { + my $first = 1; + for (my $i=0; $i < @XCHG_AX; ++$i) + { + if($XCHG_AX[$i]) + { + $XCHG_AX[$i]->[4] = 1; + # This is definitely a hack. The "right" way + # to do this would be to enhance + # get_token_number to get the nth reg16 + # instead of always getting the first. + my $regarg = + get_token_number ($tokens, "reg16") + $i*2; + + if ($first) + { + print GRAMMAR cond_action_if ($rule, $tokens, $count++, $regarg, 0, $func, $XCHG_AX[$i]->[3]); + $first = 0; + } + else + { + $count++; + print GRAMMAR cond_action_elsif ($regarg, 0, $func, $XCHG_AX[$i]->[3]); + } + } + } + print GRAMMAR cond_action_else ($func, \@args); + } + elsif (($XCHG_EAX[0] or $XCHG_EAX[1]) and + ($inst->[OPERANDS]||"") =~ m/reg32,reg32/) + { + my $first = 1; + for (my $i=0; $i < @XCHG_EAX; ++$i) + { + if($XCHG_EAX[$i]) + { + $XCHG_EAX[$i]->[4] = 1; + # This is definitely a hack. The "right" way + # to do this would be to enhance + # get_token_number to get the nth reg32 + # instead of always getting the first. + my $regarg = + get_token_number ($tokens, "reg32") + $i*2; + + if ($first) + { + print GRAMMAR cond_action_if ($rule, $tokens, $count++, $regarg, 0, $func, $XCHG_EAX[$i]->[3]); + $first = 0; + } + else + { + $count++; + print GRAMMAR cond_action_elsif ($regarg, 0, $func, $XCHG_EAX[$i]->[3]); + } + } + } + print GRAMMAR cond_action_else ($func, \@args); + } # otherwise, generate the normal version else diff --git a/src/instrs.dat b/src/instrs.dat index 70a026f4..e1873a83 100644 --- a/src/instrs.dat +++ b/src/instrs.dat @@ -1,4 +1,4 @@ -; $Id: instrs.dat,v 1.27 2001/07/05 07:00:01 peter Exp $ +; $Id: instrs.dat,v 1.28 2001/07/05 09:30:04 peter Exp $ ; List of valid instruction/operand combinations ; ; Copyright (C) 2001 Peter Johnson @@ -197,20 +197,20 @@ popaw!onebyte 10,61 186 ; ; Exchange instructions ; -;xchg REG_AX,reg16 16 90+$2 nil nil 8086 -;xchg reg16,REG_AX 16 90+$1 nil nil 8086 -;xchg REG_EAX,reg32 32 90+$2 nil nil 386 -;xchg reg32,REG_EAX 32 90+$1 nil nil 386 ; arbitrary encoding, picked $1r,$2 instead of $2r,$1 xchg reg8,reg8 nil 86 $1r,$2 nil 8086 xchg mem,reg8 nil 86 $1,$2 nil 8086 xchg mem8x,reg8 nil 86 $1,$2 nil 8086 xchg reg8,mem8 nil 86 $2,$1 nil 8086 +xchg REG_AX,reg16 16 90+$2 nil nil 8086 +xchg reg16,REG_AX 16 90+$1 nil nil 8086 ; arbitrary encoding, picked $1r,$2 instead of $2r,$1 xchg reg16,reg16 16 87 $1r,$2 nil 8086 xchg mem,reg16 16 87 $1,$2 nil 8086 xchg mem16x,reg16 16 87 $1,$2 nil 8086 xchg reg16,mem16 16 87 $2,$1 nil 8086 +xchg REG_EAX,reg32 32 90+$2 nil nil 386 +xchg reg32,REG_EAX 32 90+$1 nil nil 386 ; arbitrary encoding, picked $1r,$2 instead of $2r,$1 xchg reg32,reg32 32 87 $1r,$2 nil 386 xchg mem,reg32 32 87 $1,$2 nil 386 diff --git a/src/parsers/nasm/gen_instr.pl b/src/parsers/nasm/gen_instr.pl index f041d540..3ec75f9f 100755 --- a/src/parsers/nasm/gen_instr.pl +++ b/src/parsers/nasm/gen_instr.pl @@ -1,5 +1,5 @@ #!/usr/bin/perl -w -# $Id: gen_instr.pl,v 1.14 2001/07/05 07:21:35 peter Exp $ +# $Id: gen_instr.pl,v 1.15 2001/07/05 09:30:04 peter Exp $ # Generates bison.y and token.l from instrs.dat for YASM # # Copyright (C) 2001 Michael Urman @@ -312,19 +312,41 @@ sub rule_footer () { return " }\n"; } -sub cond_action ( $ $ $ $ $ $ $ $ ) + +sub cond_action_if ( $ $ $ $ $ $ $ ) { - my ($rule, $tokens, $count, $regarg, $val, $func, $a_eax, $a_args) - = splice (@_); - return rule_header ($rule, $tokens, $count) . <<"EOF" . rule_footer; + my ($rule, $tokens, $count, $regarg, $val, $func, $a_eax) = splice (@_); + return rule_header ($rule, $tokens, $count) . <<"EOF"; if (\$$regarg == $val) { $func(@$a_eax); } +EOF +} +sub cond_action_elsif ( $ $ $ $ ) +{ + my ($regarg, $val, $func, $a_eax) = splice (@_); + return <<"EOF"; + else if (\$$regarg == $val) { + $func(@$a_eax); + } +EOF +} +sub cond_action_else ( $ $ ) +{ + my ($func, $a_args) = splice (@_); + return <<"EOF" . rule_footer; else { $func (@$a_args); } EOF } +sub cond_action ( $ $ $ $ $ $ $ $ ) +{ + my ($rule, $tokens, $count, $regarg, $val, $func, $a_eax, $a_args) + = splice (@_); + return cond_action_if ($rule, $tokens, $count, $regarg, $val, $func, + $a_eax) . cond_action_else ($func, $a_args); +} #sub action ( $ $ $ $ $ ) sub action ( @ $ ) @@ -400,6 +422,7 @@ sub output_yacc ($@) join( "\n | ", sort keys %$groups), "\n;\n"; my ($ONE, $AL, $AX, $EAX); # need the outer scope + my (@XCHG_AX, @XCHG_EAX); # list the arguments and actions (buildbc) #foreach my $instrname (sort keys %$instrlist) @@ -414,6 +437,8 @@ sub output_yacc ($@) # BUT, if we don't fold it in, we have to generate the # original version we would have otherwise. ($ONE, $AL, $AX, $EAX) = (0, 0, 0, 0); + # Folding for xchg (REG_E?AX,reg16 and reg16,REG_E?AX). + (@XCHG_AX, @XCHG_EAX) = ((0, 0), (0, 0)); my $count = 0; foreach my $inst (@{$groups->{$group}{rules}}) { # build the instruction in pieces. @@ -511,6 +536,22 @@ sub output_yacc ($@) { $EAX = [ $rule, $tokens, $func, \@args]; } + elsif (($inst->[OPERANDS]||"") =~ m/REG_AX,reg16/) + { + $XCHG_AX[0] = [ $rule, $tokens, $func, \@args]; + } + elsif (($inst->[OPERANDS]||"") =~ m/reg16,REG_AX/) + { + $XCHG_AX[1] = [ $rule, $tokens, $func, \@args]; + } + elsif (($inst->[OPERANDS]||"") =~ m/REG_EAX,reg32/) + { + $XCHG_EAX[0] = [ $rule, $tokens, $func, \@args]; + } + elsif (($inst->[OPERANDS]||"") =~ m/reg32,REG_EAX/) + { + $XCHG_EAX[1] = [ $rule, $tokens, $func, \@args]; + } # or if we've deferred and we match the folding version elsif ($ONE and ($inst->[OPERANDS]||"") =~ m/imm8/) @@ -541,6 +582,66 @@ sub output_yacc ($@) print GRAMMAR cond_action ($rule, $tokens, $count++, $regarg, 0, $func, $EAX->[3], \@args); } + elsif (($XCHG_AX[0] or $XCHG_AX[1]) and + ($inst->[OPERANDS]||"") =~ m/reg16,reg16/) + { + my $first = 1; + for (my $i=0; $i < @XCHG_AX; ++$i) + { + if($XCHG_AX[$i]) + { + $XCHG_AX[$i]->[4] = 1; + # This is definitely a hack. The "right" way + # to do this would be to enhance + # get_token_number to get the nth reg16 + # instead of always getting the first. + my $regarg = + get_token_number ($tokens, "reg16") + $i*2; + + if ($first) + { + print GRAMMAR cond_action_if ($rule, $tokens, $count++, $regarg, 0, $func, $XCHG_AX[$i]->[3]); + $first = 0; + } + else + { + $count++; + print GRAMMAR cond_action_elsif ($regarg, 0, $func, $XCHG_AX[$i]->[3]); + } + } + } + print GRAMMAR cond_action_else ($func, \@args); + } + elsif (($XCHG_EAX[0] or $XCHG_EAX[1]) and + ($inst->[OPERANDS]||"") =~ m/reg32,reg32/) + { + my $first = 1; + for (my $i=0; $i < @XCHG_EAX; ++$i) + { + if($XCHG_EAX[$i]) + { + $XCHG_EAX[$i]->[4] = 1; + # This is definitely a hack. The "right" way + # to do this would be to enhance + # get_token_number to get the nth reg32 + # instead of always getting the first. + my $regarg = + get_token_number ($tokens, "reg32") + $i*2; + + if ($first) + { + print GRAMMAR cond_action_if ($rule, $tokens, $count++, $regarg, 0, $func, $XCHG_EAX[$i]->[3]); + $first = 0; + } + else + { + $count++; + print GRAMMAR cond_action_elsif ($regarg, 0, $func, $XCHG_EAX[$i]->[3]); + } + } + } + print GRAMMAR cond_action_else ($func, \@args); + } # otherwise, generate the normal version else