1 /* read.c - read a source file -
3 Copyright (C) 1986, 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
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.)
27 #define MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT (16)
28 /* This is the largest known floating point */
29 /* format (for now). It will grow when we */
30 /* do 4361 style flonums. */
33 /* Routines that read assembler source text to build spagetti in memory. */
34 /* Another group of these functions is in the as-expr.c module */
40 char *input_line_pointer
; /*->next char of source file to parse. */
43 #if BITS_PER_CHAR != 8
44 The following table is indexed by
[ (char) ] and will
break if
45 a
char does
not have exactly
256 states (hopefully
0:255!) !
48 const char /* used by is_... macros. our ctype[] */
50 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */
51 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ[\]^_ */
52 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */
53 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0123456789:;<=>? */
54 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */
55 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 3, /* PQRSTUVWXYZ[\]^_ */
56 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* `abcdefghijklmno */
57 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, /* pqrstuvwxyz{|}~. */
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,
64 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
70 * Out: 1 if this character ends a line.
73 char is_end_of_line
[256] = {
75 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
,99, _
, _
, 99, _
, _
,/* @abcdefghijklmno */
77 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
,99, _
, _
, _
, _
, _
, /* @abcdefghijklmno */
79 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, /* */
80 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, /* */
81 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
,99, _
, _
, _
, _
, /* 0123456789:;<=>? */
82 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, /* */
83 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, /* */
84 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, /* */
85 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, /* */
86 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, /* */
87 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, /* */
88 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, /* */
89 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, /* */
90 _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
, _
/* */
94 /* Functions private to this file. */
96 char line_comment_chars
[1];
97 char line_separator_chars
[1];
99 static char *buffer
; /* 1st char of each buffer of lines is here. */
100 static char *buffer_limit
; /*->1 + last char in buffer. */
102 static char *bignum_low
; /* Lowest char of bignum. */
103 static char *bignum_limit
; /* 1st illegal address of bignum. */
104 static char *bignum_high
; /* Highest char of bignum. */
105 /* May point to (bignum_start-1). */
106 /* Never >= bignum_limit. */
107 static char *old_buffer
= 0; /* JF a hack */
108 static char *old_input
;
109 static char *old_limit
;
111 /* Variables for handling include file directory list. */
113 char **include_dirs
; /* List of pointers to directories to
114 search for .include's */
115 int include_dir_count
; /* How many are in the list */
116 int include_dir_maxlen
= 1; /* Length of longest in list */
118 #ifndef WORKING_DOT_WORD
119 struct broken_word
*broken_words
;
120 int new_broken_words
= 0;
125 static char *demand_copy_string(int *lenP
);
126 int is_it_end_of_statement(void);
127 unsigned int next_char_of_string(void);
128 static segT
get_known_segmented_expression(expressionS
*expP
);
129 static void grow_bignum(void);
130 static void pobegin(void);
131 void stringer(int append_zero
);
135 static char *demand_copy_string();
136 int is_it_end_of_statement();
137 unsigned int next_char_of_string();
138 static segT
get_known_segmented_expression();
139 static void grow_bignum();
140 static void pobegin();
143 #endif /* not __STDC__ */
154 obj_read_begin_hook();
156 obstack_begin(¬es
, 5000);
157 obstack_begin(&cond_obstack
, 960);
159 #define BIGNUM_BEGIN_SIZE (16)
160 bignum_low
= xmalloc((long)BIGNUM_BEGIN_SIZE
);
161 bignum_limit
= bignum_low
+ BIGNUM_BEGIN_SIZE
;
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. */
169 /* set up pseudo-op tables */
171 struct hash_control
*
172 po_hash
= NULL
; /* use before set up: NULL->address error */
174 static const pseudo_typeS
177 { "abort", s_abort
, 0 },
178 { "align", s_align_ptwo
, 0 },
179 { "ascii", stringer
, 0 },
180 { "asciz", stringer
, 1 },
183 { "comm", s_comm
, 0 },
184 { "data", s_data
, 0 },
186 { "double", float_cons
, 'd' },
189 { "eject", s_ignore
, 0 }, /* Formfeed listing */
191 { "eject", listing_eject
, 0 }, /* Formfeed listing */
192 #endif /* NO_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' },
205 { "global", s_globl
, 0 },
206 { "globl", s_globl
, 0 },
207 { "hword", cons
, 2 },
209 { "ifdef", s_ifdef
, 0 },
210 { "ifeqs", s_ifeqs
, 0 },
211 { "ifndef", s_ifdef
, 1 },
212 { "ifnes", s_ifeqs
, 1 },
213 { "ifnotdef", s_ifdef
, 1 },
214 { "include", s_include
, 0 },
216 { "lcomm", s_lcomm
, 0 },
218 { "lflags", s_ignore
, 0 }, /* Listing flags */
219 { "list", s_ignore
, 1 }, /* Turn listing on */
221 { "lflags", listing_flags
, 0 }, /* Listing flags */
222 { "list", listing_list
, 1 }, /* Turn listing on */
223 #endif /* NO_LISTING */
225 { "lsym", s_lsym
, 0 },
227 { "nolist", s_ignore
, 0 }, /* Turn listing off */
229 { "nolist", listing_list
, 0 }, /* Turn listing off */
230 #endif /* NO_LISTING */
231 { "octa", big_cons
, 16 },
234 { "psize", s_ignore
, 0 }, /* set paper size */
236 { "psize", listing_psize
, 0 }, /* set paper size */
237 #endif /* NO_LISTING */
239 { "quad", big_cons
, 8 },
241 { "sbttl", s_ignore
, 1 }, /* Subtitle of listing */
243 { "sbttl", listing_title
, 1 }, /* Subtitle of listing */
244 #endif /* NO_LISTING */
248 { "short", cons
, 2 },
249 { "single", float_cons
, 'f' },
251 { "space", s_space
, 0 },
253 { "text", s_text
, 0 },
255 { "title", s_ignore
, 0 }, /* Listing title */
257 { "title", listing_title
, 0 }, /* Listing title */
258 #endif /* NO_LISTING */
263 { NULL
} /* end sentinel */
266 static void pobegin() {
267 char *errtxt
; /* error text */
268 const pseudo_typeS
* pop
;
270 po_hash
= hash_new();
272 /* Do the target-specific pseudo ops. */
273 for (pop
= md_pseudo_table
; pop
->poc_name
; pop
++) {
274 errtxt
= hash_insert(po_hash
, pop
->poc_name
, (char *)pop
);
275 if (errtxt
&& *errtxt
) {
276 as_fatal("error constructing md pseudo-op table");
280 /* Now object specific. Skip any that were in the target table. */
281 for (pop
=obj_pseudo_table
; pop
->poc_name
; pop
++) {
282 errtxt
= hash_insert (po_hash
, pop
->poc_name
, (char *)pop
);
283 if (errtxt
&& *errtxt
) {
284 if (!strcmp (errtxt
, "exists")) {
285 #ifdef DIE_ON_OVERRIDES
286 as_fatal("pseudo op \".%s\" overridden.\n", pop
->poc_name
);
287 #endif /* DIE_ON_OVERRIDES */
288 continue; /* OK if target table overrides. */
290 as_fatal("error constructing obj pseudo-op table");
291 } /* if overridden */
295 /* Now portable ones. Skip any that we've seen already. */
296 for (pop
=potable
; pop
->poc_name
; pop
++) {
297 errtxt
= hash_insert (po_hash
, pop
->poc_name
, (char *)pop
);
298 if (errtxt
&& *errtxt
) {
299 if (!strcmp (errtxt
, "exists")) {
300 #ifdef DIE_ON_OVERRIDES
301 as_fatal("pseudo op \".%s\" overridden.\n", pop
->poc_name
);
302 #endif /* DIE_ON_OVERRIDES */
303 continue; /* OK if target table overrides. */
305 as_fatal("error constructing obj pseudo-op table");
306 } /* if overridden */
313 #define HANDLE_CONDITIONAL_ASSEMBLY() \
314 if (ignore_input ()) \
316 while (! is_end_of_line[*input_line_pointer++]) \
317 if (input_line_pointer == buffer_limit) \
323 /* read_a_source_file()
325 * We read the file, putting things into a web that
326 * represents what we have been reading.
328 void read_a_source_file(name
)
332 register char * s
; /* string of symbol, '\0' appended */
334 /* register struct frag * fragP; JF unused */ /* a frag we just made */
337 buffer
= input_scrub_new_file(name
);
342 while ((buffer_limit
= input_scrub_next_buffer(&input_line_pointer
)) != 0) { /* We have another line to parse. */
343 know(buffer_limit
[-1] == '\n'); /* Must have a sentinel. */
344 contin
: /* JF this goto is my fault I admit it. Someone brave please re-write
345 the whole input section here? Pleeze??? */
346 while (input_line_pointer
< buffer_limit
) { /* We have more of this buffer to parse. */
349 * We now have input_line_pointer->1st char of next line.
350 * If input_line_pointer [-1] == '\n' then we just
351 * scanned another line: so bump line counters.
353 if (input_line_pointer
[-1] == '\n') {
354 bump_line_counters();
355 } /* just passed a newline */
360 * We are at the begining of a line, or similar place.
361 * We expect a well-formed assembler statement.
362 * A "symbol-name:" is a statement.
364 * Depending on what compiler is used, the order of these tests
365 * may vary to catch most common case 1st.
366 * Each test is independent of all other tests at the (top) level.
367 * PLEASE make a compiler that doesn't use this assembler.
368 * It is crufty to waste a compiler's time encoding things for this
369 * assembler, which then wastes more time decoding it.
370 * (And communicating via (linear) files is silly!
371 * If you must pass stuff, please pass a tree!)
373 if ((c
= *input_line_pointer
++) == '\t' || c
== ' ' || c
=='\f' || c
== 0) {
374 c
= *input_line_pointer
++;
376 know(c
!= ' '); /* No further leading whitespace. */
379 * C is the 1st significant character.
380 * Input_line_pointer points after that character.
382 if (is_name_beginner(c
)) { /* want user-defined label or pseudo/opcode */
383 HANDLE_CONDITIONAL_ASSEMBLY();
385 s
= --input_line_pointer
;
386 c
= get_symbol_end(); /* name's delimiter */
388 * C is character after symbol.
389 * That character's place in the input line is now '\0'.
390 * S points to the beginning of the symbol.
391 * [In case of pseudo-op, s->'.'.]
392 * Input_line_pointer->'\0' where c was.
395 colon(s
); /* user-defined label */
396 * input_line_pointer
++ = ':'; /* Put ':' back for error messages' sake. */
397 /* Input_line_pointer->after ':'. */
401 } else if (c
== '=' || input_line_pointer
[1] == '=') { /* JF deal with FOO=BAR */
403 demand_empty_rest_of_line();
404 } else { /* expect pseudo-op or machine instruction */
409 * WARNING: c has next char, which may be end-of-line.
410 * We lookup the pseudo-op table with s+1 because we
411 * already know that the pseudo-op begins with a '.'.
414 pop
= (pseudo_typeS
*) hash_find(po_hash
, s
+1);
416 /* Print the error msg now, while we still can */
418 as_bad("Unknown pseudo-op: `%s'",s
);
419 *input_line_pointer
= c
;
424 /* Put it back for error messages etc. */
425 *input_line_pointer
= c
;
426 /* The following skip of whitespace is compulsory. */
427 /* A well shaped space is sometimes all that separates keyword from operands. */
428 if (c
== ' ' || c
== '\t') {
429 input_line_pointer
++;
430 } /* Skip seperator after keyword. */
432 * Input_line is restored.
433 * Input_line_pointer->1st non-blank char
434 * after pseudo-operation.
437 ignore_rest_of_line();
440 (*pop
->poc_handler
)(pop
->poc_val
);
441 } /* if we have one */
442 } else { /* machine instruction */
443 /* WARNING: c has char, which may be end-of-line. */
444 /* Also: input_line_pointer->`\0` where c was. */
445 * input_line_pointer
= c
;
446 while (!is_end_of_line
[*input_line_pointer
]) {
447 input_line_pointer
++;
449 c
= *input_line_pointer
;
450 *input_line_pointer
= '\0';
451 md_assemble(s
); /* Assemble 1 instruction. */
452 *input_line_pointer
++ = c
;
453 /* We resume loop AFTER the end-of-line from this instruction */
458 } /* if (is_name_beginner(c) */
461 if (is_end_of_line
[c
]) {
463 } /* empty statement */
466 if (isdigit(c
)) { /* local label ("4:") */
467 HANDLE_CONDITIONAL_ASSEMBLY ();
470 #ifdef LOCAL_LABELS_DOLLAR
471 if (*input_line_pointer
=='$')
472 input_line_pointer
++;
474 if (* input_line_pointer
++ == ':')
480 as_bad("Spurious digit %d.", temp
);
481 input_line_pointer
-- ;
482 ignore_rest_of_line();
485 } /* local label ("4:") */
487 if (c
&& strchr(line_comment_chars
,c
)) { /* Its a comment. Better say APP or NO_APP */
493 extern char *scrub_string
,*scrub_last_string
;
495 bump_line_counters();
496 s
=input_line_pointer
;
497 if (strncmp(s
,"APP\n",4))
498 continue; /* We ignore it */
501 ends
=strstr(s
,"#NO_APP\n");
507 /* The end of the #APP wasn't in this buffer. We
508 keep reading in buffers until we find the #NO_APP
509 that goes with this #APP There is one. The specs
511 tmp_len
=buffer_limit
-s
;
512 tmp_buf
=xmalloc(tmp_len
);
513 memcpy(tmp_buf
, s
, tmp_len
);
515 new_tmp
= input_scrub_next_buffer(&buffer
);
519 buffer_limit
= new_tmp
;
520 input_line_pointer
= buffer
;
521 ends
= strstr(buffer
,"#NO_APP\n");
525 num
=buffer_limit
-buffer
;
527 tmp_buf
= xrealloc(tmp_buf
, tmp_len
+ num
);
528 memcpy(tmp_buf
+ tmp_len
, buffer
, num
);
532 input_line_pointer
= ends
? ends
+8 : NULL
;
538 input_line_pointer
=ends
+8;
540 new_buf
=xmalloc(100);
545 scrub_last_string
= ends
;
549 ch
= do_scrub_next_char(scrub_from_string
, scrub_to_string
);
552 if (new_tmp
==new_buf
+new_length
) {
553 new_buf
=xrealloc(new_buf
,new_length
+100);
554 new_tmp
=new_buf
+new_length
;
562 old_input
=input_line_pointer
;
563 old_limit
=buffer_limit
;
565 input_line_pointer
=new_buf
;
566 buffer_limit
=new_tmp
;
570 HANDLE_CONDITIONAL_ASSEMBLY();
572 /* as_warn("Junk character %d.",c); Now done by ignore_rest */
573 input_line_pointer
--; /* Report unknown char as ignored. */
574 ignore_rest_of_line();
575 } /* while (input_line_pointer<buffer_limit) */
577 bump_line_counters();
578 if (old_input
!= 0) {
580 input_line_pointer
=old_input
;
581 buffer_limit
=old_limit
;
586 } /* while (more buffers to scan) */
587 input_scrub_close(); /* Close the input file */
589 } /* read_a_source_file() */
592 as_fatal(".abort detected. Abandoning ship.");
595 /* For machines where ".align 4" means align to a 4 byte boundary. */
596 void s_align_bytes(arg
)
599 register unsigned int temp
;
600 register long temp_fill
;
602 unsigned long max_alignment
= 1 << 15;
604 if (is_end_of_line
[*input_line_pointer
])
605 temp
= arg
; /* Default value from pseudo-op table */
607 temp
= get_absolute_expression ();
609 if (temp
> max_alignment
) {
610 as_bad("Alignment too large: %d. assumed.", temp
= max_alignment
);
614 * For the sparc, `.align (1<<n)' actually means `.align n'
615 * so we have to convert it.
618 for (i
= 0; (temp
& 1) == 0; temp
>>= 1, ++i
)
622 as_bad("Alignment not a power of 2");
625 if (*input_line_pointer
== ',') {
626 input_line_pointer
++;
627 temp_fill
= get_absolute_expression ();
631 /* Only make a frag if we HAVE to. . . */
632 if (temp
&& ! need_pass_2
)
633 frag_align(temp
, (int)temp_fill
);
635 demand_empty_rest_of_line();
636 } /* s_align_bytes() */
638 /* For machines where ".align 4" means align to 2**4 boundary. */
639 void s_align_ptwo() {
641 register long temp_fill
;
642 long max_alignment
= 15;
644 temp
= get_absolute_expression ();
645 if (temp
> max_alignment
)
646 as_bad("Alignment too large: %d. assumed.", temp
= max_alignment
);
648 as_bad("Alignment negative. 0 assumed.");
651 if (*input_line_pointer
== ',') {
652 input_line_pointer
++;
653 temp_fill
= get_absolute_expression ();
656 /* Only make a frag if we HAVE to. . . */
657 if (temp
&& ! need_pass_2
)
658 frag_align (temp
, (int)temp_fill
);
660 record_alignment(now_seg
, temp
);
662 demand_empty_rest_of_line();
663 } /* s_align_ptwo() */
670 register symbolS
* symbolP
;
672 name
= input_line_pointer
;
673 c
= get_symbol_end();
674 /* just after name is now '\0' */
675 p
= input_line_pointer
;
678 if (*input_line_pointer
!= ',') {
679 as_bad("Expected comma after symbol-name: rest of line ignored.");
680 ignore_rest_of_line();
683 input_line_pointer
++; /* skip ',' */
684 if ((temp
= get_absolute_expression()) < 0) {
685 as_warn(".COMMon length (%d.) <0! Ignored.", temp
);
686 ignore_rest_of_line();
690 symbolP
= symbol_find_or_make(name
);
692 if (S_IS_DEFINED(symbolP
)) {
693 as_bad("Ignoring attempt to re-define symbol");
694 ignore_rest_of_line();
697 if (S_GET_VALUE(symbolP
)) {
698 if (S_GET_VALUE(symbolP
) != temp
)
699 as_bad("Length of .comm \"%s\" is already %d. Not changed to %d.",
701 S_GET_VALUE(symbolP
),
704 S_SET_VALUE(symbolP
, temp
);
705 S_SET_EXTERNAL(symbolP
);
709 symbolP
->sy_other
= const_flag
;
711 know(symbolP
->sy_frag
== &zero_address_frag
);
712 demand_empty_rest_of_line();
720 temp
= get_absolute_expression ();
722 subseg_new (SEG_E1
, (subsegT
)temp
);
724 subseg_new (SEG_DATA
, (subsegT
)temp
);
730 demand_empty_rest_of_line();
737 /* Some assemblers tolerate immediately following '"' */
738 if ((s
= demand_copy_string(&length
)) != 0) {
739 new_logical_line(s
, -1);
740 demand_empty_rest_of_line();
743 c_dot_file_symbol(s
);
744 #endif /* OBJ_COFF */
750 register long temp_fill
;
753 if (get_absolute_expression_and_terminator(& temp_repeat
) != ',') {
754 input_line_pointer
--; /* Backup over what was not a ','. */
755 as_bad("Expect comma after rep-size in .fill:");
756 ignore_rest_of_line();
759 if (get_absolute_expression_and_terminator(& temp_size
) != ',') {
760 input_line_pointer
--; /* Backup over what was not a ','. */
761 as_bad("Expected comma after size in .fill");
762 ignore_rest_of_line();
766 * This is to be compatible with BSD 4.2 AS, not for any rational reason.
768 #define BSD_FILL_SIZE_CROCK_8 (8)
769 if (temp_size
> BSD_FILL_SIZE_CROCK_8
) {
770 as_bad(".fill size clamped to %d.", BSD_FILL_SIZE_CROCK_8
);
771 temp_size
= BSD_FILL_SIZE_CROCK_8
;
772 } if (temp_size
< 0) {
773 as_warn("Size negative: .fill ignored.");
775 } else if (temp_repeat
<= 0) {
776 as_warn("Repeat < 0, .fill ignored");
779 temp_fill
= get_absolute_expression ();
780 if (temp_size
&& !need_pass_2
) {
781 p
= frag_var(rs_fill
, (int)temp_size
, (int)temp_size
, (relax_substateT
)0, (symbolS
*)0, temp_repeat
, (char *)0);
782 memset(p
, '\0', (int) temp_size
);
784 * The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX flavoured AS.
785 * The following bizzare behaviour is to be compatible with above.
786 * I guess they tried to take up to 8 bytes from a 4-byte expression
787 * and they forgot to sign extend. Un*x Sux.
789 #define BSD_FILL_SIZE_CROCK_4 (4)
790 md_number_to_chars (p
, temp_fill
, temp_size
> BSD_FILL_SIZE_CROCK_4
? BSD_FILL_SIZE_CROCK_4
: (int)temp_size
);
792 * Note: .fill (),0 emits no frag (since we are asked to .fill 0 bytes)
793 * but emits no error message because it seems a legal thing to do.
794 * It is a degenerate case of .fill but could be emitted by a compiler.
797 demand_empty_rest_of_line();
803 register symbolS
* symbolP
;
806 name
= input_line_pointer
;
807 c
= get_symbol_end();
808 symbolP
= symbol_find_or_make(name
);
809 * input_line_pointer
= c
;
811 S_SET_EXTERNAL(symbolP
);
813 input_line_pointer
++;
815 if (*input_line_pointer
=='\n')
819 demand_empty_rest_of_line();
822 void s_lcomm(needs_align
)
823 int needs_align
; /* 1 if this was a ".bss" directive, which may require
824 * a 3rd argument (alignment).
825 * 0 if it was an ".lcomm" (2 args only)
832 register symbolS
* symbolP
;
833 const int max_alignment
= 15;
836 name
= input_line_pointer
;
837 c
= get_symbol_end();
838 p
= input_line_pointer
;
841 if (*input_line_pointer
!= ',') {
842 as_bad("Expected comma after name");
843 ignore_rest_of_line();
847 ++input_line_pointer
;
849 if (*input_line_pointer
== '\n') {
850 as_bad("Missing size expression");
854 if ((temp
= get_absolute_expression ()) < 0) {
855 as_warn("BSS length (%d.) <0! Ignored.", temp
);
856 ignore_rest_of_line();
863 if (*input_line_pointer
!= ',') {
864 as_bad("Expected comma after size");
865 ignore_rest_of_line();
868 input_line_pointer
++;
870 if (*input_line_pointer
== '\n') {
871 as_bad("Missing alignment");
874 align
= get_absolute_expression ();
875 if (align
> max_alignment
){
876 align
= max_alignment
;
877 as_warn("Alignment too large: %d. assumed.", align
);
878 } else if (align
< 0) {
880 as_warn("Alignment negative. 0 assumed.");
883 #define SEG_BSS SEG_E2
884 record_alignment(SEG_E2
, align
);
886 record_alignment(SEG_BSS
, align
);
888 } /* if needs align */
891 symbolP
= symbol_find_or_make(name
);
895 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
896 S_GET_OTHER(symbolP
) == 0 &&
897 S_GET_DESC(symbolP
) == 0 &&
898 #endif /* OBJ_AOUT or OBJ_BOUT */
899 (((S_GET_SEGMENT(symbolP
) == SEG_BSS
) && (S_GET_VALUE(symbolP
) == local_bss_counter
))
900 || (!S_IS_DEFINED(symbolP
) && S_GET_VALUE(symbolP
) == 0))) {
903 align
= ~ ((~0) << align
); /* Convert to a mask */
905 (local_bss_counter
+ align
) & (~align
);
908 S_SET_VALUE(symbolP
,local_bss_counter
);
909 S_SET_SEGMENT(symbolP
, SEG_BSS
);
911 /* The symbol may already have been created with a preceding
912 * ".globl" directive -- be careful not to step on storage
913 * class in that case. Otherwise, set it to static.
915 if (S_GET_STORAGE_CLASS(symbolP
) != C_EXT
){
916 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
918 #endif /* OBJ_COFF */
919 symbolP
->sy_frag
= & bss_address_frag
;
920 local_bss_counter
+= temp
;
922 as_bad("Ignoring attempt to re-define symbol from %d. to %d.",
923 S_GET_VALUE(symbolP
), local_bss_counter
);
925 demand_empty_rest_of_line();
946 register segT segment
;
948 register symbolS
*symbolP
;
950 /* we permit ANY defined expression: BSD4.2 demands constants */
951 name
= input_line_pointer
;
952 c
= get_symbol_end();
953 p
= input_line_pointer
;
956 if (* input_line_pointer
!= ',') {
958 as_bad("Expected comma after name \"%s\"", name
);
960 ignore_rest_of_line();
963 input_line_pointer
++;
964 segment
= expression(& exp
);
965 if (segment
!= SEG_ABSOLUTE
967 && ! ( segment
>= SEG_E0
&& segment
<= SEG_UNKNOWN
)
969 && segment
!= SEG_DATA
970 && segment
!= SEG_TEXT
971 && segment
!= SEG_BSS
973 && segment
!= SEG_REGISTER
) {
974 as_bad("Bad expression: %s", segment_name(segment
));
975 ignore_rest_of_line();
979 symbolP
= symbol_find_or_make(name
);
981 /* FIXME-SOON I pulled a (&& symbolP->sy_other == 0
982 && symbolP->sy_desc == 0) out of this test
983 because coff doesn't have those fields, and I
984 can't see when they'd ever be tripped. I don't
985 think I understand why they were here so I may
986 have introduced a bug. As recently as 1.37 didn't
987 have this test anyway. xoxorich. */
989 if (S_GET_SEGMENT(symbolP
) == SEG_UNKNOWN
990 && S_GET_VALUE(symbolP
) == 0) {
991 /* The name might be an undefined .global symbol; be
992 sure to keep the "external" bit. */
993 S_SET_SEGMENT(symbolP
, segment
);
994 S_SET_VALUE(symbolP
, (valueT
)(exp
.X_add_number
));
996 as_bad("Symbol %s already defined", name
);
999 demand_empty_rest_of_line();
1003 register segT segment
;
1005 register long temp_fill
;
1008 * Don't believe the documentation of BSD 4.2 AS.
1009 * There is no such thing as a sub-segment-relative origin.
1010 * Any absolute origin is given a warning, then assumed to be segment-relative.
1011 * Any segmented origin expression ("foo+42") had better be in the right
1012 * segment or the .org is ignored.
1014 * BSD 4.2 AS warns if you try to .org backwards. We cannot because we
1015 * never know sub-segment sizes when we are reading code.
1016 * BSD will crash trying to emit -ve numbers of filler bytes in certain
1017 * .orgs. We don't crash, but see as-write for that code.
1020 * Don't make frag if need_pass_2==1.
1022 segment
= get_known_segmented_expression(&exp
);
1023 if (*input_line_pointer
== ',') {
1024 input_line_pointer
++;
1025 temp_fill
= get_absolute_expression ();
1028 if (! need_pass_2
) {
1029 if (segment
!= now_seg
&& segment
!= SEG_ABSOLUTE
)
1030 as_bad("Invalid segment \"%s\". Segment \"%s\" assumed.",
1031 segment_name(segment
), segment_name(now_seg
));
1032 p
= frag_var (rs_org
, 1, 1, (relax_substateT
)0, exp
. X_add_symbol
,
1033 exp
. X_add_number
, (char *)0);
1035 } /* if (ok to make frag) */
1036 demand_empty_rest_of_line();
1040 register char *name
;
1041 register char delim
;
1042 register char *end_name
;
1043 register symbolS
*symbolP
;
1046 * Especial apologies for the random logic:
1047 * this just grew, and could be parsed much more simply!
1050 name
= input_line_pointer
;
1051 delim
= get_symbol_end();
1052 end_name
= input_line_pointer
;
1056 if (*input_line_pointer
!= ',') {
1058 as_bad("Expected comma after name \"%s\"", name
);
1060 ignore_rest_of_line();
1064 input_line_pointer
++;
1067 if (name
[0]=='.' && name
[1]=='\0') {
1068 /* Turn '. = mumble' into a .org mumble */
1069 register segT segment
;
1073 segment
= get_known_segmented_expression(& exp
);
1076 if (segment
!= now_seg
&& segment
!= SEG_ABSOLUTE
)
1077 as_bad("Invalid segment \"%s\". Segment \"%s\" assumed.",
1078 segment_name(segment
),
1079 segment_name (now_seg
));
1080 ptr
= frag_var(rs_org
, 1, 1, (relax_substateT
)0, exp
.X_add_symbol
,
1081 exp
.X_add_number
, (char *)0);
1083 } /* if (ok to make frag) */
1089 if ((symbolP
= symbol_find(name
)) == NULL
1090 && (symbolP
= md_undefined_symbol(name
)) == NULL
) {
1091 symbolP
= symbol_new(name
,
1094 &zero_address_frag
);
1096 /* "set" symbols are local unless otherwise specified. */
1097 SF_SET_LOCAL(symbolP
);
1098 #endif /* OBJ_COFF */
1100 } /* make a new symbol */
1102 symbol_table_insert(symbolP
);
1105 pseudo_set(symbolP
);
1106 demand_empty_rest_of_line();
1111 register long temp_fill
;
1114 /* Just like .fill, but temp_size = 1 */
1115 if (get_absolute_expression_and_terminator(& temp_repeat
) == ',') {
1116 temp_fill
= get_absolute_expression ();
1118 input_line_pointer
--; /* Backup over what was not a ','. */
1121 if (temp_repeat
<= 0) {
1122 as_warn("Repeat < 0, .space ignored");
1123 ignore_rest_of_line();
1126 if (! need_pass_2
) {
1127 p
= frag_var (rs_fill
, 1, 1, (relax_substateT
)0, (symbolS
*)0,
1128 temp_repeat
, (char *)0);
1131 demand_empty_rest_of_line();
1139 temp
= get_absolute_expression ();
1140 #ifdef MANY_SEGMENTS
1141 subseg_new (SEG_E0
, (subsegT
)temp
);
1143 subseg_new (SEG_TEXT
, (subsegT
)temp
);
1145 demand_empty_rest_of_line();
1149 /*(JF was static, but can't be if machine dependent pseudo-ops are to use it */
1151 void demand_empty_rest_of_line() {
1153 if (is_end_of_line
[*input_line_pointer
]) {
1154 input_line_pointer
++;
1156 ignore_rest_of_line();
1158 /* Return having already swallowed end-of-line. */
1159 } /* Return pointing just after end-of-line. */
1162 ignore_rest_of_line() /* For suspect lines: gives warning. */
1164 if (! is_end_of_line
[* input_line_pointer
])
1166 if (isprint(*input_line_pointer
))
1167 as_bad("Rest of line ignored. First ignored character is `%c'.",
1168 *input_line_pointer
);
1170 as_bad("Rest of line ignored. First ignored character valued 0x%x.",
1171 *input_line_pointer
);
1172 while (input_line_pointer
< buffer_limit
1173 && ! is_end_of_line
[* input_line_pointer
])
1175 input_line_pointer
++;
1178 input_line_pointer
++; /* Return pointing just after end-of-line. */
1179 know(is_end_of_line
[input_line_pointer
[-1]]);
1185 * In: Pointer to a symbol.
1186 * Input_line_pointer->expression.
1188 * Out: Input_line_pointer->just after any whitespace after expression.
1189 * Tried to set symbol to value of expression.
1190 * Will change symbols type, value, and frag;
1191 * May set need_pass_2 == 1.
1194 pseudo_set (symbolP
)
1198 register segT segment
;
1199 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1201 #endif /* OBJ_AOUT or OBJ_BOUT */
1203 know(symbolP
); /* NULL pointer is logic error. */
1204 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1205 ext
=S_IS_EXTERNAL(symbolP
);
1206 #endif /* OBJ_AOUT or OBJ_BOUT */
1208 if ((segment
= expression(& exp
)) == SEG_ABSENT
)
1210 as_bad("Missing expression: absolute 0 assumed");
1211 exp
. X_seg
= SEG_ABSOLUTE
;
1212 exp
. X_add_number
= 0;
1218 as_bad("%s number invalid. Absolute 0 assumed.",
1219 exp
. X_add_number
> 0 ? "Bignum" : "Floating-Point");
1220 S_SET_SEGMENT(symbolP
, SEG_ABSOLUTE
);
1221 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1222 ext
? S_SET_EXTERNAL(symbolP
) :
1223 S_CLEAR_EXTERNAL(symbolP
);
1224 #endif /* OBJ_AOUT or OBJ_BOUT */
1225 S_SET_VALUE(symbolP
, 0);
1226 symbolP
->sy_frag
= & zero_address_frag
;
1230 as_warn("No expression: Using absolute 0");
1231 S_SET_SEGMENT(symbolP
, SEG_ABSOLUTE
);
1232 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1233 ext
? S_SET_EXTERNAL(symbolP
) :
1234 S_CLEAR_EXTERNAL(symbolP
);
1235 #endif /* OBJ_AOUT or OBJ_BOUT */
1236 S_SET_VALUE(symbolP
, 0);
1237 symbolP
->sy_frag
= & zero_address_frag
;
1240 case SEG_DIFFERENCE
:
1241 if (exp
.X_add_symbol
&& exp
.X_subtract_symbol
1242 && (S_GET_SEGMENT(exp
.X_add_symbol
) ==
1243 S_GET_SEGMENT(exp
.X_subtract_symbol
))) {
1244 if (exp
.X_add_symbol
->sy_frag
!= exp
.X_subtract_symbol
->sy_frag
) {
1245 as_bad("Unknown expression: symbols %s and %s are in different frags.",
1246 S_GET_NAME(exp
.X_add_symbol
), S_GET_NAME(exp
.X_subtract_symbol
));
1249 exp
.X_add_number
+=S_GET_VALUE(exp
.X_add_symbol
) -
1250 S_GET_VALUE(exp
.X_subtract_symbol
);
1252 as_bad("Complex expression. Absolute segment assumed.");
1254 S_SET_SEGMENT(symbolP
, SEG_ABSOLUTE
);
1255 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1256 ext
? S_SET_EXTERNAL(symbolP
) :
1257 S_CLEAR_EXTERNAL(symbolP
);
1258 #endif /* OBJ_AOUT or OBJ_BOUT */
1259 S_SET_VALUE(symbolP
, exp
.X_add_number
);
1260 symbolP
->sy_frag
= & zero_address_frag
;
1264 #ifdef MANY_SEGMENTS
1265 S_SET_SEGMENT(symbolP
, segment
);
1268 case SEG_DATA
: S_SET_SEGMENT(symbolP
, SEG_DATA
); break;
1269 case SEG_TEXT
: S_SET_SEGMENT(symbolP
, SEG_TEXT
); break;
1270 case SEG_BSS
: S_SET_SEGMENT(symbolP
, SEG_BSS
); break;
1271 default: as_fatal("failed sanity check.");
1272 } /* switch on segment */
1274 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1276 S_SET_EXTERNAL(symbolP
);
1278 S_CLEAR_EXTERNAL(symbolP
);
1280 #endif /* OBJ_AOUT or OBJ_BOUT */
1282 S_SET_VALUE(symbolP
, exp
.X_add_number
+ S_GET_VALUE(exp
.X_add_symbol
));
1283 symbolP
->sy_frag
= exp
. X_add_symbol
->sy_frag
;
1286 case SEG_PASS1
: /* Not an error. Just try another pass. */
1287 symbolP
->sy_forward
=exp
.X_add_symbol
;
1288 as_bad("Unknown expression");
1289 know(need_pass_2
== 1);
1293 symbolP
->sy_forward
=exp
.X_add_symbol
;
1294 /* as_warn("unknown symbol"); */
1295 /* need_pass_2 = 1; */
1306 * CONStruct more frag of .bytes, or .words etc.
1307 * Should need_pass_2 be 1 then emit no frag(s).
1308 * This understands EXPRESSIONS, as opposed to big_cons().
1312 * This has a split personality. We use expression() to read the
1313 * value. We can detect if the value won't fit in a byte or word.
1314 * But we can't detect if expression() discarded significant digits
1315 * in the case of a long. Not worth the crocks required to fix it.
1318 /* worker to do .byte etc statements */
1319 /* clobbers input_line_pointer, checks */
1322 register unsigned int nbytes
; /* 1=.byte, 2=.word, 4=.long */
1325 register long mask
; /* High-order bits we will left-truncate, */
1326 /* but includes sign bit also. */
1327 register long get
; /* what we get */
1328 register long use
; /* get after truncation. */
1329 register long unmask
; /* what bits we will store */
1331 register segT segment
;
1335 * Input_line_pointer->1st char after pseudo-op-code and could legally
1336 * be a end-of-line. (Or, less legally an eof - which we cope with.)
1338 /* JF << of >= number of bits in the object is undefined. In particular
1339 SPARC (Sun 4) has problems */
1341 if (nbytes
>=sizeof(long)) {
1344 mask
= ~0 << (BITS_PER_CHAR
* nbytes
); /* Don't store these bits. */
1345 } /* bigger than a long */
1347 unmask
= ~mask
; /* Do store these bits. */
1350 "Do this mod if you want every overflow check to assume SIGNED 2's complement data.";
1351 mask
= ~ (unmask
>> 1); /* Includes sign bit now. */
1355 * The following awkward logic is to parse ZERO or more expressions,
1356 * comma seperated. Recall an expression includes its leading &
1357 * trailing blanks. We fake a leading ',' if there is (supposed to
1358 * be) a 1st expression, and keep demanding 1 expression for each ','.
1360 if (is_it_end_of_statement()) {
1361 c
= 0; /* Skip loop. */
1362 input_line_pointer
++; /* Matches end-of-loop 'correction'. */
1365 } /* if the end else fake it */
1369 #ifdef WANT_BITFIELDS
1370 unsigned int bits_available
= BITS_PER_CHAR
* nbytes
;
1371 /* used for error messages and rescanning */
1372 char *hold
= input_line_pointer
;
1373 #endif /* WANT_BITFIELDS */
1375 /* At least scan over the expression. */
1376 segment
= expression(&exp
);
1378 #ifdef WANT_BITFIELDS
1379 /* Some other assemblers, (eg, asm960), allow
1380 bitfields after ".byte" as w:x,y:z, where w and
1381 y are bitwidths and x and y are values. They
1382 then pack them all together. We do a little
1383 better in that we allow them in words, longs,
1384 etc. and we'll pack them in target byte order
1387 The rules are: pack least significat bit first,
1388 if a field doesn't entirely fit, put it in the
1389 next unit. Overflowing the bitfield is
1390 explicitly *not* even a warning. The bitwidth
1391 should be considered a "mask".
1393 FIXME-SOMEDAY: If this is considered generally
1394 useful, this logic should probably be reworked.
1397 if (*input_line_pointer
== ':') { /* bitfields */
1401 unsigned long width
;
1403 if (*input_line_pointer
!= ':') {
1404 input_line_pointer
= hold
;
1406 } /* next piece is not a bitfield */
1408 /* In the general case, we can't allow
1409 full expressions with symbol
1410 differences and such. The relocation
1411 entries for symbols not defined in this
1412 assembly would require arbitrary field
1413 widths, positions, and masks which most
1414 of our current object formats don't
1417 In the specific case where a symbol
1418 *is* defined in this assembly, we
1419 *could* build fixups and track it, but
1420 this could lead to confusion for the
1421 backends. I'm lazy. I'll take any
1422 SEG_ABSOLUTE. I think that means that
1423 you can use a previous .set or
1424 .equ type symbol. xoxorich. */
1426 if (segment
== SEG_ABSENT
) {
1427 as_warn("Using a bit field width of zero.");
1428 exp
.X_add_number
= 0;
1429 segment
= SEG_ABSOLUTE
;
1430 } /* implied zero width bitfield */
1432 if (segment
!= SEG_ABSOLUTE
) {
1433 *input_line_pointer
= '\0';
1434 as_bad("Field width \"%s\" too complex for a bitfield.\n", hold
);
1435 *input_line_pointer
= ':';
1436 demand_empty_rest_of_line();
1440 if ((width
= exp
.X_add_number
) > (BITS_PER_CHAR
* nbytes
)) {
1441 as_warn("Field width %d too big to fit in %d bytes: truncated to %d bits.",
1442 width
, nbytes
, (BITS_PER_CHAR
* nbytes
));
1443 width
= BITS_PER_CHAR
* nbytes
;
1446 if (width
> bits_available
) {
1447 /* FIXME-SOMEDAY: backing up and
1448 reparsing is wasteful */
1449 input_line_pointer
= hold
;
1450 exp
.X_add_number
= value
;
1454 hold
= ++input_line_pointer
; /* skip ':' */
1456 if ((segment
= expression(&exp
)) != SEG_ABSOLUTE
) {
1457 char cache
= *input_line_pointer
;
1459 *input_line_pointer
= '\0';
1460 as_bad("Field value \"%s\" too complex for a bitfield.\n", hold
);
1461 *input_line_pointer
= cache
;
1462 demand_empty_rest_of_line();
1466 value
|= (~(-1 << width
) & exp
.X_add_number
)
1467 << ((BITS_PER_CHAR
* nbytes
) - bits_available
);
1469 if ((bits_available
-= width
) == 0
1470 || is_it_end_of_statement()
1471 || *input_line_pointer
!= ',') {
1473 } /* all the bitfields we're gonna get */
1475 hold
= ++input_line_pointer
;
1476 segment
= expression(&exp
);
1477 } /* forever loop */
1479 exp
.X_add_number
= value
;
1480 segment
= SEG_ABSOLUTE
;
1481 } /* if looks like a bitfield */
1482 #endif /* WANT_BITFIELDS */
1484 if (!need_pass_2
) { /* Still worthwhile making frags. */
1486 /* Don't call this if we are going to junk this pass anyway! */
1487 know(segment
!= SEG_PASS1
);
1489 if (segment
== SEG_DIFFERENCE
&& exp
.X_add_symbol
== NULL
) {
1490 as_bad("Subtracting symbol \"%s\"(segment\"%s\") is too hard. Absolute segment assumed.",
1491 S_GET_NAME(exp
.X_subtract_symbol
),
1492 segment_name(S_GET_SEGMENT(exp
.X_subtract_symbol
)));
1493 segment
= SEG_ABSOLUTE
;
1494 /* Leave exp . X_add_number alone. */
1496 p
= frag_more(nbytes
);
1499 as_bad("%s number invalid. Absolute 0 assumed.",
1500 exp
. X_add_number
> 0 ? "Bignum" : "Floating-Point");
1501 md_number_to_chars (p
, (long)0, nbytes
);
1505 as_warn("0 assumed for missing expression");
1506 exp
. X_add_number
= 0;
1507 know(exp
. X_add_symbol
== NULL
);
1508 /* fall into SEG_ABSOLUTE */
1510 get
= exp
. X_add_number
;
1512 if ((get
& mask
) && (get
& mask
) != mask
)
1513 { /* Leading bits contain both 0s & 1s. */
1514 as_warn("Value 0x%x truncated to 0x%x.", get
, use
);
1516 md_number_to_chars (p
, use
, nbytes
); /* put bytes in right order. */
1519 case SEG_DIFFERENCE
:
1520 #ifndef WORKING_DOT_WORD
1522 struct broken_word
*x
;
1524 x
=(struct broken_word
*)xmalloc(sizeof(struct broken_word
));
1525 x
->next_broken_word
=broken_words
;
1528 x
->word_goes_here
=p
;
1530 x
->add
=exp
.X_add_symbol
;
1531 x
->sub
=exp
.X_subtract_symbol
;
1532 x
->addnum
=exp
.X_add_number
;
1537 /* Else Fall through into. . . */
1542 fix_new_ns32k(frag_now
, p
- frag_now
->fr_literal
, nbytes
,
1543 exp
.X_add_symbol
, exp
.X_subtract_symbol
,
1544 exp
.X_add_number
, 0, 0, 2, 0, 0);
1546 fix_new(frag_now
, p
- frag_now
->fr_literal
, nbytes
,
1547 exp
.X_add_symbol
, exp
.X_subtract_symbol
,
1548 exp
.X_add_number
, 0, RELOC_32
);
1549 #endif /* TC_NS32K */
1551 } /* switch(segment) */
1552 } /* if (!need_pass_2) */
1553 c
= *input_line_pointer
++;
1554 } /* while(c==',') */
1555 input_line_pointer
--; /* Put terminator back into stream. */
1556 demand_empty_rest_of_line();
1562 * CONStruct more frag(s) of .quads, or .octa etc.
1563 * Makes 0 or more new frags.
1564 * If need_pass_2 == 1, generate no frag.
1565 * This understands only bignums, not expressions. Cons() understands
1568 * Constants recognised are '0...'(octal) '0x...'(hex) '...'(decimal).
1570 * This creates objects with struct obstack_control objs, destroying
1571 * any context objs held about a partially completed object. Beware!
1574 * I think it sucks to have 2 different types of integers, with 2
1575 * routines to read them, store them etc.
1576 * It would be nicer to permit bignums in expressions and only
1577 * complain if the result overflowed. However, due to "efficiency"...
1579 /* worker to do .quad etc statements */
1580 /* clobbers input_line_pointer, checks */
1582 /* 8=.quad 16=.octa ... */
1584 void big_cons(nbytes
)
1585 register int nbytes
;
1587 register char c
; /* input_line_pointer->c. */
1589 register long length
; /* Number of chars in an object. */
1590 register int digit
; /* Value of 1 digit. */
1591 register int carry
; /* For multi-precision arithmetic. */
1592 register int work
; /* For multi-precision arithmetic. */
1593 register char * p
; /* For multi-precision arithmetic. */
1595 extern char hex_value
[]; /* In hex_value.c. */
1598 * The following awkward logic is to parse ZERO or more strings,
1599 * comma seperated. Recall an expression includes its leading &
1600 * trailing blanks. We fake a leading ',' if there is (supposed to
1601 * be) a 1st expression, and keep demanding 1 expression for each ','.
1603 if (is_it_end_of_statement())
1605 c
= 0; /* Skip loop. */
1609 c
= ','; /* Do loop. */
1610 -- input_line_pointer
;
1614 ++ input_line_pointer
;
1616 c
= * input_line_pointer
;
1617 /* C contains 1st non-blank character of what we hope is a number. */
1620 c
= * ++ input_line_pointer
;
1621 if (c
== 'x' || c
=='X')
1623 c
= * ++ input_line_pointer
;
1636 * This feature (?) is here to stop people worrying about
1637 * mysterious zero constants: which is what they get when
1638 * they completely omit digits.
1640 if (hex_value
[c
] >= radix
) {
1641 as_bad("Missing digits. 0 assumed.");
1643 bignum_high
= bignum_low
- 1; /* Start constant with 0 chars. */
1644 for(; (digit
= hex_value
[c
]) < radix
; c
= * ++ input_line_pointer
)
1646 /* Multiply existing number by radix, then add digit. */
1648 for (p
=bignum_low
; p
<= bignum_high
; p
++)
1650 work
= (*p
& MASK_CHAR
) * radix
+ carry
;
1651 *p
= work
& MASK_CHAR
;
1652 carry
= work
>> BITS_PER_CHAR
;
1657 * bignum_high
= carry
& MASK_CHAR
;
1658 know((carry
& ~ MASK_CHAR
) == 0);
1661 length
= bignum_high
- bignum_low
+ 1;
1662 if (length
> nbytes
)
1664 as_warn("Most significant bits truncated in integer constant.");
1668 register long leading_zeroes
;
1670 for(leading_zeroes
= nbytes
- length
;
1680 p
= frag_more (nbytes
);
1681 memcpy(p
, bignum_low
, (int) nbytes
);
1683 /* C contains character after number. */
1685 c
= *input_line_pointer
;
1686 /* C contains 1st non-blank character after number. */
1688 demand_empty_rest_of_line();
1691 /* Extend bignum by 1 char. */
1692 static void grow_bignum() {
1693 register long length
;
1696 if (bignum_high
>= bignum_limit
)
1698 length
= bignum_limit
- bignum_low
;
1699 bignum_low
= xrealloc(bignum_low
, length
+ length
);
1700 bignum_high
= bignum_low
+ length
;
1701 bignum_limit
= bignum_low
+ length
+ length
;
1703 } /* grow_bignum(); */
1708 * CONStruct some more frag chars of .floats .ffloats etc.
1709 * Makes 0 or more new frags.
1710 * If need_pass_2 == 1, no frags are emitted.
1711 * This understands only floating literals, not expressions. Sorry.
1713 * A floating constant is defined by atof_generic(), except it is preceded
1714 * by 0d 0f 0g or 0h. After observing the STRANGE way my BSD AS does its
1715 * reading, I decided to be incompatible. This always tries to give you
1716 * rounded bits to the precision of the pseudo-op. Former AS did premature
1717 * truncatation, restored noisy bits instead of trailing 0s AND gave you
1718 * a choice of 2 flavours of noise according to which of 2 floating-point
1719 * scanners you directed AS to use.
1721 * In: input_line_pointer->whitespace before, or '0' of flonum.
1725 void /* JF was static, but can't be if VAX.C is goning to use it */
1726 float_cons(float_type
) /* Worker to do .float etc statements. */
1727 /* Clobbers input_line-pointer, checks end-of-line. */
1728 register int float_type
; /* 'f':.ffloat ... 'F':.float ... */
1732 int length
; /* Number of chars in an object. */
1733 register char * err
; /* Error from scanning floating literal. */
1734 char temp
[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT
];
1737 * The following awkward logic is to parse ZERO or more strings,
1738 * comma seperated. Recall an expression includes its leading &
1739 * trailing blanks. We fake a leading ',' if there is (supposed to
1740 * be) a 1st expression, and keep demanding 1 expression for each ','.
1742 if (is_it_end_of_statement())
1744 c
= 0; /* Skip loop. */
1745 ++ input_line_pointer
; /*->past termintor. */
1749 c
= ','; /* Do loop. */
1752 /* input_line_pointer->1st char of a flonum (we hope!). */
1754 /* Skip any 0{letter} that may be present. Don't even check if the
1755 * letter is legal. Someone may invent a "z" format and this routine
1756 * has no use for such information. Lusers beware: you get
1757 * diagnostics if your input is ill-conditioned.
1760 if (input_line_pointer
[0]=='0' && isalpha(input_line_pointer
[1]))
1761 input_line_pointer
+=2;
1763 err
= md_atof (float_type
, temp
, &length
);
1764 know(length
<= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT
);
1767 as_bad("Bad floating literal: %s", err
);
1768 ignore_rest_of_line();
1769 /* Input_line_pointer->just after end-of-line. */
1770 c
= 0; /* Break out of loop. */
1772 if (! need_pass_2
) {
1773 p
= frag_more (length
);
1774 memcpy(p
, temp
, length
);
1777 c
= *input_line_pointer
++;
1778 /* C contains 1st non-white character after number. */
1779 /* input_line_pointer->just after terminator (c). */
1782 --input_line_pointer
; /*->terminator (is not ','). */
1783 demand_empty_rest_of_line();
1784 } /* float_cons() */
1789 * We read 0 or more ',' seperated, double-quoted strings.
1791 * Caller should have checked need_pass_2 is FALSE because we don't check it.
1795 void stringer(append_zero
) /* Worker to do .ascii etc statements. */
1796 /* Checks end-of-line. */
1797 register int append_zero
; /* 0: don't append '\0', else 1 */
1799 /* register char * p; JF unused */
1800 /* register int length; JF unused */ /* Length of string we read, excluding */
1801 /* trailing '\0' implied by closing quote. */
1802 /* register char * where; JF unused */
1803 /* register fragS * fragP; JF unused */
1804 register unsigned int c
;
1807 * The following awkward logic is to parse ZERO or more strings,
1808 * comma seperated. Recall a string expression includes spaces
1809 * before the opening '\"' and spaces after the closing '\"'.
1810 * We fake a leading ',' if there is (supposed to be)
1811 * a 1st, expression. We keep demanding expressions for each
1814 if (is_it_end_of_statement())
1816 c
= 0; /* Skip loop. */
1817 ++ input_line_pointer
; /* Compensate for end of loop. */
1821 c
= ','; /* Do loop. */
1823 while (c
== ',' || c
== '<' || c
== '"' ) {
1825 switch (*input_line_pointer
) {
1827 ++input_line_pointer
; /*->1st char of string. */
1828 while (is_a_char(c
= next_char_of_string())) {
1829 FRAG_APPEND_1_CHAR(c
);
1832 FRAG_APPEND_1_CHAR(0);
1834 know(input_line_pointer
[-1] == '\"');
1837 input_line_pointer
++;
1838 c
=get_single_number();
1839 FRAG_APPEND_1_CHAR(c
);
1840 if(*input_line_pointer
!= '>') {
1841 as_bad("Expected <nn>");
1843 input_line_pointer
++;
1846 input_line_pointer
++;
1850 c
= *input_line_pointer
;
1853 demand_empty_rest_of_line();
1856 /* FIXME-SOMEDAY: I had trouble here on characters with the
1857 high bits set. We'll probably also have trouble with
1858 multibyte chars, wide chars, etc. Also be careful about
1859 returning values bigger than 1 byte. xoxorich. */
1861 unsigned int next_char_of_string() {
1862 register unsigned int c
;
1864 c
= *input_line_pointer
++ & CHAR_MASK
;
1871 switch (c
= *input_line_pointer
++) {
1900 break; /* As itself. */
1914 for (number
= 0; isdigit(c
); c
= *input_line_pointer
++) {
1915 number
= number
* 8 + c
- '0';
1919 --input_line_pointer
;
1923 /* To be compatible with BSD 4.2 as: give the luser a linefeed!! */
1924 as_warn("Unterminated string: Newline inserted.");
1930 #ifdef ONLY_STANDARD_ESCAPES
1931 as_bad("Bad escaped character in string, '?' assumed");
1933 #endif /* ONLY_STANDARD_ESCAPES */
1936 } /* switch on escaped char */
1941 } /* switch on char */
1943 } /* next_char_of_string() */
1946 get_segmented_expression (expP
)
1947 register expressionS
* expP
;
1949 register segT retval
;
1951 if ((retval
= expression(expP
)) == SEG_PASS1
|| retval
== SEG_ABSENT
|| retval
== SEG_BIG
)
1953 as_bad("Expected address expression: absolute 0 assumed");
1954 retval
= expP
->X_seg
= SEG_ABSOLUTE
;
1955 expP
->X_add_number
= 0;
1956 expP
->X_add_symbol
= expP
->X_subtract_symbol
= 0;
1958 return (retval
); /* SEG_ ABSOLUTE,UNKNOWN,DATA,TEXT,BSS */
1961 static segT
get_known_segmented_expression(expP
)
1962 register expressionS
*expP
;
1964 register segT retval
;
1965 register char * name1
;
1966 register char * name2
;
1968 if ((retval
= get_segmented_expression (expP
)) == SEG_UNKNOWN
)
1970 name1
= expP
->X_add_symbol
? S_GET_NAME(expP
->X_add_symbol
) : "";
1971 name2
= expP
->X_subtract_symbol
?
1972 S_GET_NAME(expP
->X_subtract_symbol
) :
1976 as_warn("Symbols \"%s\" \"%s\" are undefined: absolute 0 assumed.",
1981 as_warn("Symbol \"%s\" undefined: absolute 0 assumed.",
1982 name1
? name1
: name2
);
1984 retval
= expP
->X_seg
= SEG_ABSOLUTE
;
1985 expP
->X_add_number
= 0;
1986 expP
->X_add_symbol
= expP
->X_subtract_symbol
= NULL
;
1988 #ifndef MANY_SEGMENTS
1989 know(retval
== SEG_ABSOLUTE
|| retval
== SEG_DATA
|| retval
== SEG_TEXT
|| retval
== SEG_BSS
|| retval
== SEG_DIFFERENCE
);
1993 } /* get_known_segmented_expression() */
1997 /* static */ long /* JF was static, but can't be if the MD pseudos are to use it */
1998 get_absolute_expression ()
2003 if ((s
= expression(& exp
)) != SEG_ABSOLUTE
)
2005 if (s
!= SEG_ABSENT
)
2007 as_bad("Bad Absolute Expression, absolute 0 assumed.");
2009 exp
. X_add_number
= 0;
2011 return (exp
. X_add_number
);
2014 char /* return terminator */
2015 get_absolute_expression_and_terminator(val_pointer
)
2016 long * val_pointer
; /* return value of expression */
2018 * val_pointer
= get_absolute_expression ();
2019 return (* input_line_pointer
++);
2023 * demand_copy_C_string()
2025 * Like demand_copy_string, but return NULL if the string contains any '\0's.
2026 * Give a warning if that happens.
2029 demand_copy_C_string (len_pointer
)
2034 if ((s
= demand_copy_string(len_pointer
)) != 0)
2038 for (len
= * len_pointer
;
2047 as_bad("This string may not contain \'\\0\'");
2055 * demand_copy_string()
2057 * Demand string, but return a safe (=private) copy of the string.
2058 * Return NULL if we can't read a string here.
2060 static char *demand_copy_string(lenP
)
2063 register unsigned int c
;
2069 if (*input_line_pointer
== '\"') {
2070 input_line_pointer
++; /* Skip opening quote. */
2072 while (is_a_char(c
= next_char_of_string())) {
2073 obstack_1grow(¬es
, c
);
2076 /* JF this next line is so demand_copy_C_string will return a null
2077 termanated string. */
2078 obstack_1grow(¬es
,'\0');
2079 retval
=obstack_finish(¬es
);
2081 as_warn("Missing string");
2083 ignore_rest_of_line();
2087 } /* demand_copy_string() */
2090 * is_it_end_of_statement()
2092 * In: Input_line_pointer->next character.
2094 * Do: Skip input_line_pointer over all whitespace.
2096 * Out: 1 if input_line_pointer->end-of-line.
2098 int is_it_end_of_statement() {
2100 return (is_end_of_line
[* input_line_pointer
]);
2101 } /* is_it_end_of_statement() */
2103 void equals(sym_name
)
2106 register symbolS
*symbolP
; /* symbol we are working with */
2108 input_line_pointer
++;
2109 if (*input_line_pointer
=='=')
2110 input_line_pointer
++;
2112 while(*input_line_pointer
==' ' || *input_line_pointer
=='\t')
2113 input_line_pointer
++;
2115 if (sym_name
[0]=='.' && sym_name
[1]=='\0') {
2116 /* Turn '. = mumble' into a .org mumble */
2117 register segT segment
;
2121 segment
= get_known_segmented_expression(& exp
);
2122 if (! need_pass_2
) {
2123 if (segment
!= now_seg
&& segment
!= SEG_ABSOLUTE
)
2124 as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",
2125 segment_name(segment
),
2126 segment_name(now_seg
));
2127 p
= frag_var(rs_org
, 1, 1, (relax_substateT
)0, exp
.X_add_symbol
,
2128 exp
.X_add_number
, (char *)0);
2130 } /* if (ok to make frag) */
2132 symbolP
=symbol_find_or_make(sym_name
);
2133 pseudo_set(symbolP
);
2137 /* .include -- include a file at this point. */
2149 filename
= demand_copy_string(&i
);
2150 demand_empty_rest_of_line();
2151 path
= xmalloc(i
+ include_dir_maxlen
+ 5 /* slop */);
2152 for (i
= 0; i
< include_dir_count
; i
++) {
2153 strcpy(path
, include_dirs
[i
]);
2155 strcat(path
, filename
);
2156 if (0 != (try = fopen(path
, "r")))
2165 /* malloc Storage leak when file is found on path. FIXME-SOMEDAY. */
2166 newbuf
= input_scrub_include_file (path
, input_line_pointer
);
2167 buffer_limit
= input_scrub_next_buffer (&input_line_pointer
);
2170 void add_include_dir(path
)
2175 if (include_dir_count
== 0)
2177 include_dirs
= (char **)xmalloc (2 * sizeof (*include_dirs
));
2178 include_dirs
[0] = "."; /* Current dir */
2179 include_dir_count
= 2;
2183 include_dir_count
++;
2184 include_dirs
= (char **) realloc(include_dirs
,
2185 include_dir_count
*sizeof (*include_dirs
));
2188 include_dirs
[include_dir_count
-1] = path
; /* New one */
2191 if (i
> include_dir_maxlen
)
2192 include_dir_maxlen
= i
;
2193 } /* add_include_dir() */
2198 extern char is_end_of_line
[];
2200 while (!is_end_of_line
[*input_line_pointer
]) {
2201 ++input_line_pointer
;
2203 ++input_line_pointer
;