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