This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Patch to implement rotates by zero
cgd@broadcom.com writes:
> At 19 Aug 2002 15:27:23 +0100, Richard Sandiford wrote:
> > The point is that, at the moment, we generate no instructions at all.
> > And, when it came to deciding what instruction to use, I thought "sll"
> > was a better choice than "srl" because in general it is "more defined".
> > If the consensus is that being "more defined" makes it worse than "srl"
> > (because it makes ror-by-zero well-defined in circumstances that ror by
> > non-zero wouldn't be) then I'm happy to use "srl" instead.
>
> I suggest 'srl' ...
OK. Here's a revised patch. Tested as before on mips-elf.
Richard
[gas/]
* config/tc-mips.c (macro2): Implement rotates by zero using shifts
by zero.
[gas/testsuite]
* gas/mips/rol.s: Add rotate by zero tests.
* gas/mips/rol.d: Update accordingly.
* gas/mips/rol64.d: Expect rotates by zero to use dsrl.
Index: gas/config/tc-mips.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mips.c,v
retrieving revision 1.160
diff -c -d -p -r1.160 tc-mips.c
*** gas/config/tc-mips.c 17 Aug 2002 15:09:29 -0000 1.160
--- gas/config/tc-mips.c 19 Aug 2002 14:48:56 -0000
*************** macro2 (ip)
*** 6653,6674 ****
case M_DROL_I:
{
unsigned int rot;
- char *l, *r;
if (imm_expr.X_op != O_constant)
as_bad (_("rotate count too large"));
rot = imm_expr.X_add_number & 0x3f;
! if (! rot)
! break;
! l = (rot < 0x20) ? "dsll" : "dsll32";
! r = ((0x40 - rot) < 0x20) ? "dsrl" : "dsrl32";
! rot &= 0x1f;
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, l,
! "d,w,<", AT, sreg, rot);
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, r,
! "d,w,<", dreg, sreg, (0x20 - rot) & 0x1f);
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "or",
! "d,v,t", dreg, dreg, AT);
}
break;
--- 6653,6679 ----
case M_DROL_I:
{
unsigned int rot;
if (imm_expr.X_op != O_constant)
as_bad (_("rotate count too large"));
rot = imm_expr.X_add_number & 0x3f;
! if (rot == 0)
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "dsrl",
! "d,w,<", dreg, sreg, 0);
! else
! {
! char *l, *r;
!
! l = (rot < 0x20) ? "dsll" : "dsll32";
! r = ((0x40 - rot) < 0x20) ? "dsrl" : "dsrl32";
! rot &= 0x1f;
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, l,
! "d,w,<", AT, sreg, rot);
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, r,
! "d,w,<", dreg, sreg, (0x20 - rot) & 0x1f);
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "or",
! "d,v,t", dreg, dreg, AT);
! }
}
break;
*************** macro2 (ip)
*** 6679,6692 ****
if (imm_expr.X_op != O_constant)
as_bad (_("rotate count too large"));
rot = imm_expr.X_add_number & 0x1f;
! if (! rot)
! break;
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "sll",
! "d,w,<", AT, sreg, rot);
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "srl",
! "d,w,<", dreg, sreg, (0x20 - rot) & 0x1f);
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "or",
! "d,v,t", dreg, dreg, AT);
}
break;
--- 6684,6701 ----
if (imm_expr.X_op != O_constant)
as_bad (_("rotate count too large"));
rot = imm_expr.X_add_number & 0x1f;
! if (rot == 0)
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "srl",
! "d,w,<", dreg, sreg, 0);
! else
! {
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "sll",
! "d,w,<", AT, sreg, rot);
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "srl",
! "d,w,<", dreg, sreg, (0x20 - rot) & 0x1f);
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "or",
! "d,v,t", dreg, dreg, AT);
! }
}
break;
*************** macro2 (ip)
*** 6715,6736 ****
case M_DROR_I:
{
unsigned int rot;
- char *l, *r;
if (imm_expr.X_op != O_constant)
as_bad (_("rotate count too large"));
rot = imm_expr.X_add_number & 0x3f;
! if (! rot)
! break;
! r = (rot < 0x20) ? "dsrl" : "dsrl32";
! l = ((0x40 - rot) < 0x20) ? "dsll" : "dsll32";
! rot &= 0x1f;
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, r,
! "d,w,<", AT, sreg, rot);
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, l,
! "d,w,<", dreg, sreg, (0x20 - rot) & 0x1f);
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "or",
! "d,v,t", dreg, dreg, AT);
}
break;
--- 6724,6750 ----
case M_DROR_I:
{
unsigned int rot;
if (imm_expr.X_op != O_constant)
as_bad (_("rotate count too large"));
rot = imm_expr.X_add_number & 0x3f;
! if (rot == 0)
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "dsrl",
! "d,w,<", dreg, sreg, 0);
! else
! {
! char *l, *r;
!
! r = (rot < 0x20) ? "dsrl" : "dsrl32";
! l = ((0x40 - rot) < 0x20) ? "dsll" : "dsll32";
! rot &= 0x1f;
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, r,
! "d,w,<", AT, sreg, rot);
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, l,
! "d,w,<", dreg, sreg, (0x20 - rot) & 0x1f);
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "or",
! "d,v,t", dreg, dreg, AT);
! }
}
break;
*************** macro2 (ip)
*** 6741,6754 ****
if (imm_expr.X_op != O_constant)
as_bad (_("rotate count too large"));
rot = imm_expr.X_add_number & 0x1f;
! if (! rot)
! break;
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "srl",
! "d,w,<", AT, sreg, rot);
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "sll",
! "d,w,<", dreg, sreg, (0x20 - rot) & 0x1f);
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "or",
! "d,v,t", dreg, dreg, AT);
}
break;
--- 6755,6772 ----
if (imm_expr.X_op != O_constant)
as_bad (_("rotate count too large"));
rot = imm_expr.X_add_number & 0x1f;
! if (rot == 0)
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "srl",
! "d,w,<", dreg, sreg, 0);
! else
! {
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "srl",
! "d,w,<", AT, sreg, rot);
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "sll",
! "d,w,<", dreg, sreg, (0x20 - rot) & 0x1f);
! macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "or",
! "d,v,t", dreg, dreg, AT);
! }
}
break;
Index: gas/testsuite/gas/mips/rol.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/rol.d,v
retrieving revision 1.3
diff -c -d -p -r1.3 rol.d
*** gas/testsuite/gas/mips/rol.d 29 Jun 2001 21:27:43 -0000 1.3
--- gas/testsuite/gas/mips/rol.d 19 Aug 2002 14:48:56 -0000
*************** Disassembly of section .text:
*** 21,37 ****
0+002c <[^>]*> sll at,a1,0x1
0+0030 <[^>]*> srl a0,a1,0x1f
0+0034 <[^>]*> or a0,a0,at
! 0+0038 <[^>]*> negu at,a1
! 0+003c <[^>]*> sllv at,a0,at
! 0+0040 <[^>]*> srlv a0,a0,a1
! 0+0044 <[^>]*> or a0,a0,at
! 0+0048 <[^>]*> negu at,a2
! 0+004c <[^>]*> sllv at,a1,at
! 0+0050 <[^>]*> srlv a0,a1,a2
! 0+0054 <[^>]*> or a0,a0,at
! 0+0058 <[^>]*> srl at,a0,0x1
! 0+005c <[^>]*> sll a0,a0,0x1f
! 0+0060 <[^>]*> or a0,a0,at
! 0+0064 <[^>]*> srl at,a1,0x1
! 0+0068 <[^>]*> sll a0,a1,0x1f
! 0+006c <[^>]*> or a0,a0,at
--- 21,40 ----
0+002c <[^>]*> sll at,a1,0x1
0+0030 <[^>]*> srl a0,a1,0x1f
0+0034 <[^>]*> or a0,a0,at
! 0+0038 <[^>]*> srl a0,a1,0x0
! 0+003c <[^>]*> negu at,a1
! 0+0040 <[^>]*> sllv at,a0,at
! 0+0044 <[^>]*> srlv a0,a0,a1
! 0+0048 <[^>]*> or a0,a0,at
! 0+004c <[^>]*> negu at,a2
! 0+0050 <[^>]*> sllv at,a1,at
! 0+0054 <[^>]*> srlv a0,a1,a2
! 0+0058 <[^>]*> or a0,a0,at
! 0+005c <[^>]*> srl at,a0,0x1
! 0+0060 <[^>]*> sll a0,a0,0x1f
! 0+0064 <[^>]*> or a0,a0,at
! 0+0068 <[^>]*> srl at,a1,0x1
! 0+006c <[^>]*> sll a0,a1,0x1f
! 0+0070 <[^>]*> or a0,a0,at
! 0+0074 <[^>]*> srl a0,a1,0x0
! ...
Index: gas/testsuite/gas/mips/rol.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/rol.s,v
retrieving revision 1.1.1.1
diff -c -d -p -r1.1.1.1 rol.s
*** gas/testsuite/gas/mips/rol.s 3 May 1999 07:28:51 -0000 1.1.1.1
--- gas/testsuite/gas/mips/rol.s 19 Aug 2002 14:48:56 -0000
*************** foo:
*** 5,12 ****
--- 5,15 ----
rol $4,$5,$6
rol $4,1
rol $4,$5,1
+ rol $4,$5,0
ror $4,$5
ror $4,$5,$6
ror $4,1
ror $4,$5,1
+ ror $4,$5,0
+ .space 8
Index: gas/testsuite/gas/mips/rol64.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/rol64.d,v
retrieving revision 1.1
diff -c -d -p -r1.1 rol64.d
*** gas/testsuite/gas/mips/rol64.d 21 May 2002 23:54:45 -0000 1.1
--- gas/testsuite/gas/mips/rol64.d 19 Aug 2002 14:48:56 -0000
*************** Disassembly of section .text:
*** 18,62 ****
0+0020 <[^>]*> dsll at,a0,0x1
0+0024 <[^>]*> dsrl32 a0,a0,0x1f
0+0028 <[^>]*> or a0,a0,at
! 0+002c <[^>]*> dsll at,a1,0x1
! 0+0030 <[^>]*> dsrl32 a0,a1,0x1f
! 0+0034 <[^>]*> or a0,a0,at
! 0+0038 <[^>]*> dsll at,a1,0x1f
! 0+003c <[^>]*> dsrl32 a0,a1,0x1
! 0+0040 <[^>]*> or a0,a0,at
! 0+0044 <[^>]*> dsll32 at,a1,0x0
! 0+0048 <[^>]*> dsrl32 a0,a1,0x0
! 0+004c <[^>]*> or a0,a0,at
! 0+0050 <[^>]*> dsll32 at,a1,0x1
! 0+0054 <[^>]*> dsrl a0,a1,0x1f
! 0+0058 <[^>]*> or a0,a0,at
! 0+005c <[^>]*> dsll32 at,a1,0x1f
! 0+0060 <[^>]*> dsrl a0,a1,0x1
! 0+0064 <[^>]*> or a0,a0,at
! 0+0068 <[^>]*> dnegu at,a1
! 0+006c <[^>]*> dsllv at,a0,at
! 0+0070 <[^>]*> dsrlv a0,a0,a1
! 0+0074 <[^>]*> or a0,a0,at
! 0+0078 <[^>]*> dnegu at,a2
! 0+007c <[^>]*> dsllv at,a1,at
! 0+0080 <[^>]*> dsrlv a0,a1,a2
! 0+0084 <[^>]*> or a0,a0,at
! 0+0088 <[^>]*> dsrl at,a0,0x1
! 0+008c <[^>]*> dsll32 a0,a0,0x1f
! 0+0090 <[^>]*> or a0,a0,at
! 0+0094 <[^>]*> dsrl at,a1,0x1
! 0+0098 <[^>]*> dsll32 a0,a1,0x1f
! 0+009c <[^>]*> or a0,a0,at
! 0+00a0 <[^>]*> dsrl at,a1,0x1f
! 0+00a4 <[^>]*> dsll32 a0,a1,0x1
0+00a8 <[^>]*> or a0,a0,at
! 0+00ac <[^>]*> dsrl32 at,a1,0x0
! 0+00b0 <[^>]*> dsll32 a0,a1,0x0
0+00b4 <[^>]*> or a0,a0,at
! 0+00b8 <[^>]*> dsrl32 at,a1,0x1
! 0+00bc <[^>]*> dsll a0,a1,0x1f
0+00c0 <[^>]*> or a0,a0,at
! 0+00c4 <[^>]*> dsrl32 at,a1,0x1f
! 0+00c8 <[^>]*> dsll a0,a1,0x1
0+00cc <[^>]*> or a0,a0,at
...
--- 18,66 ----
0+0020 <[^>]*> dsll at,a0,0x1
0+0024 <[^>]*> dsrl32 a0,a0,0x1f
0+0028 <[^>]*> or a0,a0,at
! 0+002c <[^>]*> dsrl a0,a1,0x0
! 0+0030 <[^>]*> dsll at,a1,0x1
! 0+0034 <[^>]*> dsrl32 a0,a1,0x1f
! 0+0038 <[^>]*> or a0,a0,at
! 0+003c <[^>]*> dsll at,a1,0x1f
! 0+0040 <[^>]*> dsrl32 a0,a1,0x1
! 0+0044 <[^>]*> or a0,a0,at
! 0+0048 <[^>]*> dsll32 at,a1,0x0
! 0+004c <[^>]*> dsrl32 a0,a1,0x0
! 0+0050 <[^>]*> or a0,a0,at
! 0+0054 <[^>]*> dsll32 at,a1,0x1
! 0+0058 <[^>]*> dsrl a0,a1,0x1f
! 0+005c <[^>]*> or a0,a0,at
! 0+0060 <[^>]*> dsll32 at,a1,0x1f
! 0+0064 <[^>]*> dsrl a0,a1,0x1
! 0+0068 <[^>]*> or a0,a0,at
! 0+006c <[^>]*> dsrl a0,a1,0x0
! 0+0070 <[^>]*> dnegu at,a1
! 0+0074 <[^>]*> dsllv at,a0,at
! 0+0078 <[^>]*> dsrlv a0,a0,a1
! 0+007c <[^>]*> or a0,a0,at
! 0+0080 <[^>]*> dnegu at,a2
! 0+0084 <[^>]*> dsllv at,a1,at
! 0+0088 <[^>]*> dsrlv a0,a1,a2
! 0+008c <[^>]*> or a0,a0,at
! 0+0090 <[^>]*> dsrl at,a0,0x1
! 0+0094 <[^>]*> dsll32 a0,a0,0x1f
! 0+0098 <[^>]*> or a0,a0,at
! 0+009c <[^>]*> dsrl a0,a1,0x0
! 0+00a0 <[^>]*> dsrl at,a1,0x1
! 0+00a4 <[^>]*> dsll32 a0,a1,0x1f
0+00a8 <[^>]*> or a0,a0,at
! 0+00ac <[^>]*> dsrl at,a1,0x1f
! 0+00b0 <[^>]*> dsll32 a0,a1,0x1
0+00b4 <[^>]*> or a0,a0,at
! 0+00b8 <[^>]*> dsrl32 at,a1,0x0
! 0+00bc <[^>]*> dsll32 a0,a1,0x0
0+00c0 <[^>]*> or a0,a0,at
! 0+00c4 <[^>]*> dsrl32 at,a1,0x1
! 0+00c8 <[^>]*> dsll a0,a1,0x1f
0+00cc <[^>]*> or a0,a0,at
+ 0+00d0 <[^>]*> dsrl32 at,a1,0x1f
+ 0+00d4 <[^>]*> dsll a0,a1,0x1
+ 0+00d8 <[^>]*> or a0,a0,at
+ 0+00dc <[^>]*> dsrl a0,a1,0x0
...