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