* config/tc-sh.h (sh_do_align): Declare.
authorIan Lance Taylor <ian@airs.com>
Wed, 7 Feb 1996 22:00:28 +0000 (22:00 +0000)
committerIan Lance Taylor <ian@airs.com>
Wed, 7 Feb 1996 22:00:28 +0000 (22:00 +0000)
(md_do_align): Define.
* config/tc-sh.c (sh_do_align): New function.
PR 8974.

gas/ChangeLog
gas/config/tc-sh.c
gas/config/tc-sh.h

index 8dd9dbec8bbff29c7a43fe339f53f807e62ae47d..8a9061fd3867955605f220a1400ade688a6e88b3 100644 (file)
@@ -1,5 +1,9 @@
 Wed Feb  7 14:12:03 1996  Ian Lance Taylor  <ian@cygnus.com>
 
+       * config/tc-sh.h (sh_do_align): Declare.
+       (md_do_align): Define.
+       * config/tc-sh.c (sh_do_align): New function.
+
        * ecoff.c (ecoff_build_lineno): Don't try to store the address
        difference if the next address is before the current one.
 
index 27664237f833748c98f12b05aecd84a3eb5ea89c..a64f81828e8a7b699372c53babd65cb7ab8417d4 100644 (file)
@@ -211,9 +211,14 @@ parse_reg (src, mode, reg)
      int *mode;
      int *reg;
 {
-  if (src[0] == 'r') 
+  /* We use !isalnum for the next character after the register name, to
+     make sure that we won't accidentally recognize a symbol name such as
+     'sram' as being a reference to the register 'sr'.  */
+
+  if (src[0] == 'r')
     {
-      if (src[1] >= '0' && src[1] <= '7' && strncmp(&src[2], "_bank", 5) == 0)
+      if (src[1] >= '0' && src[1] <= '7' && strncmp(&src[2], "_bank", 5) == 0
+         && ! isalnum (src[7]))
        {
          *mode = A_REG_B;
          *reg  = (src[1] - '0');
@@ -225,14 +230,14 @@ parse_reg (src, mode, reg)
     {
       if (src[1] == '1')
        {
-         if (src[2] >= '0' && src[2] <= '5')
+         if (src[2] >= '0' && src[2] <= '5' && ! isalnum (src[3]))
            {
              *mode = A_REG_N;
              *reg = 10 + src[2] - '0';
              return 3;
            }
        }
-      if (src[1] >= '0' && src[1] <= '9')
+      if (src[1] >= '0' && src[1] <= '9' && ! isalnum (src[2]))
        {
          *mode = A_REG_N;
          *reg = (src[1] - '0');
@@ -240,53 +245,53 @@ parse_reg (src, mode, reg)
        }
     }
 
-  if (src[0] == 's' && src[1] == 's' && src[2] == 'r')
+  if (src[0] == 's' && src[1] == 's' && src[2] == 'r' && ! isalnum (src[3]))
     {
       *mode = A_SSR;
       return 3;
     }
 
-  if (src[0] == 's' && src[1] == 'p' && src[2] == 'c')
+  if (src[0] == 's' && src[1] == 'p' && src[2] == 'c' && ! isalnum (src[3]))
     {
       *mode = A_SPC;
       return 3;
     }
 
-  if (src[0] == 's' && src[1] == 'r')
+  if (src[0] == 's' && src[1] == 'r' && ! isalnum (src[2]))
     {
       *mode = A_SR;
       return 2;
     }
 
-  if (src[0] == 's' && src[1] == 'p')
+  if (src[0] == 's' && src[1] == 'p' && ! isalnum (src[2]))
     {
       *mode = A_REG_N;
       *reg = 15;
       return 2;
     }
 
-  if (src[0] == 'p' && src[1] == 'r')
+  if (src[0] == 'p' && src[1] == 'r' && ! isalnum (src[2]))
     {
       *mode = A_PR;
       return 2;
     }
-  if (src[0] == 'p' && src[1] == 'c')
+  if (src[0] == 'p' && src[1] == 'c' && ! isalnum (src[2]))
     {
       *mode = A_DISP_PC;
       return 2;
     }
-  if (src[0] == 'g' && src[1] == 'b' && src[2] == 'r')
+  if (src[0] == 'g' && src[1] == 'b' && src[2] == 'r' && ! isalnum (src[3]))
     {
       *mode = A_GBR;
       return 3;
     }
-  if (src[0] == 'v' && src[1] == 'b' && src[2] == 'r')
+  if (src[0] == 'v' && src[1] == 'b' && src[2] == 'r' && ! isalnum (src[3]))
     {
       *mode = A_VBR;
       return 3;
     }
 
-  if (src[0] == 'm' && src[1] == 'a' && src[2] == 'c')
+  if (src[0] == 'm' && src[1] == 'a' && src[2] == 'c' && ! isalnum (src[4]))
     {
       if (src[3] == 'l')
        {
@@ -299,38 +304,37 @@ parse_reg (src, mode, reg)
          return 4;
        }
     }
-/* start-sanitize-sh3e */
   if (src[0] == 'f' && src[1] == 'r')
     {
       if (src[2] == '1')
        {
-         if (src[3] >= '0' && src[3] <= '5')
+         if (src[3] >= '0' && src[3] <= '5' && ! isalnum (src[4]))
            {
              *mode = F_REG_N;
              *reg = 10 + src[3] - '0';
              return 4;
            }
        }
-      if (src[2] >= '0' && src[2] <= '9')
+      if (src[2] >= '0' && src[2] <= '9' && ! isalnum (src[3]))
        {
          *mode = F_REG_N;
          *reg = (src[2] - '0');
          return 3;
        }
     }
-  if (src[0] == 'f' && src[1] == 'p' && src[2] == 'u' && src[3] == 'l')
+  if (src[0] == 'f' && src[1] == 'p' && src[2] == 'u' && src[3] == 'l'
+      && ! isalnum (src[4]))
     {
       *mode = FPUL_N;
       return 4;
     }
 
-  if (src[0] == 'f' && src[1] == 'p'
-      && src[2] == 's' && src[3] == 'c' && src[4] == 'r')
+  if (src[0] == 'f' && src[1] == 'p' && src[2] == 's' && src[3] == 'c'
+      && src[4] == 'r' && ! isalnum (src[5]))
     {
       *mode = FPSCR_N;
       return 5;
     }
-/* end-sanitize-sh3e */
 
   return 0;
 }
@@ -562,7 +566,6 @@ get_operands (info, args, operand)
              ptr++;
            }
          get_operand (&ptr, operand + 1);
-/* start-sanitize-sh3e */
          if (info->arg[2])
            {
              if (*ptr == ',')
@@ -575,23 +578,18 @@ get_operands (info, args, operand)
            {
              operand[2].type = 0;
            }
-/* end-sanitize-sh3e */
        }
       else
        {
          operand[1].type = 0;
-/* start-sanitize-sh3e */
          operand[2].type = 0;
-/* end-sanitize-sh3e */
        }
     }
   else
     {
       operand[0].type = 0;
       operand[1].type = 0;
-/* start-sanitize-sh3e */
       operand[2].type = 0;
-/* end-sanitize-sh3e */
     }
   return ptr;
 }
@@ -650,12 +648,10 @@ get_specific (opcode, operands)
              if (user->type != A_R0_GBR || user->reg != 0)
                goto fail;
              break;
-/* start-sanitize-sh3e */
            case F_FR0:
              if (user->type != F_REG_N || user->reg != 0)
                goto fail;
              break;
-/* end-sanitize-sh3e */
 
            case A_REG_N:
            case A_INC_N:
@@ -663,11 +659,9 @@ get_specific (opcode, operands)
            case A_IND_N:
            case A_IND_R0_REG_N:
            case A_DISP_REG_N:
-/* start-sanitize-sh3e */
            case F_REG_N:
            case FPUL_N:
            case FPSCR_N:
-/* end-sanitize-sh3e */
              /* Opcode needs rn */
              if (user->type != arg)
                goto fail;
@@ -700,7 +694,6 @@ get_specific (opcode, operands)
              reg_m = user->reg;
              break;
 
-/* start-sanitize-sh3e */
            case F_REG_M:
            case FPUL_M:
            case FPSCR_M:
@@ -709,7 +702,6 @@ get_specific (opcode, operands)
                goto fail;
              reg_m = user->reg;
              break;
-/* end-sanitize-sh3e */
        
            default:
              printf ("unhandled %d\n", arg);
@@ -1702,6 +1694,33 @@ tc_coff_sizemachdep (frag)
   return md_relax_table[frag->fr_subtype].rlx_length;
 }
 
+/* When we align the .text section, insert the correct NOP pattern.  */
+
+int
+sh_do_align (n, fill)
+     int n;
+     const char *fill;
+{
+  if ((fill == NULL || *fill == 0)
+      && (now_seg == text_section
+#ifdef BFD_ASSEMBLER
+         || (now_seg->flags & SEC_CODE) != 0
+#endif
+         || strcmp (obj_segment_name (now_seg), ".init") == 0))
+    {
+      static const unsigned char big_nop_pattern[] = { 0x00, 0x09 };
+      static const unsigned char little_nop_pattern[] = { 0x09, 0x00 };
+
+      if (target_big_endian)
+       frag_align_pattern (n, big_nop_pattern, sizeof big_nop_pattern);
+      else
+       frag_align_pattern (n, little_nop_pattern, sizeof little_nop_pattern);
+      return 1;
+    }
+
+  return 0;
+}
+
 #ifdef OBJ_COFF
 
 /* Adjust a reloc for the SH.  This is similar to the generic code,
index 5fe40728437d7f12403923d2754dbcc76d5a35b6..2452444e67096ce2ac92199af5e68f64f68585a3 100644 (file)
@@ -1,6 +1,6 @@
 /* This file is tc-sh.h
 
-   Copyright (C) 1993 Free Software Foundation, Inc.
+   Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
 
    You should have received a copy of the GNU General Public License
    along with GAS; see the file COPYING.  If not, write to
-   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
-
+   the Free Software Foundation, 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #define TC_SH
 
 /* This macro translates between an internal fix and an coff reloc type */
-#define TC_COFF_FIX2RTYPE(fixP) tc_coff_fix2rtype(fixP)
+#define TC_COFF_FIX2RTYPE(fix) ((fix)->fx_r_type)
 
 #define BFD_ARCH bfd_arch_sh
-#define COFF_MAGIC 0x0500
-/* Write out relocs which haven't been done by gas */
-#define TC_COUNT_RELOC(x) (((x)->fx_addsy))
-#define IGNORE_NONSTANDARD_ESCAPES
 
-#define TC_RELOC_MANGLE(a,b,c) tc_reloc_mangle(a,b,c)
+extern int shl;
+
+#define COFF_MAGIC (shl ? SH_ARCH_MAGIC_LITTLE : SH_ARCH_MAGIC_BIG)
+
+/* Whether -relax was used.  */
+extern int sh_relax;
+
+/* When relaxing, we need to generate relocations for alignment
+   directives.  */
+#define HANDLE_ALIGN(frag) sh_handle_align (frag)
+extern void sh_handle_align PARAMS ((fragS *));
+
+/* We need to force out some relocations when relaxing.  */
+#define TC_FORCE_RELOCATION(fix) sh_force_relocation (fix)
+extern int sh_force_relocation ();
+
+/* We need to write out relocs which have not been completed.  */
+#define TC_COUNT_RELOC(fix) ((fix)->fx_addsy != NULL)
+
+#define TC_RELOC_MANGLE(seg, fix, int, paddr) \
+  sh_coff_reloc_mangle ((seg), (fix), (int), (paddr))
+extern void sh_coff_reloc_mangle ();
+
+#define IGNORE_NONSTANDARD_ESCAPES
 
 #define tc_coff_symbol_emit_hook(a) ; /* not used */
 
 #define DO_NOT_STRIP 0
 #define DO_STRIP 0
-#define LISTING_HEADER "Hitachi Super-H GAS "
+#define LISTING_HEADER (shl ? "Hitachi Super-H GAS Little Endian" : "Hitachi Super-H GAS Big Endian")
 #define NEED_FX_R_TYPE 1
 #define RELOC_32 1234
-#define COFF_FLAGS 1
+
+#define TC_KEEP_FX_OFFSET 1
 
 #define TC_COFF_SIZEMACHDEP(frag) tc_coff_sizemachdep(frag)
+extern int tc_coff_sizemachdep PARAMS ((fragS *));
+
+#define md_operand(x)
+
+extern const struct relax_type md_relax_table[];
+#define TC_GENERIC_RELAX_TABLE md_relax_table
+
+#define tc_frob_file sh_coff_frob_file
+extern void sh_coff_frob_file PARAMS (());
+
+/* We use a special alignment function to insert the correct nop
+   pattern.  */
+extern int sh_do_align PARAMS ((int, const char *));
+#define md_do_align(n,fill,l)  if (sh_do_align (n,fill)) goto l
 
 /* end of tc-sh.h */