OpenCores
URL https://opencores.org/ocsvn/copyblaze/copyblaze/trunk

Subversion Repositories copyblaze

[/] [copyblaze/] [trunk/] [copyblaze/] [sw/] [tools/] [asm/] [pBlazASM/] [pBlazASM/] [pbSymbols.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ameziti
/*
2
 *  Copyright © 2003..2010 : Henk van Kampen <henk@mediatronix.com>
3
 *
4
 *      This file is part of pBlazASM.
5
 *
6
 *  pBlazASM is free software: you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation, either version 3 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  pBlazASM is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with pBlazASM.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
 
20
/*! \file
21
 * Implements a closed hash table, with linear probing, with an increment of 1
22
 */
23
 
24
#include <malloc.h>
25
#include <stdio.h>
26
#include <ctype.h>
27
#include <stdint.h>
28
#include <string.h>
29
 
30
#include "pbTypes.h"
31
#include "pbSymbols.h"
32
#include "pbOpcodes.h"
33
#include "pbDirectives.h"
34
 
35
// our symbol table
36
#define SIZE 4096UL
37
static symbol_t symbols[ SIZE ] ;
38
 
39
//! \fn static uint32_t hash( const char * text )
40
//  \brief hash function, free after Donald Knuth
41
//  \param text string to hash
42
static uint32_t hash( const char * text ) {
43
        uint64_t r = 0 ;
44
        int i ;
45
 
46
        if ( text != NULL ) {
47
                for ( i = 0 ; i < strlen( text ) ; i += 1 )
48
                        r ^= 0x9E3779B1 * text[ i ] ;
49
                return r & ( SIZE - 1 ) ;
50
        } else
51
                return 0xFFFFFFFF ;
52
}
53
 
54
// add all known words, our keywords
55
 
56
static void add_keyword( const symbol_t * sym ) {
57
        add_symbol( sym->type, sym->subtype, sym->text, sym->value ) ;
58
}
59
 
60
void init_symbol( void ) {
61
        int h ;
62
 
63
        // clear table
64
        for ( h = 0 ; h < SIZE ; h += 1 ) {
65
                symbols[ h ].type = tNONE ;
66
                symbols[ h ].text = NULL ;
67
                symbols[ h ].value = 0 ;
68
        }
69
        // add keywords
70
        for ( h = 0 ; h < sizeof( opcodes ) / sizeof(symbol_t) ; h += 1 )
71
                add_keyword( &opcodes[ h ] ) ;
72
        for ( h = 0 ; h < sizeof( conditions ) / sizeof(symbol_t) ; h += 1 )
73
                add_keyword( &conditions[ h ] ) ;
74
        for ( h = 0 ; h < sizeof( indexes ) / sizeof(symbol_t) ; h += 1 )
75
                add_keyword( &indexes[ h ] ) ;
76
        for ( h = 0 ; h < sizeof( directives ) / sizeof(symbol_t) ; h += 1 )
77
                add_keyword( &directives[ h ] ) ;
78
        for ( h = 0 ; h < sizeof( registers ) / sizeof(symbol_t) ; h += 1 )
79
                add_keyword( &registers[ h ] ) ;
80
}
81
 
82
// find a symbol, returns the found symbol, or NULL
83
symbol_t * find_symbol( const char * text, bool bUpper ) {
84
        int h, p ;
85
        char buf[ 256 ], *s ;
86
 
87
        if (!text)
88
                return NULL ;
89
 
90
        // uppercase only?
91
        strcpy( buf, text ) ;
92
        for ( s = buf ; bUpper && *s != '\0' ; s++ )
93
                *s = toupper( *s ) ;
94
 
95
        // compute 1st entry
96
        p = hash( buf ) ;
97
        if ( p == 0xFFFFFFFF )
98
                return NULL ;
99
        // if empty spot, not found
100
        if ( symbols[ p ].text == NULL )
101
                return NULL ;
102
        // if text is equal, found
103
        if ( strcmp( symbols[ p ].text, buf ) == 0 )
104
                return &symbols[ p ] ;
105
        // else maybe next entry
106
        for ( h = ( p + 1 ) & ( SIZE - 1 ) ; h != p ; h = ( h + 1 ) & ( SIZE - 1 ) ) {
107
                if ( symbols[ h ].text == NULL )
108
                        return NULL ;
109
                if ( strcmp( symbols[ h ].text, buf ) == 0 )
110
                        return &symbols[ h ] ;
111
        }
112
        return NULL ; // unlikely
113
}
114
 
115
// add a symbol, rehashing is by linear probing
116
// returns false if we want to add an already known symbol
117
bool add_symbol( const type_e type, const subtype_e subtype, const char * text, const uint32_t value ) {
118
        int p = hash( text ) ;
119
        int h = p ;
120
 
121
        if ( p == 0xFFFFFFFF )
122
                return false ;
123
        do {
124
                if ( symbols[ h ].text == NULL ) { // if empty spot, put it here
125
                        symbols[ h ].type = type ;
126
                        symbols[ h ].subtype = subtype ;
127
                        symbols[ h ].text = strdup( text ) ;
128
                        symbols[ h ].value = value ;
129
                        return true ;
130
                } else if ( strcmp( symbols[ h ].text, text ) == 0 ) { // if text is equal, already there?
131
                        if ( symbols[ h ].type == type && symbols[ h ].subtype == subtype && symbols[ h ].value == value )
132
                                return false ; // really same?
133
                }
134
                h = ( h + 1 ) & ( SIZE - 1 ) ; // wrap
135
        } while ( h != p ) ; // full ?
136
        return false ;
137
}
138
 
139
// debug
140
void dump_map( void ) {
141
        int h = 0 ;
142
        int count = 0 ;
143
 
144
        for ( h = 0 ; h < SIZE ; h += 1 )
145
                if ( symbols[ h ].type != tNONE && symbols[ h ].text != NULL )
146
                        printf(
147
                                        "%d-%d: %s, %d, %d, %d\n", h, count += 1, symbols[ h ].text, symbols[ h ].value, symbols[ h ].type,
148
                                        symbols[ h ].subtype ) ;
149
}
150
 
151
// free any allocated storage
152
void free_symbol( void ) {
153
        int h ;
154
 
155
        for ( h = 0 ; h < SIZE ; h += 1 ) {
156
                symbols[ h ].type = tNONE ;
157
                if ( symbols[ h ].text != NULL )
158
                        free( symbols[ h ].text ) ;
159
                symbols[ h ].text = NULL ;
160
                symbols[ h ].value = 0 ;
161
        }
162
}
163
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.