[comp.bugs.4bsd] 4.3 & derivative: uVAXII matchc broken

mouse@mcgill-vision.UUCP (05/28/87)

Index: sys/vax/emulate.s, 4.3BSD and derivatives, including mtXinu 4.3+NFS

Description:

	The code to emulate the matchc instruction on the MicroVAX-II
	is quite broken.

	According to the Gray Book (the VAX Architecture Reference
	Manual), the matchc instruction is supposed to leave the
	registers set as follows:

		r0 = if match occurred, 0; otherwise the number of
		     bytes in the object string.

		r1 = if match occurred, the address of one byte beyond
		     the object string; otherwise the address of the
		     object string.

		r2 = if match occurred, the number of bytes remaining
		     in the source string; otherwise 0.

		r3 = if match occurred, the address of 1 byte beyond
		     the last byte matched; otherwise the address of 1
		     byte beyond the source string.

	We have some code which depends on the value in r3.  This code
	works on our big VAXen (750 and 780), since they do in fact do
	it this way.  But on a MicroVAX-II running 4.3, it broke
	horribly because the supplied emulate.s leaves r3 pointing to
	the *beginning* of the matching substring instead of 1 byte
	past the end!

Fix:
	Go into emulate.s and replace _EMmatchc with the following
	version, which appears to work and is even commented!

	I suspect this is slower than the BSD code, but would you
	rather have fast wrong answers?  (If so, I can write an
	impressively fast sort routine for you....|-)

	Also, a lot of the string instruction emulations are very
	sloppy (that is: wrong) about the condition codes they produce.
	I have rewritten all the string instructions (not the silly
	COBOL support packed decimal &c, just the string stuff) to
	conform to the Gray Book, but most of it is untested.

	I intend to improve this by doing a fast scan for the first
	character, but that is some ways off....If you want me to keep
	you posted, send me mail.

	#define pslloc    4(sp)
	#define PSL_ALLCC 0xf
	#define PSL_Z     0x4
		.align	1
		.globl	_EMmatchc
	_EMmatchc:
	/* matchc objlen.rw,objaddr.ab,srclen.rw,srcaddr.ab */
	#define objlen r0
	#define objaddr r1
	#define srclen r2
	#define srcaddr r3
	#define temp r10
	/* Pick up the arguments */
		arguw(1,objlen)
		argl(2,objaddr)
		arguw(3,srclen)
		argl(4,srcaddr)
	/* Zero the condition codes (set PSL_Z later if appropriate) */
		savepsl
		bicl2		$PSL_ALLCC,pslloc
	/* Find the match.  Algorithm follows the gray book (pg 4-154). */
	/* Gray book names: */
	#define tmp1 objlen
	#define tmp2 objaddr
	#define tmp3 srclen
	#define tmp4 srcaddr
	#define tmp5 temp
		movl		tmp1,tmp5
	2:	tstl		tmp1
		jeql		Lmatchc_out
		cmpl		tmp3,tmp1
		jlssu		Lmatchc_out
		cmpb		(tmp2),(tmp4)+
		jneq		1f
		decl		tmp1
		incl		tmp2
		decl		tmp3
		jbr		2b
	1:	subl2		tmp5,tmp1
		subl2		tmp1,tmp2
		decl		tmp3
		addl2		tmp1,tmp3
		subl2		tmp1,tmp4
		movl		tmp5,tmp1
		jbr		2b
	Lmatchc_out:
		cmpl		tmp3,tmp1
		jgequ		1f
		addl2		tmp3,tmp4
		clrl		tmp3
	1:	/* All registers already have correct values, by choice of */
		/*  registers for the temporaries. */
	#undef tmp1
	#undef tmp2
	#undef tmp3
	#undef tmp4
	#undef tmp5
		tstl		r0
		jneq		1f
		bisl2		$PSL_Z,pslloc
	1:	return
	#undef objlen
	#undef objaddr
	#undef srclen
	#undef srcaddr
	#undef temp

					der Mouse

				(mouse@mcgill-vision.uucp)