This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[PATCH] MIPS gas: 64 bit aware rol/ror macros
- From: Thiemo Seufer <ica2_ts at csv dot ica dot uni-stuttgart dot de>
- To: binutils at sources dot redhat dot com
- Date: Sat, 11 May 2002 11:25:39 +0200
- Subject: [PATCH] MIPS gas: 64 bit aware rol/ror macros
Hi All,
this extends the rotate macros of MIPS gas to do the right
thing for 64 bit registers.
Thiemo
2002-05-11 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
/gas/ChangeLog
* config/tc-mips.c (macro2): Add 64 bit support for rol, ror macros.
/gas/testsuite/ChangeLog
* gas/mips/rol64.s: New file, test of 64 bit rol, ror macros.
* gas/mips/rol64.d: Likewise.
* gas/mips/mips.exp: Add new test.
diff -BurpNX /bigdisk/src/binutils-exclude source-orig/gas/config/tc-mips.c source/gas/config/tc-mips.c
--- source-orig/gas/config/tc-mips.c Wed Apr 10 18:40:57 2002
+++ source/gas/config/tc-mips.c Fri May 10 21:22:46 2002
@@ -6670,47 +6840,77 @@ macro2 (ip)
break;
case M_ROL:
- macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "subu",
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ HAVE_32BIT_GPRS ? "subu" : "dsubu",
"d,v,t", AT, 0, treg);
- macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "srlv",
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ HAVE_32BIT_GPRS ? "srlv" : "dsrlv",
"d,t,s", AT, sreg, AT);
- macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "sllv",
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ HAVE_32BIT_GPRS ? "sllv" : "dsllv",
"d,t,s", dreg, sreg, treg);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "or",
"d,v,t", dreg, dreg, AT);
break;
case M_ROL_I:
- if (imm_expr.X_op != O_constant)
- as_bad (_("rotate count too large"));
- macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "sll", "d,w,<",
- AT, sreg, (int) (imm_expr.X_add_number & 0x1f));
- macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "srl", "d,w,<",
- dreg, sreg, (int) ((0 - imm_expr.X_add_number) & 0x1f));
- macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "or", "d,v,t",
- dreg, dreg, AT);
+ {
+ 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 & (HAVE_32BIT_GPRS ? 0x1f : 0x3f);
+ if (! rot)
+ break;
+ l = HAVE_32BIT_GPRS ? "sll" : ((rot < 0x20) ? "dsll" : "dsll32");
+ r = HAVE_32BIT_GPRS ? "srl" : (((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;
case M_ROR:
- macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "subu",
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ HAVE_32BIT_GPRS ? "subu" : "dsubu",
"d,v,t", AT, 0, treg);
- macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "sllv",
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ HAVE_32BIT_GPRS ? "sllv" : "dsllv",
"d,t,s", AT, sreg, AT);
- macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "srlv",
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ HAVE_32BIT_GPRS ? "srlv" : "dsrlv",
"d,t,s", dreg, sreg, treg);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "or",
"d,v,t", dreg, dreg, AT);
break;
case M_ROR_I:
- if (imm_expr.X_op != O_constant)
- as_bad (_("rotate count too large"));
- macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "srl", "d,w,<",
- AT, sreg, (int) (imm_expr.X_add_number & 0x1f));
- macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "sll", "d,w,<",
- dreg, sreg, (int) ((0 - imm_expr.X_add_number) & 0x1f));
- macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "or", "d,v,t",
- dreg, dreg, AT);
+ {
+ 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 & (HAVE_32BIT_GPRS ? 0x1f : 0x3f);
+ if (! rot)
+ break;
+ r = HAVE_32BIT_GPRS ? "srl" : ((rot < 0x20) ? "dsrl" : "dsrl32");
+ l = HAVE_32BIT_GPRS ? "sll" : (((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;
case M_S_DOB:
diff -BurpNX /bigdisk/src/binutils-exclude source-orig/gas/testsuite/gas/mips/mips.exp source/gas/testsuite/gas/mips/mips.exp
--- source-orig/gas/testsuite/gas/mips/mips.exp Wed Apr 10 18:40:58 2002
+++ source/gas/testsuite/gas/mips/mips.exp Thu May 9 11:07:45 2002
@@ -122,6 +122,7 @@ if { [istarget mips*-*-*] } then {
run_dump_test "mul"
}
run_dump_test "rol"
+ run_dump_test "rol64"
if !$aout { run_dump_test "sb" }
run_dump_test "trunc"
if !$aout { run_dump_test "ulh" }
diff -BurpNX /bigdisk/src/binutils-exclude source-orig/gas/testsuite/gas/mips/rol64.d source/gas/testsuite/gas/mips/rol64.d
--- source-orig/gas/testsuite/gas/mips/rol64.d Thu Jan 1 01:00:00 1970
+++ source/gas/testsuite/gas/mips/rol64.d Thu May 9 11:09:47 2002
@@ -0,0 +1,62 @@
+#objdump: -dr --prefix-addresses -mmips:4000
+#as: -march=r4000 -mtune=r4000
+#name: MIPS R4000 rol
+
+# Test the rol and ror macros.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+0+0000 <[^>]*> dnegu at,a1
+0+0004 <[^>]*> dsrlv at,a0,at
+0+0008 <[^>]*> dsllv a0,a0,a1
+0+000c <[^>]*> or a0,a0,at
+0+0010 <[^>]*> dnegu at,a2
+0+0014 <[^>]*> dsrlv at,a1,at
+0+0018 <[^>]*> dsllv a0,a1,a2
+0+001c <[^>]*> or a0,a0,at
+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
+ ...
diff -BurpNX /bigdisk/src/binutils-exclude source-orig/gas/testsuite/gas/mips/rol64.s source/gas/testsuite/gas/mips/rol64.s
--- source-orig/gas/testsuite/gas/mips/rol64.s Thu Jan 1 01:00:00 1970
+++ source/gas/testsuite/gas/mips/rol64.s Thu May 9 11:05:11 2002
@@ -0,0 +1,27 @@
+# Source file used to test the rol and ror macros.
+
+foo:
+ rol $4,$5
+ rol $4,$5,$6
+ rol $4,1
+ rol $4,$5,0
+ rol $4,$5,1
+ rol $4,$5,31
+ rol $4,$5,32
+ rol $4,$5,33
+ rol $4,$5,63
+ rol $4,$5,64
+
+ ror $4,$5
+ ror $4,$5,$6
+ ror $4,1
+ ror $4,$5,0
+ ror $4,$5,1
+ ror $4,$5,31
+ ror $4,$5,32
+ ror $4,$5,33
+ ror $4,$5,63
+ ror $4,$5,64
+
+# Force at least 8 (non-delay-slot) zero bytes, to make 'objdump' print ...
+ .space 8