ehoogerbeets@rose.waterloo.edu (Edwin Hoogerbeets) (06/10/89)
In article <14328@watdragon.waterloo.edu> ehoogerbeets@rose.waterloo.edu (Edwin Hoogerbeets) writes: % I know it is pretty gross % C code, but it occurs in GnuGrep (fish 204), and probably other Gnu % code. Speaking of Gnu code, here is another Manx bug: main() { char *list; char c; c = '8'; list = &c; c = ( list , *list ); } Causes guru 0x00000003, unaligned word or address error. (It is valid, albeit strange, C code isn't it?) Looking at the assembler: [...etc...] ; c = '8'; move.b #56,-5(a5) ; ; list = &c; lea -5(a5),a0 ; load the effective address of c into a0 move.l a0,-4(a5) ; save that address in list ; ; c = ( list , *list ); move.l -4(a5),a0 ; [redundantly] get the address again move.b (a0),d0 ; move c into d0 ext.w d0 ; sign extend it to a word [?????] move.w d0,-5(a5) ; Whoops! This is a no no! ;} The assembler produced by compiling with +L is the same, except the offensive lines are: ; c = ( list , *list ); move.l -4(a5),a0 ; [redundantly] get the address again move.b (a0),d0 ; move c into d0 ext.w d0 ; sign extend it to a word [?????] ext.l d0 ; sign extend it to a long [2*?????] move.l d0,-5(a5) ; Even better... Perhaps gnucc should be ported to the Amiga, since presumably it compiles all the gnu stuff. Edwin
addison@pollux.usc.edu (Richard Addison) (06/12/89)
In article <14395@watdragon.waterloo.edu> ehoogerbeets@rose.waterloo.edu (Edwin Hoogerbeets) writes: >In article <14328@watdragon.waterloo.edu> ehoogerbeets@rose.waterloo.edu (Edwin Hoogerbeets) writes: >% I know it is pretty gross >% C code, but it occurs in GnuGrep (fish 204), and probably other Gnu >% code. > ... > ext.w d0 ; sign extend it to a word [?????] > ... > ext.w d0 ; sign extend it to a word [?????] > ext.l d0 ; sign extend it to a long [2*?????] This brings up something that I've always found horribly stupid. I've seen C compilers use ext.w (followed by ext.l if ints are long) to test to see if a char is equal to 0, or to compare two chars, or to add, subtract two chars when the result will end up in a char. These are very clearly instances of unnecessary promotion: the additional high-order bits will never effect the lower-order bits. Caveat: I haven't been looking as closely at the code generation of the most current versions of Manx and Lattice because I have the source level debuggers. I don't know if they are still as weird about this unnecesarry code generation. Richard Addison "Jim: Life is not a dream." -- Spock, Star Trek V: The Final (?) Frontier
stan@hpcvca.CV.HP.COM (Stan Gibbs) (06/14/89)
In <14395@watdragon.waterloo.edu> ehoogerbeets@rose.waterloo.edu (Edwin Hoogerbeets) writes: >> Speaking of Gnu code, here is another Manx bug: >> >> main() >> { >> char *list; >> char c; >> >> c = '8'; >> >> list = &c; >> >> c = ( list , *list ); >> } >> >> [ ... erroneous assembler code ... ] >> >> Edwin Here's how Lattice 5.02 handles it: _main 0000-00 SECTION 00 "test.c" 00000020 BYTES ; 1: void ; 2: main() ; 3: { | 0000 4E 55 FF FA LINK A5,#FFFA ; 4: char *list; ; 5: char c; ; 6: c = '8'; | 0004 1B 7C 00 38 FF FB MOVE.B #38,FFFB(A5) ; 7: list = &c; | 000A 41 ED FF FB LEA FFFB(A5),A0 | 000E 2B 48 FF FC MOVE.L A0,FFFC(A5) ; 8: c = (list,*list); | 0012 20 6D FF FC MOVEA.L FFFC(A5),A0 | 0016 1B 50 FF FB MOVE.B (A0),FFFB(A5) ; 9: } | 001A 4E 5D UNLK A5 | 001C 4E 75 RTS Seems much more straight forward. Stan.
chk@client1.DRETOR.UUCP (C. Harald Koch) (06/16/89)
In article <17762@usc.edu> addison@pollux.usc.edu (Richard Addison) writes: >This brings up something that I've always found horribly stupid. I've seen >C compilers use ext.w (followed by ext.l if ints are long) to test to see if >a char is equal to 0, or to compare two chars, or to add, subtract two chars >when the result will end up in a char. These are very clearly instances of >unnecessary promotion: the additional high-order bits will never effect the >lower-order bits. The easiest way to handle C expression compilation is to always promote to the correct size, whether or not it is necessary. It is much more difficult to make sure that an arbitrary expression doesn't require promotion, so few compiler writers bother to implement this special case. Of course, The GNU C compiler probably checks. That monstrosity does everything short of buying you a new processor to get your code as small and efficient as possible. -- Grandpa Charnock's Law: | C. Harald Koch NTT Systems, Inc., Toronto, Ontario You never really learn | chk@gpu.utcs.utoronto.ca (long-term address) to swear until you learn | chk@zorac.dciem.dnd.ca (my current job) to drive. | chk@chkent.UUCP (my AMIGA at home)
darin@nova.laic.uucp (Darin Johnson) (06/17/89)
>Speaking of Gnu code, here is another Manx bug:
Speaking of Manx bugs in 3.6a... I don't have the example with
me (I can get it if need be) since I have taken a vacation from
that section of code so I can get a fresh perspective.
Anyway, I have a case statement in which the cases get jumpled up!
For example, "switch(DEF1)" will go to "case DEF2:". I thought my
mind was playing tricks for awhile, but I generated the assembler
output, and sure enough, the jump table has 2 entries swapped out of
order.
Has anyone seen anything like this? I have tried commenting out
the rest of the cases, but even with just 2 cases, it gets it wrong.
I really would hate having to put in a gob of IF's.
Darin Johnson (leadsv!laic!darin@pyramid.pyramid.com)
We now return you to your regularly scheduled program.