This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
SH3 problem with switch branch tables
- To: egcs-bugs at egcs dot cygnus dot com
- Subject: SH3 problem with switch branch tables
- From: AArnold at ELSA dot de
- Date: Thu, 25 Mar 1999 11:34:34 +0100
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