Index: config/tc-arm.c =================================================================== RCS file: /cvs/src/src/gas/config/tc-arm.c,v retrieving revision 1.107 diff -p -r1.107 tc-arm.c *** tc-arm.c 2002/01/11 18:00:14 1.107 --- tc-arm.c 2002/01/14 13:21:17 *************** struct reg_map *** 592,599 **** struct reg_map all_reg_maps[] = { {rn_table, 15, NULL, N_("ARM register expected")}, ! {cp_table, 15, NULL, N_("Bad or missing co-processor number")}, ! {cn_table, 15, NULL, N_("Co-processor register expected")}, {fn_table, 7, NULL, N_("FPA register expected")}, {mav_mvf_table, 15, NULL, N_("Maverick MVF register expected")}, {mav_mvd_table, 15, NULL, N_("Maverick MVD register expected")}, --- 592,599 ---- struct reg_map all_reg_maps[] = { {rn_table, 15, NULL, N_("ARM register expected")}, ! {cp_table, 15, NULL, N_("bad or missing co-processor number")}, ! {cn_table, 15, NULL, N_("co-processor register expected")}, {fn_table, 7, NULL, N_("FPA register expected")}, {mav_mvf_table, 15, NULL, N_("Maverick MVF register expected")}, {mav_mvd_table, 15, NULL, N_("Maverick MVD register expected")}, *************** static valueT md_chars_to_number PARAMS *** 800,806 **** static void build_reg_hsh PARAMS ((struct reg_map *)); static void insert_reg_alias PARAMS ((char *, int, struct hash_control *)); static int create_register_alias PARAMS ((char *, char *)); ! static void output_inst PARAMS ((void)); static int accum0_required_here PARAMS ((char **)); static int ld_mode_required_here PARAMS ((char **)); static void do_branch25 PARAMS ((char *)); --- 800,806 ---- static void build_reg_hsh PARAMS ((struct reg_map *)); static void insert_reg_alias PARAMS ((char *, int, struct hash_control *)); static int create_register_alias PARAMS ((char *, char *)); ! static void output_inst PARAMS ((const char *)); static int accum0_required_here PARAMS ((char **)); static int ld_mode_required_here PARAMS ((char **)); static void do_branch25 PARAMS ((char *)); *************** static const struct thumb_opcode tinsns[ *** 1788,1796 **** {"bkpt", 0xbe00, 2, ARM_EXT_V5T, do_t_bkpt}, }; ! #define BAD_ARGS _("Bad arguments to instruction") #define BAD_PC _("r15 not allowed here") ! #define BAD_COND _("Instruction is not conditional") #define ERR_NO_ACCUM _("acc0 expected") static struct hash_control * arm_ops_hsh = NULL; --- 1788,1796 ---- {"bkpt", 0xbe00, 2, ARM_EXT_V5T, do_t_bkpt}, }; ! #define BAD_ARGS _("bad arguments to instruction") #define BAD_PC _("r15 not allowed here") ! #define BAD_COND _("instruction is not conditional") #define ERR_NO_ACCUM _("acc0 expected") static struct hash_control * arm_ops_hsh = NULL; *************** add_to_lit_pool () *** 1930,1936 **** { if (next_literal_pool_place >= MAX_LITERAL_POOL_SIZE) { ! inst.error = _("Literal Pool Overflow"); return FAIL; } --- 1930,1936 ---- { if (next_literal_pool_place >= MAX_LITERAL_POOL_SIZE) { ! inst.error = _("literal pool overflow"); return FAIL; } *************** static void *** 2072,2078 **** s_req (a) int a ATTRIBUTE_UNUSED; { ! as_bad (_("Invalid syntax for .req directive.")); } static void --- 2072,2078 ---- s_req (a) int a ATTRIBUTE_UNUSED; { ! as_bad (_("invalid syntax for .req directive")); } static void *************** s_align (unused) *** 2147,2156 **** temp = get_absolute_expression (); if (temp > max_alignment) ! as_bad (_("Alignment too large: %d. assumed."), temp = max_alignment); else if (temp < 0) { ! as_bad (_("Alignment negative. 0 assumed.")); temp = 0; } --- 2147,2156 ---- temp = get_absolute_expression (); if (temp > max_alignment) ! as_bad (_("alignment too large: %d assumed"), temp = max_alignment); else if (temp < 0) { ! as_bad (_("alignment negative. 0 assumed.")); temp = 0; } *************** s_thumb_set (equiv) *** 2234,2240 **** if (*input_line_pointer != ',') { *end_name = 0; ! as_bad (_("Expected comma after name \"%s\""), name); *end_name = delim; ignore_rest_of_line (); return; --- 2234,2240 ---- if (*input_line_pointer != ',') { *end_name = 0; ! as_bad (_("expected comma after name \"%s\""), name); *end_name = delim; ignore_rest_of_line (); return; *************** s_code (unused) *** 2421,2432 **** static void end_of_line (str) ! char * str; { skip_whitespace (str); ! if (* str != '\0') ! inst.error = _("Garbage following instruction"); } static int --- 2421,2432 ---- static void end_of_line (str) ! char *str; { skip_whitespace (str); ! if (*str != '\0' && !inst.error) ! inst.error = _("garbage following instruction"); } static int *************** reg_required_here (str, shift) *** 2476,2482 **** /* In the few cases where we might be able to accept something else this error can be overridden. */ ! sprintf (buff, _("Register expected, not '%.100s'"), start); inst.error = buff; return FAIL; --- 2476,2482 ---- /* In the few cases where we might be able to accept something else this error can be overridden. */ ! sprintf (buff, _("register expected, not '%.100s'"), start); inst.error = buff; return FAIL; *************** co_proc_number (str) *** 2582,2595 **** processor = processor * 10 + *(*str)++ - '0'; if (processor > 15) { ! inst.error = _("Illegal co-processor number"); return FAIL; } } } else { ! inst.error = _("Bad or missing co-processor number"); return FAIL; } } --- 2582,2595 ---- processor = processor * 10 + *(*str)++ - '0'; if (processor > 15) { ! inst.error = _("illegal co-processor number"); return FAIL; } } } else { ! inst.error = _("bad or missing co-processor number"); return FAIL; } } *************** cp_reg_required_here (str, where) *** 2644,2650 **** /* In the few cases where we might be able to accept something else this error can be overridden. */ ! inst.error = _("Co-processor register expected"); /* Restore the start point. */ *str = start; --- 2644,2650 ---- /* In the few cases where we might be able to accept something else this error can be overridden. */ ! inst.error = _("co-processor register expected"); /* Restore the start point. */ *str = start; *************** fp_reg_required_here (str, where) *** 2667,2673 **** /* In the few cases where we might be able to accept something else this error can be overridden. */ ! inst.error = _("Floating point register expected"); /* Restore the start point. */ *str = start; --- 2667,2673 ---- /* In the few cases where we might be able to accept something else this error can be overridden. */ ! inst.error = _("floating point register expected"); /* Restore the start point. */ *str = start; *************** do_mrs (str) *** 2863,2869 **** skip = 8; else { ! inst.error = _("{C|S}PSR expected"); return; } --- 2863,2869 ---- skip = 8; else { ! inst.error = _("CPSR or SPSR expected"); return; } *************** do_msr (str) *** 2944,2950 **** if (value == (unsigned) FAIL) { ! inst.error = _("Invalid constant"); return; } --- 2944,2950 ---- if (value == (unsigned) FAIL) { ! inst.error = _("invalid constant"); return; } *************** do_co_reg2c (str) *** 3434,3440 **** /* Unpredictable result if rd or rn is R15. */ if (rd == REG_PC || rn == REG_PC) as_tsktsk ! (_("Warning: Instruction unpredictable when using r15")); if (skip_past_comma (& str) == FAIL || cp_reg_required_here (& str, 0) == FAIL) --- 3434,3440 ---- /* Unpredictable result if rd or rn is R15. */ if (rd == REG_PC || rn == REG_PC) as_tsktsk ! (_("Warning: instruction unpredictable when using r15")); if (skip_past_comma (& str) == FAIL || cp_reg_required_here (& str, 0) == FAIL) *************** do_ldrd (str) *** 4064,4070 **** /* inst.instruction has now been zapped with Rd and the addressing mode. */ if (rd & 1) /* Unpredictable result if Rd is odd. */ { ! inst.error = _("Destination register must be even"); return; } --- 4064,4070 ---- /* inst.instruction has now been zapped with Rd and the addressing mode. */ if (rd & 1) /* Unpredictable result if Rd is odd. */ { ! inst.error = _("destination register must be even"); return; } *************** walk_no_bignums (sp) *** 4182,4187 **** --- 4182,4189 ---- return 0; } + static int in_my_get_expression = 0; + static int my_get_expression (ep, str) expressionS * ep; *************** my_get_expression (ep, str) *** 4192,4198 **** --- 4194,4210 ---- save_in = input_line_pointer; input_line_pointer = *str; + in_my_get_expression = 1; seg = expression (ep); + in_my_get_expression = 0; + + if (ep->X_op == O_illegal) + { + /* We found a bad expression in md_operand(). */ + *str = input_line_pointer; + input_line_pointer = save_in; + return 1; + } #ifdef OBJ_AOUT if (seg != absolute_section *************** my_get_expression (ep, str) *** 4217,4223 **** || (ep->X_op_symbol && walk_no_bignums (ep->X_op_symbol))))) { ! inst.error = _("Invalid constant"); *str = input_line_pointer; input_line_pointer = save_in; return 1; --- 4229,4235 ---- || (ep->X_op_symbol && walk_no_bignums (ep->X_op_symbol))))) { ! inst.error = _("invalid constant"); *str = input_line_pointer; input_line_pointer = save_in; return 1; *************** my_get_expression (ep, str) *** 4228,4233 **** --- 4240,4259 ---- return 0; } + /* We handle all bad expressions here, spo that we can report the faulty + instruction in the error message. */ + void + md_operand(expr) + expressionS *expr; + { + if (in_my_get_expression) + { + expr->X_op = O_illegal; + if (inst.error == NULL) + inst.error = _("bad expression"); + } + } + /* UNRESTRICT should be one if is permitted for this instruction. */ *************** decode_shift (str, unrestrict) *** 4247,4253 **** if (p == * str) { ! inst.error = _("Shift expression expected"); return FAIL; } --- 4273,4279 ---- if (p == * str) { ! inst.error = _("shift expression expected"); return FAIL; } *************** decode_shift (str, unrestrict) *** 4258,4264 **** if (shift == NULL) { ! inst.error = _("Shift expression expected"); return FAIL; } --- 4284,4290 ---- if (shift == NULL) { ! inst.error = _("shift expression expected"); return FAIL; } *************** decode_shift (str, unrestrict) *** 4313,4325 **** about this though. */ if (num == 0) { ! as_warn (_("Shift of 0 ignored.")); shift = & shift_names[0]; assert (shift->properties->index == SHIFT_LSL); } else { ! inst.error = _("Invalid immediate shift"); return FAIL; } } --- 4339,4351 ---- about this though. */ if (num == 0) { ! as_warn (_("shift of 0 ignored.")); shift = & shift_names[0]; assert (shift->properties->index == SHIFT_LSL); } else { ! inst.error = _("invalid immediate shift"); return FAIL; } } *************** data_op2 (str) *** 4474,4480 **** if (expr.X_op != O_constant) { ! inst.error = _("Constant expression expected"); return FAIL; } --- 4500,4506 ---- if (expr.X_op != O_constant) { ! inst.error = _("constant expression expected"); return FAIL; } *************** data_op2 (str) *** 4483,4489 **** || (expr.X_add_number & 1) != 0 || ((unsigned) inst.reloc.exp.X_add_number) > 255) { ! inst.error = _("Invalid constant"); return FAIL; } inst.instruction |= INST_IMMEDIATE; --- 4509,4515 ---- || (expr.X_add_number & 1) != 0 || ((unsigned) inst.reloc.exp.X_add_number) > 255) { ! inst.error = _("invalid constant"); return FAIL; } inst.instruction |= INST_IMMEDIATE; *************** data_op2 (str) *** 4503,4509 **** inst.reloc.exp.X_add_number)) == FAIL) { ! inst.error = _("Invalid constant"); return FAIL; } } --- 4529,4535 ---- inst.reloc.exp.X_add_number)) == FAIL) { ! inst.error = _("invalid constant"); return FAIL; } } *************** data_op2 (str) *** 4516,4522 **** } (*str)++; ! inst.error = _("Register or shift expression expected"); return FAIL; } } --- 4542,4548 ---- } (*str)++; ! inst.error = _("register or shift expression expected"); return FAIL; } } *************** fp_op2 (str) *** 4569,4579 **** return SUCCESS; } ! inst.error = _("Invalid floating point immediate expression"); return FAIL; } inst.error = ! _("Floating point register or immediate expression expected"); return FAIL; } } --- 4595,4605 ---- return SUCCESS; } ! inst.error = _("invalid floating point immediate expression"); return FAIL; } inst.error = ! _("floating point register or immediate expression expected"); return FAIL; } } *************** do_ldst (str) *** 4785,4791 **** if (skip_past_comma (&str) == FAIL) { ! inst.error = _("Address expected"); return; } --- 4811,4817 ---- if (skip_past_comma (&str) == FAIL) { ! inst.error = _("address expected"); return; } *************** do_ldst (str) *** 4874,4879 **** --- 4900,4911 ---- } else if (*str == '=') { + if ((inst.instruction & LOAD_BIT) == 0) + { + inst.error = _("invalid pseudo operation"); + return; + } + /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */ str++; *************** do_ldst (str) *** 4885,4891 **** if (inst.reloc.exp.X_op != O_constant && inst.reloc.exp.X_op != O_symbol) { ! inst.error = _("Constant expression expected"); return; } --- 4917,4923 ---- if (inst.reloc.exp.X_op != O_constant && inst.reloc.exp.X_op != O_symbol) { ! inst.error = _("constant expression expected"); return; } *************** do_ldstt (str) *** 4969,4975 **** if (skip_past_comma (& str) == FAIL) { ! inst.error = _("Address expected"); return; } --- 5001,5007 ---- if (skip_past_comma (& str) == FAIL) { ! inst.error = _("address expected"); return; } *************** do_ldstv4 (str) *** 5111,5117 **** if (skip_past_comma (& str) == FAIL) { ! inst.error = _("Address expected"); return; } --- 5143,5149 ---- if (skip_past_comma (& str) == FAIL) { ! inst.error = _("address expected"); return; } *************** do_ldstv4 (str) *** 5202,5207 **** --- 5234,5245 ---- } else if (*str == '=') { + if ((inst.instruction & LOAD_BIT) == 0) + { + inst.error = _("invalid pseudo operation"); + return; + } + /* XXX Does this work correctly for half-word/byte ops? */ /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */ str++; *************** do_ldstv4 (str) *** 5214,5220 **** if (inst.reloc.exp.X_op != O_constant && inst.reloc.exp.X_op != O_symbol) { ! inst.error = _("Constant expression expected"); return; } --- 5252,5258 ---- if (inst.reloc.exp.X_op != O_constant && inst.reloc.exp.X_op != O_symbol) { ! inst.error = _("constant expression expected"); return; } *************** reg_list (strp) *** 5315,5321 **** if (reg <= cur_reg) { ! inst.error = _("Bad range in register list"); return FAIL; } --- 5353,5359 ---- if (reg <= cur_reg) { ! inst.error = _("bad range in register list"); return FAIL; } *************** reg_list (strp) *** 5323,5329 **** { if (range & (1 << i)) as_tsktsk ! (_("Warning: Duplicated register (r%d) in register list"), i); else range |= 1 << i; --- 5361,5367 ---- { if (range & (1 << i)) as_tsktsk ! (_("Warning: duplicated register (r%d) in register list"), i); else range |= 1 << i; *************** reg_list (strp) *** 5332,5341 **** } if (range & (1 << reg)) ! as_tsktsk (_("Warning: Duplicated register (r%d) in register list"), reg); else if (reg <= cur_reg) ! as_tsktsk (_("Warning: Register range not in ascending order")); range |= 1 << reg; cur_reg = reg; --- 5370,5379 ---- } if (range & (1 << reg)) ! as_tsktsk (_("Warning: duplicated register (r%d) in register list"), reg); else if (reg <= cur_reg) ! as_tsktsk (_("Warning: register range not in ascending order")); range |= 1 << reg; cur_reg = reg; *************** reg_list (strp) *** 5347,5353 **** if (*str++ != '}') { ! inst.error = _("Missing `}'"); return FAIL; } } --- 5385,5391 ---- if (*str++ != '}') { ! inst.error = _("missing `}'"); return FAIL; } } *************** reg_list (strp) *** 5374,5380 **** regno &= -regno; regno = (1 << regno) - 1; as_tsktsk ! (_("Warning: Duplicated register (r%d) in register list"), regno); } --- 5412,5418 ---- regno &= -regno; regno = (1 << regno) - 1; as_tsktsk ! (_("Warning: duplicated register (r%d) in register list"), regno); } *************** do_bx (str) *** 5595,5601 **** /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */ if (reg == REG_PC) ! as_tsktsk (_("Use of r15 in bx in ARM mode is not really useful")); end_of_line (str); } --- 5633,5639 ---- /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */ if (reg == REG_PC) ! as_tsktsk (_("use of r15 in bx in ARM mode is not really useful")); end_of_line (str); } *************** do_fpa_ldmstm (str) *** 5829,5835 **** if (inst.reloc.exp.X_op != O_constant) { ! inst.error = _("Constant value required for number of registers"); return; } --- 5867,5873 ---- if (inst.reloc.exp.X_op != O_constant) { ! inst.error = _("constant value required for number of registers"); return; } *************** do_fpa_ldmstm (str) *** 5898,5904 **** if (reg == REG_PC) { inst.error = ! _("R15 not allowed as base register with write-back"); return; } } --- 5936,5942 ---- if (reg == REG_PC) { inst.error = ! _("r15 not allowed as base register with write-back"); return; } } *************** thumb_shift (str, shift) *** 6373,6379 **** if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL)) { ! inst.error = _("Invalid immediate for shift"); return; } --- 6411,6417 ---- if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL)) { ! inst.error = _("invalid immediate for shift"); return; } *************** thumb_load_store (str, load_store, size) *** 6532,6537 **** --- 6570,6581 ---- } else if (*str == '=') { + if (load_store != THUMB_LOAD) + { + inst.error = _("invalid pseudo operation"); + return; + } + /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */ str++; *************** thumb_load_store (str, load_store, size) *** 6597,6608 **** } else if (Rb == REG_PC && load_store != THUMB_LOAD) { ! inst.error = _("R15 based store not allowed"); return; } else if (Ro != FAIL) { ! inst.error = _("Invalid base register for register offset"); return; } --- 6641,6652 ---- } else if (Rb == REG_PC && load_store != THUMB_LOAD) { ! inst.error = _("r15 based store not allowed"); return; } else if (Ro != FAIL) { ! inst.error = _("invalid base register for register offset"); return; } *************** thumb_load_store (str, load_store, size) *** 6655,6661 **** if (offset & ~(0x1f << size)) { ! inst.error = _("Invalid offset"); return; } inst.instruction |= (offset >> size) << 6; --- 6699,6705 ---- if (offset & ~(0x1f << size)) { ! inst.error = _("invalid offset"); return; } inst.instruction |= (offset >> size) << 6; *************** do_t_ldmstm (str) *** 7522,7528 **** return; if (*str != '!') ! as_warn (_("Inserted missing '!': load/store multiple always writes back base register")); else str++; --- 7566,7572 ---- return; if (*str != '!') ! as_warn (_("inserted missing '!': load/store multiple always writes back base register")); else str++; *************** do_t_ldmstm (str) *** 7538,7544 **** { /* This really doesn't seem worth it. */ inst.reloc.type = BFD_RELOC_NONE; ! inst.error = _("Expression too complex"); return; } --- 7582,7588 ---- { /* This really doesn't seem worth it. */ inst.reloc.type = BFD_RELOC_NONE; ! inst.error = _("expression too complex"); return; } *************** do_t_lds (str) *** 7590,7596 **** || *str++ != ']') { if (! inst.error) ! inst.error = _("Syntax: ldrs[b] Rd, [Rb, Ro]"); return; } --- 7634,7640 ---- || *str++ != ']') { if (! inst.error) ! inst.error = _("syntax: ldrs[b] Rd, [Rb, Ro]"); return; } *************** do_t_push_pop (str) *** 7638,7644 **** { /* This really doesn't seem worth it. */ inst.reloc.type = BFD_RELOC_NONE; ! inst.error = _("Expression too complex"); return; } --- 7682,7688 ---- { /* This really doesn't seem worth it. */ inst.reloc.type = BFD_RELOC_NONE; ! inst.error = _("expression too complex"); return; } *************** build_reg_hsh (map) *** 7766,7772 **** const struct reg_entry *r; if ((map->htab = hash_new ()) == NULL) ! as_fatal (_("Virtual memory exhausted")); for (r = map->names; r->name != NULL; r++) insert_reg (r, map->htab); --- 7810,7816 ---- const struct reg_entry *r; if ((map->htab = hash_new ()) == NULL) ! as_fatal (_("virtual memory exhausted")); for (r = map->names; r->name != NULL; r++) insert_reg (r, map->htab); *************** md_begin () *** 7944,7950 **** || (arm_cond_hsh = hash_new ()) == NULL || (arm_shift_hsh = hash_new ()) == NULL || (arm_psr_hsh = hash_new ()) == NULL) ! as_fatal (_("Virtual memory exhausted")); build_arm_ops_hsh (); for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++) --- 7988,7994 ---- || (arm_cond_hsh = hash_new ()) == NULL || (arm_shift_hsh = hash_new ()) == NULL || (arm_psr_hsh = hash_new ()) == NULL) ! as_fatal (_("virtual memory exhausted")); build_arm_ops_hsh (); for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++) *************** md_atof (type, litP, sizeP) *** 8139,8145 **** default: *sizeP = 0; ! return _("Bad call to MD_ATOF()"); } t = atof_ieee (input_line_pointer, type, words); --- 8183,8189 ---- default: *sizeP = 0; ! return _("bad call to MD_ATOF()"); } t = atof_ieee (input_line_pointer, type, words); *************** md_apply_fix3 (fixP, valP, seg) *** 8398,8404 **** else { as_bad_where (fixP->fx_file, fixP->fx_line, ! _("Unable to compute ADRL instructions for PC offset of 0x%lx"), value); break; } --- 8442,8448 ---- else { as_bad_where (fixP->fx_file, fixP->fx_line, ! _("unable to compute ADRL instructions for PC offset of 0x%lx"), value); break; } *************** md_apply_fix3 (fixP, valP, seg) *** 8508,8514 **** { if (((unsigned long) value) > 0xff) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("Invalid swi expression")); newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00; newval |= value; md_number_to_chars (buf, newval, THUMB_SIZE); --- 8552,8558 ---- { if (((unsigned long) value) > 0xff) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("invalid swi expression")); newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00; newval |= value; md_number_to_chars (buf, newval, THUMB_SIZE); *************** md_apply_fix3 (fixP, valP, seg) *** 8517,8523 **** { if (((unsigned long) value) > 0x00ffffff) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("Invalid swi expression")); newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000; newval |= value; md_number_to_chars (buf, newval, INSN_SIZE); --- 8561,8567 ---- { if (((unsigned long) value) > 0x00ffffff) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("invalid swi expression")); newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000; newval |= value; md_number_to_chars (buf, newval, INSN_SIZE); *************** md_apply_fix3 (fixP, valP, seg) *** 8527,8533 **** case BFD_RELOC_ARM_MULTI: if (((unsigned long) value) > 0xffff) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("Invalid expression in load/store multiple")); newval = value | md_chars_to_number (buf, INSN_SIZE); md_number_to_chars (buf, newval, INSN_SIZE); break; --- 8571,8577 ---- case BFD_RELOC_ARM_MULTI: if (((unsigned long) value) > 0xffff) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("invalid expression in load/store multiple")); newval = value | md_chars_to_number (buf, INSN_SIZE); md_number_to_chars (buf, newval, INSN_SIZE); break; *************** md_apply_fix3 (fixP, valP, seg) *** 8580,8586 **** if (! fixP->fx_done) #endif as_bad_where (fixP->fx_file, fixP->fx_line, ! _("gas can't handle same-section branch dest >= 0x04000000")); } value >>= 2; --- 8624,8630 ---- if (! fixP->fx_done) #endif as_bad_where (fixP->fx_file, fixP->fx_line, ! _("GAS can't handle same-section branch dest >= 0x04000000")); } value >>= 2; *************** md_apply_fix3 (fixP, valP, seg) *** 8622,8628 **** value += diff; if ((value & ~0xff) && ((value & ~0xff) != ~0xff)) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("Branch out of range")); newval = (newval & 0xff00) | ((value & 0x1ff) >> 1); } md_number_to_chars (buf, newval, THUMB_SIZE); --- 8666,8672 ---- value += diff; if ((value & ~0xff) && ((value & ~0xff) != ~0xff)) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("branch out of range")); newval = (newval & 0xff00) | ((value & 0x1ff) >> 1); } md_number_to_chars (buf, newval, THUMB_SIZE); *************** md_apply_fix3 (fixP, valP, seg) *** 8638,8644 **** value += diff; if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff)) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("Branch out of range")); newval = (newval & 0xf800) | ((value & 0xfff) >> 1); } md_number_to_chars (buf, newval, THUMB_SIZE); --- 8682,8688 ---- value += diff; if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff)) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("branch out of range")); newval = (newval & 0xf800) | ((value & 0xfff) >> 1); } md_number_to_chars (buf, newval, THUMB_SIZE); *************** md_apply_fix3 (fixP, valP, seg) *** 8661,8667 **** value += diff; if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff)) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("Branch with link out of range")); newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12); newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1); --- 8705,8711 ---- value += diff; if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff)) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("branch with link out of range")); newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12); newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1); *************** md_apply_fix3 (fixP, valP, seg) *** 8737,8743 **** sign = value >= 0; if (value < -1023 || value > 1023 || (value & 3)) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("Illegal value for co-processor offset")); if (value < 0) value = -value; newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00; --- 8781,8787 ---- sign = value >= 0; if (value < -1023 || value > 1023 || (value & 3)) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("illegal value for co-processor offset")); if (value < 0) value = -value; newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00; *************** md_apply_fix3 (fixP, valP, seg) *** 8761,8773 **** if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("Invalid offset, target not word aligned (0x%08X)"), (unsigned int) (fixP->fx_frag->fr_address + fixP->fx_where + value)); if ((value + 2) & ~0x3fe) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("Invalid offset, value too big (0x%08lX)"), value); /* Round up, since pc will be rounded down. */ newval |= (value + 2) >> 2; --- 8805,8817 ---- if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("invalid offset, target not word aligned (0x%08X)"), (unsigned int) (fixP->fx_frag->fr_address + fixP->fx_where + value)); if ((value + 2) & ~0x3fe) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("invalid offset, value too big (0x%08lX)"), value); /* Round up, since pc will be rounded down. */ newval |= (value + 2) >> 2; *************** md_apply_fix3 (fixP, valP, seg) *** 8776,8803 **** case 9: /* SP load/store. */ if (value & ~0x3fc) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("Invalid offset, value too big (0x%08lX)"), value); newval |= value >> 2; break; case 6: /* Word load/store. */ if (value & ~0x7c) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("Invalid offset, value too big (0x%08lX)"), value); newval |= value << 4; /* 6 - 2. */ break; case 7: /* Byte load/store. */ if (value & ~0x1f) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("Invalid offset, value too big (0x%08lX)"), value); newval |= value << 6; break; case 8: /* Halfword load/store. */ if (value & ~0x3e) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("Invalid offset, value too big (0x%08lX)"), value); newval |= value << 5; /* 6 - 1. */ break; --- 8820,8847 ---- case 9: /* SP load/store. */ if (value & ~0x3fc) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("invalid offset, value too big (0x%08lX)"), value); newval |= value >> 2; break; case 6: /* Word load/store. */ if (value & ~0x7c) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("invalid offset, value too big (0x%08lX)"), value); newval |= value << 4; /* 6 - 2. */ break; case 7: /* Byte load/store. */ if (value & ~0x1f) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("invalid offset, value too big (0x%08lX)"), value); newval |= value << 6; break; case 8: /* Halfword load/store. */ if (value & ~0x3e) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("invalid offset, value too big (0x%08lX)"), value); newval |= value << 5; /* 6 - 1. */ break; *************** md_apply_fix3 (fixP, valP, seg) *** 8836,8842 **** { if (value & ~0x1fc) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("Invalid immediate for stack address calculation")); newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST; newval |= value >> 2; } --- 8880,8886 ---- { if (value & ~0x1fc) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("invalid immediate for stack address calculation")); newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST; newval |= value >> 2; } *************** md_apply_fix3 (fixP, valP, seg) *** 8845,8851 **** if (subtract || value & ~0x3fc) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("Invalid immediate for address calculation (value = 0x%08lX)"), (unsigned long) value); newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP); newval |= rd << 8; --- 8889,8895 ---- if (subtract || value & ~0x3fc) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("invalid immediate for address calculation (value = 0x%08lX)"), (unsigned long) value); newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP); newval |= rd << 8; *************** md_apply_fix3 (fixP, valP, seg) *** 8855,8861 **** { if (value & ~0xff) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("Invalid 8bit immediate")); newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8; newval |= (rd << 8) | value; } --- 8899,8905 ---- { if (value & ~0xff) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("invalid 8bit immediate")); newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8; newval |= (rd << 8) | value; } *************** md_apply_fix3 (fixP, valP, seg) *** 8863,8869 **** { if (value & ~0x7) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("Invalid 3bit immediate")); newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3; newval |= rd | (rs << 3) | (value << 6); } --- 8907,8913 ---- { if (value & ~0x7) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("invalid 3bit immediate")); newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3; newval |= rd | (rs << 3) | (value << 6); } *************** md_apply_fix3 (fixP, valP, seg) *** 8879,8885 **** case 0x05: /* 8bit immediate CMP. */ if (value < 0 || value > 255) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("Invalid immediate: %ld is too large"), (long) value); newval |= value; break; --- 8923,8929 ---- case 0x05: /* 8bit immediate CMP. */ if (value < 0 || value > 255) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("invalid immediate: %ld is too large"), (long) value); newval |= value; break; *************** md_apply_fix3 (fixP, valP, seg) *** 8894,8900 **** /* 5bit shift value (0..31). */ if (value < 0 || value > 31) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("Illegal Thumb shift value: %ld"), (long) value); newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f; newval |= value << 6; md_number_to_chars (buf, newval, THUMB_SIZE); --- 8938,8944 ---- /* 5bit shift value (0..31). */ if (value < 0 || value > 31) as_bad_where (fixP->fx_file, fixP->fx_line, ! _("illegal Thumb shift value: %ld"), (long) value); newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f; newval |= value << 6; md_number_to_chars (buf, newval, THUMB_SIZE); *************** md_apply_fix3 (fixP, valP, seg) *** 8908,8914 **** case BFD_RELOC_NONE: default: as_bad_where (fixP->fx_file, fixP->fx_line, ! _("Bad relocation fixup type (%d)"), fixP->fx_r_type); } } --- 8952,8958 ---- case BFD_RELOC_NONE: default: as_bad_where (fixP->fx_file, fixP->fx_line, ! _("bad relocation fixup type (%d)"), fixP->fx_r_type); } } *************** tc_gen_reloc (section, fixp) *** 8979,8985 **** /* If this is called then the a literal has been referenced across a section boundary - possibly due to an implicit dump. */ as_bad_where (fixp->fx_file, fixp->fx_line, ! _("Literal referenced across section boundary (Implicit dump?)")); return NULL; #ifdef OBJ_ELF --- 9023,9029 ---- /* If this is called then the a literal has been referenced across a section boundary - possibly due to an implicit dump. */ as_bad_where (fixp->fx_file, fixp->fx_line, ! _("literal referenced across section boundary (Implicit dump?)")); return NULL; #ifdef OBJ_ELF *************** tc_gen_reloc (section, fixp) *** 8992,8998 **** case BFD_RELOC_ARM_IMMEDIATE: as_bad_where (fixp->fx_file, fixp->fx_line, ! _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"), fixp->fx_r_type); return NULL; --- 9036,9042 ---- case BFD_RELOC_ARM_IMMEDIATE: as_bad_where (fixp->fx_file, fixp->fx_line, ! _("internal relocation (type %d) not fixed up (IMMEDIATE)"), fixp->fx_r_type); return NULL; *************** tc_gen_reloc (section, fixp) *** 9003,9009 **** case BFD_RELOC_ARM_OFFSET_IMM: as_bad_where (fixp->fx_file, fixp->fx_line, ! _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"), fixp->fx_r_type); return NULL; --- 9047,9053 ---- case BFD_RELOC_ARM_OFFSET_IMM: as_bad_where (fixp->fx_file, fixp->fx_line, ! _("internal_relocation (type %d) not fixed up (OFFSET_IMM)"), fixp->fx_r_type); return NULL; *************** tc_gen_reloc (section, fixp) *** 9027,9033 **** default: type = _(""); break; } as_bad_where (fixp->fx_file, fixp->fx_line, ! _("Cannot represent %s relocation in this object file format"), type); return NULL; } --- 9071,9077 ---- default: type = _(""); break; } as_bad_where (fixp->fx_file, fixp->fx_line, ! _("cannot represent %s relocation in this object file format"), type); return NULL; } *************** tc_gen_reloc (section, fixp) *** 9048,9054 **** if (reloc->howto == NULL) { as_bad_where (fixp->fx_file, fixp->fx_line, ! _("Can not represent %s relocation in this object file format"), bfd_get_reloc_code_name (code)); return NULL; } --- 9092,9098 ---- if (reloc->howto == NULL) { as_bad_where (fixp->fx_file, fixp->fx_line, ! _("cannot represent %s relocation in this object file format"), bfd_get_reloc_code_name (code)); return NULL; } *************** md_estimate_size_before_relax (fragP, se *** 9071,9083 **** } static void ! output_inst PARAMS ((void)) { char * to = NULL; if (inst.error) { ! as_bad (inst.error); return; } --- 9115,9128 ---- } static void ! output_inst (str) ! const char *str; { char * to = NULL; if (inst.error) { ! as_bad ("%s -- `%s'", inst.error, str); return; } *************** md_assemble (str) *** 9144,9150 **** if (p == str) { ! as_bad (_("No operator -- statement `%s'\n"), str); return; } --- 9189,9195 ---- if (p == str) { ! as_bad (_("no operator -- statement `%s'\n"), str); return; } *************** md_assemble (str) *** 9162,9175 **** /* Check that this instruction is supported for this CPU. */ if (thumb_mode == 1 && (opcode->variant & cpu_variant) == 0) { ! as_bad (_("selected processor does not support this opcode")); return; } inst.instruction = opcode->value; inst.size = opcode->size; (*opcode->parms) (p); ! output_inst (); return; } } --- 9207,9220 ---- /* Check that this instruction is supported for this CPU. */ if (thumb_mode == 1 && (opcode->variant & cpu_variant) == 0) { ! as_bad (_("selected processor does not support `%s'"), str); return; } inst.instruction = opcode->value; inst.size = opcode->size; (*opcode->parms) (p); ! output_inst (str); return; } } *************** md_assemble (str) *** 9187,9200 **** /* Check that this instruction is supported for this CPU. */ if ((opcode->variant & cpu_variant) == 0) { ! as_bad (_("selected processor does not support this opcode")); return; } inst.instruction = opcode->value; inst.size = INSN_SIZE; (*opcode->parms) (p); ! output_inst (); return; } } --- 9232,9245 ---- /* Check that this instruction is supported for this CPU. */ if ((opcode->variant & cpu_variant) == 0) { ! as_bad (_("selected processor does not support `%s'"), str); return; } inst.instruction = opcode->value; inst.size = INSN_SIZE; (*opcode->parms) (p); ! output_inst (str); return; } } *************** md_parse_option (c, arg) *** 9378,9384 **** return 1; } ! as_bad (_("Unrecognised APCS switch -m%s"), arg); return 0; } --- 9423,9429 ---- return 1; } ! as_bad (_("unrecognised APCS switch -m%s"), arg); return 0; } *************** md_parse_option (c, arg) *** 9539,9545 **** cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2; break; default: ! as_bad (_("Invalid architecture variant -m%s"), arg); break; } break; --- 9584,9590 ---- cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2; break; default: ! as_bad (_("invalid architecture variant -m%s"), arg); break; } break; *************** md_parse_option (c, arg) *** 9552,9558 **** case 'm': cpu_variant |= ARM_EXT_V3M; break; case 0: break; default: ! as_bad (_("Invalid architecture variant -m%s"), arg); break; } break; --- 9597,9603 ---- case 'm': cpu_variant |= ARM_EXT_V3M; break; case 0: break; default: ! as_bad (_("invalid architecture variant -m%s"), arg); break; } break; *************** md_parse_option (c, arg) *** 9565,9571 **** case 't': cpu_variant |= ARM_EXT_V4T; break; case 0: break; default: ! as_bad (_("Invalid architecture variant -m%s"), arg); break; } break; --- 9610,9616 ---- case 't': cpu_variant |= ARM_EXT_V4T; break; case 0: break; default: ! as_bad (_("invalid architecture variant -m%s"), arg); break; } break; *************** md_parse_option (c, arg) *** 9578,9597 **** case 'e': cpu_variant |= ARM_EXT_V5E; break; case 0: break; default: ! as_bad (_("Invalid architecture variant -m%s"), arg); break; } break; default: ! as_bad (_("Invalid architecture variant -m%s"), arg); break; } break; default: bad: ! as_bad (_("Invalid processor variant -m%s"), arg); return 0; } } --- 9623,9642 ---- case 'e': cpu_variant |= ARM_EXT_V5E; break; case 0: break; default: ! as_bad (_("invalid architecture variant -m%s"), arg); break; } break; default: ! as_bad (_("invalid architecture variant -m%s"), arg); break; } break; default: bad: ! as_bad (_("invalid processor variant -m%s"), arg); return 0; } } Index: config/tc-arm.h =================================================================== RCS file: /cvs/src/src/gas/config/tc-arm.h,v retrieving revision 1.15 diff -p -r1.15 tc-arm.h *** tc-arm.h 2001/11/15 21:28:54 1.15 --- tc-arm.h 2002/01/14 13:21:19 *************** void armelf_frob_symbol PARAMS ((symbolS *** 169,176 **** #define OPTIONAL_REGISTER_PREFIX '%' - #define md_operand(x) - #define LOCAL_LABEL(name) (name[0] == '.' && (name[1] == 'L')) #define LOCAL_LABELS_FB 1 #ifdef OBJ_ELF --- 169,174 ---- Index: testsuite/gas/arm/arm.exp =================================================================== RCS file: /cvs/src/src/gas/testsuite/gas/arm/arm.exp,v retrieving revision 1.8 diff -p -r1.8 arm.exp *** arm.exp 2002/01/11 18:00:17 1.8 --- arm.exp 2002/01/14 13:21:19 *************** *** 1,10 **** --- 1,25 ---- # # Some ARM tests # + proc run_errors_test { name opts tname} { + global srcdir subdir + set testname "$tname" + set file $srcdir/$subdir/$name + gas_run ${name}.s $opts ">&${name}.out" + if { [regexp_diff "${name}.out" "${file}.l"] } then { + fail $testname + verbose "output is [file_contents "${name}.out"]" 2 + return + } + pass $testname + } + if {[istarget *arm*-*-*] || [istarget "xscale-*-*"]} then { run_dump_test "inst" run_dump_test "ldconst" + + run_errors_test "armv1-bad" "-marm1" "ARM v1 errors" gas_test "arm3.s" "-marm3" $stdoptlist "Arm 3 instructions" Index: testsuite/gas/arm/armv1-bad.l =================================================================== RCS file: armv1-bad.l diff -N armv1-bad.l *** /dev/null Tue May 5 13:32:27 1998 --- armv1-bad.l Mon Jan 14 05:21:20 2002 *************** *** 0 **** --- 1,8 ---- + [^:]*: Assembler messages: + [^:]*:4: Error: invalid pseudo operation -- `str r0,=0x00ff0000' + [^:]*:5: Error: bad expression -- `ldr r0,{r1}' + [^:]*:6: Error: address offset too large -- `ldr r0,\[r1,#4096\]' + [^:]*:7: Error: address offset too large -- `ldr r0,\[r1,#-4096\]' + [^:]*:8: Error: invalid constant -- `mov r0,#0x1ff' + [^:]*:9: Error: bad instruction `cmpl r0,r0' + [^:]*:10: Error: selected processor does not support `strh r0,\[r1\]' Index: testsuite/gas/arm/armv1-bad.s =================================================================== RCS file: armv1-bad.s diff -N armv1-bad.s *** /dev/null Tue May 5 13:32:27 1998 --- armv1-bad.s Mon Jan 14 05:21:20 2002 *************** *** 0 **** --- 1,10 ---- + .global entry + .text + entry: + str r0, =0x00ff0000 + ldr r0, {r1} + ldr r0, [r1, #4096] + ldr r0, [r1, #-4096] + mov r0, #0x1ff + cmpl r0, r0 + strh r0, [r1]