X-Git-Url: http://drtracing.org/?a=blobdiff_plain;ds=sidebyside;f=gas%2Fconfig%2Ftc-hppa.c;h=12279f2c6f572a137be092b45e7aba54b49db6c4;hb=0ac2b354ee006d94d6fc46bea08f39f99b18f869;hp=09581ac16d293783a1d28d01be20ede5cca0d5fa;hpb=499ac353610f24006acf82c32503d8d15d0f278c;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-hppa.c b/gas/config/tc-hppa.c index 09581ac16d..12279f2c6f 100644 --- a/gas/config/tc-hppa.c +++ b/gas/config/tc-hppa.c @@ -1,6 +1,5 @@ /* tc-hppa.c -- Assemble for the PA - Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + Copyright (C) 1989-2019 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -351,7 +350,7 @@ typedef struct space_dictionary_chain sd_chain_struct; struct default_subspace_dict { /* Name of the subspace. */ - char *name; + const char *name; /* FIXME. Is this still needed? */ char defined; @@ -404,7 +403,7 @@ struct default_subspace_dict struct default_space_dict { /* Name of the space. */ - char *name; + const char *name; /* Space number. It is possible to identify spaces within assembly code numerically! */ @@ -466,7 +465,7 @@ struct hppa_fix_struct struct pd_reg { - char *name; + const char *name; int value; }; @@ -474,7 +473,7 @@ struct pd_reg to a condition number which can be recorded in an instruction. */ struct fp_cond_map { - char *string; + const char *string; int cond; }; @@ -482,7 +481,7 @@ struct fp_cond_map string to a field selector type. */ struct selector_entry { - char *prefix; + const char *prefix; int field_selector; }; @@ -504,27 +503,27 @@ static void pa_align (int); static void pa_space (int); static void pa_spnum (int); static void pa_subspace (int); -static sd_chain_struct *create_new_space (char *, int, int, - int, int, int, - asection *, int); +static sd_chain_struct *create_new_space (const char *, int, int, + int, int, int, + asection *, int); static ssd_chain_struct *create_new_subspace (sd_chain_struct *, - char *, int, int, - int, int, int, int, - int, int, int, int, - int, asection *); + const char *, int, int, + int, int, int, int, + int, int, int, int, + int, asection *); static ssd_chain_struct *update_subspace (sd_chain_struct *, - char *, int, int, int, - int, int, int, int, - int, int, int, int, - asection *); -static sd_chain_struct *is_defined_space (char *); -static ssd_chain_struct *is_defined_subspace (char *); + char *, int, int, int, + int, int, int, int, + int, int, int, int, + asection *); +static sd_chain_struct *is_defined_space (const char *); +static ssd_chain_struct *is_defined_subspace (const char *); static sd_chain_struct *pa_segment_to_space (asection *); static ssd_chain_struct *pa_subsegment_to_subspace (asection *, subsegT); static sd_chain_struct *pa_find_space_by_number (int); static unsigned int pa_subspace_start (sd_chain_struct *, int); -static sd_chain_struct *pa_parse_space_stmt (char *, int); +static sd_chain_struct *pa_parse_space_stmt (const char *, int); #endif /* File and globally scoped variable declarations. */ @@ -607,8 +606,8 @@ static int within_procedure; seen in each subspace. */ static label_symbol_struct *label_symbols_rootp = NULL; -/* Holds the last field selector. */ -static int hppa_field_selector; +/* Last label symbol */ +static label_symbol_struct last_label_symbol; /* Nonzero when strict matching is enabled. Zero otherwise. @@ -948,8 +947,8 @@ static const struct selector_entry selector_table[] = #ifdef OBJ_SOM /* default space and subspace dictionaries */ -#define GDB_SYMBOLS GDB_SYMBOLS_SUBSPACE_NAME -#define GDB_STRINGS GDB_STRINGS_SUBSPACE_NAME +#define GDB_SYMBOLS GDB_SYMBOLS_SUBSPACE_NAME +#define GDB_STRINGS GDB_STRINGS_SUBSPACE_NAME /* pre-defined subsegments (subspaces) for the HPPA. */ #define SUBSEG_CODE 0 @@ -995,6 +994,19 @@ static struct default_space_dict pa_def_spaces[] = #define IS_R_SELECT(S) (*(S) == 'R' || *(S) == 'r') #define IS_L_SELECT(S) (*(S) == 'L' || *(S) == 'l') +/* Store immediate values of shift/deposit/extract functions. */ + +#define SAVE_IMMEDIATE(VALUE) \ + { \ + if (immediate_check) \ + { \ + if (pos == -1) \ + pos = (VALUE); \ + else if (len == -1) \ + len = (VALUE); \ + } \ + } + /* Insert FIELD into OPCODE starting at bit START. Continue pa_ip main loop after insertion. */ @@ -1012,9 +1024,9 @@ static struct default_space_dict pa_def_spaces[] = if ((FIELD) > (HIGH) || (FIELD) < (LOW)) \ { \ if (! IGNORE) \ - as_bad (_("Field out of range [%d..%d] (%d)."), (LOW), (HIGH), \ + as_bad (_("Field out of range [%d..%d] (%d)."), (LOW), (HIGH), \ (int) (FIELD));\ - break; \ + break; \ } \ } @@ -1025,10 +1037,10 @@ static struct default_space_dict pa_def_spaces[] = { \ if ((FIELD) > (HIGH) || (FIELD) < (LOW)) \ { \ - as_bad_where ((FILENAME), (LINE), \ + as_bad_where ((FILENAME), (LINE), \ _("Field out of range [%d..%d] (%d)."), (LOW), (HIGH), \ (int) (FIELD));\ - break; \ + break; \ } \ } @@ -1040,9 +1052,9 @@ static struct default_space_dict pa_def_spaces[] = if ((FIELD) & ((ALIGN) - 1)) \ { \ if (! IGNORE) \ - as_bad (_("Field not properly aligned [%d] (%d)."), (ALIGN), \ + as_bad (_("Field not properly aligned [%d] (%d)."), (ALIGN), \ (int) (FIELD));\ - break; \ + break; \ } \ } @@ -1050,6 +1062,10 @@ static struct default_space_dict pa_def_spaces[] = ((exp).X_op == O_subtract \ && strcmp (S_GET_NAME ((exp).X_op_symbol), "$global$") == 0) +#define is_SB_relative(exp) \ + ((exp).X_op == O_subtract \ + && strcmp (S_GET_NAME ((exp).X_op_symbol), "$segrel$") == 0) + #define is_PC_relative(exp) \ ((exp).X_op == O_subtract \ && strcmp (S_GET_NAME ((exp).X_op_symbol), "$PIC_pcrel$0") == 0) @@ -1101,19 +1117,17 @@ pa_check_eof (void) static label_symbol_struct * pa_get_label (void) { - label_symbol_struct *label_chain; + label_symbol_struct *label_chain = label_symbols_rootp; - for (label_chain = label_symbols_rootp; - label_chain; - label_chain = label_chain->lss_next) + if (label_chain) { #ifdef OBJ_SOM - if (current_space == label_chain->lss_space && label_chain->lss_label) - return label_chain; + if (current_space == label_chain->lss_space && label_chain->lss_label) + return label_chain; #endif #ifdef OBJ_ELF - if (now_seg == label_chain->lss_segment && label_chain->lss_label) - return label_chain; + if (now_seg == label_chain->lss_segment && label_chain->lss_label) + return label_chain; #endif } @@ -1126,28 +1140,23 @@ pa_get_label (void) void pa_define_label (symbolS *symbol) { - label_symbol_struct *label_chain = pa_get_label (); + label_symbol_struct *label_chain = label_symbols_rootp; - if (label_chain) - label_chain->lss_label = symbol; - else - { - /* Create a new label entry and add it to the head of the chain. */ - label_chain = xmalloc (sizeof (label_symbol_struct)); - label_chain->lss_label = symbol; + if (!label_chain) + label_chain = &last_label_symbol; + + label_chain->lss_label = symbol; #ifdef OBJ_SOM - label_chain->lss_space = current_space; + label_chain->lss_space = current_space; #endif #ifdef OBJ_ELF - label_chain->lss_segment = now_seg; + label_chain->lss_segment = now_seg; #endif - label_chain->lss_next = NULL; - if (label_symbols_rootp) - label_chain->lss_next = label_symbols_rootp; + /* Not used. */ + label_chain->lss_next = NULL; - label_symbols_rootp = label_chain; - } + label_symbols_rootp = label_chain; #ifdef OBJ_ELF dwarf2_emit_label (symbol); @@ -1160,33 +1169,7 @@ pa_define_label (symbolS *symbol) static void pa_undefine_label (void) { - label_symbol_struct *label_chain; - label_symbol_struct *prev_label_chain = NULL; - - for (label_chain = label_symbols_rootp; - label_chain; - label_chain = label_chain->lss_next) - { - if (1 -#ifdef OBJ_SOM - && current_space == label_chain->lss_space && label_chain->lss_label -#endif -#ifdef OBJ_ELF - && now_seg == label_chain->lss_segment && label_chain->lss_label -#endif - ) - { - /* Remove the label from the chain and free its memory. */ - if (prev_label_chain) - prev_label_chain->lss_next = label_chain->lss_next; - else - label_symbols_rootp = label_chain->lss_next; - - free (label_chain); - break; - } - prev_label_chain = label_chain; - } + label_symbols_rootp = NULL; } /* An HPPA-specific version of fix_new. This is required because the HPPA @@ -1211,7 +1194,7 @@ fix_new_hppa (fragS *frag, int unwind_bits ATTRIBUTE_UNUSED) { fixS *new_fix; - struct hppa_fix_struct *hppa_fix = obstack_alloc (¬es, sizeof (struct hppa_fix_struct)); + struct hppa_fix_struct *hppa_fix = XOBNEW (¬es, struct hppa_fix_struct); if (exp != NULL) new_fix = fix_new_exp (frag, where, size, exp, pcrel, r_type); @@ -1233,6 +1216,7 @@ fix_new_hppa (fragS *frag, it now so as not to confuse write.c. Ditto for $PIC_pcrel$0. */ if (new_fix->fx_subsy && (strcmp (S_GET_NAME (new_fix->fx_subsy), "$global$") == 0 + || strcmp (S_GET_NAME (new_fix->fx_subsy), "$segrel$") == 0 || strcmp (S_GET_NAME (new_fix->fx_subsy), "$PIC_pcrel$0") == 0 || strcmp (S_GET_NAME (new_fix->fx_subsy), "$tls_gdidx$") == 0 || strcmp (S_GET_NAME (new_fix->fx_subsy), "$tls_ldidx$") == 0 @@ -1246,7 +1230,8 @@ fix_new_hppa (fragS *frag, hppa_field_selector is set by the parse_cons_expression_hppa. */ void -cons_fix_new_hppa (fragS *frag, int where, int size, expressionS *exp) +cons_fix_new_hppa (fragS *frag, int where, int size, expressionS *exp, + int hppa_field_selector) { unsigned int rel_type; @@ -1256,6 +1241,8 @@ cons_fix_new_hppa (fragS *frag, int where, int size, expressionS *exp) else if (is_PC_relative (*exp)) rel_type = R_HPPA_PCREL_CALL; #ifdef OBJ_ELF + else if (is_SB_relative (*exp)) + rel_type = R_PARISC_SEGREL32; else if (is_tls_gdidx (*exp)) rel_type = R_PARISC_TLS_GD21L; else if (is_tls_ldidx (*exp)) @@ -1281,9 +1268,6 @@ cons_fix_new_hppa (fragS *frag, int where, int size, expressionS *exp) fix_new_hppa (frag, where, size, (symbolS *) NULL, (offsetT) 0, exp, 0, rel_type, hppa_field_selector, size * 8, 0, 0); - - /* Reset field selector to its default state. */ - hppa_field_selector = 0; } /* Mark (via expr_end) the end of an expression (I think). FIXME. */ @@ -1335,7 +1319,7 @@ pa_parse_nullif (char **s) return nullif; } -char * +const char * md_atof (int type, char *litP, int *sizeP) { return ieee_md_atof (type, litP, sizeP, TRUE); @@ -1368,15 +1352,28 @@ tc_gen_reloc (asection *section, fixS *fixp) if (fixp->fx_addsy == 0) return &no_relocs; - assert (hppa_fixp != 0); - assert (section != 0); + gas_assert (hppa_fixp != 0); + gas_assert (section != 0); - reloc = xmalloc (sizeof (arelent)); + reloc = XNEW (arelent); - reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); + reloc->sym_ptr_ptr = XNEW (asymbol *); *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); + + /* Allow fixup_segment to recognize hand-written pc-relative relocations. + When we went through cons_fix_new_hppa, we classified them as complex. */ + /* ??? It might be better to hide this +8 stuff in tc_cfi_emit_pcrel_expr, + undefine DIFF_EXPR_OK, and let these sorts of complex expressions fail + when R_HPPA_COMPLEX == R_PARISC_UNIMPLEMENTED. */ + if (fixp->fx_r_type == (int) R_HPPA_COMPLEX + && fixp->fx_pcrel) + { + fixp->fx_r_type = (int) R_HPPA_PCREL_CALL; + fixp->fx_offset += 8; + } + codes = hppa_gen_reloc_type (stdoutput, - fixp->fx_r_type, + (int) fixp->fx_r_type, hppa_fixp->fx_r_format, hppa_fixp->fx_r_field, fixp->fx_subsy != NULL, @@ -1391,8 +1388,8 @@ tc_gen_reloc (asection *section, fixS *fixp) for (n_relocs = 0; codes[n_relocs]; n_relocs++) ; - relocs = xmalloc (sizeof (arelent *) * n_relocs + 1); - reloc = xmalloc (sizeof (arelent) * n_relocs); + relocs = XNEWVEC (arelent *, n_relocs + 1); + reloc = XNEWVEC (arelent, n_relocs); for (i = 0; i < n_relocs; i++) relocs[i] = &reloc[i]; @@ -1402,7 +1399,7 @@ tc_gen_reloc (asection *section, fixS *fixp) switch (fixp->fx_r_type) { default: - assert (n_relocs == 1); + gas_assert (n_relocs == 1); code = *codes[0]; @@ -1443,20 +1440,20 @@ tc_gen_reloc (asection *section, fixS *fixp) /* Facilitate hand-crafted unwind info. */ if (strcmp (section->name, UNWIND_SECTION_NAME) == 0) code = R_PARISC_SEGREL32; - /* Fall thru */ + /* Fallthru */ default: reloc->addend = fixp->fx_offset; break; } - reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); + reloc->sym_ptr_ptr = XNEW (asymbol *); *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); reloc->howto = bfd_reloc_type_lookup (stdoutput, (bfd_reloc_code_real_type) code); reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; - assert (reloc->howto && (unsigned int) code == reloc->howto->type); + gas_assert (reloc->howto && (unsigned int) code == reloc->howto->type); break; } #else /* OBJ_SOM */ @@ -1466,7 +1463,7 @@ tc_gen_reloc (asection *section, fixS *fixp) { code = *codes[i]; - relocs[i]->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); + relocs[i]->sym_ptr_ptr = XNEW (asymbol *); *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); relocs[i]->howto = bfd_reloc_type_lookup (stdoutput, @@ -1479,7 +1476,7 @@ tc_gen_reloc (asection *section, fixS *fixp) /* The only time we ever use a R_COMP2 fixup is for the difference of two symbols. With that in mind we fill in all four relocs now and break out of the loop. */ - assert (i == 1); + gas_assert (i == 1); relocs[0]->sym_ptr_ptr = (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr; relocs[0]->howto @@ -1487,14 +1484,14 @@ tc_gen_reloc (asection *section, fixS *fixp) (bfd_reloc_code_real_type) *codes[0]); relocs[0]->address = fixp->fx_frag->fr_address + fixp->fx_where; relocs[0]->addend = 0; - relocs[1]->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); + relocs[1]->sym_ptr_ptr = XNEW (asymbol *); *relocs[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); relocs[1]->howto = bfd_reloc_type_lookup (stdoutput, (bfd_reloc_code_real_type) *codes[1]); relocs[1]->address = fixp->fx_frag->fr_address + fixp->fx_where; relocs[1]->addend = 0; - relocs[2]->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); + relocs[2]->sym_ptr_ptr = XNEW (asymbol *); *relocs[2]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy); relocs[2]->howto = bfd_reloc_type_lookup (stdoutput, @@ -1549,7 +1546,7 @@ tc_gen_reloc (asection *section, fixS *fixp) case R_N0SEL: case R_N1SEL: /* There is no symbol or addend associated with these fixups. */ - relocs[i]->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); + relocs[i]->sym_ptr_ptr = XNEW (asymbol *); *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (dummy_symbol); relocs[i]->addend = 0; break; @@ -1558,7 +1555,7 @@ tc_gen_reloc (asection *section, fixS *fixp) case R_ENTRY: case R_EXIT: /* There is no symbol associated with these fixups. */ - relocs[i]->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); + relocs[i]->sym_ptr_ptr = XNEW (asymbol *); *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (dummy_symbol); relocs[i]->addend = fixp->fx_offset; break; @@ -1611,7 +1608,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, valueT md_section_align (asection *segment, valueT size) { - int align = bfd_get_section_alignment (stdoutput, segment); + int align = bfd_section_alignment (segment); int align2 = (1 << align) - 1; return (size + align2) & ~align2; @@ -1656,7 +1653,7 @@ struct option md_longopts[] = size_t md_longopts_size = sizeof (md_longopts); int -md_parse_option (int c, char *arg ATTRIBUTE_UNUSED) +md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED) { switch (c) { @@ -1946,7 +1943,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) case R_PARISC_TLS_LE14R: case R_PARISC_TLS_IE21L: case R_PARISC_TLS_IE14R: - if (fixP->fx_addsy) + if (fixP->fx_addsy) S_SET_THREAD_LOCAL (fixP->fx_addsy); break; default: @@ -2099,8 +2096,8 @@ pa_parse_number (char **s, int is_float) p++; c = *p; /* Tege hack: Special case for general registers as the general - code makes a binary search with case translation, and is VERY - slow. */ + code makes a binary search with case translation, and is VERY + slow. */ if (c == 'r') { p++; @@ -2155,7 +2152,7 @@ pa_parse_number (char **s, int is_float) else { /* And finally, it could be a symbol in the absolute section which - is effectively a constant, or a register alias symbol. */ + is effectively a constant, or a register alias symbol. */ name = p; c = *p; while (is_part_of_name (c)) @@ -2173,7 +2170,7 @@ pa_parse_number (char **s, int is_float) register, so... */ have_prefix = TRUE; } - else if (S_GET_SEGMENT (sym) == &bfd_abs_section) + else if (S_GET_SEGMENT (sym) == bfd_abs_section_ptr) num = S_GET_VALUE (sym); else if (!strict) { @@ -2485,11 +2482,12 @@ pa_chk_field_selector (char **str) /* Parse a .byte, .word, .long expression for the HPPA. Called by cons via the TC_PARSE_CONS_EXPRESSION macro. */ -void +int parse_cons_expression_hppa (expressionS *exp) { - hppa_field_selector = pa_chk_field_selector (&input_line_pointer); + int hppa_field_selector = pa_chk_field_selector (&input_line_pointer); expression (exp); + return hppa_field_selector; } /* Evaluate an absolute expression EXP which may be modified by @@ -2518,51 +2516,54 @@ pa_get_absolute_expression (struct pa_it *insn, char **strp) save_in = input_line_pointer; input_line_pointer = *strp; expression (&insn->exp); - /* This is not perfect, but is a huge improvement over doing nothing. + expr_end = input_line_pointer; + input_line_pointer = save_in; + if (insn->exp.X_op != O_constant) + { + /* We have a non-match in strict mode. */ + if (!strict) + as_bad (_("Bad segment (should be absolute).")); + return 0; + } + return evaluate_absolute (insn); +} + +/* Get an absolute number. The input string is terminated at the + first whitespace character. */ + +static int +pa_get_number (struct pa_it *insn, char **strp) +{ + char *save_in; + char *s, c; + int result; + + save_in = input_line_pointer; + input_line_pointer = *strp; - The PA assembly syntax is ambiguous in a variety of ways. Consider + /* The PA assembly syntax is ambiguous in a variety of ways. Consider this string "4 %r5" Is that the number 4 followed by the register - r5, or is that 4 MOD r5? + r5, or is that 4 MOD r5? This situation occurs for example in the + coprocessor load and store instructions. Previously, calling + pa_get_absolute_expression directly results in r5 being entered + in the symbol table. - If we get a modulo expression when looking for an absolute, we try - again cutting off the input string at the first whitespace character. */ - if (insn->exp.X_op == O_modulus) - { - char *s, c; - int retval; + So, when looking for an absolute number, we cut off the input string + at the first whitespace character. Thus, expressions should generally + contain no whitespace. */ - input_line_pointer = *strp; - s = *strp; - while (*s != ',' && *s != ' ' && *s != '\t') - s++; + s = *strp; + while (*s != ',' && *s != ' ' && *s != '\t') + s++; - c = *s; - *s = 0; + c = *s; + *s = 0; - retval = pa_get_absolute_expression (insn, strp); + result = pa_get_absolute_expression (insn, strp); - input_line_pointer = save_in; - *s = c; - return evaluate_absolute (insn); - } - /* When in strict mode we have a non-match, fix up the pointers - and return to our caller. */ - if (insn->exp.X_op != O_constant && strict) - { - expr_end = input_line_pointer; - input_line_pointer = save_in; - return 0; - } - if (insn->exp.X_op != O_constant) - { - as_bad (_("Bad segment (should be absolute).")); - expr_end = input_line_pointer; - input_line_pointer = save_in; - return 0; - } - expr_end = input_line_pointer; input_line_pointer = save_in; - return evaluate_absolute (insn); + *s = c; + return result; } /* Given an argument location specification return the associated @@ -2666,7 +2667,7 @@ pa_parse_nonneg_cmpsub_cmpltr (char **s) cmpltr = 7; } /* If we have something like addb,n then there is no condition - completer. */ + completer. */ else if (strcasecmp (name, "n") == 0) { cmpltr = 0; @@ -2740,7 +2741,7 @@ pa_parse_neg_cmpsub_cmpltr (char **s) cmpltr = 7; } /* If we have something like addb,n then there is no condition - completer. */ + completer. */ else if (strcasecmp (name, "n") == 0) { cmpltr = 0; @@ -2966,7 +2967,7 @@ pa_parse_nonneg_add_cmpltr (char **s) cmpltr = 7; } /* If we have something like addb,n then there is no condition - completer. */ + completer. */ else if (strcasecmp (name, "n") == 0) { cmpltr = 0; @@ -3039,7 +3040,7 @@ pa_parse_neg_add_cmpltr (char **s) cmpltr = 7; } /* If we have something like addb,n then there is no condition - completer. */ + completer. */ else if (strcasecmp (name, "n") == 0) { cmpltr = 0; @@ -3140,7 +3141,7 @@ pa_parse_addb_64_cmpltr (char **s) cmpltr = 15; } /* If we have something like addb,n then there is no condition - completer. */ + completer. */ else if (strcasecmp (name, "n") == 0) { cmpltr = 0; @@ -3166,12 +3167,13 @@ pa_parse_addb_64_cmpltr (char **s) static void pa_ip (char *str) { - char *error_message = ""; + const char *error_message = ""; char *s, c, *argstart, *name, *save_s; const char *args; int match = FALSE; int comma = 0; - int cmpltr, nullif, flag, cond, num; + int cmpltr, nullif, flag, cond, need_cond, num; + int immediate_check = 0, pos = -1, len = -1; unsigned long opcode; struct pa_opcode *insn; @@ -3211,10 +3213,10 @@ pa_ip (char *str) return; } - /* Look up the opcode in the has table. */ + /* Look up the opcode in the hash table. */ if ((insn = (struct pa_opcode *) hash_find (op_hash, str)) == NULL) { - as_bad ("Unknown opcode: `%s'", str); + as_bad (_("Unknown opcode: `%s'"), str); return; } @@ -3230,6 +3232,7 @@ pa_ip (char *str) opcode = insn->match; strict = (insn->flags & FLAG_STRICT); memset (&the_insn, 0, sizeof (the_insn)); + need_cond = 1; the_insn.reloc = R_HPPA_NONE; @@ -3238,7 +3241,7 @@ pa_ip (char *str) goto failed; /* Build the opcode, checking as we go to make - sure that the operands match. */ + sure that the operands match. */ for (args = insn->args;; ++args) { /* Absorb white space in instruction. */ @@ -3289,12 +3292,12 @@ pa_ip (char *str) s = s + 1; if (!strncasecmp (s, "%sar", 4)) - { + { s += 4; continue; } else if (!strncasecmp (s, "%cr11", 5)) - { + { s += 5; continue; } @@ -3332,6 +3335,7 @@ pa_ip (char *str) break; s = expr_end; CHECK_FIELD (num, 32, 1, 0); + SAVE_IMMEDIATE(num); INSERT_FIELD_AND_CONTINUE (opcode, 32 - num, 0); /* Handle a 5 bit immediate at 15. */ @@ -3498,11 +3502,12 @@ pa_ip (char *str) } else if (*args == 'J') { - /* M bit is explicit in the major opcode. */ + /* M bit is explicit in the major opcode. */ INSERT_FIELD_AND_CONTINUE (opcode, a, 2); } - else if (*args == 'e') + else { + gas_assert (*args == 'e'); /* Stash the ma/mb flag temporarily in the instruction. We will use (and remove it) later when handling 'J', 'K', '<' & '>'. */ @@ -3723,6 +3728,8 @@ pa_ip (char *str) else break; + /* Condition is not required with "dc". */ + need_cond = 0; INSERT_FIELD_AND_CONTINUE (opcode, flag, 11); /* Handle 32 bit carry for ADD. */ @@ -3791,6 +3798,8 @@ pa_ip (char *str) else break; + /* Condition is not required with "db". */ + need_cond = 0; INSERT_FIELD_AND_CONTINUE (opcode, flag, 11); /* Handle 32 bit borrow for SUB. */ @@ -3890,7 +3899,7 @@ pa_ip (char *str) permloc[2] = 8; permloc[3] = 6; for (; i < 4; i++) - { + { switch (*s++) { case '0': @@ -4016,6 +4025,11 @@ pa_ip (char *str) as_bad (_("Invalid Add Condition: %s"), name); *s = c; } + /* Except with "dc", we have a match failure with + 'A' if we don't have a doubleword condition. */ + else if (*args == 'A' && need_cond) + break; + opcode |= cmpltr << 13; INSERT_FIELD_AND_CONTINUE (opcode, flag, 12); @@ -4095,8 +4109,11 @@ pa_ip (char *str) s += 2; } else - as_bad (_("Invalid Bit Branch Condition: %c"), *s); + as_bad (_("Invalid Branch On Bit Condition: %c"), *s); } + else + as_bad (_("Missing Branch On Bit Condition")); + INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 15); /* Handle a compare/subtract condition. */ @@ -4184,6 +4201,11 @@ pa_ip (char *str) name); *s = c; } + /* Except with "db", we have a match failure with + 'S' if we don't have a doubleword condition. */ + else if (*args == 'S' && need_cond) + break; + opcode |= cmpltr << 13; INSERT_FIELD_AND_CONTINUE (opcode, flag, 12); @@ -4242,7 +4264,7 @@ pa_ip (char *str) INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13); - /* Handle a logical instruction condition. */ + /* Handle a logical instruction condition. */ case 'L': case 'l': cmpltr = 0; @@ -4306,6 +4328,10 @@ pa_ip (char *str) as_bad (_("Invalid Logical Instruction Condition.")); *s = c; } + /* 32-bit is default for no condition. */ + else if (*args == 'L') + break; + opcode |= cmpltr << 13; INSERT_FIELD_AND_CONTINUE (opcode, flag, 12); @@ -4314,6 +4340,9 @@ pa_ip (char *str) case 'x': case 'y': cmpltr = 0; + /* Check immediate values in shift/extract/deposit + * instructions if they will give undefined behaviour. */ + immediate_check = 1; if (*s == ',') { save_s = s++; @@ -4361,6 +4390,7 @@ pa_ip (char *str) as_bad (_("Invalid Shift/Extract/Deposit Condition.")); *s = c; } + INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13); /* Handle a unit instruction condition. */ @@ -4370,6 +4400,7 @@ pa_ip (char *str) flag = 0; if (*s == ',') { + int uxor; s++; /* 64 bit conditions. */ @@ -4383,6 +4414,9 @@ pa_ip (char *str) else if (*s == '*') break; + /* The uxor instruction only supports unit conditions + not involving carries. */ + uxor = (opcode & 0xfc000fc0) == 0x08000380; if (strncasecmp (s, "sbz", 3) == 0) { cmpltr = 2; @@ -4393,17 +4427,17 @@ pa_ip (char *str) cmpltr = 3; s += 3; } - else if (strncasecmp (s, "sdc", 3) == 0) + else if (!uxor && strncasecmp (s, "sdc", 3) == 0) { cmpltr = 4; s += 3; } - else if (strncasecmp (s, "sbc", 3) == 0) + else if (!uxor && strncasecmp (s, "sbc", 3) == 0) { cmpltr = 6; s += 3; } - else if (strncasecmp (s, "shc", 3) == 0) + else if (!uxor && strncasecmp (s, "shc", 3) == 0) { cmpltr = 7; s += 3; @@ -4426,19 +4460,19 @@ pa_ip (char *str) flag = 1; s += 3; } - else if (strncasecmp (s, "ndc", 3) == 0) + else if (!uxor && strncasecmp (s, "ndc", 3) == 0) { cmpltr = 4; flag = 1; s += 3; } - else if (strncasecmp (s, "nbc", 3) == 0) + else if (!uxor && strncasecmp (s, "nbc", 3) == 0) { cmpltr = 6; flag = 1; s += 3; } - else if (strncasecmp (s, "nhc", 3) == 0) + else if (!uxor && strncasecmp (s, "nhc", 3) == 0) { cmpltr = 7; flag = 1; @@ -4450,7 +4484,7 @@ pa_ip (char *str) flag = 0; s += 3; } - else if (strncasecmp (s, "swc", 3) == 0) + else if (!uxor && strncasecmp (s, "swc", 3) == 0) { cmpltr = 5; flag = 0; @@ -4462,7 +4496,7 @@ pa_ip (char *str) flag = 1; s += 3; } - else if (strncasecmp (s, "nwc", 3) == 0) + else if (!uxor && strncasecmp (s, "nwc", 3) == 0) { cmpltr = 5; flag = 1; @@ -4472,6 +4506,10 @@ pa_ip (char *str) else if (*args != 'U' || (*s != ' ' && *s != '\t')) as_bad (_("Invalid Unit Instruction Condition.")); } + /* 32-bit is default for no condition. */ + else if (*args == 'U') + break; + opcode |= cmpltr << 13; INSERT_FIELD_AND_CONTINUE (opcode, flag, 12); @@ -5065,7 +5103,7 @@ pa_ip (char *str) continue; } else - break; + break; /* Handle '%sr0,%r31' implicit operand of be,l instruction. */ case 'Y': @@ -5106,6 +5144,7 @@ pa_ip (char *str) break; s = expr_end; CHECK_FIELD (num, 31, 0, strict); + SAVE_IMMEDIATE(num); INSERT_FIELD_AND_CONTINUE (opcode, 31 - num, 5); /* Handle a 6 bit shift count at 20,22:26. */ @@ -5115,6 +5154,7 @@ pa_ip (char *str) break; s = expr_end; CHECK_FIELD (num, 63, 0, strict); + SAVE_IMMEDIATE(num); num = 63 - num; opcode |= (num & 0x20) << 6; INSERT_FIELD_AND_CONTINUE (opcode, num & 0x1f, 5); @@ -5127,6 +5167,7 @@ pa_ip (char *str) break; s = expr_end; CHECK_FIELD (num, 64, 1, strict); + SAVE_IMMEDIATE(num); num--; opcode |= (num & 0x20) << 3; num = 31 - (num & 0x1f); @@ -5139,6 +5180,7 @@ pa_ip (char *str) break; s = expr_end; CHECK_FIELD (num, 64, 1, strict); + SAVE_IMMEDIATE(num); num--; opcode |= (num & 0x20) << 7; num = 31 - (num & 0x1f); @@ -5151,6 +5193,7 @@ pa_ip (char *str) break; s = expr_end; CHECK_FIELD (num, 31, 0, strict); + SAVE_IMMEDIATE(num); INSERT_FIELD_AND_CONTINUE (opcode, num, 5); /* Handle a 6 bit bit position at 20,22:26. */ @@ -5160,6 +5203,7 @@ pa_ip (char *str) break; s = expr_end; CHECK_FIELD (num, 63, 0, strict); + SAVE_IMMEDIATE(num); opcode |= (num & 0x20) << 6; INSERT_FIELD_AND_CONTINUE (opcode, num & 0x1f, 5); @@ -5172,9 +5216,7 @@ pa_ip (char *str) s = expr_end; CHECK_FIELD (num, 63, 0, strict); if (num & 0x20) - ; - else - opcode |= (1 << 13); + opcode &= ~(1 << 13); INSERT_FIELD_AND_CONTINUE (opcode, num & 0x1f, 21); /* Handle a 5 bit immediate at 10. */ @@ -5217,7 +5259,7 @@ pa_ip (char *str) case 'v': if (*s++ != ',') as_bad (_("Invalid SFU identifier")); - num = pa_get_absolute_expression (&the_insn, &s); + num = pa_get_number (&the_insn, &s); if (strict && the_insn.exp.X_op != O_constant) break; s = expr_end; @@ -5226,7 +5268,7 @@ pa_ip (char *str) /* Handle a 20 bit SOP field for spop0. */ case 'O': - num = pa_get_absolute_expression (&the_insn, &s); + num = pa_get_number (&the_insn, &s); if (strict && the_insn.exp.X_op != O_constant) break; s = expr_end; @@ -5236,7 +5278,7 @@ pa_ip (char *str) /* Handle a 15bit SOP field for spop1. */ case 'o': - num = pa_get_absolute_expression (&the_insn, &s); + num = pa_get_number (&the_insn, &s); if (strict && the_insn.exp.X_op != O_constant) break; s = expr_end; @@ -5245,7 +5287,7 @@ pa_ip (char *str) /* Handle a 10bit SOP field for spop3. */ case '0': - num = pa_get_absolute_expression (&the_insn, &s); + num = pa_get_number (&the_insn, &s); if (strict && the_insn.exp.X_op != O_constant) break; s = expr_end; @@ -5255,7 +5297,7 @@ pa_ip (char *str) /* Handle a 15 bit SOP field for spop2. */ case '1': - num = pa_get_absolute_expression (&the_insn, &s); + num = pa_get_number (&the_insn, &s); if (strict && the_insn.exp.X_op != O_constant) break; s = expr_end; @@ -5267,7 +5309,7 @@ pa_ip (char *str) case 'u': if (*s++ != ',') as_bad (_("Invalid COPR identifier")); - num = pa_get_absolute_expression (&the_insn, &s); + num = pa_get_number (&the_insn, &s); if (strict && the_insn.exp.X_op != O_constant) break; s = expr_end; @@ -5276,7 +5318,7 @@ pa_ip (char *str) /* Handle a 22bit SOP field for copr. */ case '2': - num = pa_get_absolute_expression (&the_insn, &s); + num = pa_get_number (&the_insn, &s); if (strict && the_insn.exp.X_op != O_constant) break; s = expr_end; @@ -5388,6 +5430,7 @@ pa_ip (char *str) { case SGL: opcode |= 0x20; + /* Fall through. */ case DBL: the_insn.fpof1 = flag; continue; @@ -5402,12 +5445,15 @@ pa_ip (char *str) /* Handle all floating point registers. */ case 'f': switch (*++args) - { + { /* Float target register. */ case 't': if (!pa_parse_number (&s, 3)) break; - num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE; + /* RSEL should not be set. */ + if (pa_number & FP_REG_RSEL) + break; + num = pa_number - FP_REG_BASE; CHECK_FIELD (num, 31, 0, 0); INSERT_FIELD_AND_CONTINUE (opcode, num, 0); @@ -5530,13 +5576,13 @@ pa_ip (char *str) CHECK_FIELD (num, 31, 0, 0); if (the_insn.fpof1 == SGL) { - if (num < 16) - { + if (num < 16) + { as_bad (_("Invalid register for single precision fmpyadd or fmpysub")); break; - } - num &= 0xF; - num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0); + } + num &= 0xF; + num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0); } INSERT_FIELD_AND_CONTINUE (opcode, num, 16); } @@ -5550,13 +5596,13 @@ pa_ip (char *str) CHECK_FIELD (num, 31, 0, 0); if (the_insn.fpof1 == SGL) { - if (num < 16) - { + if (num < 16) + { as_bad (_("Invalid register for single precision fmpyadd or fmpysub")); break; - } - num &= 0xF; - num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0); + } + num &= 0xF; + num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0); } INSERT_FIELD_AND_CONTINUE (opcode, num, 0); } @@ -5570,13 +5616,13 @@ pa_ip (char *str) CHECK_FIELD (num, 31, 0, 0); if (the_insn.fpof1 == SGL) { - if (num < 16) - { + if (num < 16) + { as_bad (_("Invalid register for single precision fmpyadd or fmpysub")); break; - } - num &= 0xF; - num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0); + } + num &= 0xF; + num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0); } INSERT_FIELD_AND_CONTINUE (opcode, num, 6); } @@ -5590,13 +5636,13 @@ pa_ip (char *str) CHECK_FIELD (num, 31, 0, 0); if (the_insn.fpof1 == SGL) { - if (num < 16) - { + if (num < 16) + { as_bad (_("Invalid register for single precision fmpyadd or fmpysub")); break; - } - num &= 0xF; - num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0); + } + num &= 0xF; + num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0); } INSERT_FIELD_AND_CONTINUE (opcode, num, 11); } @@ -5639,7 +5685,7 @@ pa_ip (char *str) /* If this instruction is specific to a particular architecture, then set a new architecture. This automatic promotion crud is for compatibility with HP's old assemblers only. */ - if (match == TRUE + if (match && bfd_get_mach (stdoutput) < insn->arch && !bfd_set_arch_mach (stdoutput, bfd_arch_hppa, insn->arch)) { @@ -5667,6 +5713,13 @@ pa_ip (char *str) break; } + if (immediate_check) + { + if (pos != -1 && len != -1 && pos < len - 1) + as_warn (_("Immediates %d and %d will give undefined behavior."), + pos, len); + } + the_insn.opcode = opcode; } @@ -5678,7 +5731,7 @@ md_assemble (char *str) char *to; /* The had better be something to assemble. */ - assert (str); + gas_assert (str); /* If we are within a procedure definition, make sure we've defined a label for the procedure; handle case where the @@ -5734,7 +5787,7 @@ md_assemble (char *str) if (the_insn.reloc != R_HPPA_NONE) fix_new_hppa (frag_now, (to - frag_now->fr_literal), 4, NULL, (offsetT) 0, &the_insn.exp, the_insn.pcrel, - the_insn.reloc, the_insn.field_selector, + (int) the_insn.reloc, the_insn.field_selector, the_insn.format, the_insn.arg_reloc, 0); #ifdef OBJ_ELF @@ -5841,33 +5894,28 @@ pa_try (int begin ATTRIBUTE_UNUSED) static void pa_call_args (struct call_desc *call_desc) { - char *name, c, *p; + char *name, c; unsigned int temp, arg_reloc; while (!is_end_of_statement ()) { - name = input_line_pointer; - c = get_symbol_end (); + c = get_symbol_name (&name); /* Process a source argument. */ if ((strncasecmp (name, "argw", 4) == 0)) { temp = atoi (name + 4); - p = input_line_pointer; - *p = c; + (void) restore_line_pointer (c); input_line_pointer++; - name = input_line_pointer; - c = get_symbol_end (); + c = get_symbol_name (&name); arg_reloc = pa_build_arg_reloc (name); call_desc->arg_reloc |= pa_align_arg_reloc (temp, arg_reloc); } /* Process a return value. */ else if ((strncasecmp (name, "rtnval", 6) == 0)) { - p = input_line_pointer; - *p = c; + (void) restore_line_pointer (c); input_line_pointer++; - name = input_line_pointer; - c = get_symbol_end (); + c = get_symbol_name (&name); arg_reloc = pa_build_arg_reloc (name); call_desc->arg_reloc |= (arg_reloc & 0x3); } @@ -5875,8 +5923,8 @@ pa_call_args (struct call_desc *call_desc) { as_bad (_("Invalid .CALL argument: %s"), name); } - p = input_line_pointer; - *p = c; + + (void) restore_line_pointer (c); if (!is_end_of_statement ()) input_line_pointer++; } @@ -5898,24 +5946,6 @@ pa_call (int unused ATTRIBUTE_UNUSED) demand_empty_rest_of_line (); } -/* Return TRUE if FRAG1 and FRAG2 are the same. */ - -static bfd_boolean -is_same_frag (fragS *frag1, fragS *frag2) -{ - - if (frag1 == NULL) - return FALSE; - else if (frag2 == NULL) - return FALSE; - else if (frag1 == frag2) - return TRUE; - else if (frag2->fr_type == rs_fill && frag2->fr_fix == 0) - return (is_same_frag (frag1, frag2->fr_next)); - else - return FALSE; -} - #ifdef OBJ_ELF /* Build an entry in the UNWIND subspace from the given function attributes in CALL_INFO. This is not needed for SOM as using @@ -5929,13 +5959,43 @@ pa_build_unwind_subspace (struct call_info *call_info) subsegT save_subseg; unsigned int unwind; int reloc; - char *p; + char *name, *p; + symbolS *symbolP; - if ((bfd_get_section_flags (stdoutput, now_seg) + if ((bfd_section_flags (now_seg) & (SEC_ALLOC | SEC_LOAD | SEC_READONLY)) != (SEC_ALLOC | SEC_LOAD | SEC_READONLY)) return; + if (call_info->start_symbol == NULL) + /* This can happen if there were errors earlier on in the assembly. */ + return; + + /* Replace the start symbol with a local symbol that will be reduced + to a section offset. This avoids problems with weak functions with + multiple definitions, etc. */ + name = concat ("L$\001start_", S_GET_NAME (call_info->start_symbol), + (char *) NULL); + + /* If we have a .procend preceded by a .exit, then the symbol will have + already been defined. In that case, we don't want another unwind + entry. */ + symbolP = symbol_find (name); + if (symbolP) + { + xfree (name); + return; + } + else + { + symbolP = symbol_new (name, now_seg, + S_GET_VALUE (call_info->start_symbol), + symbol_get_frag (call_info->start_symbol)); + gas_assert (symbolP); + S_CLEAR_EXTERNAL (symbolP); + symbol_table_insert (symbolP); + } + reloc = R_PARISC_SEGREL32; save_seg = now_seg; save_subseg = now_subseg; @@ -5946,10 +6006,9 @@ pa_build_unwind_subspace (struct call_info *call_info) if (seg == ASEC_NULL) { seg = subseg_new (UNWIND_SECTION_NAME, 0); - bfd_set_section_flags (stdoutput, seg, - SEC_READONLY | SEC_HAS_CONTENTS - | SEC_LOAD | SEC_RELOC | SEC_ALLOC | SEC_DATA); - bfd_set_section_alignment (stdoutput, seg, 2); + bfd_set_section_flags (seg, (SEC_READONLY | SEC_HAS_CONTENTS | SEC_LOAD + | SEC_RELOC | SEC_ALLOC | SEC_DATA)); + bfd_set_section_alignment (seg, 2); } subseg_set (seg, 0); @@ -5961,7 +6020,7 @@ pa_build_unwind_subspace (struct call_info *call_info) /* Relocation info. for start offset of the function. */ md_number_to_chars (p, 0, 4); fix_new_hppa (frag_now, p - frag_now->fr_literal, 4, - call_info->start_symbol, (offsetT) 0, + symbolP, (offsetT) 0, (expressionS *) NULL, 0, reloc, e_fsel, 32, 0, 0); @@ -5997,7 +6056,7 @@ pa_build_unwind_subspace (struct call_info *call_info) static void pa_callinfo (int unused ATTRIBUTE_UNUSED) { - char *name, c, *p; + char *name, c; int temp; #ifdef OBJ_SOM @@ -6016,13 +6075,11 @@ pa_callinfo (int unused ATTRIBUTE_UNUSED) /* Iterate over the .CALLINFO arguments. */ while (!is_end_of_statement ()) { - name = input_line_pointer; - c = get_symbol_end (); + c = get_symbol_name (&name); /* Frame size specification. */ if ((strncasecmp (name, "frame", 5) == 0)) { - p = input_line_pointer; - *p = c; + (void) restore_line_pointer (c); input_line_pointer++; temp = get_absolute_expression (); if ((temp & 0x3) != 0) @@ -6033,13 +6090,11 @@ pa_callinfo (int unused ATTRIBUTE_UNUSED) /* callinfo is in bytes and unwind_desc is in 8 byte units. */ last_call_info->ci_unwind.descriptor.frame_size = temp / 8; - } /* Entry register (GR, GR and SR) specifications. */ else if ((strncasecmp (name, "entry_gr", 8) == 0)) { - p = input_line_pointer; - *p = c; + (void) restore_line_pointer (c); input_line_pointer++; temp = get_absolute_expression (); /* The HP assembler accepts 19 as the high bound for ENTRY_GR @@ -6051,8 +6106,7 @@ pa_callinfo (int unused ATTRIBUTE_UNUSED) } else if ((strncasecmp (name, "entry_fr", 8) == 0)) { - p = input_line_pointer; - *p = c; + (void) restore_line_pointer (c); input_line_pointer++; temp = get_absolute_expression (); /* Similarly the HP assembler takes 31 as the high bound even @@ -6063,53 +6117,46 @@ pa_callinfo (int unused ATTRIBUTE_UNUSED) } else if ((strncasecmp (name, "entry_sr", 8) == 0)) { - p = input_line_pointer; - *p = c; + (void) restore_line_pointer (c); input_line_pointer++; temp = get_absolute_expression (); if (temp != 3) as_bad (_("Value for ENTRY_SR must be 3\n")); } /* Note whether or not this function performs any calls. */ - else if ((strncasecmp (name, "calls", 5) == 0) || - (strncasecmp (name, "caller", 6) == 0)) + else if ((strncasecmp (name, "calls", 5) == 0) + || (strncasecmp (name, "caller", 6) == 0)) { - p = input_line_pointer; - *p = c; + (void) restore_line_pointer (c); } else if ((strncasecmp (name, "no_calls", 8) == 0)) { - p = input_line_pointer; - *p = c; + (void) restore_line_pointer (c); } /* Should RP be saved into the stack. */ else if ((strncasecmp (name, "save_rp", 7) == 0)) { - p = input_line_pointer; - *p = c; + (void) restore_line_pointer (c); last_call_info->ci_unwind.descriptor.save_rp = 1; } /* Likewise for SP. */ else if ((strncasecmp (name, "save_sp", 7) == 0)) { - p = input_line_pointer; - *p = c; + (void) restore_line_pointer (c); last_call_info->ci_unwind.descriptor.save_sp = 1; } /* Is this an unwindable procedure. If so mark it so - in the unwind descriptor. */ + in the unwind descriptor. */ else if ((strncasecmp (name, "no_unwind", 9) == 0)) { - p = input_line_pointer; - *p = c; + (void) restore_line_pointer (c); last_call_info->ci_unwind.descriptor.cannot_unwind = 1; } /* Is this an interrupt routine. If so mark it in the - unwind descriptor. */ + unwind descriptor. */ else if ((strncasecmp (name, "hpux_int", 7) == 0)) { - p = input_line_pointer; - *p = c; + (void) restore_line_pointer (c); last_call_info->ci_unwind.descriptor.hpux_interrupt_marker = 1; } /* Is this a millicode routine. "millicode" isn't in my @@ -6118,15 +6165,15 @@ pa_callinfo (int unused ATTRIBUTE_UNUSED) to drop the information, so we'll accept it too. */ else if ((strncasecmp (name, "millicode", 9) == 0)) { - p = input_line_pointer; - *p = c; + (void) restore_line_pointer (c); last_call_info->ci_unwind.descriptor.millicode = 1; } else { as_bad (_("Invalid .CALLINFO argument: %s"), name); - *input_line_pointer = c; + (void) restore_line_pointer (c); } + if (!is_end_of_statement ()) input_line_pointer++; } @@ -6166,7 +6213,7 @@ pa_data (int unused ATTRIBUTE_UNUSED) } /* This is different than the standard GAS s_comm(). On HP9000/800 machines, - the .comm pseudo-op has the following symtax: + the .comm pseudo-op has the following syntax: