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