String copy idiom. [lots of PDP-10 code].
Arndt Jonasson
arndt at ttds.UUCP
Mon Mar 18 15:02:17 AEST 1985
In article <464 at petsd.UUCP> joe at petsd.UUCP (Joseph M. Orost) writes:
>In article <3448 at alice.UUCP> ark at 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
More information about the Comp.lang.c
mailing list