2006-12-28 H.J. Lu <hongjiu.lu@intel.com>
authorH.J. Lu <hjl.tools@gmail.com>
Fri, 29 Dec 2006 06:02:04 +0000 (06:02 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 29 Dec 2006 06:02:04 +0000 (06:02 +0000)
* config/tc-i386.c (process_operands): Check i.reg_operands
and increment i.operands when adding a register operand.
(build_modrm_byte): Fix 4 operand instruction handling.

gas/ChangeLog
gas/config/tc-i386.c

index c545ce1b34ebd32a12dcba102b400f0fa2c68065..bb811e3e2cc63c7abd6eb518f4383bea362f8271 100644 (file)
@@ -1,3 +1,9 @@
+2006-12-28  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * config/tc-i386.c (process_operands): Check i.reg_operands
+       and increment i.operands when adding a register operand.
+       (build_modrm_byte): Fix 4 operand instruction handling.
+
 2006-12-27  H.J. Lu  <hongjiu.lu@intel.com>
 
        * config/tc-i386.c (disp_expressions): Use MAX_MEMORY_OPERANDS
index 856e953da4a1cd871ccc2aa14e3e47d3d738f495..079e9d88660c6ae2f45bcd7f3aa22b0c6350d6ac 100644 (file)
@@ -3335,10 +3335,12 @@ process_operands ()
     {
       unsigned int first_reg_op = (i.types[0] & Reg) ? 0 : 1;
       /* Pretend we saw the extra register operand.  */
-      assert (i.op[first_reg_op + 1].regs == 0);
+      assert (i.reg_operands == 1
+             && i.op[first_reg_op + 1].regs == 0);
       i.op[first_reg_op + 1].regs = i.op[first_reg_op].regs;
       i.types[first_reg_op + 1] = i.types[first_reg_op];
-      i.reg_operands = 2;
+      i.operands++;
+      i.reg_operands++;
     }
 
   if (i.tm.opcode_modifier & ShortForm)
@@ -3427,16 +3429,30 @@ build_modrm_byte ()
   if (i.reg_operands == 2)
     {
       unsigned int source, dest;
-      source = ((i.types[0]
-                & (Reg | RegMMX | RegXMM
-                   | SReg2 | SReg3
-                   | Control | Debug | Test))
-               ? 0 : 1);
 
-      /* In 4 operands instructions with 2 immediate operands, the first
-         two are immediate bytes and hence source operand will be in the
-        next byte after the immediates */
-      if ((i.operands == 4)&&(i.imm_operands=2)) source++; 
+      switch (i.operands)
+       {
+       case 2:
+         source = 0;
+         break;
+       case 3:
+         /* When there are 3 operands, one of them must be immediate,
+            which may be the first or the last operand.  */
+         assert (i.imm_operands == 1);
+         source = (i.types[0] & Imm) ? 1 : 0;
+         break;
+       case 4:
+         /* When there are 4 operands, the first two must be immediate
+            operands. The source operand will be the 3rd one.  */
+         assert (i.imm_operands == 2
+                 && (i.types[0] & Imm)
+                 && (i.types[1] & Imm));
+         source = 2;
+         break;
+       default:
+         abort ();
+       }
+
       dest = source + 1;
 
       i.rm.mode = 3;