44 #include <sys/types.h>
59 #include <machine/endian.h>
66 typedef struct patch {
76 static
void usage(
void);
77 static
void back_patch(
void);
78 static
void output_code(
void);
82 static
int check_patch(
patch_t **start_patch,
int start_instr,
83 int *skip_addr,
int *func_vals);
86 int includes_search_curdir;
88 char *stock_include_file;
95 char *regdiagfilename;
102 struct scope_list scope_stack;
103 symlist_t patch_functions;
106 extern int yy_flex_debug;
107 extern int mm_flex_debug;
136 includes_search_curdir = 1;
146 while ((ch = getopt(argc, argv,
"d:i:l:n:o:p:r:I:")) != -1) {
150 if (
strcmp(optarg,
"s") == 0) {
153 }
else if (
strcmp(optarg,
"p") == 0) {
157 fprintf(stderr,
"%s: -d Requires either an "
158 "'s' or 'p' argument\n", appname);
162 stop(
"-d: Assembler not built with debugging "
163 "information", EX_SOFTWARE);
167 stock_include_file = optarg;
171 if ((listfile = fopen(optarg,
"w")) ==
NULL) {
175 listfilename = optarg;
179 if (
strcmp(optarg,
"ostdinc")) {
180 fprintf(stderr,
"%s: Unknown option -%c%s\n",
181 appname, ch, optarg);
187 if ((ofile = fopen(optarg,
"w")) ==
NULL) {
195 if ((regdiagfile = fopen(optarg,
"w")) ==
NULL) {
199 regdiagfilename = optarg;
202 if ((regfile = fopen(optarg,
"w")) ==
NULL) {
206 regfilename = optarg;
212 if (
strcmp(optarg,
"-") == 0) {
213 if (includes_search_curdir == 0) {
214 fprintf(stderr,
"%s: Warning - '-I-' "
215 "specified multiple "
218 includes_search_curdir = 0;
232 if (include_dir ==
NULL) {
257 fprintf(stderr,
"%s: No input file specifiled\n", appname);
262 if (regdiagfile !=
NULL
263 && (regfile ==
NULL || stock_include_file ==
NULL)) {
265 "%s: The -p option requires the -r and -i options.\n",
271 inputfilename = *argv;
277 stop(
"Unterminated conditional expression", EX_DATAERR);
298 if (listfile !=
NULL)
312 "usage: %-16s [-nostdinc] [-I-] [-I directory] [-o output_file]\n"
313 " [-r register_output_file [-p register_diag_file -i includefile]]\n"
314 " [-l program_list_file]\n"
315 " input_file\n", appname);
335 "Undefined label %s",
337 stop(buf, EX_DATAERR);
342 address += cur_instr->
patch_label->info.linfo->address;
360 " * DO NOT EDIT - This file is automatically generated\n"
361 " * from the following source files:\n"
365 fprintf(ofile,
"static const uint8_t seqprog[] = {\n");
370 fprintf(ofile,
"%s\t0x%02x, 0x%02x, 0x%02x, 0x%02x",
387 if (patch_arg_list ==
NULL)
388 stop(
"Patch argument list not defined",
395 "typedef int %spatch_func_t (%s);\n",
prefix, patch_arg_list);
401 "static %spatch_func_t %spatch%d_func;\n"
404 "%spatch%d_func(%s)\n"
418 "static const struct patch {\n"
419 " %spatch_func_t *patch_func;\n"
420 " uint32_t begin :10,\n"
423 "} patches[] = {\n",
prefix);
428 fprintf(ofile,
"%s\t{ %spatch%d_func, %d, %d, %d }",
431 cur_patch->patch_func, cur_patch->begin,
432 cur_patch->skip_instr, cur_patch->skip_patch);
438 "static const struct cs {\n"
441 "} critical_sections[] = {\n");
446 fprintf(ofile,
"%s\t{ %d, %d }",
454 "static const int num_critical_sections = sizeof(critical_sections)\n"
455 " / sizeof(*critical_sections);\n");
457 fprintf(stderr,
"%s: %d instructions used\n", appname, instrcount);
475 while (cur_scope !=
NULL) {
477 dump_scope(cur_scope);
479 cur_scope =
TAILQ_NEXT(cur_scope, scope_links);
494 pinfo = &scope->
patches[patch];
502 if (new_patch ==
NULL)
503 stop(
"Could not malloc patch structure", EX_OSERR);
505 memset(new_patch, 0,
sizeof(*new_patch));
508 new_patch->patch_func = scope->
func_num;
511 new_patch->patch_func = 0;
538 if ((ifile = fopen(ifilename,
"r")) ==
NULL) {
546 for (func_count = 0, cur_func =
SLIST_FIRST(&patch_functions);
552 if (func_count != 0) {
553 func_values = (
int *)
malloc(func_count *
sizeof(
int));
555 if (func_values ==
NULL)
556 stop(
"Could not malloc", EX_OSERR);
569 cur_func =
SLIST_NEXT(cur_func, links), func_count--) {
574 "Enter the return value for "
575 "this expression[T/F]:");
583 func_values[func_count] = 1;
585 }
else if (input ==
'F') {
586 func_values[func_count] = 0;
590 if (isatty(fileno(stdin)) == 0)
593 fprintf(stdout,
"\nThanks!\n");
600 cur_instr =
STAILQ_NEXT(cur_instr, links), instrcount++) {
602 if (check_patch(&cur_patch, instrcount,
603 &skip_addr, func_values) == 0) {
611 fgets(buf,
sizeof(buf), ifile);
612 fprintf(listfile,
" \t%s", buf);
615 fprintf(listfile,
"%04x %02x%02x%02x%02x", instrptr,
632 if (line == cur_instr->
srcline) {
633 fgets(buf,
sizeof(buf), ifile);
634 fprintf(listfile,
"\t%s", buf);
642 while(fgets(buf,
sizeof(buf), ifile) !=
NULL)
649 check_patch(
patch_t **start_patch,
int start_instr,
650 int *skip_addr,
int *func_vals)
654 cur_patch = *start_patch;
656 while (cur_patch !=
NULL && start_instr == cur_patch->begin) {
657 if (func_vals[cur_patch->patch_func] == 0) {
661 *skip_addr = start_instr + cur_patch->skip_instr;
662 for (skip = cur_patch->skip_patch;
663 skip > 0 && cur_patch !=
NULL;
675 *start_patch = cur_patch;
676 if (start_instr < *skip_addr)
690 if (
string !=
NULL) {
691 fprintf(stderr,
"%s: ", appname);
693 fprintf(stderr,
"Stopped at file %s, line %d - ",
696 fprintf(stderr,
"%s\n",
string);
702 fprintf(stderr,
"%s: Removing %s due to error\n",
708 if (regfile !=
NULL) {
711 fprintf(stderr,
"%s: Removing %s due to error\n",
712 appname, regfilename);
717 if (listfile !=
NULL) {
720 fprintf(stderr,
"%s: Removing %s due to error\n",
721 appname, listfilename);
722 unlink(listfilename);
738 if (new_instr ==
NULL)
739 stop(
"Unable to malloc instruction object", EX_SOFTWARE);
740 memset(new_instr, 0,
sizeof(*new_instr));
753 stop(
"Unable to malloc critical_section object", EX_SOFTWARE);
754 memset(new_cs, 0,
sizeof(*new_cs));
766 if (new_scope ==
NULL)
767 stop(
"Unable to malloc scope object", EX_SOFTWARE);
768 memset(new_scope, 0,
sizeof(*new_scope));
773 new_scope, scope_links);
789 u_int skip_patch_count;
790 u_int skip_instr_count;
792 cur_scope =
TAILQ_LAST(&scope->inner_scope, scope_tailq);
793 skip_patch_count = 0;
794 skip_instr_count = 0;
795 while (cur_scope !=
NULL) {
796 u_int patch0_patch_skip;
798 patch0_patch_skip = 0;
799 switch (cur_scope->
type) {
802 if (skip_instr_count != 0) {
806 skip_patch_count + 1;
823 skip_patch_count += patch0_patch_skip;
826 skip_patch_count = 0;
827 skip_instr_count = 0;
834 skip_instr_count += cur_scope->
end_addr
838 stop(
"Unexpected scope type encountered", EX_SOFTWARE);
842 cur_scope =
TAILQ_PREV(cur_scope, scope_tailq, scope_links);