/* * Aic7xxx SCSI host adapter firmware assembler * * Copyright (c) 1997, 1998, 2000, 2001 Justin T. Gibbs. * Copyright (c) 2001, 2002 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * substantially similar to the "NO WARRANTY" disclaimer below * ("Disclaimer") and any redistribution must be conditioned upon * including a substantially similar Disclaimer requirement for further * binary redistribution. * 3. Neither the names of the above-listed copyright holders nor the names * of any contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#23 $ * * $FreeBSD$
*/ #include <sys/types.h> #include <sys/mman.h>
/* Process outmost scope */
process_scope(SLIST_FIRST(&scope_stack)); /* * Decend the tree of scopes and insert/emit * patches as appropriate. We perform a depth first * traversal, recursively handling each scope.
*/ /* start at the root scope */
dump_scope(SLIST_FIRST(&scope_stack));
/* Patch up forward jump addresses */
back_patch();
if (ofile != NULL)
output_code(); if (regfile != NULL)
symtable_dump(regfile, regdiagfile); if (listfile != NULL)
output_listing(inputfilename);
}
instrcount = 0;
fprintf(ofile, "/*\n" " * DO NOT EDIT - This file is automatically generated\n" " * from the following source files:\n" " *\n" "%s */\n", versions);
void
output_listing(char *ifilename)
{ char buf[1024];
FILE *ifile; struct instruction *cur_instr;
patch_t *cur_patch;
symbol_node_t *cur_func; int *func_values; int instrcount; int instrptr; int line; int func_count; int skip_addr;
/* Now output the listing */
cur_patch = STAILQ_FIRST(&patches); for (cur_instr = STAILQ_FIRST(&seq_program);
cur_instr != NULL;
cur_instr = STAILQ_NEXT(cur_instr, links), instrcount++) {
if (check_patch(&cur_patch, instrcount,
&skip_addr, func_values) == 0) { /* Don't count this instruction as it is in a patch * that was removed.
*/ continue;
}
while (line < cur_instr->srcline) {
fgets(buf, sizeof(buf), ifile);
fprintf(listfile, " \t%s", buf);
line++;
}
fprintf(listfile, "%04x %02x%02x%02x%02x", instrptr, #ifdef __LITTLE_ENDIAN
cur_instr->format.bytes[0],
cur_instr->format.bytes[1],
cur_instr->format.bytes[2],
cur_instr->format.bytes[3]); #else
cur_instr->format.bytes[3],
cur_instr->format.bytes[2],
cur_instr->format.bytes[1],
cur_instr->format.bytes[0]); #endif /* * Macro expansions can cause several instructions * to be output for a single source line. Only * advance the line once in these cases.
*/ if (line == cur_instr->srcline) {
fgets(buf, sizeof(buf), ifile);
fprintf(listfile, "\t%s", buf);
line++;
} else {
fprintf(listfile, "\n");
}
instrptr++;
} /* Dump the remainder of the file */ while(fgets(buf, sizeof(buf), ifile) != NULL)
fprintf(listfile, " %s", buf);
fclose(ifile);
}
staticint
check_patch(patch_t **start_patch, int start_instr, int *skip_addr, int *func_vals)
{
patch_t *cur_patch;
cur_patch = *start_patch;
while (cur_patch != NULL && start_instr == cur_patch->begin) { if (func_vals[cur_patch->patch_func] == 0) { int skip;
/* Start rejecting code */
*skip_addr = start_instr + cur_patch->skip_instr; for (skip = cur_patch->skip_patch;
skip > 0 && cur_patch != NULL;
skip--)
cur_patch = STAILQ_NEXT(cur_patch, links);
} else { /* Accepted this patch. Advance to the next * one and wait for our intruction pointer to * hit this point.
*/
cur_patch = STAILQ_NEXT(cur_patch, links);
}
}
*start_patch = cur_patch; if (start_instr < *skip_addr) /* Still skipping */ return (0);
return (1);
}
/* * Print out error information if appropriate, and clean up before * terminating the program.
*/ void
stop(constchar *string, int err_code)
{ if (string != NULL) {
fprintf(stderr, "%s: ", appname); if (yyfilename != NULL) {
fprintf(stderr, "Stopped at file %s, line %d - ",
yyfilename, yylineno);
}
fprintf(stderr, "%s\n", string);
}
if (ofile != NULL) {
fclose(ofile); if (err_code != 0) {
fprintf(stderr, "%s: Removing %s due to error\n",
appname, ofilename);
unlink(ofilename);
}
}
if (regfile != NULL) {
fclose(regfile); if (err_code != 0) {
fprintf(stderr, "%s: Removing %s due to error\n",
appname, regfilename);
unlink(regfilename);
}
}
if (listfile != NULL) {
fclose(listfile); if (err_code != 0) {
fprintf(stderr, "%s: Removing %s due to error\n",
appname, listfilename);
unlink(listfilename);
}
}
new_scope = (scope_t *)malloc(sizeof(scope_t)); if (new_scope == NULL)
stop("Unable to malloc scope object", EX_SOFTWARE);
memset(new_scope, 0, sizeof(*new_scope));
TAILQ_INIT(&new_scope->inner_scope);
if (SLIST_FIRST(&scope_stack) != NULL) {
TAILQ_INSERT_TAIL(&SLIST_FIRST(&scope_stack)->inner_scope,
new_scope, scope_links);
} /* This patch is now the current scope */
SLIST_INSERT_HEAD(&scope_stack, new_scope, scope_stack_links); return new_scope;
}
void
process_scope(scope_t *scope)
{ /* * We are "leaving" this scope. We should now have * enough information to process the lists of scopes * we encapsulate.
*/
scope_t *cur_scope;
u_int skip_patch_count;
u_int skip_instr_count;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.