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] Allow odd single FP registers for ISA MIPS32 and later


Hello All,

I applied this patch which allows the use of odd single FPRs for
ISA MIPS32 and later. Since that ISA revision the odd FPRs are usable
for single precision values even when the FPU runs in compatibility
mode.


Thiemo


2006-05-19  Thiemo Seufer  <ths@mips.com>
            Nigel Stephens  <nigel@mips.com>

	* config/tc-mipc.c (ISA_HAS_ODD_SINGLE_FPR): New define.
	(mips_oddfpreg_ok): New function.
	(mips_ip): Use it.


Index: gas/config/tc-mips.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mips.c,v
retrieving revision 1.335
diff -u -p -r1.335 tc-mips.c
--- gas/config/tc-mips.c	14 May 2006 15:35:21 -0000	1.335
+++ gas/config/tc-mips.c	18 May 2006 11:24:18 -0000
@@ -331,6 +331,12 @@ static int mips_32bitmode = 0;
    || (ISA) == ISA_MIPS64R2		\
    || mips_opts.ase_smartmips)
 
+/* Return true if ISA supports single-precision floats in odd registers.  */
+#define ISA_HAS_ODD_SINGLE_FPR(ISA)	\
+  ((ISA) == ISA_MIPS32			\
+   || (ISA) == ISA_MIPS32R2		\
+   || (ISA) == ISA_MIPS64		\
+   || (ISA) == ISA_MIPS64R2)
 
 #define HAVE_32BIT_GPRS		                   \
     (mips_opts.gp32 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
@@ -7952,6 +8215,46 @@ static const struct mips_immed mips_imme
   { 0,0,0,0 }
 };
 
+/* Check whether an odd floating-point register is allowed.  */
+static int
+mips_oddfpreg_ok (const struct mips_opcode *insn, int argnum)
+{
+  const char *s = insn->name;
+
+  if (insn->pinfo == INSN_MACRO)
+    /* Let a macro pass, we'll catch it later when it is expanded.  */
+    return 1;
+
+  if (ISA_HAS_ODD_SINGLE_FPR (mips_opts.isa))
+    {
+      /* Allow odd registers for single-precision ops.  */
+      switch (insn->pinfo & (FP_S | FP_D))
+	{
+	case FP_S:
+	case 0:
+	  return 1;	/* both single precision - ok */
+	case FP_D:
+	  return 0;	/* both double precision - fail */
+	default:
+	  break;
+	}
+
+      /* Cvt.w.x and cvt.x.w allow an odd register for a 'w' or 's' operand.  */
+      s = strchr (insn->name, '.');
+      if (argnum == 2)
+	s = s != NULL ? strchr (s + 1, '.') : NULL;
+      return (s != NULL && (s[1] == 'w' || s[1] == 's'));
+    } 
+
+  /* Single-precision coprocessor loads and moves are OK too.  */
+  if ((insn->pinfo & FP_S)
+      && (insn->pinfo & (INSN_COPROC_MEMORY_DELAY | INSN_STORE_MEMORY
+			 | INSN_LOAD_COPROC_DELAY | INSN_COPROC_MOVE_DELAY)))
+    return 1;
+
+  return 0;
+}
+
 /* This routine assembles an instruction into its binary format.  As a
    side effect, it sets one of the global variables imm_reloc or
    offset_reloc to the type of relocation to do if one of the operands
@@ -9105,18 +9105,7 @@ do_msbd:
 		{
 		  if ((regno & 1) != 0
 		      && HAVE_32BIT_FPRS
-		      && ! (strcmp (str, "mtc1") == 0
-			    || strcmp (str, "mfc1") == 0
-			    || strcmp (str, "lwc1") == 0
-			    || strcmp (str, "swc1") == 0
-			    || strcmp (str, "l.s") == 0
-			    || strcmp (str, "s.s") == 0
-			    || strcmp (str, "mftc1") == 0
-			    || strcmp (str, "mfthc1") == 0
-			    || strcmp (str, "cftc1") == 0
-			    || strcmp (str, "mttc1") == 0
-			    || strcmp (str, "mtthc1") == 0
-			    || strcmp (str, "cttc1") == 0))
+		      && ! mips_oddfpreg_ok (ip->insn_mo, argnum))
 		    as_warn (_("Float register should be even, was %d"),
 			     regno);
 


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