head: MIPS: A workaround for the R4000 divide/shift errata

Richard Sandiford rsandifo@redhat.com
Mon Mar 1 18:24:00 GMT 2004


"Maciej W. Rozycki" <macro@ds2.pg.gda.pl> writes:
>> I was going to add a comment about why the nop was needed even for
>> -mcheck-zero-division.  In the end, I figured it was easier just to
>> force the division into the delay slot as previously discussed.
>> Working on that now.
>
>  Please wait for a while.  I have two more patches for this area to 
> reflect events that happened meanwhile.

Too late. ;)  I'd already tested the patch below.  I thought about giving
way to your new division change, but I think doing this first will lead
to a cleaner implementation.  Will reply separately saying why.

Bootstrapped & regression tested on mips-sgi-irix6.5.  Also tested on
mips64vrel-elf to test the mips16 bits.  Applied to trunk.

Richard


	* config/mips/mips.c (mips_output_division): Use the division
	instruction to fill the delay slot of a zero check.
	(mips_idiv_insns): Adjust accordingly.

Index: config/mips/mips.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.c,v
retrieving revision 1.388
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.388 mips.c
*** config/mips/mips.c	28 Feb 2004 20:27:42 -0000	1.388
--- config/mips/mips.c	28 Feb 2004 21:24:16 -0000
*************** mips_idiv_insns (void)
*** 1359,1370 ****
  
    count = 1;
    if (TARGET_CHECK_ZERO_DIV)
!     {
!       if (TARGET_MIPS16)
! 	count += 2;
!       else
! 	count += 3;
!     }
    if (TARGET_FIX_R4000)
      count++;
    return count;
--- 1359,1365 ----
  
    count = 1;
    if (TARGET_CHECK_ZERO_DIV)
!     count += 2;
    if (TARGET_FIX_R4000)
      count++;
    return count;
*************** mips_output_conditional_branch (rtx insn
*** 9225,9240 ****
  const char *
  mips_output_division (const char *division, rtx *operands)
  {
!   const char *s = division;
  
    if (TARGET_CHECK_ZERO_DIV)
      {
-       output_asm_insn (s, operands);
- 
        if (TARGET_MIPS16)
! 	s = "bnez\t%2,1f\n\tbreak\t7\n1:";
        else
! 	s = "bne\t%2,%.,1f%#\n\tbreak\t7\n1:";
      }
    if (TARGET_FIX_R4000)
      {
--- 9220,9241 ----
  const char *
  mips_output_division (const char *division, rtx *operands)
  {
!   const char *s;
  
+   s = division;
    if (TARGET_CHECK_ZERO_DIV)
      {
        if (TARGET_MIPS16)
! 	{
! 	  output_asm_insn (s, operands);
! 	  s = "bnez\t%2,1f\n\tbreak\t7\n1:";
! 	}
        else
! 	{
! 	  output_asm_insn ("%(bne\t%2,%.,1f", operands);
! 	  output_asm_insn (s, operands);
! 	  s = "break\t7%)\n1:";
! 	}
      }
    if (TARGET_FIX_R4000)
      {



More information about the Gcc-patches mailing list