🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: net.lang.pascal
2 messages
2 total messages Started by Karl Berry. Thu, 11 Jul 1985 16:10
Otherwise in Berkeley Pascal.
#190
Author: Karl Berry.
Date: Thu, 11 Jul 1985 16:10
10 lines
1100 bytes
Although it is true that pc does not have an otherwise clause, pxp, when
given the -O option, will translate the case statements appropriately. [I
think the keyword in Pascal is `others:' to get it to do this.] This is what
the TeX distribution does, and it works fine. If it works for TeX, it'll
work for almost anything.
   I think this applies to both 4.1 and 4.2 bsd, but maybe just 4.2.
   The -O option is undocumented, of course. [Like having to use -J for long
jumps to work correctly.]

karl@dartmouth.csnet                 dartvax!karl
Re: Otherwise in Berkeley Pascal.
#191
Author: Chris Torek
Date: Fri, 12 Jul 1985 04:15
331 lines
8272 bytes
I *had* forgotten about that (blush).  However, I would like to
point out that we observed a 15% speed increase in TeX when compiling
"others" directly (without using pxp to hack cases).  That's not
insignificant....

(I squeezed an additional 15% out of it by using a post-optimizer
optimizer hack, that fixed up things like

	addl2	$30000,r0
	ashl	$2,r0,r0
	addl2	$_mem,r0
	addl2	$2,r0

turning them into

	moval	120002[r0],r0

Sequences like this are very common in code produced by pc that uses
arrays of records whose lowest subscript is negative; TeX happens to
use such arrays for pseudo-dynamic memory.  Replacing 4 instructions
with 1 has a pretty significant effect, especially when it can be
done in the memory allocator....)

[Heck, here's the code, if anyone wants to play with it.]

#ifndef lint
static char rcsid[] = "$Header$";
#endif

/*
 * fiddle - fiddle with assembly code (play peephole optimizer).
 * Depends heavily on the output format of /lib/c2.
 *
 * Date: sometime in early 1985.
 * Author: Chris Torek.
 *
 * This code is public domain, not that many would want it in its
 * present state.  You may redistribute it freely so long as the
 * author notice remains intact.
 */

#include <stdio.h>
#include <ctype.h>

char inbuf[BUFSIZ];

main () {
    register char *p, *bufp;

    while (fgets (inbuf, sizeof inbuf, stdin)) {
retry:
	p = bufp = inbuf;
	while (*p)
	    if (*p++ == ':')
		bufp = p;
	p = bufp;
	if (p > inbuf) {
	    register int c = *p;

	    *p = 0;
	    fputs (inbuf, stdout);
	    *p = c;
	}
	if (*p++ == 'a' && *p++ == 'd' && *p++ == 'd' &&
		*p++ == 'l' && *p++ == '2' && *p++ == '\t') {
	/* stuff depending on "addl2\t" */
	    if (try1 (p))
		goto retry;
	    if (try2 (p))
		goto retry;
	}
	p = bufp;
	if (*p++ == 'a' && *p++ == 's' && *p++ == 'h' &&
		*p++ == 'l' && *p++ == '\t' && *p++ == '$' &&
		*p++ == '2' && *p++ == ',' && *p++ == 'r') {
	/* stuff depending on "ashl\t$2,r" */
	    if (try3 ())
		goto retry;
	}
	fputs (bufp, stdout);
    }
    exit (0);
}

char *
getreg (p, ar)
register char *p;
int *ar;
{
    register int r;

    r = *p++ - '0';
    if (r == 1 && isdigit (*p))
	r = 10 + *p++ - '0';
    *ar = r;
    return p;
}

char *
getconst (p, ac)
register char *p;
int *ac;
{
    register int r;

    if (!isdigit (*p))
	return 0;
    r = *p++ - '0';
    while (isdigit (*p))
	r = r * 10 + *p++ - '0';
    *ac = r;
    return p;
}

/*
 * Try to convert
 *
 *		addl2	$const,rX \
 *		ashl	$2,rX,rX   >	moval	y+4*const[rX],rX
 *		addl2	$y,rX,rX  /
 *
 *		addl2	$const,rX \
 *		ashl	$2,rX,rX  --	moval	4*const[rX],rX
 *
 * return 0 iff didn't do anything at all
 */
try1 (p)
register char *p;
{
    register int    n,
                    r;
    int     n2,
	    r2;

    if (*p++ != '$')
	return 0;
    n = 0;
    while (isdigit (*p))
	n = n * 10 + *p++ - '0';
    if (*p++ != ',' || *p++ != 'r' || !isdigit (*p))
	return 0;
    r = *p++ - '0';
    if (r == 1 && isdigit (*p))
	r = 10 + *p++ - '0';
    if (*p != '\n') {		/* shouldn't happen */
	fprintf (stderr, "\n? left over: %s\n", p);
	return 0;
    }
    /*
     * About to be committed...
     */
    if (fgets (inbuf, sizeof inbuf, stdin) == NULL) {
e_o_f:
	inbuf[0] = 0;
give_up: 
	printf ("addl2\t$%d,r%d\n", n, r);
	return 1;
    }
    /*
     * addl2 $c1,rX \
     * addl2 $c2,rX -- addl2 $c1+c2,rX
     */
more_adds:
    if (inbuf[0] == 'a' && inbuf[1] == 'd' && inbuf[2] == 'd' &&
	    inbuf[3] == 'l' && inbuf[4] == '2' && inbuf[5] == '\t' &&
	    inbuf[6] == '$') {
	p = &inbuf[7];
	p = getconst (p, &n2);
	if (p == 0 || *p++ != ',' || *p++ != 'r')
	    goto give_up;
	p = getreg (p, &r2);
	if (r2 != r || *p != '\n')
	    goto give_up;
	n += n2;		/* collapse the constants */
	if (fgets (inbuf, sizeof inbuf, stdin) == NULL)
	    goto e_o_f;
	goto more_adds;
    }
    if (inbuf[0] != 'a' || inbuf[1] != 's' || inbuf[2] != 'h' ||
	    inbuf[3] != 'l' || inbuf[4] != '\t' || inbuf[5] != '$' ||
	    inbuf[6] != '2' || inbuf[7] != ',' || inbuf[8] != 'r')
	goto give_up;
    p = &inbuf[9];
    p = getreg (p, &r2);
    if (r2 != r || *p++ != ',' || *p++ != 'r')
	goto give_up;
    p = getreg (p, &r2);
    if (r2 != r || *p != '\n')
	goto give_up;
    putc ('#', stderr);
    (void) fflush (stderr);
    /*
     * One more trick: if next line is another "addl2 $y,rX", we can
     * use the instruction "moval $const*4+(y),rX".
     */
    if (fgets (inbuf, sizeof inbuf, stdin) == NULL) {
	inbuf[0] = 0;
just_one:
	printf ("moval\t%d[r%d],r%d\n", n << 2, r, r);
	return 1;
    }
    if (inbuf[0] == 'a' && inbuf[1] == 'd' && inbuf[2] == 'd' &&
	    inbuf[3] == 'l' && inbuf[4] == '2' && inbuf[5] == '\t' &&
	    inbuf[6] == '$') {
	char *end_of_y;

	p = &inbuf[7];
	while (*p != ',')
	    p++;
	end_of_y = p;
	p++;
	if (*p++ != 'r')
	    goto just_one;
	p = getreg (p, &r2);
	if (r2 != r || *p != '\n')
	    goto just_one;
	/* bingo! */
	putc ('!', stderr);
	(void) fflush (stderr);
	*end_of_y = 0;
	printf ("moval\t%s+%d[r%d],r%d\n", &inbuf[7], n << 2, r, r);
	if (fgets (inbuf, sizeof inbuf, stdin) == NULL)
	    inbuf[0] = 0;
	return 1;
    }
    goto just_one;
}

/*
 * Try to convert:
 *
 *		addl2	rX,rX \
 *		addl2	$y,rX --	movaw	y[rX],rX
 */
try2 (p)
register char *p;
{
    int     r1,
            r2;
    char   *end_of_y;

    if (*p++ != 'r')
	return 0;
    p = getreg (p, &r1);
    if (*p++ != ',' || *p++ != 'r')
	return 0;
    p = getreg (p, &r2);
    if (*p != '\n' || r1 != r2)
	return 0;
    if (fgets (inbuf, sizeof inbuf, stdin) == NULL) {
	inbuf[0] = 0;
give_up:
	printf ("addl2\tr%d,r%d\n", r1, r1);
	return 1;
    }
    if (inbuf[0] != 'a' || inbuf[1] != 'd' || inbuf[2] != 'd' ||
	    inbuf[3] != 'l' || inbuf[4] != '2' || inbuf[5] != '\t' ||
	    inbuf[6] != '$')
	goto give_up;
    p = &inbuf[7];
    while (*p != ',')
	p++;
    end_of_y = p;
    p++;
    if (*p++ != 'r')
	goto give_up;
    p = getreg (p, &r2);
    if (*p != '\n' || r1 != r2)
	goto give_up;
 /* got it */
    putc ('>', stderr);
    (void) fflush (stderr);
    *end_of_y = 0;
    printf ("movaw\t%s[r%d],r%d\n", &inbuf[7], r1, r1);
    if (fgets (inbuf, sizeof inbuf, stdin) == NULL)
	inbuf[0] = 0;
    return 1;
}

/*
 * Try to convert:
 *
 *		ashl	$2,rX,rX \
 *		addl2	$y,rX    --	moval	y[rX],rX
 */
try3 (p)
register char *p;
{
    int     r1,
            r2;
    char   *end_of_y;

    p = getreg (&inbuf[9], &r1);
    if (*p++ != ',' || *p++ != 'r')
	return 0;
    p = getreg (p, &r2);
    if (*p != '\n' || r1 != r2)
	return 0;
    if (fgets (inbuf, sizeof inbuf, stdin) == NULL) {
	inbuf[0] = 0;
give_up:
	printf ("ashl\t$2,r%d,r%d\n", r1, r1);
	return 1;
    }
    if (inbuf[0] != 'a' || inbuf[1] != 'd' || inbuf[2] != 'd' ||
	    inbuf[3] != 'l' || inbuf[4] != '2' || inbuf[5] != '\t' ||
	    inbuf[6] != '$')
	goto give_up;
    p = &inbuf[7];
    while (*p != ',')
	p++;
    end_of_y = p;
    p++;
    if (*p++ != 'r')
	goto give_up;
    p = getreg (p, &r2);
    if (*p != '\n' || r1 != r2)
	goto give_up;
 /* got it */
    putc ('-', stderr);
    (void) fflush (stderr);
    *end_of_y = 0;
    printf ("moval\t%s[r%d],r%d\n", &inbuf[7], r1, r1);
    if (fgets (inbuf, sizeof inbuf, stdin) == NULL)
	inbuf[0] = 0;
    return 1;
}
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads