Incorrect code using gcc 2.8.x for Motorola 5200 Coldfire

Russ Fellows rfellows@intellistor.com
Thu Aug 27 09:28:00 GMT 1998


Jeffrey A Law wrote:
> 
> The egcs project has fixed a few problems with codefire code generation.
> We may have even fixed yours, but without a testcase we can't be sure.
> 
> jeff

Thank you for your reply.  Yes, I have looked at ecgs, and in fact I just
downloaded the 8/24 snapshot.  I see that you have fixed another problem
with the "and.w" operation on the 5200 (which is illegal).  However, the
problem we found and fixed is not there.  As for a test case, I indeed
have one.  I posted the test case, and the code changes to fix it as a
followup news article in "gnu.gcc.bugs".  Here is that news post
---------------------------------------------------------------------------

All of the following relates to gcc-2.8.1 cross compiler:
(host = sparc-sun-solaris2.5; target = m68k-5200-aout)

Here is some more detail:
For some reason, it appears that when the Coldfire port was done,
byte (or quarter-word) access was allowed on address registers
for the Coldfire.  This is not allowed, but does not produce a
trap or illegal instruction on the 5200 series.  It does do this
on the 5307 specifically however.

When using more than 8 variables that may be assigned to a register,
the compiler will start allocating Address Registers for the next
byte variables.

For instance a program with 9 variables of type "byte", which are 
used for a loop counter, and are hence assigned to a register. The
9 - 14 (fp and sp are reserved) will be allocated for the these
byte indicies.  I will also attach a code sample which demonstrates
the problem, and finally our "patches" which appear to fix the
problem.  HOWEVER, we would like someone at Gnu to look over the
fixes and insure that there are no other similar cases that we are
over looking.

Thank you,

Test function to show problem:
--------------------------------------------------------------------
void func_init ()
{
    unsigned char c0 = 0;
    unsigned char c1 = 1;
    unsigned char c2 = 2;
    unsigned char c3 = 3;
    unsigned char c4 = 4;
    unsigned char c5 = 5;
    unsigned char c6 = 6;
    unsigned char c7 = 7;
    unsigned char c8 = 8;
    unsigned char c9 = 9;
 
    unsigned char i0 = 9;
    unsigned char i1 = 8;
    unsigned char i2 = 7;
    unsigned char i3 = 6;
    unsigned char i4 = 5;
    unsigned char i5 = 4;
    unsigned char i6 = 3;
    unsigned char i7 = 2;
    unsigned char i8 = 1;
    unsigned char i9 = 9;
 
    while (i0--)
    {
        c0 = c2 + c4 + c6 + c8;
        while (i1--)
        {
            c1 = c3 + c5 + c7 + c7;
            while (i2--)
            {
                c2 = c0 + c4 + c6 + c8;
                while (i3--)
                {
                    c3 = c1 + c5 + c7 + c7;
                    while (i4--)
                    {
                        c4 = c0 + c2 + c6 + c8;
                        while (i5--)
                        {
                            c5 = c1 + c3 + c7 + c9;
                            while (i6--)
                            {
                                c6 = c0 + c2 + c4 + c8;
                                while (i7--)
                                {
                                    c7 = c1 + c3 + c5 + c9;
                                    while (i8--)
                                    {
                                        c8 = c0 + c2 + c4 + c6;
                                        while (i9--)
                                        {
                                            c9 = c1 + c3 + c5 + c7;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
 
    while (1) ;                        // Just HANG around here for a
WHILE!
 
}
--------------------------------------------------------------------------

Begin patch for gcc-2.8.1/config/m68k/(m68k.c,m68k.h,m68k.md)
--------------------------------------------------------------------------
--- m68k.c.orig Fri Nov 21 10:53:07 1997
+++ m68k.c      Tue Aug 18 06:58:17 1998
@@ -1641,6 +1641,11 @@
   if ((ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1]))
       && ! TARGET_5200)
     return "move%.w %1,%0";
+/**** ISI Start ****/
+  if ((ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1]))
+      && ! TARGET_5200)
+    return "stop %1";
+/**** ISI End ****/
   return "move%.b %1,%0";
 }
 
--- m68k.h.orig Tue Aug 11 20:01:02 1998
+++ m68k.h      Tue Aug 18 06:59:10 1998
@@ -468,7 +468,7 @@
    if 68881 use is disabled.  */
 
 #define HARD_REGNO_MODE_OK(REGNO, MODE) \
-  (((REGNO) < 16                                       \
+  ((TARGET_5200 && ((REGNO) < 24 && (REGNO) > 7) && (MODE == QImode)) ? 0 :
((REGNO) < 16                                 \
    && !((REGNO) < 8 && (REGNO) + GET_MODE_SIZE ((MODE)) / 4 > 8))      \
    || ((REGNO) < 24                                    \
        && TARGET_68881                                  \
--- m68k.md.orig        Wed Aug 12 02:12:45 1998
+++ m68k.md     Tue Aug 18 06:58:38 1998
@@ -1027,8 +1027,8 @@
   "* return output_move_qimode (operands);")
 
 (define_insn ""
-  [(set (match_operand:QI 0 "general_operand" "=d*a<Q>,d*am")
-       (match_operand:QI 1 "general_operand" "d*ami,d*a<Q>"))]
+  [(set (match_operand:QI 0 "general_operand" "=d*<Q>,d*m")
+       (match_operand:QI 1 "general_operand" "d*mi,d*<Q>"))]
   "TARGET_5200"
   "* return output_move_qimode (operands);")
--------------------------------------------------------------------------
 

-- 

--Russ (rfellows@intellistor.com)



More information about the Gcc-bugs mailing list