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