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]

[PATCH] x86: fix register parsing and suffix recognition


Names of registers unavailable on the currently selected CPU should
never be parsed successfully (not just for 64-bit ones when .code64 is
not in effect) - these names must revert to ordinary symbol names in
such contexts.

Similarly, allowing 32-bit operations (i.e. the 'l' suffix) makes as
little sense on CPUs without 32-bit support as does using 64-bit
operations (i.e. the 'q' suffix) outside of 64-bit mode.

Built and tested on i686-pc-linux-gnu and x86_64-unknown-linux-gnu.

gas/
2008-02-13  Jan Beulich  <jbeulich@novell.com>

	* config/tc-i386.c (match_template): Disallow 'l' suffix when
	currently selected CPU has no 32-bit support.
	(parse_real_register): Do not return registers not available on
	currently selected CPU.

--- 2008-02-13/gas/config/tc-i386.c	2008-02-13 11:13:40.000000000 +0100
+++ 2008-02-13/gas/config/tc-i386.c	2008-02-13 13:12:08.000000000 +0100
@@ -3287,6 +3287,19 @@ match_template (void)
 	      || t->extension_opcode != 1 /* cmpxchg8b */))
 	continue;
 
+      /* In general, don't allow 32-bit operands on pre-386.  */
+      else if (i.suffix == LONG_MNEM_SUFFIX
+	       && !cpu_arch_flags.bitfield.cpui386
+	       && (intel_syntax
+		   ? (!t->opcode_modifier.ignoresize
+		      && !intel_float_operand (t->name))
+		   : intel_float_operand (t->name) != 2)
+	       && ((!operand_types[0].bitfield.regmmx
+		    && !operand_types[0].bitfield.regxmm)
+		   || (!operand_types[t->operands > 1].bitfield.regmmx
+		       && !!operand_types[t->operands > 1].bitfield.regxmm)))
+	continue;
+
       /* Do not verify operands when there are none.  */
       else
 	{
@@ -7064,6 +7077,24 @@ parse_real_register (char *reg_string, c
   if (UINTS_ALL_ZERO (r->reg_type))
     return (const reg_entry *) NULL;
 
+  if ((r->reg_type.bitfield.reg32
+       || r->reg_type.bitfield.sreg3
+       || r->reg_type.bitfield.control
+       || r->reg_type.bitfield.debug
+       || r->reg_type.bitfield.test)
+      && !cpu_arch_flags.bitfield.cpui386)
+    return (const reg_entry *) NULL;
+
+  /* XXX
+  if (r->reg_type.bitfield.floatreg && !cpu_arch_flags.bitfield.cpu8087)
+    return (const reg_entry *) NULL; */
+
+  if (r->reg_type.bitfield.regmmx && !cpu_arch_flags.bitfield.cpummx)
+    return (const reg_entry *) NULL;
+
+  if (r->reg_type.bitfield.regxmm && !cpu_arch_flags.bitfield.cpusse)
+    return (const reg_entry *) NULL;
+
   /* Don't allow fake index register unless allow_index_reg isn't 0. */
   if (!allow_index_reg
       && (r->reg_num == RegEiz || r->reg_num == RegRiz))




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