This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
RE: [PATCH] Add XPA ASE and MIPS R5 microMIPS support
- From: Andrew Bennett <Andrew dot Bennett at imgtec dot com>
- To: Richard Sandiford <rdsandiford at googlemail dot com>, Matthew Fortune <Matthew dot Fortune at imgtec dot com>
- Cc: "binutils at sourceware dot org" <binutils at sourceware dot org>
- Date: Thu, 19 Mar 2015 23:05:28 +0000
- Subject: RE: [PATCH] Add XPA ASE and MIPS R5 microMIPS support
- Authentication-results: sourceware.org; auth=none
- References: <0DA23CC379F5F945ACB41CF394B9827720F811E1 at LEMAIL01 dot le dot imgtec dot org> <0DA23CC379F5F945ACB41CF394B9827720F818D4 at LEMAIL01 dot le dot imgtec dot org> <87oao23pqd dot fsf at googlemail dot com> <6D39441BF12EF246A7ABCE6654B0235321002A6B at LEMAIL01 dot le dot imgtec dot org> <87oanz2r60 dot fsf at googlemail dot com>
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 },