* config/tc-alpha.c: More use of symbol accessor functions.
[binutils-gdb.git] / gas / config / tc-v850.c
index 4f42884ad7039a1b71eed72439bfa6bc27f54fe0..7d4a91f122704415c1d1ac0424be36bb787a88de 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-v850.c -- Assembler code for the NEC V850
-   Copyright (C) 1996, 1997, 1998 Free Software Foundation.
+   Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -95,10 +95,8 @@ static segT rozdata_section = NULL;
 static segT scommon_section = NULL;
 static segT tcommon_section = NULL;
 static segT zcommon_section = NULL;
-/* start-sanitize-v850e */
 static segT call_table_data_section = NULL;
 static segT call_table_text_section = NULL;
-/* end-sanitize-v850e */
 
 /* fixups */
 #define MAX_INSN_FIXUPS (5)
@@ -193,7 +191,6 @@ v850_rozdata (int ignore)
   demand_empty_rest_of_line ();
 }
 
-/* start-sanitize-v850e */
 void
 v850_call_table_data (int ignore)
 {
@@ -213,7 +210,6 @@ v850_call_table_text (int ignore)
   
   demand_empty_rest_of_line ();
 }
-/* end-sanitize-v850e */
 
 void
 v850_bss (int ignore)
@@ -255,33 +251,42 @@ v850_comm (area)
 
   name = input_line_pointer;
   c = get_symbol_end ();
+  
   /* just after name is now '\0' */
   p = input_line_pointer;
   *p = c;
+  
   SKIP_WHITESPACE ();
+  
   if (*input_line_pointer != ',')
     {
       as_bad (_("Expected comma after symbol-name"));
       ignore_rest_of_line ();
       return;
     }
-  input_line_pointer++;                /* skip ',' */
+  
+  input_line_pointer ++;               /* skip ',' */
+  
   if ((temp = get_absolute_expression ()) < 0)
     {
-      as_bad (_(".COMMon length (%d.) <0! Ignored."), temp);
+      /* xgettext:c-format */
+      as_bad (_(".COMMon length (%d.) < 0! Ignored."), temp);
       ignore_rest_of_line ();
       return;
     }
+  
   size = temp;
   *p = 0;
   symbolP = symbol_find_or_make (name);
   *p = c;
+  
   if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
     {
       as_bad (_("Ignoring attempt to re-define symbol"));
       ignore_rest_of_line ();
       return;
     }
+  
   if (S_GET_VALUE (symbolP) != 0)
     {
       if (S_GET_VALUE (symbolP) != size)
@@ -291,7 +296,9 @@ v850_comm (area)
                   S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
        }
     }
-  know (symbolP->sy_frag == &zero_address_frag);
+  
+  know (symbol_get_frag (symbolP) == & zero_address_frag);
+  
   if (*input_line_pointer != ',')
     have_align = 0;
   else
@@ -300,6 +307,7 @@ v850_comm (area)
       input_line_pointer++;
       SKIP_WHITESPACE ();
     }
+  
   if (! have_align || *input_line_pointer != '"')
     {
       if (! have_align)
@@ -307,26 +315,71 @@ v850_comm (area)
       else
        {
          temp = get_absolute_expression ();
+         
          if (temp < 0)
            {
              temp = 0;
              as_warn (_("Common alignment negative; 0 assumed"));
            }
        }
+      
       if (symbolP->local)
        {
          segT   old_sec;
          int    old_subsec;
          char * pfrag;
          int    align;
+         flagword      applicable;
 
-       /* allocate_bss: */
          old_sec = now_seg;
          old_subsec = now_subseg;
+      
+         applicable = bfd_applicable_section_flags (stdoutput);
+                 
+         applicable &= SEC_ALLOC;
+         
+         switch (area)
+           {
+           case AREA_SDA:
+             if (sbss_section == NULL)
+               {
+                 sbss_section = subseg_new (".sbss", 0);
+             
+                 bfd_set_section_flags (stdoutput, sbss_section, applicable);
+             
+                 seg_info (sbss_section)->bss = 1;
+               }
+             break;
+         
+           case AREA_ZDA:
+             if (zbss_section == NULL)
+               {
+                 zbss_section = subseg_new (".zbss", 0);
+                 
+                 bfd_set_section_flags (stdoutput, sbss_section, applicable);
+             
+                 seg_info (zbss_section)->bss = 1;
+               }
+             break;
+         
+           case AREA_TDA:
+             if (tbss_section == NULL)
+               {
+                 tbss_section = subseg_new (".tbss", 0);
+                 
+                 bfd_set_section_flags (stdoutput, tbss_section, applicable);
+                 
+                 seg_info (tbss_section)->bss = 1;
+               }
+             break;
+           }
+
          if (temp)
            {
              /* convert to a power of 2 alignment */
-             for (align = 0; (temp & 1) == 0; temp >>= 1, ++align);
+             for (align = 0; (temp & 1) == 0; temp >>= 1, ++align)
+               ;
+             
              if (temp != 1)
                {
                  as_bad (_("Common alignment not a power of 2"));
@@ -336,6 +389,7 @@ v850_comm (area)
            }
          else
            align = 0;
+         
          switch (area)
            {
            case AREA_SDA:
@@ -367,24 +421,24 @@ v850_comm (area)
            {
            case AREA_SDA:
              if (S_GET_SEGMENT (symbolP) == sbss_section)
-               symbolP->sy_frag->fr_symbol = 0;
+               symbol_get_frag (symbolP)->fr_symbol = 0;
              break;
 
            case AREA_ZDA:
              if (S_GET_SEGMENT (symbolP) == zbss_section)
-               symbolP->sy_frag->fr_symbol = 0;
+               symbol_get_frag (symbolP)->fr_symbol = 0;
              break;
 
            case AREA_TDA:
              if (S_GET_SEGMENT (symbolP) == tbss_section)
-               symbolP->sy_frag->fr_symbol = 0;
+               symbol_get_frag (symbolP)->fr_symbol = 0;
              break;
 
            default:
              abort();
            }
          
-         symbolP->sy_frag = frag_now;
+         symbol_set_frag (symbolP, frag_now);
          pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
                            (offsetT) size, (char *) 0);
          *pfrag = 0;
@@ -392,9 +446,18 @@ v850_comm (area)
          
          switch (area)
            {
-           case AREA_SDA: S_SET_SEGMENT (symbolP, sbss_section); break;
-           case AREA_ZDA: S_SET_SEGMENT (symbolP, zbss_section); break;
-           case AREA_TDA: S_SET_SEGMENT (symbolP, tbss_section); break;
+           case AREA_SDA:
+             S_SET_SEGMENT (symbolP, sbss_section);
+             break;
+             
+           case AREA_ZDA:
+             S_SET_SEGMENT (symbolP, zbss_section);
+             break;
+             
+           case AREA_TDA:
+             S_SET_SEGMENT (symbolP, tbss_section);
+             break;
+             
            default:
              abort();
            }
@@ -412,9 +475,54 @@ v850_comm (area)
          
          switch (area)
            {
-           case AREA_SDA: S_SET_SEGMENT (symbolP, scommon_section); break;
-           case AREA_ZDA: S_SET_SEGMENT (symbolP, zcommon_section); break;
-           case AREA_TDA: S_SET_SEGMENT (symbolP, tcommon_section); break;
+           case AREA_SDA:
+             if (scommon_section == NULL)
+               {
+                 flagword      applicable;
+                 
+                 applicable = bfd_applicable_section_flags (stdoutput);
+                 
+                 scommon_section = subseg_new (".scommon", 0);
+                 
+                 bfd_set_section_flags (stdoutput, scommon_section, applicable
+                    & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
+                       | SEC_HAS_CONTENTS) | SEC_IS_COMMON);
+               }
+             S_SET_SEGMENT (symbolP, scommon_section);
+             break;
+             
+           case AREA_ZDA:
+             if (zcommon_section == NULL)
+               {
+                 flagword      applicable;
+                 
+                 applicable = bfd_applicable_section_flags (stdoutput);
+                 
+                 zcommon_section = subseg_new (".zcommon", 0);
+                 
+                 bfd_set_section_flags (stdoutput, zcommon_section, applicable
+                    & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
+                       | SEC_HAS_CONTENTS) | SEC_IS_COMMON);
+               }
+             S_SET_SEGMENT (symbolP, zcommon_section);
+             break;
+             
+           case AREA_TDA:
+             if (tcommon_section == NULL)
+               {
+                 flagword      applicable;
+                 
+                 applicable = bfd_applicable_section_flags (stdoutput);
+                 
+                 tcommon_section = subseg_new (".tcommon", 0);
+                 
+                 bfd_set_section_flags (stdoutput, tcommon_section, applicable
+                    & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
+                       | SEC_HAS_CONTENTS) | SEC_IS_COMMON);
+               }
+             S_SET_SEGMENT (symbolP, tcommon_section);
+             break;
+             
            default:
              abort();
            }
@@ -440,7 +548,7 @@ v850_comm (area)
       goto allocate_common;
     }
 
-  symbolP->bsym->flags |= BSF_OBJECT;
+  symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
 
   demand_empty_rest_of_line ();
   return;
@@ -469,10 +577,8 @@ set_machine (int number)
   switch (machine)
     {
     case 0: processor_mask = PROCESSOR_V850; break;
-/* start-sanitize-v850e */
     case bfd_mach_v850e:  processor_mask = PROCESSOR_V850E; break;
     case bfd_mach_v850ea: processor_mask = PROCESSOR_V850EA; break;
-/* end-sanitize-v850e */
     }
 }
 
@@ -494,12 +600,10 @@ const pseudo_typeS md_pseudo_table[] =
   {"scomm",   v850_comm,    AREA_SDA},
   {"tcomm",   v850_comm,    AREA_TDA},
   {"v850",    set_machine,  0},
-/* start-sanitize-v850e */
   {"call_table_data", v850_call_table_data, 0},
   {"call_table_text", v850_call_table_text, 0},
   {"v850e",           set_machine,          bfd_mach_v850e},
   {"v850ea",          set_machine,          bfd_mach_v850ea},
-/* end-sanitize-v850e */
   { NULL,     NULL,         0}
 };
 
@@ -554,13 +658,11 @@ static const struct reg_name pre_defined_registers[] =
 
 static const struct reg_name system_registers[] = 
 {
-/* start-sanitize-v850e */
   { "ctbp",  20 },
   { "ctpc",  16 },
   { "ctpsw", 17 },
   { "dbpc",  18 },
   { "dbpsw", 19 },
-/* end-sanitize-v850e */
   { "ecr",    4 },
   { "eipc",   0 },
   { "eipsw",  1 },
@@ -570,14 +672,12 @@ static const struct reg_name system_registers[] =
 };
 #define SYSREG_NAME_CNT        (sizeof (system_registers) / sizeof (struct reg_name))
 
-/* start-sanitize-v850e */
 static const struct reg_name system_list_registers[] =
 {
   {"PS",      5 },
   {"SR",      0 + 1}
 };
 #define SYSREGLIST_NAME_CNT    (sizeof (system_list_registers) / sizeof (struct reg_name))
-/* end-sanitize-v850e */
 
 static const struct reg_name cc_names[] =
 {
@@ -626,17 +726,19 @@ reg_name_search (regs, regcount, name, accept_numbers)
     {
       /* If the symbol is an alias for another name then use that.
         If the symbol is an alias for a number, then return the number.  */
-      if (symbolP->sy_value.X_op == O_symbol)
+      if (symbol_equated_p (symbolP))
        {
-         name = S_GET_NAME (symbolP->sy_value.X_add_symbol);
+         name = S_GET_NAME (symbol_get_value_expression (symbolP)->X_add_symbol);
        }
       else if (accept_numbers)
        {
          int reg = S_GET_VALUE (symbolP);
-
+         
          if (reg >= 0 && reg <= 31)
            return reg;
        }
+
+      /* Otherwise drop through and try parsing name normally.  */
     }
   
   low = 0;
@@ -713,10 +815,8 @@ register_name (expressionP)
  * 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.
- * start-sanitize-v850e
  *      accept_list_names is true iff the special names PS and SR may be 
  *      accepted.
- * end-sanitize-v850e
  *
  * out: A expressionS structure in expressionP.
  *     The operand may have been a register: in this case, X_op == O_register,
@@ -725,16 +825,10 @@ register_name (expressionP)
  *     its original state.
  */
 static boolean
-system_register_name (expressionP, accept_numbers
-                     /* start-sanitize-v850e */
-                     , accept_list_names
-                     /* end-sanitize-v850e */
-                     )
+system_register_name (expressionP, accept_numbers, accept_list_names)
      expressionS * expressionP;
      boolean       accept_numbers;
-/* start-sanitize-v850e */
      boolean       accept_list_names;
-/* end-sanitize-v850e */
 {
   int    reg_number;
   char * name;
@@ -762,16 +856,13 @@ system_register_name (expressionP, accept_numbers
          /* Make sure that the register number is allowable. */
          if (   reg_number < 0
                 || reg_number > 5
-/* start-sanitize-v850e */
                 && reg_number < 16
                 || reg_number > 20
-/* end-sanitize-v850e */
                 )
            {
              reg_number = -1;
            }
        }
-/* start-sanitize-v850e */      
       else if (accept_list_names)
        {
          c = get_symbol_end ();
@@ -780,9 +871,8 @@ system_register_name (expressionP, accept_numbers
 
          * input_line_pointer = c;   /* put back the delimiting char */
        }
-/* end-sanitize-v850e */      
     }
-      
+  
   /* look to see if it's in the register table */
   if (reg_number >= 0) 
     {
@@ -860,7 +950,6 @@ skip_white_space (void)
     ++ input_line_pointer;
 }
 
-/* start-sanitize-v850e */
 /* Summary of parse_register_list ().
  *
  * in: Input_line_pointer  points to 1st char of a list of registers.
@@ -908,11 +997,11 @@ parse_register_list
     case 0xfff8000f: regs = type2_regs; break;
     case 0xfff8001f: regs = type3_regs; break;
     default:
-      as_bad (_("unknown operand shift: %x\n"), operand->shift );
+      as_bad (_("unknown operand shift: %x\n"), operand->shift);
       return _("internal failure in parse_register_list");
     }
 
-  skip_white_space();
+  skip_white_space ();
 
   /* If the expression starts with a curly brace it is a register list.
      Otherwise it is a constant expression, whoes bits indicate which
@@ -1081,7 +1170,6 @@ parse_register_list
 
   return NULL;
 }
-/* end-sanitize-v850e */
 
 CONST char * md_shortopts = "m:";
 
@@ -1096,16 +1184,14 @@ void
 md_show_usage (stream)
   FILE * stream;
 {
-  fprintf (stream, _("V850 options:\n"));
-  fprintf (stream, _("\t-mwarn-signed-overflow    Warn if signed immediate values overflow\n"));
-  fprintf (stream, _("\t-mwarn-unsigned-overflow  Warn if unsigned immediate values overflow\n"));
-  fprintf (stream, _("\t-mv850                    The code is targeted at the v850\n"));
-/* start-sanitize-v850e */
-  fprintf (stream, _("\t-mv850e                   The code is targeted at the v850e\n"));
-  fprintf (stream, _("\t-mv850ea                  The code is targeted at the v850ea\n"));
-  fprintf (stream, _("\t-mv850any                 The code is generic, despite any processor specific instructions\n"));
-/* end-sanitize-v850e */
-} 
+  fprintf (stream, _(" V850 options:\n"));
+  fprintf (stream, _("  -mwarn-signed-overflow    Warn if signed immediate values overflow\n"));
+  fprintf (stream, _("  -mwarn-unsigned-overflow  Warn if unsigned immediate values overflow\n"));
+  fprintf (stream, _("  -mv850                    The code is targeted at the v850\n"));
+  fprintf (stream, _("  -mv850e                   The code is targeted at the v850e\n"));
+  fprintf (stream, _("  -mv850ea                  The code is targeted at the v850ea\n"));
+  fprintf (stream, _("  -mv850any                 The code is generic, despite any processor specific instructions\n"));
+}
 
 int
 md_parse_option (c, arg)
@@ -1132,7 +1218,6 @@ md_parse_option (c, arg)
       machine = 0;
       processor_mask = PROCESSOR_V850;
     }
-/* start-sanitize-v850e */
   else if (strcmp (arg, "v850e") == 0)
     {
       machine = bfd_mach_v850e;
@@ -1148,7 +1233,6 @@ md_parse_option (c, arg)
       machine = 0;                       /* Tell the world that this is for any v850 chip.  */
       processor_mask = PROCESSOR_V850EA; /* But support instructions for the extended versions.  */
     }
-/* end-sanitize-v850e */
   else
     {
       /* xgettext:c-format */
@@ -1244,8 +1328,8 @@ md_convert_frag (abfd, sec, fragP)
         target.  */
       md_number_to_chars (buffer + 2, 0x00000780, 4);
       fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
-              fragP->fr_offset, 1, BFD_RELOC_UNUSED + (int) fragP->fr_opcode
-              + 1);
+              fragP->fr_offset, 1, BFD_RELOC_UNUSED +
+              (int) fragP->fr_opcode + 1);
       fragP->fr_var = 0;
       fragP->fr_fix += 6;
     }
@@ -1254,8 +1338,8 @@ md_convert_frag (abfd, sec, fragP)
     {
       md_number_to_chars (fragP->fr_fix + fragP->fr_literal, 0x00000780, 4);
       fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
-              fragP->fr_offset, 1, BFD_RELOC_UNUSED + (int) fragP->fr_opcode
-              + 1);
+              fragP->fr_offset, 1, BFD_RELOC_UNUSED +
+              (int) fragP->fr_opcode + 1);
       fragP->fr_var = 0;
       fragP->fr_fix += 4;
     }
@@ -1279,7 +1363,6 @@ md_begin ()
   register const struct v850_opcode * op;
   flagword                            applicable;
 
-/* start-sanitize-v850e */
   if (strncmp (TARGET_CPU, "v850ea", 6) == 0)
     {
       if (machine == -1)
@@ -1297,7 +1380,6 @@ md_begin ()
        processor_mask = PROCESSOR_V850E;
     }
   else
-/* end-sanitize-v850e */
   if (strncmp (TARGET_CPU, "v850", 4) == 0)
     {
       if (machine == -1)
@@ -1331,10 +1413,23 @@ md_begin ()
 
   bfd_set_arch_mach (stdoutput, TARGET_ARCH, machine);
 
+  applicable = bfd_applicable_section_flags (stdoutput);
+  
+  call_table_data_section = subseg_new (".call_table_data", 0);
+  bfd_set_section_flags (stdoutput, call_table_data_section,
+                        applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+                                      | SEC_DATA | SEC_HAS_CONTENTS));
+  
+  call_table_text_section = subseg_new (".call_table_text", 0);
+  bfd_set_section_flags (stdoutput, call_table_text_section,
+                        applicable & (SEC_ALLOC | SEC_LOAD | SEC_READONLY
+                                      | SEC_CODE));
+  
+  /* Restore text section as the current default.  */
+  subseg_set (text_section, 0);
 }
 
 
-/* start-sanitize-v850e */
 static bfd_reloc_code_real_type
 handle_ctoff (const struct v850_operand * operand)
 {
@@ -1350,16 +1445,13 @@ handle_ctoff (const struct v850_operand * operand)
       
   return BFD_RELOC_V850_CALLT_6_7_OFFSET;
 }
-/* end-sanitize-v850e */
 
 static bfd_reloc_code_real_type
 handle_sdaoff (const struct v850_operand * operand)
 {
   if (operand == NULL)                             return BFD_RELOC_V850_SDA_16_16_OFFSET;
   if (operand->bits == 15 && operand->shift == 17) return BFD_RELOC_V850_SDA_15_16_OFFSET;
-  /* start-sanitize-v850e */
   if (operand->bits == -1)                         return BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET;
-  /* end-sanitize-v850e */
   
   if (   operand->bits  != 16
       || operand->shift != 16)
@@ -1376,9 +1468,7 @@ handle_zdaoff (const struct v850_operand * operand)
 {
   if (operand == NULL)                             return BFD_RELOC_V850_ZDA_16_16_OFFSET;
   if (operand->bits == 15 && operand->shift == 17) return BFD_RELOC_V850_ZDA_15_16_OFFSET;
-  /* start-sanitize-v850e */
   if (operand->bits == -1)                         return BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET;
-  /* end-sanitize-v850e */
 
   if (   operand->bits  != 16
       || operand->shift != 16)
@@ -1395,10 +1485,8 @@ handle_tdaoff (const struct v850_operand * operand)
 {
   if (operand == NULL)                               return BFD_RELOC_V850_TDA_7_7_OFFSET;  /* data item, not an instruction.  */
   if (operand->bits == 6 && operand->shift == 1)     return BFD_RELOC_V850_TDA_6_8_OFFSET;  /* sld.w/sst.w, operand: D8_6  */
-  /* start-sanitize-v850e */
   if (operand->bits == 4 && operand->insert != NULL) return BFD_RELOC_V850_TDA_4_5_OFFSET;  /* sld.hu, operand: D5-4 */
   if (operand->bits == 4 && operand->insert == NULL) return BFD_RELOC_V850_TDA_4_4_OFFSET;  /* sld.bu, operand: D4   */
-  /* end-sanitize-v850e */
   if (operand->bits == 16 && operand->shift == 16)   return BFD_RELOC_V850_TDA_16_16_OFFSET; /* set1 & chums, operands: D16 */
   
   if (operand->bits != 7)
@@ -1442,11 +1530,8 @@ v850_reloc_prefix (const struct v850_operand * operand)
   CHECK_ ("sdaoff", handle_sdaoff (operand));
   CHECK_ ("zdaoff", handle_zdaoff (operand));
   CHECK_ ("tdaoff", handle_tdaoff (operand));
-
-/* start-sanitize-v850e */
   CHECK_ ("hilo",   BFD_RELOC_32);
   CHECK_ ("ctoff",  handle_ctoff (operand));
-/* end-sanitize-v850e */
   
   /* Restore skipped parenthesis.  */
   if (paren_skipped)
@@ -1669,7 +1754,7 @@ md_assemble (str)
          if ((reloc = v850_reloc_prefix (operand)) != BFD_RELOC_UNUSED)
            {
              /* This is a fake reloc, used to indicate an error condition.  */
-             if (reloc == BFD_RELOC_64) 
+             if (reloc == BFD_RELOC_64)
                {
                  match = 1;
                  goto error;
@@ -1711,7 +1796,6 @@ md_assemble (str)
                        break;
                      }
                    
-/* start-sanitize-v850e */
                    case BFD_RELOC_32:
                      if ((operand->flags & V850E_IMMEDIATE32) == 0)
                        {
@@ -1724,7 +1808,6 @@ md_assemble (str)
                      extra_data            = ex.X_add_number;
                      ex.X_add_number       = 0;
                      break;
-/* end-sanitize-v850e */
                      
                    default:
                      fprintf (stderr, "reloc: %d\n", reloc);
@@ -1732,17 +1815,16 @@ md_assemble (str)
                      break;
                    }
 
-                 if (fc > MAX_INSN_FIXUPS)
-                   as_fatal (_("too many fixups"));
-  
-                 fixups[ fc ].exp     = ex;
-                 fixups[ fc ].opindex = * opindex_ptr;
-                 fixups[ fc ].reloc   = reloc;
-                 fc++;
+                 if (fc > MAX_INSN_FIXUPS)
+                   as_fatal (_("too many fixups"));
+                 
+                 fixups[ fc ].exp     = ex;
+                 fixups[ fc ].opindex = * opindex_ptr;
+                 fixups[ fc ].reloc   = reloc;
+                 fc++;
                }
              else
                {
-/* start-sanitize-v850e */
                  if (reloc == BFD_RELOC_32)
                    {
                      if ((operand->flags & V850E_IMMEDIATE32) == 0)
@@ -1755,7 +1837,6 @@ md_assemble (str)
                      extra_data_len        = 4;
                      extra_data            = ex.X_add_number;
                    }
-/* end-sanitize-v850e */
                      
                  if (fc > MAX_INSN_FIXUPS)
                    as_fatal (_("too many fixups"));
@@ -1789,11 +1870,7 @@ md_assemble (str)
                }
              else if ((operand->flags & V850_OPERAND_SRG) != 0) 
                {
-                 if (!system_register_name (& ex, true
-                                            /* start-sanitize-v850e */
-                                            , false
-                                            /* end-sanitize-v850e */
-                                            ))
+                 if (!system_register_name (& ex, true, false))
                    {
                      errmsg = _("invalid system register name");
                    }
@@ -1816,8 +1893,7 @@ md_assemble (str)
                  str = input_line_pointer;
                  input_line_pointer = hold;
              
-                 while (   *str == ' ' || *str == ',' || *str == '['
-                        || *str == ']')
+                 while (*str == ' ' || *str == ',' || *str == '[' || *str == ']')
                    ++ str;
                  continue;
                }
@@ -1828,7 +1904,6 @@ md_assemble (str)
                      errmsg = _("invalid condition code name");
                    }
                }
-/* start-sanitize-v850e */
              else if (operand->flags & V850E_PUSH_POP) 
                {
                  errmsg = parse_register_list (& insn, operand);
@@ -1871,7 +1946,6 @@ md_assemble (str)
                  extra_data            = ex.X_add_number;
                  ex.X_add_number       = 0;
                }
-/* end-sanitize-v850e */
              else if (register_name (& ex)
                       && (operand->flags & V850_OPERAND_REG) == 0)
                {
@@ -1887,7 +1961,7 @@ md_assemble (str)
 
                  input_line_pointer = str;
 
-                 c = get_symbol_end();
+                 c = get_symbol_end ();
                  
                  if (symbol_find (str) != NULL)
                    exists = 1;
@@ -1917,11 +1991,7 @@ md_assemble (str)
                                       & symbol_rootP, & symbol_lastP);
                    }
                }
-             else if (system_register_name (& ex, false
-                                            /* start-sanitize-v850e */
-                                            , false
-                                            /* end-sanitize-v850e */
-                                            )
+             else if (system_register_name (& ex, false, false)
                       && (operand->flags & V850_OPERAND_SRG) == 0)
                {
                  errmsg = _("syntax error: system register not expected");
@@ -1934,7 +2004,6 @@ md_assemble (str)
              else
                {
                  expression (& ex);
-/* start-sanitize-v850e */
                  /* Special case:
                     If we are assembling a MOV instruction (or a CALLT.... :-)
                     and the immediate value does not fit into the bits
@@ -1947,7 +2016,6 @@ md_assemble (str)
                      && (ex.X_add_number < (- (1 << (operand->bits - 1)))
                          || ex.X_add_number > ((1 << operand->bits) - 1)))
                    errmsg = _("immediate operand is too large");
-/* end-sanitize-v850e */
                }
 
              if (errmsg)
@@ -2075,11 +2143,9 @@ md_assemble (str)
       else
        insn_size = 2;
 
-/* start-sanitize-v850e */
       /* Special case: 32 bit MOV */
       if ((insn & 0xffe0) == 0x0620)
        insn_size = 2;
-/* end-sanitize-v850e */
       
       f = frag_more (insn_size);
       
@@ -2126,7 +2192,7 @@ md_assemble (str)
          /* XXX This will abort on an R_V850_8 reloc -
             is this reloc actually used ? */
          if (size != 2 && size != 4) 
-           abort();
+           abort ();
 
          address = (f - frag_now->fr_literal) + insn_size - size;
 
@@ -2177,7 +2243,8 @@ tc_gen_reloc (seg, fixp)
   arelent * reloc;
   
   reloc              = (arelent *) xmalloc (sizeof (arelent));
-  reloc->sym_ptr_ptr = & fixp->fx_addsy->bsym;
+  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);
 
@@ -2186,14 +2253,18 @@ tc_gen_reloc (seg, fixp)
       as_bad_where (fixp->fx_file, fixp->fx_line,
                    /* xgettext:c-format */
                     _("reloc %d not supported by object file format"),
-                   (int)fixp->fx_r_type);
+                   (int) fixp->fx_r_type);
 
       xfree (reloc);
       
       return NULL;
     }
   
-  reloc->addend = fixp->fx_addnumber;
+  if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
+      || fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
+    reloc->addend = fixp->fx_offset;
+  else
+    reloc->addend = fixp->fx_addnumber;
   
   return reloc;
 }
@@ -2214,16 +2285,21 @@ md_estimate_size_before_relax (fragp, seg)
 } 
 
 long
-md_pcrel_from (fixp)
+v850_pcrel_from_section (fixp, section)
      fixS * fixp;
+     segT   section;
 {
   /* If the symbol is undefined, or in a section other than our own,
      then let the linker figure it out.  */
-  if (fixp->fx_addsy != (symbolS *) NULL && ! S_IS_DEFINED (fixp->fx_addsy))
+  if (fixp->fx_addsy != (symbolS *) NULL
+      && (! S_IS_DEFINED (fixp->fx_addsy)
+         || (S_GET_SEGMENT (fixp->fx_addsy) != section)))
     {
-      /* The symbol is undefined.  Let the linker figure it out.  */
+      /* The symbol is undefined/not in our section.
+        Let the linker figure it out.  */
       return 0;
     }
+
   return fixp->fx_frag->fr_address + fixp->fx_where;
 }
 
@@ -2236,6 +2312,13 @@ md_apply_fix3 (fixp, valuep, seg)
   valueT value;
   char * where;
 
+  if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+      || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+    {
+      fixp->fx_done = 0;
+      return 1;
+    }
+
   if (fixp->fx_addsy == (symbolS *) NULL)
     {
       value = * valuep;
@@ -2297,7 +2380,7 @@ md_apply_fix3 (fixp, valuep, seg)
        {
          /* fprintf (stderr, "bits: %d, insn: %x\n", operand->bits, insn); */
          
-         as_bad_where(fixp->fx_file, fixp->fx_line,
+         as_bad_where (fixp->fx_file, fixp->fx_line,
                       _("unresolved expression that must be resolved"));
          fixp->fx_done = 1;
          return 1;
@@ -2309,7 +2392,7 @@ md_apply_fix3 (fixp, valuep, seg)
       where = fixp->fx_frag->fr_literal + fixp->fx_where;
 
       if (fixp->fx_size == 1)
-       *where = value & 0xff;
+       * where = value & 0xff;
       else if (fixp->fx_size == 2)
        bfd_putl16 (value & 0xffff, (unsigned char *) where);
       else if (fixp->fx_size == 4)
@@ -2359,3 +2442,38 @@ cons_fix_new_v850 (frag, where, size, exp)
   else
     fix_new (frag, where, size, NULL, 0, 0, hold_cons_reloc);
 }
+boolean
+v850_fix_adjustable (fixP)
+    fixS *fixP;
+{
+  if (fixP->fx_addsy == NULL)
+    return 1;
+  /* Prevent all adjustments to global symbols. */
+  if (S_IS_EXTERN (fixP->fx_addsy))
+    return 0;
+  if (S_IS_WEAK (fixP->fx_addsy))
+    return 0;
+  /* Don't adjust function names */
+  if (S_IS_FUNCTION (fixP->fx_addsy))
+    return 0;
+
+  /* We need the symbol name for the VTABLE entries */
+  if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+      || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+    return 0;
+  return 1;
+}
+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;
+  return 0;
+}