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]

[PATCH] Add MIPS User Defined Instruction support


Hello All,

the appended patch adds support for udi0 - udi15 user defined
instructions. This is part of forward-porting features from
MIPS Technologies' SDE6 toolchain, they are in production use
for quite a while now.


Thiemo


[ gas/ChangeLog ]
2006-04-27  Thiemo Seufer  <ths@mips.com>
            David Ung  <davidu@mips.com>

	* config/tc-mips.c (validate_mips_insn): Handling of udi cases.
	(mips_immed): New table that records various handling of udi
	instruction patterns.
	(mips_ip): Adds udi handling.

[ include/opcode/ChangeLog ]
2006-04-27  Thiemo Seufer  <ths@mips.com>
            David Ung  <davidu@mips.com>

	* mips.h: Defines udi bits and masks.  Add description of
	characters which may appear in the args field of udi
	instructions. 

[ opcodes/ChangeLog ]
2006-04-27  Thiemo Seufer  <ths@mips.com>
            David Ung  <davidu@mips.com>

	* mips-opc.c (mips_builtin_opcodes): Add udi instructions
	"udi0" to "udi15".
	* mips-dis.c (print_insn_args): Adds udi argument handling.


Index: gas/config/tc-mips.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mips.c,v
retrieving revision 1.329
diff -u -p -r1.329 tc-mips.c
--- gas/config/tc-mips.c	23 Apr 2006 22:12:43 -0000	1.329
+++ gas/config/tc-mips.c	27 Apr 2006 16:14:20 -0000
@@ -7814,6 +7814,10 @@ validate_mips_insn (const struct mips_op
       case '+':
     	switch (c = *p++)
 	  {
+	  case '1': USE_BITS (OP_MASK_UDI1,     OP_SH_UDI1); 	break;
+	  case '2': USE_BITS (OP_MASK_UDI2,	OP_SH_UDI2); 	break;
+	  case '3': USE_BITS (OP_MASK_UDI3,	OP_SH_UDI3); 	break;
+	  case '4': USE_BITS (OP_MASK_UDI4,	OP_SH_UDI4); 	break;
 	  case 'A': USE_BITS (OP_MASK_SHAMT,	OP_SH_SHAMT);	break;
 	  case 'B': USE_BITS (OP_MASK_INSMSB,	OP_SH_INSMSB);	break;
 	  case 'C': USE_BITS (OP_MASK_EXTMSBD,	OP_SH_EXTMSBD);	break;
@@ -7919,6 +7923,22 @@ validate_mips_insn (const struct mips_op
   return 1;
 }
 
+/* UDI immediates.  */
+struct mips_immed {
+  char		type;
+  unsigned int	shift;
+  unsigned long	mask;
+  const char *	desc;
+};
+
+static const struct mips_immed mips_immed[] = {
+  { '1',	OP_SH_UDI1,	OP_MASK_UDI1,		0},
+  { '2',	OP_SH_UDI2,	OP_MASK_UDI2,		0},
+  { '3',	OP_SH_UDI3,	OP_MASK_UDI3,		0},
+  { '4',	OP_SH_UDI4,	OP_MASK_UDI4,		0},
+  { 0,0,0,0 }
+};
+
 /* This routine assembles an instruction into its binary format.  As a
    side effect, it sets one of the global variables imm_reloc or
    offset_reloc to the type of relocation to do if one of the operands
@@ -8324,6 +8344,34 @@ mips_ip (char *str, struct mips_cl_insn 
 	    case '+':		/* Opcode extension character.  */
 	      switch (*++args)
 		{
+		case '1':	/* UDI immediates.  */
+		case '2':
+		case '3':
+		case '4':
+		  {
+		    const struct mips_immed *imm = mips_immed;
+
+		    while (imm->type && imm->type != *args)
+		      ++imm;
+		    if (! imm->type)
+		      internalError ();
+		    my_getExpression (&imm_expr, s);
+		    check_absolute_expr (ip, &imm_expr);
+		    if ((unsigned long) imm_expr.X_add_number & ~imm->mask)
+		      {
+		        as_warn (_("Illegal %s number (%lu, 0x%lx)"),
+				 imm->desc ? imm->desc : ip->insn_mo->name,
+				 (unsigned long) imm_expr.X_add_number,
+				 (unsigned long) imm_expr.X_add_number);
+			      imm_expr.X_add_number &= imm->mask;
+		      }
+		    ip->insn_opcode |= ((unsigned long) imm_expr.X_add_number
+					<< imm->shift);
+		    imm_expr.X_op = O_absent;
+		    s = expr_end;
+		  }
+		  continue;
+		  
 		case 'A':		/* ins/ext position, becomes LSB.  */
 		  limlo = 0;
 		  limhi = 31;
Index: include/opcode/mips.h
===================================================================
RCS file: /cvs/src/src/include/opcode/mips.h,v
retrieving revision 1.47
diff -u -p -r1.47 mips.h
--- include/opcode/mips.h	26 Apr 2006 18:19:15 -0000	1.47
+++ include/opcode/mips.h	27 Apr 2006 16:14:21 -0000
@@ -203,6 +203,16 @@ Software Foundation, 51 Franklin Street 
 #define MDMX_FMTSEL_VEC_QH	0x15
 #define MDMX_FMTSEL_VEC_OB	0x16
 
+/* UDI */
+#define OP_SH_UDI1		6
+#define OP_MASK_UDI1		0x1f
+#define OP_SH_UDI2		6
+#define OP_MASK_UDI2		0x3ff
+#define OP_SH_UDI3		6
+#define OP_MASK_UDI3		0x7fff
+#define OP_SH_UDI4		6
+#define OP_MASK_UDI4		0xfffff
+
 /* This structure holds information for a particular instruction.  */
 
 struct mips_opcode
@@ -351,6 +361,12 @@ struct mips_opcode
    "+t" 5 bit coprocessor 0 destination register (OP_*_RT)
    "+T" 5 bit coprocessor 0 destination register (OP_*_RT) - disassembly only
 
+   UDI immediates:
+   "+1" UDI immediate bits 6-10
+   "+2" UDI immediate bits 6-15
+   "+3" UDI immediate bits 6-20
+   "+4" UDI immediate bits 6-25
+
    Other:
    "()" parens surrounding optional value
    ","  separates operands
@@ -365,6 +381,7 @@ struct mips_opcode
 
    Extension character sequences used so far ("+" followed by the
    following), for quick reference when adding more:
+   "1234"
    "ABCDEFGHIT"
    "t"
 */
Index: opcodes/mips-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/mips-dis.c,v
retrieving revision 1.55
diff -u -p -r1.55 mips-dis.c
--- opcodes/mips-dis.c	14 Nov 2005 02:25:39 -0000	1.55
+++ opcodes/mips-dis.c	27 Apr 2006 16:14:23 -0000
@@ -728,6 +728,26 @@ print_insn_args (const char *d,
 	      (*info->fprintf_func) (info->stream, "0x%x", msb - lsb + 1);
 	      break;
 
+	    case '1':
+	      (*info->fprintf_func) (info->stream, "0x%lx",
+				     (l >> OP_SH_UDI1) & OP_MASK_UDI1);
+	      break;
+	      
+	    case '2':
+	      (*info->fprintf_func) (info->stream, "0x%lx",
+				     (l >> OP_SH_UDI2) & OP_MASK_UDI2);
+	      break;
+	      
+	    case '3':
+	      (*info->fprintf_func) (info->stream, "0x%lx",
+				     (l >> OP_SH_UDI3) & OP_MASK_UDI3);
+	      break;
+      
+	    case '4':
+	      (*info->fprintf_func) (info->stream, "0x%lx",
+				     (l >> OP_SH_UDI4) & OP_MASK_UDI4);
+	      break;
+	      
 	    case 'C':
 	    case 'H':
 	      msbd = (l >> OP_SH_EXTMSBD) & OP_MASK_EXTMSBD;
Index: opcodes/mips-opc.c
===================================================================
RCS file: /cvs/src/src/opcodes/mips-opc.c,v
retrieving revision 1.54
diff -u -p -r1.54 mips-opc.c
--- opcodes/mips-opc.c	26 Jan 2006 15:14:57 -0000	1.54
+++ opcodes/mips-opc.c	27 Apr 2006 16:14:23 -0000
@@ -1263,6 +1263,72 @@ const struct mips_opcode mips_builtin_op
 {"yield",   "s",	0x7c000009, 0xfc1fffff, TRAP|RD_s,		0,		MT32	},
 {"yield",   "d,s",	0x7c000009, 0xfc1f07ff, TRAP|WR_d|RD_s,		0,		MT32	},
 
+/* User Defined Instruction.  */
+{"udi0",     "s,t,d,+1",0x70000010, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi0",     "s,t,+2",	0x70000010, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi0",     "s,+3",	0x70000010, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi0",     "+4",	0x70000010, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi1",     "s,t,d,+1",0x70000011, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi1",     "s,t,+2",	0x70000011, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi1",     "s,+3",	0x70000011, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi1",     "+4",	0x70000011, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi2",     "s,t,d,+1",0x70000012, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi2",     "s,t,+2",	0x70000012, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi2",     "s,+3",	0x70000012, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi2",     "+4",	0x70000012, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi3",     "s,t,d,+1",0x70000013, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi3",     "s,t,+2",	0x70000013, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi3",     "s,+3",	0x70000013, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi3",     "+4",	0x70000013, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi4",     "s,t,d,+1",0x70000014, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi4",     "s,t,+2",	0x70000014, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi4",     "s,+3",	0x70000014, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi4",     "+4",	0x70000014, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi5",     "s,t,d,+1",0x70000015, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi5",     "s,t,+2",	0x70000015, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi5",     "s,+3",	0x70000015, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi5",     "+4",	0x70000015, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi6",     "s,t,d,+1",0x70000016, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi6",     "s,t,+2",	0x70000016, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi6",     "s,+3",	0x70000016, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi6",     "+4",	0x70000016, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi7",     "s,t,d,+1",0x70000017, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi7",     "s,t,+2",	0x70000017, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi7",     "s,+3",	0x70000017, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi7",     "+4",	0x70000017, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi8",     "s,t,d,+1",0x70000018, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi8",     "s,t,+2",	0x70000018, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi8",     "s,+3",	0x70000018, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi8",     "+4",	0x70000018, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi9",     "s,t,d,+1",0x70000019, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi9",      "s,t,+2",	0x70000019, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi9",     "s,+3",	0x70000019, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi9",     "+4",	0x70000019, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi10",    "s,t,d,+1",0x7000001a, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi10",    "s,t,+2",	0x7000001a, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi10",    "s,+3",	0x7000001a, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi10",    "+4",	0x7000001a, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi11",    "s,t,d,+1",0x7000001b, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi11",    "s,t,+2",	0x7000001b, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi11",    "s,+3",	0x7000001b, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi11",    "+4",	0x7000001b, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi12",    "s,t,d,+1",0x7000001c, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi12",    "s,t,+2",	0x7000001c, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi12",    "s,+3",	0x7000001c, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi12",    "+4",	0x7000001c, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi13",    "s,t,d,+1",0x7000001d, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi13",    "s,t,+2",	0x7000001d, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi13",    "s,+3",	0x7000001d, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi13",    "+4",	0x7000001d, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi14",    "s,t,d,+1",0x7000001e, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi14",    "s,t,+2",	0x7000001e, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi14",    "s,+3",	0x7000001e, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi14",    "+4",	0x7000001e, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi15",    "s,t,d,+1",0x7000001f, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi15",    "s,t,+2",	0x7000001f, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi15",    "s,+3",	0x7000001f, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+{"udi15",    "+4",	0x7000001f, 0xfc00003f,	WR_d|RD_s|RD_t,		0,		I33	},
+
 /* Coprocessor 2 move/branch operations overlap with VR5400 .ob format
    instructions so they are here for the latters to take precedence.  */
 {"bc2f",    "p",	0x49000000, 0xffff0000,	CBD|RD_CC,		0,		I1	},


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