2004-05-26 H.J. Lu * 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)