PATCH: Add access restriction check for application registers (was Re: Is this a gas bug?)

H. J. Lu hjl@lucon.org
Wed May 26 21:14:00 GMT 2004


On Mon, May 24, 2004 at 11:15:59PM +0800, Jie Zhang wrote:
> On Mon, 2004-05-24 at 02:08, Andreas Schwab wrote:
> > Jie Zhang <jiez@citiz.net> writes:
> > 
> > > Gas puts these two alloc instruction into M-unit type slot without
> > > noting that ar.pfs can only be accessed by I-unit. I have no time to fix
> > > this now. I will try to fix it if nobody submit patch for it in about
> > > two weeks.
> > 
> > alloc surely is an M-unit insn.  The access restrictions about application
> > registers apply only to the mov insn.
> > 
> > Andreas.
> 
> Oh, my mistake! Here is the modified patch for this issue. Since the
> access restriction about application registers apply only to the mov
> insn, I move the check from emit_one_bundle () to md_assemble () and
> make it only check the first two operands of mov.i and mov.m. Now make
> check is OK. No need for another patch now:-)
> 

The patch is not corrrect. I am testing this patch now.


H.J.
-------------- next part --------------
2004-05-26  H.J. Lu  <hongjiu.lu@intel.com>

	* config/tc-ia64.c (ar_is_only_in_integer_unit): New.
	(ar_is_only_in_memory_unit): New.
	(generate_unwind_image): Silence gcc on 32bit host.
	(md_assemble): Check AR access.

--- gas/config/tc-ia64.c.ar	2004-05-26 08:23:17.000000000 -0700
+++ gas/config/tc-ia64.c	2004-05-26 11:24:14.092730619 -0700
@@ -696,7 +696,6 @@ static struct
 typedef void (*vbyte_func) PARAMS ((int, char *, char *));
 
 /* Forward declarations:  */
-static int ar_is_in_integer_unit PARAMS ((int regnum));
 static void set_section PARAMS ((char *name));
 static unsigned int set_regstack PARAMS ((unsigned int, unsigned int,
 					  unsigned int, unsigned int));
@@ -908,21 +907,37 @@ static unsigned int get_saved_prologue_c
 static void save_prologue_count PARAMS ((unsigned long, unsigned int));
 static void free_saved_prologue_counts PARAMS ((void));
 
-/* Determine if application register REGNUM resides in the integer
+/* Determine if application register REGNUM may reside in the integer
    unit (as opposed to the memory unit).  */
 static int
-ar_is_in_integer_unit (reg)
-     int reg;
+ar_is_in_integer_unit (int reg)
 {
   reg -= REG_AR;
 
   return (reg == 64	/* pfs */
 	  || reg == 65	/* lc */
 	  || reg == 66	/* ec */
-	  /* ??? ias accepts and puts these in the integer unit.  */
 	  || (reg >= 112 && reg <= 127));
 }
 
+/* Determine if application register REGNUM resides only in the integer
+   unit (as opposed to the memory unit).  */
+static int
+ar_is_only_in_integer_unit (int reg)
+{
+  reg -= REG_AR;
+  return reg >= 64 && reg <= 111;
+}
+
+/* Determine if application register REGNUM resides only in the memory 
+   unit (as opposed to the integer unit).  */
+static int
+ar_is_only_in_memory_unit (int reg)
+{
+  reg -= REG_AR;
+  return reg >= 0 && reg <= 47;
+}
+
 /* Switch to section NAME and create section if necessary.  It's
    rather ugly that we have to manipulate input_line_pointer but I
    don't see any other way to accomplish the same thing without
@@ -3447,7 +3462,8 @@ generate_unwind_image (const segT text_s
       unwind.info = expr_build_dot ();
       
       frag_var (rs_machine_dependent, size, size, 0, 0,
-		(offsetT) unwind.personality_routine, (char *) list);
+		(offsetT) (long) unwind.personality_routine,
+		(char *) list);
 
       /* Add the personality address to the image.  */
       if (unwind.personality_routine != 0)
@@ -10040,6 +10056,33 @@ md_assemble (str)
 	    idesc = get_next_opcode (idesc);
 	}
     }
+  else if (strcmp (idesc->name, "mov.i") == 0
+	   || strcmp (idesc->name, "mov.m") == 0)
+    {
+      enum ia64_opnd opnd1, opnd2;
+      int rop;
+      
+      opnd1 = idesc->operands[0];
+      opnd2 = idesc->operands[1];
+      if (opnd1 == IA64_OPND_AR3)
+	rop = 0;
+      else if (opnd2 == IA64_OPND_AR3)
+	rop = 1;
+      else
+	abort ();
+      if (CURR_SLOT.opnd[rop].X_op == O_register)
+	{
+	  char unit = 'a';
+	  if (ar_is_only_in_integer_unit (CURR_SLOT.opnd[rop].X_add_number))
+	    unit = 'i';
+	  else if (ar_is_only_in_memory_unit (CURR_SLOT.opnd[rop].X_add_number))
+	    unit = 'm';
+	  if (unit != 'a' && unit != idesc->name [4])
+	    as_bad ("AR %lld cannot be accessed by %c-unit",
+		    CURR_SLOT.opnd[rop].X_add_number - REG_AR,
+		    TOUPPER (unit));
+	}
+    }
 
   qp_regno = 0;
   if (md.qp.X_op == O_register)


More information about the Binutils mailing list