public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Better checking of ISA/ASE/ABI options for MIPS gas
@ 2006-05-23  0:08 Thiemo Seufer
  2006-05-23  4:06 ` Eric Christopher
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Thiemo Seufer @ 2006-05-23  0:08 UTC (permalink / raw)
  To: binutils

Hello All,

this patch adds a bunch of MIPS CPU definitions, defaults ASE
availability for some of them, improves the checks for incompatible
ISA/ASE/ABI options, especially for 32bit/64bit FP registers, adds
support for .set gp32 and .set gp64, and improves the documentation
a bit.

I'm somewhat uncertain about the ABI incompatibility warning for
wrong FP register widths, does it make sense to force a different
FP register width in the assembler in some cases?


Thiemo


2006-05-22  Thiemo Seufer  <ths@mips.com>
            David Ung  <davidu@mips.com>
            Nigel Stephens  <nigel@mips.com>

	[ gas/ChangeLog ]
	* config/tc-mips.c (ISA_SUPPORT_DSP_ASE, ISA_SUPPORT_MT_ASE,
	ISA_HAS_64BIT_FPRS, ISA_HAS_MXHC1): New macros.
	(HAVE_32BIT_FPRS): Use ISA_HAS_64BIT_FPRS instead of
	ISA_HAS_64BIT_REGS.
	(mips_cpu_info): Add ASE flags.
	(mips_after_parse_args): Change default handling of float register
	size to account for 32bit code with 64bit FP. Better sanity checking
	of ISA/ASE/ABI option combinations.
	(s_mipsset): Support switching of GPR size via .set (no-)gp64 and
	.set (no-)gp32. Better sanity checking for .set ASE options.
	(mips_elf_final_processing): We should record the use of 64bit FP
	registers in 32bit code but we don't, because ELF header flags are
	a scarce ressource.
	(mips_cpu_info_table): Add ASE flags for CPUs with mandatory ASE
	extensions. Add 4ksc, 4kec, 4kem, 4kep, 4ksd, m4kp, 24kec, 24kef,
	24kex, 34kc, 34kf, 34kx, 25kf CPU definitions.
	(mips_cpu_info_from_isa): Use MIPS_CPU_IS_ISA.

	[ gas/testsuite/Changelog ]
	* gas/mips/mips-gp32-fp64-pic.d, mips/mips-gp32-fp64.d,
	gas/mips/mips-gp64-fp32-pic.d, gas/mips/mips-gp64-fp32.l,
	gas/mips/mips-gp64-fp64.d: Adjust test cases to the changes assembler
	output.
	* gas/mips/mips-gp32-fp64.l, gas/mips/mips-gp64-fp32-pic.l: New files,
	catch assembler warnings.

	[ gas/doc/ChangeLog ]
	* c-mips.texi: Document .set (no-)gp32, .set (no-)gp64. Document
	missing -march options. Document .set arch=CPU. Move .set smartmips
	to ASE page.


Index: gas/config/tc-mips.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mips.c,v
retrieving revision 1.337
diff -u -p -r1.337 tc-mips.c
--- gas/config/tc-mips.c	19 May 2006 13:03:05 -0000	1.337
+++ gas/config/tc-mips.c	22 May 2006 15:23:40 -0000
@@ -281,10 +281,16 @@ static int file_ase_smartmips;
    command line (e.g., by -march).  */
 static int file_ase_dsp;
 
+#define ISA_SUPPORT_DSP_ASE	(mips_opts.isa == ISA_MIPS32R2       \
+				 || mips_opts.isa == ISA_MIPS64R2)
+
 /* True if -mmt was passed or implied by arguments passed on the
    command line (e.g., by -march).  */
 static int file_ase_mt;
 
+#define ISA_SUPPORT_MT_ASE	(mips_opts.isa == ISA_MIPS32R2       \
+				 || mips_opts.isa == ISA_MIPS64R2)
+
 /* The argument of the -march= flag.  The architecture we are assembling.  */
 static int file_mips_arch = CPU_UNKNOWN;
 static const char *mips_arch_string;
@@ -314,6 +320,15 @@ static int mips_32bitmode = 0;
    || (ISA) == ISA_MIPS64		\
    || (ISA) == ISA_MIPS64R2)
 
+/*  Return true if ISA supports 64 bit float register instructions.  */
+#define ISA_HAS_64BIT_FPRS(ISA)		\
+  ((ISA) == ISA_MIPS3			\
+   || (ISA) == ISA_MIPS4		\
+   || (ISA) == ISA_MIPS5		\
+   || (ISA) == ISA_MIPS32R2		\
+   || (ISA) == ISA_MIPS64		\
+   || (ISA) == ISA_MIPS64R2)
+
 /* Return true if ISA supports 64-bit right rotate (dror et al.)
    instructions.  */
 #define ISA_HAS_DROR(ISA)		\
@@ -333,14 +348,20 @@ static int mips_32bitmode = 0;
    || (ISA) == ISA_MIPS64		\
    || (ISA) == ISA_MIPS64R2)
 
+/* Return true if ISA supports move to/from high part of a 64-bit
+   floating-point register. */
+#define ISA_HAS_MXHC1(ISA)		\
+  ((ISA) == ISA_MIPS32R2		\
+   || (ISA) == ISA_MIPS64R2)
+
 #define HAVE_32BIT_GPRS		                   \
-    (mips_opts.gp32 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
+    (mips_opts.gp32 || !ISA_HAS_64BIT_REGS (mips_opts.isa))
 
 #define HAVE_32BIT_FPRS                            \
-    (mips_opts.fp32 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
+    (mips_opts.fp32 || !ISA_HAS_64BIT_FPRS (mips_opts.isa))
 
-#define HAVE_64BIT_GPRS (! HAVE_32BIT_GPRS)
-#define HAVE_64BIT_FPRS (! HAVE_32BIT_FPRS)
+#define HAVE_64BIT_GPRS (!HAVE_32BIT_GPRS)
+#define HAVE_64BIT_FPRS (!HAVE_32BIT_FPRS)
 
 #define HAVE_NEWABI (mips_abi == N32_ABI || mips_abi == N64_ABI)
 
@@ -1031,7 +1052,13 @@ static int validate_mips_insn (const str
 struct mips_cpu_info
 {
   const char *name;           /* CPU or ISA name.  */
-  int is_isa;                 /* Is this an ISA?  (If 0, a CPU.) */
+  int flags;
+#define MIPS_CPU_IS_ISA		0x0001	/* Is this an ISA?  (If 0, a CPU.) */
+#define MIPS_CPU_ASE_SMARTMIPS	0x0002	/* CPU implements SmartMIPS ASE */
+#define MIPS_CPU_ASE_DSP	0x0004	/* CPU implements DSP ASE */
+#define MIPS_CPU_ASE_MT		0x0008	/* CPU implements MT ASE */
+#define MIPS_CPU_ASE_MIPS3D	0x0010	/* CPU implements MIPS-3D ASE */
+#define MIPS_CPU_ASE_MDMX	0x0020	/* CPU implements MDMX ASE */
   int isa;                    /* ISA level.  */
   int cpu;                    /* CPU number (default CPU if ISA).  */
 };
@@ -11380,14 +11407,37 @@ mips_after_parse_args (void)
 			|| !ISA_HAS_64BIT_REGS (mips_opts.isa));
     }
 
-  /* ??? GAS treats single-float processors as though they had 64-bit
-     float registers (although it complains when double-precision
-     instructions are used).  As things stand, saying they have 32-bit
-     registers would lead to spurious "register must be even" messages.
-     So here we assume float registers are always the same size as
-     integer ones, unless the user says otherwise.  */
-  if (file_mips_fp32 < 0)
-    file_mips_fp32 = file_mips_gp32;
+  switch (file_mips_fp32)
+    {
+    default:
+    case -1:
+      /* No user specified float register size.  */
+      if (file_mips_gp32 == 0)
+	/* 64-bit integer registers implies 64-bit float registers.  */
+	file_mips_fp32 = 0;
+      else if ((mips_opts.ase_mips3d > 0 || mips_opts.ase_mdmx > 0)
+	       && ISA_HAS_64BIT_FPRS (mips_opts.isa))
+	/* -mips3d and -mdmx imply 64-bit float registers, if possible.  */
+	file_mips_fp32 = 0;
+      else
+	/* 32-bit float registers. */
+	file_mips_fp32 = 1;
+      break;
+
+    /* The user specified the size of the float registers.  Check if it
+       agrees with the ABI and ISA.  */
+    case 0:
+      if (!ISA_HAS_64BIT_FPRS (mips_opts.isa))
+	as_bad (_("-mfp64 used with a 32-bit fpu"));
+      else if (ABI_NEEDS_32BIT_REGS (mips_abi)
+	       && !ISA_HAS_MXHC1 (mips_opts.isa))
+	as_warn (_("-mfp64 used with a 32-bit ABI"));
+      break;
+    case 1:
+      if (ABI_NEEDS_64BIT_REGS (mips_abi))
+	as_warn (_("-mfp32 used with a 64-bit ABI"));
+      break;
+    }
 
   /* End of GCC-shared inference code.  */
 
@@ -11406,13 +11456,36 @@ mips_after_parse_args (void)
   if (mips_opts.mips16 == -1)
     mips_opts.mips16 = (CPU_HAS_MIPS16 (file_mips_arch)) ? 1 : 0;
   if (mips_opts.ase_mips3d == -1)
-    mips_opts.ase_mips3d = (CPU_HAS_MIPS3D (file_mips_arch)) ? 1 : 0;
+    mips_opts.ase_mips3d = ((CPU_HAS_MIPS3D (file_mips_arch)
+			     || (arch_info->flags & MIPS_CPU_ASE_MIPS3D))
+			    && file_mips_fp32 == 0) ? 1 : 0;
+  if (mips_opts.ase_mips3d && file_mips_fp32 == 1)
+    as_bad (_("-mfp32 used with -mips3d"));
+
   if (mips_opts.ase_mdmx == -1)
-    mips_opts.ase_mdmx = (CPU_HAS_MDMX (file_mips_arch)) ? 1 : 0;
+    mips_opts.ase_mdmx = ((CPU_HAS_MDMX (file_mips_arch)
+			   || (arch_info->flags & MIPS_CPU_ASE_MDMX))
+			  && file_mips_fp32 == 0) ? 1 : 0;
+  if (mips_opts.ase_mdmx && file_mips_fp32 == 1)
+    as_bad (_("-mfp32 used with -mdmx"));
+
+  if (mips_opts.ase_smartmips == -1)
+    mips_opts.ase_smartmips = (arch_info->flags & MIPS_CPU_ASE_SMARTMIPS) ? 1 : 0;
+  if (mips_opts.ase_smartmips && !ISA_SUPPORT_SMARTMIPS)
+      as_warn ("%s ISA does not support SmartMIPS", 
+	       mips_cpu_info_from_isa (mips_opts.isa)->name);
+
   if (mips_opts.ase_dsp == -1)
-    mips_opts.ase_dsp = (CPU_HAS_DSP (file_mips_arch)) ? 1 : 0;
+    mips_opts.ase_dsp = (arch_info->flags & MIPS_CPU_ASE_DSP) ? 1 : 0;
+  if (mips_opts.ase_dsp && !ISA_SUPPORT_DSP_ASE)
+      as_warn ("%s ISA does not support DSP ASE", 
+	       mips_cpu_info_from_isa (mips_opts.isa)->name);
+
   if (mips_opts.ase_mt == -1)
-    mips_opts.ase_mt = (CPU_HAS_MT (file_mips_arch)) ? 1 : 0;
+    mips_opts.ase_mt = (arch_info->flags & MIPS_CPU_ASE_MT) ? 1 : 0;
+  if (mips_opts.ase_mt && !ISA_SUPPORT_MT_ASE)
+      as_warn ("%s ISA does not support MT ASE", 
+	       mips_cpu_info_from_isa (mips_opts.isa)->name);
 
   file_mips_isa = mips_opts.isa;
   file_ase_mips16 = mips_opts.mips16;
@@ -12266,6 +12339,21 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
     {
       mips_opts.nobopt = 1;
     }
+  else if (strcmp (name, "gp64") == 0)
+    {
+      if (!ISA_HAS_64BIT_REGS (mips_opts.isa))
+	as_warn ("%s isa does not support 64-bit registers", 
+		 mips_cpu_info_from_isa (mips_opts.isa)->name);
+      mips_opts.gp32 = 0;
+    }
+  else if (strcmp (name, "gp32") == 0)
+    {
+      mips_opts.gp32 = 1;
+    }
+  else if (strcmp (name, "nogp64") == 0 || strcmp (name, "nogp32") == 0)
+    {
+      mips_opts.gp32 = file_mips_gp32;
+    }
   else if (strcmp (name, "mips16") == 0
 	   || strcmp (name, "MIPS-16") == 0)
     mips_opts.mips16 = 1;
@@ -12281,6 +12369,24 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
     }
   else if (strcmp (name, "nosmartmips") == 0)
     mips_opts.ase_smartmips = 0;
+  else if (strcmp (name, "dsp") == 0)
+    {
+      if (!ISA_SUPPORT_DSP_ASE)
+	as_warn ("%s ISA does not support DSP ASE", 
+		 mips_cpu_info_from_isa (mips_opts.isa)->name);
+      mips_opts.ase_dsp = 1;
+    }
+  else if (strcmp (name, "nodsp") == 0)
+    mips_opts.ase_dsp = 0;
+  else if (strcmp (name, "mt") == 0)
+    {
+      if (!ISA_SUPPORT_MT_ASE)
+	as_warn ("%s ISA does not support MT ASE", 
+		 mips_cpu_info_from_isa (mips_opts.isa)->name);
+      mips_opts.ase_mt = 1;
+    }
+  else if (strcmp (name, "nomt") == 0)
+    mips_opts.ase_mt = 0;
   else if (strcmp (name, "mips3d") == 0)
     mips_opts.ase_mips3d = 1;
   else if (strcmp (name, "nomips3d") == 0)
@@ -12290,11 +12396,21 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
   else if (strcmp (name, "nomdmx") == 0)
     mips_opts.ase_mdmx = 0;
   else if (strcmp (name, "dsp") == 0)
-    mips_opts.ase_dsp = 1;
+    {
+      if (!ISA_SUPPORT_DSP_ASE)
+	as_warn ("%s ISA does not support DSP ASE", 
+		 mips_cpu_info_from_isa (mips_opts.isa)->name);
+      mips_opts.ase_dsp = 1;
+    }
   else if (strcmp (name, "nodsp") == 0)
     mips_opts.ase_dsp = 0;
   else if (strcmp (name, "mt") == 0)
-    mips_opts.ase_mt = 1;
+    {
+      if (!ISA_SUPPORT_MT_ASE)
+	as_warn ("%s ISA does not support MT ASE", 
+		 mips_cpu_info_from_isa (mips_opts.isa)->name);
+      mips_opts.ase_mt = 1;
+    }
   else if (strcmp (name, "nomt") == 0)
     mips_opts.ase_mt = 0;
   else if (strncmp (name, "mips", 4) == 0 || strncmp (name, "arch=", 5) == 0)
@@ -14012,6 +14128,12 @@ mips_elf_final_processing (void)
 
   if (mips_32bitmode)
     elf_elfheader (stdoutput)->e_flags |= EF_MIPS_32BITMODE;
+
+#if 0 /* XXX FIXME */
+  /* 32 bit code with 64 bit FP registers.  */
+  if (!file_mips_fp32 && ABI_NEEDS_32BIT_REGS (mips_abi))
+    elf_elfheader (stdoutput)->e_flags |= ???;
+#endif
 }
 
 #endif /* OBJ_ELF || OBJ_MAYBE_ELF */
@@ -14414,72 +14536,90 @@ s_mips_mask (int reg_type)
 static const struct mips_cpu_info mips_cpu_info_table[] =
 {
   /* Entries for generic ISAs */
-  { "mips1",          1,      ISA_MIPS1,      CPU_R3000 },
-  { "mips2",          1,      ISA_MIPS2,      CPU_R6000 },
-  { "mips3",          1,      ISA_MIPS3,      CPU_R4000 },
-  { "mips4",          1,      ISA_MIPS4,      CPU_R8000 },
-  { "mips5",          1,      ISA_MIPS5,      CPU_MIPS5 },
-  { "mips32",         1,      ISA_MIPS32,     CPU_MIPS32 },
-  { "mips32r2",       1,      ISA_MIPS32R2,   CPU_MIPS32R2 },
-  { "mips64",         1,      ISA_MIPS64,     CPU_MIPS64 },
-  { "mips64r2",       1,      ISA_MIPS64R2,   CPU_MIPS64R2 },
+  { "mips1",          MIPS_CPU_IS_ISA,		ISA_MIPS1,      CPU_R3000 },
+  { "mips2",          MIPS_CPU_IS_ISA,		ISA_MIPS2,      CPU_R6000 },
+  { "mips3",          MIPS_CPU_IS_ISA,		ISA_MIPS3,      CPU_R4000 },
+  { "mips4",          MIPS_CPU_IS_ISA,		ISA_MIPS4,      CPU_R8000 },
+  { "mips5",          MIPS_CPU_IS_ISA,		ISA_MIPS5,      CPU_MIPS5 },
+  { "mips32",         MIPS_CPU_IS_ISA,		ISA_MIPS32,     CPU_MIPS32 },
+  { "mips32r2",       MIPS_CPU_IS_ISA,		ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "mips64",         MIPS_CPU_IS_ISA,		ISA_MIPS64,     CPU_MIPS64 },
+  { "mips64r2",       MIPS_CPU_IS_ISA,		ISA_MIPS64R2,   CPU_MIPS64R2 },
 
   /* MIPS I */
-  { "r3000",          0,      ISA_MIPS1,      CPU_R3000 },
-  { "r2000",          0,      ISA_MIPS1,      CPU_R3000 },
-  { "r3900",          0,      ISA_MIPS1,      CPU_R3900 },
+  { "r3000",          0,			ISA_MIPS1,      CPU_R3000 },
+  { "r2000",          0,			ISA_MIPS1,      CPU_R3000 },
+  { "r3900",          0,			ISA_MIPS1,      CPU_R3900 },
 
   /* MIPS II */
-  { "r6000",          0,      ISA_MIPS2,      CPU_R6000 },
+  { "r6000",          0,			ISA_MIPS2,      CPU_R6000 },
 
   /* MIPS III */
-  { "r4000",          0,      ISA_MIPS3,      CPU_R4000 },
-  { "r4010",          0,      ISA_MIPS2,      CPU_R4010 },
-  { "vr4100",         0,      ISA_MIPS3,      CPU_VR4100 },
-  { "vr4111",         0,      ISA_MIPS3,      CPU_R4111 },
-  { "vr4120",         0,      ISA_MIPS3,      CPU_VR4120 },
-  { "vr4130",         0,      ISA_MIPS3,      CPU_VR4120 },
-  { "vr4181",         0,      ISA_MIPS3,      CPU_R4111 },
-  { "vr4300",         0,      ISA_MIPS3,      CPU_R4300 },
-  { "r4400",          0,      ISA_MIPS3,      CPU_R4400 },
-  { "r4600",          0,      ISA_MIPS3,      CPU_R4600 },
-  { "orion",          0,      ISA_MIPS3,      CPU_R4600 },
-  { "r4650",          0,      ISA_MIPS3,      CPU_R4650 },
+  { "r4000",          0,			ISA_MIPS3,      CPU_R4000 },
+  { "r4010",          0,			ISA_MIPS2,      CPU_R4010 },
+  { "vr4100",         0,			ISA_MIPS3,      CPU_VR4100 },
+  { "vr4111",         0,			ISA_MIPS3,      CPU_R4111 },
+  { "vr4120",         0,			ISA_MIPS3,      CPU_VR4120 },
+  { "vr4130",         0,			ISA_MIPS3,      CPU_VR4120 },
+  { "vr4181",         0,			ISA_MIPS3,      CPU_R4111 },
+  { "vr4300",         0,			ISA_MIPS3,      CPU_R4300 },
+  { "r4400",          0,			ISA_MIPS3,      CPU_R4400 },
+  { "r4600",          0,			ISA_MIPS3,      CPU_R4600 },
+  { "orion",          0,			ISA_MIPS3,      CPU_R4600 },
+  { "r4650",          0,			ISA_MIPS3,      CPU_R4650 },
 
   /* MIPS IV */
-  { "r8000",          0,      ISA_MIPS4,      CPU_R8000 },
-  { "r10000",         0,      ISA_MIPS4,      CPU_R10000 },
-  { "r12000",         0,      ISA_MIPS4,      CPU_R12000 },
-  { "vr5000",         0,      ISA_MIPS4,      CPU_R5000 },
-  { "vr5400",         0,      ISA_MIPS4,      CPU_VR5400 },
-  { "vr5500",         0,      ISA_MIPS4,      CPU_VR5500 },
-  { "rm5200",         0,      ISA_MIPS4,      CPU_R5000 },
-  { "rm5230",         0,      ISA_MIPS4,      CPU_R5000 },
-  { "rm5231",         0,      ISA_MIPS4,      CPU_R5000 },
-  { "rm5261",         0,      ISA_MIPS4,      CPU_R5000 },
-  { "rm5721",         0,      ISA_MIPS4,      CPU_R5000 },
-  { "rm7000",         0,      ISA_MIPS4,      CPU_RM7000 },
-  { "rm9000",         0,      ISA_MIPS4,      CPU_RM9000 },
+  { "r8000",          0,			ISA_MIPS4,      CPU_R8000 },
+  { "r10000",         0,			ISA_MIPS4,      CPU_R10000 },
+  { "r12000",         0,			ISA_MIPS4,      CPU_R12000 },
+  { "vr5000",         0,			ISA_MIPS4,      CPU_R5000 },
+  { "vr5400",         0,			ISA_MIPS4,      CPU_VR5400 },
+  { "vr5500",         0,			ISA_MIPS4,      CPU_VR5500 },
+  { "rm5200",         0,			ISA_MIPS4,      CPU_R5000 },
+  { "rm5230",         0,			ISA_MIPS4,      CPU_R5000 },
+  { "rm5231",         0,			ISA_MIPS4,      CPU_R5000 },
+  { "rm5261",         0,			ISA_MIPS4,      CPU_R5000 },
+  { "rm5721",         0,			ISA_MIPS4,      CPU_R5000 },
+  { "rm7000",         0,			ISA_MIPS4,      CPU_RM7000 },
+  { "rm9000",         0,			ISA_MIPS4,      CPU_RM9000 },
 
   /* MIPS 32 */
-  { "4kc",            0,      ISA_MIPS32,     CPU_MIPS32 },
-  { "4km",            0,      ISA_MIPS32,     CPU_MIPS32 },
-  { "4kp",            0,      ISA_MIPS32,     CPU_MIPS32 },
-
-  /* MIPS32 Release 2 */
-  { "m4k",            0,      ISA_MIPS32R2,   CPU_MIPS32R2 },
-  { "24k",            0,      ISA_MIPS32R2,   CPU_MIPS32R2 },
-  { "24kc",           0,      ISA_MIPS32R2,   CPU_MIPS32R2 },
-  { "24kf",           0,      ISA_MIPS32R2,   CPU_MIPS32R2 },
-  { "24kx",           0,      ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "4kc",            0,			ISA_MIPS32,	CPU_MIPS32 },
+  { "4km",            0,			ISA_MIPS32,	CPU_MIPS32 },
+  { "4kp",            0,			ISA_MIPS32,	CPU_MIPS32 },
+  { "4ksc",           MIPS_CPU_ASE_SMARTMIPS,	ISA_MIPS32,	CPU_MIPS32 },
+
+  /* MIPS 32 Release 2 */
+  { "4kec",           0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "4kem",           0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "4kep",           0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "4ksd",           MIPS_CPU_ASE_SMARTMIPS,	ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "m4k",            0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "m4kp",           0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "24k",            0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "24kc",           0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "24kf",           0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "24kx",           0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  /* 24ke is a 24k with DSP ASE, other ASEs are optional.  */
+  { "24ke",           MIPS_CPU_ASE_DSP,		ISA_MIPS32R2,	CPU_MIPS32R2 },
+  { "24kec",          MIPS_CPU_ASE_DSP,		ISA_MIPS32R2,	CPU_MIPS32R2 },
+  { "24kef",          MIPS_CPU_ASE_DSP,		ISA_MIPS32R2,	CPU_MIPS32R2 },
+  { "24kex",         MIPS_CPU_ASE_DSP,		ISA_MIPS32R2,	CPU_MIPS32R2 },
+  /* 34k is a 24k with MT ASE, other ASEs are optional.  */
+  { "34kc",           MIPS_CPU_ASE_MT,		ISA_MIPS32R2,	CPU_MIPS32R2 },
+  { "34kf",           MIPS_CPU_ASE_MT,		ISA_MIPS32R2,	CPU_MIPS32R2 },
+  { "34kx",          MIPS_CPU_ASE_MT,		ISA_MIPS32R2,	CPU_MIPS32R2 },
 
   /* MIPS 64 */
-  { "5kc",            0,      ISA_MIPS64,     CPU_MIPS64 },
-  { "5kf",            0,      ISA_MIPS64,     CPU_MIPS64 },
-  { "20kc",           0,      ISA_MIPS64,     CPU_MIPS64 },
+  { "5kc",            0,			ISA_MIPS64,	CPU_MIPS64 },
+  { "5kf",            0,			ISA_MIPS64,	CPU_MIPS64 },
+  { "20kc",           MIPS_CPU_ASE_MIPS3D,	ISA_MIPS64,	CPU_MIPS64 },
+
+  /* MIPS 64 Release 2 */
+  { "25kf",           MIPS_CPU_ASE_MIPS3D,	ISA_MIPS64R2,   CPU_MIPS64R2 },
 
   /* Broadcom SB-1 CPU core */
-  { "sb1",            0,      ISA_MIPS64,     CPU_SB1 },
+  { "sb1",            0,			ISA_MIPS64,	CPU_SB1 },
 
   /* End marker */
   { NULL, 0, 0, 0 }
@@ -14594,7 +14736,7 @@ mips_cpu_info_from_isa (int isa)
   int i;
 
   for (i = 0; mips_cpu_info_table[i].name != NULL; i++)
-    if (mips_cpu_info_table[i].is_isa
+    if ((mips_cpu_info_table[i].flags & MIPS_CPU_IS_ISA)
 	&& isa == mips_cpu_info_table[i].isa)
       return (&mips_cpu_info_table[i]);
 
Index: gas/testsuite/gas/mips/mips-gp32-fp64-pic.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips-gp32-fp64-pic.d,v
retrieving revision 1.6
diff -u -p -r1.6 mips-gp32-fp64-pic.d
--- gas/testsuite/gas/mips/mips-gp32-fp64-pic.d	22 Apr 2004 18:13:56 -0000	1.6
+++ gas/testsuite/gas/mips/mips-gp32-fp64-pic.d	22 May 2006 15:23:40 -0000
@@ -1,6 +1,7 @@
 #objdump: -d -mmips:8000
 #as: -32 -march=8000 -EB -mgp32 -mfp64 -KPIC
 #name: MIPS -mgp32 -mfp64 (SVR4 PIC)
+#stderr: mips-gp32-fp64.l
 
 .*: +file format.*
 
Index: gas/testsuite/gas/mips/mips-gp32-fp64.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips-gp32-fp64.d,v
retrieving revision 1.5
diff -u -p -r1.5 mips-gp32-fp64.d
--- gas/testsuite/gas/mips/mips-gp32-fp64.d	7 May 2003 05:08:20 -0000	1.5
+++ gas/testsuite/gas/mips/mips-gp32-fp64.d	22 May 2006 15:23:40 -0000
@@ -1,6 +1,7 @@
 #objdump: -d -mmips:8000
 #as: -32 -march=8000 -EB -mgp32 -mfp64
 #name: MIPS -mgp32 -mfp64
+#stderr: mips-gp32-fp64.l
 
 .*: +file format.*
 
Index: gas/testsuite/gas/mips/mips-gp64-fp32-pic.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips-gp64-fp32-pic.d,v
retrieving revision 1.6
diff -u -p -r1.6 mips-gp64-fp32-pic.d
--- gas/testsuite/gas/mips/mips-gp64-fp32-pic.d	22 Apr 2004 18:13:56 -0000	1.6
+++ gas/testsuite/gas/mips/mips-gp64-fp32-pic.d	22 May 2006 15:23:40 -0000
@@ -1,6 +1,7 @@
 #objdump: -d -mmips:8000
 #as: -mabi=o64 -march=8000 -EB -mfp32 -KPIC
 #name: MIPS -mgp64 -mfp32 (SVR4 PIC)
+#stderr: mips-gp64-fp32-pic.l
 
 .*: +file format.*
 
Index: gas/testsuite/gas/mips/mips-gp64-fp32.l
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips-gp64-fp32.l,v
retrieving revision 1.1
diff -u -p -r1.1 mips-gp64-fp32.l
--- gas/testsuite/gas/mips/mips-gp64-fp32.l	22 Apr 2002 22:29:47 -0000	1.1
+++ gas/testsuite/gas/mips/mips-gp64-fp32.l	22 May 2006 15:23:40 -0000
@@ -1,4 +1,5 @@
-.*: Assembler messages:
+Assembler messages:
+Warning: -mfp32 used with a 64-bit ABI
 .*:92: Warning: Macro instruction expanded into multiple instructions in a branch delay slot
 .*:96: Warning: Macro instruction expanded into multiple instructions in a branch delay slot
 .*:100: Warning: Macro instruction expanded into multiple instructions in a branch delay slot
Index: gas/testsuite/gas/mips/mips-gp64-fp64.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips-gp64-fp64.d,v
retrieving revision 1.6
diff -u -p -r1.6 mips-gp64-fp64.d
--- gas/testsuite/gas/mips/mips-gp64-fp64.d	7 May 2003 05:08:20 -0000	1.6
+++ gas/testsuite/gas/mips/mips-gp64-fp64.d	22 May 2006 15:23:40 -0000
@@ -1,7 +1,7 @@
 #objdump: -d -mmips:8000
 #as: -mabi=o64 -march=8000 -EB
 #name: MIPS -mgp64 -mfp64
-#stderr: mips-gp64-fp32.l
+#stderr: mips-gp64-fp64.l
 
 .*: +file format.*
 
--- /dev/null	2006-05-17 20:07:57.714000000 +0100
+++ gas/testsuite/gas/mips/mips-gp32-fp64.l	2006-05-22 15:40:46.000000000 +0100
@@ -0,0 +1,2 @@
+Assembler messages:
+Warning: -mfp64 used with a 32-bit ABI
--- /dev/null	2006-05-17 20:07:57.714000000 +0100
+++ gas/testsuite/gas/mips/mips-gp64-fp32-pic.l	2006-05-22 16:06:58.000000000 +0100
@@ -0,0 +1,2 @@
+Assembler messages:
+Warning: -mfp32 used with a 64-bit ABI
Index: gas/doc/c-mips.texi
===================================================================
RCS file: /cvs/src/src/gas/doc/c-mips.texi,v
retrieving revision 1.37
diff -u -p -r1.37 c-mips.texi
--- gas/doc/c-mips.texi	8 May 2006 15:57:05 -0000	1.37
+++ gas/doc/c-mips.texi	22 May 2006 19:56:05 -0000
@@ -91,6 +91,10 @@ flags force a certain group of registers
 all times.  @samp{-mgp32} controls the size of general-purpose registers
 and @samp{-mfp32} controls the size of floating-point registers.
 
+The @samp{.set gp32} directive allows to change the size of
+general-purpose registers for parts of an object. The default
+value is restored by @samp{.set nogp32}.
+
 On some MIPS variants there is a 32-bit mode flag; when this flag is
 set, 64-bit instructions generate a trap.  Also, some 32-bit OSes only
 save the 32-bit registers on a context switch, so it is essential never
@@ -100,6 +104,10 @@ to use the 64-bit registers.
 Assume that 64-bit general purpose registers are available.  This is
 provided in the interests of symmetry with -gp32.
 
+The @samp{.set gp64} directive allows to change the size of
+general-purpose registers for parts of an object. The default
+value is restored by @samp{.set nogp64}.
+
 @item -mips16
 @itemx -no-mips16
 Generate code for the MIPS 16 processor.  This is equivalent to putting
@@ -210,7 +218,29 @@ rm7000,
 rm9000,
 10000,
 12000,
-mips32-4k,
+4kc,
+4km,
+4kp,
+4ksc,
+4kec,
+4kem,
+4kep,
+4ksd,
+m4k,
+m4kp,
+24kc,
+24kf,
+24kx,
+24kec,
+24kef,
+24kex,
+34kc,
+34kf,
+34kx,
+5kc,
+5kf,
+20kc,
+25kf,
 sb1
 @end quotation
 
@@ -399,18 +429,22 @@ assembly.  @code{.set mips@var{n}} affec
 are permitted, but also how certain macros are expanded.  @code{.set
 mips0} restores the @sc{isa} level to its original level: either the
 level you selected with command line options, or the default for your
-configuration.  You can use this feature to permit specific @sc{r4000}
+configuration.  You can use this feature to permit specific @sc{mips3}
 instructions while assembling in 32 bit mode.  Use this directive with
 care!
 
+@cindex MIPS CPU override
+@kindex @code{.set arch=@var{cpu}}
+Even finer control provides the @code{.set arch=@var{cpu}} directive.
+It changes the effective CPU target and allows to assemble instructions
+specific to a particular CPU.  All CPUs supported by the @samp{-march}
+command line option are also selectable by this directive.  The original
+value is restored by @code{.set arch=default}.
+
 The directive @samp{.set mips16} puts the assembler into MIPS 16 mode,
 in which it will assemble instructions for the MIPS 16 processor.  Use
 @samp{.set nomips16} to return to normal 32 bit mode.
 
-The @samp{.set smartmips} directive enables use of the SmartMIPS
-extensions to the MIPS32 @sc{isa}; the @samp{.set nosmartmips} directive
-reverses that.
-
 Traditional @sc{mips} assemblers do not support this directive.
 
 @node MIPS autoextend
@@ -467,6 +501,15 @@ from the MIPS-3D Application Specific Ex
 in the assembly.  The @code{.set nomips3d} directive prevents MIPS-3D
 instructions from being accepted.
 
+@cindex SmartMIPS instruction generation override
+@kindex @code{.set smartmips}
+@kindex @code{.set nosmartmips}
+The directive @code{.set smartmips} makes the assembler accept
+instructions from the SmartMIPS Application Specific Extension to the
+MIPS32 @sc{isa} from that point on in the assembly.  The
+@code{.set nosmartmips} directive prevents SmartMIPS instructions from
+being accepted.
+
 @cindex MIPS MDMX instruction generation override
 @kindex @code{.set mdmx}
 @kindex @code{.set nomdmx}

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Better checking of ISA/ASE/ABI options for MIPS gas
  2006-05-23  0:08 [PATCH] Better checking of ISA/ASE/ABI options for MIPS gas Thiemo Seufer
@ 2006-05-23  4:06 ` Eric Christopher
  2006-05-23  4:40   ` Thiemo Seufer
  2006-05-23 12:10 ` Richard Sandiford
  2006-05-23 17:47 ` Thiemo Seufer
  2 siblings, 1 reply; 14+ messages in thread
From: Eric Christopher @ 2006-05-23  4:06 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils

>
> I'm somewhat uncertain about the ABI incompatibility warning for
> wrong FP register widths, does it make sense to force a different
> FP register width in the assembler in some cases?
>

No. No more reading the minds of programmers. :)

btw, the indention on the code in the diff is wacky. I assume it's  
correct in your files?

> @@ -1031,7 +1052,13 @@ static int validate_mips_insn (const str
>  struct mips_cpu_info
>  {
>    const char *name;           /* CPU or ISA name.  */
> -  int is_isa;                 /* Is this an ISA?  (If 0, a CPU.) */
> +  int flags;
> +#define MIPS_CPU_IS_ISA		0x0001	/* Is this an ISA?  (If 0, a CPU.) */
> +#define MIPS_CPU_ASE_SMARTMIPS	0x0002	/* CPU implements SmartMIPS  
> ASE */
> +#define MIPS_CPU_ASE_DSP	0x0004	/* CPU implements DSP ASE */
> +#define MIPS_CPU_ASE_MT		0x0008	/* CPU implements MT ASE */
> +#define MIPS_CPU_ASE_MIPS3D	0x0010	/* CPU implements MIPS-3D ASE */
> +#define MIPS_CPU_ASE_MDMX	0x0020	/* CPU implements MDMX ASE */
>    int isa;                    /* ISA level.  */
>    int cpu;                    /* CPU number (default CPU if ISA).  */
>  };

Ugh. Can you haul these defines out somewhere else? And why change  
the table to include default extensions for the cpu?

>
>    /* End of GCC-shared inference code.  */

You need to make sure that this shared code is the same logic in both  
places - preferably before committing this.

> +
> +#if 0 /* XXX FIXME */
> +  /* 32 bit code with 64 bit FP registers.  */
> +  if (!file_mips_fp32 && ABI_NEEDS_32BIT_REGS (mips_abi))
> +    elf_elfheader (stdoutput)->e_flags |= ???;
> +#endif
>  }
>

???

-eric

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Better checking of ISA/ASE/ABI options for MIPS gas
  2006-05-23  4:06 ` Eric Christopher
@ 2006-05-23  4:40   ` Thiemo Seufer
  2006-05-23  5:01     ` Eric Christopher
  0 siblings, 1 reply; 14+ messages in thread
From: Thiemo Seufer @ 2006-05-23  4:40 UTC (permalink / raw)
  To: Eric Christopher; +Cc: binutils

Eric Christopher wrote:
> >
> >I'm somewhat uncertain about the ABI incompatibility warning for
> >wrong FP register widths, does it make sense to force a different
> >FP register width in the assembler in some cases?
> >
> 
> No. No more reading the minds of programmers. :)

Well, for GP registers we do even as_bad().

> btw, the indention on the code in the diff is wacky. I assume it's  
> correct in your files?

I think so.

> >@@ -1031,7 +1052,13 @@ static int validate_mips_insn (const str
> > struct mips_cpu_info
> > {
> >   const char *name;           /* CPU or ISA name.  */
> >-  int is_isa;                 /* Is this an ISA?  (If 0, a CPU.) */
> >+  int flags;
> >+#define MIPS_CPU_IS_ISA		0x0001	/* Is this an ISA?  (If 0, a 
> >CPU.) */
> >+#define MIPS_CPU_ASE_SMARTMIPS	0x0002	/* CPU implements SmartMIPS  
> >ASE */
> >+#define MIPS_CPU_ASE_DSP	0x0004	/* CPU implements DSP ASE */
> >+#define MIPS_CPU_ASE_MT		0x0008	/* CPU implements MT ASE */
> >+#define MIPS_CPU_ASE_MIPS3D	0x0010	/* CPU implements MIPS-3D ASE */
> >+#define MIPS_CPU_ASE_MDMX	0x0020	/* CPU implements MDMX ASE */
> >   int isa;                    /* ISA level.  */
> >   int cpu;                    /* CPU number (default CPU if ISA).  */
> > };
> 
> Ugh. Can you haul these defines out somewhere else?

Sure.

> And why change the table to include default extensions for the cpu?

To handle them the same way as the ISA. This is for ASEs which are
always implemented in that particular CPU.

> >   /* End of GCC-shared inference code.  */
> 
> You need to make sure that this shared code is the same logic in both  
> places - preferably before committing this.

Yes. Do you think the logic is ok (modulo the FP ABI warning)?

> >+#if 0 /* XXX FIXME */
> >+  /* 32 bit code with 64 bit FP registers.  */
> >+  if (!file_mips_fp32 && ABI_NEEDS_32BIT_REGS (mips_abi))
> >+    elf_elfheader (stdoutput)->e_flags |= ???;
> >+#endif
> > }
> >
> 
> ???

Same like for MIPS3D, we should tell the linker this object is (possibly)
incompatible to other O32 objects with 32bit FP regs.


Thiemo

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Better checking of ISA/ASE/ABI options for MIPS gas
  2006-05-23  4:40   ` Thiemo Seufer
@ 2006-05-23  5:01     ` Eric Christopher
  2006-05-23  5:27       ` Thiemo Seufer
  0 siblings, 1 reply; 14+ messages in thread
From: Eric Christopher @ 2006-05-23  5:01 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils

>>
>> No. No more reading the minds of programmers. :)
>
> Well, for GP registers we do even as_bad().

Yup.

>> And why change the table to include default extensions for the cpu?
>
> To handle them the same way as the ISA. This is for ASEs which are
> always implemented in that particular CPU.

You'll need to look through the code and make sure we aren't  
depending on
the value not being zero somewhere then. To be honest I'd just prefer  
another
field for "default ASEs".

>>>   /* End of GCC-shared inference code.  */
>>
>> You need to make sure that this shared code is the same logic in both
>> places - preferably before committing this.
>
> Yes. Do you think the logic is ok (modulo the FP ABI warning)?

I do. :)

>>> +#if 0 /* XXX FIXME */
>>> +  /* 32 bit code with 64 bit FP registers.  */
>>> +  if (!file_mips_fp32 && ABI_NEEDS_32BIT_REGS (mips_abi))
>>> +    elf_elfheader (stdoutput)->e_flags |= ???;
>>> +#endif
>>> }
>>>
>>
>> ???
>
> Same like for MIPS3D, we should tell the linker this object is  
> (possibly)
> incompatible to other O32 objects with 32bit FP regs.

More comments then :)

-eric

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Better checking of ISA/ASE/ABI options for MIPS gas
  2006-05-23  5:01     ` Eric Christopher
@ 2006-05-23  5:27       ` Thiemo Seufer
  2006-05-23  5:51         ` Eric Christopher
  0 siblings, 1 reply; 14+ messages in thread
From: Thiemo Seufer @ 2006-05-23  5:27 UTC (permalink / raw)
  To: Eric Christopher; +Cc: binutils

Eric Christopher wrote:
[snip]
> >>And why change the table to include default extensions for the cpu?
> >
> >To handle them the same way as the ISA. This is for ASEs which are
> >always implemented in that particular CPU.
> 
> You'll need to look through the code and make sure we aren't depending on
> the value not being zero somewhere then.

I changed the test for is_isa in mips_cpu_info_from_isa() to
(flags & MIPS_CPU_IS_ISA). mips_cpu_info_from_isa() is the only user.

> To be honest I'd just prefer another field for "default ASEs".

  a) This would bloat the table by another field to initialise.
  b) There is no generic ISA with an ASE, both uses are mutually
     exclusive.


Thiemo

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Better checking of ISA/ASE/ABI options for MIPS gas
  2006-05-23  5:27       ` Thiemo Seufer
@ 2006-05-23  5:51         ` Eric Christopher
  0 siblings, 0 replies; 14+ messages in thread
From: Eric Christopher @ 2006-05-23  5:51 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils

>
> I changed the test for is_isa in mips_cpu_info_from_isa() to
> (flags & MIPS_CPU_IS_ISA). mips_cpu_info_from_isa() is the only user.
>
>> To be honest I'd just prefer another field for "default ASEs".
>
>   a) This would bloat the table by another field to initialise.
>   b) There is no generic ISA with an ASE, both uses are mutually
>      exclusive.

No more objections then. :)

-eric

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Better checking of ISA/ASE/ABI options for MIPS gas
  2006-05-23  0:08 [PATCH] Better checking of ISA/ASE/ABI options for MIPS gas Thiemo Seufer
  2006-05-23  4:06 ` Eric Christopher
@ 2006-05-23 12:10 ` Richard Sandiford
  2006-05-23 13:34   ` Thiemo Seufer
  2006-05-23 17:47 ` Thiemo Seufer
  2 siblings, 1 reply; 14+ messages in thread
From: Richard Sandiford @ 2006-05-23 12:10 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils

FWIW, as a bystander, I like this.  Just a couple of things:

> I'm somewhat uncertain about the ABI incompatibility warning for
> wrong FP register widths, does it make sense to force a different
> FP register width in the assembler in some cases?

I agree with you and Eric that complaining rather than overriding
is the right way to go.

Thiemo Seufer <ths@networkno.de> writes:
> +#define ISA_SUPPORT_DSP_ASE	(mips_opts.isa == ISA_MIPS32R2       \
> +				 || mips_opts.isa == ISA_MIPS64R2)
> +
>  /* True if -mmt was passed or implied by arguments passed on the
>     command line (e.g., by -march).  */
>  static int file_ase_mt;
>  
> +#define ISA_SUPPORT_MT_ASE	(mips_opts.isa == ISA_MIPS32R2       \
> +				 || mips_opts.isa == ISA_MIPS64R2)
> +

Nitpick: ISA_SUPPORTS rather than ISA_SUPPORT.  (I see ISA_SUPPORT_SMARTMIPS
is already in, but SUPPORTS is grammatically correct, and more consistent
with other macros like ISA_HAS.)

> +/*  Return true if ISA supports 64 bit float register instructions.  */
> +#define ISA_HAS_64BIT_FPRS(ISA)		\
> +  ((ISA) == ISA_MIPS3			\
> +   || (ISA) == ISA_MIPS4		\
> +   || (ISA) == ISA_MIPS5		\
> +   || (ISA) == ISA_MIPS32R2		\
> +   || (ISA) == ISA_MIPS64		\
> +   || (ISA) == ISA_MIPS64R2)
> +

Another nitpick: "64 bit float register instructions" seems a bit woolly.
In the subset of instructions supported by ISA_MIPS3, I don't think any
instructions are inherently "32 bit float register instructions" or
"64 bit float register instructions".  It's a property of the processor
mode rather than the instruction itself.  I realise that, as far as the
ISA_MIPS3 subset goes, you probably mean "instructions with odd-numbered
register operands", but the comment doesn't make that immediately clear.
The macro name seems more accurate than the comment.

> -  /* ??? GAS treats single-float processors as though they had 64-bit
> -     float registers (although it complains when double-precision
> -     instructions are used).  As things stand, saying they have 32-bit
> -     registers would lead to spurious "register must be even" messages.
> -     So here we assume float registers are always the same size as
> -     integer ones, unless the user says otherwise.  */
> -  if (file_mips_fp32 < 0)
> -    file_mips_fp32 = file_mips_gp32;
> +  switch (file_mips_fp32)
> +    {
> +    default:
> +    case -1:
> +      /* No user specified float register size.  */
> +      if (file_mips_gp32 == 0)
> +	/* 64-bit integer registers implies 64-bit float registers.  */
> +	file_mips_fp32 = 0;
> +      else if ((mips_opts.ase_mips3d > 0 || mips_opts.ase_mdmx > 0)
> +	       && ISA_HAS_64BIT_FPRS (mips_opts.isa))
> +	/* -mips3d and -mdmx imply 64-bit float registers, if possible.  */
> +	file_mips_fp32 = 0;
> +      else
> +	/* 32-bit float registers. */
> +	file_mips_fp32 = 1;
> +      break;
> +
> +    /* The user specified the size of the float registers.  Check if it
> +       agrees with the ABI and ISA.  */
> +    case 0:
> +      if (!ISA_HAS_64BIT_FPRS (mips_opts.isa))
> +	as_bad (_("-mfp64 used with a 32-bit fpu"));
> +      else if (ABI_NEEDS_32BIT_REGS (mips_abi)
> +	       && !ISA_HAS_MXHC1 (mips_opts.isa))
> +	as_warn (_("-mfp64 used with a 32-bit ABI"));
> +      break;
> +    case 1:
> +      if (ABI_NEEDS_64BIT_REGS (mips_abi))
> +	as_warn (_("-mfp32 used with a 64-bit ABI"));
> +      break;
> +    }

Doesn't the ??? comment still hold?  I thought it would be valuable
to keep it.

> +  else if (strcmp (name, "gp64") == 0)
> +    {
> +      if (!ISA_HAS_64BIT_REGS (mips_opts.isa))
> +	as_warn ("%s isa does not support 64-bit registers", 
> +		 mips_cpu_info_from_isa (mips_opts.isa)->name);
> +      mips_opts.gp32 = 0;
> +    }
> +  else if (strcmp (name, "gp32") == 0)
> +    {
> +      mips_opts.gp32 = 1;
> +    }
> +  else if (strcmp (name, "nogp64") == 0 || strcmp (name, "nogp32") == 0)
> +    {
> +      mips_opts.gp32 = file_mips_gp32;
> +    }

Ugh.  I don't like the "nogp32" and "nogp64".  All other ".set X"/".set noX"
pairs are used for turning a particular feature on and off.  Having "nogp32"
restore the prevailing size (even if that prevailing size _is_ gp32)
seems very counter-intuitive to me.  Could we not have ".set gp=" instead,
with a special value to select the prevailing size?  That would be more
consistent with .set mipsX and .set arch=X, for example.

Richard

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Better checking of ISA/ASE/ABI options for MIPS gas
  2006-05-23 12:10 ` Richard Sandiford
@ 2006-05-23 13:34   ` Thiemo Seufer
  2006-05-23 14:14     ` Richard Sandiford
  0 siblings, 1 reply; 14+ messages in thread
From: Thiemo Seufer @ 2006-05-23 13:34 UTC (permalink / raw)
  To: binutils, richard

Richard Sandiford wrote:
[snip]
> > -  /* ??? GAS treats single-float processors as though they had 64-bit
> > -     float registers (although it complains when double-precision
> > -     instructions are used).  As things stand, saying they have 32-bit
> > -     registers would lead to spurious "register must be even" messages.
> > -     So here we assume float registers are always the same size as
> > -     integer ones, unless the user says otherwise.  */
> > -  if (file_mips_fp32 < 0)
> > -    file_mips_fp32 = file_mips_gp32;
> > +  switch (file_mips_fp32)
> > +    {
> > +    default:
> > +    case -1:
> > +      /* No user specified float register size.  */
> > +      if (file_mips_gp32 == 0)
> > +	/* 64-bit integer registers implies 64-bit float registers.  */
> > +	file_mips_fp32 = 0;
> > +      else if ((mips_opts.ase_mips3d > 0 || mips_opts.ase_mdmx > 0)
> > +	       && ISA_HAS_64BIT_FPRS (mips_opts.isa))
> > +	/* -mips3d and -mdmx imply 64-bit float registers, if possible.  */
> > +	file_mips_fp32 = 0;
> > +      else
> > +	/* 32-bit float registers. */
> > +	file_mips_fp32 = 1;
> > +      break;
> > +
> > +    /* The user specified the size of the float registers.  Check if it
> > +       agrees with the ABI and ISA.  */
> > +    case 0:
> > +      if (!ISA_HAS_64BIT_FPRS (mips_opts.isa))
> > +	as_bad (_("-mfp64 used with a 32-bit fpu"));
> > +      else if (ABI_NEEDS_32BIT_REGS (mips_abi)
> > +	       && !ISA_HAS_MXHC1 (mips_opts.isa))
> > +	as_warn (_("-mfp64 used with a 32-bit ABI"));
> > +      break;
> > +    case 1:
> > +      if (ABI_NEEDS_64BIT_REGS (mips_abi))
> > +	as_warn (_("-mfp32 used with a 64-bit ABI"));
> > +      break;
> > +    }
> 
> Doesn't the ??? comment still hold?  I thought it would be valuable
> to keep it.

The defaulting is now more complicated than the comment suggests.

> > +  else if (strcmp (name, "gp64") == 0)
> > +    {
> > +      if (!ISA_HAS_64BIT_REGS (mips_opts.isa))
> > +	as_warn ("%s isa does not support 64-bit registers", 
> > +		 mips_cpu_info_from_isa (mips_opts.isa)->name);
> > +      mips_opts.gp32 = 0;
> > +    }
> > +  else if (strcmp (name, "gp32") == 0)
> > +    {
> > +      mips_opts.gp32 = 1;
> > +    }
> > +  else if (strcmp (name, "nogp64") == 0 || strcmp (name, "nogp32") == 0)
> > +    {
> > +      mips_opts.gp32 = file_mips_gp32;
> > +    }
> 
> Ugh.  I don't like the "nogp32" and "nogp64". 

Well, it is what MIPS' SDE toolchain supports.

> All other ".set X"/".set noX"
> pairs are used for turning a particular feature on and off.  Having "nogp32"
> restore the prevailing size (even if that prevailing size _is_ gp32)
> seems very counter-intuitive to me.  Could we not have ".set gp=" instead,
> with a special value to select the prevailing size?  That would be more
> consistent with .set mipsX and .set arch=X, for example.

Hm, .set gp={32,64,default} or .set gp{32,64,0} ?


Thiemo

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Better checking of ISA/ASE/ABI options for MIPS gas
  2006-05-23 13:34   ` Thiemo Seufer
@ 2006-05-23 14:14     ` Richard Sandiford
  2006-05-23 15:39       ` Thiemo Seufer
  0 siblings, 1 reply; 14+ messages in thread
From: Richard Sandiford @ 2006-05-23 14:14 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils

Thiemo Seufer <ths@networkno.de> writes:
> Richard Sandiford wrote:
> [snip]
>> > -  /* ??? GAS treats single-float processors as though they had 64-bit
>> > -     float registers (although it complains when double-precision
>> > -     instructions are used).  As things stand, saying they have 32-bit
>> > -     registers would lead to spurious "register must be even" messages.
>> > -     So here we assume float registers are always the same size as
>> > -     integer ones, unless the user says otherwise.  */
>> > -  if (file_mips_fp32 < 0)
>> > -    file_mips_fp32 = file_mips_gp32;
>> > +  switch (file_mips_fp32)
>> > +    {
>> > +    default:
>> > +    case -1:
>> > +      /* No user specified float register size.  */
>> > +      if (file_mips_gp32 == 0)
>> > +	/* 64-bit integer registers implies 64-bit float registers.  */
>> > +	file_mips_fp32 = 0;
>> > +      else if ((mips_opts.ase_mips3d > 0 || mips_opts.ase_mdmx > 0)
>> > +	       && ISA_HAS_64BIT_FPRS (mips_opts.isa))
>> > +	/* -mips3d and -mdmx imply 64-bit float registers, if possible.  */
>> > +	file_mips_fp32 = 0;
>> > +      else
>> > +	/* 32-bit float registers. */
>> > +	file_mips_fp32 = 1;
>> > +      break;
>> > +
>> > +    /* The user specified the size of the float registers.  Check if it
>> > +       agrees with the ABI and ISA.  */
>> > +    case 0:
>> > +      if (!ISA_HAS_64BIT_FPRS (mips_opts.isa))
>> > +	as_bad (_("-mfp64 used with a 32-bit fpu"));
>> > +      else if (ABI_NEEDS_32BIT_REGS (mips_abi)
>> > +	       && !ISA_HAS_MXHC1 (mips_opts.isa))
>> > +	as_warn (_("-mfp64 used with a 32-bit ABI"));
>> > +      break;
>> > +    case 1:
>> > +      if (ABI_NEEDS_64BIT_REGS (mips_abi))
>> > +	as_warn (_("-mfp32 used with a 64-bit ABI"));
>> > +      break;
>> > +    }
>> 
>> Doesn't the ??? comment still hold?  I thought it would be valuable
>> to keep it.
>
> The defaulting is now more complicated than the comment suggests.

True.  I was meaning the first bit though, about single-float processors.

OTOH, the whole comment might make sense as-is in place of
"/* 32-bit float registers. */".

>> > +  else if (strcmp (name, "gp64") == 0)
>> > +    {
>> > +      if (!ISA_HAS_64BIT_REGS (mips_opts.isa))
>> > +	as_warn ("%s isa does not support 64-bit registers", 
>> > +		 mips_cpu_info_from_isa (mips_opts.isa)->name);
>> > +      mips_opts.gp32 = 0;
>> > +    }
>> > +  else if (strcmp (name, "gp32") == 0)
>> > +    {
>> > +      mips_opts.gp32 = 1;
>> > +    }
>> > +  else if (strcmp (name, "nogp64") == 0 || strcmp (name, "nogp32") == 0)
>> > +    {
>> > +      mips_opts.gp32 = file_mips_gp32;
>> > +    }
>> 
>> Ugh.  I don't like the "nogp32" and "nogp64". 
>
> Well, it is what MIPS' SDE toolchain supports.

I'm not sure whether you're giving that as a reason not to change it,
or whether it's just an FYI.

>> All other ".set X"/".set noX"
>> pairs are used for turning a particular feature on and off.  Having "nogp32"
>> restore the prevailing size (even if that prevailing size _is_ gp32)
>> seems very counter-intuitive to me.  Could we not have ".set gp=" instead,
>> with a special value to select the prevailing size?  That would be more
>> consistent with .set mipsX and .set arch=X, for example.
>
> Hm, .set gp={32,64,default} or .set gp{32,64,0} ?

The former sounds better to me.

Richard

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Better checking of ISA/ASE/ABI options for MIPS gas
  2006-05-23 14:14     ` Richard Sandiford
@ 2006-05-23 15:39       ` Thiemo Seufer
  0 siblings, 0 replies; 14+ messages in thread
From: Thiemo Seufer @ 2006-05-23 15:39 UTC (permalink / raw)
  To: binutils, richard

Richard Sandiford wrote:
[snip]
> >> Ugh.  I don't like the "nogp32" and "nogp64". 
> >
> > Well, it is what MIPS' SDE toolchain supports.
> 
> I'm not sure whether you're giving that as a reason not to change it,
> or whether it's just an FYI.

It's FYI, and it might mean one more local patch for MIPS.


Thiemo

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Better checking of ISA/ASE/ABI options for MIPS gas
  2006-05-23  0:08 [PATCH] Better checking of ISA/ASE/ABI options for MIPS gas Thiemo Seufer
  2006-05-23  4:06 ` Eric Christopher
  2006-05-23 12:10 ` Richard Sandiford
@ 2006-05-23 17:47 ` Thiemo Seufer
  2006-05-23 21:01   ` Richard Sandiford
  2 siblings, 1 reply; 14+ messages in thread
From: Thiemo Seufer @ 2006-05-23 17:47 UTC (permalink / raw)
  To: binutils; +Cc: Richard Sandiford

Thiemo Seufer wrote:
> Hello All,
> 
> this patch adds a bunch of MIPS CPU definitions, defaults ASE
> availability for some of them, improves the checks for incompatible
> ISA/ASE/ABI options, especially for 32bit/64bit FP registers, adds
> support for .set gp32 and .set gp64, and improves the documentation
> a bit.
> 
> I'm somewhat uncertain about the ABI incompatibility warning for
> wrong FP register widths, does it make sense to force a different
> FP register width in the assembler in some cases?

Updated to take all comments into account, and expanded to allow also
for .set fp={23,64,default}.

Richard, do you care about the gcc update (if/when the release cycle
permits it)?


Thiemo


2006-05-23  Thiemo Seufer  <ths@mips.com>
            David Ung  <davidu@mips.com>
            Nigel Stephens  <nigel@mips.com>

	[ gas/ChangeLog ]
	* config/tc-mips.c (ISA_SUPPORTS_SMARTMIPS): Rename.
	(ISA_SUPPORTS_DSP_ASE, ISA_SUPPORTS_MT_ASE, ISA_HAS_64BIT_FPRS,
	ISA_HAS_MXHC1): New macros.
	(HAVE_32BIT_FPRS): Use ISA_HAS_64BIT_FPRS instead of
	ISA_HAS_64BIT_REGS.  Formatting fixes.  Improved comments.
	(mips_cpu_info): Change to use combined ASE/IS_ISA flag.
	(MIPS_CPU_IS_ISA, MIPS_CPU_ASE_SMARTMIPS, MIPS_CPU_ASE_DSP,
	MIPS_CPU_ASE_MT, MIPS_CPU_ASE_MIPS3D, MIPS_CPU_ASE_MDMX): New defines.
	(mips_after_parse_args): Change default handling of float register
	size to account for 32bit code with 64bit FP. Better sanity checking
	of ISA/ASE/ABI option combinations.
	(s_mipsset): Support switching of GPR and FPR sizes via
	.set {g,f}p={32,64,default}. Better sanity checking for .set ASE
	options.
	(mips_elf_final_processing): We should record the use of 64bit FP
	registers in 32bit code but we don't, because ELF header flags are
	a scarce ressource.
	(mips_cpu_info_table): Add ASE flags for CPUs with mandatory ASE
	extensions. Add 4ksc, 4kec, 4kem, 4kep, 4ksd, m4kp, 24kec, 24kef,
	24kex, 34kc, 34kf, 34kx, 25kf CPU definitions.
	(mips_cpu_info_from_isa): Use MIPS_CPU_IS_ISA.

	[ gas/testsuite/Changelog ]
	* gas/mips/mips-gp32-fp64-pic.d, mips/mips-gp32-fp64.d,
	gas/mips/mips-gp64-fp32-pic.d, gas/mips/mips-gp64-fp32.l,
	gas/mips/mips-gp64-fp64.d: Adjust test cases to the changes assembler
	output.
	* gas/mips/mips-gp32-fp64.l, gas/mips/mips-gp64-fp32-pic.l: New files,
	catch assembler warnings.

	[ gas/doc/ChangeLog ]
	* c-mips.texi: Document .set {g,f}p={32,64,default}. Document missing
	-march options. Document .set arch=CPU. Move .set smartmips to ASE
	page. Use @code for .set FOO examples.


Index: gas/config/tc-mips.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mips.c,v
retrieving revision 1.337
diff -u -p -r1.337 tc-mips.c
--- gas/config/tc-mips.c	19 May 2006 13:03:05 -0000	1.337
+++ gas/config/tc-mips.c	23 May 2006 12:46:04 -0000
@@ -274,17 +274,23 @@ static int file_ase_mdmx;
    command line (e.g., by -march).  */
 static int file_ase_smartmips;
 
-#define ISA_SUPPORT_SMARTMIPS (mips_opts.isa == ISA_MIPS32       \
-			       || mips_opts.isa == ISA_MIPS32R2)
+#define ISA_SUPPORTS_SMARTMIPS (mips_opts.isa == ISA_MIPS32		\
+				|| mips_opts.isa == ISA_MIPS32R2)
 
 /* True if -mdsp was passed or implied by arguments passed on the
    command line (e.g., by -march).  */
 static int file_ase_dsp;
 
+#define ISA_SUPPORTS_DSP_ASE (mips_opts.isa == ISA_MIPS32R2		\
+			      || mips_opts.isa == ISA_MIPS64R2)
+
 /* True if -mmt was passed or implied by arguments passed on the
    command line (e.g., by -march).  */
 static int file_ase_mt;
 
+#define ISA_SUPPORTS_MT_ASE (mips_opts.isa == ISA_MIPS32R2		\
+			     || mips_opts.isa == ISA_MIPS64R2)
+
 /* The argument of the -march= flag.  The architecture we are assembling.  */
 static int file_mips_arch = CPU_UNKNOWN;
 static const char *mips_arch_string;
@@ -306,7 +312,7 @@ static int mips_32bitmode = 0;
    || (ABI) == N64_ABI			\
    || (ABI) == O64_ABI)
 
-/*  Return true if ISA supports 64 bit gp register instructions.  */
+/*  Return true if ISA supports 64 bit wide gp registers.  */
 #define ISA_HAS_64BIT_REGS(ISA)		\
   ((ISA) == ISA_MIPS3			\
    || (ISA) == ISA_MIPS4		\
@@ -314,6 +320,15 @@ static int mips_32bitmode = 0;
    || (ISA) == ISA_MIPS64		\
    || (ISA) == ISA_MIPS64R2)
 
+/*  Return true if ISA supports 64 bit wide float registers.  */
+#define ISA_HAS_64BIT_FPRS(ISA)		\
+  ((ISA) == ISA_MIPS3			\
+   || (ISA) == ISA_MIPS4		\
+   || (ISA) == ISA_MIPS5		\
+   || (ISA) == ISA_MIPS32R2		\
+   || (ISA) == ISA_MIPS64		\
+   || (ISA) == ISA_MIPS64R2)
+
 /* Return true if ISA supports 64-bit right rotate (dror et al.)
    instructions.  */
 #define ISA_HAS_DROR(ISA)		\
@@ -333,14 +348,20 @@ static int mips_32bitmode = 0;
    || (ISA) == ISA_MIPS64		\
    || (ISA) == ISA_MIPS64R2)
 
+/* Return true if ISA supports move to/from high part of a 64-bit
+   floating-point register. */
+#define ISA_HAS_MXHC1(ISA)		\
+  ((ISA) == ISA_MIPS32R2		\
+   || (ISA) == ISA_MIPS64R2)
+
 #define HAVE_32BIT_GPRS		                   \
-    (mips_opts.gp32 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
+    (mips_opts.gp32 || !ISA_HAS_64BIT_REGS (mips_opts.isa))
 
 #define HAVE_32BIT_FPRS                            \
-    (mips_opts.fp32 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
+    (mips_opts.fp32 || !ISA_HAS_64BIT_FPRS (mips_opts.isa))
 
-#define HAVE_64BIT_GPRS (! HAVE_32BIT_GPRS)
-#define HAVE_64BIT_FPRS (! HAVE_32BIT_FPRS)
+#define HAVE_64BIT_GPRS (!HAVE_32BIT_GPRS)
+#define HAVE_64BIT_FPRS (!HAVE_32BIT_FPRS)
 
 #define HAVE_NEWABI (mips_abi == N32_ABI || mips_abi == N64_ABI)
 
@@ -1031,11 +1052,18 @@ static int validate_mips_insn (const str
 struct mips_cpu_info
 {
   const char *name;           /* CPU or ISA name.  */
-  int is_isa;                 /* Is this an ISA?  (If 0, a CPU.) */
+  int flags;                  /* ASEs available, or ISA flag.  */
   int isa;                    /* ISA level.  */
   int cpu;                    /* CPU number (default CPU if ISA).  */
 };
 
+#define MIPS_CPU_IS_ISA		0x0001	/* Is this an ISA?  (If 0, a CPU.) */
+#define MIPS_CPU_ASE_SMARTMIPS	0x0002	/* CPU implements SmartMIPS ASE */
+#define MIPS_CPU_ASE_DSP	0x0004	/* CPU implements DSP ASE */
+#define MIPS_CPU_ASE_MT		0x0008	/* CPU implements MT ASE */
+#define MIPS_CPU_ASE_MIPS3D	0x0010	/* CPU implements MIPS-3D ASE */
+#define MIPS_CPU_ASE_MDMX	0x0020	/* CPU implements MDMX ASE */
+
 static const struct mips_cpu_info *mips_parse_cpu (const char *, const char *);
 static const struct mips_cpu_info *mips_cpu_info_from_isa (int);
 static const struct mips_cpu_info *mips_cpu_info_from_arch (int);
@@ -11380,14 +11408,43 @@ mips_after_parse_args (void)
 			|| !ISA_HAS_64BIT_REGS (mips_opts.isa));
     }
 
-  /* ??? GAS treats single-float processors as though they had 64-bit
-     float registers (although it complains when double-precision
-     instructions are used).  As things stand, saying they have 32-bit
-     registers would lead to spurious "register must be even" messages.
-     So here we assume float registers are always the same size as
-     integer ones, unless the user says otherwise.  */
-  if (file_mips_fp32 < 0)
-    file_mips_fp32 = file_mips_gp32;
+  switch (file_mips_fp32)
+    {
+    default:
+    case -1:
+      /* No user specified float register size.
+	 ??? GAS treats single-float processors as though they had 64-bit
+	 float registers (although it complains when double-precision
+	 instructions are used).  As things stand, saying they have 32-bit
+	 registers would lead to spurious "register must be even" messages.
+	 So here we assume float registers are never smaller than the
+	 integer ones.  */
+      if (file_mips_gp32 == 0)
+	/* 64-bit integer registers implies 64-bit float registers.  */
+	file_mips_fp32 = 0;
+      else if ((mips_opts.ase_mips3d > 0 || mips_opts.ase_mdmx > 0)
+	       && ISA_HAS_64BIT_FPRS (mips_opts.isa))
+	/* -mips3d and -mdmx imply 64-bit float registers, if possible.  */
+	file_mips_fp32 = 0;
+      else
+	/* 32-bit float registers.  */
+	file_mips_fp32 = 1;
+      break;
+
+    /* The user specified the size of the float registers.  Check if it
+       agrees with the ABI and ISA.  */
+    case 0:
+      if (!ISA_HAS_64BIT_FPRS (mips_opts.isa))
+	as_bad (_("-mfp64 used with a 32-bit fpu"));
+      else if (ABI_NEEDS_32BIT_REGS (mips_abi)
+	       && !ISA_HAS_MXHC1 (mips_opts.isa))
+	as_warn (_("-mfp64 used with a 32-bit ABI"));
+      break;
+    case 1:
+      if (ABI_NEEDS_64BIT_REGS (mips_abi))
+	as_warn (_("-mfp32 used with a 64-bit ABI"));
+      break;
+    }
 
   /* End of GCC-shared inference code.  */
 
@@ -11406,13 +11463,36 @@ mips_after_parse_args (void)
   if (mips_opts.mips16 == -1)
     mips_opts.mips16 = (CPU_HAS_MIPS16 (file_mips_arch)) ? 1 : 0;
   if (mips_opts.ase_mips3d == -1)
-    mips_opts.ase_mips3d = (CPU_HAS_MIPS3D (file_mips_arch)) ? 1 : 0;
+    mips_opts.ase_mips3d = ((CPU_HAS_MIPS3D (file_mips_arch)
+			     || (arch_info->flags & MIPS_CPU_ASE_MIPS3D))
+			    && file_mips_fp32 == 0) ? 1 : 0;
+  if (mips_opts.ase_mips3d && file_mips_fp32 == 1)
+    as_bad (_("-mfp32 used with -mips3d"));
+
   if (mips_opts.ase_mdmx == -1)
-    mips_opts.ase_mdmx = (CPU_HAS_MDMX (file_mips_arch)) ? 1 : 0;
+    mips_opts.ase_mdmx = ((CPU_HAS_MDMX (file_mips_arch)
+			   || (arch_info->flags & MIPS_CPU_ASE_MDMX))
+			  && file_mips_fp32 == 0) ? 1 : 0;
+  if (mips_opts.ase_mdmx && file_mips_fp32 == 1)
+    as_bad (_("-mfp32 used with -mdmx"));
+
+  if (mips_opts.ase_smartmips == -1)
+    mips_opts.ase_smartmips = (arch_info->flags & MIPS_CPU_ASE_SMARTMIPS) ? 1 : 0;
+  if (mips_opts.ase_smartmips && !ISA_SUPPORTS_SMARTMIPS)
+      as_warn ("%s ISA does not support SmartMIPS", 
+	       mips_cpu_info_from_isa (mips_opts.isa)->name);
+
   if (mips_opts.ase_dsp == -1)
-    mips_opts.ase_dsp = (CPU_HAS_DSP (file_mips_arch)) ? 1 : 0;
+    mips_opts.ase_dsp = (arch_info->flags & MIPS_CPU_ASE_DSP) ? 1 : 0;
+  if (mips_opts.ase_dsp && !ISA_SUPPORTS_DSP_ASE)
+      as_warn ("%s ISA does not support DSP ASE", 
+	       mips_cpu_info_from_isa (mips_opts.isa)->name);
+
   if (mips_opts.ase_mt == -1)
-    mips_opts.ase_mt = (CPU_HAS_MT (file_mips_arch)) ? 1 : 0;
+    mips_opts.ase_mt = (arch_info->flags & MIPS_CPU_ASE_MT) ? 1 : 0;
+  if (mips_opts.ase_mt && !ISA_SUPPORTS_MT_ASE)
+      as_warn ("%s ISA does not support MT ASE", 
+	       mips_cpu_info_from_isa (mips_opts.isa)->name);
 
   file_mips_isa = mips_opts.isa;
   file_ase_mips16 = mips_opts.mips16;
@@ -12266,6 +12346,28 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
     {
       mips_opts.nobopt = 1;
     }
+  else if (strcmp (name, "gp=default") == 0)
+    mips_opts.gp32 = file_mips_gp32;
+  else if (strcmp (name, "gp=32") == 0)
+    mips_opts.gp32 = 1;
+  else if (strcmp (name, "gp=64") == 0)
+    {
+      if (!ISA_HAS_64BIT_REGS (mips_opts.isa))
+	as_warn ("%s isa does not support 64-bit registers",
+		 mips_cpu_info_from_isa (mips_opts.isa)->name);
+      mips_opts.gp32 = 0;
+    }
+  else if (strcmp (name, "fp=default") == 0)
+    mips_opts.fp32 = file_mips_fp32;
+  else if (strcmp (name, "fp=32") == 0)
+    mips_opts.fp32 = 1;
+  else if (strcmp (name, "fp=64") == 0)
+    {
+      if (!ISA_HAS_64BIT_FPRS (mips_opts.isa))
+	as_warn ("%s isa does not support 64-bit floating point registers",
+		 mips_cpu_info_from_isa (mips_opts.isa)->name);
+      mips_opts.fp32 = 0;
+    }
   else if (strcmp (name, "mips16") == 0
 	   || strcmp (name, "MIPS-16") == 0)
     mips_opts.mips16 = 1;
@@ -12274,7 +12376,7 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
     mips_opts.mips16 = 0;
   else if (strcmp (name, "smartmips") == 0)
     {
-      if (!ISA_SUPPORT_SMARTMIPS)
+      if (!ISA_SUPPORTS_SMARTMIPS)
 	as_warn ("%s ISA does not support SmartMIPS ASE", 
 		 mips_cpu_info_from_isa (mips_opts.isa)->name);
       mips_opts.ase_smartmips = 1;
@@ -12290,11 +12392,21 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
   else if (strcmp (name, "nomdmx") == 0)
     mips_opts.ase_mdmx = 0;
   else if (strcmp (name, "dsp") == 0)
-    mips_opts.ase_dsp = 1;
+    {
+      if (!ISA_SUPPORTS_DSP_ASE)
+	as_warn ("%s ISA does not support DSP ASE", 
+		 mips_cpu_info_from_isa (mips_opts.isa)->name);
+      mips_opts.ase_dsp = 1;
+    }
   else if (strcmp (name, "nodsp") == 0)
     mips_opts.ase_dsp = 0;
   else if (strcmp (name, "mt") == 0)
-    mips_opts.ase_mt = 1;
+    {
+      if (!ISA_SUPPORTS_MT_ASE)
+	as_warn ("%s ISA does not support MT ASE", 
+		 mips_cpu_info_from_isa (mips_opts.isa)->name);
+      mips_opts.ase_mt = 1;
+    }
   else if (strcmp (name, "nomt") == 0)
     mips_opts.ase_mt = 0;
   else if (strncmp (name, "mips", 4) == 0 || strncmp (name, "arch=", 5) == 0)
@@ -14012,6 +14124,12 @@ mips_elf_final_processing (void)
 
   if (mips_32bitmode)
     elf_elfheader (stdoutput)->e_flags |= EF_MIPS_32BITMODE;
+
+#if 0 /* XXX FIXME */
+  /* 32 bit code with 64 bit FP registers.  */
+  if (!file_mips_fp32 && ABI_NEEDS_32BIT_REGS (mips_abi))
+    elf_elfheader (stdoutput)->e_flags |= ???;
+#endif
 }
 
 #endif /* OBJ_ELF || OBJ_MAYBE_ELF */
@@ -14414,72 +14532,90 @@ s_mips_mask (int reg_type)
 static const struct mips_cpu_info mips_cpu_info_table[] =
 {
   /* Entries for generic ISAs */
-  { "mips1",          1,      ISA_MIPS1,      CPU_R3000 },
-  { "mips2",          1,      ISA_MIPS2,      CPU_R6000 },
-  { "mips3",          1,      ISA_MIPS3,      CPU_R4000 },
-  { "mips4",          1,      ISA_MIPS4,      CPU_R8000 },
-  { "mips5",          1,      ISA_MIPS5,      CPU_MIPS5 },
-  { "mips32",         1,      ISA_MIPS32,     CPU_MIPS32 },
-  { "mips32r2",       1,      ISA_MIPS32R2,   CPU_MIPS32R2 },
-  { "mips64",         1,      ISA_MIPS64,     CPU_MIPS64 },
-  { "mips64r2",       1,      ISA_MIPS64R2,   CPU_MIPS64R2 },
+  { "mips1",          MIPS_CPU_IS_ISA,		ISA_MIPS1,      CPU_R3000 },
+  { "mips2",          MIPS_CPU_IS_ISA,		ISA_MIPS2,      CPU_R6000 },
+  { "mips3",          MIPS_CPU_IS_ISA,		ISA_MIPS3,      CPU_R4000 },
+  { "mips4",          MIPS_CPU_IS_ISA,		ISA_MIPS4,      CPU_R8000 },
+  { "mips5",          MIPS_CPU_IS_ISA,		ISA_MIPS5,      CPU_MIPS5 },
+  { "mips32",         MIPS_CPU_IS_ISA,		ISA_MIPS32,     CPU_MIPS32 },
+  { "mips32r2",       MIPS_CPU_IS_ISA,		ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "mips64",         MIPS_CPU_IS_ISA,		ISA_MIPS64,     CPU_MIPS64 },
+  { "mips64r2",       MIPS_CPU_IS_ISA,		ISA_MIPS64R2,   CPU_MIPS64R2 },
 
   /* MIPS I */
-  { "r3000",          0,      ISA_MIPS1,      CPU_R3000 },
-  { "r2000",          0,      ISA_MIPS1,      CPU_R3000 },
-  { "r3900",          0,      ISA_MIPS1,      CPU_R3900 },
+  { "r3000",          0,			ISA_MIPS1,      CPU_R3000 },
+  { "r2000",          0,			ISA_MIPS1,      CPU_R3000 },
+  { "r3900",          0,			ISA_MIPS1,      CPU_R3900 },
 
   /* MIPS II */
-  { "r6000",          0,      ISA_MIPS2,      CPU_R6000 },
+  { "r6000",          0,			ISA_MIPS2,      CPU_R6000 },
 
   /* MIPS III */
-  { "r4000",          0,      ISA_MIPS3,      CPU_R4000 },
-  { "r4010",          0,      ISA_MIPS2,      CPU_R4010 },
-  { "vr4100",         0,      ISA_MIPS3,      CPU_VR4100 },
-  { "vr4111",         0,      ISA_MIPS3,      CPU_R4111 },
-  { "vr4120",         0,      ISA_MIPS3,      CPU_VR4120 },
-  { "vr4130",         0,      ISA_MIPS3,      CPU_VR4120 },
-  { "vr4181",         0,      ISA_MIPS3,      CPU_R4111 },
-  { "vr4300",         0,      ISA_MIPS3,      CPU_R4300 },
-  { "r4400",          0,      ISA_MIPS3,      CPU_R4400 },
-  { "r4600",          0,      ISA_MIPS3,      CPU_R4600 },
-  { "orion",          0,      ISA_MIPS3,      CPU_R4600 },
-  { "r4650",          0,      ISA_MIPS3,      CPU_R4650 },
+  { "r4000",          0,			ISA_MIPS3,      CPU_R4000 },
+  { "r4010",          0,			ISA_MIPS2,      CPU_R4010 },
+  { "vr4100",         0,			ISA_MIPS3,      CPU_VR4100 },
+  { "vr4111",         0,			ISA_MIPS3,      CPU_R4111 },
+  { "vr4120",         0,			ISA_MIPS3,      CPU_VR4120 },
+  { "vr4130",         0,			ISA_MIPS3,      CPU_VR4120 },
+  { "vr4181",         0,			ISA_MIPS3,      CPU_R4111 },
+  { "vr4300",         0,			ISA_MIPS3,      CPU_R4300 },
+  { "r4400",          0,			ISA_MIPS3,      CPU_R4400 },
+  { "r4600",          0,			ISA_MIPS3,      CPU_R4600 },
+  { "orion",          0,			ISA_MIPS3,      CPU_R4600 },
+  { "r4650",          0,			ISA_MIPS3,      CPU_R4650 },
 
   /* MIPS IV */
-  { "r8000",          0,      ISA_MIPS4,      CPU_R8000 },
-  { "r10000",         0,      ISA_MIPS4,      CPU_R10000 },
-  { "r12000",         0,      ISA_MIPS4,      CPU_R12000 },
-  { "vr5000",         0,      ISA_MIPS4,      CPU_R5000 },
-  { "vr5400",         0,      ISA_MIPS4,      CPU_VR5400 },
-  { "vr5500",         0,      ISA_MIPS4,      CPU_VR5500 },
-  { "rm5200",         0,      ISA_MIPS4,      CPU_R5000 },
-  { "rm5230",         0,      ISA_MIPS4,      CPU_R5000 },
-  { "rm5231",         0,      ISA_MIPS4,      CPU_R5000 },
-  { "rm5261",         0,      ISA_MIPS4,      CPU_R5000 },
-  { "rm5721",         0,      ISA_MIPS4,      CPU_R5000 },
-  { "rm7000",         0,      ISA_MIPS4,      CPU_RM7000 },
-  { "rm9000",         0,      ISA_MIPS4,      CPU_RM9000 },
+  { "r8000",          0,			ISA_MIPS4,      CPU_R8000 },
+  { "r10000",         0,			ISA_MIPS4,      CPU_R10000 },
+  { "r12000",         0,			ISA_MIPS4,      CPU_R12000 },
+  { "vr5000",         0,			ISA_MIPS4,      CPU_R5000 },
+  { "vr5400",         0,			ISA_MIPS4,      CPU_VR5400 },
+  { "vr5500",         0,			ISA_MIPS4,      CPU_VR5500 },
+  { "rm5200",         0,			ISA_MIPS4,      CPU_R5000 },
+  { "rm5230",         0,			ISA_MIPS4,      CPU_R5000 },
+  { "rm5231",         0,			ISA_MIPS4,      CPU_R5000 },
+  { "rm5261",         0,			ISA_MIPS4,      CPU_R5000 },
+  { "rm5721",         0,			ISA_MIPS4,      CPU_R5000 },
+  { "rm7000",         0,			ISA_MIPS4,      CPU_RM7000 },
+  { "rm9000",         0,			ISA_MIPS4,      CPU_RM9000 },
 
   /* MIPS 32 */
-  { "4kc",            0,      ISA_MIPS32,     CPU_MIPS32 },
-  { "4km",            0,      ISA_MIPS32,     CPU_MIPS32 },
-  { "4kp",            0,      ISA_MIPS32,     CPU_MIPS32 },
-
-  /* MIPS32 Release 2 */
-  { "m4k",            0,      ISA_MIPS32R2,   CPU_MIPS32R2 },
-  { "24k",            0,      ISA_MIPS32R2,   CPU_MIPS32R2 },
-  { "24kc",           0,      ISA_MIPS32R2,   CPU_MIPS32R2 },
-  { "24kf",           0,      ISA_MIPS32R2,   CPU_MIPS32R2 },
-  { "24kx",           0,      ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "4kc",            0,			ISA_MIPS32,	CPU_MIPS32 },
+  { "4km",            0,			ISA_MIPS32,	CPU_MIPS32 },
+  { "4kp",            0,			ISA_MIPS32,	CPU_MIPS32 },
+  { "4ksc",           MIPS_CPU_ASE_SMARTMIPS,	ISA_MIPS32,	CPU_MIPS32 },
+
+  /* MIPS 32 Release 2 */
+  { "4kec",           0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "4kem",           0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "4kep",           0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "4ksd",           MIPS_CPU_ASE_SMARTMIPS,	ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "m4k",            0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "m4kp",           0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "24k",            0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "24kc",           0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "24kf",           0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "24kx",           0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  /* 24ke is a 24k with DSP ASE, other ASEs are optional.  */
+  { "24ke",           MIPS_CPU_ASE_DSP,		ISA_MIPS32R2,	CPU_MIPS32R2 },
+  { "24kec",          MIPS_CPU_ASE_DSP,		ISA_MIPS32R2,	CPU_MIPS32R2 },
+  { "24kef",          MIPS_CPU_ASE_DSP,		ISA_MIPS32R2,	CPU_MIPS32R2 },
+  { "24kex",         MIPS_CPU_ASE_DSP,		ISA_MIPS32R2,	CPU_MIPS32R2 },
+  /* 34k is a 24k with MT ASE, other ASEs are optional.  */
+  { "34kc",           MIPS_CPU_ASE_MT,		ISA_MIPS32R2,	CPU_MIPS32R2 },
+  { "34kf",           MIPS_CPU_ASE_MT,		ISA_MIPS32R2,	CPU_MIPS32R2 },
+  { "34kx",          MIPS_CPU_ASE_MT,		ISA_MIPS32R2,	CPU_MIPS32R2 },
 
   /* MIPS 64 */
-  { "5kc",            0,      ISA_MIPS64,     CPU_MIPS64 },
-  { "5kf",            0,      ISA_MIPS64,     CPU_MIPS64 },
-  { "20kc",           0,      ISA_MIPS64,     CPU_MIPS64 },
+  { "5kc",            0,			ISA_MIPS64,	CPU_MIPS64 },
+  { "5kf",            0,			ISA_MIPS64,	CPU_MIPS64 },
+  { "20kc",           MIPS_CPU_ASE_MIPS3D,	ISA_MIPS64,	CPU_MIPS64 },
+
+  /* MIPS 64 Release 2 */
+  { "25kf",           MIPS_CPU_ASE_MIPS3D,	ISA_MIPS64R2,   CPU_MIPS64R2 },
 
   /* Broadcom SB-1 CPU core */
-  { "sb1",            0,      ISA_MIPS64,     CPU_SB1 },
+  { "sb1",            0,			ISA_MIPS64,	CPU_SB1 },
 
   /* End marker */
   { NULL, 0, 0, 0 }
@@ -14594,7 +14730,7 @@ mips_cpu_info_from_isa (int isa)
   int i;
 
   for (i = 0; mips_cpu_info_table[i].name != NULL; i++)
-    if (mips_cpu_info_table[i].is_isa
+    if ((mips_cpu_info_table[i].flags & MIPS_CPU_IS_ISA)
 	&& isa == mips_cpu_info_table[i].isa)
       return (&mips_cpu_info_table[i]);
 
Index: gas/testsuite/gas/mips/mips-gp32-fp64-pic.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips-gp32-fp64-pic.d,v
retrieving revision 1.6
diff -u -p -r1.6 mips-gp32-fp64-pic.d
--- gas/testsuite/gas/mips/mips-gp32-fp64-pic.d	22 Apr 2004 18:13:56 -0000	1.6
+++ gas/testsuite/gas/mips/mips-gp32-fp64-pic.d	22 May 2006 15:23:40 -0000
@@ -1,6 +1,7 @@
 #objdump: -d -mmips:8000
 #as: -32 -march=8000 -EB -mgp32 -mfp64 -KPIC
 #name: MIPS -mgp32 -mfp64 (SVR4 PIC)
+#stderr: mips-gp32-fp64.l
 
 .*: +file format.*
 
Index: gas/testsuite/gas/mips/mips-gp32-fp64.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips-gp32-fp64.d,v
retrieving revision 1.5
diff -u -p -r1.5 mips-gp32-fp64.d
--- gas/testsuite/gas/mips/mips-gp32-fp64.d	7 May 2003 05:08:20 -0000	1.5
+++ gas/testsuite/gas/mips/mips-gp32-fp64.d	22 May 2006 15:23:40 -0000
@@ -1,6 +1,7 @@
 #objdump: -d -mmips:8000
 #as: -32 -march=8000 -EB -mgp32 -mfp64
 #name: MIPS -mgp32 -mfp64
+#stderr: mips-gp32-fp64.l
 
 .*: +file format.*
 
Index: gas/testsuite/gas/mips/mips-gp64-fp32-pic.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips-gp64-fp32-pic.d,v
retrieving revision 1.6
diff -u -p -r1.6 mips-gp64-fp32-pic.d
--- gas/testsuite/gas/mips/mips-gp64-fp32-pic.d	22 Apr 2004 18:13:56 -0000	1.6
+++ gas/testsuite/gas/mips/mips-gp64-fp32-pic.d	22 May 2006 15:23:40 -0000
@@ -1,6 +1,7 @@
 #objdump: -d -mmips:8000
 #as: -mabi=o64 -march=8000 -EB -mfp32 -KPIC
 #name: MIPS -mgp64 -mfp32 (SVR4 PIC)
+#stderr: mips-gp64-fp32-pic.l
 
 .*: +file format.*
 
Index: gas/testsuite/gas/mips/mips-gp64-fp32.l
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips-gp64-fp32.l,v
retrieving revision 1.1
diff -u -p -r1.1 mips-gp64-fp32.l
--- gas/testsuite/gas/mips/mips-gp64-fp32.l	22 Apr 2002 22:29:47 -0000	1.1
+++ gas/testsuite/gas/mips/mips-gp64-fp32.l	22 May 2006 15:23:40 -0000
@@ -1,4 +1,5 @@
-.*: Assembler messages:
+Assembler messages:
+Warning: -mfp32 used with a 64-bit ABI
 .*:92: Warning: Macro instruction expanded into multiple instructions in a branch delay slot
 .*:96: Warning: Macro instruction expanded into multiple instructions in a branch delay slot
 .*:100: Warning: Macro instruction expanded into multiple instructions in a branch delay slot
Index: gas/testsuite/gas/mips/mips-gp64-fp64.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips-gp64-fp64.d,v
retrieving revision 1.6
diff -u -p -r1.6 mips-gp64-fp64.d
--- gas/testsuite/gas/mips/mips-gp64-fp64.d	7 May 2003 05:08:20 -0000	1.6
+++ gas/testsuite/gas/mips/mips-gp64-fp64.d	22 May 2006 15:23:40 -0000
@@ -1,7 +1,7 @@
 #objdump: -d -mmips:8000
 #as: -mabi=o64 -march=8000 -EB
 #name: MIPS -mgp64 -mfp64
-#stderr: mips-gp64-fp32.l
+#stderr: mips-gp64-fp64.l
 
 .*: +file format.*
 
--- /dev/null	2006-05-17 20:07:57.714000000 +0100
+++ gas/testsuite/gas/mips/mips-gp32-fp64.l	2006-05-22 15:40:46.000000000 +0100
@@ -0,0 +1,2 @@
+Assembler messages:
+Warning: -mfp64 used with a 32-bit ABI
--- /dev/null	2006-05-17 20:07:57.714000000 +0100
+++ gas/testsuite/gas/mips/mips-gp64-fp32-pic.l	2006-05-22 16:06:58.000000000 +0100
@@ -0,0 +1,2 @@
+Assembler messages:
+Warning: -mfp32 used with a 64-bit ABI
Index: gas/doc/c-mips.texi
===================================================================
RCS file: /cvs/src/src/gas/doc/c-mips.texi,v
retrieving revision 1.37
diff -u -p -r1.37 c-mips.texi
--- gas/doc/c-mips.texi	8 May 2006 15:57:05 -0000	1.37
+++ gas/doc/c-mips.texi	23 May 2006 12:46:04 -0000
@@ -91,19 +91,28 @@ flags force a certain group of registers
 all times.  @samp{-mgp32} controls the size of general-purpose registers
 and @samp{-mfp32} controls the size of floating-point registers.
 
+The @code{.set gp=32} and @code{.set fp=32} directives allow to change
+the size of registers for parts of an object. The default value is
+restored by @code{.set gp=default} and @code{.set fp=default}.
+
 On some MIPS variants there is a 32-bit mode flag; when this flag is
 set, 64-bit instructions generate a trap.  Also, some 32-bit OSes only
 save the 32-bit registers on a context switch, so it is essential never
 to use the 64-bit registers.
 
 @item -mgp64
-Assume that 64-bit general purpose registers are available.  This is
-provided in the interests of symmetry with -gp32.
+@itemx -mfp64
+Assume that 64-bit registers are available.  This is provided in the
+interests of symmetry with @samp{-mgp32} and @samp{-mfp32}.
+
+The @code{.set gp=64} and @code{.set fp=64} directives allow to change
+the size of registers for parts of an object. The default value is
+restored by @code{.set gp=default} and @code{.set fp=default}.
 
 @item -mips16
 @itemx -no-mips16
 Generate code for the MIPS 16 processor.  This is equivalent to putting
-@samp{.set mips16} at the start of the assembly file.  @samp{-no-mips16}
+@code{.set mips16} at the start of the assembly file.  @samp{-no-mips16}
 turns off this option.
 
 @item -msmartmips
@@ -111,7 +120,7 @@ turns off this option.
 Enables the SmartMIPS extensions to the MIPS32 instruction set, which
 provides a number of new instructions which target smartcard and
 cryptographic applications.  This is equivalent to putting
-@samp{.set smartmips} at the start of the assembly file.
+@code{.set smartmips} at the start of the assembly file.
 @samp{-mno-smartmips} turns off this option.
 
 @item -mips3d
@@ -210,7 +219,29 @@ rm7000,
 rm9000,
 10000,
 12000,
-mips32-4k,
+4kc,
+4km,
+4kp,
+4ksc,
+4kec,
+4kem,
+4kep,
+4ksd,
+m4k,
+m4kp,
+24kc,
+24kf,
+24kx,
+24kec,
+24kef,
+24kex,
+34kc,
+34kf,
+34kx,
+5kc,
+5kf,
+20kc,
+25kf,
 sb1
 @end quotation
 
@@ -399,17 +430,21 @@ assembly.  @code{.set mips@var{n}} affec
 are permitted, but also how certain macros are expanded.  @code{.set
 mips0} restores the @sc{isa} level to its original level: either the
 level you selected with command line options, or the default for your
-configuration.  You can use this feature to permit specific @sc{r4000}
+configuration.  You can use this feature to permit specific @sc{mips3}
 instructions while assembling in 32 bit mode.  Use this directive with
 care!
 
-The directive @samp{.set mips16} puts the assembler into MIPS 16 mode,
-in which it will assemble instructions for the MIPS 16 processor.  Use
-@samp{.set nomips16} to return to normal 32 bit mode.
+@cindex MIPS CPU override
+@kindex @code{.set arch=@var{cpu}}
+Even finer control provides the @code{.set arch=@var{cpu}} directive.
+It changes the effective CPU target and allows to assemble instructions
+specific to a particular CPU.  All CPUs supported by the @samp{-march}
+command line option are also selectable by this directive.  The original
+value is restored by @code{.set arch=default}.
 
-The @samp{.set smartmips} directive enables use of the SmartMIPS
-extensions to the MIPS32 @sc{isa}; the @samp{.set nosmartmips} directive
-reverses that.
+The directive @code{.set mips16} puts the assembler into MIPS 16 mode,
+in which it will assemble instructions for the MIPS 16 processor.  Use
+@code{.set nomips16} to return to normal 32 bit mode.
 
 Traditional @sc{mips} assemblers do not support this directive.
 
@@ -419,10 +454,10 @@ Traditional @sc{mips} assemblers do not 
 @kindex @code{.set autoextend}
 @kindex @code{.set noautoextend}
 By default, MIPS 16 instructions are automatically extended to 32 bits
-when necessary.  The directive @samp{.set noautoextend} will turn this
-off.  When @samp{.set noautoextend} is in effect, any 32 bit instruction
-must be explicitly extended with the @samp{.e} modifier (e.g.,
-@samp{li.e $4,1000}).  The directive @samp{.set autoextend} may be used
+when necessary.  The directive @code{.set noautoextend} will turn this
+off.  When @code{.set noautoextend} is in effect, any 32 bit instruction
+must be explicitly extended with the @code{.e} modifier (e.g.,
+@code{li.e $4,1000}).  The directive @code{.set autoextend} may be used
 to once again automatically extend instructions when necessary.
 
 This directive is only meaningful when in MIPS 16 mode.  Traditional
@@ -467,6 +502,15 @@ from the MIPS-3D Application Specific Ex
 in the assembly.  The @code{.set nomips3d} directive prevents MIPS-3D
 instructions from being accepted.
 
+@cindex SmartMIPS instruction generation override
+@kindex @code{.set smartmips}
+@kindex @code{.set nosmartmips}
+The directive @code{.set smartmips} makes the assembler accept
+instructions from the SmartMIPS Application Specific Extension to the
+MIPS32 @sc{isa} from that point on in the assembly.  The
+@code{.set nosmartmips} directive prevents SmartMIPS instructions from
+being accepted.
+
 @cindex MIPS MDMX instruction generation override
 @kindex @code{.set mdmx}
 @kindex @code{.set nomdmx}

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Better checking of ISA/ASE/ABI options for MIPS gas
  2006-05-23 17:47 ` Thiemo Seufer
@ 2006-05-23 21:01   ` Richard Sandiford
  2006-05-23 23:37     ` Thiemo Seufer
  0 siblings, 1 reply; 14+ messages in thread
From: Richard Sandiford @ 2006-05-23 21:01 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils

Thiemo Seufer <ths@networkno.de> writes:
> Updated to take all comments into account, and expanded to allow also
> for .set fp={23,64,default}.

Thanks for agreeing to do this.  The new patch looks really good to
me FWIW.  (There are a couple of minor documentation niggles below.)

> Richard, do you care about the gcc update (if/when the release cycle
> permits it)?

I'm not sure what you mean here, but I'd certainly like to see gcc's &
gas's option handling kept in sync, so the gcc equivalent of this patch
is certainly welcome from my POV.  And I'd see a long-lasting divergence
between gas and gcc as a bug, so I'd be happy to use the discretion
given to target maintainers and have the patch go in during stage 3.

> +The @code{.set gp=32} and @code{.set fp=32} directives allow to change
> +the size of registers for parts of an object. The default value is
> +restored by @code{.set gp=default} and @code{.set fp=default}.
> +

"allow to" seems to be missing an object.  "allow <something> to"
or "tell the assembler to" (as you used in later hunks).  Or maybe:

  The @code{.set gp=32} and @code{.set fp=32} directives allow the size
  of registers to be changed for parts of an object. The default value is
  restored by @code{.set gp=default} and @code{.set fp=default}.

>  @item -mgp64
> -Assume that 64-bit general purpose registers are available.  This is
> -provided in the interests of symmetry with -gp32.
> +@itemx -mfp64
> +Assume that 64-bit registers are available.  This is provided in the
> +interests of symmetry with @samp{-mgp32} and @samp{-mfp32}.
> +
> +The @code{.set gp=64} and @code{.set fp=64} directives allow to change
> +the size of registers for parts of an object. The default value is
> +restored by @code{.set gp=default} and @code{.set fp=default}.

Same here.

> -The directive @samp{.set mips16} puts the assembler into MIPS 16 mode,
> -in which it will assemble instructions for the MIPS 16 processor.  Use
> -@samp{.set nomips16} to return to normal 32 bit mode.
> +@cindex MIPS CPU override
> +@kindex @code{.set arch=@var{cpu}}
> +Even finer control provides the @code{.set arch=@var{cpu}} directive.

"provides" -> "is provided by".  Or:

  The @code{.set arch=@var{cpu}} directive provides even finer control.

which flows better into:

> +It changes the effective CPU target and allows to assemble instructions
> +specific to a particular CPU.  All CPUs supported by the @samp{-march}
> +command line option are also selectable by this directive.  The original
> +value is restored by @code{.set arch=default}.

Same "allows to" problem as above.

The other doc bits looked fine to me.

Richard

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Better checking of ISA/ASE/ABI options for MIPS gas
  2006-05-23 21:01   ` Richard Sandiford
@ 2006-05-23 23:37     ` Thiemo Seufer
  2006-05-24  1:46       ` Richard Sandiford
  0 siblings, 1 reply; 14+ messages in thread
From: Thiemo Seufer @ 2006-05-23 23:37 UTC (permalink / raw)
  To: binutils, richard

Richard Sandiford wrote:
[snip]
> > Richard, do you care about the gcc update (if/when the release cycle
> > permits it)?
> 
> I'm not sure what you mean here, but I'd certainly like to see gcc's &
> gas's option handling kept in sync, so the gcc equivalent of this patch
> is certainly welcome from my POV.  And I'd see a long-lasting divergence
> between gas and gcc as a bug, so I'd be happy to use the discretion
> given to target maintainers and have the patch go in during stage 3.

Well, the divergence is caused by missing MIPS32R2 with 64bit FP support
on the gcc side, which is a too invasive change for stage 3. IOW, the
re-sync of the option handling will be included in that patch, hopefully
in time for next stage 1.

I committed the appended patch, which includes the documentation
improvements you suggested.


Thiemo


2006-05-23  Thiemo Seufer  <ths@mips.com>
            David Ung  <davidu@mips.com>
            Nigel Stephens  <nigel@mips.com>

	[ gas/ChangeLog ]
	* config/tc-mips.c (ISA_SUPPORTS_SMARTMIPS): Rename.
	(ISA_SUPPORTS_DSP_ASE, ISA_SUPPORTS_MT_ASE, ISA_HAS_64BIT_FPRS,
	ISA_HAS_MXHC1): New macros.
	(HAVE_32BIT_FPRS): Use ISA_HAS_64BIT_FPRS instead of
	ISA_HAS_64BIT_REGS.  Formatting fixes.  Improved comments.
	(mips_cpu_info): Change to use combined ASE/IS_ISA flag.
	(MIPS_CPU_IS_ISA, MIPS_CPU_ASE_SMARTMIPS, MIPS_CPU_ASE_DSP,
	MIPS_CPU_ASE_MT, MIPS_CPU_ASE_MIPS3D, MIPS_CPU_ASE_MDMX): New defines.
	(mips_after_parse_args): Change default handling of float register
	size to account for 32bit code with 64bit FP. Better sanity checking
	of ISA/ASE/ABI option combinations.
	(s_mipsset): Support switching of GPR and FPR sizes via
	.set {g,f}p={32,64,default}. Better sanity checking for .set ASE
	options.
	(mips_elf_final_processing): We should record the use of 64bit FP
	registers in 32bit code but we don't, because ELF header flags are
	a scarce ressource.
	(mips_cpu_info_table): Add ASE flags for CPUs with mandatory ASE
	extensions. Add 4ksc, 4kec, 4kem, 4kep, 4ksd, m4kp, 24kec, 24kef,
	24kex, 34kc, 34kf, 34kx, 25kf CPU definitions.
	(mips_cpu_info_from_isa): Use MIPS_CPU_IS_ISA.
	* doc/c-mips.texi: Document .set {g,f}p={32,64,default}. Document
	missing -march options. Document .set arch=CPU. Move .set smartmips
	to ASE page. Use @code for .set FOO examples.

	[ gas/testsuite/Changelog ]
	* gas/mips/mips-gp32-fp64-pic.d, mips/mips-gp32-fp64.d,
	gas/mips/mips-gp64-fp32-pic.d, gas/mips/mips-gp64-fp32.l,
	gas/mips/mips-gp64-fp64.d: Adjust test cases to the changes assembler
	output.
	* gas/mips/mips-gp32-fp64.l, gas/mips/mips-gp64-fp32-pic.l: New files,
	catch assembler warnings.


Index: gas/config/tc-mips.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mips.c,v
retrieving revision 1.337
diff -u -p -r1.337 tc-mips.c
--- gas/config/tc-mips.c	19 May 2006 13:03:05 -0000	1.337
+++ gas/config/tc-mips.c	23 May 2006 12:46:04 -0000
@@ -274,17 +274,23 @@ static int file_ase_mdmx;
    command line (e.g., by -march).  */
 static int file_ase_smartmips;
 
-#define ISA_SUPPORT_SMARTMIPS (mips_opts.isa == ISA_MIPS32       \
-			       || mips_opts.isa == ISA_MIPS32R2)
+#define ISA_SUPPORTS_SMARTMIPS (mips_opts.isa == ISA_MIPS32		\
+				|| mips_opts.isa == ISA_MIPS32R2)
 
 /* True if -mdsp was passed or implied by arguments passed on the
    command line (e.g., by -march).  */
 static int file_ase_dsp;
 
+#define ISA_SUPPORTS_DSP_ASE (mips_opts.isa == ISA_MIPS32R2		\
+			      || mips_opts.isa == ISA_MIPS64R2)
+
 /* True if -mmt was passed or implied by arguments passed on the
    command line (e.g., by -march).  */
 static int file_ase_mt;
 
+#define ISA_SUPPORTS_MT_ASE (mips_opts.isa == ISA_MIPS32R2		\
+			     || mips_opts.isa == ISA_MIPS64R2)
+
 /* The argument of the -march= flag.  The architecture we are assembling.  */
 static int file_mips_arch = CPU_UNKNOWN;
 static const char *mips_arch_string;
@@ -306,7 +312,7 @@ static int mips_32bitmode = 0;
    || (ABI) == N64_ABI			\
    || (ABI) == O64_ABI)
 
-/*  Return true if ISA supports 64 bit gp register instructions.  */
+/*  Return true if ISA supports 64 bit wide gp registers.  */
 #define ISA_HAS_64BIT_REGS(ISA)		\
   ((ISA) == ISA_MIPS3			\
    || (ISA) == ISA_MIPS4		\
@@ -314,6 +320,15 @@ static int mips_32bitmode = 0;
    || (ISA) == ISA_MIPS64		\
    || (ISA) == ISA_MIPS64R2)
 
+/*  Return true if ISA supports 64 bit wide float registers.  */
+#define ISA_HAS_64BIT_FPRS(ISA)		\
+  ((ISA) == ISA_MIPS3			\
+   || (ISA) == ISA_MIPS4		\
+   || (ISA) == ISA_MIPS5		\
+   || (ISA) == ISA_MIPS32R2		\
+   || (ISA) == ISA_MIPS64		\
+   || (ISA) == ISA_MIPS64R2)
+
 /* Return true if ISA supports 64-bit right rotate (dror et al.)
    instructions.  */
 #define ISA_HAS_DROR(ISA)		\
@@ -333,14 +348,20 @@ static int mips_32bitmode = 0;
    || (ISA) == ISA_MIPS64		\
    || (ISA) == ISA_MIPS64R2)
 
+/* Return true if ISA supports move to/from high part of a 64-bit
+   floating-point register. */
+#define ISA_HAS_MXHC1(ISA)		\
+  ((ISA) == ISA_MIPS32R2		\
+   || (ISA) == ISA_MIPS64R2)
+
 #define HAVE_32BIT_GPRS		                   \
-    (mips_opts.gp32 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
+    (mips_opts.gp32 || !ISA_HAS_64BIT_REGS (mips_opts.isa))
 
 #define HAVE_32BIT_FPRS                            \
-    (mips_opts.fp32 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
+    (mips_opts.fp32 || !ISA_HAS_64BIT_FPRS (mips_opts.isa))
 
-#define HAVE_64BIT_GPRS (! HAVE_32BIT_GPRS)
-#define HAVE_64BIT_FPRS (! HAVE_32BIT_FPRS)
+#define HAVE_64BIT_GPRS (!HAVE_32BIT_GPRS)
+#define HAVE_64BIT_FPRS (!HAVE_32BIT_FPRS)
 
 #define HAVE_NEWABI (mips_abi == N32_ABI || mips_abi == N64_ABI)
 
@@ -1031,11 +1052,18 @@ static int validate_mips_insn (const str
 struct mips_cpu_info
 {
   const char *name;           /* CPU or ISA name.  */
-  int is_isa;                 /* Is this an ISA?  (If 0, a CPU.) */
+  int flags;                  /* ASEs available, or ISA flag.  */
   int isa;                    /* ISA level.  */
   int cpu;                    /* CPU number (default CPU if ISA).  */
 };
 
+#define MIPS_CPU_IS_ISA		0x0001	/* Is this an ISA?  (If 0, a CPU.) */
+#define MIPS_CPU_ASE_SMARTMIPS	0x0002	/* CPU implements SmartMIPS ASE */
+#define MIPS_CPU_ASE_DSP	0x0004	/* CPU implements DSP ASE */
+#define MIPS_CPU_ASE_MT		0x0008	/* CPU implements MT ASE */
+#define MIPS_CPU_ASE_MIPS3D	0x0010	/* CPU implements MIPS-3D ASE */
+#define MIPS_CPU_ASE_MDMX	0x0020	/* CPU implements MDMX ASE */
+
 static const struct mips_cpu_info *mips_parse_cpu (const char *, const char *);
 static const struct mips_cpu_info *mips_cpu_info_from_isa (int);
 static const struct mips_cpu_info *mips_cpu_info_from_arch (int);
@@ -11380,14 +11408,43 @@ mips_after_parse_args (void)
 			|| !ISA_HAS_64BIT_REGS (mips_opts.isa));
     }
 
-  /* ??? GAS treats single-float processors as though they had 64-bit
-     float registers (although it complains when double-precision
-     instructions are used).  As things stand, saying they have 32-bit
-     registers would lead to spurious "register must be even" messages.
-     So here we assume float registers are always the same size as
-     integer ones, unless the user says otherwise.  */
-  if (file_mips_fp32 < 0)
-    file_mips_fp32 = file_mips_gp32;
+  switch (file_mips_fp32)
+    {
+    default:
+    case -1:
+      /* No user specified float register size.
+	 ??? GAS treats single-float processors as though they had 64-bit
+	 float registers (although it complains when double-precision
+	 instructions are used).  As things stand, saying they have 32-bit
+	 registers would lead to spurious "register must be even" messages.
+	 So here we assume float registers are never smaller than the
+	 integer ones.  */
+      if (file_mips_gp32 == 0)
+	/* 64-bit integer registers implies 64-bit float registers.  */
+	file_mips_fp32 = 0;
+      else if ((mips_opts.ase_mips3d > 0 || mips_opts.ase_mdmx > 0)
+	       && ISA_HAS_64BIT_FPRS (mips_opts.isa))
+	/* -mips3d and -mdmx imply 64-bit float registers, if possible.  */
+	file_mips_fp32 = 0;
+      else
+	/* 32-bit float registers.  */
+	file_mips_fp32 = 1;
+      break;
+
+    /* The user specified the size of the float registers.  Check if it
+       agrees with the ABI and ISA.  */
+    case 0:
+      if (!ISA_HAS_64BIT_FPRS (mips_opts.isa))
+	as_bad (_("-mfp64 used with a 32-bit fpu"));
+      else if (ABI_NEEDS_32BIT_REGS (mips_abi)
+	       && !ISA_HAS_MXHC1 (mips_opts.isa))
+	as_warn (_("-mfp64 used with a 32-bit ABI"));
+      break;
+    case 1:
+      if (ABI_NEEDS_64BIT_REGS (mips_abi))
+	as_warn (_("-mfp32 used with a 64-bit ABI"));
+      break;
+    }
 
   /* End of GCC-shared inference code.  */
 
@@ -11406,13 +11463,36 @@ mips_after_parse_args (void)
   if (mips_opts.mips16 == -1)
     mips_opts.mips16 = (CPU_HAS_MIPS16 (file_mips_arch)) ? 1 : 0;
   if (mips_opts.ase_mips3d == -1)
-    mips_opts.ase_mips3d = (CPU_HAS_MIPS3D (file_mips_arch)) ? 1 : 0;
+    mips_opts.ase_mips3d = ((CPU_HAS_MIPS3D (file_mips_arch)
+			     || (arch_info->flags & MIPS_CPU_ASE_MIPS3D))
+			    && file_mips_fp32 == 0) ? 1 : 0;
+  if (mips_opts.ase_mips3d && file_mips_fp32 == 1)
+    as_bad (_("-mfp32 used with -mips3d"));
+
   if (mips_opts.ase_mdmx == -1)
-    mips_opts.ase_mdmx = (CPU_HAS_MDMX (file_mips_arch)) ? 1 : 0;
+    mips_opts.ase_mdmx = ((CPU_HAS_MDMX (file_mips_arch)
+			   || (arch_info->flags & MIPS_CPU_ASE_MDMX))
+			  && file_mips_fp32 == 0) ? 1 : 0;
+  if (mips_opts.ase_mdmx && file_mips_fp32 == 1)
+    as_bad (_("-mfp32 used with -mdmx"));
+
+  if (mips_opts.ase_smartmips == -1)
+    mips_opts.ase_smartmips = (arch_info->flags & MIPS_CPU_ASE_SMARTMIPS) ? 1 : 0;
+  if (mips_opts.ase_smartmips && !ISA_SUPPORTS_SMARTMIPS)
+      as_warn ("%s ISA does not support SmartMIPS", 
+	       mips_cpu_info_from_isa (mips_opts.isa)->name);
+
   if (mips_opts.ase_dsp == -1)
-    mips_opts.ase_dsp = (CPU_HAS_DSP (file_mips_arch)) ? 1 : 0;
+    mips_opts.ase_dsp = (arch_info->flags & MIPS_CPU_ASE_DSP) ? 1 : 0;
+  if (mips_opts.ase_dsp && !ISA_SUPPORTS_DSP_ASE)
+      as_warn ("%s ISA does not support DSP ASE", 
+	       mips_cpu_info_from_isa (mips_opts.isa)->name);
+
   if (mips_opts.ase_mt == -1)
-    mips_opts.ase_mt = (CPU_HAS_MT (file_mips_arch)) ? 1 : 0;
+    mips_opts.ase_mt = (arch_info->flags & MIPS_CPU_ASE_MT) ? 1 : 0;
+  if (mips_opts.ase_mt && !ISA_SUPPORTS_MT_ASE)
+      as_warn ("%s ISA does not support MT ASE", 
+	       mips_cpu_info_from_isa (mips_opts.isa)->name);
 
   file_mips_isa = mips_opts.isa;
   file_ase_mips16 = mips_opts.mips16;
@@ -12266,6 +12346,28 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
     {
       mips_opts.nobopt = 1;
     }
+  else if (strcmp (name, "gp=default") == 0)
+    mips_opts.gp32 = file_mips_gp32;
+  else if (strcmp (name, "gp=32") == 0)
+    mips_opts.gp32 = 1;
+  else if (strcmp (name, "gp=64") == 0)
+    {
+      if (!ISA_HAS_64BIT_REGS (mips_opts.isa))
+	as_warn ("%s isa does not support 64-bit registers",
+		 mips_cpu_info_from_isa (mips_opts.isa)->name);
+      mips_opts.gp32 = 0;
+    }
+  else if (strcmp (name, "fp=default") == 0)
+    mips_opts.fp32 = file_mips_fp32;
+  else if (strcmp (name, "fp=32") == 0)
+    mips_opts.fp32 = 1;
+  else if (strcmp (name, "fp=64") == 0)
+    {
+      if (!ISA_HAS_64BIT_FPRS (mips_opts.isa))
+	as_warn ("%s isa does not support 64-bit floating point registers",
+		 mips_cpu_info_from_isa (mips_opts.isa)->name);
+      mips_opts.fp32 = 0;
+    }
   else if (strcmp (name, "mips16") == 0
 	   || strcmp (name, "MIPS-16") == 0)
     mips_opts.mips16 = 1;
@@ -12274,7 +12376,7 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
     mips_opts.mips16 = 0;
   else if (strcmp (name, "smartmips") == 0)
     {
-      if (!ISA_SUPPORT_SMARTMIPS)
+      if (!ISA_SUPPORTS_SMARTMIPS)
 	as_warn ("%s ISA does not support SmartMIPS ASE", 
 		 mips_cpu_info_from_isa (mips_opts.isa)->name);
       mips_opts.ase_smartmips = 1;
@@ -12290,11 +12392,21 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
   else if (strcmp (name, "nomdmx") == 0)
     mips_opts.ase_mdmx = 0;
   else if (strcmp (name, "dsp") == 0)
-    mips_opts.ase_dsp = 1;
+    {
+      if (!ISA_SUPPORTS_DSP_ASE)
+	as_warn ("%s ISA does not support DSP ASE", 
+		 mips_cpu_info_from_isa (mips_opts.isa)->name);
+      mips_opts.ase_dsp = 1;
+    }
   else if (strcmp (name, "nodsp") == 0)
     mips_opts.ase_dsp = 0;
   else if (strcmp (name, "mt") == 0)
-    mips_opts.ase_mt = 1;
+    {
+      if (!ISA_SUPPORTS_MT_ASE)
+	as_warn ("%s ISA does not support MT ASE", 
+		 mips_cpu_info_from_isa (mips_opts.isa)->name);
+      mips_opts.ase_mt = 1;
+    }
   else if (strcmp (name, "nomt") == 0)
     mips_opts.ase_mt = 0;
   else if (strncmp (name, "mips", 4) == 0 || strncmp (name, "arch=", 5) == 0)
@@ -14012,6 +14124,12 @@ mips_elf_final_processing (void)
 
   if (mips_32bitmode)
     elf_elfheader (stdoutput)->e_flags |= EF_MIPS_32BITMODE;
+
+#if 0 /* XXX FIXME */
+  /* 32 bit code with 64 bit FP registers.  */
+  if (!file_mips_fp32 && ABI_NEEDS_32BIT_REGS (mips_abi))
+    elf_elfheader (stdoutput)->e_flags |= ???;
+#endif
 }
 
 #endif /* OBJ_ELF || OBJ_MAYBE_ELF */
@@ -14414,72 +14532,90 @@ s_mips_mask (int reg_type)
 static const struct mips_cpu_info mips_cpu_info_table[] =
 {
   /* Entries for generic ISAs */
-  { "mips1",          1,      ISA_MIPS1,      CPU_R3000 },
-  { "mips2",          1,      ISA_MIPS2,      CPU_R6000 },
-  { "mips3",          1,      ISA_MIPS3,      CPU_R4000 },
-  { "mips4",          1,      ISA_MIPS4,      CPU_R8000 },
-  { "mips5",          1,      ISA_MIPS5,      CPU_MIPS5 },
-  { "mips32",         1,      ISA_MIPS32,     CPU_MIPS32 },
-  { "mips32r2",       1,      ISA_MIPS32R2,   CPU_MIPS32R2 },
-  { "mips64",         1,      ISA_MIPS64,     CPU_MIPS64 },
-  { "mips64r2",       1,      ISA_MIPS64R2,   CPU_MIPS64R2 },
+  { "mips1",          MIPS_CPU_IS_ISA,		ISA_MIPS1,      CPU_R3000 },
+  { "mips2",          MIPS_CPU_IS_ISA,		ISA_MIPS2,      CPU_R6000 },
+  { "mips3",          MIPS_CPU_IS_ISA,		ISA_MIPS3,      CPU_R4000 },
+  { "mips4",          MIPS_CPU_IS_ISA,		ISA_MIPS4,      CPU_R8000 },
+  { "mips5",          MIPS_CPU_IS_ISA,		ISA_MIPS5,      CPU_MIPS5 },
+  { "mips32",         MIPS_CPU_IS_ISA,		ISA_MIPS32,     CPU_MIPS32 },
+  { "mips32r2",       MIPS_CPU_IS_ISA,		ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "mips64",         MIPS_CPU_IS_ISA,		ISA_MIPS64,     CPU_MIPS64 },
+  { "mips64r2",       MIPS_CPU_IS_ISA,		ISA_MIPS64R2,   CPU_MIPS64R2 },
 
   /* MIPS I */
-  { "r3000",          0,      ISA_MIPS1,      CPU_R3000 },
-  { "r2000",          0,      ISA_MIPS1,      CPU_R3000 },
-  { "r3900",          0,      ISA_MIPS1,      CPU_R3900 },
+  { "r3000",          0,			ISA_MIPS1,      CPU_R3000 },
+  { "r2000",          0,			ISA_MIPS1,      CPU_R3000 },
+  { "r3900",          0,			ISA_MIPS1,      CPU_R3900 },
 
   /* MIPS II */
-  { "r6000",          0,      ISA_MIPS2,      CPU_R6000 },
+  { "r6000",          0,			ISA_MIPS2,      CPU_R6000 },
 
   /* MIPS III */
-  { "r4000",          0,      ISA_MIPS3,      CPU_R4000 },
-  { "r4010",          0,      ISA_MIPS2,      CPU_R4010 },
-  { "vr4100",         0,      ISA_MIPS3,      CPU_VR4100 },
-  { "vr4111",         0,      ISA_MIPS3,      CPU_R4111 },
-  { "vr4120",         0,      ISA_MIPS3,      CPU_VR4120 },
-  { "vr4130",         0,      ISA_MIPS3,      CPU_VR4120 },
-  { "vr4181",         0,      ISA_MIPS3,      CPU_R4111 },
-  { "vr4300",         0,      ISA_MIPS3,      CPU_R4300 },
-  { "r4400",          0,      ISA_MIPS3,      CPU_R4400 },
-  { "r4600",          0,      ISA_MIPS3,      CPU_R4600 },
-  { "orion",          0,      ISA_MIPS3,      CPU_R4600 },
-  { "r4650",          0,      ISA_MIPS3,      CPU_R4650 },
+  { "r4000",          0,			ISA_MIPS3,      CPU_R4000 },
+  { "r4010",          0,			ISA_MIPS2,      CPU_R4010 },
+  { "vr4100",         0,			ISA_MIPS3,      CPU_VR4100 },
+  { "vr4111",         0,			ISA_MIPS3,      CPU_R4111 },
+  { "vr4120",         0,			ISA_MIPS3,      CPU_VR4120 },
+  { "vr4130",         0,			ISA_MIPS3,      CPU_VR4120 },
+  { "vr4181",         0,			ISA_MIPS3,      CPU_R4111 },
+  { "vr4300",         0,			ISA_MIPS3,      CPU_R4300 },
+  { "r4400",          0,			ISA_MIPS3,      CPU_R4400 },
+  { "r4600",          0,			ISA_MIPS3,      CPU_R4600 },
+  { "orion",          0,			ISA_MIPS3,      CPU_R4600 },
+  { "r4650",          0,			ISA_MIPS3,      CPU_R4650 },
 
   /* MIPS IV */
-  { "r8000",          0,      ISA_MIPS4,      CPU_R8000 },
-  { "r10000",         0,      ISA_MIPS4,      CPU_R10000 },
-  { "r12000",         0,      ISA_MIPS4,      CPU_R12000 },
-  { "vr5000",         0,      ISA_MIPS4,      CPU_R5000 },
-  { "vr5400",         0,      ISA_MIPS4,      CPU_VR5400 },
-  { "vr5500",         0,      ISA_MIPS4,      CPU_VR5500 },
-  { "rm5200",         0,      ISA_MIPS4,      CPU_R5000 },
-  { "rm5230",         0,      ISA_MIPS4,      CPU_R5000 },
-  { "rm5231",         0,      ISA_MIPS4,      CPU_R5000 },
-  { "rm5261",         0,      ISA_MIPS4,      CPU_R5000 },
-  { "rm5721",         0,      ISA_MIPS4,      CPU_R5000 },
-  { "rm7000",         0,      ISA_MIPS4,      CPU_RM7000 },
-  { "rm9000",         0,      ISA_MIPS4,      CPU_RM9000 },
+  { "r8000",          0,			ISA_MIPS4,      CPU_R8000 },
+  { "r10000",         0,			ISA_MIPS4,      CPU_R10000 },
+  { "r12000",         0,			ISA_MIPS4,      CPU_R12000 },
+  { "vr5000",         0,			ISA_MIPS4,      CPU_R5000 },
+  { "vr5400",         0,			ISA_MIPS4,      CPU_VR5400 },
+  { "vr5500",         0,			ISA_MIPS4,      CPU_VR5500 },
+  { "rm5200",         0,			ISA_MIPS4,      CPU_R5000 },
+  { "rm5230",         0,			ISA_MIPS4,      CPU_R5000 },
+  { "rm5231",         0,			ISA_MIPS4,      CPU_R5000 },
+  { "rm5261",         0,			ISA_MIPS4,      CPU_R5000 },
+  { "rm5721",         0,			ISA_MIPS4,      CPU_R5000 },
+  { "rm7000",         0,			ISA_MIPS4,      CPU_RM7000 },
+  { "rm9000",         0,			ISA_MIPS4,      CPU_RM9000 },
 
   /* MIPS 32 */
-  { "4kc",            0,      ISA_MIPS32,     CPU_MIPS32 },
-  { "4km",            0,      ISA_MIPS32,     CPU_MIPS32 },
-  { "4kp",            0,      ISA_MIPS32,     CPU_MIPS32 },
-
-  /* MIPS32 Release 2 */
-  { "m4k",            0,      ISA_MIPS32R2,   CPU_MIPS32R2 },
-  { "24k",            0,      ISA_MIPS32R2,   CPU_MIPS32R2 },
-  { "24kc",           0,      ISA_MIPS32R2,   CPU_MIPS32R2 },
-  { "24kf",           0,      ISA_MIPS32R2,   CPU_MIPS32R2 },
-  { "24kx",           0,      ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "4kc",            0,			ISA_MIPS32,	CPU_MIPS32 },
+  { "4km",            0,			ISA_MIPS32,	CPU_MIPS32 },
+  { "4kp",            0,			ISA_MIPS32,	CPU_MIPS32 },
+  { "4ksc",           MIPS_CPU_ASE_SMARTMIPS,	ISA_MIPS32,	CPU_MIPS32 },
+
+  /* MIPS 32 Release 2 */
+  { "4kec",           0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "4kem",           0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "4kep",           0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "4ksd",           MIPS_CPU_ASE_SMARTMIPS,	ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "m4k",            0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "m4kp",           0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "24k",            0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "24kc",           0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "24kf",           0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "24kx",           0,			ISA_MIPS32R2,   CPU_MIPS32R2 },
+  /* 24ke is a 24k with DSP ASE, other ASEs are optional.  */
+  { "24ke",           MIPS_CPU_ASE_DSP,		ISA_MIPS32R2,	CPU_MIPS32R2 },
+  { "24kec",          MIPS_CPU_ASE_DSP,		ISA_MIPS32R2,	CPU_MIPS32R2 },
+  { "24kef",          MIPS_CPU_ASE_DSP,		ISA_MIPS32R2,	CPU_MIPS32R2 },
+  { "24kex",         MIPS_CPU_ASE_DSP,		ISA_MIPS32R2,	CPU_MIPS32R2 },
+  /* 34k is a 24k with MT ASE, other ASEs are optional.  */
+  { "34kc",           MIPS_CPU_ASE_MT,		ISA_MIPS32R2,	CPU_MIPS32R2 },
+  { "34kf",           MIPS_CPU_ASE_MT,		ISA_MIPS32R2,	CPU_MIPS32R2 },
+  { "34kx",          MIPS_CPU_ASE_MT,		ISA_MIPS32R2,	CPU_MIPS32R2 },
 
   /* MIPS 64 */
-  { "5kc",            0,      ISA_MIPS64,     CPU_MIPS64 },
-  { "5kf",            0,      ISA_MIPS64,     CPU_MIPS64 },
-  { "20kc",           0,      ISA_MIPS64,     CPU_MIPS64 },
+  { "5kc",            0,			ISA_MIPS64,	CPU_MIPS64 },
+  { "5kf",            0,			ISA_MIPS64,	CPU_MIPS64 },
+  { "20kc",           MIPS_CPU_ASE_MIPS3D,	ISA_MIPS64,	CPU_MIPS64 },
+
+  /* MIPS 64 Release 2 */
+  { "25kf",           MIPS_CPU_ASE_MIPS3D,	ISA_MIPS64R2,   CPU_MIPS64R2 },
 
   /* Broadcom SB-1 CPU core */
-  { "sb1",            0,      ISA_MIPS64,     CPU_SB1 },
+  { "sb1",            0,			ISA_MIPS64,	CPU_SB1 },
 
   /* End marker */
   { NULL, 0, 0, 0 }
@@ -14594,7 +14730,7 @@ mips_cpu_info_from_isa (int isa)
   int i;
 
   for (i = 0; mips_cpu_info_table[i].name != NULL; i++)
-    if (mips_cpu_info_table[i].is_isa
+    if ((mips_cpu_info_table[i].flags & MIPS_CPU_IS_ISA)
 	&& isa == mips_cpu_info_table[i].isa)
       return (&mips_cpu_info_table[i]);
 
Index: gas/testsuite/gas/mips/mips-gp32-fp64-pic.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips-gp32-fp64-pic.d,v
retrieving revision 1.6
diff -u -p -r1.6 mips-gp32-fp64-pic.d
--- gas/testsuite/gas/mips/mips-gp32-fp64-pic.d	22 Apr 2004 18:13:56 -0000	1.6
+++ gas/testsuite/gas/mips/mips-gp32-fp64-pic.d	22 May 2006 15:23:40 -0000
@@ -1,6 +1,7 @@
 #objdump: -d -mmips:8000
 #as: -32 -march=8000 -EB -mgp32 -mfp64 -KPIC
 #name: MIPS -mgp32 -mfp64 (SVR4 PIC)
+#stderr: mips-gp32-fp64.l
 
 .*: +file format.*
 
Index: gas/testsuite/gas/mips/mips-gp32-fp64.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips-gp32-fp64.d,v
retrieving revision 1.5
diff -u -p -r1.5 mips-gp32-fp64.d
--- gas/testsuite/gas/mips/mips-gp32-fp64.d	7 May 2003 05:08:20 -0000	1.5
+++ gas/testsuite/gas/mips/mips-gp32-fp64.d	22 May 2006 15:23:40 -0000
@@ -1,6 +1,7 @@
 #objdump: -d -mmips:8000
 #as: -32 -march=8000 -EB -mgp32 -mfp64
 #name: MIPS -mgp32 -mfp64
+#stderr: mips-gp32-fp64.l
 
 .*: +file format.*
 
Index: gas/testsuite/gas/mips/mips-gp64-fp32-pic.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips-gp64-fp32-pic.d,v
retrieving revision 1.6
diff -u -p -r1.6 mips-gp64-fp32-pic.d
--- gas/testsuite/gas/mips/mips-gp64-fp32-pic.d	22 Apr 2004 18:13:56 -0000	1.6
+++ gas/testsuite/gas/mips/mips-gp64-fp32-pic.d	22 May 2006 15:23:40 -0000
@@ -1,6 +1,7 @@
 #objdump: -d -mmips:8000
 #as: -mabi=o64 -march=8000 -EB -mfp32 -KPIC
 #name: MIPS -mgp64 -mfp32 (SVR4 PIC)
+#stderr: mips-gp64-fp32-pic.l
 
 .*: +file format.*
 
Index: gas/testsuite/gas/mips/mips-gp64-fp32.l
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips-gp64-fp32.l,v
retrieving revision 1.1
diff -u -p -r1.1 mips-gp64-fp32.l
--- gas/testsuite/gas/mips/mips-gp64-fp32.l	22 Apr 2002 22:29:47 -0000	1.1
+++ gas/testsuite/gas/mips/mips-gp64-fp32.l	22 May 2006 15:23:40 -0000
@@ -1,4 +1,5 @@
-.*: Assembler messages:
+Assembler messages:
+Warning: -mfp32 used with a 64-bit ABI
 .*:92: Warning: Macro instruction expanded into multiple instructions in a branch delay slot
 .*:96: Warning: Macro instruction expanded into multiple instructions in a branch delay slot
 .*:100: Warning: Macro instruction expanded into multiple instructions in a branch delay slot
Index: gas/testsuite/gas/mips/mips-gp64-fp64.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips-gp64-fp64.d,v
retrieving revision 1.6
diff -u -p -r1.6 mips-gp64-fp64.d
--- gas/testsuite/gas/mips/mips-gp64-fp64.d	7 May 2003 05:08:20 -0000	1.6
+++ gas/testsuite/gas/mips/mips-gp64-fp64.d	22 May 2006 15:23:40 -0000
@@ -1,7 +1,7 @@
 #objdump: -d -mmips:8000
 #as: -mabi=o64 -march=8000 -EB
 #name: MIPS -mgp64 -mfp64
-#stderr: mips-gp64-fp32.l
+#stderr: mips-gp64-fp64.l
 
 .*: +file format.*
 
--- /dev/null	2006-05-17 20:07:57.714000000 +0100
+++ gas/testsuite/gas/mips/mips-gp32-fp64.l	2006-05-22 15:40:46.000000000 +0100
@@ -0,0 +1,2 @@
+Assembler messages:
+Warning: -mfp64 used with a 32-bit ABI
--- /dev/null	2006-05-17 20:07:57.714000000 +0100
+++ gas/testsuite/gas/mips/mips-gp64-fp32-pic.l	2006-05-22 16:06:58.000000000 +0100
@@ -0,0 +1,2 @@
+Assembler messages:
+Warning: -mfp32 used with a 64-bit ABI
Index: gas/doc/c-mips.texi
===================================================================
RCS file: /cvs/src/src/gas/doc/c-mips.texi,v
retrieving revision 1.37
diff -u -p -r1.37 c-mips.texi
--- gas/doc/c-mips.texi	8 May 2006 15:57:05 -0000	1.37
+++ gas/doc/c-mips.texi	23 May 2006 13:47:00 -0000
@@ -91,19 +91,28 @@ flags force a certain group of registers
 all times.  @samp{-mgp32} controls the size of general-purpose registers
 and @samp{-mfp32} controls the size of floating-point registers.
 
+The @code{.set gp=32} and @code{.set fp=32} directives allow the size
+of registers to be changed for parts of an object. The default value is
+restored by @code{.set gp=default} and @code{.set fp=default}.
+
 On some MIPS variants there is a 32-bit mode flag; when this flag is
 set, 64-bit instructions generate a trap.  Also, some 32-bit OSes only
 save the 32-bit registers on a context switch, so it is essential never
 to use the 64-bit registers.
 
 @item -mgp64
-Assume that 64-bit general purpose registers are available.  This is
-provided in the interests of symmetry with -gp32.
+@itemx -mfp64
+Assume that 64-bit registers are available.  This is provided in the
+interests of symmetry with @samp{-mgp32} and @samp{-mfp32}.
+
+The @code{.set gp=64} and @code{.set fp=64} directives allow the size
+of registers to be changed for parts of an object. The default value is
+restored by @code{.set gp=default} and @code{.set fp=default}.
 
 @item -mips16
 @itemx -no-mips16
 Generate code for the MIPS 16 processor.  This is equivalent to putting
-@samp{.set mips16} at the start of the assembly file.  @samp{-no-mips16}
+@code{.set mips16} at the start of the assembly file.  @samp{-no-mips16}
 turns off this option.
 
 @item -msmartmips
@@ -111,7 +120,7 @@ turns off this option.
 Enables the SmartMIPS extensions to the MIPS32 instruction set, which
 provides a number of new instructions which target smartcard and
 cryptographic applications.  This is equivalent to putting
-@samp{.set smartmips} at the start of the assembly file.
+@code{.set smartmips} at the start of the assembly file.
 @samp{-mno-smartmips} turns off this option.
 
 @item -mips3d
@@ -210,7 +219,29 @@ rm7000,
 rm9000,
 10000,
 12000,
-mips32-4k,
+4kc,
+4km,
+4kp,
+4ksc,
+4kec,
+4kem,
+4kep,
+4ksd,
+m4k,
+m4kp,
+24kc,
+24kf,
+24kx,
+24kec,
+24kef,
+24kex,
+34kc,
+34kf,
+34kx,
+5kc,
+5kf,
+20kc,
+25kf,
 sb1
 @end quotation
 
@@ -399,17 +430,21 @@ assembly.  @code{.set mips@var{n}} affec
 are permitted, but also how certain macros are expanded.  @code{.set
 mips0} restores the @sc{isa} level to its original level: either the
 level you selected with command line options, or the default for your
-configuration.  You can use this feature to permit specific @sc{r4000}
+configuration.  You can use this feature to permit specific @sc{mips3}
 instructions while assembling in 32 bit mode.  Use this directive with
 care!
 
-The directive @samp{.set mips16} puts the assembler into MIPS 16 mode,
-in which it will assemble instructions for the MIPS 16 processor.  Use
-@samp{.set nomips16} to return to normal 32 bit mode.
+@cindex MIPS CPU override
+@kindex @code{.set arch=@var{cpu}}
+The @code{.set arch=@var{cpu}} directive provides even finer control.
+It changes the effective CPU target and allows the assembler to use
+instructions specific to a particular CPU.  All CPUs supported by the
+@samp{-march} command line option are also selectable by this directive.
+The original value is restored by @code{.set arch=default}.
 
-The @samp{.set smartmips} directive enables use of the SmartMIPS
-extensions to the MIPS32 @sc{isa}; the @samp{.set nosmartmips} directive
-reverses that.
+The directive @code{.set mips16} puts the assembler into MIPS 16 mode,
+in which it will assemble instructions for the MIPS 16 processor.  Use
+@code{.set nomips16} to return to normal 32 bit mode.
 
 Traditional @sc{mips} assemblers do not support this directive.
 
@@ -419,10 +454,10 @@ Traditional @sc{mips} assemblers do not 
 @kindex @code{.set autoextend}
 @kindex @code{.set noautoextend}
 By default, MIPS 16 instructions are automatically extended to 32 bits
-when necessary.  The directive @samp{.set noautoextend} will turn this
-off.  When @samp{.set noautoextend} is in effect, any 32 bit instruction
-must be explicitly extended with the @samp{.e} modifier (e.g.,
-@samp{li.e $4,1000}).  The directive @samp{.set autoextend} may be used
+when necessary.  The directive @code{.set noautoextend} will turn this
+off.  When @code{.set noautoextend} is in effect, any 32 bit instruction
+must be explicitly extended with the @code{.e} modifier (e.g.,
+@code{li.e $4,1000}).  The directive @code{.set autoextend} may be used
 to once again automatically extend instructions when necessary.
 
 This directive is only meaningful when in MIPS 16 mode.  Traditional
@@ -467,6 +502,15 @@ from the MIPS-3D Application Specific Ex
 in the assembly.  The @code{.set nomips3d} directive prevents MIPS-3D
 instructions from being accepted.
 
+@cindex SmartMIPS instruction generation override
+@kindex @code{.set smartmips}
+@kindex @code{.set nosmartmips}
+The directive @code{.set smartmips} makes the assembler accept
+instructions from the SmartMIPS Application Specific Extension to the
+MIPS32 @sc{isa} from that point on in the assembly.  The
+@code{.set nosmartmips} directive prevents SmartMIPS instructions from
+being accepted.
+
 @cindex MIPS MDMX instruction generation override
 @kindex @code{.set mdmx}
 @kindex @code{.set nomdmx}

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Better checking of ISA/ASE/ABI options for MIPS gas
  2006-05-23 23:37     ` Thiemo Seufer
@ 2006-05-24  1:46       ` Richard Sandiford
  0 siblings, 0 replies; 14+ messages in thread
From: Richard Sandiford @ 2006-05-24  1:46 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils

Thiemo Seufer <ths@networkno.de> writes:
> Richard Sandiford wrote:
> [snip]
>> > Richard, do you care about the gcc update (if/when the release cycle
>> > permits it)?
>> 
>> I'm not sure what you mean here, but I'd certainly like to see gcc's &
>> gas's option handling kept in sync, so the gcc equivalent of this patch
>> is certainly welcome from my POV.  And I'd see a long-lasting divergence
>> between gas and gcc as a bug, so I'd be happy to use the discretion
>> given to target maintainers and have the patch go in during stage 3.
>
> Well, the divergence is caused by missing MIPS32R2 with 64bit FP support
> on the gcc side, which is a too invasive change for stage 3. IOW, the
> re-sync of the option handling will be included in that patch, hopefully
> in time for next stage 1.

OK, that's fine too ;)

Richard

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2006-05-23 15:48 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-05-23  0:08 [PATCH] Better checking of ISA/ASE/ABI options for MIPS gas Thiemo Seufer
2006-05-23  4:06 ` Eric Christopher
2006-05-23  4:40   ` Thiemo Seufer
2006-05-23  5:01     ` Eric Christopher
2006-05-23  5:27       ` Thiemo Seufer
2006-05-23  5:51         ` Eric Christopher
2006-05-23 12:10 ` Richard Sandiford
2006-05-23 13:34   ` Thiemo Seufer
2006-05-23 14:14     ` Richard Sandiford
2006-05-23 15:39       ` Thiemo Seufer
2006-05-23 17:47 ` Thiemo Seufer
2006-05-23 21:01   ` Richard Sandiford
2006-05-23 23:37     ` Thiemo Seufer
2006-05-24  1:46       ` Richard Sandiford

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).