From f1bcba5b901a203c68ca4b0a280ca1af909ff8e7 Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Wed, 1 Nov 2000 00:00:34 +0000 Subject: Add tag support. Error for dangling qualifying predicates. * config/tc-ia64.c (struct md): New field tag_fixups. (ia64_flush_insns): Handle tag_fixups. Error if dangling qualifying predicate. (emit_one_bundle): Delete spurious multiplication by one. Handle tag_fixups. (ia64_start_line): Error if dangling qualifying predicate. (defining_tag): New static variable. (ia64_unrecognized_line, case '['): Parse tags. (ia64_frob_label): Create tag_fixups. (md_assemble): Reset md.qp.X_op after using it. --- gas/ChangeLog | 13 +++++++++ gas/config/tc-ia64.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 90 insertions(+), 2 deletions(-) (limited to 'gas') diff --git a/gas/ChangeLog b/gas/ChangeLog index bb239f2..9be1453 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,16 @@ +2000-10-31 Jim Wilson + + * config/tc-ia64.c (struct md): New field tag_fixups. + (ia64_flush_insns): Handle tag_fixups. Error if dangling + qualifying predicate. + (emit_one_bundle): Delete spurious multiplication by one. Handle + tag_fixups. + (ia64_start_line): Error if dangling qualifying predicate. + (defining_tag): New static variable. + (ia64_unrecognized_line, case '['): Parse tags. + (ia64_frob_label): Create tag_fixups. + (md_assemble): Reset md.qp.X_op after using it. + 2000-10-31 Kaz Kojima * config/tc-sh.c (md_apply_fix [BFD_RELOC_SH_PCDISP12BY2]): Allow 4094. diff --git a/gas/config/tc-ia64.c b/gas/config/tc-ia64.c index 1c0508e..c582e50 100644 --- a/gas/config/tc-ia64.c +++ b/gas/config/tc-ia64.c @@ -219,6 +219,7 @@ static struct fixup[2]; /* at most two fixups per insn */ struct ia64_opcode *idesc; struct label_fix *label_fixups; + struct label_fix *tag_fixups; struct unw_rec_list *unwind_record; /* Unwind directive. */ expressionS opnd[6]; char *src_file; @@ -897,8 +898,17 @@ ia64_flush_insns () symbol_set_frag (lfix->sym, frag_now); } CURR_SLOT.label_fixups = 0; + for (lfix = CURR_SLOT.tag_fixups; lfix; lfix = lfix->next) + { + S_SET_VALUE (lfix->sym, frag_now_fix ()); + symbol_set_frag (lfix->sym, frag_now); + } + CURR_SLOT.tag_fixups = 0; subseg_set (saved_seg, saved_subseg); + + if (md.qp.X_op == O_register) + as_bad ("qualifying predicate not followed by instruction"); } void @@ -5476,7 +5486,7 @@ emit_one_bundle () { bfd_vma addr; - addr = frag_now->fr_address + frag_now_fix () - 16 + 1 * i; + addr = frag_now->fr_address + frag_now_fix () - 16 + i; dwarf2_gen_line_info (addr, &md.slot[curr].debug_line); } @@ -5504,6 +5514,12 @@ emit_one_bundle () S_SET_VALUE (lfix->sym, frag_now_fix () - 16); symbol_set_frag (lfix->sym, frag_now); } + /* and fix up the tags also. */ + for (lfix = md.slot[curr].tag_fixups; lfix; lfix = lfix->next) + { + S_SET_VALUE (lfix->sym, frag_now_fix () - 16 + i); + symbol_set_frag (lfix->sym, frag_now); + } for (j = 0; j < md.slot[curr].num_fixups; ++j) { @@ -5962,6 +5978,8 @@ ia64_end_of_source () void ia64_start_line () { + if (md.qp.X_op == O_register) + as_bad ("qualifying predicate not followed by instruction"); md.qp.X_op = O_absent; if (ignore_input ()) @@ -5976,6 +5994,10 @@ ia64_start_line () } } +/* This is a hook for ia64_frob_label, so that it can distinguish tags from + labels. */ +static int defining_tag = 0; + int ia64_unrecognized_line (ch) int ch; @@ -6046,6 +6068,44 @@ ia64_unrecognized_line (ch) demand_empty_rest_of_line (); return 1; + case '[': + { + char *s; + char c; + symbolS *tag; + + if (md.qp.X_op == O_register) + { + as_bad ("Tag must come before qualifying predicate."); + return 0; + } + s = input_line_pointer; + c = get_symbol_end (); + if (c != ':') + { + /* Put ':' back for error messages' sake. */ + *input_line_pointer++ = ':'; + as_bad ("Expected ':'"); + return 0; + } + defining_tag = 1; + tag = colon (s); + defining_tag = 0; + /* Put ':' back for error messages' sake. */ + *input_line_pointer++ = ':'; + if (*input_line_pointer++ != ']') + { + as_bad ("Expected ']'"); + return 0; + } + if (! tag) + { + as_bad ("Tag name expected"); + return 0; + } + return 1; + } + default: break; } @@ -6060,6 +6120,18 @@ ia64_frob_label (sym) { struct label_fix *fix; + /* Tags need special handling since they are not bundle breaks like + labels. */ + if (defining_tag) + { + fix = obstack_alloc (¬es, sizeof (*fix)); + fix->sym = sym; + fix->next = CURR_SLOT.tag_fixups; + CURR_SLOT.tag_fixups = fix; + + return; + } + if (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) { md.last_text_seg = now_seg; @@ -8768,7 +8840,10 @@ md_assemble (str) qp_regno = 0; if (md.qp.X_op == O_register) - qp_regno = md.qp.X_add_number - REG_P; + { + qp_regno = md.qp.X_add_number - REG_P; + md.qp.X_op = O_absent; + } flags = idesc->flags; -- cgit v1.1