Thread View: net.lang.pascal
2 messages
2 total messages
Started by Karl Berry.
Thu, 11 Jul 1985 16:10
Otherwise in Berkeley Pascal.
Author: Karl Berry.
Date: Thu, 11 Jul 1985 16:10
Date: Thu, 11 Jul 1985 16:10
10 lines
1100 bytes
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.
Author: Chris Torek
Date: Fri, 12 Jul 1985 04:15
Date: Fri, 12 Jul 1985 04:15
331 lines
8272 bytes
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