This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH, MIPS] Add Octeon instructions seq* and sne*
- From: Adam Nemet <anemet at caviumnetworks dot com>
- To: binutils at sourceware dot org
- Date: Tue, 03 Jun 2008 00:04:46 -0700
- Subject: Re: [PATCH, MIPS] Add Octeon instructions seq* and sne*
- References: <18485.6012.331265.209390@localhost.localdomain>
Ping.
Adam Nemet <anemet@caviumnetworks.com> writes:
> 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