binutils/ChangeLog:
authorAndrew Pinski <apinski@cavium.com>
Fri, 10 May 2013 01:08:48 +0000 (01:08 +0000)
committerAndrew Pinski <apinski@cavium.com>
Fri, 10 May 2013 01:08:48 +0000 (01:08 +0000)
* doc/binutils.texi: Document -Mvirt disassembler option.

gas/ChangeLog:
* config/tc-mips.c (struct mips_set_options): New ase_virt field.
(mips_opts): Update for the new field.
(file_ase_virt): New variable.
(ISA_SUPPORTS_VIRT_ASE): New macro.
(ISA_SUPPORTS_VIRT64_ASE): New macro.
(MIPS_CPU_ASE_VIRT): New define.
(is_opcode_valid): Handle ase_virt.
(macro_build): Handle "+J".
(validate_mips_insn): Likewise.
(mips_ip): Likewise.
(enum options): Add OPTION_VIRT and OPTION_NO_VIRT.
(md_longopts): Add mvirt and mnovirt
(md_parse_option): Handle OPTION_VIRT and OPTION_NO_VIRT.
(mips_after_parse_args): Handle ase_virt field.
(s_mipsset): Handle "virt" and "novirt".
(mips_elf_final_processing): Add a comment about virt ASE might need a new flag.
(md_show_usage): Print out the usage of -mvirt and mno-virt options.
* doc/c-mips.texi: Document -mvirt and -mno-virt.
Document ".set virt" and ".set novirt".

gas/testsuite/ChangeLog:
* gas/mips/mips.exp: Run virt and virt64 testcases.
* gas/mips/virt.d: New file.
* gas/mips/virt.s: New file.
* gas/mips/virt64.d: New file.
* gas/mips/virt64.s: New file.

include/opcode/ChangeLog:
* mips.h (OP_MASK_CODE10): Correct definition.
(OP_SH_CODE10): Likewise.
Add a comment that "+J" is used now for OP_*CODE10.
(INSN_ASE_MASK): Update.
(INSN_VIRT): New macro.
(INSN_VIRT64): New macro

opcodes/ChangeLog:
* mips-dis.c (mips_arch_choices): Add INSN_VIRT to mips32r2 .
Add INSN_VIRT and INSN_VIRT64 to mips64r2.
(parse_mips_dis_option): Handle the virt option.
(print_insn_args): Handle "+J".
(print_mips_disassembler_options): Print out message about virt64.
* mips-opc.c (IVIRT): New define.
(IVIRT64): New define.
(mips_builtin_opcodes): Add dmfgc0, dmtgc0, hypcall, mfgc0, mtgc0,
tlbgr, tlbgwi, tlbginv, tlbginvf, tlbgwr, tlbgp VIRT instructions.
Move rfe to the bottom as it conflicts with tlbgp.

16 files changed:
binutils/ChangeLog
binutils/doc/binutils.texi
gas/ChangeLog
gas/config/tc-mips.c
gas/doc/c-mips.texi
gas/testsuite/ChangeLog
gas/testsuite/gas/mips/mips.exp
gas/testsuite/gas/mips/virt.d [new file with mode: 0644]
gas/testsuite/gas/mips/virt.s [new file with mode: 0644]
gas/testsuite/gas/mips/virt64.d [new file with mode: 0644]
gas/testsuite/gas/mips/virt64.s [new file with mode: 0644]
include/opcode/ChangeLog
include/opcode/mips.h
opcodes/ChangeLog
opcodes/mips-dis.c
opcodes/mips-opc.c

index 63f0910b9876e08c0a3f4ce87f4c1387a256fad3..685900557e44bb0577f06b8f7c5a7e62ef11a846 100644 (file)
@@ -1,3 +1,7 @@
+2013-05-09  Andrew Pinski  <apinski@cavium.com>
+
+       * doc/binutils.texi: Document -Mvirt disassembler option.
+
 2013-05-02  Nick Clifton  <nickc@redhat.com>
 
        * readelf.c: Add support for MSP430X architecture.
index 0bb1d92ad49f077f7eac5964016a2350e7018a1c..aaa0bdbdbd3b6d637b720736837bf1733eb597b8 100644 (file)
@@ -2113,6 +2113,9 @@ Print the 'raw' instruction mnemonic instead of some pseudo
 instruction mnemonic.  I.e., print 'daddu' or 'or' instead of 'move',
 'sll' instead of 'nop', etc.
 
+@item virt
+Disassemble the virtualization ASE instructions.
+
 @item gpr-names=@var{ABI}
 Print GPR (general-purpose register) names as appropriate
 for the specified ABI.  By default, GPR names are selected according to
index b32779d4e0b6e33f677f012c69c0f2c401aaa16a..e35c82147abfbbb5b7ba25d0cf9e358e07496822 100644 (file)
@@ -1,3 +1,26 @@
+2013-05-09  Andrew Pinski  <apinski@cavium.com>
+
+       * config/tc-mips.c (struct mips_set_options): New ase_virt field.
+       (mips_opts): Update for the new field.
+       (file_ase_virt): New variable.
+       (ISA_SUPPORTS_VIRT_ASE): New macro.
+       (ISA_SUPPORTS_VIRT64_ASE): New macro.
+       (MIPS_CPU_ASE_VIRT): New define.
+       (is_opcode_valid): Handle ase_virt.
+       (macro_build): Handle "+J".
+       (validate_mips_insn): Likewise.
+       (mips_ip): Likewise.
+       (enum options): Add OPTION_VIRT and OPTION_NO_VIRT.
+       (md_longopts): Add mvirt and mnovirt
+       (md_parse_option): Handle OPTION_VIRT and OPTION_NO_VIRT.
+       (mips_after_parse_args): Handle ase_virt field.
+       (s_mipsset): Handle "virt" and "novirt".
+       (mips_elf_final_processing): Add a comment about virt ASE might need
+       a new flag.
+       (md_show_usage): Print out the usage of -mvirt and mno-virt options.
+       * doc/c-mips.texi: Document -mvirt and -mno-virt.
+       Document ".set virt" and ".set novirt".
+
 2013-05-09  Alan Modra  <amodra@gmail.com>
 
        * config/tc-ppc.c (md_apply_fix): Sign extend fieldval under
index 6eff83672c63b4b6fff451d14a53762232f48401..b234795f424e1d95df0fc10878e2fa04dd74087e 100644 (file)
@@ -218,6 +218,7 @@ struct mips_set_options
   int ase_dspr2;
   int ase_mt;
   int ase_mcu;
+  int ase_virt;
   /* Whether we are assembling for the mips16 processor.  0 if we are
      not, 1 if we are, and -1 if the value has not been initialized.
      Changed by `.set mips16' and `.set nomips16', and the -mips16 and
@@ -292,10 +293,11 @@ static struct mips_set_options mips_opts =
 {
   /* isa */ ISA_UNKNOWN, /* ase_mips3d */ -1, /* ase_mdmx */ -1,
   /* ase_smartmips */ 0, /* ase_dsp */ -1, /* ase_dspr2 */ -1, /* ase_mt */ -1,
-  /* ase_mcu */ -1, /* mips16 */ -1, /* micromips */ -1, /* noreorder */ 0,
-  /* at */ ATREG, /* warn_about_macros */ 0, /* nomove */ 0, /* nobopt */ 0,
-  /* noautoextend */ 0, /* gp32 */ 0, /* fp32 */ 0, /* arch */ CPU_UNKNOWN,
-  /* sym32 */ FALSE, /* soft_float */ FALSE, /* single_float */ FALSE
+  /* ase_mcu */ -1, /* ase_virt */ -1, /* mips16 */ -1,/* micromips */ -1,
+  /* noreorder */ 0,  /* at */ ATREG, /* warn_about_macros */ 0,
+  /* nomove */ 0, /* nobopt */ 0, /* noautoextend */ 0, /* gp32 */ 0,
+  /* fp32 */ 0, /* arch */ CPU_UNKNOWN, /* sym32 */ FALSE,
+  /* soft_float */ FALSE, /* single_float */ FALSE
 };
 
 /* These variables are filled in with the masks of registers used.
@@ -374,6 +376,15 @@ static int file_ase_mt;
                              || mips_opts.isa == ISA_MIPS64R2          \
                              || mips_opts.micromips)
 
+/* True if -mvirt was passed or implied by arguments passed on the
+   command line (e.g., by -march). */
+static int file_ase_virt;
+
+#define ISA_SUPPORTS_VIRT_ASE (mips_opts.isa == ISA_MIPS32R2           \
+                              || mips_opts.isa == ISA_MIPS64R2)
+
+#define ISA_SUPPORTS_VIRT64_ASE (mips_opts.isa == ISA_MIPS64R2)
+
 /* The argument of the -march= flag.  The architecture we are assembling.  */
 static int file_mips_arch = CPU_UNKNOWN;
 static const char *mips_arch_string;
@@ -1395,6 +1406,7 @@ struct mips_cpu_info
 #define MIPS_CPU_ASE_MDMX      0x0020  /* CPU implements MDMX ASE */
 #define MIPS_CPU_ASE_DSPR2     0x0040  /* CPU implements DSP R2 ASE */
 #define MIPS_CPU_ASE_MCU       0x0080  /* CPU implements MCU ASE */
+#define MIPS_CPU_ASE_VIRT      0x0100  /* CPU implements Virtualization ASE */
 
 static const struct mips_cpu_info *mips_parse_cpu (const char *, const char *);
 static const struct mips_cpu_info *mips_cpu_info_from_isa (int);
@@ -2258,6 +2270,10 @@ is_opcode_valid (const struct mips_opcode *mo)
     isa |= INSN_SMARTMIPS;
   if (mips_opts.ase_mcu)
     isa |= INSN_MCU;
+  if (mips_opts.ase_virt)
+    isa |= INSN_VIRT;
+  if (mips_opts.ase_virt && ISA_SUPPORTS_VIRT64_ASE)
+    isa |= INSN_VIRT64;
 
   if (!opcode_is_member (mo, isa, mips_opts.arch))
     return FALSE;
@@ -5036,6 +5052,11 @@ macro_build (expressionS *ep, const char *name, const char *fmt, ...)
                              INSMSB, insn, va_arg (args, int));
              continue;
 
+           case 'J':
+             gas_assert (!mips_opts.micromips);
+             INSERT_OPERAND (0, CODE10, insn, va_arg (args, int));
+             continue;
+
            case 'C':
            case 'G':
            case 'H':
@@ -10416,6 +10437,7 @@ validate_mips_insn (const struct mips_opcode *opc)
          case 'G': USE_BITS (OP_MASK_EXTMSBD,  OP_SH_EXTMSBD); break;
          case 'H': USE_BITS (OP_MASK_EXTMSBD,  OP_SH_EXTMSBD); break;
          case 'I': break;
+         case 'J': USE_BITS (OP_MASK_CODE10,   OP_SH_CODE10);  break;
          case 't': USE_BITS (OP_MASK_RT,       OP_SH_RT);      break;
          case 'T': USE_BITS (OP_MASK_RT,       OP_SH_RT);
                    USE_BITS (OP_MASK_SEL,      OP_SH_SEL);     break;
@@ -11339,6 +11361,23 @@ mips_ip (char *str, struct mips_cl_insn *ip)
                  }
                  continue;
 
+               case 'J':               /* 10-bit hypcall code.  */
+                 gas_assert (!mips_opts.micromips);
+                 {
+                   unsigned long mask = OP_MASK_CODE10;
+
+                   my_getExpression (&imm_expr, s);
+                   check_absolute_expr (ip, &imm_expr);
+                   if ((unsigned long) imm_expr.X_add_number > mask)
+                     as_warn (_("Code for %s not in range 0..%lu (%lu)"),
+                              ip->insn_mo->name,
+                              mask, (unsigned long) imm_expr.X_add_number);
+                   INSERT_OPERAND (0, CODE10, *ip, imm_expr.X_add_number);
+                   imm_expr.X_op = O_absent;
+                   s = expr_end;
+                 }
+                 continue;
+
                case 'A':               /* ins/ext position, becomes LSB.  */
                  limlo = 0;
                  limhi = 31;
@@ -14496,6 +14535,8 @@ enum options
     OPTION_NO_DSP,
     OPTION_MT,
     OPTION_NO_MT,
+    OPTION_VIRT,
+    OPTION_NO_VIRT,
     OPTION_SMARTMIPS,
     OPTION_NO_SMARTMIPS,
     OPTION_DSPR2,
@@ -14600,6 +14641,8 @@ struct option md_longopts[] =
   {"mno-micromips", no_argument, NULL, OPTION_NO_MICROMIPS},
   {"mmcu", no_argument, NULL, OPTION_MCU},
   {"mno-mcu", no_argument, NULL, OPTION_NO_MCU},
+  {"mvirt", no_argument, NULL, OPTION_VIRT},
+  {"mno-virt", no_argument, NULL, OPTION_NO_VIRT},
 
   /* Old-style architecture options.  Don't add more of these.  */
   {"m4650", no_argument, NULL, OPTION_M4650},
@@ -14877,6 +14920,14 @@ md_parse_option (int c, char *arg)
       mips_no_prev_insn ();
       break;
 
+    case OPTION_VIRT:
+      mips_opts.ase_virt = 1;
+      break;
+
+    case OPTION_NO_VIRT:
+      mips_opts.ase_virt = 0;
+      break;
+
     case OPTION_MIPS16:
       if (mips_opts.micromips == 1)
        {
@@ -15370,6 +15421,12 @@ mips_after_parse_args (void)
       as_warn (_("%s ISA does not support MCU ASE"),
               mips_cpu_info_from_isa (mips_opts.isa)->name);
 
+  if (mips_opts.ase_virt == -1)
+    mips_opts.ase_virt = (arch_info->flags & MIPS_CPU_ASE_VIRT) ? 1 : 0;
+  if (mips_opts.ase_virt && !ISA_SUPPORTS_VIRT_ASE)
+    as_warn (_("%s ISA does not support Virtualization ASE"),
+            mips_cpu_info_from_isa (mips_opts.isa)->name);
+
   file_mips_isa = mips_opts.isa;
   file_ase_mips3d = mips_opts.ase_mips3d;
   file_ase_mdmx = mips_opts.ase_mdmx;
@@ -15377,6 +15434,7 @@ mips_after_parse_args (void)
   file_ase_dsp = mips_opts.ase_dsp;
   file_ase_dspr2 = mips_opts.ase_dspr2;
   file_ase_mt = mips_opts.ase_mt;
+  file_ase_virt = mips_opts.ase_virt;
   mips_opts.gp32 = file_mips_gp32;
   mips_opts.fp32 = file_mips_fp32;
   mips_opts.soft_float = file_mips_soft_float;
@@ -16446,6 +16504,15 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
     mips_opts.ase_mcu = 1;
   else if (strcmp (name, "nomcu") == 0)
     mips_opts.ase_mcu = 0;
+  else if (strcmp (name, "virt") == 0)
+    {
+      if (!ISA_SUPPORTS_VIRT_ASE)
+       as_warn (_("%s ISA does not support Virtualization ASE"), 
+                mips_cpu_info_from_isa (mips_opts.isa)->name);
+      mips_opts.ase_virt = 1;
+    }
+  else if (strcmp (name, "novirt") == 0)
+    mips_opts.ase_virt = 0;
   else if (strncmp (name, "mips", 4) == 0 || strncmp (name, "arch=", 5) == 0)
     {
       int reset = 0;
@@ -18718,12 +18785,8 @@ mips_elf_final_processing (void)
   if (mips_abicalls)
     elf_elfheader (stdoutput)->e_flags |= EF_MIPS_CPIC;
 
-  /* Set MIPS ELF flags for ASEs.  */
-  /* We may need to define a new flag for DSP ASE, and set this flag when
-     file_ase_dsp is true.  */
-  /* Same for DSP R2.  */
-  /* We may need to define a new flag for MT ASE, and set this flag when
-     file_ase_mt is true.  */
+  /* Set MIPS ELF flags for ASEs.  Note that not all ASEs have flags
+     defined at present; this might need to change in future.  */
   if (file_ase_mips16)
     elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ARCH_ASE_M16;
   if (file_ase_micromips)
@@ -19594,6 +19657,9 @@ MIPS options:\n\
 -mmcu                  generate MCU instructions\n\
 -mno-mcu               do not generate MCU instructions\n"));
   fprintf (stream, _("\
+-mvirt                 generate Virtualization instructions\n\
+-mno-virt              do not generate Virtualization instructions\n"));
+  fprintf (stream, _("\
 -mfix-loongson2f-jump  work around Loongson2F JUMP instructions\n\
 -mfix-loongson2f-nop   work around Loongson2F NOP errata\n\
 -mfix-vr4120           work around certain VR4120 errata\n\
index 7df5f79e68d233db84b11a4dbe50e2aec155d323..b8953be94bfd697eb975c6a7982a6240e37a277e 100644 (file)
@@ -181,6 +181,12 @@ Generate code for the MCU Application Specific Extension.
 This tells the assembler to accept MCU instructions.
 @samp{-mno-mcu} turns off this option.
 
+@item -mvirt
+@itemx -mno-virt
+Generate code for the Virtualization Application Specific Extension.
+This tells the assembler to accept Virtualization instructions.
+@samp{-mno-virt} turns off this option.
+
 @item -mfix7000
 @itemx -mno-fix7000
 Cause nops to be inserted if the read of the destination register
@@ -684,6 +690,14 @@ from the MCU Application Specific Extension from that point on
 in the assembly.  The @code{.set nomcu} directive prevents MCU
 instructions from being accepted.
 
+@cindex Virtualization instruction generation override
+@kindex @code{.set virt}
+@kindex @code{.set novirt}
+The directive @code{.set virt} makes the assembler accept instructions
+from the Virtualization Application Specific Extension from that point
+on in the assembly.  The @code{.set novirt} directive prevents Virtualization
+instructions from being accepted.
+
 Traditional @sc{mips} assemblers do not support these directives.
 
 @node MIPS floating-point
index b853d8b6e45c33232b6b8248a2717ca572bb1981..dbaed95f06d766459cbcb0b91b16a1f1b7686570 100644 (file)
@@ -1,3 +1,11 @@
+2013-05-09  Andrew Pinski  <apinski@cavium.com>
+
+       * gas/mips/mips.exp: Run virt and virt64 testcases.
+       * gas/mips/virt.d: New file.
+       * gas/mips/virt.s: New file.
+       * gas/mips/virt64.d: New file.
+       * gas/mips/virt64.s: New file.
+
 2013-05-04  Richard Sandiford  <rdsandiford@googlemail.com>
 
        * gas/mips/micromips-warn-branch-delay.d: Use numeric registers.
index 48bd33e4fa370f25f344844de958b059b695951a..d338e535c87d80401ff52ae9fbc3db92e108b7cd 100644 (file)
@@ -786,6 +786,9 @@ if { [istarget mips*-*-vxworks*] } {
     run_dump_test "lineno"
     run_dump_test "sync"
 
+    run_dump_test_arches "virt" [mips_arch_list_matching mips32r2 !micromips]
+    run_dump_test_arches "virt64" [mips_arch_list_matching mips64r2 !micromips]
+
     run_dump_test_arches "mips32"      [mips_arch_list_matching mips32]
     run_dump_test_arches "mips32-imm"  [mips_arch_list_matching mips32]
 
diff --git a/gas/testsuite/gas/mips/virt.d b/gas/testsuite/gas/mips/virt.d
new file mode 100644 (file)
index 0000000..c22f867
--- /dev/null
@@ -0,0 +1,20 @@
+#objdump: -dr --prefix-addresses  --show-raw-insn -Mvirt,cp0-names=mips32r2
+#name: virt instructions
+#as: -32 -mvirt
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 4063e800     mfgc0   v1,c0_taghi
+[0-9a-f]+ <[^>]*> 406ba005     mfgc0   t3,\$20,5
+[0-9a-f]+ <[^>]*> 40771200     mtgc0   s7,c0_entrylo0
+[0-9a-f]+ <[^>]*> 40677202     mtgc0   a3,\$14,2
+[0-9a-f]+ <[^>]*> 42000028     hypcall
+[0-9a-f]+ <[^>]*> 4212b028     hypcall 0x256
+[0-9a-f]+ <[^>]*> 4200000b     tlbginv
+[0-9a-f]+ <[^>]*> 4200000c     tlbginvf
+[0-9a-f]+ <[^>]*> 42000010     tlbgp
+[0-9a-f]+ <[^>]*> 42000009     tlbgr
+[0-9a-f]+ <[^>]*> 4200000a     tlbgwi
+[0-9a-f]+ <[^>]*> 4200000e     tlbgwr
+       ...
diff --git a/gas/testsuite/gas/mips/virt.s b/gas/testsuite/gas/mips/virt.s
new file mode 100644 (file)
index 0000000..eca5e02
--- /dev/null
@@ -0,0 +1,22 @@
+       .text
+       .set noreorder
+
+foo:
+       mfgc0   $3,$29
+       mfgc0   $11,$20,5
+       mtgc0   $23,$2
+       mtgc0   $7,$14,2
+
+       hypcall
+       hypcall 0x256
+
+       tlbginv
+       tlbginvf
+       tlbgp
+       tlbgr
+       tlbgwi
+       tlbgwr
+
+# Force at least 8 (non-delay-slot) zero bytes, to make 'objdump' print ...
+       .align  2
+       .space  8
diff --git a/gas/testsuite/gas/mips/virt64.d b/gas/testsuite/gas/mips/virt64.d
new file mode 100644 (file)
index 0000000..7a86ff9
--- /dev/null
@@ -0,0 +1,12 @@
+#objdump: -dr --prefix-addresses  --show-raw-insn -Mvirt,cp0-names=mips64r2
+#name: virt64 instructions
+#as: -64 -mvirt
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 4063e900     dmfgc0  v1,c0_taghi
+[0-9a-f]+ <[^>]*> 406ba105     dmfgc0  a7,\$20,5
+[0-9a-f]+ <[^>]*> 40771300     dmtgc0  s7,c0_entrylo0
+[0-9a-f]+ <[^>]*> 40677302     dmtgc0  a3,\$14,2
+       ...
diff --git a/gas/testsuite/gas/mips/virt64.s b/gas/testsuite/gas/mips/virt64.s
new file mode 100644 (file)
index 0000000..f3cd7b5
--- /dev/null
@@ -0,0 +1,12 @@
+       .text
+       .set noreorder
+
+foo:
+       dmfgc0   $3,$29
+       dmfgc0   $11,$20,5
+       dmtgc0   $23,$2
+       dmtgc0   $7,$14,2
+
+# Force at least 8 (non-delay-slot) zero bytes, to make 'objdump' print ...
+       .align  2
+       .space  8
index 2b76a3643ae80ac539d261268c23b7ae21910ad7..773fa58e4171b41aed85514ceb35576296fed015 100644 (file)
@@ -1,3 +1,12 @@
+2013-05-09  Andrew Pinski  <apinski@cavium.com>
+
+       * mips.h (OP_MASK_CODE10): Correct definition.
+       (OP_SH_CODE10): Likewise.
+       Add a comment that "+J" is used now for OP_*CODE10.
+       (INSN_ASE_MASK): Update.
+       (INSN_VIRT): New macro.
+       (INSN_VIRT64): New macro
+
 2013-05-02  Nick Clifton  <nickc@redhat.com>
 
        * msp430.h: Add patterns for MSP430X instructions.
index ef81bbe2bfec939646dc50ad7d67031fa7b1bf86..bf0f11573f111baf0ba4160abcd5a984094af6ac 100644 (file)
 #define        OP_OP_SDC2              0x3e
 #define        OP_OP_SDC3              0x3f    /* a.k.a. sd */
 
+/* MIPS VIRT ASE */
+#define OP_MASK_CODE10         0x3ff
+#define OP_SH_CODE10           11
+
 /* Values in the 'VSEL' field.  */
 #define MDMX_FMTSEL_IMM_QH     0x1d
 #define MDMX_FMTSEL_IMM_OB     0x1e
    of the operand handling in GAS.  The fields below only exist
    in the microMIPS encoding, so define each one to have an empty
    range.  */
-#define OP_MASK_CODE10         0
-#define OP_SH_CODE10           0
 #define OP_MASK_TRAP           0
 #define OP_SH_TRAP             0
 #define OP_MASK_OFFSET10       0
@@ -486,6 +488,9 @@ struct mips_opcode
    "~" 12 bit offset (OP_*_OFFSET12)
    "\" 3 bit position for aset and aclr (OP_*_3BITPOS)
 
+   VIRT ASE usage:
+   "+J" 10-bit hypcall code (OP_*CODE10)
+
    UDI immediates:
    "+1" UDI immediate bits 6-10
    "+2" UDI immediate bits 6-15
@@ -528,7 +533,7 @@ struct mips_opcode
    Extension character sequences used so far ("+" followed by the
    following), for quick reference when adding more:
    "1234"
-   "ABCDEFGHIPQSTXZ"
+   "ABCDEFGHIJPQSTXZ"
    "abcpstxz"
 */
 
@@ -726,7 +731,7 @@ static const unsigned int mips_isa_table[] =
 #define INSN_OCTEON2             0x00000100
 
 /* Masks used for MIPS-defined ASEs.  */
-#define INSN_ASE_MASK            0x3c00f010
+#define INSN_ASE_MASK            0x3c00f0d0
 
 /* DSP ASE */ 
 #define INSN_DSP                  0x00001000
@@ -735,6 +740,10 @@ static const unsigned int mips_isa_table[] =
 /* MIPS R5900 instruction */
 #define INSN_5900                 0x00004000
 
+/* Virtualization ASE */
+#define INSN_VIRT                0x00000080
+#define INSN_VIRT64              0x00000040
+
 /* MIPS-3D ASE */
 #define INSN_MIPS3D               0x00008000
 
index e918abca27440832883cfc2607f3e4cde79670af..9a80d0481b907ddff78ba394abc84f494536b080 100644 (file)
@@ -1,3 +1,16 @@
+2013-05-09  Andrew Pinski  <apinski@cavium.com>
+
+       * mips-dis.c (mips_arch_choices): Add INSN_VIRT to mips32r2.
+       Add INSN_VIRT and INSN_VIRT64 to mips64r2.
+       (parse_mips_dis_option): Handle the virt option.
+       (print_insn_args): Handle "+J".
+       (print_mips_disassembler_options): Print out message about virt64.
+       * mips-opc.c (IVIRT): New define.
+       (IVIRT64): New define.
+       (mips_builtin_opcodes): Add dmfgc0, dmtgc0, hypcall, mfgc0, mtgc0,
+       tlbgr, tlbgwi, tlbginv, tlbginvf, tlbgwr, tlbgp VIRT instructions.
+       Move rfe to the bottom as it conflicts with tlbgp.
+
 2013-05-09  Alan Modra  <amodra@gmail.com>
 
        * ppc-opc.c (extract_vlesi): Properly sign extend.
index 018ac94f302c0c68e2ac7f3a339c18afcfb5857e..834fd5c7d4072ab67ba7a8d002376517b3646902 100644 (file)
@@ -590,7 +590,7 @@ const struct mips_arch_choice mips_arch_choices[] =
 
   { "mips32r2",        1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
     (ISA_MIPS32R2 | INSN_SMARTMIPS | INSN_DSP | INSN_DSPR2
-     | INSN_MIPS3D | INSN_MT | INSN_MCU),
+     | INSN_MIPS3D | INSN_MT | INSN_MCU | INSN_VIRT),
     mips_cp0_names_mips3264r2,
     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
     mips_hwr_names_mips3264r2 },
@@ -604,7 +604,7 @@ const struct mips_arch_choice mips_arch_choices[] =
 
   { "mips64r2",        1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
     (ISA_MIPS64R2 | INSN_MIPS3D | INSN_DSP | INSN_DSPR2
-     | INSN_DSP64 | INSN_MT | INSN_MDMX | INSN_MCU),
+     | INSN_DSP64 | INSN_MT | INSN_MDMX | INSN_MCU | INSN_VIRT | INSN_VIRT64),
     mips_cp0_names_mips3264r2,
     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
     mips_hwr_names_mips3264r2 },
@@ -824,6 +824,14 @@ parse_mips_dis_option (const char *option, unsigned int len)
       no_aliases = 1;
       return;
     }
+
+  if (CONST_STRNEQ (option, "virt"))
+    {
+      mips_isa |= INSN_VIRT;
+      if (mips_isa & ISA_MIPS64R2)
+       mips_isa |= INSN_VIRT64;
+      return;
+    }
   
   /* Look for the = that delimits the end of the option name.  */
   for (i = 0; i < len; i++)
@@ -1066,6 +1074,10 @@ print_insn_args (const char *d,
              infprintf (is, "0x%x", msbd + 1);
              break;
 
+           case 'J':           /* hypcall operand */
+             infprintf (is, "0x%x", GET_OP (l, CODE10));
+             break;
+
            case 't': /* Coprocessor 0 reg name */
              infprintf (is, "%s", mips_cp0_names[GET_OP (l, RT)]);
              break;
@@ -3033,6 +3045,9 @@ print_mips_disassembler_options (FILE *stream)
 The following MIPS specific disassembler options are supported for use\n\
 with the -M switch (multiple options should be separated by commas):\n"));
 
+  fprintf (stream, _("\n\
+  virt            Recognize the virtualization ASE instructions.\n"));
+
   fprintf (stream, _("\n\
   gpr-names=ABI            Print GPR names according to  specified ABI.\n\
                            Default: based on binary being disassembled.\n"));
index ee189c273ebe6fbbb87753807cf7e6caec075f02..0c43d0ad97d5811be38079daa18e80423bc43f7c 100644 (file)
 #define IOCTP  (INSN_OCTEONP | INSN_OCTEON2)
 #define IOCT2  INSN_OCTEON2
 #define XLR     INSN_XLR
+#define IVIRT  INSN_VIRT
+#define IVIRT64        INSN_VIRT64
 
 #define G1      (T3             \
                  |EE            \
@@ -718,11 +720,17 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"dmfc0",   "t,G",     0x40200000, 0xffe007ff, LCD|WR_t|RD_C0,         0,              I3,     EE      },
 {"dmfc0",   "t,+D",    0x40200000, 0xffe007f8, LCD|WR_t|RD_C0,         0,              I64     },
 {"dmfc0",   "t,G,H",   0x40200000, 0xffe007f8, LCD|WR_t|RD_C0,         0,              I64     },
+{"dmfgc0",   "t,G",    0x40600100, 0xffe007ff, LCD|WR_t|RD_C0,         0,              IVIRT64 },
+{"dmfgc0",   "t,+D",   0x40600100, 0xffe007f8, LCD|WR_t|RD_C0,         0,              IVIRT64 },
+{"dmfgc0",   "t,G,H",  0x40600100, 0xffe007f8, LCD|WR_t|RD_C0,         0,              IVIRT64 },
 {"dmt",     "",                0x41600bc1, 0xffffffff, TRAP,                   0,              MT32    },
 {"dmt",     "t",       0x41600bc1, 0xffe0ffff, TRAP|WR_t,              0,              MT32    },
 {"dmtc0",   "t,G",     0x40a00000, 0xffe007ff, COD|RD_t|WR_C0|WR_CC,   0,              I3,     EE      },
 {"dmtc0",   "t,+D",    0x40a00000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,              I64     },
 {"dmtc0",   "t,G,H",   0x40a00000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,              I64     },
+{"dmtgc0",  "t,G",     0x40600300, 0xffe007ff, COD|RD_t|WR_C0|WR_CC,   0,              IVIRT64 },
+{"dmtgc0",  "t,+D",     0x40600300, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,             IVIRT64 },
+{"dmtgc0",  "t,G,H",    0x40600300, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,             IVIRT64 },
 {"dmfc1",   "t,S",     0x44200000, 0xffe007ff, LCD|WR_t|RD_S|FP_D,     0,              I3,     SF      },
 {"dmfc1",   "t,G",      0x44200000, 0xffe007ff, LCD|WR_t|RD_S|FP_D,     0,             I3,     SF      },
 {"dmtc1",   "t,S",     0x44a00000, 0xffe007ff, COD|RD_t|WR_S|FP_D,     0,              I3,     SF      },
@@ -811,6 +819,8 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"floor.w.d", "D,S",   0x4620000f, 0xffff003f, WR_D|RD_S|FP_S|FP_D,    0,              I2,     SF      },
 {"floor.w.s", "D,S",   0x4600000f, 0xffff003f, WR_D|RD_S|FP_S,         0,              I2      },
 {"hibernate","",        0x42000023, 0xffffffff,        0,                      0,              V1      },
+{"hypcall", "",                0x42000028, 0xffffffff, TRAP,                   0,              IVIRT   },
+{"hypcall", "+J",      0x42000028, 0xffe007ff, TRAP,                   0,              IVIRT   },
 {"ins",     "t,r,+A,+B", 0x7c000004, 0xfc00003f, WR_t|RD_s,                    0,              I33     },
 {"iret",    "",                0x42000038, 0xffffffff, NODS,                   0,              MC      },
 {"jr",      "s",       0x00000008, 0xfc1fffff, UBD|RD_s,               0,              I1      },
@@ -1010,6 +1020,9 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"mfc0",    "t,G",     0x40000000, 0xffe007ff, LCD|WR_t|RD_C0,         0,              I1      },
 {"mfc0",    "t,+D",0x40000000, 0xffe007f8,     LCD|WR_t|RD_C0,         0,              I32     },
 {"mfc0",    "t,G,H",   0x40000000, 0xffe007f8, LCD|WR_t|RD_C0,         0,              I32     },
+{"mfgc0",    "t,G",    0x40600000, 0xffe007ff, LCD|WR_t|RD_C0,         0,              IVIRT   },
+{"mfgc0",    "t,+D",   0x40600000, 0xffe007f8, LCD|WR_t|RD_C0,         0,              IVIRT   },
+{"mfgc0",    "t,G,H",  0x40600000, 0xffe007f8, LCD|WR_t|RD_C0,         0,              IVIRT   },
 {"mfc1",    "t,S",     0x44000000, 0xffe007ff, LCD|WR_t|RD_S|FP_S,     0,              I1      },
 {"mfc1",    "t,G",     0x44000000, 0xffe007ff, LCD|WR_t|RD_S|FP_S,     0,              I1      },
 {"mfhc1",   "t,S",     0x44600000, 0xffe007ff, LCD|WR_t|RD_S|FP_D,     0,              I33     },
@@ -1104,6 +1117,9 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"mtc0",    "t,G",     0x40800000, 0xffe007ff, COD|RD_t|WR_C0|WR_CC,   0,              I1      },
 {"mtc0",    "t,+D",    0x40800000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,              I32     },
 {"mtc0",    "t,G,H",   0x40800000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,              I32     },
+{"mtgc0",   "t,G",     0x40600200, 0xffe007ff, COD|RD_t|WR_C0|WR_CC,   0,              IVIRT   },
+{"mtgc0",   "t,+D",    0x40600200, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,              IVIRT   },
+{"mtgc0",   "t,G,H",   0x40600200, 0xffe007f8, COD|RD_t|WR_C0|WR_CC,   0,              IVIRT   },
 {"mtc1",    "t,S",     0x44800000, 0xffe007ff, COD|RD_t|WR_S|FP_S,     0,              I1      },
 {"mtc1",    "t,G",     0x44800000, 0xffe007ff, COD|RD_t|WR_S|FP_S,     0,              I1      },
 {"mthc1",   "t,S",     0x44e00000, 0xffe007ff, COD|RD_t|WR_S|FP_D,     0,              I33     },
@@ -1379,7 +1395,7 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"remu",    "d,v,I",   0,    (int) M_REMU_3I,  INSN_MACRO,             0,              I1      },
 {"rdhwr",   "t,K",     0x7c00003b, 0xffe007ff, WR_t,                   0,              I33     },
 {"rdpgpr",  "d,w",     0x41400000, 0xffe007ff, WR_d,                   0,              I33     },
-{"rfe",     "",                0x42000010, 0xffffffff, 0,                      0,              I1|T3   },
+/* rfe is moved below as it now conflicts with tlbgp */
 {"rnas.qh", "X,Q",     0x78200025, 0xfc20f83f, WR_D|RD_T|FP_D,         RD_MACC,        MX      },
 {"rnau.ob", "X,Q",     0x78000021, 0xfc20f83f, WR_D|RD_T|FP_D,         RD_MACC,        MX|SB1  },
 {"rnau.qh", "X,Q",     0x78200021, 0xfc20f83f, WR_D|RD_T|FP_D,         RD_MACC,        MX      },
@@ -1624,6 +1640,12 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"tlbr",    "",         0x42000001, 0xffffffff, INSN_TLB,              0,              I1      },
 {"tlbwi",   "",         0x42000002, 0xffffffff, INSN_TLB,              0,              I1      },
 {"tlbwr",   "",         0x42000006, 0xffffffff, INSN_TLB,              0,              I1      },
+{"tlbgr",   "",         0x42000009, 0xffffffff, INSN_TLB,              0,              IVIRT   },
+{"tlbgwi",  "",         0x4200000a, 0xffffffff, INSN_TLB,              0,              IVIRT   },
+{"tlbginv", "",         0x4200000b, 0xffffffff, INSN_TLB,              0,              IVIRT   },
+{"tlbginvf","",         0x4200000c, 0xffffffff, INSN_TLB,              0,              IVIRT   },
+{"tlbgwr",  "",         0x4200000e, 0xffffffff, INSN_TLB,              0,              IVIRT   },
+{"tlbgp",   "",         0x42000010, 0xffffffff, INSN_TLB,              0,              IVIRT   },
 {"tlti",    "s,j",     0x040a0000, 0xfc1f0000, RD_s|TRAP,              0,              I2      },
 {"tlt",     "s,t",     0x00000032, 0xfc00ffff, RD_s|RD_t|TRAP,         0,              I2      },
 {"tlt",     "s,t,q",   0x00000032, 0xfc00003f, RD_s|RD_t|TRAP,         0,              I2      },
@@ -2273,6 +2295,8 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"cop1",     "C",      0,    (int) M_COP1,     INSN_MACRO,             INSN2_M_FP_S,   I1      },
 {"cop2",     "C",      0,    (int) M_COP2,     INSN_MACRO,             0,              I1,             IOCT|IOCTP|IOCT2        },
 {"cop3",     "C",      0,    (int) M_COP3,     INSN_MACRO,             0,              I1,             IOCT|IOCTP|IOCT2        },
+/* RFE conflicts with the new Virt spec instruction tlbgp. */
+{"rfe",     "",                0x42000010, 0xffffffff, 0,                      0,              I1|T3   },
 };
 
 #define MIPS_NUM_OPCODES \