arndt@ttds.UUCP (Arndt Jonasson) (03/18/85)
In article <464@petsd.UUCP> joe@petsd.UUCP (Joseph M. Orost) writes: >In article <3448@alice.UUCP> ark@alice.UUCP (Andrew Koenig) writes: > >If s and t are char pointers in registers, > > > > while (*s++ = *t++) ; > > > >generates the best code I could possibly imagine. > > > > while ((*s = *t) != '\0') {s++; t++;} > > > >is considerably worse. Try it with register variables on your compiler. > >Ok, I did. The second sequence generates less code than the first sequence >on our machine (Perkin-Elmer). This is due to the fact that our machine >doesn't support auto-increment in hardware. The C compiler has to "fake" it. The Sargasso C compiler, running on a PDP-10, also generates worse code for the first example (in fact, lousy code), while the second example gives a fairly good result. while (*s++ = *t++) ; %2: movei 4,1 adjbp 4,2 ; increment bytepointer s by 1. exch 4,2 movei 5,1 adjbp 5,3 ; increment bytepointer t by 1. exch 5,3 ldb 6,5 ; get the character from source string. dpb 6,4 ; deposit it into the destination string. skipe 6 ; is it NULL? jrst %2 ; no, loop back. ; yes. while ((*s = *t) != '\0') {s++; t++;} %5: ldb 4,3 ; get source byte. dpb 4,2 ; deposit into destination. skipn 4 ; nonzero? jrst %4 ; no, exit loop. ibp 2 ; increment byte pointer s. ibp 3 ; increment byte pointer t. jrst %5 ; loop. %4: The second version could be optimized by replacing "skipn 4 ? jrst %4" with "jumpe 4,%4". The first version's method of incrementing a byte pointer is quite incredible; three instructions to perform the same thing that an "ibp" (increment byte pointer) does, because the increment should be done after the fetch ( *(++s) would compile far more efficently). Remark on byte pointers. The PDP-10 is not byte oriented, but word (36 bits) oriented. Characters are 7-bit bytes, packed five into one word, leaving the last bit free. A byte pointer is an entity used to access bytes; they can be incremented, loaded from and deposited into. ADJBP is a kludge that increments a byte pointer by any amount. The increment can be combined with the deposit or load, meaning autoincrement on byte pointers is possible. Finally, the way this really should be done: %1: ildb 1,t ; increment and load byte. idpb 1,s ; increment and deposit byte. jumpn 1,%1 ; jump if nonzero. The Sargasso-C compiler, however, uses byte pointers in a nonstandard way, letting them point past the current character instead of before, so this last example is incompatible to the others. Arndt Jonasson UUCP: {decvax|philabs}!mcvax!enea!ttds!arndt