This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH: Fix x86 4 operand instruction handling


On Thu, Dec 28, 2006 at 03:27:37PM -0800, H. J. Lu wrote:
> On Thu, Dec 28, 2006 at 02:39:40PM -0800, H. J. Lu wrote:
> > The current code has
> > 
> > if ((i.operands == 4)&&(i.imm_operands=2)) source++;
> > 			^^^^^^^^^^^^^^^^^
> > 
> > It is wrong. I am checking in this patch.
> > 
> 
> I am testing this patch instead now.
> 

Ooops. Wrong patch. This is the correct one.


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

	* config/tc-i386.c (process_operands): Increment i.operands
	when adding a register operand.
	(build_modrm_byte): Fix 4 operand instruction handling.

--- gas/config/tc-i386.c.4op	2006-12-28 17:40:30.000000000 -0800
+++ gas/config/tc-i386.c	2006-12-28 17:31:36.000000000 -0800
@@ -3338,6 +3338,7 @@ process_operands ()
       assert (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.operands++;
       i.reg_operands = 2;
     }
 
@@ -3427,16 +3428,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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]