gas/
authorH.J. Lu <hjl.tools@gmail.com>
Wed, 13 Dec 2006 18:00:00 +0000 (18:00 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 13 Dec 2006 18:00:00 +0000 (18:00 +0000)
2006-12-13  H.J. Lu  <hongjiu.lu@intel.com>

PR gas/3712
* config/tc-i386.c (match_template): Use MAX_OPERANDS for the
number of operands. Issue an error if MAX_OPERANDS != 4. Add
the 4th operand check.

gas/testsuite/

2006-12-13  H.J. Lu  <hongjiu.lu@intel.com>

PR gas/3712
* gas/i386/inval.s: Add invalid insertq.
* gas/i386/x86-64-inval.s: Likewise.

* gas/i386/inval.l: Updated.
* gas/i386/x86-64-inval.l: Likewise.

gas/ChangeLog
gas/config/tc-i386.c
gas/testsuite/ChangeLog
gas/testsuite/gas/i386/inval.l
gas/testsuite/gas/i386/inval.s
gas/testsuite/gas/i386/x86-64-inval.l
gas/testsuite/gas/i386/x86-64-inval.s

index 7ef8904..94357ae 100644 (file)
@@ -1,3 +1,10 @@
+2006-12-13  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR gas/3712
+       * config/tc-i386.c (match_template): Use MAX_OPERANDS for the
+       number of operands. Issue an error if MAX_OPERANDS != 4. Add
+       the 4th operand check.
+
 2006-12-13  Paul Brook  <paul@codesourcery.com>
 
        * config/tc-arm.c (arm_arch_option_table): Add v7-{a,r,m}.
index 767e7e3..01f56b0 100644 (file)
@@ -2568,12 +2568,16 @@ match_template ()
 {
   /* Points to template once we've found it.  */
   const template *t;
-  unsigned int overlap0, overlap1, overlap2;
+  unsigned int overlap0, overlap1, overlap2, overlap3;
   unsigned int found_reverse_match;
   int suffix_check;
-  unsigned int operand_types [3];
+  unsigned int operand_types [MAX_OPERANDS];
   int addr_prefix_disp;
 
+#if MAX_OPERANDS != 4
+# error "MAX_OPERANDS must be 4."
+#endif
+
 #define MATCH(overlap, given, template)                                \
   ((overlap & ~JumpAbsolute)                                   \
    && (((given) & (BaseIndex | JumpAbsolute))                  \
@@ -2590,10 +2594,12 @@ match_template ()
   overlap0 = 0;
   overlap1 = 0;
   overlap2 = 0;
+  overlap3 = 0;
   found_reverse_match = 0;
   operand_types [0] = 0;
   operand_types [1] = 0;
   operand_types [2] = 0;
+  operand_types [3] = 0;
   addr_prefix_disp = -1;
   suffix_check = (i.suffix == BYTE_MNEM_SUFFIX
                  ? No_bSuf
@@ -2625,6 +2631,7 @@ match_template ()
       operand_types [0] = t->operand_types [0];
       operand_types [1] = t->operand_types [1];
       operand_types [2] = t->operand_types [2];
+      operand_types [3] = t->operand_types [3];
 
       /* In general, don't allow 64-bit operands in 32-bit mode.  */
       if (i.suffix == QWORD_MNEM_SUFFIX
@@ -2670,7 +2677,7 @@ match_template ()
              break;
            }
 
-           for (j = 0; j < 3; j++)
+           for (j = 0; j < MAX_OPERANDS; j++)
              {
                /* There should be only one Disp operand.  */
                if ((operand_types[j] & DispOff))
@@ -2692,6 +2699,7 @@ match_template ()
          break;
        case 2:
        case 3:
+       case 4:
          overlap1 = i.types[1] & operand_types[1];
          if (!MATCH (overlap0, i.types[0], operand_types[0])
              || !MATCH (overlap1, i.types[1], operand_types[1])
@@ -2726,23 +2734,42 @@ match_template ()
                 we've found.  */
              found_reverse_match = t->opcode_modifier & (D | FloatDR);
            }
-         /* Found a forward 2 operand match here.  */
-         else if (t->operands == 3)
+         else
            {
-             /* Here we make use of the fact that there are no
-                reverse match 3 operand instructions, and all 3
-                operand instructions only need to be checked for
-                register consistency between operands 2 and 3.  */
-             overlap2 = i.types[2] & operand_types[2];
-             if (!MATCH (overlap2, i.types[2], operand_types[2])
-                 || !CONSISTENT_REGISTER_MATCH (overlap1, i.types[1],
-                                                operand_types[1],
-                                                overlap2, i.types[2],
-                                                operand_types[2]))
+             /* Found a forward 2 operand match here.  */
+             if (t->operands > 2)
+               overlap2 = i.types[2] & operand_types[2];
+             if (t->operands > 3)
+               overlap3 = i.types[3] & operand_types[3];
 
-               continue;
+             switch (t->operands)
+               {
+               case 4:
+                 if (!MATCH (overlap3, i.types[3], operand_types[3])
+                     || !CONSISTENT_REGISTER_MATCH (overlap2,
+                                                    i.types[2],
+                                                    operand_types[2],
+                                                    overlap3,
+                                                    i.types[3],
+                                                    operand_types[3]))
+                   continue;
+               case 3:
+                 /* Here we make use of the fact that there are no
+                    reverse match 3 operand instructions, and all 3
+                    operand instructions only need to be checked for
+                    register consistency between operands 2 and 3.  */
+                 if (!MATCH (overlap2, i.types[2], operand_types[2])
+                     || !CONSISTENT_REGISTER_MATCH (overlap1,
+                                                    i.types[1],
+                                                    operand_types[1],
+                                                    overlap2,
+                                                    i.types[2],
+                                                    operand_types[2]))
+                   continue;
+                 break;
+               }
            }
-         /* Found either forward/reverse 2 or 3 operand match here:
+         /* Found either forward/reverse 2, 3 or 4 operand match here:
             slip through to break.  */
        }
       if (t->cpu_flags & ~cpu_arch_flags)
index fb37d77..4e8b4ff 100644 (file)
@@ -1,3 +1,12 @@
+2006-12-13  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR gas/3712
+       * gas/i386/inval.s: Add invalid insertq.
+       * gas/i386/x86-64-inval.s: Likewise.
+
+       * gas/i386/inval.l: Updated.
+       * gas/i386/x86-64-inval.l: Likewise.
+
 2006-12-08  Christian Groessler  <chris@groessler.org>
 
        * gas/z8k/reglabel.d: New test.
index 9f32368..8abcbde 100644 (file)
@@ -46,6 +46,7 @@
 .*:47: Error: .*
 .*:48: Error: .*
 .*:49: Error: .*
+.*:50: Error: .*
 GAS LISTING .*
 
 
@@ -98,3 +99,4 @@ GAS LISTING .*
   47 [         ]*      fcompll 28\(%ebp\)
   48 [         ]*      fldlw   \(%eax\)
   49 [         ]*      movl    \$%ebx,%eax
+  50 [         ]*      insertq \$4,\$2,%xmm2,%ebx
index 1571a2f..5b440ed 100644 (file)
@@ -47,3 +47,4 @@ foo:  jaw     foo
        fcompll 28(%ebp)
        fldlw   (%eax)
        movl    $%ebx,%eax
+       insertq $4,$2,%xmm2,%ebx
index aa080cb..2e45b46 100644 (file)
@@ -48,6 +48,7 @@
 .*:49: Error: .*
 .*:50: Error: .*
 .*:51: Error: .*
+.*:52: Error: .*
 GAS LISTING .*
 
 
@@ -102,3 +103,4 @@ GAS LISTING .*
   49 [         ]*pushfl                # can't have 32-bit stack operands
   50 [         ]*popfl         # can't have 32-bit stack operands
   51 [         ]*retl          # can't have 32-bit stack operands
+  52 [         ]*insertq \$4,\$2,%xmm2,%ebx # The last operand must be XMM register.
index b069a28..68f4cb5 100644 (file)
@@ -49,3 +49,4 @@ foo:  jcxz foo        # No prefix exists to select CX as a counter
         pushfl         # can't have 32-bit stack operands
        popfl           # can't have 32-bit stack operands
        retl            # can't have 32-bit stack operands
+       insertq $4,$2,%xmm2,%ebx # The last operand must be XMM register.