[PATCH] Add x86 SSE5 instructions to the GNU binary utilities

rajagopal, dwarak dwarak.rajagopal@amd.com
Thu Sep 13 22:31:00 GMT 2007


The patch does not contain the generated files (i386-init.h and
i386-tbl.h). I have also fixed the coding typos you mentioned in the
assembler.

Is this ok?

Thanks,
- Dwarak

> -----Original Message-----
> From: H.J. Lu [mailto:hjl@lucon.org]
> Sent: Thursday, September 13, 2007 3:30 PM
> To: rajagopal, dwarak
> Cc: binutils@sourceware.org; Meissner, Michael; Harle, Christophe
> Subject: Re: [PATCH] Add x86 SSE5 instructions to the GNU binary
utilities
> 
> On Thu, Sep 13, 2007 at 03:08:54PM -0500, rajagopal, dwarak wrote:
> > The enclosed patch adds support for the SSE5 instructions to the
> > assembler and disassembler.
> >
> > I have made changes to the original patch so that it uses bitfields
(the
> > new infrastructure changes which H.J had checked in last week) for
> > cpu_flag, opcode_modifier and operand_types for the new
instructions.
> >
> > Is this ok?
> >
> 
> Here are my comments on assembler. I will take a look at disassembler
> later.
> 
> 
> H.J.
> ---
> diff -purwN --exclude=autom4te.cache --exclude=po --exclude=intl
> src/binutils/NEWS src-sse5/binutils/NEWS
> --- src/binutils/NEWS	2007-08-30 08:47:35.000000000 -0500
> +      assert (i.imm_operands == 0
> +	      && (i.operands <= 2
> +		  || ((i.tm.cpu_flags.bitfield.cpusse5) != 0
> +		      && i.operands <= 3)));
> 
> Please use
> 
> || (i.tm.cpu_flags.bitfield.cpusse5
>     && i.operands <= 3)
> 
>        exp = &im_expressions[i.imm_operands++];
>        i.op[i.operands].imms = exp;
> @@ -2338,7 +2349,14 @@ md_assemble (line)
>  	}
>      }
> 
> -  if (i.rex != 0)
> +  /* If the instruction has the DREX attribute (aka SSE5), don't emit
a
> +     REX prefix.  */
> +  if ((i.tm.opcode_modifier.drex | i.tm.opcode_modifier.drexc) != 0)
> 
> Please use
> 
> if (i.tm.opcode_modifier.drex || i.tm.opcode_modifier.drexc)
> 
> +      /* Case 2: 4 operand insn, dest = src1, src3 = memory.  */
> +      else if (i.types[0].bitfield.regxmm != 0
> +	       && i.types[1].bitfield.regxmm != 0
> +	       && (i.types[2].bitfield.regxmm | operand_type_check
> (i.types[2], anymem)) != 0
> 
> Did you mean
> 
> (i.types[2].bitfield.regxmm
> || operand_type_check (i.types[2], anymem))
> 
> +      /* Case 3: 4 operand insn, dest = src1, src2 = memory.  */
> +      else if (i.types[0].bitfield.regxmm != 0
> +	       && (operand_type_check (i.types[1], anymem)) != 0
> 
> Need for () on operand_type_check.
> 
> +      /* Case 5: 4 operand insn, dest = src3, src2 = memory.  */
> +      else if (i.types[0].bitfield.regxmm != 0
> +	       && (i.types[1].bitfield.regxmm | operand_type_check
> (i.types[1], anymem)) != 0
> 
> See above
> 
> +  else if ((i.tm.opcode_modifier.drex) &&
!(i.tm.opcode_modifier.drexv)
> 
> No need for ().
> 
> +	   && i.operands == 4)
> +    {
> +      /* Case 1: 4 operand insn, dest = src1, src3 = reg/mem.  */
> +      if ((i.types[0].bitfield.regxmm) != 0
> +	  && (i.types[1].bitfield.regxmm |
operand_type_check(i.types[1],
> anymem)) != 0
> 
> See above.
> 
> +	  && i.types[2].bitfield.regxmm != 0
> +	  && i.types[3].bitfield.regxmm != 0
> +	  && i.op[0].regs->reg_num == i.op[3].regs->reg_num
> +	  && i.op[0].regs->reg_flags == i.op[3].regs->reg_flags)
> +	{
> +	  /* clear the arguments that are stored in drex */
> +	  UINTS_CLEAR (i.types[0]);
> +	  UINTS_CLEAR (i.types[3]);
> +	  i.reg_operands -= 2;
> +
> +	  /* Specify the modrm encoding and remember the register
including
> the
> +	     high bit normally stored in the REX byte.  */
> +	  i.drex.modrm_reg = 2;
> +	  i.drex.modrm_regmem = 1;
> +	  i.drex.reg = (i.op[3].regs->reg_num
> +			+ ((i.op[3].regs->reg_flags & RegRex) ? 8 : 0));
> +	}
> +
> +      else
> +	as_bad (_("Incorrect operands for the '%s' instruction"),
> i.tm.name);
> +    }
> +
> +  /* SSE5 3 operand instructions that the result is a register, being
> either
> +     operand can be a memory operand, using OC0 to note which one is
the
> +     memory.  */
> +  else if (i.tm.opcode_modifier.drex && i.tm.opcode_modifier.drexv
> 
> Use a separate line for i.tm.opcode_modifier.drexv
> 
> +  else if ((i.tm.opcode_modifier.drexc) != 0 && i.operands == 4)
> 
> No need for ().
> 
> +    {
> +      /* Case 1: 4 operand insn, src1 = reg/memory. */
> +      if (operand_type_check (i.types[0], imm) != 0
> +	  && (i.types[1].bitfield.regxmm
> +	      | operand_type_check (i.types[1], anymem)) != 0
> 
> See above.
> 
> +	 instruction.  */
> +      else if ((i.types[0].bitfield.regxmm
> +		| operand_type_check (i.types[0], anymem)) != 0
> 
> See above
> 
>    const seg_entry *default_seg = 0;
> 
> +  /* Handle all of the DREX munging that SSE5 needs.  */
> +  if (i.tm.opcode_modifier.drex | i.tm.opcode_modifier.drexv
> +      | i.tm.opcode_modifier.drexc)
> 
> Use || and one line for each condition.
> 
> +     GAS as if this is a 2 operand instruction.  */
> +  if ((i.tm.opcode_modifier.drex | i.tm.opcode_modifier.drexv
> +       | i.tm.opcode_modifier.drexc) != 0 && i.reg_operands == 2)
> 
> See above
> 
> 
> + 	  /* This has been precalculated for SSE5 instructions that have
a
> DREX
> + 	     field earlier in process_drex.  */
> + 	  if ((i.tm.opcode_modifier.drex | i.tm.opcode_modifier.drexv
> +	       | i.tm.opcode_modifier.drexc) != 0)
> 
> See above.
> 
>  	  unsigned int op;
> 
> +	  	  /* This has been precalculated for SSE5 instructions
that
> have a DREX
> 
> This line is too lone.
> 
> +	     field earlier in process_drex.  */
> +	  if ((i.tm.opcode_modifier.drex | i.tm.opcode_modifier.drexv
> +	       | i.tm.opcode_modifier.drexc) != 0)
> +	    {
> 
> See above.
> 
> -      if (i.tm.extension_opcode != None)
> +      if (i.tm.extension_opcode != None
> +	  && (i.tm.opcode_modifier.drex | i.tm.opcode_modifier.drexv
> +	      | i.tm.opcode_modifier.drexc) == 0)
> 
> See above.
> 
>  	i.rm.reg = i.tm.extension_opcode;
>      }
>    return default_seg;
> @@ -4569,10 +4947,11 @@ output_insn (void)
>        int opc_3b;
> 
>        /* All opcodes on i386 have either 1 or 2 bytes.  SSSE3 and
> -	 SSE4 instructions have 3 bytes.  We may use one more higher
> +	 SSE4 and SSE5 instructions have 3 bytes.  We may use one more
> higher
> 
> This line is too long.
> 
> +	     multiple formats.  */
> +	  if (i.tm.opcode_modifier.drex && i.tm.opcode_modifier.drexv
> 
> One line for each condition.
> 
> +      /* Write the DREX byte if needed.  */
> +      if (i.tm.opcode_modifier.drex | i.tm.opcode_modifier.drexc)
> 
> See above.
> 
> +	  /* Encode the OC0 bit if this encoding has multiple formats.
*/
> +	  if ((i.tm.opcode_modifier.drex | i.tm.opcode_modifier.drexv)
> +	      && DREX_OC0 (i.tm.extension_opcode))
> 
> See above
> 
> +	    *p |= DREX_OC0_MASK;
> +	}
> +
> 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: Changelog
Type: application/octet-stream
Size: 6468 bytes
Desc: Changelog
URL: <https://sourceware.org/pipermail/binutils/attachments/20070913/363f2494/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: binutils-sse5.patch.gz
Type: application/x-gzip
Size: 48578 bytes
Desc: binutils-sse5.patch.gz
URL: <https://sourceware.org/pipermail/binutils/attachments/20070913/363f2494/attachment.bin>


More information about the Binutils mailing list