This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: [PATCH] Add MIPS ufr macro instruction


>> Seems like this might have hit a log-jam, so just in case, what I really
>> meant was: please answer David's question first.

> Hi Richard,

> Sorry for the delay in the replying I have been thinking about David's comments.
> David, I agree with you, having ufr as an actual instruction, rather than a macro 
> would make it much clearer to see it's use when disassembling a program.

> I am currently changing the patch to reflect these changes, and will post it back
> in the next few days.

The updated patch and ChangeLog entry is below. 

Regards,


Andrew
 

2013-11-20  Andrew Bennett  <andrew.bennett@imgtec.com>
	gas/config/
	* tc-mips.c (operand_reg_mask): Add OP_UFR_INT case.
	(match_operand): Likewise.
	(match_ufr_operand): New function.

	gas/testsuite/gas/mips/
	* mips.exp: Added ufr test.
	* ufr.d: New test.
	* ufr.s: New test.

	include/opcode/
	* mips.h: Updated the arg field character information for MIPS and 
	microMIPS.  
	(mips_operand_type): Add OP_UFR_INT.

	opcodes/
	* micromips-opc.c (decode_micromips_operand): Added support for the ?
	character.
	(micromips_opcodes): Added the ufr instruction.
	* opcodes/mips-opc.c (decode_mips_operand): Added support for the ?
	character.
	(mips_builtin_opcodes): Added the ufr instruction.
	* opcodes/mips-dis.c (print_insn_arg): Add OP_UFR_INT case.
	(print_insn_mips): Don't try to disassemble ufr instruction 
	if the coprocessor register number is not 1 or 4.
	(print_insn_micromips): Likewise.



---
 gas/config/tc-mips.c            |   39 ++++++++++++++++++++++++++++++++++++
 gas/testsuite/gas/mips/mips.exp |    1 +
 gas/testsuite/gas/mips/ufr.d    |   42 +++++++++++++++++++++++++++++++++++++++
 gas/testsuite/gas/mips/ufr.s    |   38 +++++++++++++++++++++++++++++++++++
 include/opcode/mips.h           |   16 ++++++++++++---
 opcodes/micromips-opc.c         |    2 ++
 opcodes/mips-dis.c              |   30 ++++++++++++++++++++++++++++
 opcodes/mips-opc.c              |    2 ++
 8 files changed, 167 insertions(+), 3 deletions(-)
 create mode 100644 gas/testsuite/gas/mips/ufr.d
 create mode 100644 gas/testsuite/gas/mips/ufr.s

diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index 34f1bf0..dab2889 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -4031,6 +4031,18 @@ operand_reg_mask (const struct mips_cl_insn *insn,
     case OP_IMM_INDEX:
       abort ();
 
+    case OP_UFR_INT:
+      {
+        if ((type_mask & (1 << OP_REG_GP)))
+          /* ufr implicitly uses the zero reg */
+          return 1;
+        else if ((type_mask & (1 << OP_REG_COPRO)))
+          /* ufr only works with control regs 1 and 4 */
+          return (1 << 1) | (1 << 4);
+        else
+          return 0;
+      }
+
     case OP_REG:
     case OP_OPTIONAL_REG:
       {
@@ -4796,6 +4808,30 @@ match_perf_reg_operand (struct mips_arg_info *arg,
   return TRUE;
 }
 
+/* OP_UFR matcher.  */
+
+static bfd_boolean
+match_ufr_operand (struct mips_arg_info *arg,
+                   const struct mips_operand *operand)
+{
+  offsetT sval;
+
+  if (!match_const_int (arg, &sval))
+    return FALSE;
+
+  switch (sval)
+    {
+    case 0:
+      insn_insert_operand (arg->insn, operand, 1);
+      return TRUE;
+    case 1:
+      insn_insert_operand (arg->insn, operand, 4);
+      return TRUE;
+    default:
+      match_out_of_range (arg);
+      return FALSE;
+    }
+}
 /* OP_ADDIUSP matcher.  */
 
 static bfd_boolean
@@ -5470,6 +5506,9 @@ match_operand (struct mips_arg_info *arg,
     case OP_PERF_REG:
       return match_perf_reg_operand (arg, operand);
 
+    case OP_UFR_INT:
+      return match_ufr_operand (arg, operand);
+
     case OP_ADDIUSP_INT:
       return match_addiusp_operand (arg, operand);
 
diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp
index 121566a..68514c5 100644
--- a/gas/testsuite/gas/mips/mips.exp
+++ b/gas/testsuite/gas/mips/mips.exp
@@ -1156,4 +1156,5 @@ if { [istarget mips*-*-vxworks*] } {
     run_dump_test_arches "msa64"	[mips_arch_list_matching mips64r2]
     run_dump_test_arches "msa-relax"	[mips_arch_list_matching mips32r2]
     run_dump_test_arches "msa-branch"	[mips_arch_list_matching mips32r2]
+    run_dump_test_arches "ufr"		[mips_arch_list_matching mips32r2]
 }
diff --git a/gas/testsuite/gas/mips/ufr.d b/gas/testsuite/gas/mips/ufr.d
new file mode 100644
index 0000000..4fc1421
--- /dev/null
+++ b/gas/testsuite/gas/mips/ufr.d
@@ -0,0 +1,42 @@
+#objdump: -d --prefix-addresses
+#name: MIPS ufr
+
+# Test the ufr instruction.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> ufr	0
+0+0004 <[^>]*> ufr	1
+0+0008 <[^>]*> ctc1	zero,\$0
+0+000c <[^>]*> ufr	0
+0+0010 <[^>]*> ctc1	zero,\$2
+0+0014 <[^>]*> ctc1	zero,\$3
+0+0018 <[^>]*> ufr	1
+0+001c <[^>]*> ctc1	zero,\$5
+0+0020 <[^>]*> ctc1	zero,\$6
+0+0024 <[^>]*> ctc1	zero,\$7
+0+0028 <[^>]*> ctc1	zero,\$8
+0+002c <[^>]*> ctc1	zero,\$9
+0+0030 <[^>]*> ctc1	zero,\$10
+0+0034 <[^>]*> ctc1	zero,\$11
+0+0038 <[^>]*> ctc1	zero,\$12
+0+003c <[^>]*> ctc1	zero,\$13
+0+0040 <[^>]*> ctc1	zero,\$14
+0+0044 <[^>]*> ctc1	zero,\$15
+0+0048 <[^>]*> ctc1	zero,\$16
+0+004c <[^>]*> ctc1	zero,\$17
+0+0050 <[^>]*> ctc1	zero,\$18
+0+0054 <[^>]*> ctc1	zero,\$19
+0+0058 <[^>]*> ctc1	zero,\$20
+0+005c <[^>]*> ctc1	zero,\$21
+0+0060 <[^>]*> ctc1	zero,\$22
+0+0064 <[^>]*> ctc1	zero,\$23
+0+0068 <[^>]*> ctc1	zero,\$24
+0+006c <[^>]*> ctc1	zero,\$25
+0+0070 <[^>]*> ctc1	zero,\$26
+0+0074 <[^>]*> ctc1	zero,\$27
+0+0078 <[^>]*> ctc1	zero,\$28
+0+007c <[^>]*> ctc1	zero,\$29
+0+0080 <[^>]*> ctc1	zero,\$30
+0+0084 <[^>]*> ctc1	zero,\$31
diff --git a/gas/testsuite/gas/mips/ufr.s b/gas/testsuite/gas/mips/ufr.s
new file mode 100644
index 0000000..433e3f6
--- /dev/null
+++ b/gas/testsuite/gas/mips/ufr.s
@@ -0,0 +1,38 @@
+# Source file used to test the ufr instruction.
+
+       .text
+foo:
+       ufr 0
+       ufr 1
+       ctc1 $0,$f0
+       ctc1 $0,$f1
+       ctc1 $0,$f2
+       ctc1 $0,$f3
+       ctc1 $0,$f4
+       ctc1 $0,$f5
+       ctc1 $0,$f6
+       ctc1 $0,$f7
+       ctc1 $0,$f8
+       ctc1 $0,$f9
+       ctc1 $0,$f10
+       ctc1 $0,$f11
+       ctc1 $0,$f12
+       ctc1 $0,$f13
+       ctc1 $0,$f14
+       ctc1 $0,$f15
+       ctc1 $0,$f16
+       ctc1 $0,$f17
+       ctc1 $0,$f18
+       ctc1 $0,$f19
+       ctc1 $0,$f20
+       ctc1 $0,$f21
+       ctc1 $0,$f22
+       ctc1 $0,$f23
+       ctc1 $0,$f24
+       ctc1 $0,$f25
+       ctc1 $0,$f26
+       ctc1 $0,$f27
+       ctc1 $0,$f28
+       ctc1 $0,$f29
+       ctc1 $0,$f30
+       ctc1 $0,$f31
diff --git a/include/opcode/mips.h b/include/opcode/mips.h
index c9dc52b..80e85c7 100644
--- a/include/opcode/mips.h
+++ b/include/opcode/mips.h
@@ -419,7 +419,13 @@ enum mips_operand_type {
   OP_IMM_INDEX,
 
   /* An index selected by a register, e.g. [$2].  */
-  OP_REG_INDEX
+  OP_REG_INDEX,
+
+  /* An operand to the ufr instruction.  The only values that are allowed are 0 and 1.
+     They are mapped in the following manner:
+     0 => 1
+     1 => 4 */
+  OP_UFR_INT
 };
 
 /* Enumerates the types of MIPS register.  */
@@ -807,6 +813,8 @@ struct mips_opcode
    "P" 5 bit performance-monitor register (OP_*_PERFREG)
    "e" 5 bit vector register byte specifier (OP_*_VECBYTE)
    "%" 3 bit immediate vr5400 vector alignment operand (OP_*_VECALIGN)
+   "?" 5 bit destination register.  It is used to set the FR mode, only
+       allowed values are 1 (FR = 0) and 4 (FR = 1).
 
    Macro instructions:
    "A" General 32 bit expression
@@ -936,7 +944,7 @@ struct mips_opcode
 
    Characters used so far, for quick reference when adding more:
    "1234567890"
-   "%[]<>(),+:'@!#$*&\~"
+   "%[]<>(),+:'@!#$*&\~?"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "abcdefghijklopqrstuvwxz"
 
@@ -2062,6 +2070,8 @@ extern const int bfd_mips16_num_opcodes;
    "E" 5-bit target register (MICROMIPSOP_*_RT)
    "G" 5-bit source register (MICROMIPSOP_*_RS)
    "H" 3-bit sel field for (D)MTC* and (D)MFC* (MICROMIPSOP_*_SEL)
+   "?" 5 bit target register.  It is used to set the FR mode, only
+       allowed values are 1 (FR = 0) and 4 (FR = 1).
 
    Macro instructions:
    "A" general 32 bit expression
@@ -2121,7 +2131,7 @@ extern const int bfd_mips16_num_opcodes;
 
    Characters used so far, for quick reference when adding more:
    "12345678 0"
-   "<>(),+.@\^|~"
+   "<>(),+.@\^|~?"
    "ABCDEFGHI KLMN   RST V    "
    "abcd f hijklmnopqrstuvw yz"
 
diff --git a/opcodes/micromips-opc.c b/opcodes/micromips-opc.c
index a68916a..702e6c7 100644
--- a/opcodes/micromips-opc.c
+++ b/opcodes/micromips-opc.c
@@ -147,6 +147,7 @@ decode_micromips_operand (const char *p)
     case '~': SINT (12, 0);
     case '@': SINT (10, 16);
     case '^': HINT (5, 11);
+    case '?': SPECIAL (5, 16, UFR_INT);
 
     case '0': SINT (6, 16);
     case '1': HINT (5, 16);
@@ -546,6 +547,7 @@ const struct mips_opcode micromips_opcodes[] =
 {"clo",			"t,s",		0x00004b3c, 0xfc00ffff,	WR_1|RD_2,		0,		I1,		0,	0 },
 {"clz",			"t,s",		0x00005b3c, 0xfc00ffff,	WR_1|RD_2,		0,		I1,		0,	0 },
 {"cop2",		"C",		0x00000002, 0xfc000007,	CP,			0,		I1,		0,	0 },
+{"ufr",			"?",		0x5400183b, 0xffe0ffff,	RD_1|WR_CC|FP_S,	0,		I1,		0,	0 },
 {"ctc1",		"t,G",		0x5400183b, 0xfc00ffff,	RD_1|WR_CC|FP_S,	0,		I1,		0,	0 },
 {"ctc1",		"t,S",		0x5400183b, 0xfc00ffff,	RD_1|WR_CC|FP_S,	0,		I1,		0,	0 },
 {"ctc2",		"t,G",		0x0000dd3c, 0xfc00ffff,	RD_1|WR_C2|WR_CC,	0,		I1,		0,	0 },
diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c
index 1929ffc..a903b4e 100644
--- a/opcodes/mips-dis.c
+++ b/opcodes/mips-dis.c
@@ -1114,6 +1114,22 @@ print_insn_arg (struct disassemble_info *info,
       infprintf (is, "%d", uval);
       break;
 
+    case OP_UFR_INT:
+      {
+        switch (uval)
+          {
+          case 1:
+            infprintf (is, "0");
+            break;
+          case 4:
+            infprintf (is, "1");
+            break;
+          default:
+            abort ();
+          }
+        break;
+      }
+
     case OP_ADDIUSP_INT:
       {
 	int sval;
@@ -1427,6 +1443,13 @@ print_insn_mips (bfd_vma memaddr,
 	      && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
 	      && (word & op->mask) == op->match)
 	    {
+	      if (strcmp (op->name, "ufr") == 0)
+                {
+                  unsigned int val = (word >> 11) & 0x1F;
+                  if (val != 1 && val != 4)
+                    continue;
+                }
+
 	      /* We always allow to disassemble the jalx instruction.  */
 	      if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
 		  && strcmp (op->name, "jalx"))
@@ -1974,6 +1997,13 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
 	  && ((length == 2 && (op->mask & 0xffff0000) == 0)
 	      || (length == 4 && (op->mask & 0xffff0000) != 0)))
 	{
+	  if (strcmp (op->name, "ufr") == 0)
+            {
+              unsigned int val = (insn >> 16) & 0x1F;
+              if (val != 1 && val != 4)
+                continue;
+            }
+
 	  infprintf (is, "%s", op->name);
 
 	  if (op->args[0])
diff --git a/opcodes/mips-opc.c b/opcodes/mips-opc.c
index cd43185..9f13702 100644
--- a/opcodes/mips-opc.c
+++ b/opcodes/mips-opc.c
@@ -130,6 +130,7 @@ decode_mips_operand (const char *p)
     case '&': REG (2, 13, ACC);
     case '~': SINT (12, 0);
     case '\\': BIT (3, 12, 0);			/* (0 .. 7) */
+    case '?': SPECIAL (5, 11, UFR_INT);
 
     case '0': SINT (6, 20);
     case '1': HINT (5, 6);
@@ -911,6 +912,7 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"clo",			"U,s",		0x70000021, 0xfc0007ff, WR_1|RD_2, 	0,		I32|N55,	0,	0 },
 {"clz",			"U,s",		0x70000020, 0xfc0007ff, WR_1|RD_2, 	0,		I32|N55,	0,	0 },
 {"ctc0",		"t,G",		0x40c00000, 0xffe007ff,	RD_1|WR_CC|COD,		0,		I1,		0,	IOCT|IOCTP|IOCT2 },
+{"ufr",			"?",		0x44c00000, 0xffff07ff,	RD_1|WR_CC|COD|FP_S,	0,		I1,		0,	0 },
 {"ctc1",		"t,G",		0x44c00000, 0xffe007ff,	RD_1|WR_CC|COD|FP_S,	0,		I1,		0,	0 },
 {"ctc1",		"t,S",		0x44c00000, 0xffe007ff,	RD_1|WR_CC|COD|FP_S,	0,		I1,		0,	0 },
 /* ctc2 is at the bottom of the table.  */
-- 
1.7.10.1



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]