[PATCH] Add XPA ASE and MIPS R5 microMIPS support

Andrew Bennett Andrew.Bennett@imgtec.com
Thu Mar 19 23:05:00 GMT 2015


Richard Sandiford <rdsandiford@googlemail.com> writes:
> Matthew Fortune <Matthew.Fortune@imgtec.com> writes:
> > Richard Sandiford <rdsandiford@googlemail.com> writes:
> >> Andrew Bennett <Andrew.Bennett@imgtec.com> writes:
> >> > +{"mfhc0",		"t,G",		0x000000f4, 0xfc00ffff,
> >> 	WR_1|RD_C0,		0,		0,		XPA,	0 },
> >> > +{"mfhc0",		"t,G,H",	0x000000f4, 0xfc00c7ff,	WR_1|RD_C0,
> >> 		0,		0,		XPA,	0 },
> >> > +{"mfhgc0",		"t,G",		0x000004f4, 0xfc00ffff,
> >> 	WR_1|RD_C0, 0, 0, IVIRT|XPA, 0 },
> >> > +{"mfhgc0",		"t,G,H",	0x000004f4, 0xfc00c7ff,	WR_1|RD_C0,
> >> 		0,		0,		IVIRT|XPA,	0 },
> >>
> >> Genuine question: is this really "IVIRT or XPA" or "IVIRT and XPA"?
> >> Would be good to have virt in the test if it's relevant.
> >
> > I believe this is an 'and' which is the same issue as we already have
> > in the mips-opc implementation of these instructions. I can't remember
> > exactly how the ASE field works but I guess deriving another bit for
> > the combined IVIRT+XPA won't actually be that hard.
> 
> OK.

Sorry for the delay in posting a response to this.  The following patch and 
ChangeLog below makes the mfhgc0 and mthgc0 instructions conditional on both
the XPA and Virtualization ASEs being present.  I have updated both the micromips
and mips opcode tables.

Ok to commit?

Many thanks,


Andrew



gas/
	* config/tc-mips.c (mips_ases): Add XPA support for micromips.
	(mips_set_ase): Set the ASE_VIRT_XPA flag if both the XPA and
	Virtualization ASEs are enabled.

gas/testsuite/
	* gas/mips/mips.exp: Enable support for micromips for the xpa and r5
	  tests.
	* gas/mips/xpa.d: Add -mvirt to assembly options and virt to
	  disassembly options.
	* gas/mips/micromips@xpa.d: New test.
	* gas/mips/micromips@r5.d: New test.

include/opcode/
	* mips.h (ASE_VIRT_XPA): New define.

opcodes/
	* micromips-opc.c (I36): New define.
	  (IVIRT_ASE): New define.
	  (XPA): New define.
	  (micromips_opcodes): Add XPA and eretnc instructions.
	* mips-opc.c (IVIRT_ASE): New define.
	(mips_builtin_opcodes): Updated ASE flags for mfhgc0 and mthgc0.


diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index e61bb4d..57b2324 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -1707,7 +1707,7 @@ static const struct mips_ase mips_ases[] = {
 
   { "xpa", ASE_XPA, 0,
     OPTION_XPA, OPTION_NO_XPA,
-     2,  2, -1, -1,
+     2,  2, 2, 2,
     -1 },
 };
 
@@ -2070,8 +2070,20 @@ mips_set_ase (const struct mips_ase *ase, struct mips_set_options *opts,
 
   mask = mips_ase_mask (ase->flags);
   opts->ase &= ~mask;
+  opts->ase &= ~ASE_VIRT_XPA;
+
   if (enabled_p)
     opts->ase |= ase->flags;
+
+  /* The Virtualization ASE has eXtended Physical Address (XPA) Extension
+     instructions which are only valid when both ASEs are enabled.
+     This sets the ASE_VIRT_XPA flag when both ASEs are present.  */
+  if (((opts->ase & ASE_XPA) != 0) && ((opts->ase & ASE_VIRT) != 0))
+    {
+      opts->ase |= ASE_VIRT_XPA;
+      mask |= ASE_VIRT_XPA;
+    }
+
   return mask;
 }
 
diff --git a/gas/testsuite/gas/mips/micromips@r5.d b/gas/testsuite/gas/mips/micromips@r5.d
new file mode 100644
index 0000000..ce10398
--- /dev/null
+++ b/gas/testsuite/gas/mips/micromips@r5.d
@@ -0,0 +1,9 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#source: r5.s
+#name: Test MIPS32r5 instructions
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 0001f37c 	eretnc
+	...
diff --git a/gas/testsuite/gas/mips/micromips@xpa.d b/gas/testsuite/gas/mips/micromips@xpa.d
new file mode 100644
index 0000000..d93437f
--- /dev/null
+++ b/gas/testsuite/gas/mips/micromips@xpa.d
@@ -0,0 +1,25 @@
+#objdump: -dr --prefix-addresses --show-raw-insn -Mxpa,virt,cp0-names=mips32r2
+#name: XPA instructions
+#source: xpa.s
+#as: -32 -mxpa -mvirt
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 0041 00f4 	mfhc0	v0,c0_random
+[0-9a-f]+ <[^>]*> 0050 00f4 	mfhc0	v0,c0_config
+[0-9a-f]+ <[^>]*> 0040 10f4 	mfhc0	v0,c0_mvpconf0
+[0-9a-f]+ <[^>]*> 0040 38f4 	mfhc0	v0,\$0,7
+[0-9a-f]+ <[^>]*> 0041 02f4 	mthc0	v0,c0_random
+[0-9a-f]+ <[^>]*> 0050 02f4 	mthc0	v0,c0_config
+[0-9a-f]+ <[^>]*> 0040 12f4 	mthc0	v0,c0_mvpconf0
+[0-9a-f]+ <[^>]*> 0040 3af4 	mthc0	v0,\$0,7
+[0-9a-f]+ <[^>]*> 0041 04f4 	mfhgc0	v0,c0_random
+[0-9a-f]+ <[^>]*> 0050 04f4 	mfhgc0	v0,c0_config
+[0-9a-f]+ <[^>]*> 0040 14f4 	mfhgc0	v0,c0_mvpconf0
+[0-9a-f]+ <[^>]*> 0040 3cf4 	mfhgc0	v0,\$0,7
+[0-9a-f]+ <[^>]*> 0041 06f4 	mthgc0	v0,c0_random
+[0-9a-f]+ <[^>]*> 0050 06f4 	mthgc0	v0,c0_config
+[0-9a-f]+ <[^>]*> 0040 16f4 	mthgc0	v0,c0_mvpconf0
+[0-9a-f]+ <[^>]*> 0040 3ef4 	mthgc0	v0,\$0,7
+	...
diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp
index 11c9b05..08e696a 100644
--- a/gas/testsuite/gas/mips/mips.exp
+++ b/gas/testsuite/gas/mips/mips.exp
@@ -1240,8 +1240,8 @@ if { [istarget mips*-*-vxworks*] } {
     run_dump_test_arches "msa-relax"	[mips_arch_list_matching mips32r2 !mips32r6]
     run_dump_test_arches "msa-branch"	[mips_arch_list_matching mips32r2]
 
-    run_dump_test_arches "xpa"		[mips_arch_list_matching mips32r2 !micromips]
-    run_dump_test_arches "r5" "-32"	[mips_arch_list_matching mips32r5 !micromips]
+    run_dump_test_arches "xpa"		[mips_arch_list_matching mips32r2]
+    run_dump_test_arches "r5" "-32"	[mips_arch_list_matching mips32r5]
 
     run_dump_test "pcrel-1"
     run_dump_test "pcrel-2"
diff --git a/gas/testsuite/gas/mips/xpa.d b/gas/testsuite/gas/mips/xpa.d
index f1047c9..895aa9d 100644
--- a/gas/testsuite/gas/mips/xpa.d
+++ b/gas/testsuite/gas/mips/xpa.d
@@ -1,6 +1,6 @@
-#objdump: -dr --prefix-addresses --show-raw-insn -Mxpa,cp0-names=mips32r2
+#objdump: -dr --prefix-addresses --show-raw-insn -Mxpa,virt,cp0-names=mips32r2
 #name: XPA instructions
-#as: -32 -mxpa
+#as: -32 -mxpa -mvirt
 
 .*: +file format .*mips.*
 
diff --git a/include/opcode/mips.h b/include/opcode/mips.h
index 9318fcc..5349d13 100644
--- a/include/opcode/mips.h
+++ b/include/opcode/mips.h
@@ -1256,6 +1256,9 @@ static const unsigned int mips_isa_table[] = {
 #define ASE_MSA64		0x00001000
 /* eXtended Physical Address (XPA) Extension.  */
 #define ASE_XPA			0x00002000
+/* The Virtualization ASE has eXtended Physical Address (XPA) Extension
+   instructions which are only valid when both ASEs are enabled.  */
+#define ASE_VIRT_XPA		0x00004000
 
 /* MIPS ISA defines, use instead of hardcoding ISA level.  */
 
diff --git a/opcodes/micromips-opc.c b/opcodes/micromips-opc.c
index 66c5418..79fa3e0 100644
--- a/opcodes/micromips-opc.c
+++ b/opcodes/micromips-opc.c
@@ -253,6 +253,7 @@ decode_micromips_operand (const char *p)
    are accepted as 64-bit microMIPS ISA.  */
 #define I1	INSN_ISA1
 #define I3	INSN_ISA3
+#define I36	INSN_ISA32R5
 
 /* MIPS DSP ASE support.  */
 #define WR_a	WR_HILO		/* Write DSP accumulators (reuse WR_HILO).  */
@@ -274,11 +275,15 @@ decode_micromips_operand (const char *p)
 /* MIPS Virtualization ASE.  */
 #define IVIRT	ASE_VIRT
 #define IVIRT64	ASE_VIRT64
+#define IVIRT_XPA ASE_VIRT_XPA
 
 /* MSA support.  */
 #define MSA     ASE_MSA
 #define MSA64   ASE_MSA64
 
+/* eXtended Physical Address (XPA) support.  */
+#define XPA     ASE_XPA
+
 const struct mips_opcode micromips_opcodes[] =
 {
 /* These instructions appear first so that the disassembler will find
@@ -682,6 +687,7 @@ const struct mips_opcode micromips_opcodes[] =
 {"ei",			"",		0x0000577c, 0xffffffff,	WR_C0,			0,		I1,		0,	0 },
 {"ei",			"s",		0x0000577c, 0xffe0ffff,	WR_1|WR_C0,		0,		I1,		0,	0 },
 {"eret",		"",		0x0000f37c, 0xffffffff,	NODS,			0,		I1,		0,	0 },
+{"eretnc",		"",		0x0001f37c, 0xffffffff,	NODS,			0,		I36,		0,	0 },
 {"ext",			"t,r,+A,+C",	0x0000002c, 0xfc00003f, WR_1|RD_2,		0,		I1,		0,	0 },
 {"floor.l.d",		"T,V",		0x5400433b, 0xfc00ffff,	WR_1|RD_2|FP_D,		0,		I1,		0,	0 },
 {"floor.l.s",		"T,V",		0x5400033b, 0xfc00ffff,	WR_1|RD_2|FP_S|FP_D,	0,		I1,		0,	0 },
@@ -826,6 +832,10 @@ const struct mips_opcode micromips_opcodes[] =
 {"mfc2",		"t,G",		0x00004d3c, 0xfc00ffff,	WR_1|RD_C2,		0,		I1,		0,	0 },
 {"mfgc0",		"t,G",		0x000004fc, 0xfc00ffff,	WR_1|RD_C0,		0,		0,		IVIRT,	0 },
 {"mfgc0",		"t,G,H",	0x000004fc, 0xfc00c7ff,	WR_1|RD_C0,		0,		0,		IVIRT,	0 },
+{"mfhc0",		"t,G",		0x000000f4, 0xfc00ffff,	WR_1|RD_C0,		0,		0,		XPA,	0 },
+{"mfhc0",		"t,G,H",	0x000000f4, 0xfc00c7ff,	WR_1|RD_C0,		0,		0,		XPA,	0 },
+{"mfhgc0",		"t,G",		0x000004f4, 0xfc00ffff,	WR_1|RD_C0,		0,		0,		IVIRT_XPA,	0 },
+{"mfhgc0",		"t,G,H",	0x000004f4, 0xfc00c7ff,	WR_1|RD_C0,		0,		0,		IVIRT_XPA,	0 },
 {"mfhc1",		"t,S",		0x5400303b, 0xfc00ffff,	WR_1|RD_2|FP_D|LC,	0,		I1,		0,	0 },
 {"mfhc1",		"t,G",		0x5400303b, 0xfc00ffff,	WR_1|RD_2|FP_D|LC,	0,		I1,		0,	0 },
 {"mfhc2",		"t,G",		0x00008d3c, 0xfc00ffff,	WR_1|RD_C2,		0,		I1,		0,	0 },
@@ -872,6 +882,10 @@ const struct mips_opcode micromips_opcodes[] =
 {"mtc2",		"t,G",		0x00005d3c, 0xfc00ffff,	RD_1|WR_C2|WR_CC,	0,		I1,		0,	0 },
 {"mtgc0",		"t,G",		0x000006fc, 0xfc00ffff,	RD_1|WR_C0|WR_CC,	0,		0,		IVIRT,	0 },
 {"mtgc0",		"t,G,H",	0x000006fc, 0xfc00c7ff,	RD_1|WR_C0|WR_CC,	0,		0,		IVIRT,	0 },
+{"mthc0",		"t,G",		0x000002f4, 0xfc00ffff,	RD_1|WR_C0|WR_CC,	0,		0,		XPA,	0 },
+{"mthc0",		"t,G,H",	0x000002f4, 0xfc00c7ff,	RD_1|WR_C0|WR_CC,	0,		0,		XPA,	0 },
+{"mthgc0",		"t,G",		0x000006f4, 0xfc00ffff,	RD_1|WR_C0|WR_CC,	0,		0,		IVIRT_XPA,	0 },
+{"mthgc0",		"t,G,H",	0x000006f4, 0xfc00c7ff,	RD_1|WR_C0|WR_CC,	0,		0,		IVIRT_XPA,	0 },
 {"mthc1",		"t,S",		0x5400383b, 0xfc00ffff,	RD_1|WR_2|FP_D|CM,	0,		I1,		0,	0 },
 {"mthc1",		"t,G",		0x5400383b, 0xfc00ffff,	RD_1|WR_2|FP_D|CM,	0,		I1,		0,	0 },
 {"mthc2",		"t,G",		0x00009d3c, 0xfc00ffff,	RD_1|WR_C2|WR_CC,	0,		I1,		0,	0 },
diff --git a/opcodes/mips-opc.c b/opcodes/mips-opc.c
index a0b0e26..2e069d2 100644
--- a/opcodes/mips-opc.c
+++ b/opcodes/mips-opc.c
@@ -323,6 +323,7 @@ decode_mips_operand (const char *p)
 #define XLR     INSN_XLR
 #define IVIRT	ASE_VIRT
 #define IVIRT64	ASE_VIRT64
+#define IVIRT_XPA ASE_VIRT_XPA
 
 #define G1      (T3             \
                  |EE            \
@@ -1384,8 +1385,8 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"mfgc0",		"t,G,H",	0x40600000, 0xffe007f8, WR_1|RD_C0|LC,		0,		0,		IVIRT,	0 },
 {"mfhc0",		"t,G",		0x40400000, 0xffe007ff,	WR_1|RD_C0|LC,		0,		I33,		XPA,	0 },
 {"mfhc0",		"t,G,H",	0x40400000, 0xffe007f8,	WR_1|RD_C0|LC,		0,		I33,		XPA,	0 },
-{"mfhgc0",		"t,G",		0x40600400, 0xffe007ff,	WR_1|RD_C0|LC,		0,		I33,		IVIRT|XPA,	0 },
-{"mfhgc0",		"t,G,H",	0x40600400, 0xffe007f8,	WR_1|RD_C0|LC,		0,		I33,		IVIRT|XPA,	0 },
+{"mfhgc0",		"t,G",		0x40600400, 0xffe007ff,	WR_1|RD_C0|LC,		0,		I33,		IVIRT_XPA,	0 },
+{"mfhgc0",		"t,G,H",	0x40600400, 0xffe007f8,	WR_1|RD_C0|LC,		0,		I33,		IVIRT_XPA,	0 },
 {"mfc1",		"t,S",		0x44000000, 0xffe007ff,	WR_1|RD_2|LC|FP_S,	0,		I1,		0,	0 },
 {"mfc1",		"t,G",		0x44000000, 0xffe007ff,	WR_1|RD_2|LC|FP_S,	0,		I1,		0,	0 },
 {"mfhc1",		"t,S",		0x44600000, 0xffe007ff,	WR_1|RD_2|LC|FP_D,	0,		I33,		0,	0 },
@@ -1482,8 +1483,8 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"mtgc0",		"t,G,H",	0x40600200, 0xffe007f8, RD_1|WR_C0|WR_CC|CM,   0,		0,		IVIRT,	0 },
 {"mthc0",		"t,G",		0x40c00000, 0xffe007ff,	RD_1|WR_C0|WR_CC|CM,	0,		I33,		XPA,	0 },
 {"mthc0",		"t,G,H",	0x40c00000, 0xffe007f8,	RD_1|WR_C0|WR_CC|CM,	0,		I33,		XPA,	0 },
-{"mthgc0",		"t,G",		0x40600600, 0xffe007ff,	RD_1|WR_C0|WR_CC|CM,	0,		I33,		IVIRT|XPA,	0 },
-{"mthgc0",		"t,G,H",	0x40600600, 0xffe007f8,	RD_1|WR_C0|WR_CC|CM,	0,		I33,		IVIRT|XPA,	0 },
+{"mthgc0",		"t,G",		0x40600600, 0xffe007ff,	RD_1|WR_C0|WR_CC|CM,	0,		I33,		IVIRT_XPA,	0 },
+{"mthgc0",		"t,G,H",	0x40600600, 0xffe007f8,	RD_1|WR_C0|WR_CC|CM,	0,		I33,		IVIRT_XPA,	0 },
 {"mtc1",		"t,S",		0x44800000, 0xffe007ff,	RD_1|WR_2|CM|FP_S,	0,		I1,		0,	0 },
 {"mtc1",		"t,G",		0x44800000, 0xffe007ff,	RD_1|WR_2|CM|FP_S,	0,		I1,		0,	0 },
 {"mthc1",		"t,S",		0x44e00000, 0xffe007ff,	RD_1|WR_2|CM|FP_D,	0,		I33,		0,	0 },



More information about the Binutils mailing list