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