1 /* read.c - read a source file -
2 Copyright (C) 1986, 1987, 1990, 1991 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
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)
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.
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. */
20 #define MASK_CHAR (0xFF) /* If your chars aren't 8 bits, you will
21 change this a bit. But then, GNU isn't
22 spozed to run on your machine anyway.
23 (RMS is so shortsighted sometimes.)
26 #define MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT (16)
27 /* This is the largest known floating point */
28 /* format (for now). It will grow when we */
29 /* do 4361 style flonums. */
32 /* Routines that read assembler source text to build spagetti in memory. */
33 /* Another group of these functions is in the as-expr.c module */
39 char *input_line_pointer; /*->next char of source file to parse. */
42 #if BITS_PER_CHAR != 8
43 The following table is indexed by [ (char) ] and will break if
44 a char does not have exactly 256 states (hopefully 0:255!) !
47 const char /* used by is_... macros. our ctype[] */
49 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */
50 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ[\]^_ */
51 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */
52 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0123456789:;<=>? */
53 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */
54 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 3, /* PQRSTUVWXYZ[\]^_ */
55 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* `abcdefghijklmno */
56 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, /* pqrstuvwxyz{|}~. */
57 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
58 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
59 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
60 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
61 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
69 * Out: 1 if this character ends a line.
72 char is_end_of_line [256] = {
74 _, _, _, _, _, _, _, _, _, _,99, _, _, 99, _, _,/* @abcdefghijklmno */
76 _, _, _, _, _, _, _, _, _, _,99, _, _, _, _, _, /* @abcdefghijklmno */
78 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
79 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
80 _, _, _, _, _, _, _, _, _, _, _,99, _, _, _, _, /* 0123456789:;<=>? */
81 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
82 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
83 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
84 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
85 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
86 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
87 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
88 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
89 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ /* */
93 /* Functions private to this file. */
95 char line_comment_chars[1];
96 char line_separator_chars[1];
98 static char *buffer; /* 1st char of each buffer of lines is here. */
99 static char *buffer_limit; /*->1 + last char in buffer. */
101 static char *bignum_low; /* Lowest char of bignum. */
102 static char *bignum_limit; /* 1st illegal address of bignum. */
103 static char *bignum_high; /* Highest char of bignum. */
104 /* May point to (bignum_start-1). */
105 /* Never >= bignum_limit. */
106 static char *old_buffer = 0; /* JF a hack */
107 static char *old_input;
108 static char *old_limit;
110 /* Variables for handling include file directory list. */
112 char **include_dirs; /* List of pointers to directories to
113 search for .include's */
114 int include_dir_count; /* How many are in the list */
115 int include_dir_maxlen = 1; /* Length of longest in list */
117 #ifndef WORKING_DOT_WORD
118 struct broken_word *broken_words;
119 int new_broken_words = 0;
124 static char *demand_copy_string(int *lenP);
125 int is_it_end_of_statement(void);
126 unsigned int next_char_of_string(void);
127 static segT get_known_segmented_expression(expressionS *expP);
128 static void grow_bignum(void);
129 static void pobegin(void);
130 void stringer(int append_zero);
134 static char *demand_copy_string();
135 int is_it_end_of_statement();
136 unsigned int next_char_of_string();
137 static segT get_known_segmented_expression();
138 static void grow_bignum();
139 static void pobegin();
142 #endif /* __STDC__ */
153 obj_read_begin_hook();
155 obstack_begin(¬es, 5000);
156 obstack_begin(&cond_obstack, 960);
158 #define BIGNUM_BEGIN_SIZE (16)
159 bignum_low = xmalloc((long)BIGNUM_BEGIN_SIZE);
160 bignum_limit = bignum_low + BIGNUM_BEGIN_SIZE;
162 /* Use machine dependent syntax */
163 for (p = line_separator_chars; *p; p++)
164 is_end_of_line[*p] = 1;
165 /* Use more. FIXME-SOMEDAY. */
168 /* set up pseudo-op tables */
170 struct hash_control *
171 po_hash = NULL; /* use before set up: NULL->address error */
174 void s_gdbline(), s_gdblinetab();
175 void s_gdbbeg(), s_gdbblock(), s_gdbend(), s_gdbsym();
178 static const pseudo_typeS
181 { "abort", s_abort, 0 },
182 { "align", s_align_ptwo, 0 },
183 { "ascii", stringer, 0 },
184 { "asciz", stringer, 1 },
187 { "comm", s_comm, 0 },
188 { "data", s_data, 0 },
190 { "double", float_cons, 'd' },
192 { "eject", listing_eject, 0 }, /* Formfeed listing */
193 { "else", s_else, 0 },
195 { "endif", s_endif, 0 },
200 { "extern", s_ignore, 0 }, /* We treat all undef as ext */
201 { "app-file", s_app_file, 0 },
202 { "file", s_app_file, 0 },
203 { "fill", s_fill, 0 },
204 { "float", float_cons, 'f' },
206 { "gdbbeg", s_gdbbeg, 0 },
207 { "gdbblock", s_gdbblock, 0 },
208 { "gdbend", s_gdbend, 0 },
209 { "gdbsym", s_gdbsym, 0 },
210 { "gdbline", s_gdbline, 0 },
211 { "gdblinetab",s_gdblinetab, 0 },
213 { "global", s_globl, 0 },
214 { "globl", s_globl, 0 },
215 { "hword", cons, 2 },
217 { "ifdef", s_ifdef, 0 },
218 { "ifeqs", s_ifeqs, 0 },
219 { "ifndef", s_ifdef, 1 },
220 { "ifnes", s_ifeqs, 1 },
221 { "ifnotdef", s_ifdef, 1 },
222 { "include", s_include, 0 },
224 { "lcomm", s_lcomm, 0 },
225 { "lflags", listing_flags, 0 }, /* Listing flags */
226 { "list", listing_list, 1 }, /* Turn listing on */
228 { "lsym", s_lsym, 0 },
229 { "nolist", listing_list, 0 }, /* Turn listing off */
230 { "octa", big_cons, 16 },
232 { "psize", listing_psize, 0 }, /* set paper size */
234 { "quad", big_cons, 8 },
235 { "sbttl", listing_title, 1 }, /* Subtitle of listing */
239 { "short", cons, 2 },
240 { "single", float_cons, 'f' },
242 { "space", s_space, 0 },
244 { "text", s_text, 0 },
245 { "title", listing_title, 0 }, /* Listing title */
250 { NULL} /* end sentinel */
253 static void pobegin() {
254 char *errtxt; /* error text */
255 const pseudo_typeS * pop;
257 po_hash = hash_new();
259 /* Do the target-specific pseudo ops. */
260 for (pop = md_pseudo_table; pop->poc_name; pop++) {
261 errtxt = hash_insert(po_hash, pop->poc_name, (char *)pop);
262 if (errtxt && *errtxt) {
263 as_fatal("error constructing md pseudo-op table");
267 /* Now object specific. Skip any that were in the target table. */
268 for (pop=obj_pseudo_table; pop->poc_name; pop++) {
269 errtxt = hash_insert (po_hash, pop->poc_name, (char *)pop);
270 if (errtxt && *errtxt) {
271 if (!strcmp (errtxt, "exists")) {
272 #ifdef DIE_ON_OVERRIDES
273 as_fatal("pseudo op \".%s\" overridden.\n", pop->poc_name);
274 #endif /* DIE_ON_OVERRIDES */
275 continue; /* OK if target table overrides. */
277 as_fatal("error constructing obj pseudo-op table");
278 } /* if overridden */
282 /* Now portable ones. Skip any that we've seen already. */
283 for (pop=potable; pop->poc_name; pop++) {
284 errtxt = hash_insert (po_hash, pop->poc_name, (char *)pop);
285 if (errtxt && *errtxt) {
286 if (!strcmp (errtxt, "exists")) {
287 #ifdef DIE_ON_OVERRIDES
288 as_fatal("pseudo op \".%s\" overridden.\n", pop->poc_name);
289 #endif /* DIE_ON_OVERRIDES */
290 continue; /* OK if target table overrides. */
292 as_fatal("error constructing obj pseudo-op table");
293 } /* if overridden */
300 #define HANDLE_CONDITIONAL_ASSEMBLY() \
301 if (ignore_input ()) \
303 while (! is_end_of_line[*input_line_pointer++]) \
304 if (input_line_pointer == buffer_limit) \
310 /* read_a_source_file()
312 * We read the file, putting things into a web that
313 * represents what we have been reading.
315 void read_a_source_file(name)
319 register char * s; /* string of symbol, '\0' appended */
321 /* register struct frag * fragP; JF unused */ /* a frag we just made */
324 void gdb_block_beg();
325 void gdb_block_position();
326 void gdb_block_end();
327 void gdb_symbols_fixup();
330 buffer = input_scrub_new_file(name);
335 while ((buffer_limit = input_scrub_next_buffer(&input_line_pointer)) != 0) { /* We have another line to parse. */
336 know(buffer_limit[-1] == '\n'); /* Must have a sentinel. */
337 contin: /* JF this goto is my fault I admit it. Someone brave please re-write
338 the whole input section here? Pleeze??? */
339 while (input_line_pointer < buffer_limit) { /* We have more of this buffer to parse. */
342 * We now have input_line_pointer->1st char of next line.
343 * If input_line_pointer [-1] == '\n' then we just
344 * scanned another line: so bump line counters.
346 if (input_line_pointer[-1] == '\n') {
347 bump_line_counters();
350 /* Text at the start of a line must be a label, we run down and stick a colon in */
351 if (is_name_beginner(*input_line_pointer))
353 char *line_start = input_line_pointer;
354 char c = get_symbol_end();
356 *input_line_pointer = c;
358 input_line_pointer++;
362 } /* just passed a newline */
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.
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!)
382 if ((c = *input_line_pointer++) == '\t' || c == ' ' || c=='\f' || c == 0) {
383 c = *input_line_pointer++;
385 know(c != ' '); /* No further leading whitespace. */
388 * C is the 1st significant character.
389 * Input_line_pointer points after that character.
391 if (is_name_beginner(c)) { /* want user-defined label or pseudo/opcode */
392 HANDLE_CONDITIONAL_ASSEMBLY();
394 s = --input_line_pointer;
395 c = get_symbol_end(); /* name's delimiter */
397 * C is character after symbol.
398 * That character's place in the input line is now '\0'.
399 * S points to the beginning of the symbol.
400 * [In case of pseudo-op, s->'.'.]
401 * Input_line_pointer->'\0' where c was.
404 colon(s); /* user-defined label */
405 * input_line_pointer ++ = ':'; /* Put ':' back for error messages' sake. */
406 /* Input_line_pointer->after ':'. */
410 } else if (c == '=' || input_line_pointer[1] == '=') { /* JF deal with FOO=BAR */
412 demand_empty_rest_of_line();
413 } else { /* expect pseudo-op or machine instruction */
422 * WARNING: c has next char, which may be end-of-line.
423 * We lookup the pseudo-op table with s+1 because we
424 * already know that the pseudo-op begins with a '.'.
427 pop = (pseudo_typeS *) hash_find(po_hash, s+1);
429 /* Print the error msg now, while we still can */
431 as_bad("Unknown pseudo-op: `%s'",s);
432 *input_line_pointer = c;
437 /* Put it back for error messages etc. */
438 *input_line_pointer = c;
439 /* The following skip of whitespace is compulsory. */
440 /* A well shaped space is sometimes all that separates keyword from operands. */
441 if (c == ' ' || c == '\t') {
442 input_line_pointer++;
443 } /* Skip seperator after keyword. */
445 * Input_line is restored.
446 * Input_line_pointer->1st non-blank char
447 * after pseudo-operation.
450 ignore_rest_of_line();
453 (*pop->poc_handler)(pop->poc_val);
454 } /* if we have one */
457 { /* machine instruction */
458 /* WARNING: c has char, which may be end-of-line. */
459 /* Also: input_line_pointer->`\0` where c was. */
460 * input_line_pointer = c;
461 while (!is_end_of_line[*input_line_pointer]) {
462 input_line_pointer++;
465 c = *input_line_pointer;
466 *input_line_pointer = '\0';
468 md_assemble(s); /* Assemble 1 instruction. */
470 *input_line_pointer++ = c;
472 /* We resume loop AFTER the end-of-line from this instruction */
477 } /* if (is_name_beginner(c) */
480 if (is_end_of_line [c]) {
482 } /* empty statement */
485 #if defined(LOCAL_LABELS_DOLLAR) || defined(LOCAL_LABELS_FB)
486 if (isdigit(c)) { /* local label ("4:") */
487 char *backup = input_line_pointer;
489 HANDLE_CONDITIONAL_ASSEMBLY ();
493 while (isdigit(*input_line_pointer)) {
494 temp = (temp * 10) + *input_line_pointer - '0';
495 ++input_line_pointer;
496 } /* read the whole number */
498 #ifdef LOCAL_LABELS_DOLLAR
499 if (*input_line_pointer == '$'
500 && *(input_line_pointer + 1) == ':') {
501 input_line_pointer += 2;
503 if (dollar_label_defined(temp)) {
504 as_fatal("label \"%d$\" redefined", temp);
507 define_dollar_label(temp);
508 colon(dollar_label_name(temp, 0));
511 #endif /* LOCAL_LABELS_DOLLAR */
513 #ifdef LOCAL_LABELS_FB
514 if (*input_line_pointer++ == ':') {
515 fb_label_instance_inc(temp);
516 colon(fb_label_name(temp, 0));
519 #endif /* LOCAL_LABELS_FB */
521 input_line_pointer = backup;
522 } /* local label ("4:") */
523 #endif /* LOCAL_LABELS_DOLLAR or LOCAL_LABELS_FB */
525 if (c && strchr(line_comment_chars,c)) { /* Its a comment. Better say APP or NO_APP */
531 extern char *scrub_string,*scrub_last_string;
533 bump_line_counters();
534 s=input_line_pointer;
535 if (strncmp(s,"APP\n",4))
536 continue; /* We ignore it */
539 ends=strstr(s,"#NO_APP\n");
545 /* The end of the #APP wasn't in this buffer. We
546 keep reading in buffers until we find the #NO_APP
547 that goes with this #APP There is one. The specs
549 tmp_len=buffer_limit-s;
550 tmp_buf=xmalloc(tmp_len);
551 bcopy(s,tmp_buf,tmp_len);
553 new_tmp = input_scrub_next_buffer(&buffer);
557 buffer_limit = new_tmp;
558 input_line_pointer = buffer;
559 ends = strstr(buffer,"#NO_APP\n");
563 num=buffer_limit-buffer;
565 tmp_buf = xrealloc(tmp_buf, tmp_len + num);
566 bcopy(buffer,tmp_buf+tmp_len,num);
570 input_line_pointer= ends ? ends+8 : NULL;
576 input_line_pointer=ends+8;
578 new_buf=xmalloc(100);
583 scrub_last_string = ends;
587 ch = do_scrub_next_char(scrub_from_string, scrub_to_string);
590 if (new_tmp==new_buf+new_length) {
591 new_buf=xrealloc(new_buf,new_length+100);
592 new_tmp=new_buf+new_length;
600 old_input=input_line_pointer;
601 old_limit=buffer_limit;
603 input_line_pointer=new_buf;
604 buffer_limit=new_tmp;
608 HANDLE_CONDITIONAL_ASSEMBLY();
610 /* as_warn("Junk character %d.",c); Now done by ignore_rest */
611 input_line_pointer--; /* Report unknown char as ignored. */
612 ignore_rest_of_line();
613 } /* while (input_line_pointer<buffer_limit) */
615 bump_line_counters();
616 if (old_input != 0) {
618 input_line_pointer=old_input;
619 buffer_limit=old_limit;
624 } /* while (more buffers to scan) */
625 input_scrub_close(); /* Close the input file */
627 } /* read_a_source_file() */
630 as_fatal(".abort detected. Abandoning ship.");
633 /* For machines where ".align 4" means align to a 4 byte boundary. */
634 void s_align_bytes(arg)
637 register unsigned int temp;
638 register long temp_fill;
640 unsigned long max_alignment = 1 << 15;
642 if (is_end_of_line[*input_line_pointer])
643 temp = arg; /* Default value from pseudo-op table */
645 temp = get_absolute_expression ();
647 if (temp > max_alignment) {
648 as_bad("Alignment too large: %d. assumed.", temp = max_alignment);
652 * For the sparc, `.align (1<<n)' actually means `.align n'
653 * so we have to convert it.
656 for (i = 0; (temp & 1) == 0; temp >>= 1, ++i)
660 as_bad("Alignment not a power of 2");
663 if (*input_line_pointer == ',') {
664 input_line_pointer ++;
665 temp_fill = get_absolute_expression ();
669 /* Only make a frag if we HAVE to. . . */
670 if (temp && ! need_pass_2)
671 frag_align(temp, (int)temp_fill);
673 demand_empty_rest_of_line();
674 } /* s_align_bytes() */
676 /* For machines where ".align 4" means align to 2**4 boundary. */
677 void s_align_ptwo() {
679 register long temp_fill;
680 long max_alignment = 15;
682 temp = get_absolute_expression ();
683 if (temp > max_alignment)
684 as_bad("Alignment too large: %d. assumed.", temp = max_alignment);
686 as_bad("Alignment negative. 0 assumed.");
689 if (*input_line_pointer == ',') {
690 input_line_pointer ++;
691 temp_fill = get_absolute_expression ();
694 /* Only make a frag if we HAVE to. . . */
695 if (temp && ! need_pass_2)
696 frag_align (temp, (int)temp_fill);
698 record_alignment(now_seg, temp);
700 demand_empty_rest_of_line();
701 } /* s_align_ptwo() */
708 register symbolS * symbolP;
710 name = input_line_pointer;
711 c = get_symbol_end();
712 /* just after name is now '\0' */
713 p = input_line_pointer;
716 if (*input_line_pointer != ',') {
717 as_bad("Expected comma after symbol-name: rest of line ignored.");
718 ignore_rest_of_line();
721 input_line_pointer ++; /* skip ',' */
722 if ((temp = get_absolute_expression()) < 0) {
723 as_warn(".COMMon length (%d.) <0! Ignored.", temp);
724 ignore_rest_of_line();
728 symbolP = symbol_find_or_make(name);
730 if (S_IS_DEFINED(symbolP)) {
731 as_bad("Ignoring attempt to re-define symbol");
732 ignore_rest_of_line();
735 if (S_GET_VALUE(symbolP)) {
736 if (S_GET_VALUE(symbolP) != temp)
737 as_bad("Length of .comm \"%s\" is already %d. Not changed to %d.",
739 S_GET_VALUE(symbolP),
742 S_SET_VALUE(symbolP, temp);
743 S_SET_EXTERNAL(symbolP);
747 symbolP->sy_other = const_flag;
749 know(symbolP->sy_frag == &zero_address_frag);
750 demand_empty_rest_of_line();
758 temp = get_absolute_expression ();
760 subseg_new (SEG_E1, (subsegT)temp);
762 subseg_new (SEG_DATA, (subsegT)temp);
768 demand_empty_rest_of_line();
775 /* Some assemblers tolerate immediately following '"' */
776 if ((s = demand_copy_string(&length)) != 0) {
777 new_logical_line(s, -1);
778 demand_empty_rest_of_line();
781 c_dot_file_symbol(s);
782 #endif /* OBJ_COFF */
786 long temp_repeat = 0;
788 register long temp_fill = 0;
792 temp_repeat = get_absolute_expression();
793 if (*input_line_pointer == ',')
795 input_line_pointer++;
796 temp_size = get_absolute_expression();
797 if (*input_line_pointer == ',')
799 input_line_pointer++;
800 temp_fill = get_absolute_expression();
804 * This is to be compatible with BSD 4.2 AS, not for any rational reason.
806 #define BSD_FILL_SIZE_CROCK_8 (8)
807 if (temp_size > BSD_FILL_SIZE_CROCK_8) {
808 as_warn(".fill size clamped to %d.", BSD_FILL_SIZE_CROCK_8);
809 temp_size = BSD_FILL_SIZE_CROCK_8 ;
810 } if (temp_size < 0) {
811 as_warn("Size negative: .fill ignored.");
813 } else if (temp_repeat <= 0) {
814 as_warn("Repeat < 0, .fill ignored");
818 if (temp_size && !need_pass_2) {
819 p = frag_var(rs_fill, (int)temp_size, (int)temp_size, (relax_substateT)0, (symbolS *)0, temp_repeat, (char *)0);
820 bzero (p, (int)temp_size);
822 * The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX flavoured AS.
823 * The following bizzare behaviour is to be compatible with above.
824 * I guess they tried to take up to 8 bytes from a 4-byte expression
825 * and they forgot to sign extend. Un*x Sux.
827 #define BSD_FILL_SIZE_CROCK_4 (4)
828 md_number_to_chars (p, temp_fill, temp_size > BSD_FILL_SIZE_CROCK_4 ? BSD_FILL_SIZE_CROCK_4 : (int)temp_size);
830 * Note: .fill (),0 emits no frag (since we are asked to .fill 0 bytes)
831 * but emits no error message because it seems a legal thing to do.
832 * It is a degenerate case of .fill but could be emitted by a compiler.
835 demand_empty_rest_of_line();
844 temp = get_absolute_expression ();
846 as_warn("Block number <0. Ignored.");
847 else if (flagseen ['G'])
848 gdb_block_beg ((long) temp, frag_now, (long)(obstack_next_free(& frags) - frag_now->fr_literal));
849 demand_empty_rest_of_line ();
855 register int position;
858 if (get_absolute_expression_and_terminator (&temp) != ',') {
859 as_bad("expected comma before position in .gdbblock");
860 --input_line_pointer;
861 ignore_rest_of_line ();
864 position = get_absolute_expression ();
866 gdb_block_position ((long) temp, (long) position);
867 demand_empty_rest_of_line ();
875 temp = get_absolute_expression ();
877 as_warn("Block number <0. Ignored.");
878 else if (flagseen ['G'])
879 gdb_block_end ((long) temp, frag_now, (long)(obstack_next_free(& frags) - frag_now->fr_literal));
880 demand_empty_rest_of_line ();
889 register symbolS * symbolP;
892 name = input_line_pointer;
893 c = get_symbol_end();
894 p = input_line_pointer;
895 symbolP = symbol_find_or_make(name);
898 if (* input_line_pointer != ',') {
899 as_bad("Expected comma after name");
900 ignore_rest_of_line();
903 input_line_pointer ++;
904 if ((temp = get_absolute_expression ()) < 0) {
905 as_bad("Bad GDB symbol file offset (%d.) <0! Ignored.", temp);
906 ignore_rest_of_line();
910 gdb_symbols_fixup (symbolP, (long)temp);
911 demand_empty_rest_of_line ();
920 if (get_absolute_expression_and_terminator(&file_number) != ',') {
921 as_bad("expected comman after filenum in .gdbline");
922 ignore_rest_of_line();
925 lineno=get_absolute_expression();
927 gdb_line(file_number,lineno);
928 demand_empty_rest_of_line();
938 if (get_absolute_expression_and_terminator(&file_number) != ',') {
939 as_bad("expected comma after filenum in .gdblinetab");
940 ignore_rest_of_line();
943 offset=get_absolute_expression();
945 gdb_line_tab(file_number,offset);
946 demand_empty_rest_of_line();
953 register symbolS * symbolP;
956 name = input_line_pointer;
957 c = get_symbol_end();
958 symbolP = symbol_find_or_make(name);
959 * input_line_pointer = c;
961 S_SET_EXTERNAL(symbolP);
963 input_line_pointer++;
965 if (*input_line_pointer=='\n')
969 demand_empty_rest_of_line();
972 void s_lcomm(needs_align)
973 int needs_align; /* 1 if this was a ".bss" directive, which may require
974 * a 3rd argument (alignment).
975 * 0 if it was an ".lcomm" (2 args only)
982 register symbolS * symbolP;
983 const int max_alignment = 15;
986 name = input_line_pointer;
987 c = get_symbol_end();
988 p = input_line_pointer;
991 if (*input_line_pointer != ',') {
992 as_bad("Expected comma after name");
993 ignore_rest_of_line();
997 ++input_line_pointer;
999 if (*input_line_pointer == '\n') {
1000 as_bad("Missing size expression");
1004 if ((temp = get_absolute_expression ()) < 0) {
1005 as_warn("BSS length (%d.) <0! Ignored.", temp);
1006 ignore_rest_of_line();
1013 if (*input_line_pointer != ',') {
1014 as_bad("Expected comma after size");
1015 ignore_rest_of_line();
1018 input_line_pointer++;
1020 if (*input_line_pointer == '\n') {
1021 as_bad("Missing alignment");
1024 align = get_absolute_expression ();
1025 if (align > max_alignment){
1026 align = max_alignment;
1027 as_warn("Alignment too large: %d. assumed.", align);
1028 } else if (align < 0) {
1030 as_warn("Alignment negative. 0 assumed.");
1032 #ifdef MANY_SEGMENTS
1033 #define SEG_BSS SEG_E2
1034 record_alignment(SEG_E2, align);
1036 record_alignment(SEG_BSS, align);
1038 } /* if needs align */
1041 symbolP = symbol_find_or_make(name);
1045 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1046 S_GET_OTHER(symbolP) == 0 &&
1047 S_GET_DESC(symbolP) == 0 &&
1048 #endif /* OBJ_AOUT or OBJ_BOUT */
1049 (((S_GET_SEGMENT(symbolP) == SEG_BSS) && (S_GET_VALUE(symbolP) == local_bss_counter))
1050 || (!S_IS_DEFINED(symbolP) && S_GET_VALUE(symbolP) == 0))) {
1053 align = ~ ((~0) << align); /* Convert to a mask */
1055 (local_bss_counter + align) & (~align);
1058 S_SET_VALUE(symbolP,local_bss_counter);
1059 S_SET_SEGMENT(symbolP, SEG_BSS);
1061 /* The symbol may already have been created with a preceding
1062 * ".globl" directive -- be careful not to step on storage
1063 * class in that case. Otherwise, set it to static.
1065 if (S_GET_STORAGE_CLASS(symbolP) != C_EXT){
1066 S_SET_STORAGE_CLASS(symbolP, C_STAT);
1068 #endif /* OBJ_COFF */
1069 symbolP->sy_frag = & bss_address_frag;
1070 local_bss_counter += temp;
1072 as_bad("Ignoring attempt to re-define symbol from %d. to %d.",
1073 S_GET_VALUE(symbolP), local_bss_counter);
1075 demand_empty_rest_of_line();
1093 register char *name;
1096 register segT segment;
1098 register symbolS *symbolP;
1100 /* we permit ANY defined expression: BSD4.2 demands constants */
1101 name = input_line_pointer;
1102 c = get_symbol_end();
1103 p = input_line_pointer;
1106 if (* input_line_pointer != ',') {
1108 as_bad("Expected comma after name \"%s\"", name);
1110 ignore_rest_of_line();
1113 input_line_pointer ++;
1114 segment = expression(& exp);
1115 if (segment != SEG_ABSOLUTE
1116 #ifdef MANY_SEGMENTS
1117 && ! ( segment >= SEG_E0 && segment <= SEG_UNKNOWN)
1119 && segment != SEG_DATA
1120 && segment != SEG_TEXT
1121 && segment != SEG_BSS
1123 && segment != SEG_REGISTER) {
1124 as_bad("Bad expression: %s", segment_name(segment));
1125 ignore_rest_of_line();
1129 symbolP = symbol_find_or_make(name);
1131 /* FIXME-SOON I pulled a (&& symbolP->sy_other == 0
1132 && symbolP->sy_desc == 0) out of this test
1133 because coff doesn't have those fields, and I
1134 can't see when they'd ever be tripped. I don't
1135 think I understand why they were here so I may
1136 have introduced a bug. As recently as 1.37 didn't
1137 have this test anyway. xoxorich. */
1139 if (S_GET_SEGMENT(symbolP) == SEG_UNKNOWN
1140 && S_GET_VALUE(symbolP) == 0) {
1141 /* The name might be an undefined .global symbol; be
1142 sure to keep the "external" bit. */
1143 S_SET_SEGMENT(symbolP, segment);
1144 S_SET_VALUE(symbolP, (valueT)(exp.X_add_number));
1146 as_bad("Symbol %s already defined", name);
1149 demand_empty_rest_of_line();
1153 register segT segment;
1155 register long temp_fill;
1158 * Don't believe the documentation of BSD 4.2 AS.
1159 * There is no such thing as a sub-segment-relative origin.
1160 * Any absolute origin is given a warning, then assumed to be segment-relative.
1161 * Any segmented origin expression ("foo+42") had better be in the right
1162 * segment or the .org is ignored.
1164 * BSD 4.2 AS warns if you try to .org backwards. We cannot because we
1165 * never know sub-segment sizes when we are reading code.
1166 * BSD will crash trying to emit -ve numbers of filler bytes in certain
1167 * .orgs. We don't crash, but see as-write for that code.
1170 * Don't make frag if need_pass_2==1.
1172 segment = get_known_segmented_expression(&exp);
1173 if (*input_line_pointer == ',') {
1174 input_line_pointer ++;
1175 temp_fill = get_absolute_expression ();
1178 if (! need_pass_2) {
1179 if (segment != now_seg && segment != SEG_ABSOLUTE)
1180 as_bad("Invalid segment \"%s\". Segment \"%s\" assumed.",
1181 segment_name(segment), segment_name(now_seg));
1182 p = frag_var (rs_org, 1, 1, (relax_substateT)0, exp . X_add_symbol,
1183 exp . X_add_number, (char *)0);
1185 } /* if (ok to make frag) */
1186 demand_empty_rest_of_line();
1190 register char *name;
1191 register char delim;
1192 register char *end_name;
1193 register symbolS *symbolP;
1196 * Especial apologies for the random logic:
1197 * this just grew, and could be parsed much more simply!
1200 name = input_line_pointer;
1201 delim = get_symbol_end();
1202 end_name = input_line_pointer;
1206 if (*input_line_pointer != ',') {
1208 as_bad("Expected comma after name \"%s\"", name);
1210 ignore_rest_of_line();
1214 input_line_pointer ++;
1217 if (name[0]=='.' && name[1]=='\0') {
1218 /* Turn '. = mumble' into a .org mumble */
1219 register segT segment;
1223 segment = get_known_segmented_expression(& exp);
1226 if (segment != now_seg && segment != SEG_ABSOLUTE)
1227 as_bad("Invalid segment \"%s\". Segment \"%s\" assumed.",
1228 segment_name(segment),
1229 segment_name (now_seg));
1230 ptr = frag_var(rs_org, 1, 1, (relax_substateT)0, exp.X_add_symbol,
1231 exp.X_add_number, (char *)0);
1233 } /* if (ok to make frag) */
1239 if ((symbolP = symbol_find(name)) == NULL
1240 && (symbolP = md_undefined_symbol(name)) == NULL) {
1241 symbolP = symbol_new(name,
1244 &zero_address_frag);
1246 /* "set" symbols are local unless otherwise specified. */
1247 SF_SET_LOCAL(symbolP);
1248 #endif /* OBJ_COFF */
1250 } /* make a new symbol */
1252 symbol_table_insert(symbolP);
1255 pseudo_set(symbolP);
1256 demand_empty_rest_of_line();
1263 register long temp_fill;
1266 /* Just like .fill, but temp_size = 1 */
1267 if (get_absolute_expression_and_terminator(& temp_repeat) == ',') {
1268 temp_fill = get_absolute_expression ();
1270 input_line_pointer --; /* Backup over what was not a ','. */
1277 if (temp_repeat <= 0) {
1278 as_warn("Repeat < 0, .space ignored");
1279 ignore_rest_of_line();
1282 if (! need_pass_2) {
1283 p = frag_var (rs_fill, 1, 1, (relax_substateT)0, (symbolS *)0,
1284 temp_repeat, (char *)0);
1287 demand_empty_rest_of_line();
1295 temp = get_absolute_expression ();
1296 #ifdef MANY_SEGMENTS
1297 subseg_new (SEG_E0, (subsegT)temp);
1299 subseg_new (SEG_TEXT, (subsegT)temp);
1301 demand_empty_rest_of_line();
1305 /*(JF was static, but can't be if machine dependent pseudo-ops are to use it */
1307 void demand_empty_rest_of_line() {
1309 if (is_end_of_line [*input_line_pointer]) {
1310 input_line_pointer++;
1312 ignore_rest_of_line();
1314 /* Return having already swallowed end-of-line. */
1315 } /* Return pointing just after end-of-line. */
1318 ignore_rest_of_line() /* For suspect lines: gives warning. */
1320 if (! is_end_of_line [* input_line_pointer])
1322 if (isprint(*input_line_pointer))
1323 as_bad("Rest of line ignored. First ignored character is `%c'.",
1324 *input_line_pointer);
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])
1331 input_line_pointer ++;
1334 input_line_pointer ++; /* Return pointing just after end-of-line. */
1335 know(is_end_of_line [input_line_pointer [-1]]);
1341 * In: Pointer to a symbol.
1342 * Input_line_pointer->expression.
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.
1350 pseudo_set (symbolP)
1354 register segT segment;
1355 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1357 #endif /* OBJ_AOUT or OBJ_BOUT */
1359 know(symbolP); /* NULL pointer is logic error. */
1360 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1361 ext=S_IS_EXTERNAL(symbolP);
1362 #endif /* OBJ_AOUT or OBJ_BOUT */
1364 if ((segment = expression(& exp)) == SEG_ABSENT)
1366 as_bad("Missing expression: absolute 0 assumed");
1367 exp . X_seg = SEG_ABSOLUTE;
1368 exp . X_add_number = 0;
1374 S_SET_SEGMENT(symbolP, SEG_REGISTER);
1375 S_SET_VALUE(symbolP, exp.X_add_number);
1376 symbolP->sy_frag = & zero_address_frag;
1380 as_bad("%s number invalid. Absolute 0 assumed.",
1381 exp . X_add_number > 0 ? "Bignum" : "Floating-Point");
1382 S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
1383 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1384 ext ? S_SET_EXTERNAL(symbolP) :
1385 S_CLEAR_EXTERNAL(symbolP);
1386 #endif /* OBJ_AOUT or OBJ_BOUT */
1387 S_SET_VALUE(symbolP, 0);
1388 symbolP->sy_frag = & zero_address_frag;
1392 as_warn("No expression: Using absolute 0");
1393 S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
1394 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1395 ext ? S_SET_EXTERNAL(symbolP) :
1396 S_CLEAR_EXTERNAL(symbolP);
1397 #endif /* OBJ_AOUT or OBJ_BOUT */
1398 S_SET_VALUE(symbolP, 0);
1399 symbolP->sy_frag = & zero_address_frag;
1402 case SEG_DIFFERENCE:
1403 if (exp.X_add_symbol && exp.X_subtract_symbol
1404 && (S_GET_SEGMENT(exp.X_add_symbol) ==
1405 S_GET_SEGMENT(exp.X_subtract_symbol))) {
1406 if (exp.X_add_symbol->sy_frag != exp.X_subtract_symbol->sy_frag) {
1407 as_bad("Unknown expression: symbols %s and %s are in different frags.",
1408 S_GET_NAME(exp.X_add_symbol), S_GET_NAME(exp.X_subtract_symbol));
1411 exp.X_add_number+=S_GET_VALUE(exp.X_add_symbol) -
1412 S_GET_VALUE(exp.X_subtract_symbol);
1414 as_bad("Complex expression. Absolute segment assumed.");
1416 S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
1417 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1418 ext ? S_SET_EXTERNAL(symbolP) :
1419 S_CLEAR_EXTERNAL(symbolP);
1420 #endif /* OBJ_AOUT or OBJ_BOUT */
1421 S_SET_VALUE(symbolP, exp.X_add_number);
1422 symbolP->sy_frag = & zero_address_frag;
1426 #ifdef MANY_SEGMENTS
1427 S_SET_SEGMENT(symbolP, segment);
1430 case SEG_DATA: S_SET_SEGMENT(symbolP, SEG_DATA); break;
1431 case SEG_TEXT: S_SET_SEGMENT(symbolP, SEG_TEXT); break;
1432 case SEG_BSS: S_SET_SEGMENT(symbolP, SEG_BSS); break;
1434 default: as_fatal("failed sanity check.");
1435 } /* switch on segment */
1437 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1439 S_SET_EXTERNAL(symbolP);
1441 S_CLEAR_EXTERNAL(symbolP);
1443 #endif /* OBJ_AOUT or OBJ_BOUT */
1445 S_SET_VALUE(symbolP, exp.X_add_number + S_GET_VALUE(exp.X_add_symbol));
1446 symbolP->sy_frag = exp . X_add_symbol->sy_frag;
1449 case SEG_PASS1: /* Not an error. Just try another pass. */
1450 symbolP->sy_forward=exp.X_add_symbol;
1451 as_bad("Unknown expression");
1452 know(need_pass_2 == 1);
1456 symbolP->sy_forward=exp.X_add_symbol;
1457 /* as_warn("unknown symbol"); */
1458 /* need_pass_2 = 1; */
1469 * CONStruct more frag of .bytes, or .words etc.
1470 * Should need_pass_2 be 1 then emit no frag(s).
1471 * This understands EXPRESSIONS, as opposed to big_cons().
1475 * This has a split personality. We use expression() to read the
1476 * value. We can detect if the value won't fit in a byte or word.
1477 * But we can't detect if expression() discarded significant digits
1478 * in the case of a long. Not worth the crocks required to fix it.
1481 /* worker to do .byte etc statements */
1482 /* clobbers input_line_pointer, checks */
1485 register unsigned int nbytes; /* 1=.byte, 2=.word, 4=.long */
1488 register long mask; /* High-order bits we will left-truncate, */
1489 /* but includes sign bit also. */
1490 register long get; /* what we get */
1491 register long use; /* get after truncation. */
1492 register long unmask; /* what bits we will store */
1494 register segT segment;
1498 * Input_line_pointer->1st char after pseudo-op-code and could legally
1499 * be a end-of-line. (Or, less legally an eof - which we cope with.)
1501 /* JF << of >= number of bits in the object is undefined. In particular
1502 SPARC (Sun 4) has problems */
1504 if (nbytes>=sizeof(long)) {
1507 mask = ~0 << (BITS_PER_CHAR * nbytes); /* Don't store these bits. */
1508 } /* bigger than a long */
1510 unmask = ~mask; /* Do store these bits. */
1513 "Do this mod if you want every overflow check to assume SIGNED 2's complement data.";
1514 mask = ~ (unmask >> 1); /* Includes sign bit now. */
1518 * The following awkward logic is to parse ZERO or more expressions,
1519 * comma seperated. Recall an expression includes its leading &
1520 * trailing blanks. We fake a leading ',' if there is (supposed to
1521 * be) a 1st expression, and keep demanding 1 expression for each ','.
1523 if (is_it_end_of_statement()) {
1524 c = 0; /* Skip loop. */
1525 input_line_pointer++; /* Matches end-of-loop 'correction'. */
1528 } /* if the end else fake it */
1532 #ifdef WANT_BITFIELDS
1533 unsigned int bits_available = BITS_PER_CHAR * nbytes;
1534 /* used for error messages and rescanning */
1535 char *hold = input_line_pointer;
1536 #endif /* WANT_BITFIELDS */
1538 if (*input_line_pointer == '\'')
1540 /* An MRI style string, cut into as many bytes as will fit
1541 into a nbyte chunk, left justify if necessary, and sepatate
1542 with commas so we can try again later */
1544 unsigned int result = 0;
1545 input_line_pointer++;
1546 for (scan = 0; scan < nbytes; scan++)
1548 if (*input_line_pointer == '\'')
1550 if (input_line_pointer[1] == '\'')
1552 input_line_pointer++;
1557 result = (result << 8) | (*input_line_pointer++);
1561 while (scan < nbytes)
1566 /* Create correct expression */
1567 exp.X_add_symbol = 0;
1568 exp.X_add_number = result;
1569 exp.X_seg = segment = SEG_ABSOLUTE;
1570 /* Fake it so that we can read the next char too */
1571 if (input_line_pointer[0] != '\'' ||
1572 (input_line_pointer[0] == '\'' && input_line_pointer[1] == '\''))
1574 input_line_pointer-=2;
1575 input_line_pointer[0] = ',';
1576 input_line_pointer[1] = '\'';
1579 input_line_pointer++;
1584 /* At least scan over the expression. */
1585 segment = expression(&exp);
1587 #ifdef WANT_BITFIELDS
1588 /* Some other assemblers, (eg, asm960), allow
1589 bitfields after ".byte" as w:x,y:z, where w and
1590 y are bitwidths and x and y are values. They
1591 then pack them all together. We do a little
1592 better in that we allow them in words, longs,
1593 etc. and we'll pack them in target byte order
1596 The rules are: pack least significat bit first,
1597 if a field doesn't entirely fit, put it in the
1598 next unit. Overflowing the bitfield is
1599 explicitly *not* even a warning. The bitwidth
1600 should be considered a "mask".
1602 FIXME-SOMEDAY: If this is considered generally
1603 useful, this logic should probably be reworked.
1606 if (*input_line_pointer == ':') { /* bitfields */
1610 unsigned long width;
1612 if (*input_line_pointer != ':') {
1613 input_line_pointer = hold;
1615 } /* next piece is not a bitfield */
1617 /* In the general case, we can't allow
1618 full expressions with symbol
1619 differences and such. The relocation
1620 entries for symbols not defined in this
1621 assembly would require arbitrary field
1622 widths, positions, and masks which most
1623 of our current object formats don't
1626 In the specific case where a symbol
1627 *is* defined in this assembly, we
1628 *could* build fixups and track it, but
1629 this could lead to confusion for the
1630 backends. I'm lazy. I'll take any
1631 SEG_ABSOLUTE. I think that means that
1632 you can use a previous .set or
1633 .equ type symbol. xoxorich. */
1635 if (segment == SEG_ABSENT) {
1636 as_warn("Using a bit field width of zero.");
1637 exp.X_add_number = 0;
1638 segment = SEG_ABSOLUTE;
1639 } /* implied zero width bitfield */
1641 if (segment != SEG_ABSOLUTE) {
1642 *input_line_pointer = '\0';
1643 as_bad("Field width \"%s\" too complex for a bitfield.\n", hold);
1644 *input_line_pointer = ':';
1645 demand_empty_rest_of_line();
1649 if ((width = exp.X_add_number) > (BITS_PER_CHAR * nbytes)) {
1650 as_warn("Field width %d too big to fit in %d bytes: truncated to %d bits.",
1651 width, nbytes, (BITS_PER_CHAR * nbytes));
1652 width = BITS_PER_CHAR * nbytes;
1655 if (width > bits_available) {
1656 /* FIXME-SOMEDAY: backing up and
1657 reparsing is wasteful */
1658 input_line_pointer = hold;
1659 exp.X_add_number = value;
1663 hold = ++input_line_pointer; /* skip ':' */
1665 if ((segment = expression(&exp)) != SEG_ABSOLUTE) {
1666 char cache = *input_line_pointer;
1668 *input_line_pointer = '\0';
1669 as_bad("Field value \"%s\" too complex for a bitfield.\n", hold);
1670 *input_line_pointer = cache;
1671 demand_empty_rest_of_line();
1675 value |= (~(-1 << width) & exp.X_add_number)
1676 << ((BITS_PER_CHAR * nbytes) - bits_available);
1678 if ((bits_available -= width) == 0
1679 || is_it_end_of_statement()
1680 || *input_line_pointer != ',') {
1682 } /* all the bitfields we're gonna get */
1684 hold = ++input_line_pointer;
1685 segment = expression(&exp);
1686 } /* forever loop */
1688 exp.X_add_number = value;
1689 segment = SEG_ABSOLUTE;
1690 } /* if looks like a bitfield */
1691 #endif /* WANT_BITFIELDS */
1693 if (!need_pass_2) { /* Still worthwhile making frags. */
1695 /* Don't call this if we are going to junk this pass anyway! */
1696 know(segment != SEG_PASS1);
1698 if (segment == SEG_DIFFERENCE && exp.X_add_symbol == NULL) {
1699 as_bad("Subtracting symbol \"%s\"(segment\"%s\") is too hard. Absolute segment assumed.",
1700 S_GET_NAME(exp.X_subtract_symbol),
1701 segment_name(S_GET_SEGMENT(exp.X_subtract_symbol)));
1702 segment = SEG_ABSOLUTE;
1703 /* Leave exp . X_add_number alone. */
1705 p = frag_more(nbytes);
1708 as_bad("%s number invalid. Absolute 0 assumed.",
1709 exp . X_add_number > 0 ? "Bignum" : "Floating-Point");
1710 md_number_to_chars (p, (long)0, nbytes);
1714 as_warn("0 assumed for missing expression");
1715 exp . X_add_number = 0;
1716 know(exp . X_add_symbol == NULL);
1717 /* fall into SEG_ABSOLUTE */
1719 get = exp . X_add_number;
1721 if ((get & mask) && (get & mask) != mask)
1722 { /* Leading bits contain both 0s & 1s. */
1723 as_warn("Value 0x%x truncated to 0x%x.", get, use);
1725 md_number_to_chars (p, use, nbytes); /* put bytes in right order. */
1728 case SEG_DIFFERENCE:
1729 #ifndef WORKING_DOT_WORD
1731 struct broken_word *x;
1733 x=(struct broken_word *)xmalloc(sizeof(struct broken_word));
1734 x->next_broken_word=broken_words;
1737 x->word_goes_here=p;
1739 x->add=exp.X_add_symbol;
1740 x->sub=exp.X_subtract_symbol;
1741 x->addnum=exp.X_add_number;
1746 /* Else Fall through into. . . */
1751 fix_new_ns32k (frag_now, p - frag_now->fr_literal, nbytes,
1752 exp . X_add_symbol, exp . X_subtract_symbol,
1753 exp . X_add_number, 0, 0, 2, 0, 0);
1755 # if defined(TC_SPARC) || defined(TC_A29K)
1756 fix_new (frag_now, p - frag_now->fr_literal, nbytes,
1757 exp . X_add_symbol, exp . X_subtract_symbol,
1758 exp . X_add_number, 0, RELOC_32);
1760 # if defined(TC_H8300)
1761 fix_new (frag_now, p - frag_now->fr_literal, nbytes,
1762 exp . X_add_symbol, exp . X_subtract_symbol,
1763 exp . X_add_number, 0, R_RELWORD);
1766 fix_new (frag_now, p - frag_now->fr_literal, nbytes,
1767 exp . X_add_symbol, exp . X_subtract_symbol,
1768 exp . X_add_number, 0, 0);
1770 # endif /* tc_h8300 */
1771 # endif /* tc_sparc|tc_a29k */
1772 #endif /* TC_NS32K */
1774 } /* switch(segment) */
1775 } /* if (!need_pass_2) */
1776 c = *input_line_pointer++;
1777 } /* while(c==',') */
1778 input_line_pointer--; /* Put terminator back into stream. */
1779 demand_empty_rest_of_line();
1785 * CONStruct more frag(s) of .quads, or .octa etc.
1786 * Makes 0 or more new frags.
1787 * If need_pass_2 == 1, generate no frag.
1788 * This understands only bignums, not expressions. Cons() understands
1791 * Constants recognised are '0...'(octal) '0x...'(hex) '...'(decimal).
1793 * This creates objects with struct obstack_control objs, destroying
1794 * any context objs held about a partially completed object. Beware!
1797 * I think it sucks to have 2 different types of integers, with 2
1798 * routines to read them, store them etc.
1799 * It would be nicer to permit bignums in expressions and only
1800 * complain if the result overflowed. However, due to "efficiency"...
1802 /* worker to do .quad etc statements */
1803 /* clobbers input_line_pointer, checks */
1805 /* 8=.quad 16=.octa ... */
1807 void big_cons(nbytes)
1808 register int nbytes;
1810 register char c; /* input_line_pointer->c. */
1812 register long length; /* Number of chars in an object. */
1813 register int digit; /* Value of 1 digit. */
1814 register int carry; /* For multi-precision arithmetic. */
1815 register int work; /* For multi-precision arithmetic. */
1816 register char * p; /* For multi-precision arithmetic. */
1818 extern char hex_value[]; /* In hex_value.c. */
1821 * The following awkward logic is to parse ZERO or more strings,
1822 * comma seperated. Recall an expression includes its leading &
1823 * trailing blanks. We fake a leading ',' if there is (supposed to
1824 * be) a 1st expression, and keep demanding 1 expression for each ','.
1826 if (is_it_end_of_statement())
1828 c = 0; /* Skip loop. */
1832 c = ','; /* Do loop. */
1833 -- input_line_pointer;
1837 ++ input_line_pointer;
1839 c = * input_line_pointer;
1840 /* C contains 1st non-blank character of what we hope is a number. */
1843 c = * ++ input_line_pointer;
1844 if (c == 'x' || c=='X')
1846 c = * ++ input_line_pointer;
1859 * This feature (?) is here to stop people worrying about
1860 * mysterious zero constants: which is what they get when
1861 * they completely omit digits.
1863 if (hex_value[c] >= radix) {
1864 as_bad("Missing digits. 0 assumed.");
1866 bignum_high = bignum_low - 1; /* Start constant with 0 chars. */
1867 for(; (digit = hex_value [c]) < radix; c = * ++ input_line_pointer)
1869 /* Multiply existing number by radix, then add digit. */
1871 for (p=bignum_low; p <= bignum_high; p++)
1873 work = (*p & MASK_CHAR) * radix + carry;
1874 *p = work & MASK_CHAR;
1875 carry = work >> BITS_PER_CHAR;
1880 * bignum_high = carry & MASK_CHAR;
1881 know((carry & ~ MASK_CHAR) == 0);
1884 length = bignum_high - bignum_low + 1;
1885 if (length > nbytes)
1887 as_warn("Most significant bits truncated in integer constant.");
1891 register long leading_zeroes;
1893 for(leading_zeroes = nbytes - length;
1903 p = frag_more (nbytes);
1904 bcopy (bignum_low, p, (int)nbytes);
1906 /* C contains character after number. */
1908 c = * input_line_pointer;
1909 /* C contains 1st non-blank character after number. */
1911 demand_empty_rest_of_line();
1914 /* Extend bignum by 1 char. */
1915 static void grow_bignum() {
1916 register long length;
1919 if (bignum_high >= bignum_limit)
1921 length = bignum_limit - bignum_low;
1922 bignum_low = xrealloc(bignum_low, length + length);
1923 bignum_high = bignum_low + length;
1924 bignum_limit = bignum_low + length + length;
1926 } /* grow_bignum(); */
1931 * CONStruct some more frag chars of .floats .ffloats etc.
1932 * Makes 0 or more new frags.
1933 * If need_pass_2 == 1, no frags are emitted.
1934 * This understands only floating literals, not expressions. Sorry.
1936 * A floating constant is defined by atof_generic(), except it is preceded
1937 * by 0d 0f 0g or 0h. After observing the STRANGE way my BSD AS does its
1938 * reading, I decided to be incompatible. This always tries to give you
1939 * rounded bits to the precision of the pseudo-op. Former AS did premature
1940 * truncatation, restored noisy bits instead of trailing 0s AND gave you
1941 * a choice of 2 flavours of noise according to which of 2 floating-point
1942 * scanners you directed AS to use.
1944 * In: input_line_pointer->whitespace before, or '0' of flonum.
1948 void /* JF was static, but can't be if VAX.C is goning to use it */
1949 float_cons(float_type) /* Worker to do .float etc statements. */
1950 /* Clobbers input_line-pointer, checks end-of-line. */
1951 register int float_type; /* 'f':.ffloat ... 'F':.float ... */
1955 int length; /* Number of chars in an object. */
1956 register char * err; /* Error from scanning floating literal. */
1957 char temp [MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
1960 * The following awkward logic is to parse ZERO or more strings,
1961 * comma seperated. Recall an expression includes its leading &
1962 * trailing blanks. We fake a leading ',' if there is (supposed to
1963 * be) a 1st expression, and keep demanding 1 expression for each ','.
1965 if (is_it_end_of_statement())
1967 c = 0; /* Skip loop. */
1968 ++ input_line_pointer; /*->past termintor. */
1972 c = ','; /* Do loop. */
1976 /* input_line_pointer->1st char of a flonum (we hope!). */
1978 /* Skip any 0{letter} that may be present. Don't even check if the
1979 * letter is legal. Someone may invent a "z" format and this routine
1980 * has no use for such information. Lusers beware: you get
1981 * diagnostics if your input is ill-conditioned.
1984 if (input_line_pointer[0]=='0' && isalpha(input_line_pointer[1]))
1985 input_line_pointer+=2;
1987 err = md_atof (float_type, temp, &length);
1988 know(length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
1992 as_bad("Bad floating literal: %s", err);
1993 ignore_rest_of_line();
1994 /* Input_line_pointer->just after end-of-line. */
1995 c = 0; /* Break out of loop. */
2001 p = frag_more (length);
2002 bcopy (temp, p, length);
2005 c = * input_line_pointer ++;
2006 /* C contains 1st non-white character after number. */
2007 /* input_line_pointer->just after terminator (c). */
2010 -- input_line_pointer; /*->terminator (is not ','). */
2011 demand_empty_rest_of_line();
2012 } /* float_cons() */
2017 * We read 0 or more ',' seperated, double-quoted strings.
2019 * Caller should have checked need_pass_2 is FALSE because we don't check it.
2023 void stringer(append_zero ) /* Worker to do .ascii etc statements. */
2024 /* Checks end-of-line. */
2025 register int append_zero; /* 0: don't append '\0', else 1 */
2027 /* register char * p; JF unused */
2028 /* register int length; JF unused */ /* Length of string we read, excluding */
2029 /* trailing '\0' implied by closing quote. */
2030 /* register char * where; JF unused */
2031 /* register fragS * fragP; JF unused */
2032 register unsigned int c;
2035 * The following awkward logic is to parse ZERO or more strings,
2036 * comma seperated. Recall a string expression includes spaces
2037 * before the opening '\"' and spaces after the closing '\"'.
2038 * We fake a leading ',' if there is (supposed to be)
2039 * a 1st, expression. We keep demanding expressions for each
2042 if (is_it_end_of_statement())
2044 c = 0; /* Skip loop. */
2045 ++ input_line_pointer; /* Compensate for end of loop. */
2049 c = ','; /* Do loop. */
2051 while (c == ',' || c == '<' || c == '"' ) {
2053 switch (*input_line_pointer) {
2055 ++input_line_pointer; /*->1st char of string. */
2056 while (is_a_char(c = next_char_of_string())) {
2057 FRAG_APPEND_1_CHAR(c);
2060 FRAG_APPEND_1_CHAR(0);
2062 know(input_line_pointer [-1] == '\"');
2065 input_line_pointer++;
2066 c =get_single_number();
2067 FRAG_APPEND_1_CHAR(c);
2068 if(*input_line_pointer != '>') {
2069 as_bad("Expected <nn>");
2071 input_line_pointer++;
2074 input_line_pointer++;
2078 c = *input_line_pointer;
2081 demand_empty_rest_of_line();
2084 /* FIXME-SOMEDAY: I had trouble here on characters with the
2085 high bits set. We'll probably also have trouble with
2086 multibyte chars, wide chars, etc. Also be careful about
2087 returning values bigger than 1 byte. xoxorich. */
2089 unsigned int next_char_of_string() {
2090 register unsigned int c;
2092 c = *input_line_pointer++ & CHAR_MASK;
2099 switch (c = *input_line_pointer++) {
2128 break; /* As itself. */
2142 for (number = 0; isdigit(c); c = *input_line_pointer++) {
2143 number = number * 8 + c - '0';
2147 --input_line_pointer;
2151 /* To be compatible with BSD 4.2 as: give the luser a linefeed!! */
2152 as_warn("Unterminated string: Newline inserted.");
2158 #ifdef ONLY_STANDARD_ESCAPES
2159 as_bad("Bad escaped character in string, '?' assumed");
2161 #endif /* ONLY_STANDARD_ESCAPES */
2164 } /* switch on escaped char */
2169 } /* switch on char */
2171 } /* next_char_of_string() */
2174 get_segmented_expression (expP)
2175 register expressionS * expP;
2177 register segT retval;
2179 if ((retval = expression(expP)) == SEG_PASS1 || retval == SEG_ABSENT || retval == SEG_BIG)
2181 as_bad("Expected address expression: absolute 0 assumed");
2182 retval = expP->X_seg = SEG_ABSOLUTE;
2183 expP->X_add_number = 0;
2184 expP->X_add_symbol = expP->X_subtract_symbol = 0;
2186 return (retval); /* SEG_ ABSOLUTE,UNKNOWN,DATA,TEXT,BSS */
2189 static segT get_known_segmented_expression(expP)
2190 register expressionS *expP;
2192 register segT retval;
2193 register char * name1;
2194 register char * name2;
2196 if ((retval = get_segmented_expression (expP)) == SEG_UNKNOWN)
2198 name1 = expP->X_add_symbol ? S_GET_NAME(expP->X_add_symbol) : "";
2199 name2 = expP->X_subtract_symbol ?
2200 S_GET_NAME(expP->X_subtract_symbol) :
2204 as_warn("Symbols \"%s\" \"%s\" are undefined: absolute 0 assumed.",
2209 as_warn("Symbol \"%s\" undefined: absolute 0 assumed.",
2210 name1 ? name1 : name2);
2212 retval = expP->X_seg = SEG_ABSOLUTE;
2213 expP->X_add_number = 0;
2214 expP->X_add_symbol = expP->X_subtract_symbol = NULL;
2216 #ifndef MANY_SEGMENTS
2217 know(retval == SEG_ABSOLUTE || retval == SEG_DATA || retval == SEG_TEXT || retval == SEG_BSS || retval == SEG_DIFFERENCE);
2221 } /* get_known_segmented_expression() */
2225 /* static */ long /* JF was static, but can't be if the MD pseudos are to use it */
2226 get_absolute_expression ()
2231 if ((s = expression(& exp)) != SEG_ABSOLUTE)
2233 if (s != SEG_ABSENT)
2235 as_bad("Bad Absolute Expression, absolute 0 assumed.");
2237 exp . X_add_number = 0;
2239 return (exp . X_add_number);
2242 char /* return terminator */
2243 get_absolute_expression_and_terminator(val_pointer)
2244 long * val_pointer; /* return value of expression */
2246 * val_pointer = get_absolute_expression ();
2247 return (* input_line_pointer ++);
2251 * demand_copy_C_string()
2253 * Like demand_copy_string, but return NULL if the string contains any '\0's.
2254 * Give a warning if that happens.
2257 demand_copy_C_string (len_pointer)
2262 if ((s = demand_copy_string(len_pointer)) != 0)
2266 for (len = * len_pointer;
2275 as_bad("This string may not contain \'\\0\'");
2283 * demand_copy_string()
2285 * Demand string, but return a safe (=private) copy of the string.
2286 * Return NULL if we can't read a string here.
2288 static char *demand_copy_string(lenP)
2291 register unsigned int c;
2297 if (*input_line_pointer == '\"') {
2298 input_line_pointer++; /* Skip opening quote. */
2300 while (is_a_char(c = next_char_of_string())) {
2301 obstack_1grow(¬es, c);
2304 /* JF this next line is so demand_copy_C_string will return a null
2305 termanated string. */
2306 obstack_1grow(¬es,'\0');
2307 retval=obstack_finish(¬es);
2309 as_warn("Missing string");
2311 ignore_rest_of_line();
2315 } /* demand_copy_string() */
2318 * is_it_end_of_statement()
2320 * In: Input_line_pointer->next character.
2322 * Do: Skip input_line_pointer over all whitespace.
2324 * Out: 1 if input_line_pointer->end-of-line.
2326 int is_it_end_of_statement() {
2328 return (is_end_of_line [* input_line_pointer]);
2329 } /* is_it_end_of_statement() */
2331 void equals(sym_name)
2334 register symbolS *symbolP; /* symbol we are working with */
2336 input_line_pointer++;
2337 if (*input_line_pointer=='=')
2338 input_line_pointer++;
2340 while(*input_line_pointer==' ' || *input_line_pointer=='\t')
2341 input_line_pointer++;
2343 if (sym_name[0]=='.' && sym_name[1]=='\0') {
2344 /* Turn '. = mumble' into a .org mumble */
2345 register segT segment;
2349 segment = get_known_segmented_expression(& exp);
2350 if (! need_pass_2) {
2351 if (segment != now_seg && segment != SEG_ABSOLUTE)
2352 as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",
2353 segment_name(segment),
2354 segment_name(now_seg));
2355 p = frag_var(rs_org, 1, 1, (relax_substateT)0, exp.X_add_symbol,
2356 exp.X_add_number, (char *)0);
2358 } /* if (ok to make frag) */
2360 symbolP=symbol_find_or_make(sym_name);
2361 pseudo_set(symbolP);
2365 /* .include -- include a file at this point. */
2377 filename = demand_copy_string(&i);
2378 demand_empty_rest_of_line();
2379 path = xmalloc(i + include_dir_maxlen + 5 /* slop */);
2380 for (i = 0; i < include_dir_count; i++) {
2381 strcpy(path, include_dirs[i]);
2383 strcat(path, filename);
2384 if (0 != (try = fopen(path, "r")))
2393 /* malloc Storage leak when file is found on path. FIXME-SOMEDAY. */
2394 newbuf = input_scrub_include_file (path, input_line_pointer);
2395 buffer_limit = input_scrub_next_buffer (&input_line_pointer);
2398 void add_include_dir(path)
2403 if (include_dir_count == 0)
2405 include_dirs = (char **)xmalloc (2 * sizeof (*include_dirs));
2406 include_dirs[0] = "."; /* Current dir */
2407 include_dir_count = 2;
2411 include_dir_count++;
2412 include_dirs = (char **) realloc(include_dirs,
2413 include_dir_count*sizeof (*include_dirs));
2416 include_dirs[include_dir_count-1] = path; /* New one */
2419 if (i > include_dir_maxlen)
2420 include_dir_maxlen = i;
2421 } /* add_include_dir() */
2426 extern char is_end_of_line[];
2428 while (!is_end_of_line[*input_line_pointer]) {
2429 ++input_line_pointer;
2431 ++input_line_pointer;