[PATCH, BINUTILS, AARCH64, 1/9] Add -march=armv8.5-a and related internal feature...
[external/binutils.git] / gas / config / tc-mips.c
index e4351f7..c9fc6c6 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-mips.c -- assemble code for a MIPS chip.
-   Copyright (C) 1993-2017 Free Software Foundation, Inc.
+   Copyright (C) 1993-2018 Free Software Foundation, Inc.
    Contributed by the OSF and Ralph Campbell.
    Written by Keith Knowles and Ralph Campbell, working independently.
    Modified for ECOFF and R4000 support by Ian Lance Taylor of Cygnus
@@ -422,7 +422,9 @@ static int mips_32bitmode = 0;
     || (ISA) == ISA_MIPS64R5           \
     || (ISA) == ISA_MIPS64R6           \
     || (CPU) == CPU_R5900)             \
-   && (CPU) != CPU_LOONGSON_3A)
+   && ((CPU) != CPU_GS464              \
+    || (CPU) != CPU_GS464E             \
+    || (CPU) != CPU_GS264E))
 
 /* Return true if ISA supports move to/from high part of a 64-bit
    floating-point register. */
@@ -1460,7 +1462,8 @@ enum options
     OPTION_NO_MCU,
     OPTION_MIPS16E2,
     OPTION_NO_MIPS16E2,
-    OPTION_COMPAT_ARCH_BASE,
+    OPTION_CRC,
+    OPTION_NO_CRC,
     OPTION_M4650,
     OPTION_NO_M4650,
     OPTION_M4010,
@@ -1526,6 +1529,16 @@ enum options
     OPTION_NAN,
     OPTION_ODD_SPREG,
     OPTION_NO_ODD_SPREG,
+    OPTION_GINV,
+    OPTION_NO_GINV,
+    OPTION_LOONGSON_MMI,
+    OPTION_NO_LOONGSON_MMI,
+    OPTION_LOONGSON_CAM,
+    OPTION_NO_LOONGSON_CAM,
+    OPTION_LOONGSON_EXT,
+    OPTION_NO_LOONGSON_EXT,
+    OPTION_LOONGSON_EXT2,
+    OPTION_NO_LOONGSON_EXT2,
     OPTION_END_OF_ENUM
   };
 
@@ -1582,6 +1595,18 @@ struct option md_longopts[] =
   {"mno-xpa", no_argument, NULL, OPTION_NO_XPA},
   {"mmips16e2", no_argument, NULL, OPTION_MIPS16E2},
   {"mno-mips16e2", no_argument, NULL, OPTION_NO_MIPS16E2},
+  {"mcrc", no_argument, NULL, OPTION_CRC},
+  {"mno-crc", no_argument, NULL, OPTION_NO_CRC},
+  {"mginv", no_argument, NULL, OPTION_GINV},
+  {"mno-ginv", no_argument, NULL, OPTION_NO_GINV},
+  {"mloongson-mmi", no_argument, NULL, OPTION_LOONGSON_MMI},
+  {"mno-loongson-mmi", no_argument, NULL, OPTION_NO_LOONGSON_MMI},
+  {"mloongson-cam", no_argument, NULL, OPTION_LOONGSON_CAM},
+  {"mno-loongson-cam", no_argument, NULL, OPTION_NO_LOONGSON_CAM},
+  {"mloongson-ext", no_argument, NULL, OPTION_LOONGSON_EXT},
+  {"mno-loongson-ext", no_argument, NULL, OPTION_NO_LOONGSON_EXT},
+  {"mloongson-ext2", no_argument, NULL, OPTION_LOONGSON_EXT2},
+  {"mno-loongson-ext2", no_argument, NULL, OPTION_NO_LOONGSON_EXT2},
 
   /* Old-style architecture options.  Don't add more of these.  */
   {"m4650", no_argument, NULL, OPTION_M4650},
@@ -1769,6 +1794,36 @@ static const struct mips_ase mips_ases[] = {
     OPTION_MIPS16E2, OPTION_NO_MIPS16E2,
     2,  2, -1, -1,
     6 },
+
+  { "crc", ASE_CRC, ASE_CRC64,
+    OPTION_CRC, OPTION_NO_CRC,
+    6,  6, -1, -1,
+    -1 },
+
+  { "ginv", ASE_GINV, 0,
+    OPTION_GINV, OPTION_NO_GINV,
+    6,  6, 6, 6,
+    -1 },
+
+  { "loongson-mmi", ASE_LOONGSON_MMI, 0,
+    OPTION_LOONGSON_MMI, OPTION_NO_LOONGSON_MMI,
+    0, 0, -1, -1,
+    -1 },
+
+  { "loongson-cam", ASE_LOONGSON_CAM, 0,
+    OPTION_LOONGSON_CAM, OPTION_NO_LOONGSON_CAM,
+    0, 0, -1, -1,
+    -1 },
+
+  { "loongson-ext", ASE_LOONGSON_EXT, 0,
+    OPTION_LOONGSON_EXT, OPTION_NO_LOONGSON_EXT,
+    0, 0, -1, -1,
+    -1 },
+
+  { "loongson-ext2", ASE_LOONGSON_EXT | ASE_LOONGSON_EXT2, 0,
+    OPTION_LOONGSON_EXT2, OPTION_NO_LOONGSON_EXT2,
+    0, 0, -1, -1,
+    -1 },
 };
 
 /* The set of ASEs that require -mfp64.  */
@@ -1776,7 +1831,8 @@ static const struct mips_ase mips_ases[] = {
 
 /* Groups of ASE_* flags that represent different revisions of an ASE.  */
 static const unsigned int mips_ase_groups[] = {
-  ASE_DSP | ASE_DSPR2 | ASE_DSPR3
+  ASE_DSP | ASE_DSPR2 | ASE_DSPR3, 
+  ASE_LOONGSON_EXT | ASE_LOONGSON_EXT2 
 };
 \f
 /* Pseudo-op table.
@@ -8834,7 +8890,26 @@ macro_build (expressionS *ep, const char *name, const char *fmt, ...)
                      || *r == BFD_RELOC_MIPS_HIGHER
                      || *r == BFD_RELOC_HI16_S
                      || *r == BFD_RELOC_LO16
-                     || *r == BFD_RELOC_MIPS_GOT_OFST);
+                     || *r == BFD_RELOC_MIPS_GOT_OFST
+                     || (mips_opts.micromips
+                         && (*r == BFD_RELOC_16
+                             || *r == BFD_RELOC_MIPS_GOT16
+                             || *r == BFD_RELOC_MIPS_CALL16
+                             || *r == BFD_RELOC_MIPS_GOT_HI16
+                             || *r == BFD_RELOC_MIPS_GOT_LO16
+                             || *r == BFD_RELOC_MIPS_CALL_HI16
+                             || *r == BFD_RELOC_MIPS_CALL_LO16
+                             || *r == BFD_RELOC_MIPS_SUB
+                             || *r == BFD_RELOC_MIPS_GOT_PAGE
+                             || *r == BFD_RELOC_MIPS_HIGHEST
+                             || *r == BFD_RELOC_MIPS_GOT_DISP
+                             || *r == BFD_RELOC_MIPS_TLS_GD
+                             || *r == BFD_RELOC_MIPS_TLS_LDM
+                             || *r == BFD_RELOC_MIPS_TLS_DTPREL_HI16
+                             || *r == BFD_RELOC_MIPS_TLS_DTPREL_LO16
+                             || *r == BFD_RELOC_MIPS_TLS_GOTTPREL
+                             || *r == BFD_RELOC_MIPS_TLS_TPREL_HI16
+                             || *r == BFD_RELOC_MIPS_TLS_TPREL_LO16)));
          break;
 
        case 'o':
@@ -13956,7 +14031,7 @@ mips_lookup_insn (struct hash_control *hash, const char *start,
        suffix = 0;
       if (suffix)
        {
-         memcpy (name + opend - 2, name + opend, length - opend + 1);
+         memmove (name + opend - 2, name + opend, length - opend + 1);
          insn = (struct mips_opcode *) hash_find (hash, name);
          if (insn)
            {
@@ -18977,6 +19052,18 @@ mips_convert_ase_flags (int ase)
     ext_ases |= AFL_ASE_XPA;
   if (ase & ASE_MIPS16E2)
     ext_ases |= file_ase_mips16 ? AFL_ASE_MIPS16E2 : 0;
+  if (ase & ASE_CRC)
+    ext_ases |= AFL_ASE_CRC;
+  if (ase & ASE_GINV)
+    ext_ases |= AFL_ASE_GINV;
+  if (ase & ASE_LOONGSON_MMI)
+    ext_ases |= AFL_ASE_LOONGSON_MMI;
+  if (ase & ASE_LOONGSON_CAM)
+    ext_ases |= AFL_ASE_LOONGSON_CAM;
+  if (ase & ASE_LOONGSON_EXT)
+    ext_ases |= AFL_ASE_LOONGSON_EXT;
+  if (ase & ASE_LOONGSON_EXT2)
+    ext_ases |= AFL_ASE_LOONGSON_EXT2;
 
   return ext_ases;
 }
@@ -19140,10 +19227,8 @@ mips_elf_final_processing (void)
       else
        elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_EABI32;
     }
-  else if (mips_abi == N32_ABI)
-    elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ABI2;
 
-  /* Nothing to do for N64_ABI.  */
+  /* Nothing to do for N32_ABI or N64_ABI.  */
 
   if (mips_32bitmode)
     elf_elfheader (stdoutput)->e_flags |= EF_MIPS_32BITMODE;
@@ -19327,7 +19412,7 @@ s_mips_file (int x ATTRIBUTE_UNUSED)
     {
       char *filename;
 
-      filename = dwarf2_directive_file (0);
+      filename = dwarf2_directive_filename ();
 
       /* Versions of GCC up to 3.1 start files with a ".file"
         directive even for stabs output.  Make sure that this
@@ -19625,7 +19710,7 @@ static const struct mips_cpu_info mips_cpu_info_table[] =
   { "r5900",          0, 0,                    ISA_MIPS3,    CPU_R5900 },
   /* ST Microelectronics Loongson 2E and 2F cores */
   { "loongson2e",     0, 0,                    ISA_MIPS3,    CPU_LOONGSON_2E },
-  { "loongson2f",     0, 0,                    ISA_MIPS3,    CPU_LOONGSON_2F },
+  { "loongson2f",     0, ASE_LOONGSON_MMI,     ISA_MIPS3,    CPU_LOONGSON_2F },
 
   /* MIPS IV */
   { "r8000",          0, 0,                    ISA_MIPS4,    CPU_R8000 },
@@ -19724,9 +19809,17 @@ static const struct mips_cpu_info mips_cpu_info_table[] =
   /* Broadcom SB-1A CPU core */
   { "sb1a",           0, ASE_MIPS3D | ASE_MDMX,        ISA_MIPS64,   CPU_SB1 },
 
-  { "loongson3a",     0, 0,                    ISA_MIPS64R2, CPU_LOONGSON_3A },
-
   /* MIPS 64 Release 2 */
+  /* Loongson CPU core */
+  /* -march=loongson3a is an alias of -march=gs464 for compatibility */
+  { "loongson3a",     0, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT,
+     ISA_MIPS64R2,     CPU_GS464 },
+  { "gs464",          0, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT,
+     ISA_MIPS64R2,     CPU_GS464 },
+  { "gs464e",         0, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT
+     | ASE_LOONGSON_EXT2,      ISA_MIPS64R2,   CPU_GS464E },
+  { "gs264e",         0, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT
+     | ASE_LOONGSON_EXT2 | ASE_MSA | ASE_MSA64,        ISA_MIPS64R2,   CPU_GS264E },
 
   /* Cavium Networks Octeon CPU core */
   { "octeon",        0, 0,                     ISA_MIPS64R2, CPU_OCTEON },
@@ -19960,6 +20053,9 @@ MIPS options:\n\
 -mips16                        generate mips16 instructions\n\
 -no-mips16             do not generate mips16 instructions\n"));
   fprintf (stream, _("\
+-mmips16e2             generate MIPS16e2 instructions\n\
+-mno-mips16e2          do not generate MIPS16e2 instructions\n"));
+  fprintf (stream, _("\
 -mmicromips            generate microMIPS instructions\n\
 -mno-micromips         do not generate microMIPS instructions\n"));
   fprintf (stream, _("\
@@ -19990,6 +20086,24 @@ MIPS options:\n\
 -mvirt                 generate Virtualization instructions\n\
 -mno-virt              do not generate Virtualization instructions\n"));
   fprintf (stream, _("\
+-mcrc                  generate CRC instructions\n\
+-mno-crc               do not generate CRC instructions\n"));
+  fprintf (stream, _("\
+-mginv                 generate Global INValidate (GINV) instructions\n\
+-mno-ginv              do not generate Global INValidate instructions\n"));
+  fprintf (stream, _("\
+-mloongson-mmi         generate Loongson MultiMedia extensions Instructions (MMI) instructions\n\
+-mno-loongson-mmi      do not generate Loongson MultiMedia extensions Instructions\n"));
+  fprintf (stream, _("\
+-mloongson-cam         generate Loongson Content Address Memory (CAM) instructions\n\
+-mno-loongson-cam      do not generate Loongson Content Address Memory Instructions\n"));
+  fprintf (stream, _("\
+-mloongson-ext         generate Loongson EXTensions (EXT) instructions\n\
+-mno-loongson-ext      do not generate Loongson EXTensions Instructions\n"));
+  fprintf (stream, _("\
+-mloongson-ext2                generate Loongson EXTensions R2 (EXT2) instructions\n\
+-mno-loongson-ext2     do not generate Loongson EXTensions R2 Instructions\n"));
+  fprintf (stream, _("\
 -minsn32               only generate 32-bit microMIPS instructions\n\
 -mno-insn32            generate all microMIPS instructions\n"));
   fprintf (stream, _("\
@@ -20002,8 +20116,9 @@ MIPS options:\n\
 -mgp32                 use 32-bit GPRs, regardless of the chosen ISA\n\
 -mfp32                 use 32-bit FPRs, regardless of the chosen ISA\n\
 -msym32                        assume all symbols have 32-bit values\n\
--O0                    remove unneeded NOPs, do not swap branches\n\
--O                     remove unneeded NOPs and swap branches\n\
+-O0                    do not remove unneeded NOPs, do not swap branches\n\
+-O, -O1                        remove unneeded NOPs, do not swap branches\n\
+-O2                    remove unneeded NOPs and swap branches\n\
 --trap, --no-break     trap exception on div by 0 and mult overflow\n\
 --break, --no-trap     break exception on div by 0 and mult overflow\n"));
   fprintf (stream, _("\
@@ -20046,9 +20161,14 @@ MIPS options:\n\
   fputc ('\n', stream);
 
   fprintf (stream, _("\
--32                    create o32 ABI object file (default)\n\
--n32                   create n32 ABI object file\n\
--64                    create 64 ABI object file\n"));
+-32                    create o32 ABI object file%s\n"),
+          MIPS_DEFAULT_ABI == O32_ABI ? _(" (default)") : "");
+  fprintf (stream, _("\
+-n32                   create n32 ABI object file%s\n"),
+          MIPS_DEFAULT_ABI == N32_ABI ? _(" (default)") : "");
+  fprintf (stream, _("\
+-64                    create 64 ABI object file%s\n"),
+          MIPS_DEFAULT_ABI == N64_ABI ? _(" (default)") : "");
 }
 
 #ifdef TE_IRIX