aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog23
-rw-r--r--gas/config/tc-mips.c86
-rw-r--r--gas/doc/c-mips.texi14
-rw-r--r--gas/testsuite/ChangeLog8
-rw-r--r--gas/testsuite/gas/mips/mips.exp3
-rw-r--r--gas/testsuite/gas/mips/virt.d20
-rw-r--r--gas/testsuite/gas/mips/virt.s22
-rw-r--r--gas/testsuite/gas/mips/virt64.d12
-rw-r--r--gas/testsuite/gas/mips/virt64.s12
9 files changed, 190 insertions, 10 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index b32779d..e35c821 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index 6eff836..b234795 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -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\
diff --git a/gas/doc/c-mips.texi b/gas/doc/c-mips.texi
index 7df5f79..b8953be 100644
--- a/gas/doc/c-mips.texi
+++ b/gas/doc/c-mips.texi
@@ -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
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index b853d8b..dbaed95 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -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.
diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp
index 48bd33e..d338e53 100644
--- a/gas/testsuite/gas/mips/mips.exp
+++ b/gas/testsuite/gas/mips/mips.exp
@@ -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
index 0000000..c22f867
--- /dev/null
+++ b/gas/testsuite/gas/mips/virt.d
@@ -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
index 0000000..eca5e02
--- /dev/null
+++ b/gas/testsuite/gas/mips/virt.s
@@ -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
index 0000000..7a86ff9
--- /dev/null
+++ b/gas/testsuite/gas/mips/virt64.d
@@ -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
index 0000000..f3cd7b5
--- /dev/null
+++ b/gas/testsuite/gas/mips/virt64.s
@@ -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