This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: PATCH: Fix x86 4 operand instruction handling
- From: "H. J. Lu" <hjl at lucon dot org>
- To: binutils at sources dot redhat dot com
- Cc: michael dot meissner at amd dot com, dwarak dot rajagopal at amd dot com
- Date: Thu, 28 Dec 2006 17:56:04 -0800
- Subject: Re: PATCH: Fix x86 4 operand instruction handling
- References: <20061228223940.GA8218@lucon.org> <20061228232737.GA8388@lucon.org>
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;