162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Aic7xxx SCSI host adapter firmware assembler symbol table implementation 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (c) 1997 Justin T. Gibbs. 562306a36Sopenharmony_ci * Copyright (c) 2002 Adaptec Inc. 662306a36Sopenharmony_ci * All rights reserved. 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 962306a36Sopenharmony_ci * modification, are permitted provided that the following conditions 1062306a36Sopenharmony_ci * are met: 1162306a36Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright 1262306a36Sopenharmony_ci * notice, this list of conditions, and the following disclaimer, 1362306a36Sopenharmony_ci * without modification. 1462306a36Sopenharmony_ci * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1562306a36Sopenharmony_ci * substantially similar to the "NO WARRANTY" disclaimer below 1662306a36Sopenharmony_ci * ("Disclaimer") and any redistribution must be conditioned upon 1762306a36Sopenharmony_ci * including a substantially similar Disclaimer requirement for further 1862306a36Sopenharmony_ci * binary redistribution. 1962306a36Sopenharmony_ci * 3. Neither the names of the above-listed copyright holders nor the names 2062306a36Sopenharmony_ci * of any contributors may be used to endorse or promote products derived 2162306a36Sopenharmony_ci * from this software without specific prior written permission. 2262306a36Sopenharmony_ci * 2362306a36Sopenharmony_ci * Alternatively, this software may be distributed under the terms of the 2462306a36Sopenharmony_ci * GNU General Public License ("GPL") version 2 as published by the Free 2562306a36Sopenharmony_ci * Software Foundation. 2662306a36Sopenharmony_ci * 2762306a36Sopenharmony_ci * NO WARRANTY 2862306a36Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2962306a36Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3062306a36Sopenharmony_ci * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3162306a36Sopenharmony_ci * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3262306a36Sopenharmony_ci * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3362306a36Sopenharmony_ci * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3462306a36Sopenharmony_ci * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3562306a36Sopenharmony_ci * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3662306a36Sopenharmony_ci * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 3762306a36Sopenharmony_ci * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3862306a36Sopenharmony_ci * POSSIBILITY OF SUCH DAMAGES. 3962306a36Sopenharmony_ci * 4062306a36Sopenharmony_ci * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#24 $ 4162306a36Sopenharmony_ci * 4262306a36Sopenharmony_ci * $FreeBSD$ 4362306a36Sopenharmony_ci */ 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci#include <sys/types.h> 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci#include "aicdb.h" 4862306a36Sopenharmony_ci#include <fcntl.h> 4962306a36Sopenharmony_ci#include <inttypes.h> 5062306a36Sopenharmony_ci#include <regex.h> 5162306a36Sopenharmony_ci#include <stdio.h> 5262306a36Sopenharmony_ci#include <stdlib.h> 5362306a36Sopenharmony_ci#include <string.h> 5462306a36Sopenharmony_ci#include <sysexits.h> 5562306a36Sopenharmony_ci#include <ctype.h> 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci#include "aicasm_symbol.h" 5862306a36Sopenharmony_ci#include "aicasm.h" 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cistatic DB *symtable; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_cisymbol_t * 6362306a36Sopenharmony_cisymbol_create(char *name) 6462306a36Sopenharmony_ci{ 6562306a36Sopenharmony_ci symbol_t *new_symbol; 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci new_symbol = (symbol_t *)malloc(sizeof(symbol_t)); 6862306a36Sopenharmony_ci if (new_symbol == NULL) { 6962306a36Sopenharmony_ci perror("Unable to create new symbol"); 7062306a36Sopenharmony_ci exit(EX_SOFTWARE); 7162306a36Sopenharmony_ci } 7262306a36Sopenharmony_ci memset(new_symbol, 0, sizeof(*new_symbol)); 7362306a36Sopenharmony_ci new_symbol->name = strdup(name); 7462306a36Sopenharmony_ci if (new_symbol->name == NULL) 7562306a36Sopenharmony_ci stop("Unable to strdup symbol name", EX_SOFTWARE); 7662306a36Sopenharmony_ci new_symbol->type = UNINITIALIZED; 7762306a36Sopenharmony_ci new_symbol->count = 1; 7862306a36Sopenharmony_ci return (new_symbol); 7962306a36Sopenharmony_ci} 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_civoid 8262306a36Sopenharmony_cisymbol_delete(symbol_t *symbol) 8362306a36Sopenharmony_ci{ 8462306a36Sopenharmony_ci if (symtable != NULL) { 8562306a36Sopenharmony_ci DBT key; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci key.data = symbol->name; 8862306a36Sopenharmony_ci key.size = strlen(symbol->name); 8962306a36Sopenharmony_ci symtable->del(symtable, &key, /*flags*/0); 9062306a36Sopenharmony_ci } 9162306a36Sopenharmony_ci switch(symbol->type) { 9262306a36Sopenharmony_ci case SCBLOC: 9362306a36Sopenharmony_ci case SRAMLOC: 9462306a36Sopenharmony_ci case REGISTER: 9562306a36Sopenharmony_ci if (symbol->info.rinfo != NULL) 9662306a36Sopenharmony_ci free(symbol->info.rinfo); 9762306a36Sopenharmony_ci break; 9862306a36Sopenharmony_ci case ALIAS: 9962306a36Sopenharmony_ci if (symbol->info.ainfo != NULL) 10062306a36Sopenharmony_ci free(symbol->info.ainfo); 10162306a36Sopenharmony_ci break; 10262306a36Sopenharmony_ci case MASK: 10362306a36Sopenharmony_ci case FIELD: 10462306a36Sopenharmony_ci case ENUM: 10562306a36Sopenharmony_ci case ENUM_ENTRY: 10662306a36Sopenharmony_ci if (symbol->info.finfo != NULL) { 10762306a36Sopenharmony_ci symlist_free(&symbol->info.finfo->symrefs); 10862306a36Sopenharmony_ci free(symbol->info.finfo); 10962306a36Sopenharmony_ci } 11062306a36Sopenharmony_ci break; 11162306a36Sopenharmony_ci case DOWNLOAD_CONST: 11262306a36Sopenharmony_ci case CONST: 11362306a36Sopenharmony_ci if (symbol->info.cinfo != NULL) 11462306a36Sopenharmony_ci free(symbol->info.cinfo); 11562306a36Sopenharmony_ci break; 11662306a36Sopenharmony_ci case LABEL: 11762306a36Sopenharmony_ci if (symbol->info.linfo != NULL) 11862306a36Sopenharmony_ci free(symbol->info.linfo); 11962306a36Sopenharmony_ci break; 12062306a36Sopenharmony_ci case UNINITIALIZED: 12162306a36Sopenharmony_ci default: 12262306a36Sopenharmony_ci break; 12362306a36Sopenharmony_ci } 12462306a36Sopenharmony_ci free(symbol->name); 12562306a36Sopenharmony_ci free(symbol); 12662306a36Sopenharmony_ci} 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_civoid 12962306a36Sopenharmony_cisymtable_open() 13062306a36Sopenharmony_ci{ 13162306a36Sopenharmony_ci symtable = dbopen(/*filename*/NULL, 13262306a36Sopenharmony_ci O_CREAT | O_NONBLOCK | O_RDWR, /*mode*/0, DB_HASH, 13362306a36Sopenharmony_ci /*openinfo*/NULL); 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci if (symtable == NULL) { 13662306a36Sopenharmony_ci perror("Symbol table creation failed"); 13762306a36Sopenharmony_ci exit(EX_SOFTWARE); 13862306a36Sopenharmony_ci /* NOTREACHED */ 13962306a36Sopenharmony_ci } 14062306a36Sopenharmony_ci} 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_civoid 14362306a36Sopenharmony_cisymtable_close() 14462306a36Sopenharmony_ci{ 14562306a36Sopenharmony_ci if (symtable != NULL) { 14662306a36Sopenharmony_ci DBT key; 14762306a36Sopenharmony_ci DBT data; 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci while (symtable->seq(symtable, &key, &data, R_FIRST) == 0) { 15062306a36Sopenharmony_ci symbol_t *stored_ptr; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci memcpy(&stored_ptr, data.data, sizeof(stored_ptr)); 15362306a36Sopenharmony_ci symbol_delete(stored_ptr); 15462306a36Sopenharmony_ci } 15562306a36Sopenharmony_ci symtable->close(symtable); 15662306a36Sopenharmony_ci } 15762306a36Sopenharmony_ci} 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci/* 16062306a36Sopenharmony_ci * The semantics of get is to return an uninitialized symbol entry 16162306a36Sopenharmony_ci * if a lookup fails. 16262306a36Sopenharmony_ci */ 16362306a36Sopenharmony_cisymbol_t * 16462306a36Sopenharmony_cisymtable_get(char *name) 16562306a36Sopenharmony_ci{ 16662306a36Sopenharmony_ci symbol_t *stored_ptr; 16762306a36Sopenharmony_ci DBT key; 16862306a36Sopenharmony_ci DBT data; 16962306a36Sopenharmony_ci int retval; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci key.data = (void *)name; 17262306a36Sopenharmony_ci key.size = strlen(name); 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci if ((retval = symtable->get(symtable, &key, &data, /*flags*/0)) != 0) { 17562306a36Sopenharmony_ci if (retval == -1) { 17662306a36Sopenharmony_ci perror("Symbol table get operation failed"); 17762306a36Sopenharmony_ci exit(EX_SOFTWARE); 17862306a36Sopenharmony_ci /* NOTREACHED */ 17962306a36Sopenharmony_ci } else if (retval == 1) { 18062306a36Sopenharmony_ci /* Symbol wasn't found, so create a new one */ 18162306a36Sopenharmony_ci symbol_t *new_symbol; 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci new_symbol = symbol_create(name); 18462306a36Sopenharmony_ci data.data = &new_symbol; 18562306a36Sopenharmony_ci data.size = sizeof(new_symbol); 18662306a36Sopenharmony_ci if (symtable->put(symtable, &key, &data, 18762306a36Sopenharmony_ci /*flags*/0) !=0) { 18862306a36Sopenharmony_ci perror("Symtable put failed"); 18962306a36Sopenharmony_ci exit(EX_SOFTWARE); 19062306a36Sopenharmony_ci } 19162306a36Sopenharmony_ci return (new_symbol); 19262306a36Sopenharmony_ci } else { 19362306a36Sopenharmony_ci perror("Unexpected return value from db get routine"); 19462306a36Sopenharmony_ci exit(EX_SOFTWARE); 19562306a36Sopenharmony_ci /* NOTREACHED */ 19662306a36Sopenharmony_ci } 19762306a36Sopenharmony_ci } 19862306a36Sopenharmony_ci memcpy(&stored_ptr, data.data, sizeof(stored_ptr)); 19962306a36Sopenharmony_ci stored_ptr->count++; 20062306a36Sopenharmony_ci data.data = &stored_ptr; 20162306a36Sopenharmony_ci if (symtable->put(symtable, &key, &data, /*flags*/0) !=0) { 20262306a36Sopenharmony_ci perror("Symtable put failed"); 20362306a36Sopenharmony_ci exit(EX_SOFTWARE); 20462306a36Sopenharmony_ci } 20562306a36Sopenharmony_ci return (stored_ptr); 20662306a36Sopenharmony_ci} 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_cisymbol_node_t * 20962306a36Sopenharmony_cisymlist_search(symlist_t *symlist, char *symname) 21062306a36Sopenharmony_ci{ 21162306a36Sopenharmony_ci symbol_node_t *curnode; 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci curnode = SLIST_FIRST(symlist); 21462306a36Sopenharmony_ci while(curnode != NULL) { 21562306a36Sopenharmony_ci if (strcmp(symname, curnode->symbol->name) == 0) 21662306a36Sopenharmony_ci break; 21762306a36Sopenharmony_ci curnode = SLIST_NEXT(curnode, links); 21862306a36Sopenharmony_ci } 21962306a36Sopenharmony_ci return (curnode); 22062306a36Sopenharmony_ci} 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_civoid 22362306a36Sopenharmony_cisymlist_add(symlist_t *symlist, symbol_t *symbol, int how) 22462306a36Sopenharmony_ci{ 22562306a36Sopenharmony_ci symbol_node_t *newnode; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci newnode = (symbol_node_t *)malloc(sizeof(symbol_node_t)); 22862306a36Sopenharmony_ci if (newnode == NULL) { 22962306a36Sopenharmony_ci stop("symlist_add: Unable to malloc symbol_node", EX_SOFTWARE); 23062306a36Sopenharmony_ci /* NOTREACHED */ 23162306a36Sopenharmony_ci } 23262306a36Sopenharmony_ci newnode->symbol = symbol; 23362306a36Sopenharmony_ci if (how == SYMLIST_SORT) { 23462306a36Sopenharmony_ci symbol_node_t *curnode; 23562306a36Sopenharmony_ci int field; 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci field = FALSE; 23862306a36Sopenharmony_ci switch(symbol->type) { 23962306a36Sopenharmony_ci case REGISTER: 24062306a36Sopenharmony_ci case SCBLOC: 24162306a36Sopenharmony_ci case SRAMLOC: 24262306a36Sopenharmony_ci break; 24362306a36Sopenharmony_ci case FIELD: 24462306a36Sopenharmony_ci case MASK: 24562306a36Sopenharmony_ci case ENUM: 24662306a36Sopenharmony_ci case ENUM_ENTRY: 24762306a36Sopenharmony_ci field = TRUE; 24862306a36Sopenharmony_ci break; 24962306a36Sopenharmony_ci default: 25062306a36Sopenharmony_ci stop("symlist_add: Invalid symbol type for sorting", 25162306a36Sopenharmony_ci EX_SOFTWARE); 25262306a36Sopenharmony_ci /* NOTREACHED */ 25362306a36Sopenharmony_ci } 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci curnode = SLIST_FIRST(symlist); 25662306a36Sopenharmony_ci if (curnode == NULL 25762306a36Sopenharmony_ci || (field 25862306a36Sopenharmony_ci && (curnode->symbol->type > newnode->symbol->type 25962306a36Sopenharmony_ci || (curnode->symbol->type == newnode->symbol->type 26062306a36Sopenharmony_ci && (curnode->symbol->info.finfo->value > 26162306a36Sopenharmony_ci newnode->symbol->info.finfo->value)))) 26262306a36Sopenharmony_ci || (!field && (curnode->symbol->info.rinfo->address > 26362306a36Sopenharmony_ci newnode->symbol->info.rinfo->address))) { 26462306a36Sopenharmony_ci SLIST_INSERT_HEAD(symlist, newnode, links); 26562306a36Sopenharmony_ci return; 26662306a36Sopenharmony_ci } 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci while (1) { 26962306a36Sopenharmony_ci if (SLIST_NEXT(curnode, links) == NULL) { 27062306a36Sopenharmony_ci SLIST_INSERT_AFTER(curnode, newnode, 27162306a36Sopenharmony_ci links); 27262306a36Sopenharmony_ci break; 27362306a36Sopenharmony_ci } else { 27462306a36Sopenharmony_ci symbol_t *cursymbol; 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci cursymbol = SLIST_NEXT(curnode, links)->symbol; 27762306a36Sopenharmony_ci if ((field 27862306a36Sopenharmony_ci && (cursymbol->type > symbol->type 27962306a36Sopenharmony_ci || (cursymbol->type == symbol->type 28062306a36Sopenharmony_ci && (cursymbol->info.finfo->value > 28162306a36Sopenharmony_ci symbol->info.finfo->value)))) 28262306a36Sopenharmony_ci || (!field 28362306a36Sopenharmony_ci && (cursymbol->info.rinfo->address > 28462306a36Sopenharmony_ci symbol->info.rinfo->address))) { 28562306a36Sopenharmony_ci SLIST_INSERT_AFTER(curnode, newnode, 28662306a36Sopenharmony_ci links); 28762306a36Sopenharmony_ci break; 28862306a36Sopenharmony_ci } 28962306a36Sopenharmony_ci } 29062306a36Sopenharmony_ci curnode = SLIST_NEXT(curnode, links); 29162306a36Sopenharmony_ci } 29262306a36Sopenharmony_ci } else { 29362306a36Sopenharmony_ci SLIST_INSERT_HEAD(symlist, newnode, links); 29462306a36Sopenharmony_ci } 29562306a36Sopenharmony_ci} 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_civoid 29862306a36Sopenharmony_cisymlist_free(symlist_t *symlist) 29962306a36Sopenharmony_ci{ 30062306a36Sopenharmony_ci symbol_node_t *node1, *node2; 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci node1 = SLIST_FIRST(symlist); 30362306a36Sopenharmony_ci while (node1 != NULL) { 30462306a36Sopenharmony_ci node2 = SLIST_NEXT(node1, links); 30562306a36Sopenharmony_ci free(node1); 30662306a36Sopenharmony_ci node1 = node2; 30762306a36Sopenharmony_ci } 30862306a36Sopenharmony_ci SLIST_INIT(symlist); 30962306a36Sopenharmony_ci} 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_civoid 31262306a36Sopenharmony_cisymlist_merge(symlist_t *symlist_dest, symlist_t *symlist_src1, 31362306a36Sopenharmony_ci symlist_t *symlist_src2) 31462306a36Sopenharmony_ci{ 31562306a36Sopenharmony_ci symbol_node_t *node; 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci *symlist_dest = *symlist_src1; 31862306a36Sopenharmony_ci while((node = SLIST_FIRST(symlist_src2)) != NULL) { 31962306a36Sopenharmony_ci SLIST_REMOVE_HEAD(symlist_src2, links); 32062306a36Sopenharmony_ci SLIST_INSERT_HEAD(symlist_dest, node, links); 32162306a36Sopenharmony_ci } 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci /* These are now empty */ 32462306a36Sopenharmony_ci SLIST_INIT(symlist_src1); 32562306a36Sopenharmony_ci SLIST_INIT(symlist_src2); 32662306a36Sopenharmony_ci} 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_civoid 32962306a36Sopenharmony_ciaic_print_file_prologue(FILE *ofile) 33062306a36Sopenharmony_ci{ 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci if (ofile == NULL) 33362306a36Sopenharmony_ci return; 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci fprintf(ofile, 33662306a36Sopenharmony_ci"/*\n" 33762306a36Sopenharmony_ci" * DO NOT EDIT - This file is automatically generated\n" 33862306a36Sopenharmony_ci" * from the following source files:\n" 33962306a36Sopenharmony_ci" *\n" 34062306a36Sopenharmony_ci"%s */\n", 34162306a36Sopenharmony_ci versions); 34262306a36Sopenharmony_ci} 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_civoid 34562306a36Sopenharmony_ciaic_print_include(FILE *dfile, char *include_file) 34662306a36Sopenharmony_ci{ 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci if (dfile == NULL) 34962306a36Sopenharmony_ci return; 35062306a36Sopenharmony_ci fprintf(dfile, "\n#include \"%s\"\n\n", include_file); 35162306a36Sopenharmony_ci} 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_civoid 35462306a36Sopenharmony_ciaic_print_reg_dump_types(FILE *ofile) 35562306a36Sopenharmony_ci{ 35662306a36Sopenharmony_ci if (ofile == NULL) 35762306a36Sopenharmony_ci return; 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci fprintf(ofile, 36062306a36Sopenharmony_ci"typedef int (%sreg_print_t)(u_int, u_int *, u_int);\n" 36162306a36Sopenharmony_ci"typedef struct %sreg_parse_entry {\n" 36262306a36Sopenharmony_ci" char *name;\n" 36362306a36Sopenharmony_ci" uint8_t value;\n" 36462306a36Sopenharmony_ci" uint8_t mask;\n" 36562306a36Sopenharmony_ci"} %sreg_parse_entry_t;\n" 36662306a36Sopenharmony_ci"\n", 36762306a36Sopenharmony_ci prefix, prefix, prefix); 36862306a36Sopenharmony_ci} 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_cistatic void 37162306a36Sopenharmony_ciaic_print_reg_dump_start(FILE *dfile, symbol_node_t *regnode) 37262306a36Sopenharmony_ci{ 37362306a36Sopenharmony_ci if (dfile == NULL) 37462306a36Sopenharmony_ci return; 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ci fprintf(dfile, 37762306a36Sopenharmony_ci"static const %sreg_parse_entry_t %s_parse_table[] = {\n", 37862306a36Sopenharmony_ci prefix, 37962306a36Sopenharmony_ci regnode->symbol->name); 38062306a36Sopenharmony_ci} 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_cistatic void 38362306a36Sopenharmony_ciaic_print_reg_dump_end(FILE *ofile, FILE *dfile, 38462306a36Sopenharmony_ci symbol_node_t *regnode, u_int num_entries) 38562306a36Sopenharmony_ci{ 38662306a36Sopenharmony_ci char *lower_name; 38762306a36Sopenharmony_ci char *letter; 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_ci lower_name = strdup(regnode->symbol->name); 39062306a36Sopenharmony_ci if (lower_name == NULL) 39162306a36Sopenharmony_ci stop("Unable to strdup symbol name", EX_SOFTWARE); 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci for (letter = lower_name; *letter != '\0'; letter++) 39462306a36Sopenharmony_ci *letter = tolower(*letter); 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci if (dfile != NULL) { 39762306a36Sopenharmony_ci if (num_entries != 0) 39862306a36Sopenharmony_ci fprintf(dfile, 39962306a36Sopenharmony_ci"\n" 40062306a36Sopenharmony_ci"};\n" 40162306a36Sopenharmony_ci"\n"); 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ci fprintf(dfile, 40462306a36Sopenharmony_ci"int\n" 40562306a36Sopenharmony_ci"%s%s_print(u_int regvalue, u_int *cur_col, u_int wrap)\n" 40662306a36Sopenharmony_ci"{\n" 40762306a36Sopenharmony_ci" return (%sprint_register(%s%s, %d, \"%s\",\n" 40862306a36Sopenharmony_ci" 0x%02x, regvalue, cur_col, wrap));\n" 40962306a36Sopenharmony_ci"}\n" 41062306a36Sopenharmony_ci"\n", 41162306a36Sopenharmony_ci prefix, 41262306a36Sopenharmony_ci lower_name, 41362306a36Sopenharmony_ci prefix, 41462306a36Sopenharmony_ci num_entries != 0 ? regnode->symbol->name : "NULL", 41562306a36Sopenharmony_ci num_entries != 0 ? "_parse_table" : "", 41662306a36Sopenharmony_ci num_entries, 41762306a36Sopenharmony_ci regnode->symbol->name, 41862306a36Sopenharmony_ci regnode->symbol->info.rinfo->address); 41962306a36Sopenharmony_ci } 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci fprintf(ofile, 42262306a36Sopenharmony_ci"#if AIC_DEBUG_REGISTERS\n" 42362306a36Sopenharmony_ci"%sreg_print_t %s%s_print;\n" 42462306a36Sopenharmony_ci"#else\n" 42562306a36Sopenharmony_ci"#define %s%s_print(regvalue, cur_col, wrap) \\\n" 42662306a36Sopenharmony_ci" %sprint_register(NULL, 0, \"%s\", 0x%02x, regvalue, cur_col, wrap)\n" 42762306a36Sopenharmony_ci"#endif\n" 42862306a36Sopenharmony_ci"\n", 42962306a36Sopenharmony_ci prefix, 43062306a36Sopenharmony_ci prefix, 43162306a36Sopenharmony_ci lower_name, 43262306a36Sopenharmony_ci prefix, 43362306a36Sopenharmony_ci lower_name, 43462306a36Sopenharmony_ci prefix, 43562306a36Sopenharmony_ci regnode->symbol->name, 43662306a36Sopenharmony_ci regnode->symbol->info.rinfo->address); 43762306a36Sopenharmony_ci} 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_cistatic void 44062306a36Sopenharmony_ciaic_print_reg_dump_entry(FILE *dfile, symbol_node_t *curnode) 44162306a36Sopenharmony_ci{ 44262306a36Sopenharmony_ci int num_tabs; 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_ci if (dfile == NULL) 44562306a36Sopenharmony_ci return; 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ci fprintf(dfile, 44862306a36Sopenharmony_ci" { \"%s\",", 44962306a36Sopenharmony_ci curnode->symbol->name); 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_ci num_tabs = 3 - (strlen(curnode->symbol->name) + 5) / 8; 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_ci while (num_tabs-- > 0) 45462306a36Sopenharmony_ci fputc('\t', dfile); 45562306a36Sopenharmony_ci fprintf(dfile, "0x%02x, 0x%02x }", 45662306a36Sopenharmony_ci curnode->symbol->info.finfo->value, 45762306a36Sopenharmony_ci curnode->symbol->info.finfo->mask); 45862306a36Sopenharmony_ci} 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_civoid 46162306a36Sopenharmony_cisymtable_dump(FILE *ofile, FILE *dfile) 46262306a36Sopenharmony_ci{ 46362306a36Sopenharmony_ci /* 46462306a36Sopenharmony_ci * Sort the registers by address with a simple insertion sort. 46562306a36Sopenharmony_ci * Put bitmasks next to the first register that defines them. 46662306a36Sopenharmony_ci * Put constants at the end. 46762306a36Sopenharmony_ci */ 46862306a36Sopenharmony_ci symlist_t registers; 46962306a36Sopenharmony_ci symlist_t masks; 47062306a36Sopenharmony_ci symlist_t constants; 47162306a36Sopenharmony_ci symlist_t download_constants; 47262306a36Sopenharmony_ci symlist_t aliases; 47362306a36Sopenharmony_ci symlist_t exported_labels; 47462306a36Sopenharmony_ci symbol_node_t *curnode; 47562306a36Sopenharmony_ci symbol_node_t *regnode; 47662306a36Sopenharmony_ci DBT key; 47762306a36Sopenharmony_ci DBT data; 47862306a36Sopenharmony_ci int flag; 47962306a36Sopenharmony_ci int reg_count = 0, reg_used = 0; 48062306a36Sopenharmony_ci u_int i; 48162306a36Sopenharmony_ci 48262306a36Sopenharmony_ci if (symtable == NULL) 48362306a36Sopenharmony_ci return; 48462306a36Sopenharmony_ci 48562306a36Sopenharmony_ci SLIST_INIT(®isters); 48662306a36Sopenharmony_ci SLIST_INIT(&masks); 48762306a36Sopenharmony_ci SLIST_INIT(&constants); 48862306a36Sopenharmony_ci SLIST_INIT(&download_constants); 48962306a36Sopenharmony_ci SLIST_INIT(&aliases); 49062306a36Sopenharmony_ci SLIST_INIT(&exported_labels); 49162306a36Sopenharmony_ci flag = R_FIRST; 49262306a36Sopenharmony_ci while (symtable->seq(symtable, &key, &data, flag) == 0) { 49362306a36Sopenharmony_ci symbol_t *cursym; 49462306a36Sopenharmony_ci 49562306a36Sopenharmony_ci memcpy(&cursym, data.data, sizeof(cursym)); 49662306a36Sopenharmony_ci switch(cursym->type) { 49762306a36Sopenharmony_ci case REGISTER: 49862306a36Sopenharmony_ci case SCBLOC: 49962306a36Sopenharmony_ci case SRAMLOC: 50062306a36Sopenharmony_ci symlist_add(®isters, cursym, SYMLIST_SORT); 50162306a36Sopenharmony_ci break; 50262306a36Sopenharmony_ci case MASK: 50362306a36Sopenharmony_ci case FIELD: 50462306a36Sopenharmony_ci case ENUM: 50562306a36Sopenharmony_ci case ENUM_ENTRY: 50662306a36Sopenharmony_ci symlist_add(&masks, cursym, SYMLIST_SORT); 50762306a36Sopenharmony_ci break; 50862306a36Sopenharmony_ci case CONST: 50962306a36Sopenharmony_ci symlist_add(&constants, cursym, 51062306a36Sopenharmony_ci SYMLIST_INSERT_HEAD); 51162306a36Sopenharmony_ci break; 51262306a36Sopenharmony_ci case DOWNLOAD_CONST: 51362306a36Sopenharmony_ci symlist_add(&download_constants, cursym, 51462306a36Sopenharmony_ci SYMLIST_INSERT_HEAD); 51562306a36Sopenharmony_ci break; 51662306a36Sopenharmony_ci case ALIAS: 51762306a36Sopenharmony_ci symlist_add(&aliases, cursym, 51862306a36Sopenharmony_ci SYMLIST_INSERT_HEAD); 51962306a36Sopenharmony_ci break; 52062306a36Sopenharmony_ci case LABEL: 52162306a36Sopenharmony_ci if (cursym->info.linfo->exported == 0) 52262306a36Sopenharmony_ci break; 52362306a36Sopenharmony_ci symlist_add(&exported_labels, cursym, 52462306a36Sopenharmony_ci SYMLIST_INSERT_HEAD); 52562306a36Sopenharmony_ci break; 52662306a36Sopenharmony_ci default: 52762306a36Sopenharmony_ci break; 52862306a36Sopenharmony_ci } 52962306a36Sopenharmony_ci flag = R_NEXT; 53062306a36Sopenharmony_ci } 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_ci /* Register dianostic functions/declarations first. */ 53362306a36Sopenharmony_ci aic_print_file_prologue(ofile); 53462306a36Sopenharmony_ci aic_print_reg_dump_types(ofile); 53562306a36Sopenharmony_ci aic_print_file_prologue(dfile); 53662306a36Sopenharmony_ci aic_print_include(dfile, stock_include_file); 53762306a36Sopenharmony_ci SLIST_FOREACH(curnode, ®isters, links) { 53862306a36Sopenharmony_ci 53962306a36Sopenharmony_ci if (curnode->symbol->dont_generate_debug_code) 54062306a36Sopenharmony_ci continue; 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_ci switch(curnode->symbol->type) { 54362306a36Sopenharmony_ci case REGISTER: 54462306a36Sopenharmony_ci case SCBLOC: 54562306a36Sopenharmony_ci case SRAMLOC: 54662306a36Sopenharmony_ci { 54762306a36Sopenharmony_ci symlist_t *fields; 54862306a36Sopenharmony_ci symbol_node_t *fieldnode; 54962306a36Sopenharmony_ci int num_entries; 55062306a36Sopenharmony_ci 55162306a36Sopenharmony_ci num_entries = 0; 55262306a36Sopenharmony_ci reg_count++; 55362306a36Sopenharmony_ci if (curnode->symbol->count == 1) 55462306a36Sopenharmony_ci break; 55562306a36Sopenharmony_ci fields = &curnode->symbol->info.rinfo->fields; 55662306a36Sopenharmony_ci SLIST_FOREACH(fieldnode, fields, links) { 55762306a36Sopenharmony_ci if (num_entries == 0) 55862306a36Sopenharmony_ci aic_print_reg_dump_start(dfile, 55962306a36Sopenharmony_ci curnode); 56062306a36Sopenharmony_ci else if (dfile != NULL) 56162306a36Sopenharmony_ci fputs(",\n", dfile); 56262306a36Sopenharmony_ci num_entries++; 56362306a36Sopenharmony_ci aic_print_reg_dump_entry(dfile, fieldnode); 56462306a36Sopenharmony_ci } 56562306a36Sopenharmony_ci aic_print_reg_dump_end(ofile, dfile, 56662306a36Sopenharmony_ci curnode, num_entries); 56762306a36Sopenharmony_ci reg_used++; 56862306a36Sopenharmony_ci } 56962306a36Sopenharmony_ci default: 57062306a36Sopenharmony_ci break; 57162306a36Sopenharmony_ci } 57262306a36Sopenharmony_ci } 57362306a36Sopenharmony_ci fprintf(stderr, "%s: %d of %d register definitions used\n", appname, 57462306a36Sopenharmony_ci reg_used, reg_count); 57562306a36Sopenharmony_ci 57662306a36Sopenharmony_ci /* Fold in the masks and bits */ 57762306a36Sopenharmony_ci while (SLIST_FIRST(&masks) != NULL) { 57862306a36Sopenharmony_ci char *regname; 57962306a36Sopenharmony_ci 58062306a36Sopenharmony_ci curnode = SLIST_FIRST(&masks); 58162306a36Sopenharmony_ci SLIST_REMOVE_HEAD(&masks, links); 58262306a36Sopenharmony_ci 58362306a36Sopenharmony_ci regnode = SLIST_FIRST(&curnode->symbol->info.finfo->symrefs); 58462306a36Sopenharmony_ci regname = regnode->symbol->name; 58562306a36Sopenharmony_ci regnode = symlist_search(®isters, regname); 58662306a36Sopenharmony_ci SLIST_INSERT_AFTER(regnode, curnode, links); 58762306a36Sopenharmony_ci } 58862306a36Sopenharmony_ci 58962306a36Sopenharmony_ci /* Add the aliases */ 59062306a36Sopenharmony_ci while (SLIST_FIRST(&aliases) != NULL) { 59162306a36Sopenharmony_ci char *regname; 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_ci curnode = SLIST_FIRST(&aliases); 59462306a36Sopenharmony_ci SLIST_REMOVE_HEAD(&aliases, links); 59562306a36Sopenharmony_ci 59662306a36Sopenharmony_ci regname = curnode->symbol->info.ainfo->parent->name; 59762306a36Sopenharmony_ci regnode = symlist_search(®isters, regname); 59862306a36Sopenharmony_ci SLIST_INSERT_AFTER(regnode, curnode, links); 59962306a36Sopenharmony_ci } 60062306a36Sopenharmony_ci 60162306a36Sopenharmony_ci /* Output generated #defines. */ 60262306a36Sopenharmony_ci while (SLIST_FIRST(®isters) != NULL) { 60362306a36Sopenharmony_ci symbol_node_t *curnode; 60462306a36Sopenharmony_ci u_int value; 60562306a36Sopenharmony_ci char *tab_str; 60662306a36Sopenharmony_ci char *tab_str2; 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_ci curnode = SLIST_FIRST(®isters); 60962306a36Sopenharmony_ci SLIST_REMOVE_HEAD(®isters, links); 61062306a36Sopenharmony_ci switch(curnode->symbol->type) { 61162306a36Sopenharmony_ci case REGISTER: 61262306a36Sopenharmony_ci case SCBLOC: 61362306a36Sopenharmony_ci case SRAMLOC: 61462306a36Sopenharmony_ci fprintf(ofile, "\n"); 61562306a36Sopenharmony_ci value = curnode->symbol->info.rinfo->address; 61662306a36Sopenharmony_ci tab_str = "\t"; 61762306a36Sopenharmony_ci tab_str2 = "\t\t"; 61862306a36Sopenharmony_ci break; 61962306a36Sopenharmony_ci case ALIAS: 62062306a36Sopenharmony_ci { 62162306a36Sopenharmony_ci symbol_t *parent; 62262306a36Sopenharmony_ci 62362306a36Sopenharmony_ci parent = curnode->symbol->info.ainfo->parent; 62462306a36Sopenharmony_ci value = parent->info.rinfo->address; 62562306a36Sopenharmony_ci tab_str = "\t"; 62662306a36Sopenharmony_ci tab_str2 = "\t\t"; 62762306a36Sopenharmony_ci break; 62862306a36Sopenharmony_ci } 62962306a36Sopenharmony_ci case MASK: 63062306a36Sopenharmony_ci case FIELD: 63162306a36Sopenharmony_ci case ENUM: 63262306a36Sopenharmony_ci case ENUM_ENTRY: 63362306a36Sopenharmony_ci value = curnode->symbol->info.finfo->value; 63462306a36Sopenharmony_ci tab_str = "\t\t"; 63562306a36Sopenharmony_ci tab_str2 = "\t"; 63662306a36Sopenharmony_ci break; 63762306a36Sopenharmony_ci default: 63862306a36Sopenharmony_ci value = 0; /* Quiet compiler */ 63962306a36Sopenharmony_ci tab_str = NULL; 64062306a36Sopenharmony_ci tab_str2 = NULL; 64162306a36Sopenharmony_ci stop("symtable_dump: Invalid symbol type " 64262306a36Sopenharmony_ci "encountered", EX_SOFTWARE); 64362306a36Sopenharmony_ci break; 64462306a36Sopenharmony_ci } 64562306a36Sopenharmony_ci fprintf(ofile, "#define%s%-16s%s0x%02x\n", 64662306a36Sopenharmony_ci tab_str, curnode->symbol->name, tab_str2, 64762306a36Sopenharmony_ci value); 64862306a36Sopenharmony_ci free(curnode); 64962306a36Sopenharmony_ci } 65062306a36Sopenharmony_ci fprintf(ofile, "\n\n"); 65162306a36Sopenharmony_ci 65262306a36Sopenharmony_ci while (SLIST_FIRST(&constants) != NULL) { 65362306a36Sopenharmony_ci symbol_node_t *curnode; 65462306a36Sopenharmony_ci 65562306a36Sopenharmony_ci curnode = SLIST_FIRST(&constants); 65662306a36Sopenharmony_ci SLIST_REMOVE_HEAD(&constants, links); 65762306a36Sopenharmony_ci fprintf(ofile, "#define\t%-8s\t0x%02x\n", 65862306a36Sopenharmony_ci curnode->symbol->name, 65962306a36Sopenharmony_ci curnode->symbol->info.cinfo->value); 66062306a36Sopenharmony_ci free(curnode); 66162306a36Sopenharmony_ci } 66262306a36Sopenharmony_ci 66362306a36Sopenharmony_ci fprintf(ofile, "\n\n/* Downloaded Constant Definitions */\n"); 66462306a36Sopenharmony_ci 66562306a36Sopenharmony_ci for (i = 0; SLIST_FIRST(&download_constants) != NULL; i++) { 66662306a36Sopenharmony_ci symbol_node_t *curnode; 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_ci curnode = SLIST_FIRST(&download_constants); 66962306a36Sopenharmony_ci SLIST_REMOVE_HEAD(&download_constants, links); 67062306a36Sopenharmony_ci fprintf(ofile, "#define\t%-8s\t0x%02x\n", 67162306a36Sopenharmony_ci curnode->symbol->name, 67262306a36Sopenharmony_ci curnode->symbol->info.cinfo->value); 67362306a36Sopenharmony_ci free(curnode); 67462306a36Sopenharmony_ci } 67562306a36Sopenharmony_ci fprintf(ofile, "#define\tDOWNLOAD_CONST_COUNT\t0x%02x\n", i); 67662306a36Sopenharmony_ci 67762306a36Sopenharmony_ci fprintf(ofile, "\n\n/* Exported Labels */\n"); 67862306a36Sopenharmony_ci 67962306a36Sopenharmony_ci while (SLIST_FIRST(&exported_labels) != NULL) { 68062306a36Sopenharmony_ci symbol_node_t *curnode; 68162306a36Sopenharmony_ci 68262306a36Sopenharmony_ci curnode = SLIST_FIRST(&exported_labels); 68362306a36Sopenharmony_ci SLIST_REMOVE_HEAD(&exported_labels, links); 68462306a36Sopenharmony_ci fprintf(ofile, "#define\tLABEL_%-8s\t0x%02x\n", 68562306a36Sopenharmony_ci curnode->symbol->name, 68662306a36Sopenharmony_ci curnode->symbol->info.linfo->address); 68762306a36Sopenharmony_ci free(curnode); 68862306a36Sopenharmony_ci } 68962306a36Sopenharmony_ci} 69062306a36Sopenharmony_ci 691