/* Copyright (c) 1984 Regents of the University of California */
static char sccsid
[] = "@(#)main.c 1.6 (Berkeley) 9/20/84";
* These are the pattern tables to be loaded
struct pats
*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 */
int savedmove
; /* move to tmp reg eliminated */
register char *cp
, *lp
, *qp
;
register struct pats
*pp
, **php
;
register struct inststoptbl
*itp
, **ithp
;
if (argc
> 1 && bcmp(argv
[1], "-d", 3) == 0)
freopen(argv
[1], "r", stdin
);
freopen(argv
[2], "w", stdout
);
* Set up the hash table for the patterns.
for (tablep
= inittables
; *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
);
qp
= index(bufp
, QUOTECHAR
);
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) {
fprintf(stderr
, "inline: %s %d, %s %d, %s %d, %s %d\n",
"attempts", stats
.attempted
,
"finished", stats
.finished
,
"inhibited", stats
.lostmodified
,
"merged", stats
.savedpush
,
"nomoves", stats
.savedmove
);
* Integrate an expansion into the assembly stream
char *nextreplace
, *argv
[MAXARGS
];
int argc
, argreg
, foundarg
, mod
= 0, args
= 0;
struct oparg oparg
[MAXARGS
];
for (curptr
= bufhead
; ; ) {
nextreplace
= copyline(replace
, line
[bufhead
]);
argc
= parseline(line
[bufhead
], argv
, parsebuf
);
argreg
= nextarg(argc
, argv
, &flag
);
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
)) {
if (checkvar(argc
, argv
, flag
, oparg
[argno
].source
, mod
)) {
oparg
[argno
].reg
= argreg
;
rewrite(line
[curptr
], argc
, argv
, argreg
);
output_replace(replace
, oparg
, argno
, stdout
);
* 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
;
* 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')