* config/tc-sh.c (md_assemble): For branches, check & update
[deliverable/binutils-gdb.git] / gas / config / tc-v850.c
index cdc3940f04fd30db4f611f81d6ac1e68367eb612..1e618aa2bc3c90ee8e71179e22dd962b7b8942c3 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-v850.c -- Assembler code for the NEC V850
-   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
+   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
@@ -195,9 +195,9 @@ v850_offset (ignore)
 {
   char *pfrag;
   int temp = get_absolute_expression ();
-   
+
   pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, (symbolS *)0,
-                       (offsetT) temp, (char *) 0);
+                   (offsetT) temp, (char *) 0);
   *pfrag = 0;
 
   demand_empty_rest_of_line ();
@@ -396,12 +396,12 @@ v850_comm (area)
        }
       else
        {
-          segT   old_sec;
-          int    old_subsec;
+         segT   old_sec;
+         int    old_subsec;
 
        allocate_common:
-          old_sec = now_seg;
-          old_subsec = now_subseg;
+         old_sec = now_seg;
+         old_subsec = now_subseg;
 
          S_SET_VALUE (symbolP, (valueT) size);
          S_SET_ALIGN (symbolP, temp);
@@ -477,7 +477,7 @@ set_machine (number)
 
   switch (machine)
     {
-    case 0:               processor_mask = PROCESSOR_V850;   break;
+    case 0:              processor_mask = PROCESSOR_V850;   break;
     case bfd_mach_v850e:  processor_mask = PROCESSOR_V850E;  break;
     }
 }
@@ -495,7 +495,7 @@ v850_longcode (type)
       if (type == 1)
        as_warn (".longcall pseudo-op seen when not relaxing");
       else
-       as_warn (".longjump pseudo-op seen when not relaxing"); 
+       as_warn (".longjump pseudo-op seen when not relaxing");
     }
 
   expression (&ex);
@@ -508,7 +508,7 @@ v850_longcode (type)
       return;
     }
 
-  if (type == 1) 
+  if (type == 1)
     fix_new_exp (frag_now, frag_now_fix (), 4, & ex, 1,
                 BFD_RELOC_V850_LONGCALL);
   else
@@ -519,7 +519,8 @@ v850_longcode (type)
 }
 
 /* The target specific pseudo-ops which we support.  */
-const pseudo_typeS md_pseudo_table[] = {
+const pseudo_typeS md_pseudo_table[] =
+{
   { "sdata",           v850_seg,               SDATA_SECTION           },
   { "tdata",           v850_seg,               TDATA_SECTION           },
   { "zdata",           v850_seg,               ZDATA_SECTION           },
@@ -538,10 +539,8 @@ const pseudo_typeS md_pseudo_table[] = {
   { "call_table_data", v850_seg,               CALL_TABLE_DATA_SECTION },
   { "call_table_text", v850_seg,               CALL_TABLE_TEXT_SECTION },
   { "v850e",           set_machine,            bfd_mach_v850e          },
-  { "file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0 },
-  { "loc",             dwarf2_directive_loc,   0                       },
-  { "longcall",         v850_longcode,          1                       },
-  { "longjump",         v850_longcode,          2                       },
+  { "longcall",                v850_longcode,          1                       },
+  { "longjump",                v850_longcode,          2                       },
   { NULL,              NULL,                   0                       }
 };
 
@@ -549,7 +548,8 @@ const pseudo_typeS md_pseudo_table[] = {
 static struct hash_control *v850_hash;
 
 /* This table is sorted.  Suitable for searching by a binary search.  */
-static const struct reg_name pre_defined_registers[] = {
+static const struct reg_name pre_defined_registers[] =
+{
   { "ep",  30 },               /* ep - element ptr */
   { "gp",   4 },               /* gp - global ptr  */
   { "hp",   2 },               /* hp - handler stack ptr  */
@@ -594,12 +594,20 @@ static const struct reg_name pre_defined_registers[] = {
 #define REG_NAME_CNT                                           \
   (sizeof (pre_defined_registers) / sizeof (struct reg_name))
 
-static const struct reg_name system_registers[] = {
+static const struct reg_name system_registers[] =
+{
+  { "asid",  23 },
+  { "bpc",   22 },
+  { "bpav",  24 },
+  { "bpam",  25 },
+  { "bpdv",  26 },
+  { "bpdm",  27 },
   { "ctbp",  20 },
   { "ctpc",  16 },
   { "ctpsw", 17 },
   { "dbpc",  18 },
   { "dbpsw", 19 },
+  { "dir",   21 },
   { "ecr",    4 },
   { "eipc",   0 },
   { "eipsw",  1 },
@@ -611,7 +619,8 @@ static const struct reg_name system_registers[] = {
 #define SYSREG_NAME_CNT                                                \
   (sizeof (system_registers) / sizeof (struct reg_name))
 
-static const struct reg_name system_list_registers[] = {
+static const struct reg_name system_list_registers[] =
+{
   {"PS",      5 },
   {"SR",      0 + 1}
 };
@@ -619,7 +628,8 @@ static const struct reg_name system_list_registers[] = {
 #define SYSREGLIST_NAME_CNT                                    \
   (sizeof (system_list_registers) / sizeof (struct reg_name))
 
-static const struct reg_name cc_names[] = {
+static const struct reg_name cc_names[] =
+{
   { "c",  0x1 },
   { "e",  0x2 },
   { "ge", 0xe },
@@ -705,14 +715,14 @@ reg_name_search (regs, regcount, name, accept_numbers)
 }
 
 /* Summary of register_name().
- *
* in: Input_line_pointer points to 1st char of operand.
- *
* out: An expressionS.
*     The operand may have been a register: in this case, X_op == O_register,
*     X_add_number is set to the register number, and truth is returned.
*     Input_line_pointer->(next non-blank) char after operand, or is in
*     its original state.  */
+
  in: Input_line_pointer points to 1st char of operand.
+
  out: An expressionS.
      The operand may have been a register: in this case, X_op == O_register,
      X_add_number is set to the register number, and truth is returned.
      Input_line_pointer->(next non-blank) char after operand, or is in
      its original state.  */
 
 static bfd_boolean register_name PARAMS ((expressionS *));
 
@@ -739,7 +749,7 @@ register_name (expressionP)
   /* Look to see if it's in the register table.  */
   if (reg_number >= 0)
     {
-      expressionP->X_op         = O_register;
+      expressionP->X_op                = O_register;
       expressionP->X_add_number = reg_number;
 
       /* Make the rest nice.  */
@@ -758,18 +768,18 @@ register_name (expressionP)
 }
 
 /* Summary of system_register_name().
- *
* in:  INPUT_LINE_POINTER points to 1st char of operand.
*      EXPRESSIONP points to an expression structure to be filled in.
*      ACCEPT_NUMBERS is true iff numerical register names may be used.
*      ACCEPT_LIST_NAMES is true iff the special names PS and SR may be
*      accepted.
- *
* out: An expressionS structure in expressionP.
*     The operand may have been a register: in this case, X_op == O_register,
*     X_add_number is set to the register number, and truth is returned.
*     Input_line_pointer->(next non-blank) char after operand, or is in
*     its original state.  */
+
  in:  INPUT_LINE_POINTER points to 1st char of operand.
+       EXPRESSIONP points to an expression structure to be filled in.
+       ACCEPT_NUMBERS is true iff numerical register names may be used.
+       ACCEPT_LIST_NAMES is true iff the special names PS and SR may be
+       accepted.
+
  out: An expressionS structure in expressionP.
      The operand may have been a register: in this case, X_op == O_register,
      X_add_number is set to the register number, and truth is returned.
      Input_line_pointer->(next non-blank) char after operand, or is in
      its original state.  */
 
 static bfd_boolean system_register_name
   PARAMS ((expressionS *, bfd_boolean, bfd_boolean));
@@ -808,7 +818,7 @@ system_register_name (expressionP, accept_numbers, accept_list_names)
          /* Make sure that the register number is allowable.  */
          if (reg_number < 0
              || (reg_number > 5 && reg_number < 16)
-             || reg_number > 20)
+             || reg_number > 27)
            {
              reg_number = -1;
            }
@@ -827,7 +837,7 @@ system_register_name (expressionP, accept_numbers, accept_list_names)
   /* Look to see if it's in the register table.  */
   if (reg_number >= 0)
     {
-      expressionP->X_op         = O_register;
+      expressionP->X_op                = O_register;
       expressionP->X_add_number = reg_number;
 
       /* Make the rest nice.  */
@@ -846,14 +856,14 @@ system_register_name (expressionP, accept_numbers, accept_list_names)
 }
 
 /* Summary of cc_name().
- *
* in: INPUT_LINE_POINTER points to 1st char of operand.
- *
* out: An expressionS.
*     The operand may have been a register: in this case, X_op == O_register,
*     X_add_number is set to the register number, and truth is returned.
*     Input_line_pointer->(next non-blank) char after operand, or is in
*     its original state.  */
+
  in: INPUT_LINE_POINTER points to 1st char of operand.
+
  out: An expressionS.
      The operand may have been a register: in this case, X_op == O_register,
      X_add_number is set to the register number, and truth is returned.
      Input_line_pointer->(next non-blank) char after operand, or is in
      its original state.  */
 
 static bfd_boolean cc_name PARAMS ((expressionS *));
 
@@ -878,7 +888,7 @@ cc_name (expressionP)
   /* Look to see if it's in the register table.  */
   if (reg_number >= 0)
     {
-      expressionP->X_op         = O_constant;
+      expressionP->X_op                = O_constant;
       expressionP->X_add_number = reg_number;
 
       /* Make the rest nice.  */
@@ -907,29 +917,29 @@ skip_white_space ()
 }
 
 /* Summary of parse_register_list ().
- *
* in: INPUT_LINE_POINTER  points to 1st char of a list of registers.
*     INSN                is the partially constructed instruction.
*     OPERAND             is the operand being inserted.
- *
* out: NULL if the parse completed successfully, otherwise a
*      pointer to an error message is returned.  If the parse
*      completes the correct bit fields in the instruction
*      will be filled in.
- *
* Parses register lists with the syntax:
- *
*   { rX }
*   { rX, rY }
*   { rX - rY }
*   { rX - rY, rZ }
*   etc
- *
* and also parses constant epxressions whoes bits indicate the
* registers in the lists.  The LSB in the expression refers to
* the lowest numbered permissable register in the register list,
* and so on upwards.  System registers are considered to be very
* high numbers.  */
+
  in: INPUT_LINE_POINTER  points to 1st char of a list of registers.
      INSN               is the partially constructed instruction.
      OPERAND            is the operand being inserted.
+
  out: NULL if the parse completed successfully, otherwise a
+       pointer to an error message is returned.  If the parse
+       completes the correct bit fields in the instruction
+       will be filled in.
+
  Parses register lists with the syntax:
+
    { rX }
    { rX, rY }
    { rX - rY }
    { rX - rY, rZ }
    etc
+
  and also parses constant epxressions whoes bits indicate the
  registers in the lists.  The LSB in the expression refers to
  the lowest numbered permissable register in the register list,
  and so on upwards.  System registers are considered to be very
  high numbers.  */
 
 static char *parse_register_list
   PARAMS ((unsigned long *, const struct v850_operand *));
@@ -970,7 +980,6 @@ parse_register_list (insn, operand)
   /* If the expression starts with a curly brace it is a register list.
      Otherwise it is a constant expression, whoes bits indicate which
      registers are to be included in the list.  */
-
   if (*input_line_pointer != '{')
     {
       int reg;
@@ -1055,9 +1064,7 @@ parse_register_list (insn, operand)
            }
 
          if (i == 32)
-           {
-             return _("illegal register included in list");
-           }
+           return _("illegal register included in list");
        }
       else if (system_register_name (&exp, TRUE, TRUE))
        {
@@ -1124,9 +1131,7 @@ parse_register_list (insn, operand)
            }
        }
       else
-       {
-         break;
-       }
+       break;
 
       skip_white_space ();
     }
@@ -1153,7 +1158,6 @@ md_show_usage (stream)
   fprintf (stream, _("  -mv850e                   The code is targeted at the v850e\n"));
   fprintf (stream, _("  -mv850any                 The code is generic, despite any processor specific instructions\n"));
   fprintf (stream, _("  -mrelax                   Enable relaxation\n"));
-  
 }
 
 int
@@ -1342,7 +1346,7 @@ md_begin ()
   else
     /* xgettext:c-format  */
     as_bad (_("Unable to determine default target processor from string: %s"),
-            TARGET_CPU);
+           TARGET_CPU);
 
   v850_hash = hash_new ();
 
@@ -1350,7 +1354,6 @@ md_begin ()
      has many identical opcode names that have different opcodes based
      on the operands.  This hash table then provides a quick index to
      the first opcode with a particular name in the opcode table.  */
-
   op = v850_opcodes;
   while (op->name)
     {
@@ -1505,13 +1508,13 @@ v850_reloc_prefix (operand)
       return reloc;                                                    \
     }
 
-  CHECK_ ("hi0",    BFD_RELOC_HI16         );
-  CHECK_ ("hi",     BFD_RELOC_HI16_S       );
-  CHECK_ ("lo",     BFD_RELOC_LO16         );
+  CHECK_ ("hi0",    BFD_RELOC_HI16        );
+  CHECK_ ("hi",            BFD_RELOC_HI16_S       );
+  CHECK_ ("lo",            BFD_RELOC_LO16         );
   CHECK_ ("sdaoff", handle_sdaoff (operand));
   CHECK_ ("zdaoff", handle_zdaoff (operand));
   CHECK_ ("tdaoff", handle_tdaoff (operand));
-  CHECK_ ("hilo",   BFD_RELOC_32           );
+  CHECK_ ("hilo",   BFD_RELOC_32          );
   CHECK_ ("ctoff",  handle_ctoff (operand) );
 
   /* Restore skipped parenthesis.  */
@@ -1787,8 +1790,8 @@ md_assemble (str)
                        }
 
                      extra_data_after_insn = TRUE;
-                     extra_data_len        = 4;
-                     extra_data            = 0;
+                     extra_data_len        = 4;
+                     extra_data            = 0;
                      break;
 
                    default:
@@ -1816,8 +1819,8 @@ md_assemble (str)
                        }
 
                      extra_data_after_insn = TRUE;
-                     extra_data_len        = 4;
-                     extra_data            = ex.X_add_number;
+                     extra_data_len        = 4;
+                     extra_data            = ex.X_add_number;
                    }
 
                  if (fc > MAX_INSN_FIXUPS)
@@ -1893,7 +1896,7 @@ md_assemble (str)
 
                  /* The parse_register_list() function has already done
                     everything, so fake a dummy expression.  */
-                 ex.X_op         = O_constant;
+                 ex.X_op         = O_constant;
                  ex.X_add_number = 0;
                }
              else if (operand->flags & V850E_IMMEDIATE16)
@@ -1913,9 +1916,9 @@ md_assemble (str)
                    }
 
                  extra_data_after_insn = TRUE;
-                 extra_data_len        = 2;
-                 extra_data            = ex.X_add_number;
-                 ex.X_add_number       = 0;
+                 extra_data_len        = 2;
+                 extra_data            = ex.X_add_number;
+                 ex.X_add_number       = 0;
                }
              else if (operand->flags & V850E_IMMEDIATE32)
                {
@@ -1925,9 +1928,9 @@ md_assemble (str)
                    errmsg = _("constant expression expected");
 
                  extra_data_after_insn = TRUE;
-                 extra_data_len        = 4;
-                 extra_data            = ex.X_add_number;
-                 ex.X_add_number       = 0;
+                 extra_data_len        = 4;
+                 extra_data            = ex.X_add_number;
+                 ex.X_add_number       = 0;
                }
              else if (register_name (&ex)
                       && (operand->flags & V850_OPERAND_REG) == 0)
@@ -2212,7 +2215,7 @@ md_assemble (str)
          fix_new_exp (frag_now,
                       f - frag_now->fr_literal, 4,
                       & fixups[i].exp,
-                      1 /* FIXME: V850_OPERAND_RELATIVE ???  */,
+                      (operand->flags & V850_OPERAND_DISP) != 0,
                       (bfd_reloc_code_real_type) (fixups[i].opindex
                                                   + (int) BFD_RELOC_UNUSED));
        }
@@ -2231,11 +2234,27 @@ tc_gen_reloc (seg, fixp)
 {
   arelent *reloc;
 
-  reloc               = (arelent *) xmalloc (sizeof (arelent));
+  reloc                      = (arelent *) xmalloc (sizeof (arelent));
   reloc->sym_ptr_ptr  = (asymbol **) xmalloc (sizeof (asymbol *));
   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   reloc->address      = fixp->fx_frag->fr_address + fixp->fx_where;
-  reloc->howto        = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
+
+  if (   fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
+      || fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+      || fixp->fx_r_type == BFD_RELOC_V850_LONGCALL
+      || fixp->fx_r_type == BFD_RELOC_V850_LONGJUMP
+      || fixp->fx_r_type == BFD_RELOC_V850_ALIGN)
+    reloc->addend = fixp->fx_offset;
+  else
+    {
+      if (fixp->fx_r_type == BFD_RELOC_32
+         && fixp->fx_pcrel)
+       fixp->fx_r_type = BFD_RELOC_32_PCREL;
+
+      reloc->addend = fixp->fx_addnumber;
+    }
+
+  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
 
   if (reloc->howto == (reloc_howto_type *) NULL)
     {
@@ -2249,16 +2268,6 @@ tc_gen_reloc (seg, fixp)
       return NULL;
     }
 
-  if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
-      || fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
-    reloc->addend = fixp->fx_offset;
-  else if (   fixp->fx_r_type == BFD_RELOC_V850_LONGCALL
-          || fixp->fx_r_type == BFD_RELOC_V850_LONGJUMP
-           || fixp->fx_r_type == BFD_RELOC_V850_ALIGN)
-    reloc->addend = fixp->fx_offset;
-  else
-    reloc->addend = fixp->fx_addnumber;
-
   return reloc;
 }
 
@@ -2275,7 +2284,7 @@ v850_handle_align (frag)
       && now_seg != v850_seg_table[TBSS_SECTION].s
       && now_seg != v850_seg_table[ZBSS_SECTION].s)
     fix_new (frag, frag->fr_fix, 2, & abs_symbol, frag->fr_offset, 0,
-           BFD_RELOC_V850_ALIGN);
+            BFD_RELOC_V850_ALIGN);
 }
 
 /* Return current size of variable part of frag.  */
@@ -2360,7 +2369,7 @@ md_apply_fix3 (fixP, valueP, seg)
       operand = &v850_operands[opindex];
 
       /* Fetch the instruction, insert the fully resolved operand
-         value, and stuff the instruction back again.
+        value, and stuff the instruction back again.
 
         Note the instruction has been stored in little endian
         format!  */
@@ -2474,10 +2483,6 @@ int
 v850_force_relocation (fixP)
      struct fix *fixP;
 {
-  if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
-      || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
-    return 1;
-
   if (fixP->fx_r_type == BFD_RELOC_V850_LONGCALL
       || fixP->fx_r_type == BFD_RELOC_V850_LONGJUMP)
     return 1;
@@ -2490,5 +2495,5 @@ v850_force_relocation (fixP)
          || fixP->fx_r_type >= BFD_RELOC_UNUSED))
     return 1;
 
-  return S_FORCE_RELOC (fixP->fx_addsy);
+  return generic_force_reloc (fixP);
 }
This page took 0.033094 seconds and 4 git commands to generate.