Add GINV(+VIRT) ASE for MIPSr6
Checks
Commit Message
This patch adds the VZ extension to MIPSr6 as part of the GINV ASE.
gas/ChangeLog
* config/tc-mips.c (mips_ases): Add microMIPS ASE.
(mips_set_ase): Set combination VZ+GINV ASE flag.
gas/testsuite/ChangeLog
* gas/mips/ginv.s: Add test case.
* gas/mips/ginv-virt.d: New test.
* gas/mips/mips.exp: Run the new tests.
include/Changelog
* opcode/mips.h: Add note for micromips +\ format descriptor.
(ASE_GINV_VIRT): New macro.
opcodes/ChangeLog
* mips-dis.c (mips_calculate_combination_ases): Set ASE_GINV_VIRT.
* mips-opc.c (GINVVZ): New macro.
(mips_opcode): Add instructions GINVGT.
---
gas/config/tc-mips.c | 11 ++++++++++-
gas/testsuite/gas/mips/ginv-virt.d | 22 ++++++++++++++++++++++
gas/testsuite/gas/mips/ginv.s | 5 +++++
gas/testsuite/gas/mips/mips.exp | 1 +
include/opcode/mips.h | 6 ++++++
opcodes/mips-dis.c | 2 ++
opcodes/mips-opc.c | 2 ++
7 files changed, 48 insertions(+), 1 deletion(-)
create mode 100644 gas/testsuite/gas/mips/ginv-virt.d
Comments
On Thu, 18 May 2023, Tsing wrote:
> This patch adds the VZ extension to MIPSr6 as part of the GINV ASE.
>
> gas/ChangeLog
> * config/tc-mips.c (mips_ases): Add microMIPS ASE.
This surely isn't right.
> diff --git a/gas/testsuite/gas/mips/ginv-virt.d b/gas/testsuite/gas/mips/ginv-virt.d
> new file mode 100644
> index 00000000..50fa6d54
> --- /dev/null
> +++ b/gas/testsuite/gas/mips/ginv-virt.d
> @@ -0,0 +1,22 @@
> +#objdump: -pdr --prefix-addresses --show-raw-insn
> +#name: MIPS GINV Virtualization
> +#as: --defsym VX= -mginv -mvirt -32
Please use `VX=1'. I'm surprised using `--defsym' without giving the
symbol a value even works.
> diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp
> index fafed2dc..4e3e226f 100644
> --- a/gas/testsuite/gas/mips/mips.exp
> +++ b/gas/testsuite/gas/mips/mips.exp
> @@ -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]
Use tabs for indentation.
> diff --git a/include/opcode/mips.h b/include/opcode/mips.h
> index 75d3fc25..b26a8ffd 100644
> --- a/include/opcode/mips.h
> +++ b/include/opcode/mips.h
> @@ -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
Why is there a hole in bit assignments here? Also use tabs for
indentation.
> @@ -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
We write bit-field references with a hyphen, i.e. "2-bit".
> diff --git a/opcodes/mips-opc.c b/opcodes/mips-opc.c
> index 2a1a6cbb..80a5124b 100644
> --- a/opcodes/mips-opc.c
> +++ b/opcodes/mips-opc.c
> @@ -412,6 +412,7 @@ decode_mips_operand (const char *p)
>
> /* Global INValidate (GINV) support. */
> #define GINV ASE_GINV
> +#define GINVVZ ASE_GINV_VIRT
Use a tab here.
> @@ -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 },
I take it the encoding is correct, as I can't find it in published docs,
and the instruction itself is only mentioned once, in the context of SYNC.
How did you verify your change?
Maciej
Hi.
Thanks for the advise on formatting, I will review the code and keep you updated.
>I take it the encoding is correct, as I can't find it in published docs,
>and the instruction itself is only mentioned once, in the context of SYNC.
>
>How did you verify your change?
The encoding is documented in the I6500 core programming guide and there is
also a description of the `GINVGT` instruction in the MIPS64 I6500 System Instruction Guide.
You can find the docs here:
page 176 of https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MIPS_ Warrior_I6500_ProgrammerGuide_MD01179_P_1.00.pdf
Thanks.
Tsing
@@ -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= -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 },