OSDN Git Service

Add tag support. Error for dangling qualifying predicates.
authorJim Wilson <wilson@tuliptree.org>
Wed, 1 Nov 2000 00:00:34 +0000 (00:00 +0000)
committerJim Wilson <wilson@tuliptree.org>
Wed, 1 Nov 2000 00:00:34 +0000 (00:00 +0000)
* 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
gas/config/tc-ia64.c

index bb239f2..9be1453 100644 (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.
index 1c0508e..c582e50 100644 (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;