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