Add missing ifdef to make m68k-aout targets happy.
[external/binutils.git] / gas / read.c
1 /* read.c - read a source file -
2    Copyright (C) 1986, 1987, 1990, 1991, 1993 Free Software Foundation, Inc.
3
4 This file is part of GAS, the GNU Assembler.
5
6 GAS 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 2, or (at your option)
9 any later version.
10
11 GAS 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 GAS; see the file COPYING.  If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #if 0
21 #define MASK_CHAR (0xFF)        /* If your chars aren't 8 bits, you will
22                                    change this a bit.  But then, GNU isn't
23                                    spozed to run on your machine anyway.
24                                    (RMS is so shortsighted sometimes.)
25                                    */
26 #else
27 #define MASK_CHAR ((int)(unsigned char)-1)
28 #endif
29
30
31 /* This is the largest known floating point format (for now). It will
32    grow when we do 4361 style flonums. */
33
34 #define MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT (16)
35
36 /* Routines that read assembler source text to build spagetti in memory.
37    Another group of these functions is in the expr.c module.  */
38
39 /* for isdigit() */
40 #include <ctype.h>
41
42 #include "as.h"
43 #include "subsegs.h"
44
45 #include "obstack.h"
46 #include "listing.h"
47
48 /* We need this, despite the apparent object format dependency, since
49    it defines stab types, which all object formats can use now. */
50
51 #include "aout/stab_gnu.h"
52
53 #ifndef TC_START_LABEL
54 #define TC_START_LABEL(x,y) (x==':')
55 #endif
56
57 /* The NOP_OPCODE is for the alignment fill value.
58  * fill it a nop instruction so that the disassembler does not choke
59  * on it
60  */
61 #ifndef NOP_OPCODE
62 #define NOP_OPCODE 0x00
63 #endif
64
65 char *input_line_pointer;       /*->next char of source file to parse. */
66
67 #if BITS_PER_CHAR != 8
68 /*  The following table is indexed by[(char)] and will break if
69     a char does not have exactly 256 states (hopefully 0:255!)!  */
70 die horribly;
71 #endif
72
73 #ifndef LEX_AT
74 /* The m88k unfortunately uses @ as a label beginner.  */
75 #define LEX_AT 0
76 #endif
77
78 /* used by is_... macros. our ctype[] */
79 const char lex_type[256] =
80 {
81   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,       /* @ABCDEFGHIJKLMNO */
82   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,       /* PQRSTUVWXYZ[\]^_ */
83   0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,       /* _!"#$%&'()*+,-./ */
84   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,       /* 0123456789:;<=>? */
85   LEX_AT, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,  /* @ABCDEFGHIJKLMNO */
86   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 3,       /* PQRSTUVWXYZ[\]^_ */
87   0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,       /* `abcdefghijklmno */
88   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0,       /* pqrstuvwxyz{|}~. */
89   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
90   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
91   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
92   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
93   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
94   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
95   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
96 };
97
98
99 /*
100  * In: a character.
101  * Out: 1 if this character ends a line.
102  */
103 #define _ (0)
104 char is_end_of_line[256] =
105 {
106 #ifdef CR_EOL
107   _, _, _, _, _, _, _, _, _, _, 99, _, _, 99, _, _,     /* @abcdefghijklmno */
108 #else
109   _, _, _, _, _, _, _, _, _, _, 99, _, _, _, _, _,      /* @abcdefghijklmno */
110 #endif
111   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* */
112 #ifdef TC_HPPA
113   _,99, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* _!"#$%&'()*+,-./ */
114   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* 0123456789:;<=>? */
115 #else
116   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* */
117   _, _, _, _, _, _, _, _, _, _, _, 99, _, _, _, _,      /* 0123456789:;<=>? */
118 #endif
119   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* */
120   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* */
121   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* */
122   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* */
123   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* */
124   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* */
125   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* */
126   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* */
127   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* */
128 };
129 #undef _
130
131 /* Functions private to this file. */
132
133 static char *buffer;    /* 1st char of each buffer of lines is here. */
134 static char *buffer_limit;      /*->1 + last char in buffer. */
135
136 static char *bignum_low;        /* Lowest char of bignum. */
137 static char *bignum_limit;      /* 1st illegal address of bignum. */
138 static char *bignum_high;       /* Highest char of bignum. */
139 /* May point to (bignum_start-1). */
140 /* Never >= bignum_limit. */
141
142 int target_big_endian;
143
144 static char *old_buffer;        /* JF a hack */
145 static char *old_input;
146 static char *old_limit;
147
148 /* Variables for handling include file directory list. */
149
150 char **include_dirs;    /* List of pointers to directories to
151                            search for .include's */
152 int include_dir_count;  /* How many are in the list */
153 int include_dir_maxlen = 1;/* Length of longest in list */
154
155 #ifndef WORKING_DOT_WORD
156 struct broken_word *broken_words;
157 int new_broken_words;
158 #endif
159
160 static char *demand_copy_string PARAMS ((int *lenP));
161 int is_it_end_of_statement PARAMS ((void));
162 unsigned int next_char_of_string PARAMS ((void));
163 static segT get_segmented_expression PARAMS ((expressionS *expP));
164 static segT get_known_segmented_expression PARAMS ((expressionS * expP));
165 static void grow_bignum PARAMS ((void));
166 static void pobegin PARAMS ((void));
167
168 extern int listing;
169 \f
170
171 void
172 read_begin ()
173 {
174   const char *p;
175
176   pobegin ();
177   obj_read_begin_hook ();
178
179   /* Something close -- but not too close -- to a multiple of 1024.
180      The debugging malloc I'm using has 24 bytes of overhead.  */
181   obstack_begin (&notes, 5090);
182   obstack_begin (&cond_obstack, 990);
183
184 #define BIGNUM_BEGIN_SIZE (16)
185   bignum_low = xmalloc ((long) BIGNUM_BEGIN_SIZE);
186   bignum_limit = bignum_low + BIGNUM_BEGIN_SIZE;
187
188   /* Use machine dependent syntax */
189   for (p = line_separator_chars; *p; p++)
190     is_end_of_line[*p] = 1;
191   /* Use more.  FIXME-SOMEDAY. */
192 }
193 \f
194 /* set up pseudo-op tables */
195
196 struct hash_control *po_hash;
197
198 static const pseudo_typeS potable[] =
199 {
200   {"abort", s_abort, 0},
201   {"align", s_align_ptwo, 0},
202   {"ascii", stringer, 0},
203   {"asciz", stringer, 1},
204 /* block */
205   {"byte", cons, 1},
206   {"comm", s_comm, 0},
207   {"data", s_data, 0},
208   {"desc", s_desc, 0},
209 /* dim */
210   {"double", float_cons, 'd'},
211 /* dsect */
212   {"eject", listing_eject, 0},  /* Formfeed listing */
213   {"else", s_else, 0},
214   {"end", s_end, 0},
215   {"endif", s_endif, 0},
216 /* endef */
217   {"equ", s_set, 0},
218 /* err */
219 /* extend */
220   {"extern", s_ignore, 0},      /* We treat all undef as ext */
221   {"appfile", s_app_file, 1},
222   {"appline", s_app_line, 0},
223   {"file", s_app_file, 0},
224   {"fill", s_fill, 0},
225   {"float", float_cons, 'f'},
226   {"global", s_globl, 0},
227   {"globl", s_globl, 0},
228   {"hword", cons, 2},
229   {"if", s_if, 0},
230   {"ifdef", s_ifdef, 0},
231   {"ifeqs", s_ifeqs, 0},
232   {"ifndef", s_ifdef, 1},
233   {"ifnes", s_ifeqs, 1},
234   {"ifnotdef", s_ifdef, 1},
235   {"include", s_include, 0},
236   {"int", cons, 4},
237   {"lcomm", s_lcomm, 0},
238   {"lflags", listing_flags, 0}, /* Listing flags */
239   {"list", listing_list, 1},    /* Turn listing on */
240   {"long", cons, 4},
241   {"lsym", s_lsym, 0},
242   {"nolist", listing_list, 0},  /* Turn listing off */
243   {"octa", big_cons, 16},
244   {"org", s_org, 0},
245   {"psize", listing_psize, 0},  /* set paper size */
246 /* print */
247   {"quad", big_cons, 8},
248   {"sbttl", listing_title, 1},  /* Subtitle of listing */
249 /* scl */
250 /* sect */
251   {"set", s_set, 0},
252   {"short", cons, 2},
253   {"single", float_cons, 'f'},
254 /* size */
255   {"space", s_space, 0},
256   {"stabd", s_stab, 'd'},
257   {"stabn", s_stab, 'n'},
258   {"stabs", s_stab, 's'},
259   {"string", stringer, 1},
260 /* tag */
261   {"text", s_text, 0},
262   {"title", listing_title, 0},  /* Listing title */
263 /* type */
264 /* use */
265 /* val */
266   {"xstabs", s_xstab, 's'},
267   {"word", cons, 2},
268   {NULL}                        /* end sentinel */
269 };
270
271 static void 
272 pobegin ()
273 {
274   char *errtxt;                 /* error text */
275   const pseudo_typeS *pop;
276
277   po_hash = hash_new ();
278
279   /* Do the target-specific pseudo ops. */
280   for (pop = md_pseudo_table; pop->poc_name; pop++)
281     {
282       errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop);
283       if (errtxt && *errtxt)
284         {
285           as_fatal ("error constructing md pseudo-op table");
286         }                       /* on error */
287     }                           /* for each op */
288
289   /* Now object specific.  Skip any that were in the target table. */
290   for (pop = obj_pseudo_table; pop->poc_name; pop++)
291     {
292       errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop);
293       if (errtxt && *errtxt)
294         {
295           if (!strcmp (errtxt, "exists"))
296             {
297 #ifdef DIE_ON_OVERRIDES
298               as_fatal ("pseudo op \".%s\" overridden.\n", pop->poc_name);
299 #endif /* DIE_ON_OVERRIDES */
300               continue;         /* OK if target table overrides. */
301             }
302           else
303             {
304               as_fatal ("error constructing obj pseudo-op table");
305             }                   /* if overridden */
306         }                       /* on error */
307     }                           /* for each op */
308
309   /* Now portable ones.  Skip any that we've seen already. */
310   for (pop = potable; pop->poc_name; pop++)
311     {
312       errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop);
313       if (errtxt && *errtxt)
314         {
315           if (!strcmp (errtxt, "exists"))
316             {
317 #ifdef DIE_ON_OVERRIDES
318               as_fatal ("pseudo op \".%s\" overridden.\n", pop->poc_name);
319 #endif /* DIE_ON_OVERRIDES */
320               continue;         /* OK if target table overrides. */
321             }
322           else
323             {
324               as_fatal ("error constructing obj pseudo-op table");
325             }                   /* if overridden */
326         }                       /* on error */
327     }                           /* for each op */
328
329   return;
330 }                               /* pobegin() */
331 \f
332 #define HANDLE_CONDITIONAL_ASSEMBLY()   \
333   if (ignore_input ())                                  \
334     {                                                   \
335       while (! is_end_of_line[*input_line_pointer++])   \
336         if (input_line_pointer == buffer_limit)         \
337           break;                                        \
338       continue;                                         \
339     }
340
341
342 /*      read_a_source_file()
343  *
344  * We read the file, putting things into a web that
345  * represents what we have been reading.
346  */
347 void 
348 read_a_source_file (name)
349      char *name;
350 {
351   register char c;
352   register char *s;             /* string of symbol, '\0' appended */
353   register int temp;
354   pseudo_typeS *pop;
355
356   buffer = input_scrub_new_file (name);
357
358   listing_file (name);
359   listing_newline ("");
360
361   while ((buffer_limit = input_scrub_next_buffer (&input_line_pointer)) != 0)
362     {                           /* We have another line to parse. */
363       know (buffer_limit[-1] == '\n');  /* Must have a sentinel. */
364     contin:                     /* JF this goto is my fault I admit it.
365                                    Someone brave please re-write the whole
366                                    input section here?  Pleeze???  */
367       while (input_line_pointer < buffer_limit)
368         {
369           /* We have more of this buffer to parse. */
370
371           /*
372            * We now have input_line_pointer->1st char of next line.
373            * If input_line_pointer [-1] == '\n' then we just
374            * scanned another line: so bump line counters.
375            */
376           if (input_line_pointer[-1] == '\n')
377             {
378               bump_line_counters ();
379
380 #ifdef MRI
381               /* Text at the start of a line must be a label, we run down and stick a colon in */
382               if (is_name_beginner (*input_line_pointer))
383                 {
384                   char *line_start = input_line_pointer;
385                   char c = get_symbol_end ();
386                   colon (line_start);
387                   *input_line_pointer = c;
388                   if (c == ':')
389                     input_line_pointer++;
390
391                 }
392 #endif
393             }
394
395
396           /*
397            * We are at the begining of a line, or similar place.
398            * We expect a well-formed assembler statement.
399            * A "symbol-name:" is a statement.
400            *
401            * Depending on what compiler is used, the order of these tests
402            * may vary to catch most common case 1st.
403            * Each test is independent of all other tests at the (top) level.
404            * PLEASE make a compiler that doesn't use this assembler.
405            * It is crufty to waste a compiler's time encoding things for this
406            * assembler, which then wastes more time decoding it.
407            * (And communicating via (linear) files is silly!
408            * If you must pass stuff, please pass a tree!)
409            */
410           if ((c = *input_line_pointer++) == '\t'
411               || c == ' '
412               || c == '\f'
413               || c == 0)
414             {
415               c = *input_line_pointer++;
416             }
417           know (c != ' ');      /* No further leading whitespace. */
418           LISTING_NEWLINE ();
419           /*
420            * C is the 1st significant character.
421            * Input_line_pointer points after that character.
422            */
423           if (is_name_beginner (c))
424             {                   /* want user-defined label or pseudo/opcode */
425               HANDLE_CONDITIONAL_ASSEMBLY ();
426
427               s = --input_line_pointer;
428               c = get_symbol_end ();    /* name's delimiter */
429               /*
430                * C is character after symbol.
431                * That character's place in the input line is now '\0'.
432                * S points to the beginning of the symbol.
433                *   [In case of pseudo-op, s->'.'.]
434                * Input_line_pointer->'\0' where c was.
435                */
436               if (TC_START_LABEL(c, input_line_pointer))
437                 {
438                   colon (s);    /* user-defined label */
439                   *input_line_pointer++ = ':';  /* Put ':' back for error messages' sake. */
440                   /* Input_line_pointer->after ':'. */
441                   SKIP_WHITESPACE ();
442
443
444                 }
445               else if (c == '='
446                        || (input_line_pointer[1] == '='
447 #ifdef TC_EQUAL_IN_INSN
448                            && ! TC_EQUAL_IN_INSN (c, input_line_pointer)
449 #endif
450                            ))
451                 {
452                   equals (s);
453                   demand_empty_rest_of_line ();
454                 }
455               else
456                 {               /* expect pseudo-op or machine instruction */
457 #ifdef MRI
458                   if (!done_pseudo (s))
459
460 #else
461
462                   pop = NULL;
463
464 #ifdef NO_PSEUDO_DOT
465                   /* The m88k uses pseudo-ops without a period.  */
466                   pop = (pseudo_typeS *) hash_find (po_hash, s);
467                   if (pop != NULL && pop->poc_handler == NULL)
468                     pop = NULL;
469 #endif
470
471                   if (pop != NULL || *s == '.')
472                     {
473                       /*
474                        * PSEUDO - OP.
475                        *
476                        * WARNING: c has next char, which may be end-of-line.
477                        * We lookup the pseudo-op table with s+1 because we
478                        * already know that the pseudo-op begins with a '.'.
479                        */
480
481                       if (pop == NULL)
482                         pop = (pseudo_typeS *) hash_find (po_hash, s + 1);
483
484                       /* Print the error msg now, while we still can */
485                       if (pop == NULL)
486                         {
487                           as_bad ("Unknown pseudo-op:  `%s'", s);
488                           *input_line_pointer = c;
489                           s_ignore (0);
490                           break;
491                         }
492
493                       /* Put it back for error messages etc. */
494                       *input_line_pointer = c;
495                       /* The following skip of whitespace is compulsory.
496                          A well shaped space is sometimes all that separates
497                          keyword from operands. */
498                       if (c == ' ' || c == '\t')
499                         {
500                           input_line_pointer++;
501                         }       /* Skip seperator after keyword. */
502                       /*
503                        * Input_line is restored.
504                        * Input_line_pointer->1st non-blank char
505                        * after pseudo-operation.
506                        */
507                       if (!pop)
508                         {
509                           ignore_rest_of_line ();
510                           break;
511                         }
512                       else
513                         {
514                           (*pop->poc_handler) (pop->poc_val);
515                         }       /* if we have one */
516                     }
517                   else
518 #endif
519                     {           /* machine instruction */
520                       /* WARNING: c has char, which may be end-of-line. */
521                       /* Also: input_line_pointer->`\0` where c was. */
522                       *input_line_pointer = c;
523                       while (!is_end_of_line[*input_line_pointer]
524 #ifdef TC_EOL_IN_INSN
525                              || TC_EOL_IN_INSN (input_line_pointer)
526 #endif
527                              )
528                         {
529                           input_line_pointer++;
530                         }
531
532                       c = *input_line_pointer;
533                       *input_line_pointer = '\0';
534
535                       md_assemble (s);  /* Assemble 1 instruction. */
536
537                       *input_line_pointer++ = c;
538
539                       /* We resume loop AFTER the end-of-line from this instruction */
540                     }           /* if (*s=='.') */
541
542                 }               /* if c==':' */
543               continue;
544             }                   /* if (is_name_beginner(c) */
545
546
547           if (is_end_of_line[c])
548             {
549               continue;
550             }                   /* empty statement */
551
552
553 #if defined(LOCAL_LABELS_DOLLAR) || defined(LOCAL_LABELS_FB)
554           if (isdigit (c))
555             {                   /* local label  ("4:") */
556               char *backup = input_line_pointer;
557
558               HANDLE_CONDITIONAL_ASSEMBLY ();
559
560               temp = c - '0';
561
562               while (isdigit (*input_line_pointer))
563                 {
564                   temp = (temp * 10) + *input_line_pointer - '0';
565                   ++input_line_pointer;
566                 }               /* read the whole number */
567
568 #ifdef LOCAL_LABELS_DOLLAR
569               if (*input_line_pointer == '$'
570                   && *(input_line_pointer + 1) == ':')
571                 {
572                   input_line_pointer += 2;
573
574                   if (dollar_label_defined (temp))
575                     {
576                       as_fatal ("label \"%d$\" redefined", temp);
577                     }
578
579                   define_dollar_label (temp);
580                   colon (dollar_label_name (temp, 0));
581                   continue;
582                 }
583 #endif /* LOCAL_LABELS_DOLLAR */
584
585 #ifdef LOCAL_LABELS_FB
586               if (*input_line_pointer++ == ':')
587                 {
588                   fb_label_instance_inc (temp);
589                   colon (fb_label_name (temp, 0));
590                   continue;
591                 }
592 #endif /* LOCAL_LABELS_FB */
593
594               input_line_pointer = backup;
595             }                   /* local label  ("4:") */
596 #endif /* LOCAL_LABELS_DOLLAR or LOCAL_LABELS_FB */
597
598           if (c && strchr (line_comment_chars, c))
599             {                   /* Its a comment.  Better say APP or NO_APP */
600               char *ends;
601               char *new_buf;
602               char *new_tmp;
603               int new_length;
604               char *tmp_buf = 0;
605               extern char *scrub_string, *scrub_last_string;
606
607               bump_line_counters ();
608               s = input_line_pointer;
609               if (strncmp (s, "APP\n", 4))
610                 continue;       /* We ignore it */
611               s += 4;
612
613               ends = strstr (s, "#NO_APP\n");
614
615               if (!ends)
616                 {
617                   int tmp_len;
618                   int num;
619
620                   /* The end of the #APP wasn't in this buffer.  We
621                      keep reading in buffers until we find the #NO_APP
622                      that goes with this #APP  There is one.  The specs
623                      guarentee it. . . */
624                   tmp_len = buffer_limit - s;
625                   tmp_buf = xmalloc (tmp_len + 1);
626                   memcpy (tmp_buf, s, tmp_len);
627                   do
628                     {
629                       new_tmp = input_scrub_next_buffer (&buffer);
630                       if (!new_tmp)
631                         break;
632                       else
633                         buffer_limit = new_tmp;
634                       input_line_pointer = buffer;
635                       ends = strstr (buffer, "#NO_APP\n");
636                       if (ends)
637                         num = ends - buffer;
638                       else
639                         num = buffer_limit - buffer;
640
641                       tmp_buf = xrealloc (tmp_buf, tmp_len + num);
642                       memcpy (tmp_buf, buffer + tmp_len, num);
643                       tmp_len += num;
644                     }
645                   while (!ends);
646
647                   input_line_pointer = ends ? ends + 8 : NULL;
648
649                   s = tmp_buf;
650                   ends = s + tmp_len;
651
652                 }
653               else
654                 {
655                   input_line_pointer = ends + 8;
656                 }
657               new_buf = xmalloc (100);
658               new_length = 100;
659               new_tmp = new_buf;
660
661               scrub_string = s;
662               scrub_last_string = ends;
663               for (;;)
664                 {
665                   int ch;
666
667                   ch = do_scrub_next_char (scrub_from_string, scrub_to_string);
668                   if (ch == EOF)
669                     break;
670                   *new_tmp++ = ch;
671                   if (new_tmp == new_buf + new_length)
672                     {
673                       new_buf = xrealloc (new_buf, new_length + 100);
674                       new_tmp = new_buf + new_length;
675                       new_length += 100;
676                     }
677                 }
678
679               if (tmp_buf)
680                 free (tmp_buf);
681               old_buffer = buffer;
682               old_input = input_line_pointer;
683               old_limit = buffer_limit;
684               buffer = new_buf;
685               input_line_pointer = new_buf;
686               buffer_limit = new_tmp;
687               continue;
688             }
689
690           HANDLE_CONDITIONAL_ASSEMBLY ();
691
692           /* as_warn("Junk character %d.",c);  Now done by ignore_rest */
693           input_line_pointer--; /* Report unknown char as ignored. */
694           ignore_rest_of_line ();
695         }                       /* while (input_line_pointer<buffer_limit) */
696       if (old_buffer)
697         {
698           bump_line_counters ();
699           if (old_input != 0)
700             {
701               buffer = old_buffer;
702               input_line_pointer = old_input;
703               buffer_limit = old_limit;
704               old_buffer = 0;
705               goto contin;
706             }
707         }
708     }                           /* while (more buffers to scan) */
709   input_scrub_close ();         /* Close the input file */
710
711 }                               /* read_a_source_file() */
712
713 void 
714 s_abort ()
715 {
716   as_fatal (".abort detected.  Abandoning ship.");
717 }                               /* s_abort() */
718
719 /* For machines where ".align 4" means align to a 4 byte boundary. */
720 void 
721 s_align_bytes (arg)
722      int arg;
723 {
724   register unsigned int temp;
725   register long temp_fill;
726   unsigned int i = 0;
727   unsigned long max_alignment = 1 << 15;
728
729   if (is_end_of_line[*input_line_pointer])
730     temp = arg;                 /* Default value from pseudo-op table */
731   else
732     temp = get_absolute_expression ();
733
734   if (temp > max_alignment)
735     {
736       as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
737     }
738
739   /*
740      * For the sparc, `.align (1<<n)' actually means `.align n'
741      * so we have to convert it.
742      */
743   if (temp != 0)
744     {
745       for (i = 0; (temp & 1) == 0; temp >>= 1, ++i)
746         ;
747     }
748   if (temp != 1)
749     as_bad ("Alignment not a power of 2");
750
751   temp = i;
752   if (*input_line_pointer == ',')
753     {
754       input_line_pointer++;
755       temp_fill = get_absolute_expression ();
756     }
757   else if (now_seg != data_section && now_seg != bss_section)
758     temp_fill = NOP_OPCODE;
759   else
760     temp_fill = 0;
761   /* Only make a frag if we HAVE to. . . */
762   if (temp && !need_pass_2)
763     frag_align (temp, (int) temp_fill);
764
765   record_alignment (now_seg, temp);
766
767   demand_empty_rest_of_line ();
768 }                               /* s_align_bytes() */
769
770 /* For machines where ".align 4" means align to 2**4 boundary. */
771 void 
772 s_align_ptwo ()
773 {
774   register int temp;
775   register long temp_fill;
776   long max_alignment = 15;
777
778   temp = get_absolute_expression ();
779   if (temp > max_alignment)
780     as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
781   else if (temp < 0)
782     {
783       as_bad ("Alignment negative. 0 assumed.");
784       temp = 0;
785     }
786   if (*input_line_pointer == ',')
787     {
788       input_line_pointer++;
789       temp_fill = get_absolute_expression ();
790     }
791   /* @@ Fix this right for BFD!  */
792   else if (now_seg != data_section && now_seg != bss_section)
793     temp_fill = NOP_OPCODE;
794   else
795     temp_fill = 0;
796   /* Only make a frag if we HAVE to. . . */
797   if (temp && !need_pass_2)
798     frag_align (temp, (int) temp_fill);
799
800   record_alignment (now_seg, temp);
801
802   demand_empty_rest_of_line ();
803 }                               /* s_align_ptwo() */
804
805 void 
806 s_comm ()
807 {
808   register char *name;
809   register char c;
810   register char *p;
811   valueT temp;
812   register symbolS *symbolP;
813
814   name = input_line_pointer;
815   c = get_symbol_end ();
816   /* just after name is now '\0' */
817   p = input_line_pointer;
818   *p = c;
819   SKIP_WHITESPACE ();
820   if (*input_line_pointer != ',')
821     {
822       as_bad ("Expected comma after symbol-name: rest of line ignored.");
823       ignore_rest_of_line ();
824       return;
825     }
826   input_line_pointer++;         /* skip ',' */
827   if ((temp = get_absolute_expression ()) < 0)
828     {
829       as_warn (".COMMon length (%d.) <0! Ignored.", temp);
830       ignore_rest_of_line ();
831       return;
832     }
833   *p = 0;
834   symbolP = symbol_find_or_make (name);
835   *p = c;
836   if (S_IS_DEFINED (symbolP))
837     {
838       as_bad ("Ignoring attempt to re-define symbol");
839       ignore_rest_of_line ();
840       return;
841     }
842   if (S_GET_VALUE (symbolP))
843     {
844       if (S_GET_VALUE (symbolP) != temp)
845         as_bad ("Length of .comm \"%s\" is already %d. Not changed to %d.",
846                 S_GET_NAME (symbolP),
847                 S_GET_VALUE (symbolP),
848                 temp);
849     }
850   else
851     {
852       S_SET_VALUE (symbolP, temp);
853       S_SET_EXTERNAL (symbolP);
854     }
855 #ifdef OBJ_VMS
856   if ( (!temp) || !flagseen['1'])
857     S_GET_OTHER(symbolP) = const_flag;
858 #endif /* not OBJ_VMS */
859   know (symbolP->sy_frag == &zero_address_frag);
860   demand_empty_rest_of_line ();
861 }                               /* s_comm() */
862
863 void
864 s_data ()
865 {
866   segT section;
867   register int temp;
868
869   temp = get_absolute_expression ();
870   if (flagseen['R'])
871     {
872       section = text_section;
873       temp += 1000;
874     }
875   else
876     section = data_section;
877
878 #ifdef BFD_ASSEMBLER
879   subseg_set (section, (subsegT) temp);
880 #else
881   subseg_new (section, (subsegT) temp);
882 #endif
883
884 #ifdef OBJ_VMS
885   const_flag = 0;
886 #endif
887   demand_empty_rest_of_line ();
888 }
889
890 /* Handle the .appfile pseudo-op.  This is automatically generated by
891    do_scrub_next_char when a preprocessor # line comment is seen with
892    a file name.  This default definition may be overridden by the
893    object or CPU specific pseudo-ops.  This function is also the
894    default definition for .file; the APPFILE argument is 1 for
895    .appfile, 0 for .file.  */
896
897 void 
898 s_app_file (appfile)
899      int appfile;
900 {
901   register char *s;
902   int length;
903
904   /* Some assemblers tolerate immediately following '"' */
905   if ((s = demand_copy_string (&length)) != 0)
906     {
907       /* If this is a fake .appfile, a fake newline was inserted into
908          the buffer.  Passing -2 to new_logical_line tells it to
909          account for it.  */
910       new_logical_line (s, appfile ? -2 : -1);
911       demand_empty_rest_of_line ();
912 #ifdef LISTING
913       if (listing)
914         listing_source_file (s);
915 #endif
916     }
917 #ifdef OBJ_COFF
918   c_dot_file_symbol (s);
919 #endif /* OBJ_COFF */
920 #ifdef OBJ_ELF
921   elf_file_symbol (s);
922 #endif
923 }
924
925 /* Handle the .appline pseudo-op.  This is automatically generated by
926    do_scrub_next_char when a preprocessor # line comment is seen.
927    This default definition may be overridden by the object or CPU
928    specific pseudo-ops.  */
929
930 void
931 s_app_line ()
932 {
933   int l;
934
935   /* The given number is that of the next line.  */
936   l = get_absolute_expression () - 1;
937   new_logical_line ((char *) NULL, l);
938 #ifdef LISTING
939   if (listing)
940     listing_source_line (l);
941 #endif
942   demand_empty_rest_of_line ();
943 }
944
945 void 
946 s_fill ()
947 {
948   long temp_repeat = 0;
949   long temp_size = 1;
950   register long temp_fill = 0;
951   char *p;
952
953
954   temp_repeat = get_absolute_expression ();
955   if (*input_line_pointer == ',')
956     {
957       input_line_pointer++;
958       temp_size = get_absolute_expression ();
959       if (*input_line_pointer == ',')
960         {
961           input_line_pointer++;
962           temp_fill = get_absolute_expression ();
963         }
964     }
965   /* This is to be compatible with BSD 4.2 AS, not for any rational reason.  */
966 #define BSD_FILL_SIZE_CROCK_8 (8)
967   if (temp_size > BSD_FILL_SIZE_CROCK_8)
968     {
969       as_warn (".fill size clamped to %d.", BSD_FILL_SIZE_CROCK_8);
970       temp_size = BSD_FILL_SIZE_CROCK_8;
971     }
972   if (temp_size < 0)
973     {
974       as_warn ("Size negative: .fill ignored.");
975       temp_size = 0;
976     }
977   else if (temp_repeat <= 0)
978     {
979       as_warn ("Repeat < 0, .fill ignored");
980       temp_size = 0;
981     }
982
983   if (temp_size && !need_pass_2)
984     {
985       p = frag_var (rs_fill, (int) temp_size, (int) temp_size, (relax_substateT) 0, (symbolS *) 0, temp_repeat, (char *) 0);
986       memset (p, 0, (int) temp_size);
987       /* The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX
988        * flavoured AS.  The following bizzare behaviour is to be
989        * compatible with above.  I guess they tried to take up to 8
990        * bytes from a 4-byte expression and they forgot to sign
991        * extend. Un*x Sux. */
992 #define BSD_FILL_SIZE_CROCK_4 (4)
993       md_number_to_chars (p, temp_fill,
994                           (temp_size > BSD_FILL_SIZE_CROCK_4
995                            ? BSD_FILL_SIZE_CROCK_4
996                            : (int) temp_size));
997       /* Note: .fill (),0 emits no frag (since we are asked to .fill 0 bytes)
998        * but emits no error message because it seems a legal thing to do.
999        * It is a degenerate case of .fill but could be emitted by a compiler.
1000        */
1001     }
1002   demand_empty_rest_of_line ();
1003 }
1004
1005 void 
1006 s_globl ()
1007 {
1008   char *name;
1009   int c;
1010   symbolS *symbolP;
1011
1012   do
1013     {
1014       name = input_line_pointer;
1015       c = get_symbol_end ();
1016       symbolP = symbol_find_or_make (name);
1017       *input_line_pointer = c;
1018       SKIP_WHITESPACE ();
1019       S_SET_EXTERNAL (symbolP);
1020       if (c == ',')
1021         {
1022           input_line_pointer++;
1023           SKIP_WHITESPACE ();
1024           if (*input_line_pointer == '\n')
1025             c = '\n';
1026         }
1027     }
1028   while (c == ',');
1029   demand_empty_rest_of_line ();
1030 }
1031
1032 void 
1033 s_lcomm (needs_align)
1034      /* 1 if this was a ".bss" directive, which may require a 3rd argument
1035         (alignment); 0 if it was an ".lcomm" (2 args only)  */
1036      int needs_align;
1037 {
1038   register char *name;
1039   register char c;
1040   register char *p;
1041   register int temp;
1042   register symbolS *symbolP;
1043   segT current_seg = now_seg;
1044   subsegT current_subseg = now_subseg;
1045   const int max_alignment = 15;
1046   int align = 0;
1047   segT bss_seg = bss_section;
1048
1049   name = input_line_pointer;
1050   c = get_symbol_end ();
1051   p = input_line_pointer;
1052   *p = c;
1053   SKIP_WHITESPACE ();
1054   if (*input_line_pointer != ',')
1055     {
1056       as_bad ("Expected comma after name");
1057       ignore_rest_of_line ();
1058       return;
1059     }
1060
1061   ++input_line_pointer;
1062
1063   if (*input_line_pointer == '\n')
1064     {
1065       as_bad ("Missing size expression");
1066       return;
1067     }
1068
1069   if ((temp = get_absolute_expression ()) < 0)
1070     {
1071       as_warn ("BSS length (%d.) <0! Ignored.", temp);
1072       ignore_rest_of_line ();
1073       return;
1074     }
1075
1076 #ifdef TC_MIPS
1077 #ifdef OBJ_ECOFF
1078   /* For MIPS ECOFF, small objects are put in .sbss.  */
1079   if (temp <= bfd_get_gp_size (stdoutput))
1080     bss_seg = subseg_new (".sbss", 1);
1081 #endif
1082 #endif
1083
1084   if (needs_align)
1085     {
1086       align = 0;
1087       SKIP_WHITESPACE ();
1088       if (*input_line_pointer != ',')
1089         {
1090           as_bad ("Expected comma after size");
1091           ignore_rest_of_line ();
1092           return;
1093         }
1094       input_line_pointer++;
1095       SKIP_WHITESPACE ();
1096       if (*input_line_pointer == '\n')
1097         {
1098           as_bad ("Missing alignment");
1099           return;
1100         }
1101       align = get_absolute_expression ();
1102       if (align > max_alignment)
1103         {
1104           align = max_alignment;
1105           as_warn ("Alignment too large: %d. assumed.", align);
1106         }
1107       else if (align < 0)
1108         {
1109           align = 0;
1110           as_warn ("Alignment negative. 0 assumed.");
1111         }
1112       record_alignment (bss_seg, align);
1113     }                           /* if needs align */
1114
1115   *p = 0;
1116   symbolP = symbol_find_or_make (name);
1117   *p = c;
1118
1119   if (
1120 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1121        S_GET_OTHER (symbolP) == 0 &&
1122        S_GET_DESC (symbolP) == 0 &&
1123 #endif /* OBJ_AOUT or OBJ_BOUT */
1124        (S_GET_SEGMENT (symbolP) == bss_seg
1125         || (!S_IS_DEFINED (symbolP) && S_GET_VALUE (symbolP) == 0)))
1126     {
1127       char *p;
1128
1129 #ifdef BFD_ASSEMBLER
1130       subseg_set (bss_seg, 1);
1131 #else
1132       subseg_new (bss_seg, 1);
1133 #endif
1134
1135       if (align)
1136         frag_align (align, 0);
1137                                         /* detach from old frag */
1138       if (S_GET_SEGMENT (symbolP) == bss_seg)
1139         symbolP->sy_frag->fr_symbol = NULL;
1140
1141       symbolP->sy_frag = frag_now;
1142       p = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP,
1143                     temp, (char *)0);
1144       *p = 0;
1145
1146       S_SET_SEGMENT (symbolP, bss_seg);
1147
1148 #ifdef OBJ_COFF
1149       /* The symbol may already have been created with a preceding
1150          ".globl" directive -- be careful not to step on storage class
1151          in that case.  Otherwise, set it to static. */
1152       if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
1153         {
1154           S_SET_STORAGE_CLASS (symbolP, C_STAT);
1155         }
1156 #endif /* OBJ_COFF */
1157     }
1158   else
1159     {
1160       as_bad ("Ignoring attempt to re-define symbol %s.", name);
1161     }
1162
1163 #ifdef BFD_ASSEMBLER
1164   subseg_set (current_seg, current_subseg);
1165 #else
1166   subseg_new (current_seg, current_subseg);
1167 #endif
1168
1169   demand_empty_rest_of_line ();
1170 }                               /* s_lcomm() */
1171
1172 void
1173 s_long ()
1174 {
1175   cons (4);
1176 }
1177
1178 void
1179 s_int ()
1180 {
1181   cons (4);
1182 }
1183
1184 void 
1185 s_lsym ()
1186 {
1187   register char *name;
1188   register char c;
1189   register char *p;
1190   expressionS exp;
1191   register symbolS *symbolP;
1192
1193   /* we permit ANY defined expression: BSD4.2 demands constants */
1194   name = input_line_pointer;
1195   c = get_symbol_end ();
1196   p = input_line_pointer;
1197   *p = c;
1198   SKIP_WHITESPACE ();
1199   if (*input_line_pointer != ',')
1200     {
1201       *p = 0;
1202       as_bad ("Expected comma after name \"%s\"", name);
1203       *p = c;
1204       ignore_rest_of_line ();
1205       return;
1206     }
1207   input_line_pointer++;
1208   expression (&exp);
1209   if (exp.X_op != O_constant
1210       && exp.X_op != O_register)
1211     {
1212       as_bad ("bad expression");
1213       ignore_rest_of_line ();
1214       return;
1215     }
1216   *p = 0;
1217   symbolP = symbol_find_or_make (name);
1218
1219   /* FIXME-SOON I pulled a (&& symbolP->sy_other == 0 &&
1220      symbolP->sy_desc == 0) out of this test because coff doesn't have
1221      those fields, and I can't see when they'd ever be tripped.  I
1222      don't think I understand why they were here so I may have
1223      introduced a bug. As recently as 1.37 didn't have this test
1224      anyway.  xoxorich. */
1225
1226   if (S_GET_SEGMENT (symbolP) == undefined_section
1227       && S_GET_VALUE (symbolP) == 0)
1228     {
1229       /* The name might be an undefined .global symbol; be sure to
1230          keep the "external" bit. */
1231       S_SET_SEGMENT (symbolP,
1232                      (exp.X_op == O_constant
1233                       ? absolute_section
1234                       : reg_section));
1235       S_SET_VALUE (symbolP, (valueT) exp.X_add_number);
1236     }
1237   else
1238     {
1239       as_bad ("Symbol %s already defined", name);
1240     }
1241   *p = c;
1242   demand_empty_rest_of_line ();
1243 }                               /* s_lsym() */
1244
1245 void 
1246 s_org ()
1247 {
1248   register segT segment;
1249   expressionS exp;
1250   register long temp_fill;
1251   register char *p;
1252   /* Don't believe the documentation of BSD 4.2 AS.  There is no such
1253      thing as a sub-segment-relative origin.  Any absolute origin is
1254      given a warning, then assumed to be segment-relative.  Any
1255      segmented origin expression ("foo+42") had better be in the right
1256      segment or the .org is ignored.
1257
1258      BSD 4.2 AS warns if you try to .org backwards. We cannot because
1259      we never know sub-segment sizes when we are reading code.  BSD
1260      will crash trying to emit negative numbers of filler bytes in
1261      certain .orgs. We don't crash, but see as-write for that code.
1262
1263      Don't make frag if need_pass_2==1.  */
1264   segment = get_known_segmented_expression (&exp);
1265   if (*input_line_pointer == ',')
1266     {
1267       input_line_pointer++;
1268       temp_fill = get_absolute_expression ();
1269     }
1270   else
1271     temp_fill = 0;
1272   if (!need_pass_2)
1273     {
1274       if (segment != now_seg && segment != absolute_section)
1275         as_bad ("Invalid segment \"%s\". Segment \"%s\" assumed.",
1276                 segment_name (segment), segment_name (now_seg));
1277       p = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp.X_add_symbol,
1278                     exp.X_add_number, (char *) 0);
1279       *p = temp_fill;
1280     }                           /* if (ok to make frag) */
1281   demand_empty_rest_of_line ();
1282 }                               /* s_org() */
1283
1284 void 
1285 s_set ()
1286 {
1287   register char *name;
1288   register char delim;
1289   register char *end_name;
1290   register symbolS *symbolP;
1291
1292   /*
1293    * Especial apologies for the random logic:
1294    * this just grew, and could be parsed much more simply!
1295    * Dean in haste.
1296    */
1297   name = input_line_pointer;
1298   delim = get_symbol_end ();
1299   end_name = input_line_pointer;
1300   *end_name = delim;
1301   SKIP_WHITESPACE ();
1302
1303   if (*input_line_pointer != ',')
1304     {
1305       *end_name = 0;
1306       as_bad ("Expected comma after name \"%s\"", name);
1307       *end_name = delim;
1308       ignore_rest_of_line ();
1309       return;
1310     }
1311
1312   input_line_pointer++;
1313   *end_name = 0;
1314
1315   if (name[0] == '.' && name[1] == '\0')
1316     {
1317       /* Turn '. = mumble' into a .org mumble */
1318       register segT segment;
1319       expressionS exp;
1320       register char *ptr;
1321
1322       segment = get_known_segmented_expression (&exp);
1323
1324       if (!need_pass_2)
1325         {
1326           if (segment != now_seg && segment != absolute_section)
1327             as_bad ("Invalid segment \"%s\". Segment \"%s\" assumed.",
1328                     segment_name (segment),
1329                     segment_name (now_seg));
1330           ptr = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp.X_add_symbol,
1331                           exp.X_add_number, (char *) 0);
1332           *ptr = 0;
1333         }                       /* if (ok to make frag) */
1334
1335       *end_name = delim;
1336       return;
1337     }
1338
1339   if ((symbolP = symbol_find (name)) == NULL
1340       && (symbolP = md_undefined_symbol (name)) == NULL)
1341     {
1342       symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
1343 #ifdef OBJ_COFF
1344       /* "set" symbols are local unless otherwise specified. */
1345       SF_SET_LOCAL (symbolP);
1346 #endif /* OBJ_COFF */
1347
1348     }                           /* make a new symbol */
1349
1350   symbol_table_insert (symbolP);
1351
1352   *end_name = delim;
1353   pseudo_set (symbolP);
1354   demand_empty_rest_of_line ();
1355 }                               /* s_set() */
1356
1357 void 
1358 s_space (mult)
1359      int mult;
1360 {
1361   long temp_repeat;
1362   register long temp_fill;
1363   register char *p;
1364
1365   /* Just like .fill, but temp_size = 1 */
1366   if (get_absolute_expression_and_terminator (&temp_repeat) == ',')
1367     {
1368       temp_fill = get_absolute_expression ();
1369     }
1370   else
1371     {
1372       input_line_pointer--;     /* Backup over what was not a ','. */
1373       temp_fill = 0;
1374     }
1375   if (mult)
1376     {
1377       temp_repeat *= mult;
1378     }
1379   if (temp_repeat <= 0)
1380     {
1381       as_warn ("Repeat < 0, .space ignored");
1382       ignore_rest_of_line ();
1383       return;
1384     }
1385   if (!need_pass_2)
1386     {
1387       p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0,
1388                     temp_repeat, (char *) 0);
1389       *p = temp_fill;
1390     }
1391   demand_empty_rest_of_line ();
1392 }                               /* s_space() */
1393
1394 void
1395 s_text ()
1396 {
1397   register int temp;
1398
1399   temp = get_absolute_expression ();
1400 #ifdef BFD_ASSEMBLER
1401   subseg_set (text_section, (subsegT) temp);
1402 #else
1403   subseg_new (text_section, (subsegT) temp);
1404 #endif
1405   demand_empty_rest_of_line ();
1406 }                               /* s_text() */
1407 \f
1408
1409 void 
1410 demand_empty_rest_of_line ()
1411 {
1412   SKIP_WHITESPACE ();
1413   if (is_end_of_line[*input_line_pointer])
1414     {
1415       input_line_pointer++;
1416     }
1417   else
1418     {
1419       ignore_rest_of_line ();
1420     }
1421   /* Return having already swallowed end-of-line. */
1422 }                               /* Return pointing just after end-of-line. */
1423
1424 void
1425 ignore_rest_of_line ()          /* For suspect lines: gives warning. */
1426 {
1427   if (!is_end_of_line[*input_line_pointer])
1428     {
1429       if (isprint (*input_line_pointer))
1430         as_bad ("Rest of line ignored. First ignored character is `%c'.",
1431                 *input_line_pointer);
1432       else
1433         as_bad ("Rest of line ignored. First ignored character valued 0x%x.",
1434                 *input_line_pointer);
1435       while (input_line_pointer < buffer_limit
1436              && !is_end_of_line[*input_line_pointer])
1437         {
1438           input_line_pointer++;
1439         }
1440     }
1441   input_line_pointer++;         /* Return pointing just after end-of-line. */
1442   know (is_end_of_line[input_line_pointer[-1]]);
1443 }
1444
1445 /*
1446  *                      pseudo_set()
1447  *
1448  * In:  Pointer to a symbol.
1449  *      Input_line_pointer->expression.
1450  *
1451  * Out: Input_line_pointer->just after any whitespace after expression.
1452  *      Tried to set symbol to value of expression.
1453  *      Will change symbols type, value, and frag;
1454  */
1455 void
1456 pseudo_set (symbolP)
1457      symbolS *symbolP;
1458 {
1459   expressionS exp;
1460 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1461   int ext;
1462 #endif /* OBJ_AOUT or OBJ_BOUT */
1463
1464   know (symbolP);               /* NULL pointer is logic error. */
1465 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1466   /* @@ Fix this right for BFD.  */
1467   ext = S_IS_EXTERNAL (symbolP);
1468 #endif /* OBJ_AOUT or OBJ_BOUT */
1469
1470   (void) expression (&exp);
1471
1472   if (exp.X_op == O_illegal)
1473     as_bad ("illegal expression; zero assumed");
1474   else if (exp.X_op == O_absent)
1475     as_bad ("missing expression; zero assumed");
1476   else if (exp.X_op == O_big)
1477     as_bad ("%s number invalid; zero assumed",
1478             exp.X_add_number > 0 ? "bignum" : "floating point");
1479   else if (exp.X_op == O_subtract
1480            && (S_GET_SEGMENT (exp.X_add_symbol)
1481                == S_GET_SEGMENT (exp.X_op_symbol))
1482            && SEG_NORMAL (S_GET_SEGMENT (exp.X_add_symbol))
1483            && exp.X_add_symbol->sy_frag == exp.X_op_symbol->sy_frag)
1484     {
1485       exp.X_op = O_constant;
1486       exp.X_add_number = (S_GET_VALUE (exp.X_add_symbol)
1487                           - S_GET_VALUE (exp.X_op_symbol));
1488     }
1489
1490   switch (exp.X_op)
1491     {
1492     case O_illegal:
1493     case O_absent:
1494     case O_big:
1495       exp.X_add_number = 0;
1496       /* Fall through.  */
1497     case O_constant:
1498       S_SET_SEGMENT (symbolP, absolute_section);
1499 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1500       /* @@ Fix this right for BFD.  */
1501       if (ext)
1502         S_SET_EXTERNAL (symbolP);
1503       else
1504         S_CLEAR_EXTERNAL (symbolP);
1505 #endif /* OBJ_AOUT or OBJ_BOUT */
1506       S_SET_VALUE (symbolP, exp.X_add_number);
1507       symbolP->sy_frag = &zero_address_frag;
1508       break;
1509
1510     case O_register:
1511       S_SET_SEGMENT (symbolP, reg_section);
1512       S_SET_VALUE (symbolP, exp.X_add_number);
1513       symbolP->sy_frag = &zero_address_frag;
1514       break;
1515
1516     case O_symbol:
1517       if (S_GET_SEGMENT (exp.X_add_symbol) == undefined_section)
1518         symbolP->sy_value = exp;
1519       else
1520         {
1521           S_SET_SEGMENT (symbolP, S_GET_SEGMENT (exp.X_add_symbol));
1522 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1523           /* @@ Fix this right for BFD!  */
1524           if (ext)
1525             S_SET_EXTERNAL (symbolP);
1526           else
1527             S_CLEAR_EXTERNAL (symbolP);
1528 #endif /* OBJ_AOUT or OBJ_BOUT */
1529           S_SET_VALUE (symbolP,
1530                        exp.X_add_number + S_GET_VALUE (exp.X_add_symbol));
1531           symbolP->sy_frag = exp.X_add_symbol->sy_frag;
1532         }
1533       break;
1534
1535     default:
1536       /* The value is some complex expression.
1537          FIXME: Should we set the segment to anything?  */
1538       symbolP->sy_value = exp;
1539       break;
1540     }
1541 }
1542 \f
1543 /*
1544  *                      cons()
1545  *
1546  * CONStruct more frag of .bytes, or .words etc.
1547  * Should need_pass_2 be 1 then emit no frag(s).
1548  * This understands EXPRESSIONS, as opposed to big_cons().
1549  *
1550  * Bug (?)
1551  *
1552  * This has a split personality. We use expression() to read the
1553  * value. We can detect if the value won't fit in a byte or word.
1554  * But we can't detect if expression() discarded significant digits
1555  * in the case of a long. Not worth the crocks required to fix it.
1556  */
1557
1558 /* Select a parser for cons expressions.  */
1559
1560 /* Some targets need to parse the expression in various fancy ways.
1561    You can define TC_PARSE_CONS_EXPRESSION to do whatever you like
1562    (for example, the HPPA does this).  Otherwise, you can define
1563    BITFIELD_CONS_EXPRESSIONS to permit bitfields to be specified, or
1564    REPEAT_CONS_EXPRESSIONS to permit repeat counts.  If none of these
1565    are defined, which is the normal case, then only simple expressions
1566    are permitted.  */
1567
1568 #ifndef TC_PARSE_CONS_EXPRESSION
1569 #ifdef BITFIELD_CONS_EXPRESSIONS
1570 #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_bitfield_cons (EXP, NBYTES)
1571 static void 
1572 parse_bitfield_cons PARAMS ((expressionS *exp, unsigned int nbytes));
1573 #endif
1574 #ifdef MRI
1575 #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_mri_cons (EXP)
1576 static void
1577 parse_mri_cons PARAMS ((expressionS *exp));
1578 #endif
1579 #ifdef REPEAT_CONS_EXPRESSIONS
1580 #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_repeat_cons (EXP, NBYTES)
1581 static void
1582 parse_repeat_cons PARAMS ((expressionS *exp, unsigned int nbytes));
1583 #endif
1584
1585 /* If we haven't gotten one yet, just call expression.  */
1586 #ifndef TC_PARSE_CONS_EXPRESSION
1587 #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) expression (EXP)
1588 #endif
1589 #endif
1590
1591 /* worker to do .byte etc statements */
1592 /* clobbers input_line_pointer, checks */
1593 /* end-of-line. */
1594 void 
1595 cons (nbytes)
1596      register unsigned int nbytes;      /* 1=.byte, 2=.word, 4=.long */
1597 {
1598   expressionS exp;
1599
1600   if (is_it_end_of_statement ())
1601     {
1602       demand_empty_rest_of_line ();
1603       return;
1604     }
1605
1606   do
1607     {
1608       TC_PARSE_CONS_EXPRESSION (&exp, nbytes);
1609       emit_expr (&exp, nbytes);
1610     }
1611   while (*input_line_pointer++ == ',');
1612
1613   input_line_pointer--;         /* Put terminator back into stream. */
1614   demand_empty_rest_of_line ();
1615 }                               /* cons() */
1616
1617 /* Put the contents of expression EXP into the object file using
1618    NBYTES bytes.  If need_pass_2 is 1, this does nothing.  */
1619
1620 void
1621 emit_expr (exp, nbytes)
1622      expressionS *exp;
1623      unsigned int nbytes;
1624 {
1625   operatorT op;
1626   register char *p;
1627
1628   /* Don't do anything if we are going to make another pass.  */
1629   if (need_pass_2)
1630     return;
1631
1632   op = exp->X_op;
1633
1634   if (op == O_absent || op == O_illegal)
1635     {
1636       as_warn ("zero assumed for missing expression");
1637       exp->X_add_number = 0;
1638       op = O_constant;
1639     }
1640   else if (op == O_big)
1641     {
1642       as_bad ("%s number invalid; zero assumed",
1643               exp->X_add_number > 0 ? "bignum" : "floating point");
1644       exp->X_add_number = 0;
1645       op = O_constant;
1646     }
1647   else if (op == O_register)
1648     {
1649       as_warn ("register value used as expression");
1650       op = O_constant;
1651     }
1652
1653   p = frag_more (nbytes);
1654
1655 #ifndef WORKING_DOT_WORD
1656   /* If we have the difference of two symbols in a word, save it on
1657      the broken_words list.  See the code in write.c.  */
1658   if (op == O_subtract && nbytes == 2)
1659     {
1660       struct broken_word *x;
1661
1662       x = (struct broken_word *) xmalloc (sizeof (struct broken_word));
1663       x->next_broken_word = broken_words;
1664       broken_words = x;
1665       x->frag = frag_now;
1666       x->word_goes_here = p;
1667       x->dispfrag = 0;
1668       x->add = exp->X_add_symbol;
1669       x->sub = exp->X_op_symbol;
1670       x->addnum = exp->X_add_number;
1671       x->added = 0;
1672       new_broken_words++;
1673       return;
1674     }
1675 #endif
1676
1677   if (op == O_constant)
1678     {
1679       register long get;
1680       register long use;
1681       register long mask;
1682       register long unmask;
1683
1684       /* JF << of >= number of bits in the object is undefined.  In
1685          particular SPARC (Sun 4) has problems */
1686       if (nbytes >= sizeof (long))
1687         mask = 0;
1688       else
1689         mask = ~0 << (BITS_PER_CHAR * nbytes);  /* Don't store these bits. */
1690
1691       unmask = ~mask;           /* Do store these bits. */
1692
1693 #ifdef NEVER
1694       "Do this mod if you want every overflow check to assume SIGNED 2's complement data.";
1695       mask = ~(unmask >> 1);    /* Includes sign bit now. */
1696 #endif
1697
1698       get = exp->X_add_number;
1699       use = get & unmask;
1700       if ((get & mask) != 0 && (get & mask) != mask)
1701         {               /* Leading bits contain both 0s & 1s. */
1702           as_warn ("Value 0x%x truncated to 0x%x.", get, use);
1703         }
1704       md_number_to_chars (p, use, nbytes);      /* put bytes in right order. */
1705     }
1706   else
1707     {
1708       md_number_to_chars (p, (long) 0, nbytes);
1709
1710       /* Now we need to generate a fixS to record the symbol value.
1711          This is easy for BFD.  For other targets it can be more
1712          complex.  For very complex cases (currently, the HPPA and
1713          NS32K), you can define TC_CONS_FIX_NEW to do whatever you
1714          want.  For simpler cases, you can define TC_CONS_RELOC to be
1715          the name of the reloc code that should be stored in the fixS.
1716          If neither is defined, the code uses NO_RELOC if it is
1717          defined, and otherwise uses 0.  */
1718
1719 #ifdef BFD_ASSEMBLER
1720 #ifdef TC_CONS_FIX_NEW
1721       TC_CONS_FIX_NEW (frag_now, p - frag_now->fr_literal, nbytes, exp);
1722 #else
1723       fix_new_exp (frag_now, p - frag_now->fr_literal, nbytes, exp, 0,
1724                    /* @@ Should look at CPU word size.  */
1725                    nbytes == 2 ? BFD_RELOC_16
1726                    : nbytes == 8 ? BFD_RELOC_64
1727                    : BFD_RELOC_32);
1728 #endif
1729 #else
1730 #ifdef TC_CONS_FIX_NEW
1731       TC_CONS_FIX_NEW (frag_now, p - frag_now->fr_literal, nbytes, exp);
1732 #else
1733       /* Figure out which reloc number to use.  Use TC_CONS_RELOC if
1734          it is defined, otherwise use NO_RELOC if it is defined,
1735          otherwise use 0.  */
1736 #ifndef TC_CONS_RELOC
1737 #ifdef NO_RELOC
1738 #define TC_CONS_RELOC NO_RELOC
1739 #else
1740 #define TC_CONS_RELOC 0
1741 #endif
1742 #endif
1743       fix_new_exp (frag_now, p - frag_now->fr_literal, nbytes, exp, 0,
1744                    TC_CONS_RELOC);
1745 #endif /* TC_CONS_FIX_NEW */
1746 #endif /* BFD_ASSEMBLER */
1747     }
1748 }
1749 \f
1750 #ifdef BITFIELD_CONS_EXPRESSIONS
1751
1752 /* i960 assemblers, (eg, asm960), allow bitfields after ".byte" as
1753    w:x,y:z, where w and y are bitwidths and x and y are values.  They
1754    then pack them all together. We do a little better in that we allow
1755    them in words, longs, etc. and we'll pack them in target byte order
1756    for you.
1757
1758    The rules are: pack least significat bit first, if a field doesn't
1759    entirely fit, put it in the next unit.  Overflowing the bitfield is
1760    explicitly *not* even a warning.  The bitwidth should be considered
1761    a "mask".
1762
1763    To use this function the tc-XXX.h file should define
1764    BITFIELD_CONS_EXPRESSIONS.  */
1765
1766 static void 
1767 parse_bitfield_cons (exp, nbytes)
1768      expressionS *exp;
1769      unsigned int nbytes;
1770 {
1771   unsigned int bits_available = BITS_PER_CHAR * nbytes;
1772   char *hold = input_line_pointer;
1773
1774   (void) expression (exp);
1775
1776   if (*input_line_pointer == ':')
1777     {                   /* bitfields */
1778       long value = 0;
1779
1780       for (;;)
1781         {
1782           unsigned long width;
1783
1784           if (*input_line_pointer != ':')
1785             {
1786               input_line_pointer = hold;
1787               break;
1788             }                   /* next piece is not a bitfield */
1789
1790           /* In the general case, we can't allow
1791              full expressions with symbol
1792              differences and such.  The relocation
1793              entries for symbols not defined in this
1794              assembly would require arbitrary field
1795              widths, positions, and masks which most
1796              of our current object formats don't
1797              support.
1798              
1799              In the specific case where a symbol
1800              *is* defined in this assembly, we
1801              *could* build fixups and track it, but
1802              this could lead to confusion for the
1803              backends.  I'm lazy. I'll take any
1804              SEG_ABSOLUTE. I think that means that
1805              you can use a previous .set or
1806              .equ type symbol.  xoxorich. */
1807
1808           if (exp->X_op == O_absent)
1809             {
1810               as_warn ("using a bit field width of zero");
1811               exp->X_add_number = 0;
1812               exp->X_op = O_constant;
1813             }                   /* implied zero width bitfield */
1814
1815           if (exp->X_op != O_constant)
1816             {
1817               *input_line_pointer = '\0';
1818               as_bad ("field width \"%s\" too complex for a bitfield", hold);
1819               *input_line_pointer = ':';
1820               demand_empty_rest_of_line ();
1821               return;
1822             }                   /* too complex */
1823
1824           if ((width = exp->X_add_number) > (BITS_PER_CHAR * nbytes))
1825             {
1826               as_warn ("field width %d too big to fit in %d bytes: truncated to %d bits",
1827                        width, nbytes, (BITS_PER_CHAR * nbytes));
1828               width = BITS_PER_CHAR * nbytes;
1829             }                   /* too big */
1830
1831           if (width > bits_available)
1832             {
1833               /* FIXME-SOMEDAY: backing up and reparsing is wasteful.  */
1834               input_line_pointer = hold;
1835               exp->X_add_number = value;
1836               break;
1837             }                   /* won't fit */
1838
1839           hold = ++input_line_pointer; /* skip ':' */
1840
1841           (void) expression (exp);
1842           if (exp->X_op != O_constant)
1843             {
1844               char cache = *input_line_pointer;
1845
1846               *input_line_pointer = '\0';
1847               as_bad ("field value \"%s\" too complex for a bitfield", hold);
1848               *input_line_pointer = cache;
1849               demand_empty_rest_of_line ();
1850               return;
1851             }                   /* too complex */
1852
1853           value |= ((~(-1 << width) & exp->X_add_number)
1854                     << ((BITS_PER_CHAR * nbytes) - bits_available));
1855
1856           if ((bits_available -= width) == 0
1857               || is_it_end_of_statement ()
1858               || *input_line_pointer != ',')
1859             {
1860               break;
1861             }                   /* all the bitfields we're gonna get */
1862
1863           hold = ++input_line_pointer;
1864           (void) expression (exp);
1865         }                       /* forever loop */
1866
1867       exp->X_add_number = value;
1868       exp->X_op = O_constant;
1869     }                           /* if looks like a bitfield */
1870 }                               /* parse_bitfield_cons() */
1871
1872 #endif /* BITFIELD_CONS_EXPRESSIONS */
1873 \f
1874 #ifdef MRI
1875
1876 static void
1877 parse_mri_cons (exp, nbytes)
1878      expressionS *exp;
1879      unsigned int nbytes;
1880 {
1881   if (*input_line_pointer == '\'')
1882     {
1883       /* An MRI style string, cut into as many bytes as will fit into
1884          a nbyte chunk, left justify if necessary, and separate with
1885          commas so we can try again later */
1886       int scan = 0;
1887       unsigned int result = 0;
1888       input_line_pointer++;
1889       for (scan = 0; scan < nbytes; scan++)
1890         {
1891           if (*input_line_pointer == '\'')
1892             {
1893               if (input_line_pointer[1] == '\'')
1894                 {
1895                   input_line_pointer++;
1896                 }
1897               else
1898                 break;
1899             }
1900           result = (result << 8) | (*input_line_pointer++);
1901         }
1902
1903       /* Left justify */
1904       while (scan < nbytes)
1905         {
1906           result <<= 8;
1907           scan++;
1908         }
1909       /* Create correct expression */
1910       exp->X_op = O_constant;
1911       exp->X_add_number = result;
1912       /* Fake it so that we can read the next char too */
1913       if (input_line_pointer[0] != '\'' ||
1914           (input_line_pointer[0] == '\'' && input_line_pointer[1] == '\''))
1915         {
1916           input_line_pointer -= 2;
1917           input_line_pointer[0] = ',';
1918           input_line_pointer[1] = '\'';
1919         }
1920       else
1921         input_line_pointer++;
1922     }
1923   else
1924     expression (&exp);
1925 }
1926
1927 #endif /* MRI */
1928 \f
1929 #ifdef REPEAT_CONS_EXPRESSIONS
1930
1931 /* Parse a repeat expression for cons.  This is used by the MIPS
1932    assembler.  The format is NUMBER:COUNT; NUMBER appears in the
1933    object file COUNT times.
1934
1935    To use this for a target, define REPEAT_CONS_EXPRESSIONS.  */
1936
1937 static void
1938 parse_repeat_cons (exp, nbytes)
1939      expressionS *exp;
1940      unsigned int nbytes;
1941 {
1942   expressionS count;
1943   register int i;
1944
1945   expression (exp);
1946
1947   if (*input_line_pointer != ':')
1948     {
1949       /* No repeat count.  */
1950       return;
1951     }
1952
1953   ++input_line_pointer;
1954   expression (&count);
1955   if (count.X_op != O_constant
1956       || count.X_add_number <= 0)
1957     {
1958       as_warn ("Unresolvable or nonpositive repeat count; using 1");
1959       return;
1960     }
1961
1962   /* The cons function is going to output this expression once.  So we
1963      output it count - 1 times.  */
1964   for (i = count.X_add_number - 1; i > 0; i--)
1965     emit_expr (exp, nbytes);
1966 }
1967
1968 #endif /* REPEAT_CONS_EXPRESSIONS */
1969 \f
1970 /*
1971  *                      big_cons()
1972  *
1973  * CONStruct more frag(s) of .quads, or .octa etc.
1974  * Makes 0 or more new frags.
1975  * If need_pass_2 == 1, generate no frag.
1976  * This understands only bignums, not expressions. Cons() understands
1977  * expressions.
1978  *
1979  * Constants recognised are '0...'(octal) '0x...'(hex) '...'(decimal).
1980  *
1981  * This creates objects with struct obstack_control objs, destroying
1982  * any context objs held about a partially completed object. Beware!
1983  *
1984  *
1985  * I think it sucks to have 2 different types of integers, with 2
1986  * routines to read them, store them etc.
1987  * It would be nicer to permit bignums in expressions and only
1988  * complain if the result overflowed. However, due to "efficiency"...
1989  */
1990 /* Worker to do .quad etc statements.  Clobbers input_line_pointer, checks
1991    end-of-line.  8=.quad 16=.octa ... */
1992
1993 void 
1994 big_cons (nbytes)
1995      register int nbytes;
1996 {
1997   register char c;              /* input_line_pointer->c. */
1998   register int radix;
1999   register long length;         /* Number of chars in an object. */
2000   register int digit;           /* Value of 1 digit. */
2001   register int carry;           /* For multi-precision arithmetic. */
2002   register int work;            /* For multi-precision arithmetic. */
2003   register char *p;             /* For multi-precision arithmetic. */
2004
2005   extern const char hex_value[];        /* In hex_value.c. */
2006
2007   /*
2008    * The following awkward logic is to parse ZERO or more strings,
2009    * comma seperated. Recall an expression includes its leading &
2010    * trailing blanks. We fake a leading ',' if there is (supposed to
2011    * be) a 1st expression, and keep demanding 1 expression for each ','.
2012    */
2013   if (is_it_end_of_statement ())
2014     {
2015       c = 0;                    /* Skip loop. */
2016     }
2017   else
2018     {
2019       c = ',';                  /* Do loop. */
2020       --input_line_pointer;
2021     }
2022   while (c == ',')
2023     {
2024       ++input_line_pointer;
2025       SKIP_WHITESPACE ();
2026       c = *input_line_pointer;
2027       /* C contains 1st non-blank character of what we hope is a number. */
2028       if (c == '0')
2029         {
2030           c = *++input_line_pointer;
2031           if (c == 'x' || c == 'X')
2032             {
2033               c = *++input_line_pointer;
2034               radix = 16;
2035             }
2036           else
2037             {
2038               radix = 8;
2039             }
2040         }
2041       else
2042         {
2043           radix = 10;
2044         }
2045       /*
2046        * This feature (?) is here to stop people worrying about
2047        * mysterious zero constants: which is what they get when
2048        * they completely omit digits.
2049        */
2050       if (hex_value[c] >= radix)
2051         {
2052           as_bad ("Missing digits. 0 assumed.");
2053         }
2054       bignum_high = bignum_low - 1;     /* Start constant with 0 chars. */
2055       for (; (digit = hex_value[c]) < radix; c = *++input_line_pointer)
2056         {
2057           /* Multiply existing number by radix, then add digit. */
2058           carry = digit;
2059           for (p = bignum_low; p <= bignum_high; p++)
2060             {
2061               work = (*p & MASK_CHAR) * radix + carry;
2062               *p = work & MASK_CHAR;
2063               carry = work >> BITS_PER_CHAR;
2064             }
2065           if (carry)
2066             {
2067               grow_bignum ();
2068               *bignum_high = carry & MASK_CHAR;
2069               know ((carry & ~MASK_CHAR) == 0);
2070             }
2071         }
2072       length = bignum_high - bignum_low + 1;
2073       if (length > nbytes)
2074         {
2075           as_warn ("Most significant bits truncated in integer constant.");
2076         }
2077       else
2078         {
2079           register long leading_zeroes;
2080
2081           for (leading_zeroes = nbytes - length;
2082                leading_zeroes;
2083                leading_zeroes--)
2084             {
2085               grow_bignum ();
2086               *bignum_high = 0;
2087             }
2088         }
2089       if (!need_pass_2)
2090         {
2091           char *src = bignum_low;
2092           p = frag_more (nbytes);
2093           if (target_big_endian)
2094             {
2095               int i;
2096               for (i = nbytes - 1; i >= 0; i--)
2097                 p[i] = *src++;
2098             }
2099           else
2100             memcpy (p, bignum_low, (int) nbytes);
2101         }
2102       /* C contains character after number. */
2103       SKIP_WHITESPACE ();
2104       c = *input_line_pointer;
2105       /* C contains 1st non-blank character after number. */
2106     }
2107   demand_empty_rest_of_line ();
2108 }                               /* big_cons() */
2109
2110 /* Extend bignum by 1 char. */
2111 static void 
2112 grow_bignum ()
2113 {
2114   register long length;
2115
2116   bignum_high++;
2117   if (bignum_high >= bignum_limit)
2118     {
2119       length = bignum_limit - bignum_low;
2120       bignum_low = xrealloc (bignum_low, length + length);
2121       bignum_high = bignum_low + length;
2122       bignum_limit = bignum_low + length + length;
2123     }
2124 }                               /* grow_bignum(); */
2125 \f
2126 /*
2127  *                      float_cons()
2128  *
2129  * CONStruct some more frag chars of .floats .ffloats etc.
2130  * Makes 0 or more new frags.
2131  * If need_pass_2 == 1, no frags are emitted.
2132  * This understands only floating literals, not expressions. Sorry.
2133  *
2134  * A floating constant is defined by atof_generic(), except it is preceded
2135  * by 0d 0f 0g or 0h. After observing the STRANGE way my BSD AS does its
2136  * reading, I decided to be incompatible. This always tries to give you
2137  * rounded bits to the precision of the pseudo-op. Former AS did premature
2138  * truncatation, restored noisy bits instead of trailing 0s AND gave you
2139  * a choice of 2 flavours of noise according to which of 2 floating-point
2140  * scanners you directed AS to use.
2141  *
2142  * In:  input_line_pointer->whitespace before, or '0' of flonum.
2143  *
2144  */
2145
2146 void
2147 float_cons (float_type)
2148      /* Clobbers input_line-pointer, checks end-of-line. */
2149      register int float_type;   /* 'f':.ffloat ... 'F':.float ... */
2150 {
2151   register char *p;
2152   int length;                   /* Number of chars in an object. */
2153   register char *err;           /* Error from scanning floating literal. */
2154   char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
2155
2156   if (is_it_end_of_statement ())
2157     {
2158       demand_empty_rest_of_line ();
2159       return;
2160     }
2161
2162   do
2163     {
2164       /* input_line_pointer->1st char of a flonum (we hope!). */
2165       SKIP_WHITESPACE ();
2166
2167       /* Skip any 0{letter} that may be present. Don't even check if the
2168        * letter is legal. Someone may invent a "z" format and this routine
2169        * has no use for such information. Lusers beware: you get
2170        * diagnostics if your input is ill-conditioned.
2171        */
2172       if (input_line_pointer[0] == '0' && isalpha (input_line_pointer[1]))
2173         input_line_pointer += 2;
2174
2175       err = md_atof (float_type, temp, &length);
2176       know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
2177       know (length > 0);
2178       if (err && *err)
2179         {
2180           as_bad ("Bad floating literal: %s", err);
2181           ignore_rest_of_line ();
2182           return;
2183         }
2184
2185       if (!need_pass_2)
2186         {
2187           int count;
2188
2189           count = 1;
2190
2191 #ifdef REPEAT_CONS_EXPRESSIONS
2192           if (*input_line_pointer == ':')
2193             {
2194               expressionS count_exp;
2195
2196               ++input_line_pointer;
2197               expression (&count_exp);
2198               if (count_exp.X_op != O_constant
2199                   || count_exp.X_add_number <= 0)
2200                 {
2201                   as_warn ("unresolvable or nonpositive repeat count; using 1");
2202                 }
2203               else
2204                 count = count_exp.X_add_number;
2205             }
2206 #endif
2207
2208           while (--count >= 0)
2209             {
2210               p = frag_more (length);
2211               memcpy (p, temp, length);
2212             }
2213         }
2214       SKIP_WHITESPACE ();
2215     }
2216   while (*input_line_pointer++ == ',');
2217
2218   --input_line_pointer;         /* Put terminator back into stream.  */
2219   demand_empty_rest_of_line ();
2220 }                               /* float_cons() */
2221 \f
2222 /*
2223  *                      stringer()
2224  *
2225  * We read 0 or more ',' seperated, double-quoted strings.
2226  *
2227  * Caller should have checked need_pass_2 is FALSE because we don't check it.
2228  */
2229
2230
2231 void 
2232 stringer (append_zero)          /* Worker to do .ascii etc statements. */
2233      /* Checks end-of-line. */
2234      register int append_zero;  /* 0: don't append '\0', else 1 */
2235 {
2236   register unsigned int c;
2237
2238   /*
2239    * The following awkward logic is to parse ZERO or more strings,
2240    * comma seperated. Recall a string expression includes spaces
2241    * before the opening '\"' and spaces after the closing '\"'.
2242    * We fake a leading ',' if there is (supposed to be)
2243    * a 1st, expression. We keep demanding expressions for each
2244    * ','.
2245    */
2246   if (is_it_end_of_statement ())
2247     {
2248       c = 0;                    /* Skip loop. */
2249       ++input_line_pointer;     /* Compensate for end of loop. */
2250     }
2251   else
2252     {
2253       c = ',';                  /* Do loop. */
2254     }
2255   while (c == ',' || c == '<' || c == '"')
2256     {
2257       SKIP_WHITESPACE ();
2258       switch (*input_line_pointer)
2259         {
2260         case '\"':
2261           ++input_line_pointer; /*->1st char of string. */
2262           while (is_a_char (c = next_char_of_string ()))
2263             {
2264               FRAG_APPEND_1_CHAR (c);
2265             }
2266           if (append_zero)
2267             {
2268               FRAG_APPEND_1_CHAR (0);
2269             }
2270           know (input_line_pointer[-1] == '\"');
2271           break;
2272         case '<':
2273           input_line_pointer++;
2274           c = get_single_number ();
2275           FRAG_APPEND_1_CHAR (c);
2276           if (*input_line_pointer != '>')
2277             {
2278               as_bad ("Expected <nn>");
2279             }
2280           input_line_pointer++;
2281           break;
2282         case ',':
2283           input_line_pointer++;
2284           break;
2285         }
2286       SKIP_WHITESPACE ();
2287       c = *input_line_pointer;
2288     }
2289
2290   demand_empty_rest_of_line ();
2291 }                               /* stringer() */
2292 \f
2293 /* FIXME-SOMEDAY: I had trouble here on characters with the
2294     high bits set.  We'll probably also have trouble with
2295     multibyte chars, wide chars, etc.  Also be careful about
2296     returning values bigger than 1 byte.  xoxorich. */
2297
2298 unsigned int 
2299 next_char_of_string ()
2300 {
2301   register unsigned int c;
2302
2303   c = *input_line_pointer++ & CHAR_MASK;
2304   switch (c)
2305     {
2306     case '\"':
2307       c = NOT_A_CHAR;
2308       break;
2309
2310     case '\\':
2311       switch (c = *input_line_pointer++)
2312         {
2313         case 'b':
2314           c = '\b';
2315           break;
2316
2317         case 'f':
2318           c = '\f';
2319           break;
2320
2321         case 'n':
2322           c = '\n';
2323           break;
2324
2325         case 'r':
2326           c = '\r';
2327           break;
2328
2329         case 't':
2330           c = '\t';
2331           break;
2332
2333 #ifdef BACKSLASH_V
2334         case 'v':
2335           c = '\013';
2336           break;
2337 #endif
2338
2339         case '\\':
2340         case '"':
2341           break;                /* As itself. */
2342
2343         case '0':
2344         case '1':
2345         case '2':
2346         case '3':
2347         case '4':
2348         case '5':
2349         case '6':
2350         case '7':
2351         case '8':
2352         case '9':
2353           {
2354             long number;
2355
2356             for (number = 0; isdigit (c); c = *input_line_pointer++)
2357               {
2358                 number = number * 8 + c - '0';
2359               }
2360             c = number & 0xff;
2361           }
2362           --input_line_pointer;
2363           break;
2364
2365         case '\n':
2366           /* To be compatible with BSD 4.2 as: give the luser a linefeed!! */
2367           as_warn ("Unterminated string: Newline inserted.");
2368           c = '\n';
2369           break;
2370
2371         default:
2372
2373 #ifdef ONLY_STANDARD_ESCAPES
2374           as_bad ("Bad escaped character in string, '?' assumed");
2375           c = '?';
2376 #endif /* ONLY_STANDARD_ESCAPES */
2377
2378           break;
2379         }                       /* switch on escaped char */
2380       break;
2381
2382     default:
2383       break;
2384     }                           /* switch on char */
2385   return (c);
2386 }                               /* next_char_of_string() */
2387 \f
2388 static segT
2389 get_segmented_expression (expP)
2390      register expressionS *expP;
2391 {
2392   register segT retval;
2393
2394   retval = expression (expP);
2395   if (expP->X_op == O_illegal
2396       || expP->X_op == O_absent
2397       || expP->X_op == O_big)
2398     {
2399       as_bad ("expected address expression; zero assumed");
2400       expP->X_op = O_constant;
2401       expP->X_add_number = 0;
2402       retval = absolute_section;
2403     }
2404   return retval;
2405 }
2406
2407 static segT 
2408 get_known_segmented_expression (expP)
2409      register expressionS *expP;
2410 {
2411   register segT retval;
2412
2413   if ((retval = get_segmented_expression (expP)) == undefined_section)
2414     {
2415       /* There is no easy way to extract the undefined symbol from the
2416          expression.  */
2417       if (expP->X_add_symbol != NULL
2418           && S_GET_SEGMENT (expP->X_add_symbol) != expr_section)
2419         as_warn ("symbol \"%s\" undefined; zero assumed",
2420                  S_GET_NAME (expP->X_add_symbol));
2421       else
2422         as_warn ("some symbol undefined; zero assumed");
2423       retval = absolute_section;
2424       expP->X_op = O_constant;
2425       expP->X_add_number = 0;
2426     }
2427   know (retval == absolute_section || SEG_NORMAL (retval));
2428   return (retval);
2429 }                               /* get_known_segmented_expression() */
2430
2431 /* static */ long               /* JF was static, but can't be if the MD pseudos are to use it */
2432 get_absolute_expression ()
2433 {
2434   expressionS exp;
2435
2436   expression (&exp);
2437   if (exp.X_op != O_constant)
2438     {
2439       if (exp.X_op != O_absent)
2440         as_bad ("bad absolute expression; zero assumed");
2441       exp.X_add_number = 0;
2442     }
2443   return exp.X_add_number;
2444 }
2445
2446 char                            /* return terminator */
2447 get_absolute_expression_and_terminator (val_pointer)
2448      long *val_pointer;         /* return value of expression */
2449 {
2450   *val_pointer = get_absolute_expression ();
2451   return (*input_line_pointer++);
2452 }
2453 \f
2454 /*
2455  *                      demand_copy_C_string()
2456  *
2457  * Like demand_copy_string, but return NULL if the string contains any '\0's.
2458  * Give a warning if that happens.
2459  */
2460 char *
2461 demand_copy_C_string (len_pointer)
2462      int *len_pointer;
2463 {
2464   register char *s;
2465
2466   if ((s = demand_copy_string (len_pointer)) != 0)
2467     {
2468       register int len;
2469
2470       for (len = *len_pointer;
2471            len > 0;
2472            len--)
2473         {
2474           if (*s == 0)
2475             {
2476               s = 0;
2477               len = 1;
2478               *len_pointer = 0;
2479               as_bad ("This string may not contain \'\\0\'");
2480             }
2481         }
2482     }
2483   return (s);
2484 }
2485 \f
2486 /*
2487  *                      demand_copy_string()
2488  *
2489  * Demand string, but return a safe (=private) copy of the string.
2490  * Return NULL if we can't read a string here.
2491  */
2492 static char *
2493 demand_copy_string (lenP)
2494      int *lenP;
2495 {
2496   register unsigned int c;
2497   register int len;
2498   char *retval;
2499
2500   len = 0;
2501   SKIP_WHITESPACE ();
2502   if (*input_line_pointer == '\"')
2503     {
2504       input_line_pointer++;     /* Skip opening quote. */
2505
2506       while (is_a_char (c = next_char_of_string ()))
2507         {
2508           obstack_1grow (&notes, c);
2509           len++;
2510         }
2511       /* JF this next line is so demand_copy_C_string will return a null
2512                    termanated string. */
2513       obstack_1grow (&notes, '\0');
2514       retval = obstack_finish (&notes);
2515     }
2516   else
2517     {
2518       as_warn ("Missing string");
2519       retval = NULL;
2520       ignore_rest_of_line ();
2521     }
2522   *lenP = len;
2523   return (retval);
2524 }                               /* demand_copy_string() */
2525 \f
2526 /*
2527  *              is_it_end_of_statement()
2528  *
2529  * In:  Input_line_pointer->next character.
2530  *
2531  * Do:  Skip input_line_pointer over all whitespace.
2532  *
2533  * Out: 1 if input_line_pointer->end-of-line.
2534 */
2535 int 
2536 is_it_end_of_statement ()
2537 {
2538   SKIP_WHITESPACE ();
2539   return (is_end_of_line[*input_line_pointer]);
2540 }                               /* is_it_end_of_statement() */
2541
2542 void 
2543 equals (sym_name)
2544      char *sym_name;
2545 {
2546   register symbolS *symbolP;    /* symbol we are working with */
2547
2548   input_line_pointer++;
2549   if (*input_line_pointer == '=')
2550     input_line_pointer++;
2551
2552   while (*input_line_pointer == ' ' || *input_line_pointer == '\t')
2553     input_line_pointer++;
2554
2555   if (sym_name[0] == '.' && sym_name[1] == '\0')
2556     {
2557       /* Turn '. = mumble' into a .org mumble */
2558       register segT segment;
2559       expressionS exp;
2560       register char *p;
2561
2562       segment = get_known_segmented_expression (&exp);
2563       if (!need_pass_2)
2564         {
2565           if (segment != now_seg && segment != absolute_section)
2566             as_warn ("Illegal segment \"%s\". Segment \"%s\" assumed.",
2567                      segment_name (segment),
2568                      segment_name (now_seg));
2569           p = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp.X_add_symbol,
2570                         exp.X_add_number, (char *) 0);
2571           *p = 0;
2572         }                       /* if (ok to make frag) */
2573     }
2574   else
2575     {
2576       symbolP = symbol_find_or_make (sym_name);
2577       pseudo_set (symbolP);
2578     }
2579 }                               /* equals() */
2580
2581 /* .include -- include a file at this point. */
2582
2583 /* ARGSUSED */
2584 void 
2585 s_include (arg)
2586      int arg;
2587 {
2588   char *newbuf;
2589   char *filename;
2590   int i;
2591   FILE *try;
2592   char *path;
2593
2594   filename = demand_copy_string (&i);
2595   demand_empty_rest_of_line ();
2596   path = xmalloc (i + include_dir_maxlen + 5 /* slop */ );
2597   for (i = 0; i < include_dir_count; i++)
2598     {
2599       strcpy (path, include_dirs[i]);
2600       strcat (path, "/");
2601       strcat (path, filename);
2602       if (0 != (try = fopen (path, "r")))
2603         {
2604           fclose (try);
2605           goto gotit;
2606         }
2607     }
2608   free (path);
2609   path = filename;
2610 gotit:
2611   /* malloc Storage leak when file is found on path.  FIXME-SOMEDAY. */
2612   newbuf = input_scrub_include_file (path, input_line_pointer);
2613   buffer_limit = input_scrub_next_buffer (&input_line_pointer);
2614 }                               /* s_include() */
2615
2616 void 
2617 add_include_dir (path)
2618      char *path;
2619 {
2620   int i;
2621
2622   if (include_dir_count == 0)
2623     {
2624       include_dirs = (char **) xmalloc (2 * sizeof (*include_dirs));
2625       include_dirs[0] = ".";    /* Current dir */
2626       include_dir_count = 2;
2627     }
2628   else
2629     {
2630       include_dir_count++;
2631       include_dirs = (char **) realloc (include_dirs,
2632                                 include_dir_count * sizeof (*include_dirs));
2633     }
2634
2635   include_dirs[include_dir_count - 1] = path;   /* New one */
2636
2637   i = strlen (path);
2638   if (i > include_dir_maxlen)
2639     include_dir_maxlen = i;
2640 }                               /* add_include_dir() */
2641
2642 void 
2643 s_ignore (arg)
2644      int arg;
2645 {
2646   while (!is_end_of_line[*input_line_pointer])
2647     {
2648       ++input_line_pointer;
2649     }
2650   ++input_line_pointer;
2651
2652   return;
2653 }                               /* s_ignore() */
2654
2655 /*
2656  * Handle .stabX directives, which used to be open-coded.
2657  * So much creeping featurism overloaded the semantics that we decided
2658  * to put all .stabX thinking in one place. Here.
2659  *
2660  * We try to make any .stabX directive legal. Other people's AS will often
2661  * do assembly-time consistency checks: eg assigning meaning to n_type bits
2662  * and "protecting" you from setting them to certain values. (They also zero
2663  * certain bits before emitting symbols. Tut tut.)
2664  *
2665  * If an expression is not absolute we either gripe or use the relocation
2666  * information. Other people's assemblers silently forget information they
2667  * don't need and invent information they need that you didn't supply.
2668  */
2669
2670 void
2671 change_to_section (name, len, exp)
2672        char *name;
2673        unsigned int len;
2674        unsigned int exp;
2675 {
2676 #ifndef BFD_ASSEMBLER
2677 #ifdef MANY_SEGMENTS
2678   unsigned int i;
2679   extern segment_info_type segment_info[];
2680
2681   /* Find out if we've already got a section of this name etc */
2682   for (i = SEG_E0; i < SEG_E9 && segment_info[i].scnhdr.s_name[0]; i++)
2683     {
2684       if (strncmp (segment_info[i].scnhdr.s_name, name, len) == 0)
2685         {
2686           subseg_new (i, exp);
2687           return;
2688         }
2689     }
2690   /* No section, add one */
2691   strncpy (segment_info[i].scnhdr.s_name, name, 8);
2692   segment_info[i].scnhdr.s_flags = 0 /* STYP_NOLOAD */;
2693   subseg_new (i, exp);
2694 #endif
2695 #endif
2696 }
2697
2698 /*
2699  * Build a string dictionary entry for a .stabX symbol.
2700  * The symbol is added to the .<secname>str section.
2701  */
2702
2703 static unsigned int
2704 get_stab_string_offset (string, secname)
2705      char *string, *secname;
2706 {
2707   segT save_seg;
2708   segT seg;
2709   subsegT save_subseg;
2710   unsigned int length;
2711   unsigned int old_gdb_string_index;
2712   char *clengthP;
2713   int i;
2714   char c;
2715   /* @@FIXME -- there should be no static data here!
2716      This also has the effect of making all stab string tables large enough
2717      to contain all the contents written to any of them.  This only matters
2718      with the Solaris native compiler for the moment, but it should be fixed
2719      anyways.  */
2720   static unsigned int gdb_string_index = 0;
2721
2722   old_gdb_string_index = 0;
2723   length = strlen (string);
2724   clengthP = (char *) &length;
2725   if (length > 0)
2726     {                           /* Ordinary case. */
2727       save_seg = now_seg;
2728       save_subseg = now_subseg;
2729
2730       /* Create the stabstr sections, if they are not already created. */
2731       {
2732         char *newsecname = xmalloc (strlen (secname) + 4);
2733         strcpy (newsecname, secname);
2734         strcat (newsecname, "str");
2735 #ifdef BFD_ASSEMBLER
2736         seg = bfd_get_section_by_name (stdoutput, newsecname);
2737         if (seg == 0)
2738           {
2739             seg = bfd_make_section_old_way (stdoutput, newsecname);
2740             bfd_set_section_flags (stdoutput, seg, SEC_READONLY | SEC_ALLOC);
2741           }
2742 #else
2743         change_to_section(newsecname, strlen(newsecname), 0);
2744 #endif
2745 /*      free (newsecname);*/
2746       }
2747 #ifdef BFD_ASSEMBLER
2748       subseg_new ((char *) seg->name, save_subseg);
2749 #else
2750 /*      subseg_new (seg, save_subseg);  */
2751 #endif
2752       old_gdb_string_index = gdb_string_index;
2753       i = 0;
2754       while ((c = *string++))
2755         {
2756           i++;
2757           gdb_string_index++;
2758           FRAG_APPEND_1_CHAR (c);
2759         }
2760       {
2761         FRAG_APPEND_1_CHAR ((char) 0);
2762         i++;
2763         gdb_string_index++;
2764       }
2765       while (i % 4 != 0)
2766         {
2767           FRAG_APPEND_1_CHAR ((char) 0);
2768           i++;
2769           gdb_string_index++;
2770         }
2771 #ifdef BFD_ASSEMBLER
2772       subseg_new ((char *) save_seg->name, save_subseg);
2773 #else
2774 /*      subseg_new (save_seg, save_subseg);  */
2775 #endif
2776     }
2777   return old_gdb_string_index;
2778 }
2779
2780 /* This can handle different kinds of stabs (s,n,d) and different
2781    kinds of stab sections. */
2782
2783 static void 
2784 s_stab_generic (what, secname)
2785      int what;
2786      char *secname;
2787 {
2788   extern int listing;
2789
2790   symbolS *symbol;
2791   char *string;
2792   int saved_type = 0;
2793   int length;
2794   int goof = 0;
2795   int seg_is_new = 0;
2796   long longint;
2797   segT saved_seg = now_seg;
2798   segT seg;
2799   subsegT saved_subseg = now_subseg;
2800   subsegT subseg;
2801   int offset;
2802   int valu;
2803   char *toP;
2804
2805   valu = ((char *) obstack_next_free (&frags)) - frag_now->fr_literal;
2806
2807 #ifdef SEPARATE_STAB_SECTIONS
2808 #ifdef BFD_ASSEMBLER
2809   seg = bfd_get_section_by_name (stdoutput, secname);
2810   if (seg == 0)
2811     {
2812       seg = subseg_new (secname, 0);
2813       bfd_set_section_flags (stdoutput, seg,
2814                              SEC_READONLY | SEC_ALLOC | SEC_RELOC);
2815       subseg_set (saved_seg, subseg);
2816       seg_is_new = 1;
2817     }
2818 #else
2819   change_to_section (secname, strlen(secname), 0);
2820 #endif
2821 #endif /* SEPARATE_STAB_SECTIONS */
2822
2823   /*
2824    * Enter with input_line_pointer pointing past .stabX and any following
2825    * whitespace.
2826    */
2827   if (what == 's')
2828     {
2829       string = demand_copy_C_string (&length);
2830       SKIP_WHITESPACE ();
2831       if (*input_line_pointer == ',')
2832         input_line_pointer++;
2833       else
2834         {
2835           as_bad ("I need a comma after symbol's name");
2836           goof = 1;
2837         }
2838     }
2839   else
2840     string = "";
2841
2842   /*
2843    * Input_line_pointer->after ','.  String->symbol name.
2844    */
2845   if (!goof)
2846     {
2847 #ifdef MAKE_STAB_SYMBOL
2848       MAKE_STAB_SYMBOL(symbol, string, secname);
2849 #else
2850       symbol = symbol_new (string, undefined_section, 0, (struct frag *) 0);
2851 #endif
2852       /* Make sure that the rest of this is going to work. */
2853       if (symbol == NULL)
2854         as_fatal ("no stab symbol created");
2855
2856       switch (what)
2857         {
2858         case 'd':
2859           S_SET_NAME (symbol, NULL);    /* .stabd feature. */
2860 #ifdef STAB_SYMBOL_SET_VALUE
2861           STAB_SYMBOL_SET_VALUE (symbol, valu);
2862 #else
2863           S_SET_VALUE (symbol, valu);
2864 #endif
2865 #if STAB_SYMBOL_SET_SEGMENT
2866 #else
2867           S_SET_SEGMENT (symbol, now_seg);
2868 #endif
2869           symbol->sy_frag = frag_now;
2870           break;
2871
2872         case 'n':
2873           symbol->sy_frag = &zero_address_frag;
2874           break;
2875
2876         case 's':
2877           symbol->sy_frag = &zero_address_frag;
2878           break;
2879
2880         default:
2881           BAD_CASE (what);
2882           break;
2883         }
2884
2885       if (get_absolute_expression_and_terminator (&longint) == ',')
2886         {
2887           saved_type = longint;
2888           S_SET_TYPE (symbol, saved_type);
2889         }
2890       else
2891         {
2892           as_bad ("I want a comma after the n_type expression");
2893           goof = 1;
2894           input_line_pointer--; /* Backup over a non-',' char. */
2895         }
2896     }
2897
2898   if (!goof)
2899     {
2900       if (get_absolute_expression_and_terminator (&longint) == ',')
2901         S_SET_OTHER (symbol, longint);
2902       else
2903         {
2904           as_bad ("I want a comma after the n_other expression");
2905           goof = 1;
2906           input_line_pointer--; /* Backup over a non-',' char. */
2907         }
2908     }
2909
2910   if (!goof)
2911     {
2912       S_SET_DESC (symbol, get_absolute_expression ());
2913       if (what == 's' || what == 'n')
2914         {
2915           if (*input_line_pointer != ',')
2916             {
2917               as_bad ("I want a comma after the n_desc expression");
2918               goof = 1;
2919             }
2920           else
2921             {
2922               input_line_pointer++;
2923             }
2924         }
2925     }
2926
2927   /* Line is messed up - ignore it and get out of here. */
2928   if (goof)
2929     {
2930       ignore_rest_of_line ();
2931       subseg_new (saved_seg, saved_subseg);
2932       return;
2933     }
2934
2935 #ifdef BFD_ASSEMBLER
2936   subseg_new ((char *) seg->name, subseg);
2937 #endif
2938
2939 #if 0  /* needed for elf only? */
2940   if (seg_is_new)
2941     /* allocate and discard -- filled in later */
2942     (void) frag_more (12);
2943 #endif
2944
2945 #ifdef SEPARATE_STAB_SECTIONS
2946   change_to_section(secname, strlen(secname), 0);
2947   toP = frag_more (8);
2948   /* the string index portion of the stab */
2949   md_number_to_chars (toP, (valueT) S_GET_OFFSET_2(symbol), 4);
2950   md_number_to_chars (toP + 4, (valueT) S_GET_TYPE(symbol), 1);
2951   md_number_to_chars (toP + 5, (valueT) S_GET_OTHER(symbol), 1);
2952   md_number_to_chars (toP + 6, (valueT) S_GET_DESC(symbol), 2);
2953 #endif
2954
2955 #ifdef SEPARATE_STAB_SECTIONS
2956   if (what == 's' || what == 'n')
2957     {
2958       cons (4);
2959       input_line_pointer--;
2960     }
2961   else
2962     {
2963       char *p = frag_more (4);
2964       md_number_to_chars (p, 0, 4);
2965     }
2966 #ifdef BFD_ASSEMBLER
2967   subseg_new ((char *) saved_seg->name, subseg);
2968 #else
2969 /*  subseg_new (saved_seg, subseg);  */
2970 #endif
2971 #else
2972   if (what == 's' || what == 'n')
2973     {
2974       pseudo_set (symbol);
2975       S_SET_TYPE (symbol, saved_type);
2976     }
2977 #endif
2978
2979 #if 0  /* for elf only? */
2980   if (what == 's' && S_GET_TYPE (symbol) == N_SO)
2981     {
2982       fragS *fragp = seg_info (seg)->frchainP->frch_root;
2983       while (fragp
2984              && fragp->fr_address + fragp->fr_fix < 12)
2985         fragp = fragp->fr_next;
2986       assert (fragp != 0);
2987       assert (fragp->fr_type == rs_fill);
2988       assert (fragp->fr_address == 0 && fragp->fr_fix >= 12);
2989       md_number_to_chars (fragp->fr_literal, (valueT) symbol->sy_name_offset,
2990                           4);
2991     }
2992 #endif
2993
2994 #ifndef NO_LISTING
2995   if (listing)
2996     switch (S_GET_TYPE (symbol))
2997       {
2998       case N_SLINE:
2999         listing_source_line (S_GET_DESC (symbol));
3000         break;
3001       case N_SO:
3002       case N_SOL:
3003         listing_source_file (string);
3004         break;
3005       }
3006 #endif /* !NO_LISTING */
3007
3008 #ifdef SEPARATE_STAB_SECTIONS
3009   subseg_new (saved_seg, saved_subseg);
3010 #endif
3011
3012   demand_empty_rest_of_line ();
3013 }
3014
3015 /* Regular stab directive. */
3016
3017 void
3018 s_stab (what)
3019      int what;
3020 {
3021   s_stab_generic (what, ".stab");
3022 }
3023
3024 /* "Extended stabs", used in Solaris only now. */
3025
3026 void
3027 s_xstab (what)
3028      int what;
3029 {
3030   int length;
3031   char *secname;
3032
3033   secname = demand_copy_C_string (&length);
3034   SKIP_WHITESPACE ();
3035   if (*input_line_pointer == ',')
3036     input_line_pointer++;
3037   else
3038     {
3039       as_bad ("comma missing in .xstabs");
3040       ignore_rest_of_line ();
3041       return;
3042     }
3043   s_stab_generic (what, secname);
3044 }
3045
3046 /* Frob invented at RMS' request. Set the n_desc of a symbol.  */
3047
3048 void 
3049 s_desc ()
3050 {
3051   char *name;
3052   char c;
3053   char *p;
3054   symbolS *symbolP;
3055   int temp;
3056
3057   name = input_line_pointer;
3058   c = get_symbol_end ();
3059   p = input_line_pointer;
3060   *p = c;
3061   SKIP_WHITESPACE ();
3062   if (*input_line_pointer != ',')
3063     {
3064       *p = 0;
3065       as_bad ("Expected comma after name \"%s\"", name);
3066       *p = c;
3067       ignore_rest_of_line ();
3068     }
3069   else
3070     {
3071       input_line_pointer++;
3072       temp = get_absolute_expression ();
3073       *p = 0;
3074       symbolP = symbol_find_or_make (name);
3075       *p = c;
3076       S_SET_DESC (symbolP, temp);
3077     }
3078   demand_empty_rest_of_line ();
3079 }                               /* s_desc() */
3080
3081 /* end of read.c */