This is the mail archive of the binutils@sourceware.cygnus.com mailing list for the binutils project.


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

[patch] mips 7000 fixup


Sorry about that last email.  I hit send prematurely.

I would like to submit the following patch for gas.  It is meant
to address an issue that was discovered with a mips 7000 board.
Apparently, the destination register of an mfhi/mflo is not available
for two instructions.  This patch will cause the necessary nops to be
inserted if the -mfix700 option is passed to gas.  I am also submitting
a patch to gcc which will recognize and pass the option to gas.

Okay to commit?

Catherine

2000-02-18  Catherine Moore  <clm@cygnus.com>
 
        * config/tc-mips.c (MF_HILO_INSN): Define.
        (mips_7000_hilo_fix): Declare.
        (append_insn): Conditionally insert nops after an mfhi/mflo insn.
        (md_parse_option): Check for 7000_HILO_FIX options.
        (OPTION_M7000_HILO_FIX): Define.
        (OPTION_NO_M7000_HILO_FIX): Define.
        * doc/c-mips.texi (-mfix7000): Describe.

Index: doc/c-mips.texi
===================================================================
RCS file: /cvs/cvsfiles/devo/gas/doc/c-mips.texi,v
retrieving revision 1.10.50.1
diff -p -r1.10.50.1 c-mips.texi
*** c-mips.texi	1999/11/03 03:51:38	1.10.50.1
--- c-mips.texi	2000/02/18 21:50:32
*************** Generate code for the MIPS 16 processor.
*** 73,78 ****
--- 73,83 ----
  @samp{.set mips16} at the start of the assembly file.  @samp{-no-mips16}
  turns off this option.
  
+ @item -mfix7000
+ @itemx -no-mfix7000
+ Cause nops to be inserted if the read of the destination register
+ of an mfhi or mflo instruction occurs in the following two instructions.
+ 
  @item -m4010
  @itemx -no-m4010
  Generate code for the LSI @sc{r4010} chip.  This tells the assembler to
Index: config/tc-mips.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gas/config/tc-mips.c,v
retrieving revision 1.366.10.1
diff -p -r1.366.10.1 tc-mips.c
*** tc-mips.c	1999/11/03 03:51:28	1.366.10.1
--- tc-mips.c	2000/02/18 21:51:30
*************** static int mips_32bitmode = 0;
*** 267,272 ****
--- 267,277 ----
  			|| mips_cpu == 5400			    \
  			)
  
+ /* Is this a mfhi or mflo instruction?  */
+ #define MF_HILO_INSN(PINFO) \
+         ((PINFO & INSN_WRITE_GPR_D) \
+           && (PINFO & INSN_READ_HI) || (PINFO & INSN_READ_LO))
+ 
  /* MIPS PIC level.  */
  
  enum mips_pic_level
*************** static int mips_trap;
*** 302,307 ****
--- 307,316 ----
  
  static int mips_any_noreorder;
  
+ /* Non-zero if nops should be inserted when the register referenced in
+    an mfhi/mflo instruction is read in the next two instructions.  */
+ static int mips_7000_hilo_fix;
+ 
  /* The size of the small data section.  */
  static int g_switch_value = 8;
  /* Whether the -G option was used.  */
*************** append_insn (place, ip, address_expr, re
*** 1557,1562 ****
--- 1566,1604 ----
  	      || (pinfo & INSN_READ_COND_CODE))
  	    ++nops;
  	}
+ 
+       /* If we're fixing up mfhi/mflo for the r7000 and the
+ 	 previous insn was an mfhi/mflo and the current insn
+ 	 reads the register that the mfhi/mflo wrote to, then
+ 	 insert two nops.  */
+ 
+       else if (mips_7000_hilo_fix
+ 	       && MF_HILO_INSN (prev_pinfo)
+ 	       && (pinfo & INSN_READ_GPR_S || pinfo & INSN_READ_GPR_T)
+ 	       && insn_uses_reg (ip, ((prev_insn.insn_opcode >> OP_SH_RD)
+                                        & OP_MASK_RD),
+                                     MIPS_GR_REG))
+ 
+ 	{
+ 	  nops += 2;
+ 	}
+ 
+       /* If we're fixing up mfhi/mflo for the r7000 and the
+ 	 2nd previous insn was an mfhi/mflo and the current insn
+ 	 reads the register that the mfhi/mflo wrote to, then
+ 	 insert one nop.  */
+ 
+       else if (mips_7000_hilo_fix
+ 	       && MF_HILO_INSN (prev_prev_insn.insn_opcode)
+ 	       && (pinfo & INSN_READ_GPR_S || pinfo & INSN_READ_GPR_T)
+ 	       && insn_uses_reg (ip, ((prev_prev_insn.insn_opcode >> OP_SH_RD)
+                                        & OP_MASK_RD),
+                                     MIPS_GR_REG))
+      
+ 	{
+ 	  nops += 1;
+ 	}
+  
        else if (prev_pinfo & INSN_READ_LO)
  	{
  	  /* The previous instruction reads the LO register; if the
*************** struct option md_longopts[] = {
*** 8897,8902 ****
--- 8939,8949 ----
  #define OPTION_MABI (OPTION_MD_BASE + 38)
    {"mabi", required_argument, NULL, OPTION_MABI},
  
+ #define OPTION_M7000_HILO_FIX (OPTION_MD_BASE + 39)
+   {"mfix7000", no_argument, NULL, OPTION_M7000_HILO_FIX},
+ #define OPTION_NO_M7000_HILO_FIX (OPTION_MD_BASE + 40)
+   {"no-fix-7000", no_argument, NULL, OPTION_NO_M7000_HILO_FIX},
+ 
  #define OPTION_CALL_SHARED (OPTION_MD_BASE + 7)
  #define OPTION_NON_SHARED (OPTION_MD_BASE + 8)
  #define OPTION_XGOT (OPTION_MD_BASE + 19)
*************** md_parse_option (c, arg)
*** 9229,9234 ****
--- 9276,9289 ----
  	  || strcmp (arg,"o64") == 0
  	  || strcmp (arg,"eabi") == 0)
  	mips_abi_string = arg;
+       break;
+ 
+     case OPTION_M7000_HILO_FIX:
+       mips_7000_hilo_fix = true;
+       break;
+ 
+     case OPTION_NO_M7000_HILO_FIX:
+       mips_7000_hilo_fix = false;
        break;
  
      default:

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