* cgen.h: New file.
[deliverable/binutils-gdb.git] / gas / config / tc-m32r.c
index bdbd1984843f048b335f3d257138457fbd667e65..31c491587d300b1cc9dc9199960ebb084075be6d 100644 (file)
 #include "subsegs.h"     
 #include "symcat.h"
 #include "cgen-opc.h"
+#include "cgen.h"
 
+/* Linked list of symbols that are debugging symbols to be defined as the
+   beginning of the current instruction.  */
+typedef struct sym_link
+{
+  struct sym_link *next;
+  symbolS        *symbol;
+} sym_linkS;
+
+static sym_linkS *debug_sym_link = (sym_linkS *)0;
+  
 /* Structure to hold all of the different components describing an individual instruction.  */
 typedef struct
 {
@@ -38,7 +49,10 @@ typedef struct
 #endif
   char *               addr;
   fragS *              frag;
+  int                   num_fixups;
+  fixS *                fixups [CGEN_MAX_FIXUPS];
   int                   indices [MAX_OPERAND_INSTANCES];
+  sym_linkS            *debug_sym_link;
 }
 m32r_insn;
 
@@ -69,10 +83,8 @@ static int enable_m32rx = 0;
    instruction might have constraint violations.  */
 static int warn_explicit_parallel_conflicts = 1;
 
-/* start-sanitize-phase2-m32rx */
 /* Non-zero if insns can be made parallel.  */
 static int optimize;
-/* end-sanitize-phase2-m32rx */
 /* end-sanitize-m32rx */
 
 /* stuff for .scomm symbols.  */
@@ -124,10 +136,10 @@ allow_m32rx (on)
 /* end-sanitize-m32rx */
 \f
 #define M32R_SHORTOPTS ""
-/* start-sanitize-phase2-m32rx */
+/* start-sanitize-m32rx */
 #undef M32R_SHORTOPTS
 #define M32R_SHORTOPTS "O"
-/* end-sanitize-phase2-m32rx */
+/* end-sanitize-m32rx */
 const char * md_shortopts = M32R_SHORTOPTS;
 
 struct option md_longopts[] =
@@ -162,11 +174,9 @@ md_parse_option (c, arg)
   switch (c)
     {
 /* start-sanitize-m32rx */
-/* start-sanitize-phase2-m32rx */
     case 'O':
       optimize = 1;
       break;
-/* end-sanitize-phase2-m32rx */
 
     case OPTION_M32RX:
       allow_m32rx (1);
@@ -200,14 +210,12 @@ md_show_usage (stream)
   FILE * stream;
 {
 /* start-sanitize-m32rx */
-  fprintf (stream, _("M32R/X options:\n"));
+  fprintf (stream, _("M32R/X specific command line options:\n"));
   fprintf (stream, _("\
 --m32rx                        support the extended m32rx instruction set\n"));
 
-/* start-sanitize-phase2-m32rx */
   fprintf (stream, _("\
 -O                     try to combine instructions in parallel\n"));
-/* end-sanitize-phase2-m32rx */
 
   fprintf (stream, _("\
 --warn-explicit-parallel-conflicts     warn when parallel instrucitons violate contraints\n"));
@@ -229,6 +237,8 @@ md_show_usage (stream)
 
 static void fill_insn PARAMS ((int));
 static void m32r_scomm PARAMS ((int));
+static void debug_sym PARAMS ((int));
+static void expand_debug_syms PARAMS ((sym_linkS *, int));
 
 /* Set by md_assemble for use by m32r_fill_insn.  */
 static subsegT prev_subseg;
@@ -237,12 +247,13 @@ static segT prev_seg;
 /* The target specific pseudo-ops which we support.  */
 const pseudo_typeS md_pseudo_table[] =
 {
-  { "word", cons, 4 },
-  { "fillinsn", fill_insn, 0 },
-  { "scomm", m32r_scomm, 0 },
+  { "word",    cons,           4 },
+  { "fillinsn", fill_insn,     0 },
+  { "scomm",   m32r_scomm,     0 },
+  { "debugsym",        debug_sym,      0 },
 /* start-sanitize-m32rx */
-  { "m32r",  allow_m32rx, 0},
-  { "m32rx", allow_m32rx, 1},
+  { "m32r",    allow_m32rx,    0 },
+  { "m32rx",   allow_m32rx,    1 },
 /* end-sanitize-m32rx */
   { NULL, NULL, 0 }
 };
@@ -324,6 +335,77 @@ fill_insn (ignore)
   seen_relaxable_p = 0;
 }
 
+/* Record the symbol so that when we output the insn, we can create
+   a symbol that is at the start of the instruction.  This is used
+   to emit the label for the start of a breakpoint without causing
+   the assembler to emit a NOP if the previous instruction was a
+   16 bit instruction.  */
+
+static void
+debug_sym (ignore)
+     int ignore;
+{
+  register char *name;
+  register char delim;
+  register char *end_name;
+  register symbolS *symbolP;
+  register sym_linkS *link;
+
+  name = input_line_pointer;
+  delim = get_symbol_end ();
+  end_name = input_line_pointer;
+  if ((symbolP = symbol_find (name)) == NULL
+      && (symbolP = md_undefined_symbol (name)) == NULL)
+    {
+      symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
+    }
+
+  symbol_table_insert (symbolP);
+  if (S_IS_DEFINED (symbolP) && S_GET_SEGMENT (symbolP) != reg_section)
+    as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
+
+  else
+    {
+      link = (sym_linkS *) xmalloc (sizeof (sym_linkS));
+      link->symbol = symbolP;
+      link->next = debug_sym_link;
+      debug_sym_link = link;
+      symbolP->local = 1;
+    }
+
+  *end_name = delim;
+  demand_empty_rest_of_line ();
+}
+
+/* Second pass to expanding the debug symbols, go through linked
+   list of symbols and reassign the address.  */
+
+static void
+expand_debug_syms (syms, align)
+     sym_linkS *syms;
+     int align;
+{
+  char *save_input_line = input_line_pointer;
+  sym_linkS *next_syms;
+  expressionS exp;
+
+  if (!syms)
+    return;
+
+  (void) m32r_do_align (align, NULL, 0, 0);
+  for (; syms != (sym_linkS *)0; syms = next_syms)
+    {
+      symbolS *symbolP = syms->symbol;
+      next_syms = syms->next;
+      input_line_pointer = ".\n";
+      pseudo_set (symbolP);
+      free ((char *)syms);
+    }
+
+  input_line_pointer = save_input_line;
+}
+
 /* Cover function to fill_insn called after a label and at end of assembly.
 
    The result is always 1: we're called in a conditional to see if the
@@ -534,7 +616,7 @@ can_make_parallel (a, b)
     abort();
 
   if (first_writes_to_seconds_operands (a, b, true))
-    return "Instructions write to the same destination register.";
+    return _("Instructions write to the same destination register.");
   
   a_pipe = CGEN_INSN_ATTR (a->insn, CGEN_INSN_PIPE);
   b_pipe = CGEN_INSN_ATTR (b->insn, CGEN_INSN_PIPE);
@@ -542,19 +624,20 @@ can_make_parallel (a, b)
   /* Make sure that the instructions use the correct execution pipelines.  */
   if (   a_pipe == PIPE_NONE
       || b_pipe == PIPE_NONE)
-    return "Instructions do not use parallel execution pipelines.";
+    return _("Instructions do not use parallel execution pipelines.");
 
   /* Leave this test for last, since it is the only test that can
      go away if the instructions are swapped, and we want to make
      sure that any other errors are detected before this happens.  */
   if (   a_pipe == PIPE_S
       || b_pipe == PIPE_O)
-    return "Instructions share the same execution pipeline";
+    return _("Instructions share the same execution pipeline");
   
   return NULL;
 }
 
 #ifdef CGEN_INT_INSN
+
 static void
 make_parallel (buffer)
      cgen_insn_t * buffer;
@@ -576,7 +659,9 @@ make_parallel (buffer)
       bfd_putl16 (value, (char *) buffer);
     }
 }
+
 #else
+
 static void
 make_parallel (buffer)
      char * buffer;
@@ -585,8 +670,8 @@ make_parallel (buffer)
 
   buffer [CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG ? 0 : 1] |= 0x80;
 }
-#endif
 
+#endif /* ! CGEN_INT_INSN */
 
 static void
 assemble_parallel_insn (str, str2)
@@ -605,6 +690,9 @@ assemble_parallel_insn (str, str2)
   if (prev_insn.insn)
     fill_insn (0);
 
+  first.debug_sym_link = debug_sym_link;
+  debug_sym_link = (sym_linkS *)0;
+
   /* Parse the first instruction.  */
   if (! (first.insn = CGEN_SYM (assemble_insn)
         (str, & first.fields, first.buffer, & errmsg)))
@@ -612,61 +700,31 @@ assemble_parallel_insn (str, str2)
       as_bad (errmsg);
       return;
     }
-  
-  /* Check to see if this is an allowable parallel insn.  */
-  if (CGEN_INSN_ATTR (first.insn, CGEN_INSN_PIPE) == PIPE_NONE)
-    {
-      as_bad (_("instruction '%s' cannot be executed in parallel."), str);
-      return;
-    }
-  
+
   if (! enable_m32rx
+      /* FIXME: Need standard macro to perform this test.  */
       && CGEN_INSN_ATTR (first.insn, CGEN_INSN_MACH) == (1 << MACH_M32RX))
     {
       as_bad (_("instruction '%s' is for the M32RX only"), str);
       return;
     }
-  
-  /* Temporary Hack:
-     If the instruciton is relaxable, reparse it looking for a non-relaxable variant.
-     (We do not want to relax instructions inside a parallel construction, and if it
-     turns out that the branch is too far for the displacement field available to the
-     non-relaxed instruction, then this is the programmer's fault.
-     A better solution would be to pass attribute requirements to assemble_insn() so
-     that the relaxable variant would not be accepted as a valid parse of the instruction.  */
-  
-  if (CGEN_INSN_ATTR (first.insn, CGEN_INSN_RELAXABLE) != 0)
-    {
-      char buf[128];
-      char * p;
-      /* Oh dear - the insn is relaxable, so it might be replaced with a longer,
-        non-parallel version.  Try appending ".s" to the instruction and reparsing it.  */
 
-      p = strchr (str, ' ');
-      if (p == NULL)
-       abort();
-      * p = 0;
-      sprintf (buf, "%s.s %s", str, p + 1);
-      * p = ' ';
-
-      /* Reset fixup list to empty.  */
-      cgen_save_fixups();
-      
-      first.insn = CGEN_SYM (assemble_insn) (buf, & first.fields, first.buffer, & errmsg);
-
-      if (first.insn == NULL)
-       abort();
+  /* Check to see if this is an allowable parallel insn.  */
+  if (CGEN_INSN_ATTR (first.insn, CGEN_INSN_PIPE) == PIPE_NONE)
+    {
+      as_bad (_("instruction '%s' cannot be executed in parallel."), str);
+      return;
     }
   
   *str2 = '|';       /* Restore the original assembly text, just in case it is needed.  */
   str3  = str;       /* Save the original string pointer.  */
   str   = str2 + 2;  /* Advanced past the parsed string.  */
   str2  = str3;      /* Remember the entire string in case it is needed for error messages.  */
-  
+
   /* Preserve any fixups that have been generated and reset the list to empty.  */
   cgen_save_fixups();
 
-  /* Get the indicies of the operands of the instruction.  */
+  /* Get the indices of the operands of the instruction.  */
   /* FIXME: CGEN_FIELDS is already recorded, but relying on that fact
      doesn't seem right.  Perhaps allow passing fields like we do insn.  */
   /* FIXME: ALIAS insns do not have operands, so we use this function
@@ -676,10 +734,14 @@ assemble_parallel_insn (str, str2)
      version (eg relaxability).  When aliases behave differently this
      may have to change.  */
   first.orig_insn = first.insn;
-  first.insn = m32r_cgen_get_insn_operands (first.insn, bfd_getb16 ((char *) first.buffer), 16,
-                                           first.indices);
+  first.insn = m32r_cgen_lookup_get_insn_operands (NULL,
+                                                  bfd_getb16 ((char *) first.buffer),
+                                                  16,
+                                                  first.indices);
   if (first.insn == NULL)
-    as_fatal (_("internal error: m32r_cgen_get_insn_operands failed for first insn"));
+    as_fatal (_("internal error: m32r_cgen_lookup_get_insn_operands failed for first insn"));
+
+  second.debug_sym_link = NULL;
 
   /* Parse the second instruction.  */
   if (! (second.insn = CGEN_SYM (assemble_insn)
@@ -696,48 +758,32 @@ assemble_parallel_insn (str, str2)
       as_bad (_("instruction '%s' is for the M32RX only"), str);
       return;
     }
+
+  /* Check to see if this is an allowable parallel insn.  */
+  if (CGEN_INSN_ATTR (second.insn, CGEN_INSN_PIPE) == PIPE_NONE)
+    {
+      as_bad (_("instruction '%s' cannot be executed in parallel."), str);
+      return;
+    }
   
   if (! enable_m32rx)
     {
-      if (   strcmp (first.insn->name, "nop") != 0
-         && strcmp (second.insn->name, "nop") != 0)
+      if (CGEN_INSN_NUM (first.insn) != M32R_INSN_NOP
+         && CGEN_INSN_NUM (second.insn) != M32R_INSN_NOP)
        {
          as_bad (_("'%s': only the NOP instruction can be issued in parallel on the m32r"), str2);
          return;
        }
     }
 
-  /* See comment above.  */
-  if (CGEN_INSN_ATTR (second.insn, CGEN_INSN_RELAXABLE) != 0)
-    {
-      char   buf[128];
-      char * p;
-      /* Oh dear - the insn is relaxable, so it might be replaced with a longer,
-        non-parallel version.  Try appending ".s" to the instruction and reparsing it.  */
-
-      p = strchr (str, ' ');
-      if (p == NULL)
-       abort();
-      * p = 0;
-      sprintf (buf, "%s.s %s", str, p + 1);
-      * p = ' ';
-
-      /* Reset fixup list to empty, preserving saved fixups.  */
-      cgen_restore_fixups();
-      cgen_save_fixups();
-      
-      second.insn = CGEN_SYM (assemble_insn) (buf, & second.fields, second.buffer, & errmsg);
-
-      if (second.insn == NULL)
-       abort();
-    }
-  
-  /* Get the indicies of the operands of the instruction.  */
+  /* Get the indices of the operands of the instruction.  */
   second.orig_insn = second.insn;
-  second.insn = m32r_cgen_get_insn_operands (second.insn, bfd_getb16 ((char *) second.buffer), 16,
-                                            second.indices);
+  second.insn = m32r_cgen_lookup_get_insn_operands (NULL,
+                                                   bfd_getb16 ((char *) second.buffer),
+                                                   16,
+                                                   second.indices);
   if (second.insn == NULL)
-    as_fatal (_("internal error: m32r_cgen_get_insn_operands failed for second insn"));
+    as_fatal (_("internal error: m32r_cgen_lookup_get_insn_operands failed for second insn"));
 
   /* We assume that if the first instruction writes to a register that is
      read by the second instruction it is because the programmer intended
@@ -762,8 +808,9 @@ assemble_parallel_insn (str, str2)
       cgen_swap_fixups ();
 
       /* Write it out.  */
-      (void) cgen_asm_finish_insn (first.orig_insn, first.buffer,
-                                  CGEN_FIELDS_BITSIZE (& first.fields));
+      expand_debug_syms (first.debug_sym_link, 1);
+      cgen_asm_finish_insn (first.orig_insn, first.buffer,
+                           CGEN_FIELDS_BITSIZE (& first.fields), 0, NULL);
       
       /* Force the top bit of the second insn to be set.  */
       make_parallel (second.buffer);
@@ -772,15 +819,17 @@ assemble_parallel_insn (str, str2)
       cgen_restore_fixups ();
 
       /* Write it out.  */
-      (void) cgen_asm_finish_insn (second.orig_insn, second.buffer,
-                                  CGEN_FIELDS_BITSIZE (& second.fields));
+      expand_debug_syms (second.debug_sym_link, 1);
+      cgen_asm_finish_insn (second.orig_insn, second.buffer,
+                           CGEN_FIELDS_BITSIZE (& second.fields), 0, NULL);
     }
   /* Try swapping the instructions to see if they work that way.  */
   else if (can_make_parallel (& second, & first) == NULL)
     {
       /* Write out the second instruction first.  */
-      (void) cgen_asm_finish_insn (second.orig_insn, second.buffer,
-                                  CGEN_FIELDS_BITSIZE (& second.fields));
+      expand_debug_syms (second.debug_sym_link, 1);
+      cgen_asm_finish_insn (second.orig_insn, second.buffer,
+                           CGEN_FIELDS_BITSIZE (& second.fields), 0, NULL);
       
       /* Force the top bit of the first instruction to be set.  */
       make_parallel (first.buffer);
@@ -789,8 +838,9 @@ assemble_parallel_insn (str, str2)
       cgen_restore_fixups ();
 
       /* Write out the first instruction.  */
-      (void) cgen_asm_finish_insn (first.orig_insn, first.buffer,
-                                  CGEN_FIELDS_BITSIZE (& first.fields));
+      expand_debug_syms (first.debug_sym_link, 1);
+      cgen_asm_finish_insn (first.orig_insn, first.buffer,
+                           CGEN_FIELDS_BITSIZE (& first.fields), 0, NULL);
     }
   else
     {
@@ -801,8 +851,6 @@ assemble_parallel_insn (str, str2)
   /* Set these so m32r_fill_insn can use them.  */
   prev_seg    = now_seg;
   prev_subseg = now_subseg;
-
-  return;
 }
 
 /* end-sanitize-m32rx */
@@ -828,6 +876,9 @@ md_assemble (str)
     }
 /* end-sanitize-m32rx */
   
+  insn.debug_sym_link = debug_sym_link;
+  debug_sym_link = (sym_linkS *)0;
+
   insn.insn = CGEN_SYM (assemble_insn) (str, & insn.fields, insn.buffer, & errmsg);
   if (!insn.insn)
     {
@@ -852,78 +903,92 @@ md_assemble (str)
             pig, can we call assemble_nop instead of !seen_relaxable_p?  */
          fill_insn (0);
        }
-      
-      (void) cgen_asm_finish_insn (insn.insn, insn.buffer,
-                                  CGEN_FIELDS_BITSIZE (& insn.fields));
+
+      expand_debug_syms (insn.debug_sym_link, 2);
+
+      /* Doesn't really matter what we pass for RELAX_P here.  */
+      cgen_asm_finish_insn (insn.insn, insn.buffer,
+                           CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL);
     }
   else
     {
+      int on_32bit_boundary_p;
 /* start-sanitize-m32rx */
-/* start-sanitize-phase2-m32rx */
       int swap = false;
-/* end-sanitize-phase2-m32rx */
 /* end-sanitize-m32rx */
-      
+
       if (CGEN_INSN_BITSIZE (insn.insn) != 16)
        abort();
-      
-      /* Get the indices of the operands of the instruction.  */
-      insn.insn = m32r_cgen_get_insn_operands (insn.insn,
-                                              bfd_getb16 ((char *) insn.buffer),
-                                              16,
-                                              insn.indices);
-      if (insn.insn == NULL)
-       as_fatal (_("internal error: m32r_cgen_get_insn_operands failed"));
 
-      /* Keep track of whether we've seen a pair of 16 bit insns.
-        prev_insn.insn is NULL when we're on a 32 bit boundary.  */
-      if (prev_insn.insn)
-       {
+      insn.orig_insn = insn.insn;
 /* start-sanitize-m32rx */
-/* start-sanitize-phase2-m32rx */
-         /* Look to see if this instruction can be combined with the
-            previous instruction to make one, parallel, 32 bit instruction.
-            If the previous instruction (potentially) changed the flow of
-            program control, then it cannot be combined with the current
-            instruction.  If the current instruction is relaxable, then it
-            might be replaced with a longer version, so we cannot combine it.
-            Also if the output of the previous instruction is used as an
-            input to the current instruction then it cannot be combined.
-            Otherwise call can_make_parallel() with both orderings of the
-            instructions to see if they can be combined.  */
-         if (      enable_m32rx
-             &&    optimize
-             &&    CGEN_INSN_ATTR (insn.insn, CGEN_INSN_RELAXABLE) == 0
-             && ! writes_to_pc (& prev_insn)
-             && ! first_writes_to_seconds_operands (& prev_insn, &insn, false)
-                )
-           {
-             if (can_make_parallel (& prev_insn, & insn) == NULL)
-               make_parallel (insn.buffer);
-             else if (can_make_parallel (& insn, & prev_insn.insn) == NULL)
-               swap = true;
-           }
-/* end-sanitize-phase2-m32rx */
-/* end-sanitize-m32rx */
-         
-         prev_insn.insn = NULL;
+      if (enable_m32rx)
+       {
+         /* Get the indices of the operands of the instruction.
+            FIXME: See assemble_parallel for notes on orig_insn.  */
+         insn.insn = m32r_cgen_lookup_get_insn_operands (NULL,
+                                                         bfd_getb16 ((char *) insn.buffer),
+                                                         16,
+                                                         insn.indices);
+         if (insn.insn == NULL)
+           as_fatal (_("internal error: m32r_cgen_get_insn_operands failed"));
        }
-      else
+/* end-sanitize-m32rx */
+
+      /* Compute whether we're on a 32 bit boundary or not.
+        prev_insn.insn is NULL when we're on a 32 bit boundary.  */
+      on_32bit_boundary_p = prev_insn.insn == NULL;
+
+/* start-sanitize-m32rx */
+      /* Look to see if this instruction can be combined with the
+        previous instruction to make one, parallel, 32 bit instruction.
+        If the previous instruction (potentially) changed the flow of
+        program control, then it cannot be combined with the current
+        instruction.  If the current instruction is relaxable, then it
+        might be replaced with a longer version, so we cannot combine it.
+        Also if the output of the previous instruction is used as an
+        input to the current instruction then it cannot be combined.
+        Otherwise call can_make_parallel() with both orderings of the
+        instructions to see if they can be combined.  */
+      if (     ! on_32bit_boundary_p
+         &&   enable_m32rx
+         &&   optimize
+         &&   CGEN_INSN_ATTR (insn.orig_insn, CGEN_INSN_RELAXABLE) == 0
+         && ! writes_to_pc (& prev_insn)
+         && ! first_writes_to_seconds_operands (& prev_insn, &insn, false)
+         )
        {
-         prev_insn = insn;
+         if (can_make_parallel (& prev_insn, & insn) == NULL)
+           make_parallel (insn.buffer);
+         else if (can_make_parallel (& insn, & prev_insn) == NULL)
+           swap = true;
        }
+/* end-sanitize-m32rx */
 
-      /* Record the frag that might be used by this insn.  */
-      insn.frag = frag_now;
-      insn.addr = cgen_asm_finish_insn (insn.insn, insn.buffer,
-                                  CGEN_FIELDS_BITSIZE (& insn.fields));
+      expand_debug_syms (insn.debug_sym_link, 1);
+
+      {
+       int i;
+       finished_insnS fi;
+
+       /* Ensure each pair of 16 bit insns is in the same frag.  */
+       frag_grow (4);
+
+       cgen_asm_finish_insn (insn.orig_insn, insn.buffer,
+                             CGEN_FIELDS_BITSIZE (& insn.fields),
+                             1 /*relax_p*/, &fi);
+       insn.addr = fi.addr;
+       insn.frag = fi.frag;
+       insn.num_fixups = fi.num_fixups;
+       for (i = 0; i < fi.num_fixups; ++i)
+         insn.fixups[i] = fi.fixups[i];
+      }
 
 /* start-sanitize-m32rx */
-/* start-sanitize-phase2-m32rx */
       if (swap)
        {
-         int tmp;
-         
+         int i,tmp;
+
 #define SWAP_BYTES(a,b) tmp = a; a = b; b = tmp
 
          /* Swap the two insns */
@@ -933,28 +998,39 @@ md_assemble (str)
          make_parallel (insn.addr);
 
          /* Swap any relaxable frags recorded for the two insns.  */
+         /* FIXME: Clarify.  relaxation precludes parallel insns */
          if (prev_insn.frag->fr_opcode == prev_insn.addr)
            prev_insn.frag->fr_opcode = insn.addr;
          else if (insn.frag->fr_opcode == insn.addr)
            insn.frag->fr_opcode = prev_insn.addr;
-       }
-/* end-sanitize-phase2-m32rx */
 
-      /* Record where this instruction was assembled.  */
-      prev_insn.addr = insn.addr;
-      prev_insn.frag = insn.frag;
+         /* Update the addresses in any fixups.
+            Note that we don't have to handle the case where each insn is in
+            a different frag as we ensure they're in the same frag above.  */
+         for (i = 0; i < prev_insn.num_fixups; ++i)
+           prev_insn.fixups[i]->fx_where += 2;
+         for (i = 0; i < insn.num_fixups; ++i)
+           insn.fixups[i]->fx_where -= 2;
+       }
 /* end-sanitize-m32rx */
+
+      /* Keep track of whether we've seen a pair of 16 bit insns.
+        prev_insn.insn is NULL when we're on a 32 bit boundary.  */
+      if (on_32bit_boundary_p)
+       prev_insn = insn;
+      else
+       prev_insn.insn = NULL;
       
       /* If the insn needs the following one to be on a 32 bit boundary
         (e.g. subroutine calls), fill this insn's slot.  */
-      if (prev_insn.insn != NULL
-         && CGEN_INSN_ATTR (insn.insn, CGEN_INSN_FILL_SLOT) != 0)
+      if (on_32bit_boundary_p
+         && CGEN_INSN_ATTR (insn.orig_insn, CGEN_INSN_FILL_SLOT) != 0)
        fill_insn (0);
 
       /* If this is a relaxable insn (can be replaced with a larger version)
         mark the fact so that we can emit an alignment directive for a
         following 32 bit insn if we see one.   */
-      if (CGEN_INSN_ATTR (insn.insn, CGEN_INSN_RELAXABLE) != 0)
+      if (CGEN_INSN_ATTR (insn.orig_insn, CGEN_INSN_RELAXABLE) != 0)
        seen_relaxable_p = 1;
     }
 
This page took 0.046572 seconds and 4 git commands to generate.