@@ -2227,7 +2227,7 @@ mips_set_ase (const struct mips_ase *ase, struct mips_set_options *opts,
/* Clear combination ASE flags, which need to be recalculated based on
updated regular ASE settings. */
- opts->ase &= ~(ASE_MIPS16E2_MT | ASE_XPA_VIRT | ASE_EVA_R6);
+ opts->ase &= ~(ASE_MIPS16E2_MT | ASE_XPA_VIRT | ASE_EVA_R6 | ASE_GINV_VIRT);
if (enabled_p)
opts->ase |= ase->flags;
@@ -2255,6 +2255,15 @@ mips_set_ase (const struct mips_ase *ase, struct mips_set_options *opts,
mask |= ASE_EVA_R6;
}
+ /* The Virtualization ASE has Global INValidate (GINV) instructions
+ which are only valid when both ASEs are enabled. This sets the
+ ASE_GINV_VIRT flag when both ASEs are present. */
+ if ((opts->ase & (ASE_GINV | ASE_VIRT)) == (ASE_GINV | ASE_VIRT))
+ {
+ opts->ase |= ASE_GINV_VIRT;
+ mask |= ASE_GINV_VIRT;
+ }
+
return mask;
}
new file mode 100644
@@ -0,0 +1,22 @@
+#objdump: -pdr --prefix-addresses --show-raw-insn
+#name: MIPS GINV Virtualization
+#as: --defsym VX=1 -mginv -mvirt -32
+#source: ginv.s
+
+# Test GINV+VZ instructions.
+
+.*: +file format .*mips.*
+#...
+ASEs:
+#...
+ VZ ASE
+ GINV ASE
+#...
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 7c40003d ginvi v0
+[0-9a-f]+ <[^>]*> 7c6000bd ginvt v1,0x0
+[0-9a-f]+ <[^>]*> 7c8001bd ginvt a0,0x1
+[0-9a-f]+ <[^>]*> 7c8002fd ginvgt a0,0x2
+[0-9a-f]+ <[^>]*> 7ca003fd ginvgt a1,0x3
+ \.\.\.
@@ -4,6 +4,11 @@ test:
ginvt $3,0
ginvt $4,1
+ .ifdef VX
+ ginvgt $4,2
+ ginvgt $5,3
+ .endif
+
# Force at least 8 (non-delay-slot) zero bytes, to make 'objdump' print ...
.align 2
.space 8
@@ -2131,6 +2131,7 @@ if { [istarget mips*-*-vxworks*] } {
run_dump_test_arches "ginv" [mips_arch_list_matching mips32r6]
run_dump_test_arches "ginv-err" [mips_arch_list_matching mips32r6]
+ run_dump_test_arches "ginv-virt" [mips_arch_list_matching mips32r6]
run_dump_test_arches "llpscp-32" [mips_arch_list_matching mips32r6]
run_dump_test_arch "llpscp-64" "" mips64r6
@@ -1316,6 +1316,9 @@ static const unsigned int mips_isa_table[] = {
/* The Enhanced VA Scheme (EVA) extension has instructions which are
only valid for the R6 ISA. */
#define ASE_EVA_R6 0x02000000
+/* The Virtualization ASE has Global INValidate (GINV)
+ instructions which are only valid when both ASEs are enabled. */
+#define ASE_GINV_VIRT 0x08000000
/* MIPS ISA defines, use instead of hardcoding ISA level. */
@@ -2351,6 +2354,9 @@ extern const int bfd_mips16_num_opcodes;
"+*" 5-bit register vector element index at bit 16
"+|" 8-bit mask at bit 16
+ GINV ASE usage:
+ "+\" 2-bit Global TLB invalidate type at bit 8
+
Other:
"()" parens surrounding optional value
"," separates operands
@@ -866,6 +866,8 @@ mips_calculate_combination_ases (int opcode_isa, unsigned long opcode_ases)
&& ((opcode_isa & INSN_ISA_MASK) == ISA_MIPS64R6
|| (opcode_isa & INSN_ISA_MASK) == ISA_MIPS32R6))
combination_ases |= ASE_EVA_R6;
+ if ((opcode_ases & (ASE_GINV | ASE_VIRT)) == (ASE_GINV | ASE_VIRT))
+ combination_ases |= ASE_GINV_VIRT;
return combination_ases;
}
@@ -412,6 +412,7 @@ decode_mips_operand (const char *p)
/* Global INValidate (GINV) support. */
#define GINV ASE_GINV
+#define GINVVZ ASE_GINV_VIRT
/* Loongson MultiMedia extensions Instructions (MMI) support. */
#define LMMI ASE_LOONGSON_MMI
@@ -3329,6 +3330,7 @@ const struct mips_opcode mips_builtin_opcodes[] =
/* MIPS Global INValidate (GINV) ASE. */
{"ginvi", "s", 0x7c00003d, 0xfc1fffff, RD_1, 0, 0, GINV, 0 },
{"ginvt", "s,+\\", 0x7c0000bd, 0xfc1ffcff, RD_1, 0, 0, GINV, 0 },
+{"ginvgt", "s,+\\", 0x7c0000fd, 0xfc1ffcff, RD_1, 0, 0, GINVVZ, 0 },
/* Move bc0* after mftr and mttr to avoid opcode collision. */
{"bc0f", "p", 0x41000000, 0xffff0000, RD_CC|CBD, 0, I1, 0, I4_32 },