Change type of v850_target_arch to enum bfd_architecture
[deliverable/binutils-gdb.git] / gas / config / tc-v850.c
index c48c01112e95cf55474626a9926fe89e148fd7b4..b0135b33d3f2cef57542521b13ce82cde75ec6eb 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-v850.c -- Assembler code for the NEC V850
-   Copyright (C) 1996-2015 Free Software Foundation, Inc.
+   Copyright (C) 1996-2016 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
 static bfd_boolean warn_signed_overflows   = FALSE;
 static bfd_boolean warn_unsigned_overflows = FALSE;
 
+/* Non-zero if floating point insns are not being used.  */
+static signed int soft_float = -1;
+
 /* Indicates the target BFD machine number.  */
 static int machine = -1;
 
 
 /* Indiciates the target BFD architecture.  */
-int          v850_target_arch = bfd_arch_v850_rh850;
+enum bfd_architecture v850_target_arch = bfd_arch_v850_rh850;
 const char * v850_target_format = "elf32-v850-rh850";
 static flagword v850_e_flags = 0;
 
@@ -267,8 +270,7 @@ v850_comm (int area)
   symbolS *symbolP;
   int have_align;
 
-  name = input_line_pointer;
-  c = get_symbol_end ();
+  c = get_symbol_name (&name);
 
   /* Just after name is now '\0'.  */
   p = input_line_pointer;
@@ -1002,15 +1004,14 @@ register_name (expressionS *expressionP)
   char c;
 
   /* Find the spelling of the operand.  */
-  start = name = input_line_pointer;
-
-  c = get_symbol_end ();
+  start = input_line_pointer;
+  c = get_symbol_name (&name);
 
   reg_number = reg_name_search (pre_defined_registers, REG_NAME_CNT,
                                name, FALSE);
 
   /* Put back the delimiting char.  */
-  *input_line_pointer = c;
+  (void) restore_line_pointer (c);
 
   expressionP->X_add_symbol = NULL;
   expressionP->X_op_symbol  = NULL;
@@ -1054,14 +1055,13 @@ system_register_name (expressionS *expressionP,
   char c;
 
   /* Find the spelling of the operand.  */
-  start = name = input_line_pointer;
-
-  c = get_symbol_end ();
+  start = input_line_pointer;
+  c = get_symbol_name (&name);
   reg_number = reg_name_search (system_registers, SYSREG_NAME_CNT, name,
                                accept_numbers);
 
   /* Put back the delimiting char.  */
-  *input_line_pointer = c;
+  (void) restore_line_pointer (c);
 
   if (reg_number < 0
       && accept_numbers)
@@ -1115,13 +1115,12 @@ cc_name (expressionS *expressionP,
   char c;
 
   /* Find the spelling of the operand.  */
-  start = name = input_line_pointer;
-
-  c = get_symbol_end ();
+  start = input_line_pointer;
+  c = get_symbol_name (&name);
   reg_number = reg_name_search (cc_names, CC_NAME_CNT, name, accept_numbers);
 
   /* Put back the delimiting char.  */
-  *input_line_pointer = c;
+  (void) restore_line_pointer (c);
 
   if (reg_number < 0
       && accept_numbers)
@@ -1166,13 +1165,12 @@ float_cc_name (expressionS *expressionP,
   char c;
 
   /* Find the spelling of the operand.  */
-  start = name = input_line_pointer;
-
-  c = get_symbol_end ();
+  start = input_line_pointer;
+  c = get_symbol_name (&name);
   reg_number = reg_name_search (float_cc_names, FLOAT_CC_NAME_CNT, name, accept_numbers);
 
   /* Put back the delimiting char.  */
-  *input_line_pointer = c;
+  (void) restore_line_pointer (c);
 
   if (reg_number < 0
       && accept_numbers)
@@ -1217,13 +1215,12 @@ cacheop_name (expressionS * expressionP,
   char c;
 
   /* Find the spelling of the operand.  */
-  start = name = input_line_pointer;
-
-  c = get_symbol_end ();
+  start = input_line_pointer;
+  c = get_symbol_name (&name);
   reg_number = reg_name_search (cacheop_names, CACHEOP_NAME_CNT, name, accept_numbers);
 
   /* Put back the delimiting char.  */
-  *input_line_pointer = c;
+  (void) restore_line_pointer (c);
 
   if (reg_number < 0
       && accept_numbers)
@@ -1266,13 +1263,12 @@ prefop_name (expressionS * expressionP,
   char c;
 
   /* Find the spelling of the operand.  */
-  start = name = input_line_pointer;
-
-  c = get_symbol_end ();
+  start = input_line_pointer;
+  c = get_symbol_name (&name);
   reg_number = reg_name_search (prefop_names, PREFOP_NAME_CNT, name, accept_numbers);
 
   /* Put back the delimiting char.  */
-  *input_line_pointer = c;
+  (void) restore_line_pointer (c);
 
   if (reg_number < 0
       && accept_numbers)
@@ -1314,15 +1310,14 @@ vector_register_name (expressionS *expressionP)
   char c;
 
   /* Find the spelling of the operand.  */
-  start = name = input_line_pointer;
-
-  c = get_symbol_end ();
+  start = input_line_pointer;
+  c = get_symbol_name (&name);
 
   reg_number = reg_name_search (vector_registers, VREG_NAME_CNT,
                                name, FALSE);
 
   /* Put back the delimiting char.  */
-  *input_line_pointer = c;
+  (void) restore_line_pointer (c);
 
   expressionP->X_add_symbol = NULL;
   expressionP->X_op_symbol  = NULL;
@@ -1377,7 +1372,7 @@ skip_white_space (void)
    and so on upwards.  System registers are considered to be very
    high numbers.  */
 
-static char *
+static const char *
 parse_register_list (unsigned long *insn,
                     const struct v850_operand *operand)
 {
@@ -1537,6 +1532,8 @@ struct option md_longopts[] =
 
 size_t md_longopts_size = sizeof (md_longopts);
 
+static bfd_boolean v850_data_8 = FALSE;
+
 void
 md_show_usage (FILE *stream)
 {
@@ -1560,10 +1557,12 @@ md_show_usage (FILE *stream)
   fprintf (stream, _("  -mrh850-abi               Mark the binary as using the RH850 ABI (default)\n"));
   fprintf (stream, _("  -m8byte-align             Mark the binary as using 64-bit alignment\n"));
   fprintf (stream, _("  -m4byte-align             Mark the binary as using 32-bit alignment (default)\n"));
+  fprintf (stream, _("  -msoft-float              Mark the binary as not using FP insns (default for pre e2v3)\n"));
+  fprintf (stream, _("  -mhard-float              Mark the binary as using FP insns (default for e2v3 and up)\n"));
 }
 
 int
-md_parse_option (int c, char *arg)
+md_parse_option (int c, const char *arg)
 {
   if (c != 'm')
     {
@@ -1646,9 +1645,19 @@ md_parse_option (int c, char *arg)
       v850_target_format = "elf32-v850-rh850";
     }
   else if (strcmp (arg, "8byte-align") == 0)
-    v850_e_flags |= EF_RH850_DATA_ALIGN8;
+    {
+      v850_data_8 = TRUE;
+      v850_e_flags |= EF_RH850_DATA_ALIGN8;
+    }
   else if (strcmp (arg, "4byte-align") == 0)
-    v850_e_flags &= ~ EF_RH850_DATA_ALIGN8;
+    {
+      v850_data_8 = FALSE;
+      v850_e_flags &= ~ EF_RH850_DATA_ALIGN8;
+    }
+  else if (strcmp (arg, "soft-float") == 0)
+    soft_float = 1;
+  else if (strcmp (arg, "hard-float") == 0)
+    soft_float = 0;
   else
     return 0;
 
@@ -1661,7 +1670,7 @@ md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
   return 0;
 }
 
-char *
+const char *
 md_atof (int type, char *litp, int *sizep)
 {
   return ieee_md_atof (type, litp, sizep, FALSE);
@@ -1750,7 +1759,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
   /* Out of range conditional branch.  Emit a branch around a 22bit jump.  */
   else if (fragP->fr_subtype == SUBYPTE_COND_9_22 + 1
           || fragP->fr_subtype == SUBYPTE_COND_9_22_32 + 1
-          || fragP->fr_subtype == SUBYPTE_COND_9_17_22 + 2 
+          || fragP->fr_subtype == SUBYPTE_COND_9_17_22 + 2
           || fragP->fr_subtype == SUBYPTE_COND_9_17_22_32 + 2)
     {
       unsigned char *buffer =
@@ -1870,13 +1879,13 @@ valueT
 md_section_align (asection *seg, valueT addr)
 {
   int align = bfd_get_section_alignment (stdoutput, seg);
-  return ((addr + (1 << align) - 1) & (-1 << align));
+  return ((addr + (1 << align) - 1) & -(1 << align));
 }
 
 void
 md_begin (void)
 {
-  char *prev_name = "";
+  const char *prev_name = "";
   const struct v850_opcode *op;
 
   if (strncmp (TARGET_CPU, "v850e3v5", 8) == 0)
@@ -1940,6 +1949,9 @@ md_begin (void)
     as_bad (_("Unable to determine default target processor from string: %s"),
            TARGET_CPU);
 
+  if (soft_float == -1)
+    soft_float = machine < bfd_mach_v850e2v3;
+
   v850_hash = hash_new ();
 
   /* Insert unique names into hash table.  The V850 instruction set
@@ -2772,18 +2784,19 @@ md_assemble (char *str)
              else if ((operand->flags & V850_OPERAND_EP) != 0)
                {
                  char *start = input_line_pointer;
-                 char c = get_symbol_end ();
+                 char *name;
+                 char c = get_symbol_name (&name);
 
-                 if (strcmp (start, "ep") != 0 && strcmp (start, "r30") != 0)
+                 if (strcmp (name, "ep") != 0 && strcmp (name, "r30") != 0)
                    {
                      /* Put things back the way we found them.  */
-                     *input_line_pointer = c;
+                     (void) restore_line_pointer (c);
                      input_line_pointer = start;
                      errmsg = _("expected EP register");
                      goto error;
                    }
 
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  str = input_line_pointer;
                  input_line_pointer = hold;
 
@@ -2830,6 +2843,7 @@ md_assemble (char *str)
              else if ((register_name (&ex)
                        && (operand->flags & V850_OPERAND_REG) == 0))
                {
+                 char *name;
                  char c;
                  int exists = 0;
 
@@ -2842,12 +2856,12 @@ md_assemble (char *str)
 
                  input_line_pointer = str;
 
-                 c = get_symbol_end ();
+                 c = get_symbol_name (&name);
 
-                 if (symbol_find (str) != NULL)
+                 if (symbol_find (name) != NULL)
                    exists = 1;
 
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  input_line_pointer = str;
 
                  expression (&ex);
@@ -3323,8 +3337,8 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
 {
   arelent *reloc;
 
-  reloc                      = xmalloc (sizeof (arelent));
-  reloc->sym_ptr_ptr  = xmalloc (sizeof (asymbol *));
+  reloc                      = XNEW (arelent);
+  reloc->sym_ptr_ptr  = XNEW (asymbol *);
   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   reloc->address      = fixp->fx_frag->fr_address + fixp->fx_where;
 
@@ -3716,3 +3730,73 @@ v850_force_relocation (struct fix *fixP)
 
   return generic_force_reloc (fixP);
 }
+
+/* Create a v850 note section.  */
+void
+v850_md_end (void)
+{
+  segT note_sec;
+  segT orig_seg = now_seg;
+  subsegT orig_subseg = now_subseg;
+  enum v850_notes id;
+
+  note_sec = subseg_new (V850_NOTE_SECNAME, 0);
+  bfd_set_section_flags (stdoutput, note_sec, SEC_HAS_CONTENTS | SEC_READONLY | SEC_MERGE);
+  bfd_set_section_alignment (stdoutput, note_sec, 2);
+
+  /* Provide default values for all of the notes.  */
+  for (id = V850_NOTE_ALIGNMENT; id <= NUM_V850_NOTES; id++)
+    {
+      int val = 0;
+      char * p;
+
+      /* Follow the standard note section layout:
+        First write the length of the name string.  */
+      p = frag_more (4);
+      md_number_to_chars (p, 4, 4);
+
+      /* Next comes the length of the "descriptor", i.e., the actual data.  */
+      p = frag_more (4);
+      md_number_to_chars (p, 4, 4);
+
+      /* Write the note type.  */
+      p = frag_more (4);
+      md_number_to_chars (p, (valueT) id, 4);
+
+      /* Write the name field.  */
+      p = frag_more (4);
+      memcpy (p, V850_NOTE_NAME, 4);
+
+      /* Finally, write the descriptor.  */
+      p = frag_more (4);
+      switch (id)
+       {
+       case V850_NOTE_ALIGNMENT:
+         val = v850_data_8 ? EF_RH850_DATA_ALIGN8 : EF_RH850_DATA_ALIGN4;
+         break;
+
+       case V850_NOTE_DATA_SIZE:
+         /* GCC does not currently support an option
+            for 32-bit doubles with the V850 backend.  */
+         val = EF_RH850_DOUBLE64;
+         break;
+
+       case V850_NOTE_FPU_INFO:
+         if (! soft_float)
+           switch (machine)
+             {
+             case bfd_mach_v850e3v5: val = EF_RH850_FPU30; break;
+             case bfd_mach_v850e2v3: val = EF_RH850_FPU20; break;
+             default: break;
+             }
+         break;
+
+       default:
+         break;
+       }
+      md_number_to_chars (p, val, 4);
+    }
+
+  /* Paranoia - we probably do not need this.  */
+  subseg_set (orig_seg, orig_subseg);
+}
This page took 0.030007 seconds and 4 git commands to generate.