This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


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

SH3 problem with switch branch tables





Hi,

we at ELSA use egcs to compile the firmware for an ISDN router which is Hitachi
SH3-based.
I think we stepped into a bug that occurs sometimes in the generation of branch
tables for
switch statements when SH3 instructions are enabled.  I tried to reproduce the
problem in a small
test case but had no luck since it seems to depend heavily on the address layout
of the generated
assembler code.  Since I cannot give out the full sources, all I can show here
is a small code snippet
from our project that triggered the bug.  It occurs in a small function that
mainly consists of a switch
statement with case values between 1 and 7:

static tU8 EvalLcpMru
( tU8 OpCode,
  tComChan _near* pComChan )
{ tU16 TestMru;
  tU32 fQuiet = FALSE;
  tU8 Result = EVAL_ACK;                    /* Default: Option akzeptieren  */

  switch( OpCode )                          /* Subfunktionen verwalten =>   */
  {
    case EVAL_QUT:                          /* Quiet-Mode f?r GetLastReq => */
      fQuiet = TRUE;                        /* Explizit KEIN break!!        */

    case EVAL_INS:                          /* In Config-Request eintragen  */
      TxOption.Length = 0x00;

      if( LCP_MRU_DEF != pComChan->LcpRxOpt.AktMru )
      {
        #if( OPT_NETTRACE )
          if( !fQuiet )                     /* Trace-Ausgaben anzeigen =>   */
          {
            xNetTrcAdd( &pTrcBuf, "Inserting local MRU %d\n",
                                  pComChan->LcpRxOpt.AktMru );
          }
        #endif

        TxOption.Option = LCP_MRU;
        TxOption.Length = mSizeMru( TxOption );
        TxOption.Data.LcpMru = mHost2Net16( pComChan->LcpRxOpt.AktMru );
      }

      break;

    case EVAL_REQ:                          /* In Config-Request pr?fen =>  */
      TestMru = mNet2Host16( RxOption.Data.LcpMru );

      #if( OPT_NETTRACE )
        xNetTrcAdd( &pTrcBuf, "Peer MRU %d ", TestMru );
      #endif

      if( (LCP_MRU_DEF <= TestMru)          /* Option ist OK =>             */
       && (mSizeMru( RxOption ) == RxOption.Length) )
      {
        #if( OPT_NETTRACE )
          xNetTrcAdd( &pTrcBuf, "accepted\n" );
        #endif

        pComChan->LcpTxOpt.AktMru = TestMru;/* Neue MRU merken              */
        Result = EVAL_ACK;
      }
      else                                  /* Option ist fehlerhaft =>     */
      {
        #if( OPT_NETTRACE )
          xNetTrcAdd( &pTrcBuf, "bad coded MRU option, NAK with %d\n",
LCP_MRU_DEF );
        #endif

        TxOption.Option = LCP_MRU;          /* MRU neu verhandeln           */
        TxOption.Length = mSizeMru( TxOption );
        TxOption.Data.LcpMru = mHost2Net16( LCP_MRU_DEF );
        Result = EVAL_NAK;
      }
      break;

    case EVAL_NAK:                          /* In Config-NAK pr?fen =>      */
      TestMru = mNet2Host16( RxOption.Data.LcpMru );

      #if( OPT_NETTRACE )
        xNetTrcAdd( &pTrcBuf, "Peer MRU %d %s", TestMru,
                    ( LOK_MRU_DEF >= TestMru ) ? "accepted" : "ignored" );
      #endif

      if( LOK_MRU_DEF >= TestMru )
        pComChan->LcpRxOpt.AktMru = TestMru;

      break;

    case EVAL_REJ:                          /* In Config-Reject pr?fen =>   */
      #if( OPT_NETTRACE )
        xNetTrcAdd( &pTrcBuf, "Local MRU reset to PPP default" );
      #endif

      pComChan->LcpRxOpt.AktMru = LCP_MRU_DEF;/* Option zur?cksetzen          */
      break;
  } /* switch OpCode */

  return( Result );
} /* EvalLcpMru */

(FYI: this is a part of the ISDN router's PPP stack)

We are compiling under Windows NT 4.0 with egcs 1.1b with the options

-m3 -fomit-frame-pointer -O3

We also made a test with the latest official release 1.1.2 and the problem is
still there :-(

The generated assembler code is:

 2970               _EvalLcpMru:
 2971 1a80 2F86               mov.l      r8,@-r15
 2972 1a82 2F96               mov.l      r9,@-r15
 2973 1a84 2FA6               mov.l      r10,@-r15
 2974 1a86 E200               mov  #0,r2
 2975 1a88 2FB6               mov.l      r11,@-r15
 2976 1a8a 644C               extu.b     r4,r4
 2977 1a8c 2FC6               mov.l      r12,@-r15
 2978 1a8e EB05               mov  #5,r11
 2979 1a90 4F22               sts.l      pr,@-r15
 2980 1a92 E106               mov  #6,r1
 2981 1a94 74FF               add  #-1,r4
 2982 1a96 3416               cmp/hi     r1,r4
 2983 1a98 8D2A               bt.s L1327
 2984 1a9a 6C53               mov  r5,r12
 2985 1a9c C702               mova L1300,r0
 2986 1a9e 014C               mov.b      @(r0,r4),r1
 2987 1aa0 611C               extu.b     r1,r1
 2988 1aa2 0123               braf r1
 2989 1aa4 0009               nop
 2990 1aa6 0009               .align 2
 2991               L1302:
 2992                    .align 2
 2993               L1300:
 2994 1aa8 0A                 .byte      L1289-L1302
 2995 1aa9 58                 .byte      L1292-L1302
 2996 1aaa A8                 .byte      L1295-L1302
 2997 1aab D8                 .byte      L1299-L1302
 2998 1aac E8                 .byte      L1287-L1302
 2999 1aad E8                 .byte      L1287-L1302
 3000 1aae 08                 .byte      L1288-L1302
 3001 1aaf 00                 .align 4
 3002               L1288:
 3003 1ab0 E201               mov  #1,r2
 3004               L1289:
 3005 1ab2 D93E               mov.l      L1308,r9
 3006 1ab4 9A75               mov.w      L1309,r10
 3007 1ab6 6893               mov  r9,r8
 3008 1ab8 7807               add  #7,r8
 3009 1aba E100               mov  #0,r1
 3010 1abc 2810               mov.b      r1,@r8
 3011 1abe 60C3               mov  r12,r0
 3012 1ac0 01AD               mov.w      @(r0,r10),r1
 3013 1ac2 661D               extu.w     r1,r6
 3014 1ac4 916E               mov.w      L1310,r1
 3015 1ac6 3610               cmp/eq     r1,r6
 3016 1ac8 8D62               bt.s L1287
 3017 1aca 2228               tst  r2,r2
 3018 1acc 8F06               bf.s L1329
 3019 1ace 6193               mov  r9,r1
 3020 1ad0 D537               mov.l      L1311,r5
 3021 1ad2 D038               mov.l      L1312,r0
 3022 1ad4 D438               mov.l      L1313,r4
 3023 1ad6 400B               jsr  @r0
Hitachi Super-H GAS Big Endian C:\TEMP\ccfDXI7N.s                page 61


 3024 1ad8 0009               nop
 3025 1ada 6193               mov  r9,r1
 3026               L1329:
 3027 1adc 7106               add  #6,r1
 3028 1ade E201               mov  #1,r2
 3029 1ae0 2120               mov.b      r2,@r1
 3030 1ae2 E104               mov  #4,r1
 3031 1ae4 2810               mov.b      r1,@r8
 3032 1ae6 60C3               mov  r12,r0
 3033 1ae8 6193               mov  r9,r1
 3034 1aea 7108               add  #8,r1
 3035 1aec 02AD               mov.w      @(r0,r10),r2
 3036 1aee 2121               mov.w      r2,@r1
 3037               L1327:
 3038 1af0 A050               bra  L1328
 3039 1af2 4F26               lds.l      @r15+,pr
 3040 1af4 00090009           .align 4
 3040      00090009
 3040      00090009
 3041               L1292:
 3042 1b00 D82E               mov.l      L1314,r8
 3043 1b02 DA2D               mov.l      L1313,r10
 3044 1b04 D52E               mov.l      L1315,r5
 3045 1b06 6181               mov.w      @r8,r1
 3046 1b08 DB2A               mov.l      L1312,r11
 3047 1b0a 691D               extu.w     r1,r9
 3048 1b0c 64A3               mov  r10,r4
 3049 1b0e 4B0B               jsr  @r11
 3050 1b10 6693               mov  r9,r6
 3051 1b12 9148               mov.w      L1316,r1
 3052 1b14 3916               cmp/hi     r1,r9
 3053 1b16 8F0B               bf.s L1293
 3054 1b18 78F8               add  #-8,r8
 3055 1b1a 7807               add  #7,r8
 3056 1b1c 6080               mov.b      @r8,r0
 3057 1b1e 8804               cmp/eq     #4,r0
 3058 1b20 8B06               bf   L1293
 3059 1b22 D528               mov.l      L1317,r5
 3060 1b24 4B0B               jsr  @r11
 3061 1b26 64A3               mov  r10,r4
 3062 1b28 903E               mov.w      L1318,r0
 3063 1b2a 0C95               mov.w      r9,@(r0,r12)
 3064 1b2c A030               bra  L1287
 3065 1b2e EB05               mov  #5,r11
 3066                    .align 4
 3067               L1293:
 3068 1b30 9838               mov.w      L1310,r8
 3069 1b32 64A3               mov  r10,r4
 3070 1b34 D524               mov.l      L1319,r5
 3071 1b36 4B0B               jsr  @r11
 3072 1b38 6683               mov  r8,r6
 3073 1b3a D124               mov.l      L1320,r1
 3074 1b3c E201               mov  #1,r2
 3075 1b3e 2120               mov.b      r2,@r1
 3076 1b40 71FA               add  #-6,r1
 3077 1b42 7107               add  #7,r1
 3078 1b44 E204               mov  #4,r2

Hitachi Super-H GAS Big Endian C:\TEMP\ccfDXI7N.s                page 62


 3079 1b46 2120               mov.b      r2,@r1
 3080 1b48 7101               add  #1,r1
 3081 1b4a 2181               mov.w      r8,@r1
 3082 1b4c A020               bra  L1287
 3083 1b4e EB03               mov  #3,r11
 3084                    .align 4
 3085               L1295:
 3086 1b50 D11A               mov.l      L1314,r1
 3087 1b52 6111               mov.w      @r1,r1
 3088 1b54 9829               mov.w      L1321,r8
 3089 1b56 691D               extu.w     r1,r9
 3090 1b58 D71D               mov.l      L1322,r7
 3091 1b5a 3986               cmp/hi     r8,r9
 3092 1b5c 8900               bt   L1296
 3093 1b5e D71D               mov.l      L1323,r7
 3094               L1296:
 3095 1b60 D014               mov.l      L1312,r0
 3096 1b62 D415               mov.l      L1313,r4
 3097 1b64 D51C               mov.l      L1324,r5
 3098 1b66 400B               jsr  @r0
 3099 1b68 6693               mov  r9,r6
 3100 1b6a 3986               cmp/hi     r8,r9
 3101 1b6c 8910               bt   L1287
 3102 1b6e 9018               mov.w      L1309,r0
 3103 1b70 A00E               bra  L1287
 3104 1b72 0C95               mov.w      r9,@(r0,r12)
 3105 1b74 00090009           .align 4
 3105      00090009
 3105      00090009
 3106               L1299:
 3107 1b80 D516               mov.l      L1325,r5
 3108 1b82 D00C               mov.l      L1312,r0
 3109 1b84 D40C               mov.l      L1313,r4
 3110 1b86 400B               jsr  @r0
 3111 1b88 0009               nop
 3112 1b8a 900A               mov.w      L1309,r0
 3113 1b8c 910A               mov.w      L1310,r1
 3114 1b8e 0C15               mov.w      r1,@(r0,r12)
 3115               L1287:
 3116 1b90 4F26               lds.l      @r15+,pr
 3117 1b92 0009               .align 2
 3118               L1328:
 3119 1b94 6CF6               mov.l      @r15+,r12
 3120 1b96 60B3               mov  r11,r0
 3121 1b98 6BF6               mov.l      @r15+,r11
 3122 1b9a 6AF6               mov.l      @r15+,r10
 3123 1b9c 69F6               mov.l      @r15+,r9
 3124 1b9e 000B               rts
 3125 1ba0 68F6               mov.l      @r15+,r8
 3126                    .align 1
 3127               L1309:
 3128 1ba2 05A0               .short     1440
 3129               L1310:
 3130 1ba4 05DC               .short     1500
 3131               L1316:
 3132 1ba6 05DB               .short     1499
 3133               L1318:

Hitachi Super-H GAS Big Endian C:\TEMP\ccfDXI7N.s                page 63


 3134 1ba8 05D0               .short     1488
 3135               L1321:
 3136 1baa 05E0               .short     1504
 3137               L1326:
 3138                    .align 2
 3139               L1308:
 3140 1bac 00010C00           .long      _TxOption
 3141               L1311:
 3142 1bb0 00001A00           .long      LC78
 3143               L1312:
 3144 1bb4 00000000           .long      _xNetTrcAdd
 3145               L1313:
 3146 1bb8 00010D24           .long      _pTrcBuf
 3147               L1314:
 3148 1bbc 00010B00           .long      _RxOption+8
 3149               L1315:
 3150 1bc0 00001A18           .long      LC79
 3151               L1317:
 3152 1bc4 00001344           .long      LC63
 3153               L1319:
 3154 1bc8 00001A28           .long      LC80
 3155               L1320:
 3156 1bcc 00010C06           .long      _TxOption+6
 3157               L1322:
 3158 1bd0 0000139C           .long      LC67
 3159               L1323:
 3160 1bd4 00001390           .long      LC66
 3161               L1324:
 3162 1bd8 00001A4C           .long      LC81
 3163               L1325:
 3164 1bdc 00001A5C           .long      LC82
 3165                    .align 2
 3166               LC83:
 3167 1be0 496E7365           .ascii "Inserting local MRRU %d\12\0"
 3167      7274696E
 3167      67206C6F
 3167      63616C20
 3167      4D525255
 3168 1bf9 000009             .align 2
 3169               LC84:
 3170 1bfc 50656572           .ascii "Peer MRRU %d \0"
 3170      204D5252
 3170      55202564
 3170      2000
 3171 1c0a 0009               .align 2
 3172               LC85:
 3173 1c0c 62616420           .ascii "bad coded MRRU option, NAK with %d\12\0"
 3173      636F6465
 3173      64204D52
 3173      5255206F
 3173      7074696F
 3174                    .align 2
 3175               LC86:
 3176 1c30 50656572           .ascii "Peer MRRU %d %s\0"
 3176      204D5252
 3176      55202564
 3176      20257300

Hitachi Super-H GAS Big Endian C:\TEMP\ccfDXI7N.s                page 64


 3177                    .align 2
 3178               LC87:
 3179 1c40 44697361           .ascii "Disable MRRU %d\12\0"
 3179      626C6520
 3179      4D525255
 3179      2025640A
 3179      00
 3180 1c51 00000900           .align 4
 3180      09000900
 3180      09000900
 3180      090009

The problem is the branch table at label L1300 that is part of the code
generated for the switch construct:
the offsets are computed relative to label L1302, which would be correct if
there weren't another align
statement after the braf/nop that inserts another word of code.  This way, for
example, the case value 7
leads to a target address of 0x1aa2+4+8=0x1aae, which is not L1288 as it should
be, but instead the last
entry in the branch table.  At runtime, the processor raises an invalid opcode
exception because 0x0800
is not a valid SH3 machine instruction...

We have looked at the compilation of other statements and they never have two
align statement except
when the compiler has to dump literals between the branch code and the branch
table.  So maybe the
the first '.align' is generated erroneously without other parts of the compiler
noticing it?

I know this is not a perfect bug report, but as I already said, I cannot give
out the full source.  I still hope this
gives enough information to deduce where the error might be.  We currently can
work around this bug
by not enabling SH3 instructions, so it's not absolutely urgent, however
regaining the ~10% improvement
in speed would be nice..

Yours

Alfred Arnold

ESA AG, Aachen, Germany

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