This is the mail archive of the binutils@sources.redhat.com 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 to implement rotates by zero


Noticed while reading the code that:

        ror $2,$4,0

expands to nothing at all.  And the testsuite actually requires this
behaviour ;).

This patch implements double-rotates by zero using "dsll", so that they
trap in the same circumstances that non-zero rotates would.  Likewise
"rol" and "ror" will use "sll" to give the correct sign extension
on 64-bit targets.

Tested on mips-elf.  OK to install?

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 dsll.

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	17 Aug 2002 16:49:33 -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, "dsll",
! 		       "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, "sll",
! 		       "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, "dsll",
! 		       "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, "sll",
! 		       "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	17 Aug 2002 16:49:33 -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 <[^>]*> sll	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 <[^>]*> sll	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	17 Aug 2002 16:49:33 -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	17 Aug 2002 16:49:33 -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 <[^>]*> dsll	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 <[^>]*> dsll	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 <[^>]*> dsll	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 <[^>]*> dsll	a0,a1,0x0
  	...


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