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.
This commit is contained in:
Jim Wilson 2000-11-01 00:00:34 +00:00
parent 4d765177eb
commit f1bcba5b90
2 changed files with 90 additions and 2 deletions

View file

@ -1,3 +1,16 @@
2000-10-31 Jim Wilson <wilson@redhat.com>
* 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 <kkojima@rr.iij4u.or.jp>
* config/tc-sh.c (md_apply_fix [BFD_RELOC_SH_PCDISP12BY2]): Allow 4094.

View file

@ -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 (&notes, 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;