* .gdbinit (pe, ps): Define new commands.
[deliverable/binutils-gdb.git] / gas / symbols.c
CommitLineData
fecd2382 1/* symbols.c -symbol table-
dacf29ea
KR
2 Copyright (C) 1987, 1990, 1991, 1992, 1993, 1994
3 Free Software Foundation, Inc.
6efd877d 4
a39116f1 5 This file is part of GAS, the GNU Assembler.
6efd877d 6
a39116f1
RP
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
6efd877d 11
a39116f1
RP
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
6efd877d 16
a39116f1
RP
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
fecd2382 20
58d4951d 21/* #define DEBUG_SYMS / * to debug symbol list maintenance */
2b68b820 22
6efd877d
KR
23#include <ctype.h>
24
fecd2382
RP
25#include "as.h"
26
27#include "obstack.h" /* For "symbols.h" */
28#include "subsegs.h"
29
30#ifndef WORKING_DOT_WORD
31extern int new_broken_words;
32#endif
fecd2382 33
2b68b820
KR
34/* symbol-name => struct symbol pointer */
35static struct hash_control *sy_hash;
fecd2382 36
a39116f1 37/* Below are commented in "symbols.h". */
6efd877d
KR
38symbolS *symbol_rootP;
39symbolS *symbol_lastP;
40symbolS abs_symbol;
fecd2382 41
dacf29ea
KR
42#ifdef DEBUG_SYMS
43#define debug_verify_symchain verify_symbol_chain
44#else
45#define debug_verify_symchain (void)
46#endif
47
6efd877d 48struct obstack notes;
fecd2382 49
85825401 50static void fb_label_init PARAMS ((void));
fecd2382 51
dacf29ea
KR
52/* symbol_new()
53
54 Return a pointer to a new symbol. Die if we can't make a new
55 symbol. Fill in the symbol's values. Add symbol to end of symbol
56 chain.
57
58 This function should be called in the general case of creating a
59 symbol. However, if the output file symbol table has already been
60 set, and you are certain that this symbol won't be wanted in the
61 output file, you can call symbol_create. */
fecd2382 62
6efd877d 63symbolS *
604633ae 64symbol_new (name, segment, valu, frag)
dacf29ea
KR
65 const char *name;
66 segT segment;
67 valueT valu;
68 fragS *frag;
69{
70 symbolS *symbolP = symbol_create (name, segment, valu, frag);
71
72 /*
73 * Link to end of symbol chain.
74 */
75#ifdef BFD_ASSEMBLER
76 {
77 extern int symbol_table_frozen;
78 if (symbol_table_frozen)
79 abort ();
80 }
81#endif
82 symbol_append (symbolP, symbol_lastP, &symbol_rootP, &symbol_lastP);
83 debug_verify_symchain (symbol_rootP, symbol_lastP);
84
85 return symbolP;
86}
87
88symbolS *
89symbol_create (name, segment, valu, frag)
90 const char *name; /* It is copied, the caller can destroy/modify */
6efd877d 91 segT segment; /* Segment identifier (SEG_<something>) */
604633ae 92 valueT valu; /* Symbol value */
6efd877d 93 fragS *frag; /* Associated fragment */
fecd2382 94{
6efd877d
KR
95 unsigned int name_length;
96 char *preserved_copy_of_name;
97 symbolS *symbolP;
98
99 name_length = strlen (name) + 1; /* +1 for \0 */
100 obstack_grow (&notes, name, name_length);
101 preserved_copy_of_name = obstack_finish (&notes);
2b68b820
KR
102#ifdef STRIP_UNDERSCORE
103 if (preserved_copy_of_name[0] == '_')
104 preserved_copy_of_name++;
105#endif
dacf29ea
KR
106
107#ifdef tc_canonicalize_symbol_name
108 preserved_copy_of_name =
109 tc_canonicalize_symbol_name (preserved_copy_of_name);
110#endif
111
6efd877d
KR
112 symbolP = (symbolS *) obstack_alloc (&notes, sizeof (symbolS));
113
114 /* symbol must be born in some fixed state. This seems as good as any. */
115 memset (symbolP, 0, sizeof (symbolS));
116
2b68b820
KR
117#ifdef BFD_ASSEMBLER
118 symbolP->bsym = bfd_make_empty_symbol (stdoutput);
119 assert (symbolP->bsym != 0);
120 symbolP->bsym->udata = (PTR) symbolP;
121#endif
6efd877d 122 S_SET_NAME (symbolP, preserved_copy_of_name);
6efd877d
KR
123
124 S_SET_SEGMENT (symbolP, segment);
604633ae 125 S_SET_VALUE (symbolP, valu);
dacf29ea 126 symbol_clear_list_pointers (symbolP);
6efd877d
KR
127
128 symbolP->sy_frag = frag;
2b68b820 129#ifndef BFD_ASSEMBLER
6efd877d 130 symbolP->sy_number = ~0;
0cafaab1 131 symbolP->sy_name_offset = (unsigned int) ~0;
2b68b820 132#endif
6efd877d 133
6efd877d
KR
134 obj_symbol_new_hook (symbolP);
135
dacf29ea
KR
136#ifdef tc_symbol_new_hook
137 tc_symbol_new_hook (symbolP);
138#endif
fecd2382 139
2b68b820
KR
140 return symbolP;
141}
fecd2382 142\f
6efd877d 143
fecd2382
RP
144/*
145 * colon()
146 *
147 * We have just seen "<name>:".
148 * Creates a struct symbol unless it already exists.
149 *
150 * Gripes if we are redefining a symbol incompatibly (and ignores it).
151 *
152 */
6efd877d
KR
153void
154colon (sym_name) /* just seen "x:" - rattle symbols & frags */
155 register char *sym_name; /* symbol name, as a cannonical string */
156 /* We copy this string: OK to alter later. */
fecd2382 157{
6efd877d
KR
158 register symbolS *symbolP; /* symbol we are working with */
159
fecd2382 160#ifdef LOCAL_LABELS_DOLLAR
2b68b820
KR
161 /* Sun local labels go out of scope whenever a non-local symbol is
162 defined. */
6efd877d
KR
163
164 if (*sym_name != 'L')
165 dollar_label_clear ();
166#endif /* LOCAL_LABELS_DOLLAR */
167
fecd2382 168#ifndef WORKING_DOT_WORD
6efd877d
KR
169 if (new_broken_words)
170 {
171 struct broken_word *a;
172 int possible_bytes;
173 fragS *frag_tmp;
174 char *frag_opcode;
175
2b68b820
KR
176 extern const int md_short_jump_size;
177 extern const int md_long_jump_size;
178 possible_bytes = (md_short_jump_size
179 + new_broken_words * md_long_jump_size);
6efd877d
KR
180
181 frag_tmp = frag_now;
182 frag_opcode = frag_var (rs_broken_word,
183 possible_bytes,
184 possible_bytes,
185 (relax_substateT) 0,
186 (symbolS *) broken_words,
187 0L,
188 NULL);
189
190 /* We want to store the pointer to where to insert the jump table in the
2b68b820
KR
191 fr_opcode of the rs_broken_word frag. This requires a little
192 hackery. */
193 while (frag_tmp
194 && (frag_tmp->fr_type != rs_broken_word
195 || frag_tmp->fr_opcode))
6efd877d
KR
196 frag_tmp = frag_tmp->fr_next;
197 know (frag_tmp);
198 frag_tmp->fr_opcode = frag_opcode;
199 new_broken_words = 0;
200
201 for (a = broken_words; a && a->dispfrag == 0; a = a->next_broken_word)
202 a->dispfrag = frag_tmp;
203 }
204#endif /* WORKING_DOT_WORD */
205
206 if ((symbolP = symbol_find (sym_name)) != 0)
207 {
2b68b820
KR
208#ifdef RESOLVE_SYMBOL_REDEFINITION
209 if (RESOLVE_SYMBOL_REDEFINITION (symbolP))
6efd877d 210 return;
2b68b820 211#endif
6efd877d 212 /*
2b68b820
KR
213 * Now check for undefined symbols
214 */
6efd877d
KR
215 if (!S_IS_DEFINED (symbolP))
216 {
217 if (S_GET_VALUE (symbolP) == 0)
218 {
219 symbolP->sy_frag = frag_now;
2b68b820
KR
220#ifdef OBJ_VMS
221 S_GET_OTHER(symbolP) = const_flag;
fecd2382 222#endif
2b68b820 223 S_SET_VALUE (symbolP, (valueT) ((char*)obstack_next_free (&frags) - frag_now->fr_literal));
6efd877d 224 S_SET_SEGMENT (symbolP, now_seg);
fecd2382 225#ifdef N_UNDF
6efd877d 226 know (N_UNDF == 0);
fecd2382 227#endif /* if we have one, it better be zero. */
6efd877d
KR
228
229 }
230 else
231 {
232 /*
2b68b820
KR
233 * There are still several cases to check:
234 * A .comm/.lcomm symbol being redefined as
235 * initialized data is OK
236 * A .comm/.lcomm symbol being redefined with
237 * a larger size is also OK
238 *
239 * This only used to be allowed on VMS gas, but Sun cc
240 * on the sparc also depends on it.
241 */
242
243 if (((!S_IS_DEBUG (symbolP)
244 && !S_IS_DEFINED (symbolP)
245 && S_IS_EXTERNAL (symbolP))
246 || S_GET_SEGMENT (symbolP) == bss_section)
247 && (now_seg == data_section
248 || now_seg == S_GET_SEGMENT (symbolP)))
6efd877d
KR
249 {
250 /*
2b68b820
KR
251 * Select which of the 2 cases this is
252 */
253 if (now_seg != data_section)
6efd877d
KR
254 {
255 /*
2b68b820
KR
256 * New .comm for prev .comm symbol.
257 * If the new size is larger we just
258 * change its value. If the new size
259 * is smaller, we ignore this symbol
260 */
6efd877d 261 if (S_GET_VALUE (symbolP)
2b68b820 262 < ((unsigned) frag_now_fix ()))
6efd877d 263 {
2b68b820 264 S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
6efd877d
KR
265 }
266 }
267 else
268 {
85825401
ILT
269 /* It is a .comm/.lcomm being converted to initialized
270 data. */
6efd877d 271 symbolP->sy_frag = frag_now;
2b68b820
KR
272#ifdef OBJ_VMS
273 S_GET_OTHER(symbolP) = const_flag;
274#endif /* OBJ_VMS */
275 S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
6efd877d
KR
276 S_SET_SEGMENT (symbolP, now_seg); /* keep N_EXT bit */
277 }
278 }
279 else
280 {
2b68b820
KR
281#if defined (S_GET_OTHER) && defined (S_GET_DESC)
282 as_fatal ("Symbol \"%s\" is already defined as \"%s\"/%d.%d.%ld.",
6efd877d
KR
283 sym_name,
284 segment_name (S_GET_SEGMENT (symbolP)),
2b68b820
KR
285 S_GET_OTHER (symbolP), S_GET_DESC (symbolP),
286 (long) S_GET_VALUE (symbolP));
287#else
58d4951d 288 as_fatal ("Symbol \"%s\" is already defined as \"%s\"/%ld.",
6efd877d
KR
289 sym_name,
290 segment_name (S_GET_SEGMENT (symbolP)),
58d4951d 291 (long) S_GET_VALUE (symbolP));
2b68b820 292#endif
6efd877d
KR
293 }
294 } /* if the undefined symbol has no value */
295 }
296 else
297 {
298 /* Don't blow up if the definition is the same */
299 if (!(frag_now == symbolP->sy_frag
2b68b820 300 && S_GET_VALUE (symbolP) == (char*)obstack_next_free (&frags) - frag_now->fr_literal
6efd877d
KR
301 && S_GET_SEGMENT (symbolP) == now_seg))
302 as_fatal ("Symbol %s already defined.", sym_name);
303 } /* if this symbol is not yet defined */
304
305 }
306 else
307 {
308 symbolP = symbol_new (sym_name,
309 now_seg,
2b68b820 310 (valueT) ((char*)obstack_next_free (&frags) - frag_now->fr_literal),
6efd877d 311 frag_now);
2b68b820 312#ifdef OBJ_VMS
6efd877d 313 S_SET_OTHER (symbolP, const_flag);
2b68b820 314#endif /* OBJ_VMS */
fecd2382 315
6efd877d
KR
316 symbol_table_insert (symbolP);
317 } /* if we have seen this symbol before */
1e9cf565
ILT
318
319#ifdef tc_frob_label
320 tc_frob_label (symbolP);
2b68b820 321#endif
1ecd6c4a 322}
fecd2382 323\f
6efd877d 324
fecd2382
RP
325/*
326 * symbol_table_insert()
327 *
328 * Die if we can't insert the symbol.
329 *
330 */
331
6efd877d
KR
332void
333symbol_table_insert (symbolP)
334 symbolS *symbolP;
fecd2382 335{
604633ae 336 register const char *error_string;
6efd877d
KR
337
338 know (symbolP);
339 know (S_GET_NAME (symbolP));
340
0cafaab1 341 if ((error_string = hash_jam (sy_hash, S_GET_NAME (symbolP), (PTR) symbolP)))
6efd877d
KR
342 {
343 as_fatal ("Inserting \"%s\" into symbol table failed: %s",
344 S_GET_NAME (symbolP), error_string);
345 } /* on error */
346} /* symbol_table_insert() */
fecd2382
RP
347\f
348/*
349 * symbol_find_or_make()
350 *
351 * If a symbol name does not exist, create it as undefined, and insert
352 * it into the symbol table. Return a pointer to it.
353 */
6efd877d
KR
354symbolS *
355symbol_find_or_make (name)
356 char *name;
fecd2382 357{
6efd877d
KR
358 register symbolS *symbolP;
359
360 symbolP = symbol_find (name);
361
362 if (symbolP == NULL)
363 {
364 symbolP = symbol_make (name);
365
366 symbol_table_insert (symbolP);
367 } /* if symbol wasn't found */
368
369 return (symbolP);
370} /* symbol_find_or_make() */
371
372symbolS *
373symbol_make (name)
2b68b820 374 CONST char *name;
fecd2382 375{
6efd877d
KR
376 symbolS *symbolP;
377
378 /* Let the machine description default it, e.g. for register names. */
2b68b820 379 symbolP = md_undefined_symbol ((char *) name);
6efd877d
KR
380
381 if (!symbolP)
2b68b820 382 symbolP = symbol_new (name, undefined_section, (valueT) 0, &zero_address_frag);
6efd877d
KR
383
384 return (symbolP);
385} /* symbol_make() */
fecd2382
RP
386
387/*
388 * symbol_find()
6efd877d 389 *
fecd2382
RP
390 * Implement symbol table lookup.
391 * In: A symbol's name as a string: '\0' can't be part of a symbol name.
392 * Out: NULL if the name was not in the symbol table, else the address
393 * of a struct symbol associated with that name.
394 */
395
6efd877d
KR
396symbolS *
397symbol_find (name)
2b68b820 398 CONST char *name;
fecd2382 399{
a6c6eaf8 400#ifdef STRIP_UNDERSCORE
6efd877d 401 return (symbol_find_base (name, 1));
a6c6eaf8 402#else /* STRIP_UNDERSCORE */
6efd877d 403 return (symbol_find_base (name, 0));
fecd2382 404#endif /* STRIP_UNDERSCORE */
6efd877d 405} /* symbol_find() */
fecd2382 406
6efd877d
KR
407symbolS *
408symbol_find_base (name, strip_underscore)
2b68b820 409 CONST char *name;
6efd877d 410 int strip_underscore;
fecd2382 411{
6efd877d
KR
412 if (strip_underscore && *name == '_')
413 name++;
dacf29ea
KR
414
415#ifdef tc_canonicalize_symbol_name
416 {
417 char *copy;
418
419 copy = (char *) alloca (strlen (name) + 1);
420 strcpy (copy, name);
421 name = tc_canonicalize_symbol_name (copy);
422 }
423#endif
424
6efd877d 425 return ((symbolS *) hash_find (sy_hash, name));
fecd2382
RP
426}
427
428/*
429 * Once upon a time, symbols were kept in a singly linked list. At
430 * least coff needs to be able to rearrange them from time to time, for
431 * which a doubly linked list is much more convenient. Loic did these
432 * as macros which seemed dangerous to me so they're now functions.
433 * xoxorich.
434 */
435
436/* Link symbol ADDME after symbol TARGET in the chain. */
6efd877d
KR
437void
438symbol_append (addme, target, rootPP, lastPP)
439 symbolS *addme;
440 symbolS *target;
441 symbolS **rootPP;
442 symbolS **lastPP;
fecd2382 443{
6efd877d
KR
444 if (target == NULL)
445 {
446 know (*rootPP == NULL);
447 know (*lastPP == NULL);
448 *rootPP = addme;
449 *lastPP = addme;
450 return;
451 } /* if the list is empty */
452
453 if (target->sy_next != NULL)
454 {
fecd2382 455#ifdef SYMBOLS_NEED_BACKPOINTERS
6efd877d 456 target->sy_next->sy_previous = addme;
fecd2382 457#endif /* SYMBOLS_NEED_BACKPOINTERS */
6efd877d
KR
458 }
459 else
460 {
461 know (*lastPP == target);
462 *lastPP = addme;
463 } /* if we have a next */
464
465 addme->sy_next = target->sy_next;
466 target->sy_next = addme;
467
fecd2382 468#ifdef SYMBOLS_NEED_BACKPOINTERS
6efd877d 469 addme->sy_previous = target;
fecd2382 470#endif /* SYMBOLS_NEED_BACKPOINTERS */
2b68b820 471}
fecd2382 472
dacf29ea
KR
473/* Set the chain pointers of SYMBOL to null. */
474void
475symbol_clear_list_pointers (symbolP)
476 symbolS *symbolP;
477{
478 symbolP->sy_next = NULL;
479#ifdef SYMBOLS_NEED_BACKPOINTERS
480 symbolP->sy_previous = NULL;
481#endif
482}
483
fecd2382
RP
484#ifdef SYMBOLS_NEED_BACKPOINTERS
485/* Remove SYMBOLP from the list. */
6efd877d
KR
486void
487symbol_remove (symbolP, rootPP, lastPP)
488 symbolS *symbolP;
489 symbolS **rootPP;
490 symbolS **lastPP;
fecd2382 491{
6efd877d
KR
492 if (symbolP == *rootPP)
493 {
494 *rootPP = symbolP->sy_next;
495 } /* if it was the root */
496
497 if (symbolP == *lastPP)
498 {
499 *lastPP = symbolP->sy_previous;
500 } /* if it was the tail */
501
502 if (symbolP->sy_next != NULL)
503 {
504 symbolP->sy_next->sy_previous = symbolP->sy_previous;
505 } /* if not last */
506
507 if (symbolP->sy_previous != NULL)
508 {
509 symbolP->sy_previous->sy_next = symbolP->sy_next;
510 } /* if not first */
511
dacf29ea 512 debug_verify_symchain (*rootPP, *lastPP);
2b68b820 513}
fecd2382
RP
514
515/* Link symbol ADDME before symbol TARGET in the chain. */
6efd877d
KR
516void
517symbol_insert (addme, target, rootPP, lastPP)
518 symbolS *addme;
519 symbolS *target;
520 symbolS **rootPP;
521 symbolS **lastPP;
fecd2382 522{
6efd877d
KR
523 if (target->sy_previous != NULL)
524 {
525 target->sy_previous->sy_next = addme;
526 }
527 else
528 {
529 know (*rootPP == target);
530 *rootPP = addme;
531 } /* if not first */
532
533 addme->sy_previous = target->sy_previous;
534 target->sy_previous = addme;
535 addme->sy_next = target;
536
dacf29ea 537 debug_verify_symchain (*rootPP, *lastPP);
2b68b820 538}
6efd877d 539
fecd2382
RP
540#endif /* SYMBOLS_NEED_BACKPOINTERS */
541
6efd877d
KR
542void
543verify_symbol_chain (rootP, lastP)
544 symbolS *rootP;
545 symbolS *lastP;
fecd2382 546{
6efd877d
KR
547 symbolS *symbolP = rootP;
548
549 if (symbolP == NULL)
2b68b820 550 return;
6efd877d
KR
551
552 for (; symbol_next (symbolP) != NULL; symbolP = symbol_next (symbolP))
553 {
fecd2382 554#ifdef SYMBOLS_NEED_BACKPOINTERS
6efd877d 555 know (symbolP->sy_next->sy_previous == symbolP);
2b68b820
KR
556#else
557 /* Walk the list anyways, to make sure pointers are still good. */
604633ae 558 ;
fecd2382 559#endif /* SYMBOLS_NEED_BACKPOINTERS */
2b68b820 560 }
6efd877d 561
2b68b820
KR
562 assert (lastP == symbolP);
563}
6efd877d 564
2b68b820
KR
565void
566verify_symbol_chain_2 (sym)
567 symbolS *sym;
568{
569 symbolS *p = sym, *n = sym;
570#ifdef SYMBOLS_NEED_BACKPOINTERS
571 while (symbol_previous (p))
572 p = symbol_previous (p);
573#endif
574 while (symbol_next (n))
575 n = symbol_next (n);
576 verify_symbol_chain (p, n);
577}
6efd877d 578
5868b1fe
ILT
579/* Resolve the value of a symbol. This is called during the final
580 pass over the symbol table to resolve any symbols with complex
581 values. */
582
583void
584resolve_symbol_value (symp)
585 symbolS *symp;
586{
0cafaab1
ILT
587 int resolved;
588
5868b1fe
ILT
589 if (symp->sy_resolved)
590 return;
591
0cafaab1
ILT
592 resolved = 0;
593
5868b1fe
ILT
594 if (symp->sy_resolving)
595 {
596 as_bad ("Symbol definition loop encountered at %s",
597 S_GET_NAME (symp));
598 S_SET_VALUE (symp, (valueT) 0);
0cafaab1 599 resolved = 1;
5868b1fe
ILT
600 }
601 else
602 {
5ac34ac3
ILT
603 offsetT left, right, val;
604 segT seg_left, seg_right;
605
5868b1fe
ILT
606 symp->sy_resolving = 1;
607
5ac34ac3 608 switch (symp->sy_value.X_op)
5868b1fe 609 {
5ac34ac3
ILT
610 case O_absent:
611 S_SET_VALUE (symp, 0);
612 /* Fall through. */
613 case O_constant:
614 S_SET_VALUE (symp, S_GET_VALUE (symp) + symp->sy_frag->fr_address);
615 if (S_GET_SEGMENT (symp) == expr_section)
616 S_SET_SEGMENT (symp, absolute_section);
0cafaab1 617 resolved = 1;
5ac34ac3
ILT
618 break;
619
620 case O_symbol:
5868b1fe
ILT
621 resolve_symbol_value (symp->sy_value.X_add_symbol);
622
623#ifdef obj_frob_forward_symbol
624 /* Some object formats need to forward the segment. */
625 obj_frob_forward_symbol (symp);
626#endif
627
628 S_SET_VALUE (symp,
629 (symp->sy_value.X_add_number
630 + symp->sy_frag->fr_address
631 + S_GET_VALUE (symp->sy_value.X_add_symbol)));
5ac34ac3
ILT
632 if (S_GET_SEGMENT (symp) == expr_section
633 || S_GET_SEGMENT (symp) == undefined_section)
634 S_SET_SEGMENT (symp,
635 S_GET_SEGMENT (symp->sy_value.X_add_symbol));
0cafaab1
ILT
636
637 resolved = symp->sy_value.X_add_symbol->sy_resolved;
5ac34ac3
ILT
638 break;
639
640 case O_uminus:
641 case O_bit_not:
642 resolve_symbol_value (symp->sy_value.X_add_symbol);
643 if (symp->sy_value.X_op == O_uminus)
644 val = - S_GET_VALUE (symp->sy_value.X_add_symbol);
645 else
646 val = ~ S_GET_VALUE (symp->sy_value.X_add_symbol);
647 S_SET_VALUE (symp,
648 (val
649 + symp->sy_value.X_add_number
650 + symp->sy_frag->fr_address));
651 if (S_GET_SEGMENT (symp) == expr_section
652 || S_GET_SEGMENT (symp) == undefined_section)
653 S_SET_SEGMENT (symp, absolute_section);
0cafaab1 654 resolved = symp->sy_value.X_add_symbol->sy_resolved;
5ac34ac3
ILT
655 break;
656
657 case O_multiply:
658 case O_divide:
659 case O_modulus:
660 case O_left_shift:
661 case O_right_shift:
662 case O_bit_inclusive_or:
663 case O_bit_or_not:
664 case O_bit_exclusive_or:
665 case O_bit_and:
666 case O_add:
667 case O_subtract:
c978e704 668 resolve_symbol_value (symp->sy_value.X_add_symbol);
5ac34ac3
ILT
669 resolve_symbol_value (symp->sy_value.X_op_symbol);
670 seg_left = S_GET_SEGMENT (symp->sy_value.X_add_symbol);
671 seg_right = S_GET_SEGMENT (symp->sy_value.X_op_symbol);
672 if (seg_left != seg_right
673 && seg_left != undefined_section
674 && seg_right != undefined_section)
675 as_bad ("%s is operation on symbols in different sections",
c978e704 676 S_GET_NAME (symp));
5ac34ac3
ILT
677 if ((S_GET_SEGMENT (symp->sy_value.X_add_symbol)
678 != absolute_section)
679 && symp->sy_value.X_op != O_subtract)
680 as_bad ("%s is illegal operation on non-absolute symbols",
681 S_GET_NAME (symp));
682 left = S_GET_VALUE (symp->sy_value.X_add_symbol);
683 right = S_GET_VALUE (symp->sy_value.X_op_symbol);
684 switch (symp->sy_value.X_op)
685 {
686 case O_multiply: val = left * right; break;
687 case O_divide: val = left / right; break;
688 case O_modulus: val = left % right; break;
689 case O_left_shift: val = left << right; break;
690 case O_right_shift: val = left >> right; break;
691 case O_bit_inclusive_or: val = left | right; break;
692 case O_bit_or_not: val = left |~ right; break;
693 case O_bit_exclusive_or: val = left ^ right; break;
694 case O_bit_and: val = left & right; break;
695 case O_add: val = left + right; break;
696 case O_subtract: val = left - right; break;
697 default: abort ();
698 }
c978e704
ILT
699 S_SET_VALUE (symp,
700 (symp->sy_value.X_add_number
701 + symp->sy_frag->fr_address
5ac34ac3
ILT
702 + val));
703 if (S_GET_SEGMENT (symp) == expr_section
704 || S_GET_SEGMENT (symp) == undefined_section)
705 S_SET_SEGMENT (symp, absolute_section);
0cafaab1
ILT
706 resolved = (symp->sy_value.X_add_symbol->sy_resolved
707 && symp->sy_value.X_op_symbol->sy_resolved);
5ac34ac3
ILT
708 break;
709
710 case O_register:
711 case O_big:
712 case O_illegal:
0cafaab1
ILT
713 /* Give an error (below) if not in expr_section. We don't
714 want to worry about expr_section symbols, because they
715 are fictional (they are created as part of expression
716 resolution), and any problems may not actually mean
717 anything. */
5ac34ac3 718 break;
5868b1fe
ILT
719 }
720 }
721
0cafaab1
ILT
722 /* Don't worry if we can't resolve an expr_section symbol. */
723 if (resolved)
724 symp->sy_resolved = 1;
725 else if (S_GET_SEGMENT (symp) != expr_section)
726 {
727 as_bad ("can't resolve value for symbol \"%s\"", S_GET_NAME (symp));
728 symp->sy_resolved = 1;
729 }
5868b1fe
ILT
730}
731
6efd877d
KR
732#ifdef LOCAL_LABELS_DOLLAR
733
734/* Dollar labels look like a number followed by a dollar sign. Eg, "42$".
735 They are *really* local. That is, they go out of scope whenever we see a
736 label that isn't local. Also, like fb labels, there can be multiple
737 instances of a dollar label. Therefor, we name encode each instance with
738 the instance number, keep a list of defined symbols separate from the real
739 symbol table, and we treat these buggers as a sparse array. */
740
2b68b820
KR
741static long *dollar_labels;
742static long *dollar_label_instances;
743static char *dollar_label_defines;
744static long dollar_label_count;
604633ae 745static unsigned long dollar_label_max;
6efd877d
KR
746
747int
748dollar_label_defined (label)
749 long label;
750{
751 long *i;
752
753 know ((dollar_labels != NULL) || (dollar_label_count == 0));
754
755 for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
2b68b820
KR
756 if (*i == label)
757 return dollar_label_defines[i - dollar_labels];
6efd877d
KR
758
759 /* if we get here, label isn't defined */
2b68b820 760 return 0;
6efd877d
KR
761} /* dollar_label_defined() */
762
763static int
764dollar_label_instance (label)
765 long label;
766{
767 long *i;
768
769 know ((dollar_labels != NULL) || (dollar_label_count == 0));
770
771 for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
2b68b820
KR
772 if (*i == label)
773 return (dollar_label_instances[i - dollar_labels]);
6efd877d 774
2b68b820
KR
775 /* If we get here, we haven't seen the label before, therefore its instance
776 count is zero. */
777 return 0;
778}
6efd877d
KR
779
780void
781dollar_label_clear ()
782{
604633ae 783 memset (dollar_label_defines, '\0', (unsigned int) dollar_label_count);
2b68b820 784}
6efd877d
KR
785
786#define DOLLAR_LABEL_BUMP_BY 10
787
788void
789define_dollar_label (label)
790 long label;
791{
792 long *i;
793
794 for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
2b68b820
KR
795 if (*i == label)
796 {
797 ++dollar_label_instances[i - dollar_labels];
798 dollar_label_defines[i - dollar_labels] = 1;
799 return;
800 }
6efd877d
KR
801
802 /* if we get to here, we don't have label listed yet. */
803
804 if (dollar_labels == NULL)
805 {
806 dollar_labels = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long));
807 dollar_label_instances = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long));
808 dollar_label_defines = xmalloc (DOLLAR_LABEL_BUMP_BY);
809 dollar_label_max = DOLLAR_LABEL_BUMP_BY;
810 dollar_label_count = 0;
6efd877d
KR
811 }
812 else if (dollar_label_count == dollar_label_max)
813 {
814 dollar_label_max += DOLLAR_LABEL_BUMP_BY;
815 dollar_labels = (long *) xrealloc ((char *) dollar_labels,
816 dollar_label_max * sizeof (long));
817 dollar_label_instances = (long *) xrealloc ((char *) dollar_label_instances,
818 dollar_label_max * sizeof (long));
819 dollar_label_defines = xrealloc (dollar_label_defines, dollar_label_max);
820 } /* if we needed to grow */
821
822 dollar_labels[dollar_label_count] = label;
823 dollar_label_instances[dollar_label_count] = 1;
824 dollar_label_defines[dollar_label_count] = 1;
825 ++dollar_label_count;
2b68b820 826}
6efd877d
KR
827
828/*
829 * dollar_label_name()
830 *
831 * Caller must copy returned name: we re-use the area for the next name.
832 *
2b68b820
KR
833 * The mth occurence of label n: is turned into the symbol "Ln^Am"
834 * where n is the label number and m is the instance number. "L" makes
835 * it a label discarded unless debugging and "^A"('\1') ensures no
836 * ordinary symbol SHOULD get the same name as a local label
837 * symbol. The first "4:" is "L4^A1" - the m numbers begin at 1.
6efd877d
KR
838 *
839 * fb labels get the same treatment, except that ^B is used in place of ^A.
840 */
841
842char * /* Return local label name. */
843dollar_label_name (n, augend)
844 register long n; /* we just saw "n$:" : n a number */
845 register int augend; /* 0 for current instance, 1 for new instance */
846{
847 long i;
848 /* Returned to caller, then copied. used for created names ("4f") */
849 static char symbol_name_build[24];
850 register char *p;
851 register char *q;
852 char symbol_name_temporary[20]; /* build up a number, BACKWARDS */
853
854 know (n >= 0);
855 know (augend == 0 || augend == 1);
856 p = symbol_name_build;
857 *p++ = 'L';
858
859 /* Next code just does sprintf( {}, "%d", n); */
860 /* label number */
861 q = symbol_name_temporary;
862 for (*q++ = 0, i = n; i; ++q)
863 {
864 *q = i % 10 + '0';
865 i /= 10;
866 }
867 while ((*p = *--q) != '\0')
868 ++p;
869
870 *p++ = 1; /* ^A */
871
872 /* instance number */
873 q = symbol_name_temporary;
874 for (*q++ = 0, i = dollar_label_instance (n) + augend; i; ++q)
875 {
876 *q = i % 10 + '0';
877 i /= 10;
878 }
879 while ((*p++ = *--q) != '\0');;
880
881 /* The label, as a '\0' ended string, starts at symbol_name_build. */
2b68b820
KR
882 return symbol_name_build;
883}
6efd877d
KR
884
885#endif /* LOCAL_LABELS_DOLLAR */
886
887#ifdef LOCAL_LABELS_FB
888
889/*
890 * Sombody else's idea of local labels. They are made by "n:" where n
891 * is any decimal digit. Refer to them with
892 * "nb" for previous (backward) n:
893 * or "nf" for next (forward) n:.
894 *
895 * We do a little better and let n be any number, not just a single digit, but
896 * since the other guy's assembler only does ten, we treat the first ten
897 * specially.
898 *
899 * Like someone else's assembler, we have one set of local label counters for
900 * entire assembly, not one set per (sub)segment like in most assemblers. This
901 * implies that one can refer to a label in another segment, and indeed some
902 * crufty compilers have done just that.
903 *
904 * Since there could be a LOT of these things, treat them as a sparse array.
905 */
906
907#define FB_LABEL_SPECIAL (10)
908
909static long fb_low_counter[FB_LABEL_SPECIAL];
910static long *fb_labels;
911static long *fb_label_instances;
eec0de3f
KR
912static long fb_label_count;
913static long fb_label_max;
6efd877d
KR
914
915/* this must be more than FB_LABEL_SPECIAL */
916#define FB_LABEL_BUMP_BY (FB_LABEL_SPECIAL + 6)
917
918static void
919fb_label_init ()
920{
921 memset ((void *) fb_low_counter, '\0', sizeof (fb_low_counter));
6efd877d
KR
922} /* fb_label_init() */
923
924/* add one to the instance number of this fb label */
925void
926fb_label_instance_inc (label)
927 long label;
928{
929 long *i;
930
931 if (label < FB_LABEL_SPECIAL)
932 {
933 ++fb_low_counter[label];
934 return;
935 }
936
e154ecf4 937 if (fb_labels != NULL)
6efd877d 938 {
e154ecf4
ILT
939 for (i = fb_labels + FB_LABEL_SPECIAL;
940 i < fb_labels + fb_label_count; ++i)
6efd877d 941 {
e154ecf4
ILT
942 if (*i == label)
943 {
944 ++fb_label_instances[i - fb_labels];
945 return;
946 } /* if we find it */
947 } /* for each existing label */
948 }
6efd877d
KR
949
950 /* if we get to here, we don't have label listed yet. */
951
952 if (fb_labels == NULL)
953 {
954 fb_labels = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long));
955 fb_label_instances = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long));
956 fb_label_max = FB_LABEL_BUMP_BY;
957 fb_label_count = FB_LABEL_SPECIAL;
958
959 }
960 else if (fb_label_count == fb_label_max)
961 {
962 fb_label_max += FB_LABEL_BUMP_BY;
963 fb_labels = (long *) xrealloc ((char *) fb_labels,
964 fb_label_max * sizeof (long));
965 fb_label_instances = (long *) xrealloc ((char *) fb_label_instances,
966 fb_label_max * sizeof (long));
967 } /* if we needed to grow */
968
969 fb_labels[fb_label_count] = label;
970 fb_label_instances[fb_label_count] = 1;
971 ++fb_label_count;
1ecd6c4a 972}
6efd877d
KR
973
974static long
975fb_label_instance (label)
976 long label;
977{
978 long *i;
979
980 if (label < FB_LABEL_SPECIAL)
981 {
982 return (fb_low_counter[label]);
983 }
984
e154ecf4 985 if (fb_labels != NULL)
6efd877d 986 {
e154ecf4
ILT
987 for (i = fb_labels + FB_LABEL_SPECIAL;
988 i < fb_labels + fb_label_count; ++i)
6efd877d 989 {
e154ecf4
ILT
990 if (*i == label)
991 {
992 return (fb_label_instances[i - fb_labels]);
993 } /* if we find it */
994 } /* for each existing label */
995 }
6efd877d 996
e154ecf4
ILT
997 /* We didn't find the label, so this must be a reference to the
998 first instance. */
999 return 0;
2b68b820 1000}
6efd877d
KR
1001
1002/*
1003 * fb_label_name()
1004 *
1005 * Caller must copy returned name: we re-use the area for the next name.
1006 *
2b68b820
KR
1007 * The mth occurence of label n: is turned into the symbol "Ln^Bm"
1008 * where n is the label number and m is the instance number. "L" makes
1009 * it a label discarded unless debugging and "^B"('\2') ensures no
1010 * ordinary symbol SHOULD get the same name as a local label
1011 * symbol. The first "4:" is "L4^B1" - the m numbers begin at 1.
6efd877d 1012 *
2b68b820 1013 * dollar labels get the same treatment, except that ^A is used in place of ^B. */
6efd877d
KR
1014
1015char * /* Return local label name. */
1016fb_label_name (n, augend)
1017 long n; /* we just saw "n:", "nf" or "nb" : n a number */
1018 long augend; /* 0 for nb, 1 for n:, nf */
1019{
1020 long i;
1021 /* Returned to caller, then copied. used for created names ("4f") */
1022 static char symbol_name_build[24];
1023 register char *p;
1024 register char *q;
1025 char symbol_name_temporary[20]; /* build up a number, BACKWARDS */
1026
1027 know (n >= 0);
1028 know (augend == 0 || augend == 1);
1029 p = symbol_name_build;
1030 *p++ = 'L';
1031
1032 /* Next code just does sprintf( {}, "%d", n); */
1033 /* label number */
1034 q = symbol_name_temporary;
1035 for (*q++ = 0, i = n; i; ++q)
1036 {
1037 *q = i % 10 + '0';
1038 i /= 10;
1039 }
1040 while ((*p = *--q) != '\0')
1041 ++p;
1042
1043 *p++ = 2; /* ^B */
1044
1045 /* instance number */
1046 q = symbol_name_temporary;
1047 for (*q++ = 0, i = fb_label_instance (n) + augend; i; ++q)
1048 {
1049 *q = i % 10 + '0';
1050 i /= 10;
1051 }
1052 while ((*p++ = *--q) != '\0');;
1053
1054 /* The label, as a '\0' ended string, starts at symbol_name_build. */
1055 return (symbol_name_build);
1056} /* fb_label_name() */
1057
1058#endif /* LOCAL_LABELS_FB */
fecd2382
RP
1059
1060
a6c6eaf8 1061/*
6efd877d
KR
1062 * decode name that may have been generated by foo_label_name() above. If
1063 * the name wasn't generated by foo_label_name(), then return it unaltered.
a6c6eaf8
RP
1064 * This is used for error messages.
1065 */
a39116f1 1066
6efd877d
KR
1067char *
1068decode_local_label_name (s)
1069 char *s;
a6c6eaf8 1070{
6efd877d
KR
1071 char *p;
1072 char *symbol_decode;
1073 int label_number;
1074 int instance_number;
1075 char *type;
1076 const char *message_format = "\"%d\" (instance number %d of a %s label)";
1077
1078 if (s[0] != 'L')
1079 return (s);
1080
1081 for (label_number = 0, p = s + 1; isdigit (*p); ++p)
1082 {
1083 label_number = (10 * label_number) + *p - '0';
1084 }
1085
1086 if (*p == 1)
1087 {
1088 type = "dollar";
1089 }
1090 else if (*p == 2)
1091 {
1092 type = "fb";
1093 }
1094 else
1095 {
1096 return (s);
1097 }
1098
1099 for (instance_number = 0, p = s + 1; isdigit (*p); ++p)
1100 {
1101 instance_number = (10 * instance_number) + *p - '0';
1102 }
1103
1104 symbol_decode = obstack_alloc (&notes, strlen (message_format) + 30);
1105 (void) sprintf (symbol_decode, message_format, label_number,
1106 instance_number, type);
1107
1108 return (symbol_decode);
1109} /* decode_local_label_name() */
a6c6eaf8 1110
85051959
ILT
1111/* Get the value of a symbol. */
1112
1113valueT
1114S_GET_VALUE (s)
1115 symbolS *s;
1116{
5ac34ac3 1117 if (s->sy_value.X_op != O_constant)
5868b1fe 1118 as_bad ("Attempt to get value of unresolved symbol %s", S_GET_NAME (s));
85051959
ILT
1119 return (valueT) s->sy_value.X_add_number;
1120}
1121
1122/* Set the value of a symbol. */
1123
1124void
1125S_SET_VALUE (s, val)
1126 symbolS *s;
1127 valueT val;
1128{
5ac34ac3 1129 s->sy_value.X_op = O_constant;
85051959 1130 s->sy_value.X_add_number = (offsetT) val;
0cafaab1 1131 s->sy_value.X_unsigned = 0;
85051959
ILT
1132}
1133
2b68b820
KR
1134#ifdef BFD_ASSEMBLER
1135
1136int
1137S_IS_EXTERNAL (s)
1138 symbolS *s;
1139{
1140 flagword flags = s->bsym->flags;
1141
1142 /* sanity check */
0cafaab1 1143 if (flags & BSF_LOCAL && flags & BSF_GLOBAL)
2b68b820
KR
1144 abort ();
1145
0cafaab1 1146 return (flags & BSF_GLOBAL) != 0;
2b68b820
KR
1147}
1148
1149int
1150S_IS_COMMON (s)
1151 symbolS *s;
1152{
0cafaab1 1153 return bfd_is_com_section (s->bsym->section);
2b68b820
KR
1154}
1155
1156int
1157S_IS_DEFINED (s)
1158 symbolS *s;
1159{
1160 return s->bsym->section != undefined_section;
1161}
1162
1163int
1164S_IS_DEBUG (s)
1165 symbolS *s;
1166{
1167 if (s->bsym->flags & BSF_DEBUGGING)
1168 return 1;
1169 return 0;
1170}
1171
1172int
1173S_IS_LOCAL (s)
1174 symbolS *s;
1175{
1176 flagword flags = s->bsym->flags;
1177
1178 /* sanity check */
0cafaab1 1179 if (flags & BSF_LOCAL && flags & BSF_GLOBAL)
2b68b820
KR
1180 abort ();
1181
1182 return (S_GET_NAME (s)
1183 && ! S_IS_DEBUG (s)
1184 && (strchr (S_GET_NAME (s), '\001')
1185 || strchr (S_GET_NAME (s), '\002')
1186 || (S_LOCAL_NAME (s)
dacf29ea 1187 && !flag_keep_locals)));
2b68b820
KR
1188}
1189
1190int
1191S_IS_EXTERN (s)
1192 symbolS *s;
1193{
1194 return S_IS_EXTERNAL (s);
1195}
1196
1197int
1198S_IS_STABD (s)
1199 symbolS *s;
1200{
1201 return S_GET_NAME (s) == 0;
1202}
1203
2b68b820
KR
1204CONST char *
1205S_GET_NAME (s)
1206 symbolS *s;
1207{
1208 return s->bsym->name;
1209}
1210
1211segT
1212S_GET_SEGMENT (s)
1213 symbolS *s;
1214{
1215 return s->bsym->section;
1216}
1217
2b68b820
KR
1218void
1219S_SET_SEGMENT (s, seg)
1220 symbolS *s;
1221 segT seg;
1222{
1223 s->bsym->section = seg;
1224}
1225
1226void
1227S_SET_EXTERNAL (s)
1228 symbolS *s;
1229{
1ecd6c4a
KR
1230 s->bsym->flags |= BSF_GLOBAL;
1231 s->bsym->flags &= ~(BSF_LOCAL|BSF_WEAK);
2b68b820
KR
1232}
1233
1234void
1235S_CLEAR_EXTERNAL (s)
1236 symbolS *s;
1237{
1238 s->bsym->flags |= BSF_LOCAL;
1ecd6c4a
KR
1239 s->bsym->flags &= ~(BSF_GLOBAL|BSF_WEAK);
1240}
1241
1242void
1243S_SET_WEAK (s)
1244 symbolS *s;
1245{
1246 s->bsym->flags |= BSF_WEAK;
1247 s->bsym->flags &= ~(BSF_GLOBAL|BSF_LOCAL);
2b68b820
KR
1248}
1249
1250void
1251S_SET_NAME (s, name)
1252 symbolS *s;
1253 char *name;
1254{
1255 s->bsym->name = name;
1256}
1257#endif /* BFD_ASSEMBLER */
1258
eec0de3f
KR
1259void
1260symbol_begin ()
1261{
1262 symbol_lastP = NULL;
1263 symbol_rootP = NULL; /* In case we have 0 symbols (!!) */
1264 sy_hash = hash_new ();
dacf29ea 1265
eec0de3f
KR
1266 memset ((char *) (&abs_symbol), '\0', sizeof (abs_symbol));
1267#ifdef BFD_ASSEMBLER
dacf29ea 1268#if defined (EMIT_SECTION_SYMBOLS) || !defined (RELOC_REQUIRES_SYMBOL)
eec0de3f 1269 abs_symbol.bsym = bfd_abs_section.symbol;
dacf29ea 1270#endif
eec0de3f
KR
1271#else
1272 /* Can't initialise a union. Sigh. */
1273 S_SET_SEGMENT (&abs_symbol, absolute_section);
1274#endif
dacf29ea
KR
1275 abs_symbol.sy_value.X_op = O_constant;
1276
eec0de3f
KR
1277#ifdef LOCAL_LABELS_FB
1278 fb_label_init ();
1279#endif /* LOCAL_LABELS_FB */
1280}
1281
dacf29ea
KR
1282static int indent_level;
1283
1284static void
1285indent ()
1286{
1287 printf ("%*s", indent_level * 4, "");
1288}
1289
1290void print_expr_1 PARAMS ((FILE *, expressionS *));
1291void print_symbol_value_1 PARAMS ((FILE *, symbolS *));
1292
1293void
1294print_symbol_value_1 (file, sym)
1295 FILE *file;
1296 symbolS *sym;
1297{
1298 const char *name = S_GET_NAME (sym);
1299 if (!name || !name[0])
1300 name = "(unnamed)";
1301 fprintf (file, "sym %lx %s frag %lx", sym, name, (long) sym->sy_frag);
1302 if (sym->written)
1303 fprintf (file, " written");
1304 if (sym->sy_resolved)
1305 fprintf (file, " resolved");
1306 if (sym->sy_resolving)
1307 fprintf (file, " resolving");
1308 if (sym->sy_used_in_reloc)
1309 fprintf (file, " used-in-reloc");
1310 if (sym->sy_used)
1311 fprintf (file, " used");
1312 if (sym->sy_resolved)
1313 {
1314 /* XXX print segment name too */
1315 fprintf (file, " value %lx", (long) S_GET_VALUE (sym));
1316 }
1317 else if (indent_level < 8)
1318 {
1319 indent_level++;
1320 fprintf (file, "\n%*s<", indent_level * 4, "");
1321 print_expr_1 (file, &sym->sy_value);
1322 fprintf (file, ">");
1323 indent_level--;
1324 }
1325 fflush (file);
1326}
1327
1328void
1329print_symbol_value (sym)
1330 symbolS *sym;
1331{
1332 indent_level = 0;
1333 print_symbol_value_1 (stderr, sym);
1334 fprintf (stderr, "\n");
1335}
1336
1337void
1338print_expr_1 (file, exp)
1339 FILE *file;
1340 expressionS *exp;
1341{
1342 fprintf (file, "expr %lx ", (long) exp);
1343 switch (exp->X_op)
1344 {
1345 case O_illegal:
1346 fprintf (file, "illegal");
1347 break;
1348 case O_absent:
1349 fprintf (file, "absent");
1350 break;
1351 case O_constant:
1352 fprintf (file, "constant %lx", (long) exp->X_add_number);
1353 break;
1354 case O_symbol:
1355 indent_level++;
1356 fprintf (file, "symbol\n%*s<", indent_level * 4, "");
1357 print_symbol_value_1 (file, exp->X_add_symbol);
1358 fprintf (file, ">");
1359 maybe_print_addnum:
1360 indent_level--;
1361 if (exp->X_add_number)
1362 fprintf (file, "\n%*s %lx", indent_level * 4, "",
1363 (long) exp->X_add_number);
1364 break;
1365 case O_register:
1366 fprintf (file, "register #%d", (int) exp->X_add_number);
1367 break;
1368 case O_big:
1369 fprintf (file, "big");
1370 break;
1371 case O_uminus:
1372 fprintf (file, "uminus -<");
1373 indent_level++;
1374 print_symbol_value_1 (file, exp->X_add_symbol);
1375 fprintf (file, ">");
1376 goto maybe_print_addnum;
1377 case O_bit_not:
1378 fprintf (file, "bit_not");
1379 break;
1380 case O_multiply:
1381 fprintf (file, "multiply");
1382 break;
1383 case O_divide:
1384 fprintf (file, "divide");
1385 break;
1386 case O_modulus:
1387 fprintf (file, "modulus");
1388 break;
1389 case O_left_shift:
1390 fprintf (file, "lshift");
1391 break;
1392 case O_right_shift:
1393 fprintf (file, "rshift");
1394 break;
1395 case O_bit_inclusive_or:
1396 fprintf (file, "bit_ior");
1397 break;
1398 case O_bit_exclusive_or:
1399 fprintf (file, "bit_xor");
1400 break;
1401 case O_bit_and:
1402 fprintf (file, "bit_and");
1403 break;
1404 case O_add:
1405 indent_level++;
1406 fprintf (file, "add\n%*s<", indent_level * 4, "");
1407 print_symbol_value_1 (file, exp->X_add_symbol);
1408 fprintf (file, ">\n%*s<", indent_level * 4, "");
1409 print_symbol_value_1 (file, exp->X_op_symbol);
1410 fprintf (file, ">");
1411 goto maybe_print_addnum;
1412 case O_subtract:
1413 indent_level++;
1414 fprintf (file, "subtract\n%*s<", indent_level * 4, "");
1415 print_symbol_value_1 (file, exp->X_add_symbol);
1416 fprintf (file, ">\n%*s<", indent_level * 4, "");
1417 print_symbol_value_1 (file, exp->X_op_symbol);
1418 fprintf (file, ">");
1419 goto maybe_print_addnum;
1420 default:
1421 fprintf (file, "{unknown opcode %d}", (int) exp->X_op);
1422 break;
1423 }
1424 fflush (stdout);
1425}
1426
1427void
1428print_expr (exp)
1429 expressionS *exp;
1430{
1431 print_expr_1 (stderr, exp);
1432 fprintf (stderr, "\n");
1433}
1434
8b228fe9 1435/* end of symbols.c */
This page took 0.313254 seconds and 4 git commands to generate.