* Copyright (c) 1984, 1986 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
"@(#) Copyright (c) 1984, 1986 Regents of the University of California.\n\
static char sccsid
[] = "@(#)main.c 7.1 (Berkeley) %G%";
* These are the pattern tables to be loaded
struct pats
*vax_inittables
[] = {
struct pats
*vaxsubset_inittables
[] = {
int attempted
; /* number of expansion attempts */
int finished
; /* expansions done before end of basic block */
int lostmodified
; /* mergers inhibited by intervening mod */
int savedpush
; /* successful push/pop merger */
register struct pats
*pp
, **php
;
register struct inststoptbl
*itp
, **ithp
;
while (argc
> 0 && argv
[0][0] == '-') {
freopen(argv
[0], "r", stdin
);
freopen(argv
[1], "w", stdout
);
* Set up the hash table for the patterns.
tablep
= vaxsubset_inittables
;
for ( ; *tablep
; tablep
++) {
for (pp
= *tablep
; pp
->name
[0] != '\0'; pp
++) {
php
= &patshdr
[hash(pp
->name
, &size
)];
* Set up the hash table for the instruction stop table.
for (itp
= inststoptable
; itp
->name
[0] != '\0'; itp
++) {
ithp
= &inststoptblhdr
[hash(itp
->name
, &size
)];
* check each line and replace as appropriate
while (fgets(bufp
, MAXLINELEN
, stdin
)) {
lp
= index(bufp
, LABELCHAR
);
for (cp
= bufp
; cp
< lp
; cp
++)
for (cp
= bufp
; isspace(*cp
); cp
++)
if ((cp
= doreplaceon(cp
)) == 0) {
for (pp
= patshdr
[hash(cp
, &size
)]; pp
; pp
= pp
->next
) {
if (pp
->size
== size
&& bcmp(pp
->name
, cp
, size
) == 0) {
if (argcounterr(pp
->args
, countargs(bufp
), pp
->name
)) {
fprintf(stderr
, "%s: %s %d, %s %d, %s %d, %s %d\n",
"attempts", stats
.attempted
,
"finished", stats
.finished
,
"inhibited", stats
.lostmodified
,
"merged", stats
.savedpush
);
* Integrate an expansion into the assembly stream
char *nextreplace
, *argv
[MAXARGS
];
int argc
, argreg
, foundarg
, mod
= 0, args
= 0;
for (curptr
= bufhead
; ; ) {
nextreplace
= copyline(replace
, line
[bufhead
]);
argc
= parseline(line
[bufhead
], argv
, parsebuf
);
argreg
= nextarg(argc
, argv
);
for (foundarg
= 0; curptr
!= buftail
; ) {
argc
= parseline(line
[curptr
], argv
, parsebuf
);
if (isendofblock(argc
, argv
))
if (foundarg
= ispusharg(argc
, argv
))
mod
|= 1 << modifies(argc
, argv
);
if (mod
& (1 << argreg
)) {
rewrite(line
[curptr
], argc
, argv
, argreg
);
* Parse a line of assembly language into opcode and arguments.
parseline(linep
, argv
, linebuf
)
register char *bufp
= linebuf
, *cp
= linep
;
if (argc
== MAXARGS
- 1) {
fprintf(stderr
, "instruction too long->%s", linep
);
while (!isspace(*cp
) && *cp
!= ARGSEPCHAR
&& *cp
!= COMMENTCHAR
)
* Check for instructions that end a basic block.
register struct inststoptbl
*itp
;
for (itp
= inststoptblhdr
[hash(argv
[0], &size
)]; itp
; itp
= itp
->next
)
if (itp
->size
== size
&& bcmp(argv
[0], itp
->name
, size
) == 0)
* Copy a newline terminated string.
* Return pointer to character following last character copied.
register char *from
, *to
;
* Check for a disparity between the number of arguments a function
* is called with and the number which we expect to see.
* If the error is unrecoverable, return 1, otherwise 0.
argcounterr(args
, callargs
, name
)
char namebuf
[MAXLINELEN
];
cp
= strcpy(namebuf
, name
);
while (*cp
!= '\0' && *cp
!= '\n')
"%s: error: arg count mismatch, %d != %d for '%s' at line %d\n",
whoami
, callargs
, args
, namebuf
, lineno
);
"%s: warning: can't verify arg count for '%s' at line %d\n",
whoami
, namebuf
, lineno
);
* open space for next line in the queue
if (bufhead
== buftail
) {
fputs(line
[buftail
], stdout
);
* empty the queue by printing out all its lines.
while (buftail
!= bufhead
) {
fputs(line
[buftail
], stdout
);
* Compute the hash of a string.
* Return the hash and the size of the item hashed
while (*cp1
&& *cp1
!= '\n')