]> granicus.if.org Git - yasm/commitdiff
Enable and add support for (in gen_instr.pl) short xchg AX and EAX forms.
authorPeter Johnson <peter@tortall.net>
Thu, 5 Jul 2001 09:30:04 +0000 (09:30 -0000)
committerPeter Johnson <peter@tortall.net>
Thu, 5 Jul 2001 09:30:04 +0000 (09:30 -0000)
svn path=/trunk/yasm/; revision=112

modules/parsers/nasm/gen_instr.pl
src/gen_instr.pl
src/instrs.dat
src/parsers/nasm/gen_instr.pl

index f041d5402f28cf83c5f6c8163dadb4f8b3df37ac..3ec75f9fc04b4a31472af9fab30727890cda1ce6 100755 (executable)
@@ -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
index f041d5402f28cf83c5f6c8163dadb4f8b3df37ac..3ec75f9fc04b4a31472af9fab30727890cda1ce6 100755 (executable)
@@ -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
index 70a026f42af3b25db98eda0cfbb54ff745ccd75a..e1873a8365232049359fe55cc83b041bba4425a7 100644 (file)
@@ -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
index f041d5402f28cf83c5f6c8163dadb4f8b3df37ac..3ec75f9fc04b4a31472af9fab30727890cda1ce6 100755 (executable)
@@ -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