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 */
788 register long temp_fill
;
791 if (get_absolute_expression_and_terminator(& temp_repeat
) != ',') {
792 input_line_pointer
--; /* Backup over what was not a ','. */
793 as_bad("Expect comma after rep-size in .fill:");
794 ignore_rest_of_line();
797 if (get_absolute_expression_and_terminator(& temp_size
) != ',') {
798 input_line_pointer
--; /* Backup over what was not a ','. */
799 as_bad("Expected comma after size in .fill");
800 ignore_rest_of_line();
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_bad(".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");
817 temp_fill
= get_absolute_expression ();
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();
1261 register long temp_fill
;
1264 /* Just like .fill, but temp_size = 1 */
1265 if (get_absolute_expression_and_terminator(& temp_repeat
) == ',') {
1266 temp_fill
= get_absolute_expression ();
1268 input_line_pointer
--; /* Backup over what was not a ','. */
1271 if (temp_repeat
<= 0) {
1272 as_warn("Repeat < 0, .space ignored");
1273 ignore_rest_of_line();
1276 if (! need_pass_2
) {
1277 p
= frag_var (rs_fill
, 1, 1, (relax_substateT
)0, (symbolS
*)0,
1278 temp_repeat
, (char *)0);
1281 demand_empty_rest_of_line();
1289 temp
= get_absolute_expression ();
1290 #ifdef MANY_SEGMENTS
1291 subseg_new (SEG_E0
, (subsegT
)temp
);
1293 subseg_new (SEG_TEXT
, (subsegT
)temp
);
1295 demand_empty_rest_of_line();
1299 /*(JF was static, but can't be if machine dependent pseudo-ops are to use it */
1301 void demand_empty_rest_of_line() {
1303 if (is_end_of_line
[*input_line_pointer
]) {
1304 input_line_pointer
++;
1306 ignore_rest_of_line();
1308 /* Return having already swallowed end-of-line. */
1309 } /* Return pointing just after end-of-line. */
1312 ignore_rest_of_line() /* For suspect lines: gives warning. */
1314 if (! is_end_of_line
[* input_line_pointer
])
1316 if (isprint(*input_line_pointer
))
1317 as_bad("Rest of line ignored. First ignored character is `%c'.",
1318 *input_line_pointer
);
1320 as_bad("Rest of line ignored. First ignored character valued 0x%x.",
1321 *input_line_pointer
);
1322 while (input_line_pointer
< buffer_limit
1323 && ! is_end_of_line
[* input_line_pointer
])
1325 input_line_pointer
++;
1328 input_line_pointer
++; /* Return pointing just after end-of-line. */
1329 know(is_end_of_line
[input_line_pointer
[-1]]);
1335 * In: Pointer to a symbol.
1336 * Input_line_pointer->expression.
1338 * Out: Input_line_pointer->just after any whitespace after expression.
1339 * Tried to set symbol to value of expression.
1340 * Will change symbols type, value, and frag;
1341 * May set need_pass_2 == 1.
1344 pseudo_set (symbolP
)
1348 register segT segment
;
1349 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1351 #endif /* OBJ_AOUT or OBJ_BOUT */
1353 know(symbolP
); /* NULL pointer is logic error. */
1354 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1355 ext
=S_IS_EXTERNAL(symbolP
);
1356 #endif /* OBJ_AOUT or OBJ_BOUT */
1358 if ((segment
= expression(& exp
)) == SEG_ABSENT
)
1360 as_bad("Missing expression: absolute 0 assumed");
1361 exp
. X_seg
= SEG_ABSOLUTE
;
1362 exp
. X_add_number
= 0;
1368 S_SET_SEGMENT(symbolP
, SEG_REGISTER
);
1369 S_SET_VALUE(symbolP
, exp
.X_add_number
);
1370 symbolP
->sy_frag
= & zero_address_frag
;
1374 as_bad("%s number invalid. Absolute 0 assumed.",
1375 exp
. X_add_number
> 0 ? "Bignum" : "Floating-Point");
1376 S_SET_SEGMENT(symbolP
, SEG_ABSOLUTE
);
1377 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1378 ext
? S_SET_EXTERNAL(symbolP
) :
1379 S_CLEAR_EXTERNAL(symbolP
);
1380 #endif /* OBJ_AOUT or OBJ_BOUT */
1381 S_SET_VALUE(symbolP
, 0);
1382 symbolP
->sy_frag
= & zero_address_frag
;
1386 as_warn("No expression: Using absolute 0");
1387 S_SET_SEGMENT(symbolP
, SEG_ABSOLUTE
);
1388 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1389 ext
? S_SET_EXTERNAL(symbolP
) :
1390 S_CLEAR_EXTERNAL(symbolP
);
1391 #endif /* OBJ_AOUT or OBJ_BOUT */
1392 S_SET_VALUE(symbolP
, 0);
1393 symbolP
->sy_frag
= & zero_address_frag
;
1396 case SEG_DIFFERENCE
:
1397 if (exp
.X_add_symbol
&& exp
.X_subtract_symbol
1398 && (S_GET_SEGMENT(exp
.X_add_symbol
) ==
1399 S_GET_SEGMENT(exp
.X_subtract_symbol
))) {
1400 if (exp
.X_add_symbol
->sy_frag
!= exp
.X_subtract_symbol
->sy_frag
) {
1401 as_bad("Unknown expression: symbols %s and %s are in different frags.",
1402 S_GET_NAME(exp
.X_add_symbol
), S_GET_NAME(exp
.X_subtract_symbol
));
1405 exp
.X_add_number
+=S_GET_VALUE(exp
.X_add_symbol
) -
1406 S_GET_VALUE(exp
.X_subtract_symbol
);
1408 as_bad("Complex expression. Absolute segment assumed.");
1410 S_SET_SEGMENT(symbolP
, SEG_ABSOLUTE
);
1411 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1412 ext
? S_SET_EXTERNAL(symbolP
) :
1413 S_CLEAR_EXTERNAL(symbolP
);
1414 #endif /* OBJ_AOUT or OBJ_BOUT */
1415 S_SET_VALUE(symbolP
, exp
.X_add_number
);
1416 symbolP
->sy_frag
= & zero_address_frag
;
1420 #ifdef MANY_SEGMENTS
1421 S_SET_SEGMENT(symbolP
, segment
);
1424 case SEG_DATA
: S_SET_SEGMENT(symbolP
, SEG_DATA
); break;
1425 case SEG_TEXT
: S_SET_SEGMENT(symbolP
, SEG_TEXT
); break;
1426 case SEG_BSS
: S_SET_SEGMENT(symbolP
, SEG_BSS
); break;
1428 default: as_fatal("failed sanity check.");
1429 } /* switch on segment */
1431 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1433 S_SET_EXTERNAL(symbolP
);
1435 S_CLEAR_EXTERNAL(symbolP
);
1437 #endif /* OBJ_AOUT or OBJ_BOUT */
1439 S_SET_VALUE(symbolP
, exp
.X_add_number
+ S_GET_VALUE(exp
.X_add_symbol
));
1440 symbolP
->sy_frag
= exp
. X_add_symbol
->sy_frag
;
1443 case SEG_PASS1
: /* Not an error. Just try another pass. */
1444 symbolP
->sy_forward
=exp
.X_add_symbol
;
1445 as_bad("Unknown expression");
1446 know(need_pass_2
== 1);
1450 symbolP
->sy_forward
=exp
.X_add_symbol
;
1451 /* as_warn("unknown symbol"); */
1452 /* need_pass_2 = 1; */
1463 * CONStruct more frag of .bytes, or .words etc.
1464 * Should need_pass_2 be 1 then emit no frag(s).
1465 * This understands EXPRESSIONS, as opposed to big_cons().
1469 * This has a split personality. We use expression() to read the
1470 * value. We can detect if the value won't fit in a byte or word.
1471 * But we can't detect if expression() discarded significant digits
1472 * in the case of a long. Not worth the crocks required to fix it.
1475 /* worker to do .byte etc statements */
1476 /* clobbers input_line_pointer, checks */
1479 register unsigned int nbytes
; /* 1=.byte, 2=.word, 4=.long */
1482 register long mask
; /* High-order bits we will left-truncate, */
1483 /* but includes sign bit also. */
1484 register long get
; /* what we get */
1485 register long use
; /* get after truncation. */
1486 register long unmask
; /* what bits we will store */
1488 register segT segment
;
1492 * Input_line_pointer->1st char after pseudo-op-code and could legally
1493 * be a end-of-line. (Or, less legally an eof - which we cope with.)
1495 /* JF << of >= number of bits in the object is undefined. In particular
1496 SPARC (Sun 4) has problems */
1498 if (nbytes
>=sizeof(long)) {
1501 mask
= ~0 << (BITS_PER_CHAR
* nbytes
); /* Don't store these bits. */
1502 } /* bigger than a long */
1504 unmask
= ~mask
; /* Do store these bits. */
1507 "Do this mod if you want every overflow check to assume SIGNED 2's complement data.";
1508 mask
= ~ (unmask
>> 1); /* Includes sign bit now. */
1512 * The following awkward logic is to parse ZERO or more expressions,
1513 * comma seperated. Recall an expression includes its leading &
1514 * trailing blanks. We fake a leading ',' if there is (supposed to
1515 * be) a 1st expression, and keep demanding 1 expression for each ','.
1517 if (is_it_end_of_statement()) {
1518 c
= 0; /* Skip loop. */
1519 input_line_pointer
++; /* Matches end-of-loop 'correction'. */
1522 } /* if the end else fake it */
1526 #ifdef WANT_BITFIELDS
1527 unsigned int bits_available
= BITS_PER_CHAR
* nbytes
;
1528 /* used for error messages and rescanning */
1529 char *hold
= input_line_pointer
;
1530 #endif /* WANT_BITFIELDS */
1532 if (*input_line_pointer
== '\'')
1534 /* An MRI style string, cut into as many bytes as will fit
1535 into a nbyte chunk, left justify if necessary, and sepatate
1536 with commas so we can try again later */
1538 unsigned int result
= 0;
1539 input_line_pointer
++;
1540 for (scan
= 0; scan
< nbytes
; scan
++)
1542 if (*input_line_pointer
== '\'')
1544 if (input_line_pointer
[1] == '\'')
1546 input_line_pointer
++;
1551 result
= (result
<< 8) | (*input_line_pointer
++);
1555 while (scan
< nbytes
)
1560 /* Create correct expression */
1561 exp
.X_add_symbol
= 0;
1562 exp
.X_add_number
= result
;
1563 exp
.X_seg
= segment
= SEG_ABSOLUTE
;
1564 /* Fake it so that we can read the next char too */
1565 if (input_line_pointer
[0] != '\'' ||
1566 (input_line_pointer
[0] == '\'' && input_line_pointer
[1] == '\''))
1568 input_line_pointer
-=2;
1569 input_line_pointer
[0] = ',';
1570 input_line_pointer
[1] = '\'';
1573 input_line_pointer
++;
1578 /* At least scan over the expression. */
1579 segment
= expression(&exp
);
1581 #ifdef WANT_BITFIELDS
1582 /* Some other assemblers, (eg, asm960), allow
1583 bitfields after ".byte" as w:x,y:z, where w and
1584 y are bitwidths and x and y are values. They
1585 then pack them all together. We do a little
1586 better in that we allow them in words, longs,
1587 etc. and we'll pack them in target byte order
1590 The rules are: pack least significat bit first,
1591 if a field doesn't entirely fit, put it in the
1592 next unit. Overflowing the bitfield is
1593 explicitly *not* even a warning. The bitwidth
1594 should be considered a "mask".
1596 FIXME-SOMEDAY: If this is considered generally
1597 useful, this logic should probably be reworked.
1600 if (*input_line_pointer
== ':') { /* bitfields */
1604 unsigned long width
;
1606 if (*input_line_pointer
!= ':') {
1607 input_line_pointer
= hold
;
1609 } /* next piece is not a bitfield */
1611 /* In the general case, we can't allow
1612 full expressions with symbol
1613 differences and such. The relocation
1614 entries for symbols not defined in this
1615 assembly would require arbitrary field
1616 widths, positions, and masks which most
1617 of our current object formats don't
1620 In the specific case where a symbol
1621 *is* defined in this assembly, we
1622 *could* build fixups and track it, but
1623 this could lead to confusion for the
1624 backends. I'm lazy. I'll take any
1625 SEG_ABSOLUTE. I think that means that
1626 you can use a previous .set or
1627 .equ type symbol. xoxorich. */
1629 if (segment
== SEG_ABSENT
) {
1630 as_warn("Using a bit field width of zero.");
1631 exp
.X_add_number
= 0;
1632 segment
= SEG_ABSOLUTE
;
1633 } /* implied zero width bitfield */
1635 if (segment
!= SEG_ABSOLUTE
) {
1636 *input_line_pointer
= '\0';
1637 as_bad("Field width \"%s\" too complex for a bitfield.\n", hold
);
1638 *input_line_pointer
= ':';
1639 demand_empty_rest_of_line();
1643 if ((width
= exp
.X_add_number
) > (BITS_PER_CHAR
* nbytes
)) {
1644 as_warn("Field width %d too big to fit in %d bytes: truncated to %d bits.",
1645 width
, nbytes
, (BITS_PER_CHAR
* nbytes
));
1646 width
= BITS_PER_CHAR
* nbytes
;
1649 if (width
> bits_available
) {
1650 /* FIXME-SOMEDAY: backing up and
1651 reparsing is wasteful */
1652 input_line_pointer
= hold
;
1653 exp
.X_add_number
= value
;
1657 hold
= ++input_line_pointer
; /* skip ':' */
1659 if ((segment
= expression(&exp
)) != SEG_ABSOLUTE
) {
1660 char cache
= *input_line_pointer
;
1662 *input_line_pointer
= '\0';
1663 as_bad("Field value \"%s\" too complex for a bitfield.\n", hold
);
1664 *input_line_pointer
= cache
;
1665 demand_empty_rest_of_line();
1669 value
|= (~(-1 << width
) & exp
.X_add_number
)
1670 << ((BITS_PER_CHAR
* nbytes
) - bits_available
);
1672 if ((bits_available
-= width
) == 0
1673 || is_it_end_of_statement()
1674 || *input_line_pointer
!= ',') {
1676 } /* all the bitfields we're gonna get */
1678 hold
= ++input_line_pointer
;
1679 segment
= expression(&exp
);
1680 } /* forever loop */
1682 exp
.X_add_number
= value
;
1683 segment
= SEG_ABSOLUTE
;
1684 } /* if looks like a bitfield */
1685 #endif /* WANT_BITFIELDS */
1687 if (!need_pass_2
) { /* Still worthwhile making frags. */
1689 /* Don't call this if we are going to junk this pass anyway! */
1690 know(segment
!= SEG_PASS1
);
1692 if (segment
== SEG_DIFFERENCE
&& exp
.X_add_symbol
== NULL
) {
1693 as_bad("Subtracting symbol \"%s\"(segment\"%s\") is too hard. Absolute segment assumed.",
1694 S_GET_NAME(exp
.X_subtract_symbol
),
1695 segment_name(S_GET_SEGMENT(exp
.X_subtract_symbol
)));
1696 segment
= SEG_ABSOLUTE
;
1697 /* Leave exp . X_add_number alone. */
1699 p
= frag_more(nbytes
);
1702 as_bad("%s number invalid. Absolute 0 assumed.",
1703 exp
. X_add_number
> 0 ? "Bignum" : "Floating-Point");
1704 md_number_to_chars (p
, (long)0, nbytes
);
1708 as_warn("0 assumed for missing expression");
1709 exp
. X_add_number
= 0;
1710 know(exp
. X_add_symbol
== NULL
);
1711 /* fall into SEG_ABSOLUTE */
1713 get
= exp
. X_add_number
;
1715 if ((get
& mask
) && (get
& mask
) != mask
)
1716 { /* Leading bits contain both 0s & 1s. */
1717 as_warn("Value 0x%x truncated to 0x%x.", get
, use
);
1719 md_number_to_chars (p
, use
, nbytes
); /* put bytes in right order. */
1722 case SEG_DIFFERENCE
:
1723 #ifndef WORKING_DOT_WORD
1725 struct broken_word
*x
;
1727 x
=(struct broken_word
*)xmalloc(sizeof(struct broken_word
));
1728 x
->next_broken_word
=broken_words
;
1731 x
->word_goes_here
=p
;
1733 x
->add
=exp
.X_add_symbol
;
1734 x
->sub
=exp
.X_subtract_symbol
;
1735 x
->addnum
=exp
.X_add_number
;
1740 /* Else Fall through into. . . */
1745 fix_new_ns32k (frag_now
, p
- frag_now
->fr_literal
, nbytes
,
1746 exp
. X_add_symbol
, exp
. X_subtract_symbol
,
1747 exp
. X_add_number
, 0, 0, 2, 0, 0);
1749 # if defined(TC_SPARC) || defined(TC_A29K)
1750 fix_new (frag_now
, p
- frag_now
->fr_literal
, nbytes
,
1751 exp
. X_add_symbol
, exp
. X_subtract_symbol
,
1752 exp
. X_add_number
, 0, RELOC_32
);
1754 # if defined(TC_H8300)
1755 fix_new (frag_now
, p
- frag_now
->fr_literal
, nbytes
,
1756 exp
. X_add_symbol
, exp
. X_subtract_symbol
,
1757 exp
. X_add_number
, 0, R_RELWORD
);
1760 fix_new (frag_now
, p
- frag_now
->fr_literal
, nbytes
,
1761 exp
. X_add_symbol
, exp
. X_subtract_symbol
,
1762 exp
. X_add_number
, 0, 0);
1764 # endif /* tc_h8300 */
1765 # endif /* tc_sparc|tc_a29k */
1766 #endif /* TC_NS32K */
1768 } /* switch(segment) */
1769 } /* if (!need_pass_2) */
1770 c
= *input_line_pointer
++;
1771 } /* while(c==',') */
1772 input_line_pointer
--; /* Put terminator back into stream. */
1773 demand_empty_rest_of_line();
1779 * CONStruct more frag(s) of .quads, or .octa etc.
1780 * Makes 0 or more new frags.
1781 * If need_pass_2 == 1, generate no frag.
1782 * This understands only bignums, not expressions. Cons() understands
1785 * Constants recognised are '0...'(octal) '0x...'(hex) '...'(decimal).
1787 * This creates objects with struct obstack_control objs, destroying
1788 * any context objs held about a partially completed object. Beware!
1791 * I think it sucks to have 2 different types of integers, with 2
1792 * routines to read them, store them etc.
1793 * It would be nicer to permit bignums in expressions and only
1794 * complain if the result overflowed. However, due to "efficiency"...
1796 /* worker to do .quad etc statements */
1797 /* clobbers input_line_pointer, checks */
1799 /* 8=.quad 16=.octa ... */
1801 void big_cons(nbytes
)
1802 register int nbytes
;
1804 register char c
; /* input_line_pointer->c. */
1806 register long length
; /* Number of chars in an object. */
1807 register int digit
; /* Value of 1 digit. */
1808 register int carry
; /* For multi-precision arithmetic. */
1809 register int work
; /* For multi-precision arithmetic. */
1810 register char * p
; /* For multi-precision arithmetic. */
1812 extern char hex_value
[]; /* In hex_value.c. */
1815 * The following awkward logic is to parse ZERO or more strings,
1816 * comma seperated. Recall an expression includes its leading &
1817 * trailing blanks. We fake a leading ',' if there is (supposed to
1818 * be) a 1st expression, and keep demanding 1 expression for each ','.
1820 if (is_it_end_of_statement())
1822 c
= 0; /* Skip loop. */
1826 c
= ','; /* Do loop. */
1827 -- input_line_pointer
;
1831 ++ input_line_pointer
;
1833 c
= * input_line_pointer
;
1834 /* C contains 1st non-blank character of what we hope is a number. */
1837 c
= * ++ input_line_pointer
;
1838 if (c
== 'x' || c
=='X')
1840 c
= * ++ input_line_pointer
;
1853 * This feature (?) is here to stop people worrying about
1854 * mysterious zero constants: which is what they get when
1855 * they completely omit digits.
1857 if (hex_value
[c
] >= radix
) {
1858 as_bad("Missing digits. 0 assumed.");
1860 bignum_high
= bignum_low
- 1; /* Start constant with 0 chars. */
1861 for(; (digit
= hex_value
[c
]) < radix
; c
= * ++ input_line_pointer
)
1863 /* Multiply existing number by radix, then add digit. */
1865 for (p
=bignum_low
; p
<= bignum_high
; p
++)
1867 work
= (*p
& MASK_CHAR
) * radix
+ carry
;
1868 *p
= work
& MASK_CHAR
;
1869 carry
= work
>> BITS_PER_CHAR
;
1874 * bignum_high
= carry
& MASK_CHAR
;
1875 know((carry
& ~ MASK_CHAR
) == 0);
1878 length
= bignum_high
- bignum_low
+ 1;
1879 if (length
> nbytes
)
1881 as_warn("Most significant bits truncated in integer constant.");
1885 register long leading_zeroes
;
1887 for(leading_zeroes
= nbytes
- length
;
1897 p
= frag_more (nbytes
);
1898 bcopy (bignum_low
, p
, (int)nbytes
);
1900 /* C contains character after number. */
1902 c
= * input_line_pointer
;
1903 /* C contains 1st non-blank character after number. */
1905 demand_empty_rest_of_line();
1908 /* Extend bignum by 1 char. */
1909 static void grow_bignum() {
1910 register long length
;
1913 if (bignum_high
>= bignum_limit
)
1915 length
= bignum_limit
- bignum_low
;
1916 bignum_low
= xrealloc(bignum_low
, length
+ length
);
1917 bignum_high
= bignum_low
+ length
;
1918 bignum_limit
= bignum_low
+ length
+ length
;
1920 } /* grow_bignum(); */
1925 * CONStruct some more frag chars of .floats .ffloats etc.
1926 * Makes 0 or more new frags.
1927 * If need_pass_2 == 1, no frags are emitted.
1928 * This understands only floating literals, not expressions. Sorry.
1930 * A floating constant is defined by atof_generic(), except it is preceded
1931 * by 0d 0f 0g or 0h. After observing the STRANGE way my BSD AS does its
1932 * reading, I decided to be incompatible. This always tries to give you
1933 * rounded bits to the precision of the pseudo-op. Former AS did premature
1934 * truncatation, restored noisy bits instead of trailing 0s AND gave you
1935 * a choice of 2 flavours of noise according to which of 2 floating-point
1936 * scanners you directed AS to use.
1938 * In: input_line_pointer->whitespace before, or '0' of flonum.
1942 void /* JF was static, but can't be if VAX.C is goning to use it */
1943 float_cons(float_type
) /* Worker to do .float etc statements. */
1944 /* Clobbers input_line-pointer, checks end-of-line. */
1945 register int float_type
; /* 'f':.ffloat ... 'F':.float ... */
1949 int length
; /* Number of chars in an object. */
1950 register char * err
; /* Error from scanning floating literal. */
1951 char temp
[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT
];
1954 * The following awkward logic is to parse ZERO or more strings,
1955 * comma seperated. Recall an expression includes its leading &
1956 * trailing blanks. We fake a leading ',' if there is (supposed to
1957 * be) a 1st expression, and keep demanding 1 expression for each ','.
1959 if (is_it_end_of_statement())
1961 c
= 0; /* Skip loop. */
1962 ++ input_line_pointer
; /*->past termintor. */
1966 c
= ','; /* Do loop. */
1970 /* input_line_pointer->1st char of a flonum (we hope!). */
1972 /* Skip any 0{letter} that may be present. Don't even check if the
1973 * letter is legal. Someone may invent a "z" format and this routine
1974 * has no use for such information. Lusers beware: you get
1975 * diagnostics if your input is ill-conditioned.
1978 if (input_line_pointer
[0]=='0' && isalpha(input_line_pointer
[1]))
1979 input_line_pointer
+=2;
1981 err
= md_atof (float_type
, temp
, &length
);
1982 know(length
<= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT
);
1986 as_bad("Bad floating literal: %s", err
);
1987 ignore_rest_of_line();
1988 /* Input_line_pointer->just after end-of-line. */
1989 c
= 0; /* Break out of loop. */
1995 p
= frag_more (length
);
1996 bcopy (temp
, p
, length
);
1999 c
= * input_line_pointer
++;
2000 /* C contains 1st non-white character after number. */
2001 /* input_line_pointer->just after terminator (c). */
2004 -- input_line_pointer
; /*->terminator (is not ','). */
2005 demand_empty_rest_of_line();
2006 } /* float_cons() */
2011 * We read 0 or more ',' seperated, double-quoted strings.
2013 * Caller should have checked need_pass_2 is FALSE because we don't check it.
2017 void stringer(append_zero
) /* Worker to do .ascii etc statements. */
2018 /* Checks end-of-line. */
2019 register int append_zero
; /* 0: don't append '\0', else 1 */
2021 /* register char * p; JF unused */
2022 /* register int length; JF unused */ /* Length of string we read, excluding */
2023 /* trailing '\0' implied by closing quote. */
2024 /* register char * where; JF unused */
2025 /* register fragS * fragP; JF unused */
2026 register unsigned int c
;
2029 * The following awkward logic is to parse ZERO or more strings,
2030 * comma seperated. Recall a string expression includes spaces
2031 * before the opening '\"' and spaces after the closing '\"'.
2032 * We fake a leading ',' if there is (supposed to be)
2033 * a 1st, expression. We keep demanding expressions for each
2036 if (is_it_end_of_statement())
2038 c
= 0; /* Skip loop. */
2039 ++ input_line_pointer
; /* Compensate for end of loop. */
2043 c
= ','; /* Do loop. */
2045 while (c
== ',' || c
== '<' || c
== '"' ) {
2047 switch (*input_line_pointer
) {
2049 ++input_line_pointer
; /*->1st char of string. */
2050 while (is_a_char(c
= next_char_of_string())) {
2051 FRAG_APPEND_1_CHAR(c
);
2054 FRAG_APPEND_1_CHAR(0);
2056 know(input_line_pointer
[-1] == '\"');
2059 input_line_pointer
++;
2060 c
=get_single_number();
2061 FRAG_APPEND_1_CHAR(c
);
2062 if(*input_line_pointer
!= '>') {
2063 as_bad("Expected <nn>");
2065 input_line_pointer
++;
2068 input_line_pointer
++;
2072 c
= *input_line_pointer
;
2075 demand_empty_rest_of_line();
2078 /* FIXME-SOMEDAY: I had trouble here on characters with the
2079 high bits set. We'll probably also have trouble with
2080 multibyte chars, wide chars, etc. Also be careful about
2081 returning values bigger than 1 byte. xoxorich. */
2083 unsigned int next_char_of_string() {
2084 register unsigned int c
;
2086 c
= *input_line_pointer
++ & CHAR_MASK
;
2093 switch (c
= *input_line_pointer
++) {
2122 break; /* As itself. */
2136 for (number
= 0; isdigit(c
); c
= *input_line_pointer
++) {
2137 number
= number
* 8 + c
- '0';
2141 --input_line_pointer
;
2145 /* To be compatible with BSD 4.2 as: give the luser a linefeed!! */
2146 as_warn("Unterminated string: Newline inserted.");
2152 #ifdef ONLY_STANDARD_ESCAPES
2153 as_bad("Bad escaped character in string, '?' assumed");
2155 #endif /* ONLY_STANDARD_ESCAPES */
2158 } /* switch on escaped char */
2163 } /* switch on char */
2165 } /* next_char_of_string() */
2168 get_segmented_expression (expP
)
2169 register expressionS
* expP
;
2171 register segT retval
;
2173 if ((retval
= expression(expP
)) == SEG_PASS1
|| retval
== SEG_ABSENT
|| retval
== SEG_BIG
)
2175 as_bad("Expected address expression: absolute 0 assumed");
2176 retval
= expP
->X_seg
= SEG_ABSOLUTE
;
2177 expP
->X_add_number
= 0;
2178 expP
->X_add_symbol
= expP
->X_subtract_symbol
= 0;
2180 return (retval
); /* SEG_ ABSOLUTE,UNKNOWN,DATA,TEXT,BSS */
2183 static segT
get_known_segmented_expression(expP
)
2184 register expressionS
*expP
;
2186 register segT retval
;
2187 register char * name1
;
2188 register char * name2
;
2190 if ((retval
= get_segmented_expression (expP
)) == SEG_UNKNOWN
)
2192 name1
= expP
->X_add_symbol
? S_GET_NAME(expP
->X_add_symbol
) : "";
2193 name2
= expP
->X_subtract_symbol
?
2194 S_GET_NAME(expP
->X_subtract_symbol
) :
2198 as_warn("Symbols \"%s\" \"%s\" are undefined: absolute 0 assumed.",
2203 as_warn("Symbol \"%s\" undefined: absolute 0 assumed.",
2204 name1
? name1
: name2
);
2206 retval
= expP
->X_seg
= SEG_ABSOLUTE
;
2207 expP
->X_add_number
= 0;
2208 expP
->X_add_symbol
= expP
->X_subtract_symbol
= NULL
;
2210 #ifndef MANY_SEGMENTS
2211 know(retval
== SEG_ABSOLUTE
|| retval
== SEG_DATA
|| retval
== SEG_TEXT
|| retval
== SEG_BSS
|| retval
== SEG_DIFFERENCE
);
2215 } /* get_known_segmented_expression() */
2219 /* static */ long /* JF was static, but can't be if the MD pseudos are to use it */
2220 get_absolute_expression ()
2225 if ((s
= expression(& exp
)) != SEG_ABSOLUTE
)
2227 if (s
!= SEG_ABSENT
)
2229 as_bad("Bad Absolute Expression, absolute 0 assumed.");
2231 exp
. X_add_number
= 0;
2233 return (exp
. X_add_number
);
2236 char /* return terminator */
2237 get_absolute_expression_and_terminator(val_pointer
)
2238 long * val_pointer
; /* return value of expression */
2240 * val_pointer
= get_absolute_expression ();
2241 return (* input_line_pointer
++);
2245 * demand_copy_C_string()
2247 * Like demand_copy_string, but return NULL if the string contains any '\0's.
2248 * Give a warning if that happens.
2251 demand_copy_C_string (len_pointer
)
2256 if ((s
= demand_copy_string(len_pointer
)) != 0)
2260 for (len
= * len_pointer
;
2269 as_bad("This string may not contain \'\\0\'");
2277 * demand_copy_string()
2279 * Demand string, but return a safe (=private) copy of the string.
2280 * Return NULL if we can't read a string here.
2282 static char *demand_copy_string(lenP
)
2285 register unsigned int c
;
2291 if (*input_line_pointer
== '\"') {
2292 input_line_pointer
++; /* Skip opening quote. */
2294 while (is_a_char(c
= next_char_of_string())) {
2295 obstack_1grow(¬es
, c
);
2298 /* JF this next line is so demand_copy_C_string will return a null
2299 termanated string. */
2300 obstack_1grow(¬es
,'\0');
2301 retval
=obstack_finish(¬es
);
2303 as_warn("Missing string");
2305 ignore_rest_of_line();
2309 } /* demand_copy_string() */
2312 * is_it_end_of_statement()
2314 * In: Input_line_pointer->next character.
2316 * Do: Skip input_line_pointer over all whitespace.
2318 * Out: 1 if input_line_pointer->end-of-line.
2320 int is_it_end_of_statement() {
2322 return (is_end_of_line
[* input_line_pointer
]);
2323 } /* is_it_end_of_statement() */
2325 void equals(sym_name
)
2328 register symbolS
*symbolP
; /* symbol we are working with */
2330 input_line_pointer
++;
2331 if (*input_line_pointer
=='=')
2332 input_line_pointer
++;
2334 while(*input_line_pointer
==' ' || *input_line_pointer
=='\t')
2335 input_line_pointer
++;
2337 if (sym_name
[0]=='.' && sym_name
[1]=='\0') {
2338 /* Turn '. = mumble' into a .org mumble */
2339 register segT segment
;
2343 segment
= get_known_segmented_expression(& exp
);
2344 if (! need_pass_2
) {
2345 if (segment
!= now_seg
&& segment
!= SEG_ABSOLUTE
)
2346 as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",
2347 segment_name(segment
),
2348 segment_name(now_seg
));
2349 p
= frag_var(rs_org
, 1, 1, (relax_substateT
)0, exp
.X_add_symbol
,
2350 exp
.X_add_number
, (char *)0);
2352 } /* if (ok to make frag) */
2354 symbolP
=symbol_find_or_make(sym_name
);
2355 pseudo_set(symbolP
);
2359 /* .include -- include a file at this point. */
2371 filename
= demand_copy_string(&i
);
2372 demand_empty_rest_of_line();
2373 path
= xmalloc(i
+ include_dir_maxlen
+ 5 /* slop */);
2374 for (i
= 0; i
< include_dir_count
; i
++) {
2375 strcpy(path
, include_dirs
[i
]);
2377 strcat(path
, filename
);
2378 if (0 != (try = fopen(path
, "r")))
2387 /* malloc Storage leak when file is found on path. FIXME-SOMEDAY. */
2388 newbuf
= input_scrub_include_file (path
, input_line_pointer
);
2389 buffer_limit
= input_scrub_next_buffer (&input_line_pointer
);
2392 void add_include_dir(path
)
2397 if (include_dir_count
== 0)
2399 include_dirs
= (char **)xmalloc (2 * sizeof (*include_dirs
));
2400 include_dirs
[0] = "."; /* Current dir */
2401 include_dir_count
= 2;
2405 include_dir_count
++;
2406 include_dirs
= (char **) realloc(include_dirs
,
2407 include_dir_count
*sizeof (*include_dirs
));
2410 include_dirs
[include_dir_count
-1] = path
; /* New one */
2413 if (i
> include_dir_maxlen
)
2414 include_dir_maxlen
= i
;
2415 } /* add_include_dir() */
2420 extern char is_end_of_line
[];
2422 while (!is_end_of_line
[*input_line_pointer
]) {
2423 ++input_line_pointer
;
2425 ++input_line_pointer
;