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, MIPS] Add Octeon instructions seq* and sne*


I wanted to keep this separate from the other instructions because this
changes the related macros, seq and sne.

For small immediates we can expand the immediate variants of these
instructions.  If the immediate is big enough so that we need to load it into
a register we can expand the register variants instead of using xor and sltu.
For the other cases I kept the original expansions as they are equally good on
Octeon.

Tested on mips64octeon-linux-gnu.

OK to install?

Adam


include/opcode/

	* mips.h: Document new field descriptors +Q.
	(OP_SH_SEQI, OP_MASK_SEQI): New bit mask and shift count for SEQI.

opcodes/

	* mips-dis.c (print_insn_args): Handle field descriptor +Q.
	* mips-opc.c (mips_builtin_opcodes): Add Octeon instructions seq,
	seqi, sne and snei.

gas/

	* config/tc-mips.c (validate_mips_insn): Handle field descriptor +Q.
	(mips_ip): Likewise.
	(macro_build): Likewise.
	(CPU_HAS_SEQ): New macro.
	(macro2) <M_SEQ_I, M_SNE_I>: Use it.  Emit seq/sne and seqi/snei.

gas/testsuite/

	* gas/mips/octeon.s, gas/mips/octeon.d: Add tests for seq* and sne*.
	* gas/mips/octeon-ill.s, gas/mips/octeon-ill.s: Add tests for seqi
	and snei.

Index: src/include/opcode/mips.h
===================================================================
--- src.orig/include/opcode/mips.h	2008-05-16 17:13:26.000000000 -0700
+++ src/include/opcode/mips.h	2008-05-17 20:28:15.000000000 -0700
@@ -222,6 +222,8 @@ Software Foundation, 51 Franklin Street 
 #define OP_MASK_CINSPOS		0x1f
 #define OP_SH_CINSLM1		11
 #define OP_MASK_CINSLM1		0x1f
+#define OP_SH_SEQI		6
+#define OP_MASK_SEQI		0x3ff
 
 /* This structure holds information for a particular instruction.  */
 
@@ -385,6 +387,7 @@ struct mips_opcode
    "+p" Position field of cins/cins32/exts/exts32. Enforces 0 <= pos < 32.
    "+P" Position field of cins/exts aliasing cins32/exts32.  Matches if
 	32 <= pos < 64, otherwise skips to next candidate.
+   "+Q" Immediate field of seqi/snei.  Enforces -512 <= imm < 512.
    "+s" Length-minus-one field of cins/exts.  Enforces: 0 <= lenm1 < 32.
    "+S" Length-minus-one field of cins32/exts32 or cins/exts aliasing
 	cint32/exts32.  Enforces non-negative value and that
@@ -406,7 +409,7 @@ struct mips_opcode
    Extension character sequences used so far ("+" followed by the
    following), for quick reference when adding more:
    "1234"
-   "ABCDEFGHIPSTX"
+   "ABCDEFGHIPQSTX"
    "pstx"
 */
 
Index: src/opcodes/mips-opc.c
===================================================================
--- src.orig/opcodes/mips-opc.c	2008-05-16 16:59:17.000000000 -0700
+++ src/opcodes/mips-opc.c	2008-05-19 09:10:52.000000000 -0700
@@ -1191,10 +1191,12 @@ const struct mips_opcode mips_builtin_op
 {"seh",     "d,w",	0x7c000620, 0xffe007ff,	WR_d|RD_t,		0,		I33	},
 {"selsl",   "d,v,t",	0x00000005, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		L1	},
 {"selsr",   "d,v,t",	0x00000001, 0xfc0007ff,	WR_d|RD_s|RD_t,		0,		L1	},
+{"seq",	    "d,v,t",	0x7000002a, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		IOCT	},
 {"seq",     "d,v,t",	0,    (int) M_SEQ,	INSN_MACRO,		0,		I1	},
 {"seq",     "d,v,I",	0,    (int) M_SEQ_I,	INSN_MACRO,		0,		I1	},
 {"seq",	"S,T",		0x46a00032,	0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,	IL2E	},
 {"seq",	"S,T",		0x4ba0000c,	0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,	IL2F	},
+{"seqi",    "t,r,+Q",	0x7000002e, 0xfc00003f, WR_t|RD_s,		0,		IOCT	},
 {"sge",     "d,v,t",	0,    (int) M_SGE,	INSN_MACRO,		0,		I1	},
 {"sge",     "d,v,I",	0,    (int) M_SGE_I,	INSN_MACRO,		0,		I1	},
 {"sgeu",    "d,v,t",	0,    (int) M_SGEU,	INSN_MACRO,		0,		I1	},
@@ -1246,8 +1248,10 @@ const struct mips_opcode mips_builtin_op
 {"sltu",    "d,v,I",	0,    (int) M_SLTU_I,	INSN_MACRO,		0,		I1	},
 {"sltu",	"S,T",		0x4680003c,	0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,	IL2E	},
 {"sltu",	"S,T",		0x4b80000d,	0xffe007ff,	RD_S|RD_T|WR_CC|FP_D,	0,	IL2F	},
+{"sne",	    "d,v,t",	0x7000002b, 0xfc0007ff, WR_d|RD_s|RD_t,		0,		IOCT	},
 {"sne",     "d,v,t",	0,    (int) M_SNE,	INSN_MACRO,		0,		I1	},
 {"sne",     "d,v,I",	0,    (int) M_SNE_I,	INSN_MACRO,		0,		I1	},
+{"snei",    "t,r,+Q",	0x7000002f, 0xfc00003f, WR_t|RD_s,		0,		IOCT	},
 {"sqrt.d",  "D,S",	0x46200004, 0xffff003f, WR_D|RD_S|FP_D,		0,		I2	},
 {"sqrt.s",  "D,S",	0x46000004, 0xffff003f, WR_D|RD_S|FP_S,		0,		I2	},
 {"sqrt.ps", "D,S",	0x46c00004, 0xffff003f, WR_D|RD_S|FP_D,		0,		SB1	},
Index: src/opcodes/mips-dis.c
===================================================================
--- src.orig/opcodes/mips-dis.c	2008-05-17 20:49:11.000000000 -0700
+++ src/opcodes/mips-dis.c	2008-05-17 23:34:43.000000000 -0700
@@ -902,6 +902,13 @@ print_insn_args (const char *d,
 				     (l >> OP_SH_CINSLM1) & OP_MASK_CINSLM1);
 	      break;
 
+	    case 'Q':		/* seqi/snei immediate field */
+	      op = (l >> OP_SH_SEQI) & OP_MASK_SEQI;
+	      /* Sign-extend it.  */
+	      op = (op ^ 512) - 512;
+	      (*info->fprintf_func) (info->stream, "%d", op);
+	      break;
+
 	    default:
 	      /* xgettext:c-format */
 	      (*info->fprintf_func) (info->stream,
Index: src/gas/config/tc-mips.c
===================================================================
--- src.orig/gas/config/tc-mips.c	2008-05-16 16:54:46.000000000 -0700
+++ src/gas/config/tc-mips.c	2008-05-21 23:05:41.000000000 -0700
@@ -444,6 +444,9 @@ static int mips_32bitmode = 0;
 /* True if CPU has a ror instruction.  */
 #define CPU_HAS_ROR(CPU)	CPU_HAS_DROR (CPU)
 
+/* True if CPU has seq/sne and seqi/snei instructions.  */
+#define CPU_HAS_SEQ(CPU)	((CPU) == CPU_OCTEON)
+
 /* True if mflo and mfhi can be immediately followed by instructions
    which write to the HI and LO registers.
 
@@ -3500,6 +3503,10 @@ macro_build (expressionS *ep, const char
 	      INSERT_OPERAND (EXTMSBD, insn, va_arg (args, int));
 	      continue;
 
+	    case 'Q':
+	      INSERT_OPERAND (SEQI, insn, va_arg (args, int));
+	      continue;
+
 	    default:
 	      internalError ();
 	    }
@@ -7541,6 +7548,14 @@ macro2 (struct mips_cl_insn *ip)
 	  move_register (dreg, 0);
 	  break;
 	}
+      if (CPU_HAS_SEQ (mips_opts.arch)
+	  && -512 <= imm_expr.X_add_number
+	  && imm_expr.X_add_number < 512)
+	{
+	  macro_build (NULL, "seqi", "t,r,+Q", dreg, sreg,
+		       imm_expr.X_add_number);
+	  break;
+	}
       if (imm_expr.X_op == O_constant
 	  && imm_expr.X_add_number >= 0
 	  && imm_expr.X_add_number < 0x10000)
@@ -7555,6 +7570,13 @@ macro2 (struct mips_cl_insn *ip)
 	  macro_build (&imm_expr, HAVE_32BIT_GPRS ? "addiu" : "daddiu",
 		       "t,r,j", dreg, sreg, BFD_RELOC_LO16);
 	}
+      else if (CPU_HAS_SEQ (mips_opts.arch))
+	{
+	  used_at = 1;
+	  load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+	  macro_build (NULL, "seq", "d,v,t", dreg, sreg, AT);
+	  break;
+	}
       else
 	{
 	  load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
@@ -7688,6 +7710,14 @@ macro2 (struct mips_cl_insn *ip)
 		       dreg, 0, BFD_RELOC_LO16);
 	  break;
 	}
+      if (CPU_HAS_SEQ (mips_opts.arch)
+	  && -512 <= imm_expr.X_add_number
+	  && imm_expr.X_add_number < 512)
+	{
+	  macro_build (NULL, "snei", "t,r,+Q", dreg, sreg,
+		       imm_expr.X_add_number);
+	  break;
+	}
       if (imm_expr.X_op == O_constant
 	  && imm_expr.X_add_number >= 0
 	  && imm_expr.X_add_number < 0x10000)
@@ -7702,6 +7732,13 @@ macro2 (struct mips_cl_insn *ip)
 	  macro_build (&imm_expr, HAVE_32BIT_GPRS ? "addiu" : "daddiu",
 		       "t,r,j", dreg, sreg, BFD_RELOC_LO16);
 	}
+      else if (CPU_HAS_SEQ (mips_opts.arch))
+	{
+	  used_at = 1;
+	  load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
+	  macro_build (NULL, "sne", "d,v,t", dreg, sreg, AT);
+	  break;
+	}
       else
 	{
 	  load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
@@ -8272,6 +8309,7 @@ validate_mips_insn (const struct mips_op
 	  case 'X': USE_BITS (OP_MASK_BBITIND,	OP_SH_BBITIND);	break;
 	  case 'p': USE_BITS (OP_MASK_CINSPOS,	OP_SH_CINSPOS);	break;
 	  case 'P': USE_BITS (OP_MASK_CINSPOS,	OP_SH_CINSPOS);	break;
+	  case 'Q': USE_BITS (OP_MASK_SEQI,	OP_SH_SEQI);	break;
 	  case 's': USE_BITS (OP_MASK_CINSLM1,	OP_SH_CINSLM1);	break;
 	  case 'S': USE_BITS (OP_MASK_CINSLM1,	OP_SH_CINSLM1);	break;
 
@@ -9068,6 +9106,22 @@ do_msbd:
 		  s = expr_end;
 		  continue;
 
+		case 'Q':
+		  /* seqi/snei immediate field.  */
+		  my_getExpression (&imm_expr, s);
+		  check_absolute_expr (ip, &imm_expr);
+		  if ((long) imm_expr.X_add_number < -512
+		      || (long) imm_expr.X_add_number >= 512)
+		    {
+		      as_bad (_("Improper immediate (%ld)"),
+			       (long) imm_expr.X_add_number);
+		      imm_expr.X_add_number = 0;
+		    }
+		  INSERT_OPERAND (SEQI, *ip, imm_expr.X_add_number);
+		  imm_expr.X_op = O_absent;
+		  s = expr_end;
+		  continue;
+
 		default:
 		  as_bad (_("internal: bad mips opcode (unknown extension operand type `+%c'): %s %s"),
 		    *args, insn->name, insn->args);
Index: src/gas/testsuite/gas/mips/octeon.s
===================================================================
--- src.orig/gas/testsuite/gas/mips/octeon.s	2008-05-17 23:41:14.000000000 -0700
+++ src/gas/testsuite/gas/mips/octeon.s	2008-05-21 23:03:36.000000000 -0700
@@ -49,6 +49,33 @@ foo:
         mtp1    $25
         mtp2    $9
 
+        seq     $29,$23,$24
+        seq     $6,$28
+
+        seqi    $17,$15,-512
+        seqi    $16,38
+
+        seq     $5,$4,-274      # seqi
+        seq     $12,511         # seqi
+        seq     $30,$25,512     # xori $30,$25,512;sltiu $30,$30,1
+        seq     $2,$12,-777     # daddiu $2,$12,777;sltiu $2,$2,1
+        seq     $10,$30,0x10000 # lui $1,0x1; seq $10,$30,$1
+        seq     $30,$25,-47366  # lui $1,0xffff; ori $1,$1,0x46fa; seq $30,$25,$1
+
+        sne     $6,$2,$2
+        sne     $23,$20
+
+        snei    $4,$16,-313
+        snei    $26,511
+
+        sne     $21,$23,-512    # snei
+        sne     $12,81          # snei
+
+        sne     $4,$14,889      # xori $4,$14,889;sltu $4,$0,$4
+        sne     $24,$13,-513    # daddiu $24,$13,513;sltu $24,$0,$24
+        sne     $10,$30,119250  # lui $1,0x1; ori $1,$1,0xd1d2; sne $10,$30,$1
+        sne     $30,$25,-0x8000 # li $1,-32768; sne $30,$25,$1
+
 	synciobdma
         syncs
         syncw
Index: src/gas/testsuite/gas/mips/octeon.d
===================================================================
--- src.orig/gas/testsuite/gas/mips/octeon.d	2008-05-18 16:07:52.000000000 -0700
+++ src/gas/testsuite/gas/mips/octeon.d	2008-05-21 22:47:44.000000000 -0700
@@ -45,6 +45,36 @@ Disassembly of section .text:
 .*:	72000009 	mtp0	\$16
 .*:	7320000a 	mtp1	\$25
 .*:	7120000b 	mtp2	\$9
+.*:	72f8e82a 	seq	\$29,\$23,\$24
+.*:	70dc302a 	seq	\$6,\$6,\$28
+.*:	71f1802e 	seqi	\$17,\$15,-512
+.*:	721009ae 	seqi	\$16,\$16,38
+.*:	7085bbae 	seqi	\$5,\$4,-274
+.*:	718c7fee 	seqi	\$12,\$12,511
+.*:	3b3e0200 	xori	\$30,\$25,0x200
+.*:	2fde0001 	sltiu	\$30,\$30,1
+.*:	65820309 	daddiu	\$2,\$12,777
+.*:	2c420001 	sltiu	\$2,\$2,1
+.*:	3c010001 	lui	\$1,0x1
+.*:	73c1502a 	seq	\$10,\$30,\$1
+.*:	3c01ffff 	lui	\$1,0xffff
+.*:	342146fa 	ori	\$1,\$1,0x46fa
+.*:	7321f02a 	seq	\$30,\$25,\$1
+.*:	7042302b 	sne	\$6,\$2,\$2
+.*:	72f4b82b 	sne	\$23,\$23,\$20
+.*:	7204b1ef 	snei	\$4,\$16,-313
+.*:	735a7fef 	snei	\$26,\$26,511
+.*:	72f5802f 	snei	\$21,\$23,-512
+.*:	718c146f 	snei	\$12,\$12,81
+.*:	39c40379 	xori	\$4,\$14,0x379
+.*:	0004202b 	sltu	\$4,\$0,\$4
+.*:	65b80201 	daddiu	\$24,\$13,513
+.*:	0018c02b 	sltu	\$24,\$0,\$24
+.*:	3c010001 	lui	\$1,0x1
+.*:	3421d1d2 	ori	\$1,\$1,0xd1d2
+.*:	73c1502b 	sne	\$10,\$30,\$1
+.*:	24018000 	li	\$1,-32768
+.*:	7321f02b 	sne	\$30,\$25,\$1
 .*:	0000008f 	synciobdma
 .*:	0000018f 	syncs
 .*:	0000010f 	syncw
Index: src/gas/testsuite/gas/mips/octeon-ill.l
===================================================================
--- src.orig/gas/testsuite/gas/mips/octeon-ill.l	2008-05-18 16:00:07.000000000 -0700
+++ src/gas/testsuite/gas/mips/octeon-ill.l	2008-05-21 23:03:25.000000000 -0700
@@ -13,3 +13,7 @@
 .*:26: Error: Improper size \(29\)
 .*:28: Error: Improper position \(70\)
 .*:29: Error: Improper size \(25\)
+.*:31: Error: Improper immediate \(512\)
+.*:32: Error: Improper immediate \(-771\)
+.*:33: Error: Improper immediate \(615\)
+.*:34: Error: Improper immediate \(-513\)
Index: src/gas/testsuite/gas/mips/octeon-ill.s
===================================================================
--- src.orig/gas/testsuite/gas/mips/octeon-ill.s	2008-05-18 15:58:47.000000000 -0700
+++ src/gas/testsuite/gas/mips/octeon-ill.s	2008-05-18 16:03:03.000000000 -0700
@@ -27,3 +27,8 @@ foo:
 
         exts    $14,$29,70,14
         exts    $20,$16,39,25
+
+        seqi    $14,$13,512
+        seqi    $19,-771
+        snei    $18,$30,615
+        snei    $17,-513


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