struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / sdas / linksrc / lkhead.c
blobf7970a05d430dd9b32c6fe79baef0a71451f921e
1 /* lkhead.c */
3 /*
4 * Copyright (C) 1989-2009 Alan R. Baldwin
6 * This program 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.
11 * This program 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.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * Alan R. Baldwin
21 * 721 Berkeley St.
22 * Kent, Ohio 44240
25 #include "aslink.h"
27 /*Module lkhead.c
29 * The module lkhead.c contains the function newhead() which
30 * creates a head structure, the function module() which
31 * loads the module name into the current head structure,
32 * and newmode() which loads the linker merge modes.
34 * lkhead.c contains the following functions:
35 * VOID newhead()
36 * VOID newmode()
37 * VOID module()
39 * lkhead.c contains no local variables.
42 /*)Function VOID newhead()
44 * The function newhead() creates a head structure. All head
45 * structures are linked to form a linked list of head structures
46 * with the current head structure at the tail of the list.
48 * local variables:
49 * int i evaluation value
50 * char id[] temporary string
51 * head * thp temporary pointer
52 * to a header structure
54 * global variables:
55 * area *ap Pointer to the current
56 * area structure
57 * lfile *cfp The pointer *cfp points to the
58 * current lfile structure
59 * head *headp The pointer to the first
60 * head structure of a linked list
61 * head *hp Pointer to the current
62 * head structure
64 * functions called:
65 * a_uint expr() lkeval.c
66 * a_uint eval() lkeval.c
67 * VOID getid() lklex.c
68 * VOID * new() lksym.c
69 * VOID lkparea() lkarea.c
70 * int more() lklex.c
71 * int symeq() lksym.c
73 * side effects:
74 * A new head structure is created and linked to any
75 * existing linked head structure. The head structure
76 * parameters of file handle, number of areas, number
77 * of global symbols, number of banks and number of
78 * merge modes are loaded into the structure. The
79 * area, bank, symbol, and mode structure lists are created.
80 * The default area "_abs_" is created when the first
81 * head structure is created and an areax structure is
82 * created for every head structure called.
86 * Create a new header entry.
88 * H n areas n global symbols n banks n modes
89 * | | | |
90 * | | | `----- G Lines
91 * | | `------------- B Lines
92 * | `------------------------------ hp->h_nsym
93 * `-------------------------------------- hp->h_narea
96 VOID
97 newhead()
99 int i;
100 char id[NCPS];
101 struct head *thp;
103 hp = (struct head *) new (sizeof(struct head));
104 if (headp == NULL) {
105 headp = hp;
106 } else {
107 thp = headp;
108 while (thp->h_hp)
109 thp = thp->h_hp;
110 thp->h_hp = hp;
113 * Initialize the header
115 hp->h_lfile = cfp; /* Set file pointer */
116 hp->m_id = ""; /* No Module */
118 * Scan for Parameters
120 while (more()) {
121 i = (int) eval();
122 getid(id, -1);
124 * Area pointer list
126 if (symeq("areas", id, 1)) {
127 hp->h_narea = i;
128 if (i)
129 hp->a_list = (struct areax **) new (i*sizeof(struct areax *));
130 } else
132 * Symbol pointer list
134 if (symeq("global", id, 1)) {
135 hp->h_nsym = i;
136 if (i)
137 hp->s_list = (struct sym **) new (i*sizeof(struct sym *));
138 skip(-1);
139 } else
141 * Bank pointer list
143 if (symeq("banks", id, 1)) {
144 hp->h_nbank = i;
145 if (i)
146 hp->b_list = (struct bank **) new (i*sizeof(struct bank *));
147 } else
149 * Mode pointer list
151 if (symeq("modes", id, 1)) {
152 hp->h_nmode = i;
153 if (i)
154 hp->m_list = (struct mode **) new (i*sizeof(struct mode *));
158 * Setup Absolute DEF linkage.
160 lkparea(_abs_);
161 ap->a_flag = A3_ABS;
162 axp->a_addr = 0;
166 /*)Function VOID newmode()
168 * The function newmode() creates / fills in a merge mode
169 * definition for this module.
171 * The MODE structure contains the specification of one of the
172 * assemblers' relocation modes. Each assembler must specify
173 * at least one relocation mode. The relocation specification
174 * allows arbitrarily defined active bits and bit positions.
175 * The 32 element arrays are indexed from 0 to 31.
176 * Index 0 corresponds to bit 0, ..., and 31 corresponds to bit 31
177 * of a normal integer value.
179 * The value an array element defines if the normal integer bit is
180 * active (bit <7> is set, 0x80) and what destination bit
181 * (bits <4:0>, 0 - 31) should be loaded with this normal
182 * integer bit.
184 * The mode structure also contains a flag indicating if bit
185 * positioning is required, a mask word containing the active
186 * bits for merging, and an address paging mask.
188 * local variables:
189 * int index bit index of mode definition
190 * int n counter
191 * struct mode *mp pointer to a mode structure
193 * global variables:
194 * head *headp The pointer to the first
195 * head structure of a linked list
196 * head *hp Pointer to the current
197 * head structure
198 * FILE * stderr standard library error handle
200 * functions called:
201 * a_uint eval() lkexpr.c
202 * int fprintf() c_library
203 * VOID lkexit() lkmain.c
204 * int more() lklex.c
205 * char * new() lksym.c
207 * side effects:
208 * The merge mode structure is created / updated with
209 * the definition values.
212 VOID
213 newmode()
215 int index, n;
216 a_uint v;
217 struct mode *mp;
219 if (headp == NULL) {
220 fprintf(stderr, "No header defined\n");
221 lkexit(ER_FATAL);
224 * Mode number
226 n = (int) eval();
227 if (n >= hp->h_nmode) {
228 fprintf(stderr, "Header mode list overflow\n");
229 lkexit(ER_FATAL);
232 * Bit index
234 index = (int) eval();
235 if (index == 0) {
236 mp = (struct mode *) new (sizeof(struct mode));
237 hp->m_list[n] = mp;
239 * Initialize Mode
241 for (n=0; n<32; n++) {
242 mp->m_def[n] = n;
244 } else {
245 mp = hp->m_list[n];
248 * Load Bits
250 while (more() && (index < 32)) {
251 n = (int) eval();
252 if (mp->m_def[index] != (n & 0x1F)) {
253 mp->m_flag |= 1;
255 mp->m_def[index] = n;
256 if (n & 0x80) {
257 mp->m_dbits |= (((a_uint) 1) << (n & 0x1F));
258 mp->m_sbits |= (((a_uint) 1) << index);
260 index += 1;
263 * Set Missing Low Order Bits
265 for (n=0; n<32; n++) {
266 v = 1 << n;
267 if (mp->m_sbits & v) {
268 break;
269 } else {
270 mp->m_sbits |= v;
276 /*)Function VOID module()
278 * The function module() copies the module name into
279 * the current head structure.
281 * local variables:
282 * char id[] module id string
284 * global variables:
285 * head *headp The pointer to the first
286 * head structure of a linked list
287 * head *hp Pointer to the current
288 * head structure
289 * int lkerr error flag
290 * FILE * stderr c_library
292 * functions called:
293 * int fprintf() c_library
294 * VOID getid() lklex.c
295 * char * strsto() lksym.c
297 * side effects:
298 * The module name is copied into the head structure.
301 VOID
302 module()
304 char id[NCPS];
306 if (headp) {
307 getid(id, -1);
308 hp->m_id = strsto(id);
309 } else {
310 fprintf(stderr, "No header defined\n");
311 lkerr++;