Add support for .extInstruction pseudo-op.
[deliverable/binutils-gdb.git] / gas / config / tc-cris.c
index 8c2d87af9ff54e28fa959b99b986f2f7f7c82b10..536e6cbeb138e528a978add9d6724f419b124729 100644 (file)
@@ -1,6 +1,5 @@
 /* tc-cris.c -- Assembler code for the CRIS CPU core.
 /* tc-cris.c -- Assembler code for the CRIS CPU core.
-   Copyright 2000, 2001, 2002, 2003, 2004, 2006, 2007
-   Free Software Foundation, Inc.
+   Copyright (C) 2000-2016 Free Software Foundation, Inc.
 
    Contributed by Axis Communications AB, Lund, Sweden.
    Originally written for GAS 1.38.1 by Mikael Asker.
 
    Contributed by Axis Communications AB, Lund, Sweden.
    Originally written for GAS 1.38.1 by Mikael Asker.
@@ -120,7 +119,7 @@ enum cris_archs
   arch_cris_any_v0_v10, arch_crisv32, arch_cris_common_v10_v32
 };
 
   arch_cris_any_v0_v10, arch_crisv32, arch_cris_common_v10_v32
 };
 
-static enum cris_archs cris_arch_from_string (char **);
+static enum cris_archs cris_arch_from_string (const char **);
 static int cris_insn_ver_valid_for_arch (enum cris_insn_version_usage,
                                         enum cris_archs);
 
 static int cris_insn_ver_valid_for_arch (enum cris_insn_version_usage,
                                         enum cris_archs);
 
@@ -142,12 +141,11 @@ static int branch_disp (int);
 static void gen_cond_branch_32 (char *, char *, fragS *, symbolS *, symbolS *,
                                long int);
 static void cris_number_to_imm (char *, long, int, fixS *, segT);
 static void gen_cond_branch_32 (char *, char *, fragS *, symbolS *, symbolS *,
                                long int);
 static void cris_number_to_imm (char *, long, int, fixS *, segT);
-static void cris_create_short_jump (char *, addressT, addressT, fragS *,
-                                   symbolS *);
 static void s_syntax (int);
 static void s_cris_file (int);
 static void s_cris_loc (int);
 static void s_cris_arch (int);
 static void s_syntax (int);
 static void s_cris_file (int);
 static void s_cris_loc (int);
 static void s_cris_arch (int);
+static void s_cris_dtpoff (int);
 
 /* Get ":GOT", ":GOTOFF", ":PLT" etc. suffixes.  */
 static void cris_get_reloc_suffix (char **, bfd_reloc_code_real_type *,
 
 /* Get ":GOT", ":GOTOFF", ":PLT" etc. suffixes.  */
 static void cris_get_reloc_suffix (char **, bfd_reloc_code_real_type *,
@@ -198,6 +196,7 @@ static enum cris_archs cris_arch = XCONCAT2 (arch_,DEFAULT_CRIS_ARCH);
 const pseudo_typeS md_pseudo_table[] =
 {
   {"dword", cons, 4},
 const pseudo_typeS md_pseudo_table[] =
 {
   {"dword", cons, 4},
+  {"dtpoffd", s_cris_dtpoff, 4},
   {"syntax", s_syntax, 0},
   {"file", s_cris_file, 0},
   {"loc", s_cris_loc, 0},
   {"syntax", s_syntax, 0},
   {"file", s_cris_file, 0},
   {"loc", s_cris_loc, 0},
@@ -815,7 +814,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED,
 
   /* Used to check integrity of the relaxation.
      One of 2 = long, 1 = word, or 0 = byte.  */
 
   /* Used to check integrity of the relaxation.
      One of 2 = long, 1 = word, or 0 = byte.  */
-  int length_code;
+  int length_code ATTRIBUTE_UNUSED;
 
   /* Size in bytes of variable-sized part of frag.  */
   int var_part_size = 0;
 
   /* Size in bytes of variable-sized part of frag.  */
   int var_part_size = 0;
@@ -1021,14 +1020,10 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED,
 }
 
 /* Generate a short jump around a secondary jump table.
 }
 
 /* Generate a short jump around a secondary jump table.
-   Used by md_create_long_jump.
+   Also called from md_create_long_jump, when sufficient.  */
 
 
-   This used to be md_create_short_jump, but is now called from
-   md_create_long_jump instead, when sufficient, since the sizes of the
-   jumps are the same for pre-v32.  */
-
-static void
-cris_create_short_jump (char *storep, addressT from_addr, addressT to_addr,
+void
+md_create_short_jump (char *storep, addressT from_addr, addressT to_addr,
                        fragS *fragP ATTRIBUTE_UNUSED,
                        symbolS *to_symbol ATTRIBUTE_UNUSED)
 {
                        fragS *fragP ATTRIBUTE_UNUSED,
                        symbolS *to_symbol ATTRIBUTE_UNUSED)
 {
@@ -1037,18 +1032,30 @@ cris_create_short_jump (char *storep, addressT from_addr, addressT to_addr,
   /* See md_create_long_jump about the comment on the "+ 2".  */
   long int max_minimal_minus_distance;
   long int max_minimal_plus_distance;
   /* See md_create_long_jump about the comment on the "+ 2".  */
   long int max_minimal_minus_distance;
   long int max_minimal_plus_distance;
+  long int max_minus_distance;
+  long int max_plus_distance;
   int nop_opcode;
 
   if (cris_arch == arch_crisv32)
     {
       max_minimal_minus_distance = BRANCH_BB_V32 + 2;
       max_minimal_plus_distance = BRANCH_BF_V32 + 2;
   int nop_opcode;
 
   if (cris_arch == arch_crisv32)
     {
       max_minimal_minus_distance = BRANCH_BB_V32 + 2;
       max_minimal_plus_distance = BRANCH_BF_V32 + 2;
+      max_minus_distance = BRANCH_WB_V32 + 2;
+      max_plus_distance = BRANCH_WF_V32 + 2;
       nop_opcode = NOP_OPCODE_V32;
     }
       nop_opcode = NOP_OPCODE_V32;
     }
+  else if (cris_arch == arch_cris_common_v10_v32)
+    /* Bail out for compatibility mode.  (It seems it can be implemented,
+       perhaps with a 10-byte sequence: "move.d NNNN,$pc/$acr", "jump
+       $acr", "nop"; but doesn't seem worth it at the moment.)  */
+    as_fatal (_("Out-of-range .word offset handling\
+ is not implemented for .arch common_v10_v32"));
   else
     {
       max_minimal_minus_distance = BRANCH_BB + 2;
       max_minimal_plus_distance = BRANCH_BF + 2;
   else
     {
       max_minimal_minus_distance = BRANCH_BB + 2;
       max_minimal_plus_distance = BRANCH_BF + 2;
+      max_minus_distance = BRANCH_WB + 2;
+      max_plus_distance = BRANCH_WF + 2;
       nop_opcode = NOP_OPCODE;
     }
 
       nop_opcode = NOP_OPCODE;
     }
 
@@ -1068,7 +1075,8 @@ cris_create_short_jump (char *storep, addressT from_addr, addressT to_addr,
         a nop to keep disassembly sane.  */
       md_number_to_chars (storep + 4, nop_opcode, 2);
     }
         a nop to keep disassembly sane.  */
       md_number_to_chars (storep + 4, nop_opcode, 2);
     }
-  else
+  else if (max_minus_distance <= distance
+          && distance <= max_plus_distance)
     {
       /* Make it a "long" short jump: "BA (PC+)".  */
       md_number_to_chars (storep, BA_PC_INCR_OPCODE, 2);
     {
       /* Make it a "long" short jump: "BA (PC+)".  */
       md_number_to_chars (storep, BA_PC_INCR_OPCODE, 2);
@@ -1083,6 +1091,9 @@ cris_create_short_jump (char *storep, addressT from_addr, addressT to_addr,
       /* A nop for the delay slot.  */
       md_number_to_chars (storep + 4, nop_opcode, 2);
     }
       /* A nop for the delay slot.  */
       md_number_to_chars (storep + 4, nop_opcode, 2);
     }
+  else
+    as_bad_where (fragP->fr_file, fragP->fr_line,
+                 _(".word case-table handling failed: table too large"));
 }
 
 /* Generate a long jump in a secondary jump table.
 }
 
 /* Generate a long jump in a secondary jump table.
@@ -1109,20 +1120,19 @@ md_create_long_jump (char *storep, addressT from_addr, addressT to_addr,
   long int max_short_plus_distance
     = cris_arch != arch_crisv32 ? BRANCH_WF + 3 : BRANCH_WF_V32 + 3;
 
   long int max_short_plus_distance
     = cris_arch != arch_crisv32 ? BRANCH_WF + 3 : BRANCH_WF_V32 + 3;
 
-  /* Bail out for compatibility mode.  (It seems it can be implemented,
-     perhaps with a 10-byte sequence: "move.d NNNN,$pc/$acr", "jump
-     $acr", "nop"; but doesn't seem worth it at the moment.)  */
-  if (cris_arch == arch_cris_common_v10_v32)
-    as_fatal (_("Out-of-range .word offset handling\
- is not implemented for .arch common_v10_v32"));
-
   distance = to_addr - from_addr;
 
   if (max_short_minus_distance <= distance
       && distance <= max_short_plus_distance)
   distance = to_addr - from_addr;
 
   if (max_short_minus_distance <= distance
       && distance <= max_short_plus_distance)
-    /* Then make it a "short" long jump.  */
-    cris_create_short_jump (storep, from_addr, to_addr, fragP,
+    {
+      /* Then make it a "short" long jump.  */
+      md_create_short_jump (storep, from_addr, to_addr, fragP,
                            to_symbol);
                            to_symbol);
+      if (cris_arch == arch_crisv32)
+       md_number_to_chars (storep + 6, NOP_OPCODE_V32, 2);
+      else
+       md_number_to_chars (storep + 6, NOP_OPCODE, 2);
+    }
   else
     {
       /* We have a "long" long jump: "JUMP [PC+]".  If CRISv32, always
   else
     {
       /* We have a "long" long jump: "JUMP [PC+]".  If CRISv32, always
@@ -1482,6 +1492,19 @@ md_assemble (char *str)
     }
 }
 
     }
 }
 
+/* Helper error-reporting function: calls as_bad for a format string
+   for a single value and zeroes the offending value (zero assumed
+   being a valid value) to avoid repeated error reports in later value
+   checking.  */
+
+static void
+cris_bad (const char *format, offsetT *valp)
+{
+  /* We cast to long so the format string can assume that format.  */
+  as_bad (format, (long) *valp);
+  *valp = 0;
+}
+
 /* Low level text-to-bits assembly.  */
 
 static void
 /* Low level text-to-bits assembly.  */
 
 static void
@@ -1636,8 +1659,8 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
                  if (out_insnp->expr.X_op == O_constant
                      && (out_insnp->expr.X_add_number < 0
                          || out_insnp->expr.X_add_number > 31))
                  if (out_insnp->expr.X_op == O_constant
                      && (out_insnp->expr.X_add_number < 0
                          || out_insnp->expr.X_add_number > 31))
-                   as_bad (_("Immediate value not in 5 bit unsigned range: %ld"),
-                           out_insnp->expr.X_add_number);
+                   cris_bad (_("Immediate value not in 5 bit unsigned range: %ld"),
+                             &out_insnp->expr.X_add_number);
 
                  out_insnp->reloc = BFD_RELOC_CRIS_UNSIGNED_5;
                  continue;
 
                  out_insnp->reloc = BFD_RELOC_CRIS_UNSIGNED_5;
                  continue;
@@ -1652,8 +1675,8 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
                  if (out_insnp->expr.X_op == O_constant
                      && (out_insnp->expr.X_add_number < 0
                          || out_insnp->expr.X_add_number > 15))
                  if (out_insnp->expr.X_op == O_constant
                      && (out_insnp->expr.X_add_number < 0
                          || out_insnp->expr.X_add_number > 15))
-                   as_bad (_("Immediate value not in 4 bit unsigned range: %ld"),
-                           out_insnp->expr.X_add_number);
+                   cris_bad (_("Immediate value not in 4 bit unsigned range: %ld"),
+                             &out_insnp->expr.X_add_number);
 
                  out_insnp->reloc = BFD_RELOC_CRIS_UNSIGNED_4;
                  continue;
 
                  out_insnp->reloc = BFD_RELOC_CRIS_UNSIGNED_4;
                  continue;
@@ -1704,8 +1727,9 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
                  if (out_insnp->expr.X_op == O_constant
                      && (out_insnp->expr.X_add_number < -32
                          || out_insnp->expr.X_add_number > 31))
                  if (out_insnp->expr.X_op == O_constant
                      && (out_insnp->expr.X_add_number < -32
                          || out_insnp->expr.X_add_number > 31))
-                   as_bad (_("Immediate value not in 6 bit range: %ld"),
-                           out_insnp->expr.X_add_number);
+                   cris_bad (_("Immediate value not in 6 bit range: %ld"),
+                             &out_insnp->expr.X_add_number);
+
                  out_insnp->reloc = BFD_RELOC_CRIS_SIGNED_6;
                  continue;
                }
                  out_insnp->reloc = BFD_RELOC_CRIS_SIGNED_6;
                  continue;
                }
@@ -1719,8 +1743,9 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
                  if (out_insnp->expr.X_op == O_constant
                      && (out_insnp->expr.X_add_number < 0
                          || out_insnp->expr.X_add_number > 63))
                  if (out_insnp->expr.X_op == O_constant
                      && (out_insnp->expr.X_add_number < 0
                          || out_insnp->expr.X_add_number > 63))
-                   as_bad (_("Immediate value not in 6 bit unsigned range: %ld"),
-                           out_insnp->expr.X_add_number);
+                   cris_bad (_("Immediate value not in 6 bit unsigned range: %ld"),
+                             &out_insnp->expr.X_add_number);
+
                  out_insnp->reloc = BFD_RELOC_CRIS_UNSIGNED_6;
                  continue;
                }
                  out_insnp->reloc = BFD_RELOC_CRIS_UNSIGNED_6;
                  continue;
                }
@@ -1787,7 +1812,7 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
              out_insnp->opcode |= regno << 12;
              out_insnp->reloc = BFD_RELOC_CRIS_SIGNED_8;
              continue;
              out_insnp->opcode |= regno << 12;
              out_insnp->reloc = BFD_RELOC_CRIS_SIGNED_8;
              continue;
-             
+
            case 'O':
              /* A BDAP expression for any size, "expr,R".  */
              if (! cris_get_expression (&s, &prefixp->expr))
            case 'O':
              /* A BDAP expression for any size, "expr,R".  */
              if (! cris_get_expression (&s, &prefixp->expr))
@@ -1823,7 +1848,7 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
                     pseudo yet, so some of this is just unused
                     framework.  */
                  if (out_insnp->spec_reg->warning)
                     pseudo yet, so some of this is just unused
                     framework.  */
                  if (out_insnp->spec_reg->warning)
-                   as_warn (out_insnp->spec_reg->warning);
+                   as_warn ("%s", out_insnp->spec_reg->warning);
                  else if (out_insnp->spec_reg->applicable_version
                           == cris_ver_warning)
                    /* Others have a generic warning.  */
                  else if (out_insnp->spec_reg->applicable_version
                           == cris_ver_warning)
                    /* Others have a generic warning.  */
@@ -2112,8 +2137,8 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
                        if (out_insnp->expr.X_op == O_constant
                            && (out_insnp->expr.X_add_number < -128
                                || out_insnp->expr.X_add_number > 255))
                        if (out_insnp->expr.X_op == O_constant
                            && (out_insnp->expr.X_add_number < -128
                                || out_insnp->expr.X_add_number > 255))
-                         as_bad (_("Immediate value not in 8 bit range: %ld"),
-                                 out_insnp->expr.X_add_number);
+                         cris_bad (_("Immediate value not in 8 bit range: %ld"),
+                                   &out_insnp->expr.X_add_number);
                        /* Fall through.  */
                      case 2:
                        /* FIXME:  We need an indicator in the instruction
                        /* Fall through.  */
                      case 2:
                        /* FIXME:  We need an indicator in the instruction
@@ -2122,8 +2147,8 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
                        if (out_insnp->expr.X_op == O_constant
                            && (out_insnp->expr.X_add_number < -32768
                                || out_insnp->expr.X_add_number > 65535))
                        if (out_insnp->expr.X_op == O_constant
                            && (out_insnp->expr.X_add_number < -32768
                                || out_insnp->expr.X_add_number > 65535))
-                         as_bad (_("Immediate value not in 16 bit range: %ld"),
-                                 out_insnp->expr.X_add_number);
+                         cris_bad (_("Immediate value not in 16 bit range: %ld"),
+                                   &out_insnp->expr.X_add_number);
                        out_insnp->imm_oprnd_size = 2;
                        break;
 
                        out_insnp->imm_oprnd_size = 2;
                        break;
 
@@ -2152,18 +2177,18 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
                          if (instruction->imm_oprnd_size == SIZE_FIELD
                              && (out_insnp->expr.X_add_number < -128
                                  || out_insnp->expr.X_add_number > 255))
                          if (instruction->imm_oprnd_size == SIZE_FIELD
                              && (out_insnp->expr.X_add_number < -128
                                  || out_insnp->expr.X_add_number > 255))
-                           as_bad (_("Immediate value not in 8 bit range: %ld"),
-                                   out_insnp->expr.X_add_number);
+                           cris_bad (_("Immediate value not in 8 bit range: %ld"),
+                                     &out_insnp->expr.X_add_number);
                          else if (instruction->imm_oprnd_size == SIZE_FIELD_SIGNED
                              && (out_insnp->expr.X_add_number < -128
                                  || out_insnp->expr.X_add_number > 127))
                          else if (instruction->imm_oprnd_size == SIZE_FIELD_SIGNED
                              && (out_insnp->expr.X_add_number < -128
                                  || out_insnp->expr.X_add_number > 127))
-                           as_bad (_("Immediate value not in 8 bit signed range: %ld"),
-                                   out_insnp->expr.X_add_number);
+                           cris_bad (_("Immediate value not in 8 bit signed range: %ld"),
+                                     &out_insnp->expr.X_add_number);
                          else if (instruction->imm_oprnd_size == SIZE_FIELD_UNSIGNED
                                   && (out_insnp->expr.X_add_number < 0
                                       || out_insnp->expr.X_add_number > 255))
                          else if (instruction->imm_oprnd_size == SIZE_FIELD_UNSIGNED
                                   && (out_insnp->expr.X_add_number < 0
                                       || out_insnp->expr.X_add_number > 255))
-                           as_bad (_("Immediate value not in 8 bit unsigned range: %ld"),
-                                   out_insnp->expr.X_add_number);
+                           cris_bad (_("Immediate value not in 8 bit unsigned range: %ld"),
+                                     &out_insnp->expr.X_add_number);
                        }
 
                      /* Fall through.  */
                        }
 
                      /* Fall through.  */
@@ -2173,18 +2198,18 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
                          if (instruction->imm_oprnd_size == SIZE_FIELD
                              && (out_insnp->expr.X_add_number < -32768
                                  || out_insnp->expr.X_add_number > 65535))
                          if (instruction->imm_oprnd_size == SIZE_FIELD
                              && (out_insnp->expr.X_add_number < -32768
                                  || out_insnp->expr.X_add_number > 65535))
-                           as_bad (_("Immediate value not in 16 bit range: %ld"),
-                                   out_insnp->expr.X_add_number);
+                           cris_bad (_("Immediate value not in 16 bit range: %ld"),
+                                     &out_insnp->expr.X_add_number);
                          else if (instruction->imm_oprnd_size == SIZE_FIELD_SIGNED
                              && (out_insnp->expr.X_add_number < -32768
                                  || out_insnp->expr.X_add_number > 32767))
                          else if (instruction->imm_oprnd_size == SIZE_FIELD_SIGNED
                              && (out_insnp->expr.X_add_number < -32768
                                  || out_insnp->expr.X_add_number > 32767))
-                           as_bad (_("Immediate value not in 16 bit signed range: %ld"),
-                                   out_insnp->expr.X_add_number);
+                           cris_bad (_("Immediate value not in 16 bit signed range: %ld"),
+                                     &out_insnp->expr.X_add_number);
                          else if (instruction->imm_oprnd_size == SIZE_FIELD_UNSIGNED
                              && (out_insnp->expr.X_add_number < 0
                                  || out_insnp->expr.X_add_number > 65535))
                          else if (instruction->imm_oprnd_size == SIZE_FIELD_UNSIGNED
                              && (out_insnp->expr.X_add_number < 0
                                  || out_insnp->expr.X_add_number > 65535))
-                           as_bad (_("Immediate value not in 16 bit unsigned range: %ld"),
-                                   out_insnp->expr.X_add_number);
+                           cris_bad (_("Immediate value not in 16 bit unsigned range: %ld"),
+                                     &out_insnp->expr.X_add_number);
                        }
                      out_insnp->imm_oprnd_size = 2;
                      break;
                        }
                      out_insnp->imm_oprnd_size = 2;
                      break;
@@ -2208,6 +2233,7 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
                as_bad (out_insnp->reloc == BFD_RELOC_CRIS_32_GD
                        || out_insnp->reloc == BFD_RELOC_CRIS_32_TPREL
                        || out_insnp->reloc == BFD_RELOC_CRIS_16_TPREL
                as_bad (out_insnp->reloc == BFD_RELOC_CRIS_32_GD
                        || out_insnp->reloc == BFD_RELOC_CRIS_32_TPREL
                        || out_insnp->reloc == BFD_RELOC_CRIS_16_TPREL
+                       || out_insnp->reloc == BFD_RELOC_CRIS_32_IE
                        ? _("TLS relocation size does not match operand size")
                        : _("PIC relocation size does not match operand size"));
            }
                        ? _("TLS relocation size does not match operand size")
                        : _("PIC relocation size does not match operand size"));
            }
@@ -3045,6 +3071,10 @@ get_3op_or_dip_prefix_op (char **cPP, struct cris_prefix *prefixp)
       prefixp->kind = PREFIX_DIP;
       prefixp->opcode = DIP_OPCODE | (AUTOINCR_BIT << 8) | REG_PC;
       prefixp->reloc = BFD_RELOC_32;
       prefixp->kind = PREFIX_DIP;
       prefixp->opcode = DIP_OPCODE | (AUTOINCR_BIT << 8) | REG_PC;
       prefixp->reloc = BFD_RELOC_32;
+
+      /* For :GD and :IE, it makes sense to have TLS specifiers here.  */
+      if ((pic || tls) && **cPP == RELOC_SUFFIX_CHAR)
+       cris_get_reloc_suffix (cPP, &prefixp->reloc, &prefixp->expr);
     }
   else
     /* Neither '[' nor register nor expression.  We lose.  */
     }
   else
     /* Neither '[' nor register nor expression.  We lose.  */
@@ -3075,7 +3105,6 @@ static int
 cris_get_expression (char **cPP, expressionS *exprP)
 {
   char *saved_input_line_pointer;
 cris_get_expression (char **cPP, expressionS *exprP)
 {
   char *saved_input_line_pointer;
-  segT exp;
 
   /* The "expression" function expects to find an expression at the
      global variable input_line_pointer, so we have to save it to give
 
   /* The "expression" function expects to find an expression at the
      global variable input_line_pointer, so we have to save it to give
@@ -3094,7 +3123,7 @@ cris_get_expression (char **cPP, expressionS *exprP)
       return 0;
     }
 
       return 0;
     }
 
-  exp = expression (exprP);
+  expression (exprP);
   if (exprP->X_op == O_illegal || exprP->X_op == O_absent)
     {
       input_line_pointer = saved_input_line_pointer;
   if (exprP->X_op == O_illegal || exprP->X_op == O_absent)
     {
       input_line_pointer = saved_input_line_pointer;
@@ -3489,6 +3518,7 @@ cris_get_reloc_suffix (char **cPP, bfd_reloc_code_real_type *relocp,
       TLSMAP ("GD", BFD_RELOC_CRIS_32_GD),
       PICTLSMAP ("DTPREL16", BFD_RELOC_CRIS_16_DTPREL),
       PICTLSMAP ("DTPREL", BFD_RELOC_CRIS_32_DTPREL),
       TLSMAP ("GD", BFD_RELOC_CRIS_32_GD),
       PICTLSMAP ("DTPREL16", BFD_RELOC_CRIS_16_DTPREL),
       PICTLSMAP ("DTPREL", BFD_RELOC_CRIS_32_DTPREL),
+      TLSMAP ("IE", BFD_RELOC_CRIS_32_IE),
       PICTLSMAP ("TPOFFGOT16", BFD_RELOC_CRIS_16_GOT_TPREL),
       PICTLSMAP ("TPOFFGOT", BFD_RELOC_CRIS_32_GOT_TPREL),
       TLSMAP ("TPOFF16", BFD_RELOC_CRIS_16_TPREL),
       PICTLSMAP ("TPOFFGOT16", BFD_RELOC_CRIS_16_GOT_TPREL),
       PICTLSMAP ("TPOFFGOT", BFD_RELOC_CRIS_32_GOT_TPREL),
       TLSMAP ("TPOFF16", BFD_RELOC_CRIS_16_TPREL),
@@ -3561,7 +3591,7 @@ cris_get_reloc_suffix (char **cPP, bfd_reloc_code_real_type *relocp,
    code as assembly code, but if they do, they should be able enough to
    find out the correct bit patterns and use them.  */
 
    code as assembly code, but if they do, they should be able enough to
    find out the correct bit patterns and use them.  */
 
-char *
+const char *
 md_atof (int type ATTRIBUTE_UNUSED, char *litp ATTRIBUTE_UNUSED,
         int *sizep ATTRIBUTE_UNUSED)
 {
 md_atof (int type ATTRIBUTE_UNUSED, char *litp ATTRIBUTE_UNUSED,
         int *sizep ATTRIBUTE_UNUSED)
 {
@@ -3613,10 +3643,12 @@ cris_number_to_imm (char *bufp, long val, int n, fixS *fixP, segT seg)
        ;
       }
 
        ;
       }
 
-  /* Only do this for old-arch binaries.  */
+  /* Only use the computed value for old-arch binaries.  For all
+     others, where we're going to output a relocation, put 0 in the
+     code.  */
   if (cris_arch != arch_cris_any_v0_v10
       && (fixP->fx_addsy != NULL || fixP->fx_pcrel))
   if (cris_arch != arch_cris_any_v0_v10
       && (fixP->fx_addsy != NULL || fixP->fx_pcrel))
-    return;
+    val = 0;
 
   switch (fixP->fx_r_type)
     {
 
   switch (fixP->fx_r_type)
     {
@@ -3625,31 +3657,39 @@ cris_number_to_imm (char *bufp, long val, int n, fixS *fixP, segT seg)
         regression tests on the object file contents.  FIXME:  Seems
         uninteresting now that we have a test suite.  */
 
         regression tests on the object file contents.  FIXME:  Seems
         uninteresting now that we have a test suite.  */
 
-    case BFD_RELOC_CRIS_16_GOT:
-    case BFD_RELOC_CRIS_32_GOT:
-    case BFD_RELOC_CRIS_32_GOTREL:
-    case BFD_RELOC_CRIS_16_GOTPLT:
-    case BFD_RELOC_CRIS_32_GOTPLT:
-    case BFD_RELOC_CRIS_32_PLT_GOTREL:
-    case BFD_RELOC_CRIS_32_PLT_PCREL:
     case BFD_RELOC_CRIS_32_GOT_GD:
     case BFD_RELOC_CRIS_16_GOT_GD:
     case BFD_RELOC_CRIS_32_GD:
     case BFD_RELOC_CRIS_32_GOT_GD:
     case BFD_RELOC_CRIS_16_GOT_GD:
     case BFD_RELOC_CRIS_32_GD:
+    case BFD_RELOC_CRIS_32_IE:
     case BFD_RELOC_CRIS_32_DTPREL:
     case BFD_RELOC_CRIS_16_DTPREL:
     case BFD_RELOC_CRIS_32_GOT_TPREL:
     case BFD_RELOC_CRIS_16_GOT_TPREL:
     case BFD_RELOC_CRIS_32_TPREL:
     case BFD_RELOC_CRIS_16_TPREL:
     case BFD_RELOC_CRIS_32_DTPREL:
     case BFD_RELOC_CRIS_16_DTPREL:
     case BFD_RELOC_CRIS_32_GOT_TPREL:
     case BFD_RELOC_CRIS_16_GOT_TPREL:
     case BFD_RELOC_CRIS_32_TPREL:
     case BFD_RELOC_CRIS_16_TPREL:
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+      if (IS_ELF && fixP->fx_addsy != NULL)
+       S_SET_THREAD_LOCAL (fixP->fx_addsy);
+#endif
+      /* Fall through.  */
+
+    case BFD_RELOC_CRIS_16_GOT:
+    case BFD_RELOC_CRIS_32_GOT:
+    case BFD_RELOC_CRIS_32_GOTREL:
+    case BFD_RELOC_CRIS_16_GOTPLT:
+    case BFD_RELOC_CRIS_32_GOTPLT:
+    case BFD_RELOC_CRIS_32_PLT_GOTREL:
+    case BFD_RELOC_CRIS_32_PLT_PCREL:
       /* We don't want to put in any kind of non-zero bits in the data
         being relocated for these.  */
       /* We don't want to put in any kind of non-zero bits in the data
         being relocated for these.  */
+      md_number_to_chars (bufp, 0, n);
       break;
 
     case BFD_RELOC_32_PCREL:
       break;
 
     case BFD_RELOC_32_PCREL:
-      /* If this one isn't fully resolved, we don't want to put anything
+      /* If this one isn't fully resolved, we don't want to put non-zero
         in the object.  */
       if (fixP->fx_addsy != NULL || fixP->fx_pcrel)
         in the object.  */
       if (fixP->fx_addsy != NULL || fixP->fx_pcrel)
-       break;
+       val = 0;
 
       /* Fall through.  */
     case BFD_RELOC_32:
 
       /* Fall through.  */
     case BFD_RELOC_32:
@@ -3671,38 +3711,30 @@ cris_number_to_imm (char *bufp, long val, int n, fixS *fixP, segT seg)
       if (val > 0xffff || val < -32768)
        as_bad_where (fixP->fx_file, fixP->fx_line,
                      _("Value not in 16 bit range: %ld"), val);
       if (val > 0xffff || val < -32768)
        as_bad_where (fixP->fx_file, fixP->fx_line,
                      _("Value not in 16 bit range: %ld"), val);
-      if (! fixP->fx_addsy)
-       {
-         bufp[1] = (val >> 8) & 0xFF;
-         bufp[0] = val & 0xFF;
-       }
+      bufp[1] = (val >> 8) & 0xFF;
+      bufp[0] = val & 0xFF;
       break;
 
     case BFD_RELOC_CRIS_SIGNED_16:
       if (val > 32767 || val < -32768)
        as_bad_where (fixP->fx_file, fixP->fx_line,
                      _("Value not in 16 bit signed range: %ld"), val);
       break;
 
     case BFD_RELOC_CRIS_SIGNED_16:
       if (val > 32767 || val < -32768)
        as_bad_where (fixP->fx_file, fixP->fx_line,
                      _("Value not in 16 bit signed range: %ld"), val);
-      if (! fixP->fx_addsy)
-       {
-         bufp[1] = (val >> 8) & 0xFF;
-         bufp[0] = val & 0xFF;
-       }
+      bufp[1] = (val >> 8) & 0xFF;
+      bufp[0] = val & 0xFF;
       break;
 
     case BFD_RELOC_8:
     case BFD_RELOC_8_PCREL:
       if (val > 255 || val < -128)
        as_bad_where (fixP->fx_file, fixP->fx_line, _("Value not in 8 bit range: %ld"), val);
       break;
 
     case BFD_RELOC_8:
     case BFD_RELOC_8_PCREL:
       if (val > 255 || val < -128)
        as_bad_where (fixP->fx_file, fixP->fx_line, _("Value not in 8 bit range: %ld"), val);
-      if (! fixP->fx_addsy)
-       bufp[0] = val & 0xFF;
+      bufp[0] = val & 0xFF;
       break;
 
     case BFD_RELOC_CRIS_SIGNED_8:
       if (val > 127 || val < -128)
        as_bad_where (fixP->fx_file, fixP->fx_line,
                      _("Value not in 8 bit signed range: %ld"), val);
       break;
 
     case BFD_RELOC_CRIS_SIGNED_8:
       if (val > 127 || val < -128)
        as_bad_where (fixP->fx_file, fixP->fx_line,
                      _("Value not in 8 bit signed range: %ld"), val);
-      if (! fixP->fx_addsy)
-       bufp[0] = val & 0xFF;
+      bufp[0] = val & 0xFF;
       break;
 
     case BFD_RELOC_CRIS_LAPCQ_OFFSET:
       break;
 
     case BFD_RELOC_CRIS_LAPCQ_OFFSET:
@@ -3712,37 +3744,32 @@ cris_number_to_imm (char *bufp, long val, int n, fixS *fixP, segT seg)
       if (val > 15 || val < 0)
        as_bad_where (fixP->fx_file, fixP->fx_line,
                      _("Value not in 4 bit unsigned range: %ld"), val);
       if (val > 15 || val < 0)
        as_bad_where (fixP->fx_file, fixP->fx_line,
                      _("Value not in 4 bit unsigned range: %ld"), val);
-      if (! fixP->fx_addsy)
-       bufp[0] |= val & 0x0F;
+      bufp[0] |= val & 0x0F;
       break;
 
     case BFD_RELOC_CRIS_UNSIGNED_5:
       if (val > 31 || val < 0)
        as_bad_where (fixP->fx_file, fixP->fx_line,
                      _("Value not in 5 bit unsigned range: %ld"), val);
       break;
 
     case BFD_RELOC_CRIS_UNSIGNED_5:
       if (val > 31 || val < 0)
        as_bad_where (fixP->fx_file, fixP->fx_line,
                      _("Value not in 5 bit unsigned range: %ld"), val);
-      if (! fixP->fx_addsy)
-       bufp[0] |= val & 0x1F;
+      bufp[0] |= val & 0x1F;
       break;
 
     case BFD_RELOC_CRIS_SIGNED_6:
       if (val > 31 || val < -32)
        as_bad_where (fixP->fx_file, fixP->fx_line,
                      _("Value not in 6 bit range: %ld"), val);
       break;
 
     case BFD_RELOC_CRIS_SIGNED_6:
       if (val > 31 || val < -32)
        as_bad_where (fixP->fx_file, fixP->fx_line,
                      _("Value not in 6 bit range: %ld"), val);
-      if (! fixP->fx_addsy)
-       bufp[0] |= val & 0x3F;
+      bufp[0] |= val & 0x3F;
       break;
 
     case BFD_RELOC_CRIS_UNSIGNED_6:
       if (val > 63 || val < 0)
        as_bad_where (fixP->fx_file, fixP->fx_line,
                      _("Value not in 6 bit unsigned range: %ld"), val);
       break;
 
     case BFD_RELOC_CRIS_UNSIGNED_6:
       if (val > 63 || val < 0)
        as_bad_where (fixP->fx_file, fixP->fx_line,
                      _("Value not in 6 bit unsigned range: %ld"), val);
-      if (! fixP->fx_addsy)
-       bufp[0] |= val & 0x3F;
+      bufp[0] |= val & 0x3F;
       break;
 
     case BFD_RELOC_CRIS_BDISP8:
       break;
 
     case BFD_RELOC_CRIS_BDISP8:
-      if (! fixP->fx_addsy)
-       bufp[0] = branch_disp (val);
+      bufp[0] = branch_disp (val);
       break;
 
     case BFD_RELOC_NONE:
       break;
 
     case BFD_RELOC_NONE:
@@ -3775,7 +3802,7 @@ cris_number_to_imm (char *bufp, long val, int n, fixS *fixP, segT seg)
    GAS does not understand.  */
 
 int
    GAS does not understand.  */
 
 int
-md_parse_option (int arg, char *argp ATTRIBUTE_UNUSED)
+md_parse_option (int arg, const char *argp ATTRIBUTE_UNUSED)
 {
   switch (arg)
     {
 {
   switch (arg)
     {
@@ -3804,6 +3831,8 @@ md_parse_option (int arg, char *argp ATTRIBUTE_UNUSED)
       break;
 
     case OPTION_PIC:
       break;
 
     case OPTION_PIC:
+      if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
+       as_bad (_("--pic is invalid for this object format"));
       pic = TRUE;
       if (cris_arch != arch_crisv32)
        md_long_jump_size = cris_any_v0_v10_long_jump_size_pic;
       pic = TRUE;
       if (cris_arch != arch_crisv32)
        md_long_jump_size = cris_any_v0_v10_long_jump_size_pic;
@@ -3813,7 +3842,7 @@ md_parse_option (int arg, char *argp ATTRIBUTE_UNUSED)
 
     case OPTION_ARCH:
       {
 
     case OPTION_ARCH:
       {
-       char *str = argp;
+       const char *str = argp;
        enum cris_archs argarch = cris_arch_from_string (&str);
 
        if (argarch == arch_cris_unknown)
        enum cris_archs argarch = cris_arch_from_string (&str);
 
        if (argarch == arch_cris_unknown)
@@ -3915,6 +3944,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
     case BFD_RELOC_CRIS_32_GOT_GD:
     case BFD_RELOC_CRIS_16_GOT_GD:
     case BFD_RELOC_CRIS_32_GD:
     case BFD_RELOC_CRIS_32_GOT_GD:
     case BFD_RELOC_CRIS_16_GOT_GD:
     case BFD_RELOC_CRIS_32_GD:
+    case BFD_RELOC_CRIS_32_IE:
     case BFD_RELOC_CRIS_32_DTPREL:
     case BFD_RELOC_CRIS_16_DTPREL:
     case BFD_RELOC_CRIS_32_GOT_TPREL:
     case BFD_RELOC_CRIS_32_DTPREL:
     case BFD_RELOC_CRIS_16_DTPREL:
     case BFD_RELOC_CRIS_32_GOT_TPREL:
@@ -3930,7 +3960,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
     }
 
   relP = (arelent *) xmalloc (sizeof (arelent));
     }
 
   relP = (arelent *) xmalloc (sizeof (arelent));
-  assert (relP != 0);
+  gas_assert (relP != 0);
   relP->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
   *relP->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
   relP->address = fixP->fx_frag->fr_address + fixP->fx_where;
   relP->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
   *relP->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
   relP->address = fixP->fx_frag->fr_address + fixP->fx_where;
@@ -4000,8 +4030,10 @@ md_show_usage (FILE *stream)
           _("  --no-underscore         User symbols do not have any prefix.\n"));
   fprintf (stream, "%s",
           _("                          Registers will require a `$'-prefix.\n"));
           _("  --no-underscore         User symbols do not have any prefix.\n"));
   fprintf (stream, "%s",
           _("                          Registers will require a `$'-prefix.\n"));
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
   fprintf (stream, "%s",
           _("  --pic                   Enable generation of position-independent code.\n"));
   fprintf (stream, "%s",
           _("  --pic                   Enable generation of position-independent code.\n"));
+#endif
   fprintf (stream, "%s",
           _("  --march=<arch>          Generate code for <arch>.  Valid choices for <arch>\n\
                                are v0_v10, v10, v32 and common_v10_v32.\n"));
   fprintf (stream, "%s",
           _("  --march=<arch>          Generate code for <arch>.  Valid choices for <arch>\n\
                                are v0_v10, v10, v32 and common_v10_v32.\n"));
@@ -4209,13 +4241,37 @@ s_cris_loc (int dummy)
     dwarf2_directive_loc (dummy);
 }
 
     dwarf2_directive_loc (dummy);
 }
 
+/* Worker for .dtpoffd: generate a R_CRIS_32_DTPREL reloc, as for
+   expr:DTPREL but for use in debug info.  */
+
+static void
+s_cris_dtpoff (int bytes)
+{
+  expressionS ex;
+  char *p;
+
+  if (bytes != 4)
+    as_fatal (_("internal inconsistency problem: %s called for %d bytes"),
+             __FUNCTION__, bytes);
+
+  expression (&ex);
+
+  p = frag_more (bytes);
+  md_number_to_chars (p, 0, bytes);
+  fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, FALSE,
+              BFD_RELOC_CRIS_32_DTPREL);
+
+  demand_empty_rest_of_line ();
+}
+
+
 /* Translate a <arch> string (as common to --march=<arch> and .arch <arch>)
    into an enum.  If the string *STR is recognized, *STR is updated to point
    to the end of the string.  If the string is not recognized,
    arch_cris_unknown is returned.  */
 
 static enum cris_archs
 /* Translate a <arch> string (as common to --march=<arch> and .arch <arch>)
    into an enum.  If the string *STR is recognized, *STR is updated to point
    to the end of the string.  If the string is not recognized,
    arch_cris_unknown is returned.  */
 
 static enum cris_archs
-cris_arch_from_string (char **str)
+cris_arch_from_string (const char **str)
 {
   static const struct cris_arch_struct
   {
 {
   static const struct cris_arch_struct
   {
@@ -4271,7 +4327,7 @@ cris_insn_ver_valid_for_arch (enum cris_insn_version_usage iver,
         || iver == cris_ver_v8_10
         || iver == cris_ver_v10
         || iver == cris_ver_v10p);
         || iver == cris_ver_v8_10
         || iver == cris_ver_v10
         || iver == cris_ver_v10p);
-      
+
     case arch_crisv32:
       return
        (iver == cris_ver_version_all
     case arch_crisv32:
       return
        (iver == cris_ver_version_all
@@ -4342,7 +4398,7 @@ s_cris_arch (int dummy ATTRIBUTE_UNUSED)
      would be more useful than confusing, implementation-wise and
      user-wise.  */
 
      would be more useful than confusing, implementation-wise and
      user-wise.  */
 
-  char *str = input_line_pointer;
+  const char *str = input_line_pointer;
   enum cris_archs arch = cris_arch_from_string (&str);
 
   if (arch == arch_cris_unknown)
   enum cris_archs arch = cris_arch_from_string (&str);
 
   if (arch == arch_cris_unknown)
@@ -4358,7 +4414,7 @@ s_cris_arch (int dummy ATTRIBUTE_UNUSED)
   else if (arch != cris_arch)
     as_bad (_(".arch <arch> requires a matching --march=... option"));
 
   else if (arch != cris_arch)
     as_bad (_(".arch <arch> requires a matching --march=... option"));
 
-  input_line_pointer = str;
+  input_line_pointer = (char *) str;
   demand_empty_rest_of_line ();
   return;
 }
   demand_empty_rest_of_line ();
   return;
 }
This page took 0.034027 seconds and 4 git commands to generate.