Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83 (MC840302); site ttds.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!godot!harvard!seismo!mcvax!enea!ttds!arndt From: arndt@ttds.UUCP (Arndt Jonasson) Newsgroups: net.lang.c Subject: Re: String copy idiom. [lots of PDP-10 code]. Message-ID: <865@ttds.UUCP> Date: Mon, 18-Mar-85 00:02:17 EST Article-I.D.: ttds.865 Posted: Mon Mar 18 00:02:17 1985 Date-Received: Wed, 20-Mar-85 04:10:01 EST References: <7044@watdaisy.UUCP> <3448@alice.UUCP> <464@petsd.UUCP> Reply-To: arndt@ttds.UUCP (Arndt Jonasson) Organization: The Royal Inst. of Techn., Stockholm Lines: 75 Summary: 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