Replace <sys/dir.h> (and <dirent.h>) with "gdb_dirent.h".
[deliverable/binutils-gdb.git] / gas / config / tc-tic80.c
index 1ef46c075cec7fbdf130b7adb7950ac52250d710..f31dba32f93138a8a0c5478116c7c76aac541425 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-tic80.c -- Assemble for the TI TMS320C80 (MV)
-   Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -22,9 +22,9 @@
 #include "opcode/tic80.h"
 
 #define internal_error(what) \
-  as_fatal("internal error:%s:%d: %s\n",__FILE__,__LINE__,what)
+  as_fatal(_("internal error:%s:%d: %s\n"),__FILE__,__LINE__,what)
 #define internal_error_a(what,arg) \
-  as_fatal("internal error:%s:%d: %s %d\n",__FILE__,__LINE__,what,arg)
+  as_fatal(_("internal error:%s:%d: %s %d\n"),__FILE__,__LINE__,what,arg)
 
 \f
 /* Generic assembler global variables which must be defined by all targets. */
@@ -61,7 +61,7 @@ const pseudo_typeS md_pseudo_table[] =
 {
   { "align",   s_align_bytes,          4 },    /* Do byte alignment, default is a 4 byte boundary */
   { "word",    cons,                   4 },    /* FIXME: Should this be machine independent? */
-  { "bss",     s_lcomm,                1 },
+  { "bss",     s_lcomm_bytes,          1 },
   { "sect",    obj_coff_section,       0},     /* For compatibility with TI tools */
   { "section", obj_coff_section,       0},     /* Standard COFF .section pseudo-op */
   { NULL,      NULL,                   0 }
@@ -75,13 +75,19 @@ static void build_insn PARAMS ((struct tic80_opcode *, expressionS *));
 static int get_operands PARAMS ((expressionS exp[]));
 static int const_overflow PARAMS ((unsigned long num, int bits, int flags));
 
+/* Replace short PC relative instructions with long form when necessary.  Currently
+   this is off by default or when given the -no-relax option.  Turning it on by using
+   the -relax option forces all PC relative instructions to use the long form, which
+   is why it is currently not the default. */
+static int tic80_relax = 0;
+
 \f
 int
 md_estimate_size_before_relax (fragP, segment_type)
      fragS *fragP;
      segT segment_type;
 {
-  internal_error ("Relaxation is a luxury we can't afford");
+  internal_error (_("Relaxation is a luxury we can't afford"));
   return (-1);
 }
 
@@ -132,7 +138,7 @@ md_atof (type, litP, sizeP)
 
     default:
       *sizeP = 0;
-      return "bad call to md_atof ()";
+      return _("bad call to md_atof ()");
     }
 
   t = atof_ieee (input_line_pointer, type, words);
@@ -236,7 +242,7 @@ get_operands (exp)
            }
          else
            {
-             as_bad ("':' not followed by 'm' or 's'");
+             as_bad (_("':' not followed by 'm' or 's'"));
            }
          numexp++;
          continue;
@@ -250,7 +256,7 @@ get_operands (exp)
        {
          if (++parens != 1)
            {
-             as_bad ("paren nesting");
+             as_bad (_("paren nesting"));
            }
          p++;
          continue;
@@ -265,7 +271,7 @@ get_operands (exp)
          /* Record that we have left a paren group and continue */
          if (--parens < 0)
            {
-             as_bad ("mismatched parenthesis");
+             as_bad (_("mismatched parenthesis"));
            }
          p++;
          continue;
@@ -278,11 +284,11 @@ get_operands (exp)
 
       if (exp[numexp].X_op == O_illegal)
        {
-         as_bad ("illegal operand");
+         as_bad (_("illegal operand"));
        }
       else if (exp[numexp].X_op == O_absent)
        {
-         as_bad ("missing operand");
+         as_bad (_("missing operand"));
        }
 
       numexp++;
@@ -393,16 +399,19 @@ find_opcode (opcode, myops)
                }
              break;
            case O_symbol:
-             if ((bits < 32) && (flags & TIC80_OPERAND_PCREL))
+             if ((bits < 32) && (flags & TIC80_OPERAND_PCREL) && !tic80_relax)
                {
-                 /* For now we only allow PC relative relocations in the
-                    short immediate fields, like the TI assembler.
+                 /* The default is to prefer the short form of PC relative relocations.
+                    This is the only form that the TI assembler supports.
+                    If the -relax option is given, we never use the short forms.
                     FIXME: Should be able to choose "best-fit". */
                }
              else if ((bits == 32) /* && (flags & TIC80_OPERAND_BASEREL) */)
                {
-                 /* For now we only allow base relative relocations in
-                    the long immediate fields, like the TI assembler.
+                 /* The default is to prefer the long form of base relative relocations.
+                    This is the only form that the TI assembler supports.
+                    If the -no-relax option is given, we always use the long form of
+                    PC relative relocations.
                     FIXME: Should be able to choose "best-fit". */
                }
              else
@@ -455,7 +464,7 @@ find_opcode (opcode, myops)
            case O_logical_or:
            case O_max:
            default:
-             internal_error_a ("unhandled expression type", X_op);
+             internal_error_a (_("unhandled expression type"), X_op);
            }
        }
       if (!match)
@@ -525,7 +534,7 @@ find_opcode (opcode, myops)
 
   if (!match)  
     {
-      as_bad ("bad opcode or operands");
+      as_bad (_("bad opcode or operands"));
       return (0);
     }
 
@@ -536,7 +545,7 @@ find_opcode (opcode, myops)
     {
       if ((tic80_operands[opcode->operands[i]].flags & TIC80_OPERAND_EVEN) &&
          (myops[i].X_add_number & 1)) 
-       as_fatal ("Register number must be EVEN");
+       as_fatal (_("Register number must be EVEN"));
       if (myops[i].X_op == O_register)
        {
          if (!(tic80_operands[opcode->operands[i]].flags & TIC80_OPERAND_REG)) 
@@ -635,30 +644,42 @@ build_insn (opcode, opers)
            }
          break;
        case O_symbol:
-         if (flags & TIC80_OPERAND_PCREL)
+         if (bits == 32)
+           {
+             fx = frag_more (4);
+             fxfrag = frag_now;
+             insn[1] = 0;
+             if (flags & TIC80_OPERAND_PCREL)
+               {
+                 fix_new_exp (fxfrag,
+                              fx - (fxfrag -> fr_literal),
+                              4,
+                              &opers[expi], 
+                              1,
+                              R_MPPCR);
+               }
+             else
+               {
+                 fix_new_exp (fxfrag,
+                              fx - (fxfrag -> fr_literal),
+                              4,
+                              &opers[expi], 
+                              0,
+                              R_RELLONGX);
+               }
+           }
+         else if (flags & TIC80_OPERAND_PCREL)
            {
              fix_new_exp (ffrag,
                           f - (ffrag -> fr_literal),
                           4,                   /* FIXME! how is this used? */
                           &opers[expi],
                           1,
-                          R_MPPCR);
-           }
-         else if (bits == 32)  /* was (flags & TIC80_OPERAND_BASEREL) */
-           {
-             fx = frag_more (4);
-             fxfrag = frag_now;
-             insn[1] = 0;
-             fix_new_exp (fxfrag,
-                          fx - (fxfrag -> fr_literal),
-                          4,
-                          &opers[expi], 
-                          0,
-                          R_RELLONGX);
+                          R_MPPCR15W);
            }
          else
            {
-             internal_error ("symbol reloc that is not PC relative or 32 bits");
+             internal_error (_("symbol reloc that is not PC relative or 32 bits"));
            }
          break;
        case O_absent:
@@ -681,7 +702,7 @@ build_insn (opcode, opers)
            }
          else
            {
-             internal_error_a ("unhandled operand modifier", opers[expi].X_add_number);
+             internal_error_a (_("unhandled operand modifier"), opers[expi].X_add_number);
            }
          break;
        case O_big:
@@ -722,7 +743,7 @@ build_insn (opcode, opers)
        case O_logical_or:
        case O_max:
        default:
-         internal_error_a ("unhandled expression", X_op);
+         internal_error_a (_("unhandled expression"), X_op);
          break;
        }
     }
@@ -773,7 +794,7 @@ md_assemble (str)
   /* Try to find this mnemonic in the hash table */
   if ((opcode = (struct tic80_opcode *) hash_find (tic80_hash, str)) == NULL)
     {
-      as_bad ("Invalid mnemonic: '%s'", str);
+      as_bad (_("Invalid mnemonic: '%s'"), str);
       return;
     }
 
@@ -789,7 +810,7 @@ md_assemble (str)
   opcode = find_opcode (opcode, myops);
   if (opcode == NULL)
     {
-      as_bad ("Invalid operands: '%s'", input_line_save);
+      as_bad (_("Invalid operands: '%s'"), input_line_save);
     }
 
   input_line_pointer = input_line_save;
@@ -866,7 +887,7 @@ md_begin ()
          valu = PDS_VALUE (pdsp) & ~TIC80_OPERAND_MASK;
          break;
        default:
-         internal_error_a ("unhandled predefined symbol bits", symtype);
+         internal_error_a (_("unhandled predefined symbol bits"), symtype);
          break;
        }
       symbol_table_insert (symbol_create (PDS_NAME (pdsp), segment, valu,
@@ -884,6 +905,13 @@ CONST char *md_shortopts = "";
    that are passed to getopt. */
 
 struct option md_longopts[] = {
+
+#define OPTION_RELAX   (OPTION_MD_BASE)
+  {"relax", no_argument, NULL, OPTION_RELAX},
+
+#define OPTION_NO_RELAX        (OPTION_RELAX + 1)
+  {"no-relax", no_argument, NULL, OPTION_NO_RELAX},
+
   {NULL, no_argument, NULL, 0}
 };
 
@@ -898,7 +926,18 @@ md_parse_option (c, arg)
      int c;
      char *arg;
 {
-  return (0);
+  switch (c)
+    {
+    case OPTION_RELAX:
+      tic80_relax = 1;
+      break;
+    case OPTION_NO_RELAX:
+      tic80_relax = 0;
+      break;
+    default:
+      return (0);
+    }
+  return (1);
 }
 
 /* The md_show_usage function will be called whenever a usage message is
@@ -909,6 +948,10 @@ void
 md_show_usage (stream)
      FILE *stream;
 {
+  fprintf (stream, "\
+TIc80 options:\n\
+-relax                 alter PC relative branch instructions to use long form when needed\n\
+-no-relax              always use short PC relative branch instructions, error on overflow\n");
 }
 
 \f
@@ -931,10 +974,17 @@ md_apply_fix (fixP, val)
       md_number_to_chars (dest, (valueT) val, 4);
       break;
     case R_MPPCR:
-      overflow = (val < -65536) || (val > 65532);
+      val >>= 2;
+      val += 1;          /* Target address computed from inst start */
+      md_number_to_chars (dest, (valueT) val, 4);
+      break;
+    case R_MPPCR15W:
+      overflow = (val < -65536L) || (val > 65532L);
       if (overflow)
        {
-         as_bad_where (fixP -> fx_file, fixP -> fx_line, "PC relative target out of range");
+         as_bad_where (fixP -> fx_file, fixP -> fx_line,
+                       _("PC offset 0x%lx outside range 0x%lx-0x%lx"),
+                       val, -65536L, 65532L);
        }
       else
        {
@@ -948,7 +998,7 @@ md_apply_fix (fixP, val)
       md_number_to_chars (dest, (valueT) val, fixP -> fx_size);
       break;
     default:
-      internal_error_a ("unhandled relocation type in fixup", fixP -> fx_r_type);
+      internal_error_a (_("unhandled relocation type in fixup"), fixP -> fx_r_type);
       break;
     }
 }
@@ -985,7 +1035,7 @@ md_convert_frag (headers, seg, fragP)
      segT seg;
      fragS *fragP;
 {
-  internal_error ("md_convert_frag() not implemented yet");
+  internal_error (_("md_convert_frag() not implemented yet"));
   abort ();
 }
 
This page took 0.028156 seconds and 4 git commands to generate.