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