[net.lang.c] String copy idiom. [lots of PDP-10 code].

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