binutils/ChangeLog:

* 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.
This commit is contained in:
Andrew Pinski
2013-05-10 01:08:48 +00:00
parent 4e45246814
commit b015e599c7
16 changed files with 274 additions and 17 deletions

View 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> 2013-05-02 Nick Clifton <nickc@redhat.com>
* readelf.c: Add support for MSP430X architecture. * readelf.c: Add support for MSP430X architecture.

View 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', instruction mnemonic. I.e., print 'daddu' or 'or' instead of 'move',
'sll' instead of 'nop', etc. 'sll' instead of 'nop', etc.
@item virt
Disassemble the virtualization ASE instructions.
@item gpr-names=@var{ABI} @item gpr-names=@var{ABI}
Print GPR (general-purpose register) names as appropriate Print GPR (general-purpose register) names as appropriate
for the specified ABI. By default, GPR names are selected according to for the specified ABI. By default, GPR names are selected according to

View 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> 2013-05-09 Alan Modra <amodra@gmail.com>
* config/tc-ppc.c (md_apply_fix): Sign extend fieldval under * config/tc-ppc.c (md_apply_fix): Sign extend fieldval under

View File

@ -218,6 +218,7 @@ struct mips_set_options
int ase_dspr2; int ase_dspr2;
int ase_mt; int ase_mt;
int ase_mcu; int ase_mcu;
int ase_virt;
/* Whether we are assembling for the mips16 processor. 0 if we are /* 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. 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 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, /* isa */ ISA_UNKNOWN, /* ase_mips3d */ -1, /* ase_mdmx */ -1,
/* ase_smartmips */ 0, /* ase_dsp */ -1, /* ase_dspr2 */ -1, /* ase_mt */ -1, /* ase_smartmips */ 0, /* ase_dsp */ -1, /* ase_dspr2 */ -1, /* ase_mt */ -1,
/* ase_mcu */ -1, /* mips16 */ -1, /* micromips */ -1, /* noreorder */ 0, /* ase_mcu */ -1, /* ase_virt */ -1, /* mips16 */ -1,/* micromips */ -1,
/* at */ ATREG, /* warn_about_macros */ 0, /* nomove */ 0, /* nobopt */ 0, /* noreorder */ 0, /* at */ ATREG, /* warn_about_macros */ 0,
/* noautoextend */ 0, /* gp32 */ 0, /* fp32 */ 0, /* arch */ CPU_UNKNOWN, /* nomove */ 0, /* nobopt */ 0, /* noautoextend */ 0, /* gp32 */ 0,
/* sym32 */ FALSE, /* soft_float */ FALSE, /* single_float */ FALSE /* fp32 */ 0, /* arch */ CPU_UNKNOWN, /* sym32 */ FALSE,
/* soft_float */ FALSE, /* single_float */ FALSE
}; };
/* These variables are filled in with the masks of registers used. /* 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.isa == ISA_MIPS64R2 \
|| mips_opts.micromips) || 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. */ /* The argument of the -march= flag. The architecture we are assembling. */
static int file_mips_arch = CPU_UNKNOWN; static int file_mips_arch = CPU_UNKNOWN;
static const char *mips_arch_string; 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_MDMX 0x0020 /* CPU implements MDMX ASE */
#define MIPS_CPU_ASE_DSPR2 0x0040 /* CPU implements DSP R2 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_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_parse_cpu (const char *, const char *);
static const struct mips_cpu_info *mips_cpu_info_from_isa (int); 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; isa |= INSN_SMARTMIPS;
if (mips_opts.ase_mcu) if (mips_opts.ase_mcu)
isa |= INSN_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)) if (!opcode_is_member (mo, isa, mips_opts.arch))
return FALSE; return FALSE;
@ -5036,6 +5052,11 @@ macro_build (expressionS *ep, const char *name, const char *fmt, ...)
INSMSB, insn, va_arg (args, int)); INSMSB, insn, va_arg (args, int));
continue; continue;
case 'J':
gas_assert (!mips_opts.micromips);
INSERT_OPERAND (0, CODE10, insn, va_arg (args, int));
continue;
case 'C': case 'C':
case 'G': case 'G':
case 'H': 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 'G': USE_BITS (OP_MASK_EXTMSBD, OP_SH_EXTMSBD); break;
case 'H': USE_BITS (OP_MASK_EXTMSBD, OP_SH_EXTMSBD); break; case 'H': USE_BITS (OP_MASK_EXTMSBD, OP_SH_EXTMSBD); break;
case 'I': 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); break;
case 'T': USE_BITS (OP_MASK_RT, OP_SH_RT); case 'T': USE_BITS (OP_MASK_RT, OP_SH_RT);
USE_BITS (OP_MASK_SEL, OP_SH_SEL); break; USE_BITS (OP_MASK_SEL, OP_SH_SEL); break;
@ -11339,6 +11361,23 @@ mips_ip (char *str, struct mips_cl_insn *ip)
} }
continue; 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. */ case 'A': /* ins/ext position, becomes LSB. */
limlo = 0; limlo = 0;
limhi = 31; limhi = 31;
@ -14496,6 +14535,8 @@ enum options
OPTION_NO_DSP, OPTION_NO_DSP,
OPTION_MT, OPTION_MT,
OPTION_NO_MT, OPTION_NO_MT,
OPTION_VIRT,
OPTION_NO_VIRT,
OPTION_SMARTMIPS, OPTION_SMARTMIPS,
OPTION_NO_SMARTMIPS, OPTION_NO_SMARTMIPS,
OPTION_DSPR2, OPTION_DSPR2,
@ -14600,6 +14641,8 @@ struct option md_longopts[] =
{"mno-micromips", no_argument, NULL, OPTION_NO_MICROMIPS}, {"mno-micromips", no_argument, NULL, OPTION_NO_MICROMIPS},
{"mmcu", no_argument, NULL, OPTION_MCU}, {"mmcu", no_argument, NULL, OPTION_MCU},
{"mno-mcu", no_argument, NULL, OPTION_NO_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. */ /* Old-style architecture options. Don't add more of these. */
{"m4650", no_argument, NULL, OPTION_M4650}, {"m4650", no_argument, NULL, OPTION_M4650},
@ -14877,6 +14920,14 @@ md_parse_option (int c, char *arg)
mips_no_prev_insn (); mips_no_prev_insn ();
break; break;
case OPTION_VIRT:
mips_opts.ase_virt = 1;
break;
case OPTION_NO_VIRT:
mips_opts.ase_virt = 0;
break;
case OPTION_MIPS16: case OPTION_MIPS16:
if (mips_opts.micromips == 1) if (mips_opts.micromips == 1)
{ {
@ -15370,6 +15421,12 @@ mips_after_parse_args (void)
as_warn (_("%s ISA does not support MCU ASE"), as_warn (_("%s ISA does not support MCU ASE"),
mips_cpu_info_from_isa (mips_opts.isa)->name); 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_mips_isa = mips_opts.isa;
file_ase_mips3d = mips_opts.ase_mips3d; file_ase_mips3d = mips_opts.ase_mips3d;
file_ase_mdmx = mips_opts.ase_mdmx; 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_dsp = mips_opts.ase_dsp;
file_ase_dspr2 = mips_opts.ase_dspr2; file_ase_dspr2 = mips_opts.ase_dspr2;
file_ase_mt = mips_opts.ase_mt; file_ase_mt = mips_opts.ase_mt;
file_ase_virt = mips_opts.ase_virt;
mips_opts.gp32 = file_mips_gp32; mips_opts.gp32 = file_mips_gp32;
mips_opts.fp32 = file_mips_fp32; mips_opts.fp32 = file_mips_fp32;
mips_opts.soft_float = file_mips_soft_float; mips_opts.soft_float = file_mips_soft_float;
@ -16446,6 +16504,15 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
mips_opts.ase_mcu = 1; mips_opts.ase_mcu = 1;
else if (strcmp (name, "nomcu") == 0) else if (strcmp (name, "nomcu") == 0)
mips_opts.ase_mcu = 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) else if (strncmp (name, "mips", 4) == 0 || strncmp (name, "arch=", 5) == 0)
{ {
int reset = 0; int reset = 0;
@ -18718,12 +18785,8 @@ mips_elf_final_processing (void)
if (mips_abicalls) if (mips_abicalls)
elf_elfheader (stdoutput)->e_flags |= EF_MIPS_CPIC; elf_elfheader (stdoutput)->e_flags |= EF_MIPS_CPIC;
/* Set MIPS ELF flags for ASEs. */ /* Set MIPS ELF flags for ASEs. Note that not all ASEs have flags
/* We may need to define a new flag for DSP ASE, and set this flag when defined at present; this might need to change in future. */
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. */
if (file_ase_mips16) if (file_ase_mips16)
elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ARCH_ASE_M16; elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ARCH_ASE_M16;
if (file_ase_micromips) if (file_ase_micromips)
@ -19594,6 +19657,9 @@ MIPS options:\n\
-mmcu generate MCU instructions\n\ -mmcu generate MCU instructions\n\
-mno-mcu do not generate MCU instructions\n")); -mno-mcu do not generate MCU instructions\n"));
fprintf (stream, _("\ 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-jump work around Loongson2F JUMP instructions\n\
-mfix-loongson2f-nop work around Loongson2F NOP errata\n\ -mfix-loongson2f-nop work around Loongson2F NOP errata\n\
-mfix-vr4120 work around certain VR4120 errata\n\ -mfix-vr4120 work around certain VR4120 errata\n\

View File

@ -181,6 +181,12 @@ Generate code for the MCU Application Specific Extension.
This tells the assembler to accept MCU instructions. This tells the assembler to accept MCU instructions.
@samp{-mno-mcu} turns off this option. @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 @item -mfix7000
@itemx -mno-fix7000 @itemx -mno-fix7000
Cause nops to be inserted if the read of the destination register 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 in the assembly. The @code{.set nomcu} directive prevents MCU
instructions from being accepted. 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. Traditional @sc{mips} assemblers do not support these directives.
@node MIPS floating-point @node MIPS floating-point

View 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> 2013-05-04 Richard Sandiford <rdsandiford@googlemail.com>
* gas/mips/micromips-warn-branch-delay.d: Use numeric registers. * gas/mips/micromips-warn-branch-delay.d: Use numeric registers.

View File

@ -786,6 +786,9 @@ if { [istarget mips*-*-vxworks*] } {
run_dump_test "lineno" run_dump_test "lineno"
run_dump_test "sync" 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" [mips_arch_list_matching mips32]
run_dump_test_arches "mips32-imm" [mips_arch_list_matching mips32] run_dump_test_arches "mips32-imm" [mips_arch_list_matching mips32]

View File

@ -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
...

View File

@ -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

View File

@ -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
...

View File

@ -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

View 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> 2013-05-02 Nick Clifton <nickc@redhat.com>
* msp430.h: Add patterns for MSP430X instructions. * msp430.h: Add patterns for MSP430X instructions.

View File

@ -212,6 +212,10 @@
#define OP_OP_SDC2 0x3e #define OP_OP_SDC2 0x3e
#define OP_OP_SDC3 0x3f /* a.k.a. sd */ #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. */ /* Values in the 'VSEL' field. */
#define MDMX_FMTSEL_IMM_QH 0x1d #define MDMX_FMTSEL_IMM_QH 0x1d
#define MDMX_FMTSEL_IMM_OB 0x1e #define MDMX_FMTSEL_IMM_OB 0x1e
@ -255,8 +259,6 @@
of the operand handling in GAS. The fields below only exist of the operand handling in GAS. The fields below only exist
in the microMIPS encoding, so define each one to have an empty in the microMIPS encoding, so define each one to have an empty
range. */ range. */
#define OP_MASK_CODE10 0
#define OP_SH_CODE10 0
#define OP_MASK_TRAP 0 #define OP_MASK_TRAP 0
#define OP_SH_TRAP 0 #define OP_SH_TRAP 0
#define OP_MASK_OFFSET10 0 #define OP_MASK_OFFSET10 0
@ -486,6 +488,9 @@ struct mips_opcode
"~" 12 bit offset (OP_*_OFFSET12) "~" 12 bit offset (OP_*_OFFSET12)
"\" 3 bit position for aset and aclr (OP_*_3BITPOS) "\" 3 bit position for aset and aclr (OP_*_3BITPOS)
VIRT ASE usage:
"+J" 10-bit hypcall code (OP_*CODE10)
UDI immediates: UDI immediates:
"+1" UDI immediate bits 6-10 "+1" UDI immediate bits 6-10
"+2" UDI immediate bits 6-15 "+2" UDI immediate bits 6-15
@ -528,7 +533,7 @@ struct mips_opcode
Extension character sequences used so far ("+" followed by the Extension character sequences used so far ("+" followed by the
following), for quick reference when adding more: following), for quick reference when adding more:
"1234" "1234"
"ABCDEFGHIPQSTXZ" "ABCDEFGHIJPQSTXZ"
"abcpstxz" "abcpstxz"
*/ */
@ -726,7 +731,7 @@ static const unsigned int mips_isa_table[] =
#define INSN_OCTEON2 0x00000100 #define INSN_OCTEON2 0x00000100
/* Masks used for MIPS-defined ASEs. */ /* Masks used for MIPS-defined ASEs. */
#define INSN_ASE_MASK 0x3c00f010 #define INSN_ASE_MASK 0x3c00f0d0
/* DSP ASE */ /* DSP ASE */
#define INSN_DSP 0x00001000 #define INSN_DSP 0x00001000
@ -735,6 +740,10 @@ static const unsigned int mips_isa_table[] =
/* MIPS R5900 instruction */ /* MIPS R5900 instruction */
#define INSN_5900 0x00004000 #define INSN_5900 0x00004000
/* Virtualization ASE */
#define INSN_VIRT 0x00000080
#define INSN_VIRT64 0x00000040
/* MIPS-3D ASE */ /* MIPS-3D ASE */
#define INSN_MIPS3D 0x00008000 #define INSN_MIPS3D 0x00008000

View 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> 2013-05-09 Alan Modra <amodra@gmail.com>
* ppc-opc.c (extract_vlesi): Properly sign extend. * ppc-opc.c (extract_vlesi): Properly sign extend.

View File

@ -590,7 +590,7 @@ const struct mips_arch_choice mips_arch_choices[] =
{ "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2, { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
(ISA_MIPS32R2 | INSN_SMARTMIPS | INSN_DSP | INSN_DSPR2 (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_cp0_names_mips3264r2,
mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
mips_hwr_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, { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
(ISA_MIPS64R2 | INSN_MIPS3D | INSN_DSP | INSN_DSPR2 (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_cp0_names_mips3264r2,
mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
mips_hwr_names_mips3264r2 }, mips_hwr_names_mips3264r2 },
@ -825,6 +825,14 @@ parse_mips_dis_option (const char *option, unsigned int len)
return; 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. */ /* Look for the = that delimits the end of the option name. */
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
if (option[i] == '=') if (option[i] == '=')
@ -1066,6 +1074,10 @@ print_insn_args (const char *d,
infprintf (is, "0x%x", msbd + 1); infprintf (is, "0x%x", msbd + 1);
break; break;
case 'J': /* hypcall operand */
infprintf (is, "0x%x", GET_OP (l, CODE10));
break;
case 't': /* Coprocessor 0 reg name */ case 't': /* Coprocessor 0 reg name */
infprintf (is, "%s", mips_cp0_names[GET_OP (l, RT)]); infprintf (is, "%s", mips_cp0_names[GET_OP (l, RT)]);
break; break;
@ -3033,6 +3045,9 @@ print_mips_disassembler_options (FILE *stream)
The following MIPS specific disassembler options are supported for use\n\ The following MIPS specific disassembler options are supported for use\n\
with the -M switch (multiple options should be separated by commas):\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\ fprintf (stream, _("\n\
gpr-names=ABI Print GPR names according to specified ABI.\n\ gpr-names=ABI Print GPR names according to specified ABI.\n\
Default: based on binary being disassembled.\n")); Default: based on binary being disassembled.\n"));

View File

@ -128,6 +128,8 @@
#define IOCTP (INSN_OCTEONP | INSN_OCTEON2) #define IOCTP (INSN_OCTEONP | INSN_OCTEON2)
#define IOCT2 INSN_OCTEON2 #define IOCT2 INSN_OCTEON2
#define XLR INSN_XLR #define XLR INSN_XLR
#define IVIRT INSN_VIRT
#define IVIRT64 INSN_VIRT64
#define G1 (T3 \ #define G1 (T3 \
|EE \ |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,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,+D", 0x40200000, 0xffe007f8, LCD|WR_t|RD_C0, 0, I64 },
{"dmfc0", "t,G,H", 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", "", 0x41600bc1, 0xffffffff, TRAP, 0, MT32 },
{"dmt", "t", 0x41600bc1, 0xffe0ffff, TRAP|WR_t, 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,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,+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 }, {"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,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 }, {"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 }, {"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.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 }, {"floor.w.s", "D,S", 0x4600000f, 0xffff003f, WR_D|RD_S|FP_S, 0, I2 },
{"hibernate","", 0x42000023, 0xffffffff, 0, 0, V1 }, {"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 }, {"ins", "t,r,+A,+B", 0x7c000004, 0xfc00003f, WR_t|RD_s, 0, I33 },
{"iret", "", 0x42000038, 0xffffffff, NODS, 0, MC }, {"iret", "", 0x42000038, 0xffffffff, NODS, 0, MC },
{"jr", "s", 0x00000008, 0xfc1fffff, UBD|RD_s, 0, I1 }, {"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,G", 0x40000000, 0xffe007ff, LCD|WR_t|RD_C0, 0, I1 },
{"mfc0", "t,+D",0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, 0, I32 }, {"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 }, {"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,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 }, {"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 }, {"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,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,+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 }, {"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,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 }, {"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 }, {"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 }, {"remu", "d,v,I", 0, (int) M_REMU_3I, INSN_MACRO, 0, I1 },
{"rdhwr", "t,K", 0x7c00003b, 0xffe007ff, WR_t, 0, I33 }, {"rdhwr", "t,K", 0x7c00003b, 0xffe007ff, WR_t, 0, I33 },
{"rdpgpr", "d,w", 0x41400000, 0xffe007ff, WR_d, 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 }, {"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.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 }, {"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 }, {"tlbr", "", 0x42000001, 0xffffffff, INSN_TLB, 0, I1 },
{"tlbwi", "", 0x42000002, 0xffffffff, INSN_TLB, 0, I1 }, {"tlbwi", "", 0x42000002, 0xffffffff, INSN_TLB, 0, I1 },
{"tlbwr", "", 0x42000006, 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 }, {"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", 0x00000032, 0xfc00ffff, RD_s|RD_t|TRAP, 0, I2 },
{"tlt", "s,t,q", 0x00000032, 0xfc00003f, 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 }, {"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 }, {"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 }, {"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 \ #define MIPS_NUM_OPCODES \