jlilien@sdcrdcf.UUCP (Joel Lilienkamp) (02/22/84)
I worked on the MIT 68K C Compiler when I was at MIT Lincoln Laboratory. The version of the compiler I have may be slightly out of date, although I suspect that the fix I list here would not have to be changed much. The bug in the compiler can be fixed by adding one additional entry in table.c. The offending entry in the table is near the beginning, and looks something like this. ASSIGN, INAREG|FOREFF|FORCC, EAA, TSCALAR|TFLOAT, EA, TSCALAR|TFLOAT, 0, RLEFT|RRIGHT|RESCC, "\tmovZB\tAR,AL\t;\n", The bug can be fixed by adding the following entry immediately before it. ASSIGN, INAREG|FOREFF|FORCC, EAA, TCHAR, SBREG|STBREG, TCHAR, NAREG|NASR, RLEFT|RRIGHT|RESCC, "\tmovl\tAR,A1\n\tmovZB\tA1,AL\t;\n", Purists may want to change the EA in the third row of the original entry to EAA, but since the table is sorted linearly, it should make little difference. Do your own thing. While this fixes the example problem, I have not tested throughly, nor have I looked for bizarre side effects. I only hacked around for a half hour or so. Joel
smk@axiom.UUCP (Steven M. Kramer) (02/24/84)
> Purists may want to change the EA in the third row of the original entry > to EAA, but since the table is sorted linearly, it should make little > difference. Do your own thing. > > While this fixes the example problem, I have not tested throughly, nor > have I looked for bizarre side effects. I only hacked around for a half > hour or so. > Joel Not exactly correct. Your table entry is exactly what is needed to resolve the address to byte problem, but the latter suggestion noted above is wrong (and don't get me wrong, it was easy to test the proposed fix out and I'm MUCH more grateful for the fix than disheartened by the above). The suggestion to change EA to EAA is wrong, because then there would be no table entry for normal assigments from address registers to shorts or longs. You have to keep the EA in rather than EAA and depend on the ordering of the 2 entries to resolve the problem, whereby your new table entry catches the byte problem and lets all the others drop through. Note that for bytes, one extra movl instruction is generated (and I guess there is a more optimal way to do this), but from what I see, the times this occurs is minimal and optimizations efforts are better served elsewhere). While on this vein, has anyone fixed this code found in code.c so that the jump table is not hardwired to be right after the code (messing up later optimization efforts on placing the table)? Note my solution was to ifdef out the bad code, but that's definitely not too hot. Also note my efforts to begin a fix. I don't have the time to monkey with this, so I'd appreciate comments from those of you who have. ------------------------------------------------- genswitch(p,n) register struct sw *p;{ /* p points to an array of structures, each consisting of a constant value and a label. The first is >=0 if there is a default label; its value is the label number The entries p[1] to p[n] are the nontrivial cases */ register i; register CONSZ j, range; register dlab, swlab; range = p[n].sval-p[1].sval; #ifdef MAKES_BAD_CODE if( range>0 && range <= 3*n && n>=4 ){ /* implement a direct switch */ dlab = p->slab >= 0 ? p->slab : getlab(); if( p[1].sval ){ printf( " subl #" ); printf( CONFMT, p[1].sval ); printf( ",.d0\n" ); } /* note that this is a cl; it thus checks for numbers below range as well as out of range. */ printf( " cmpl #%ld,.d0\n", range ); printf( " bhi .L%d\n", dlab ); printf( " addw .d0,.d0\n" ); #ifdef PORT68 /* * The compiler produces code hardwiring the table to * be right after this code, but the optimizer moves * it to wherever. We make the movw a bit more relative * to allow for later movement of the jump table. * Note, we need to get the label here (used for the * relative jump) rather than below. THIS IS WRONG AS IT IS, SO DON'T un indef * Steve Kramer 2/20/84 */ swlab = getlab(); printf( " movw .d0,.a0\n" ); printf( " addw .a0,.a0\n" ); printf( " movw .a0@(.L%d),.a0\n" ); printf( " jmp .pc@(2,.a0:w)\n" ); #else printf( " movw .pc@(6,.d0:w),.d0\n" ); printf( " jmp .pc@(2,.d0:w)\n" ); #endif /* output table */ #ifdef PORT68 /* * In the bug fix right above, the label has already been * obtained. * Steve Kramer 2/20/84 */ printf( ".L%d = .\n", swlab); #else printf( ".L%d = .\n", swlab=getlab() ); #endif for( i=1,j=p[1].sval; i<=n; ++j ){ printf( " .word .L%d-.L%d\n", ( j == p[i].sval ) ? p[i++].slab : dlab, swlab ); } if( p->slab< 0 ) deflab( dlab ); return; } #endif genbinary(p,1,n,0); } -- --steve kramer {allegra,genrad,ihnp4,utzoo,philabs,uw-beaver}!linus!axiom!smk (UUCP) linus!axiom!smk@mitre-bedford (MIL)