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();
348 } /* just passed a newline */
353 * We are at the begining of a line, or similar place.
354 * We expect a well-formed assembler statement.
355 * A "symbol-name:" is a statement.
357 * Depending on what compiler is used, the order of these tests
358 * may vary to catch most common case 1st.
359 * Each test is independent of all other tests at the (top) level.
360 * PLEASE make a compiler that doesn't use this assembler.
361 * It is crufty to waste a compiler's time encoding things for this
362 * assembler, which then wastes more time decoding it.
363 * (And communicating via (linear) files is silly!
364 * If you must pass stuff, please pass a tree!)
366 if ((c
= *input_line_pointer
++) == '\t' || c
== ' ' || c
=='\f' || c
== 0) {
367 c
= *input_line_pointer
++;
369 know(c
!= ' '); /* No further leading whitespace. */
372 * C is the 1st significant character.
373 * Input_line_pointer points after that character.
375 if (is_name_beginner(c
)) { /* want user-defined label or pseudo/opcode */
376 HANDLE_CONDITIONAL_ASSEMBLY();
378 s
= --input_line_pointer
;
379 c
= get_symbol_end(); /* name's delimiter */
381 * C is character after symbol.
382 * That character's place in the input line is now '\0'.
383 * S points to the beginning of the symbol.
384 * [In case of pseudo-op, s->'.'.]
385 * Input_line_pointer->'\0' where c was.
388 colon(s
); /* user-defined label */
389 * input_line_pointer
++ = ':'; /* Put ':' back for error messages' sake. */
390 /* Input_line_pointer->after ':'. */
394 } else if (c
== '=' || input_line_pointer
[1] == '=') { /* JF deal with FOO=BAR */
396 demand_empty_rest_of_line();
397 } else { /* expect pseudo-op or machine instruction */
402 * WARNING: c has next char, which may be end-of-line.
403 * We lookup the pseudo-op table with s+1 because we
404 * already know that the pseudo-op begins with a '.'.
407 pop
= (pseudo_typeS
*) hash_find(po_hash
, s
+1);
409 /* Print the error msg now, while we still can */
411 as_bad("Unknown pseudo-op: `%s'",s
);
412 *input_line_pointer
= c
;
417 /* Put it back for error messages etc. */
418 *input_line_pointer
= c
;
419 /* The following skip of whitespace is compulsory. */
420 /* A well shaped space is sometimes all that separates keyword from operands. */
421 if (c
== ' ' || c
== '\t') {
422 input_line_pointer
++;
423 } /* Skip seperator after keyword. */
425 * Input_line is restored.
426 * Input_line_pointer->1st non-blank char
427 * after pseudo-operation.
430 ignore_rest_of_line();
433 (*pop
->poc_handler
)(pop
->poc_val
);
434 } /* if we have one */
435 } else { /* machine instruction */
436 /* WARNING: c has char, which may be end-of-line. */
437 /* Also: input_line_pointer->`\0` where c was. */
438 * input_line_pointer
= c
;
439 while (!is_end_of_line
[*input_line_pointer
]) {
440 input_line_pointer
++;
442 c
= *input_line_pointer
;
443 *input_line_pointer
= '\0';
444 md_assemble(s
); /* Assemble 1 instruction. */
445 *input_line_pointer
++ = c
;
446 /* We resume loop AFTER the end-of-line from this instruction */
451 } /* if (is_name_beginner(c) */
454 if (is_end_of_line
[c
]) {
456 } /* empty statement */
459 if (isdigit(c
)) { /* local label ("4:") */
460 HANDLE_CONDITIONAL_ASSEMBLY ();
463 #ifdef LOCAL_LABELS_DOLLAR
464 if (*input_line_pointer
=='$')
465 input_line_pointer
++;
467 if (* input_line_pointer
++ == ':')
473 as_bad("Spurious digit %d.", temp
);
474 input_line_pointer
-- ;
475 ignore_rest_of_line();
478 } /* local label ("4:") */
480 if (c
&& strchr(line_comment_chars
,c
)) { /* Its a comment. Better say APP or NO_APP */
486 extern char *scrub_string
,*scrub_last_string
;
488 bump_line_counters();
489 s
=input_line_pointer
;
490 if (strncmp(s
,"APP\n",4))
491 continue; /* We ignore it */
494 ends
=strstr(s
,"#NO_APP\n");
500 /* The end of the #APP wasn't in this buffer. We
501 keep reading in buffers until we find the #NO_APP
502 that goes with this #APP There is one. The specs
504 tmp_len
=buffer_limit
-s
;
505 tmp_buf
=xmalloc(tmp_len
);
506 bcopy(s
,tmp_buf
,tmp_len
);
508 new_tmp
= input_scrub_next_buffer(&buffer
);
512 buffer_limit
= new_tmp
;
513 input_line_pointer
= buffer
;
514 ends
= strstr(buffer
,"#NO_APP\n");
518 num
=buffer_limit
-buffer
;
520 tmp_buf
= xrealloc(tmp_buf
, tmp_len
+ num
);
521 bcopy(buffer
,tmp_buf
+tmp_len
,num
);
525 input_line_pointer
= ends
? ends
+8 : NULL
;
531 input_line_pointer
=ends
+8;
533 new_buf
=xmalloc(100);
538 scrub_last_string
= ends
;
542 ch
= do_scrub_next_char(scrub_from_string
, scrub_to_string
);
545 if (new_tmp
==new_buf
+new_length
) {
546 new_buf
=xrealloc(new_buf
,new_length
+100);
547 new_tmp
=new_buf
+new_length
;
555 old_input
=input_line_pointer
;
556 old_limit
=buffer_limit
;
558 input_line_pointer
=new_buf
;
559 buffer_limit
=new_tmp
;
563 HANDLE_CONDITIONAL_ASSEMBLY();
565 /* as_warn("Junk character %d.",c); Now done by ignore_rest */
566 input_line_pointer
--; /* Report unknown char as ignored. */
567 ignore_rest_of_line();
568 } /* while (input_line_pointer<buffer_limit) */
570 bump_line_counters();
571 if (old_input
!= 0) {
573 input_line_pointer
=old_input
;
574 buffer_limit
=old_limit
;
579 } /* while (more buffers to scan) */
580 input_scrub_close(); /* Close the input file */
582 } /* read_a_source_file() */
585 as_fatal(".abort detected. Abandoning ship.");
588 /* For machines where ".align 4" means align to a 4 byte boundary. */
589 void s_align_bytes(arg
)
592 register unsigned int temp
;
593 register long temp_fill
;
595 unsigned long max_alignment
= 1 << 15;
597 if (is_end_of_line
[*input_line_pointer
])
598 temp
= arg
; /* Default value from pseudo-op table */
600 temp
= get_absolute_expression ();
602 if (temp
> max_alignment
) {
603 as_bad("Alignment too large: %d. assumed.", temp
= max_alignment
);
607 * For the sparc, `.align (1<<n)' actually means `.align n'
608 * so we have to convert it.
611 for (i
= 0; (temp
& 1) == 0; temp
>>= 1, ++i
)
615 as_bad("Alignment not a power of 2");
618 if (*input_line_pointer
== ',') {
619 input_line_pointer
++;
620 temp_fill
= get_absolute_expression ();
624 /* Only make a frag if we HAVE to. . . */
625 if (temp
&& ! need_pass_2
)
626 frag_align(temp
, (int)temp_fill
);
628 demand_empty_rest_of_line();
629 } /* s_align_bytes() */
631 /* For machines where ".align 4" means align to 2**4 boundary. */
632 void s_align_ptwo() {
634 register long temp_fill
;
635 long max_alignment
= 15;
637 temp
= get_absolute_expression ();
638 if (temp
> max_alignment
)
639 as_bad("Alignment too large: %d. assumed.", temp
= max_alignment
);
641 as_bad("Alignment negative. 0 assumed.");
644 if (*input_line_pointer
== ',') {
645 input_line_pointer
++;
646 temp_fill
= get_absolute_expression ();
649 /* Only make a frag if we HAVE to. . . */
650 if (temp
&& ! need_pass_2
)
651 frag_align (temp
, (int)temp_fill
);
653 record_alignment(now_seg
, temp
);
655 demand_empty_rest_of_line();
656 } /* s_align_ptwo() */
663 register symbolS
* symbolP
;
665 name
= input_line_pointer
;
666 c
= get_symbol_end();
667 /* just after name is now '\0' */
668 p
= input_line_pointer
;
671 if (*input_line_pointer
!= ',') {
672 as_bad("Expected comma after symbol-name: rest of line ignored.");
673 ignore_rest_of_line();
676 input_line_pointer
++; /* skip ',' */
677 if ((temp
= get_absolute_expression()) < 0) {
678 as_warn(".COMMon length (%d.) <0! Ignored.", temp
);
679 ignore_rest_of_line();
683 symbolP
= symbol_find_or_make(name
);
685 if (S_IS_DEFINED(symbolP
)) {
686 as_bad("Ignoring attempt to re-define symbol");
687 ignore_rest_of_line();
690 if (S_GET_VALUE(symbolP
)) {
691 if (S_GET_VALUE(symbolP
) != temp
)
692 as_bad("Length of .comm \"%s\" is already %d. Not changed to %d.",
694 S_GET_VALUE(symbolP
),
697 S_SET_VALUE(symbolP
, temp
);
698 S_SET_EXTERNAL(symbolP
);
702 symbolP
->sy_other
= const_flag
;
704 know(symbolP
->sy_frag
== &zero_address_frag
);
705 demand_empty_rest_of_line();
713 temp
= get_absolute_expression ();
715 subseg_new (SEG_E1
, (subsegT
)temp
);
717 subseg_new (SEG_DATA
, (subsegT
)temp
);
723 demand_empty_rest_of_line();
730 /* Some assemblers tolerate immediately following '"' */
731 if ((s
= demand_copy_string(&length
)) != 0) {
732 new_logical_line(s
, -1);
733 demand_empty_rest_of_line();
736 c_dot_file_symbol(s
);
737 #endif /* OBJ_COFF */
743 register long temp_fill
;
746 if (get_absolute_expression_and_terminator(& temp_repeat
) != ',') {
747 input_line_pointer
--; /* Backup over what was not a ','. */
748 as_bad("Expect comma after rep-size in .fill:");
749 ignore_rest_of_line();
752 if (get_absolute_expression_and_terminator(& temp_size
) != ',') {
753 input_line_pointer
--; /* Backup over what was not a ','. */
754 as_bad("Expected comma after size in .fill");
755 ignore_rest_of_line();
759 * This is to be compatible with BSD 4.2 AS, not for any rational reason.
761 #define BSD_FILL_SIZE_CROCK_8 (8)
762 if (temp_size
> BSD_FILL_SIZE_CROCK_8
) {
763 as_bad(".fill size clamped to %d.", BSD_FILL_SIZE_CROCK_8
);
764 temp_size
= BSD_FILL_SIZE_CROCK_8
;
765 } if (temp_size
< 0) {
766 as_warn("Size negative: .fill ignored.");
768 } else if (temp_repeat
<= 0) {
769 as_warn("Repeat < 0, .fill ignored");
772 temp_fill
= get_absolute_expression ();
773 if (temp_size
&& !need_pass_2
) {
774 p
= frag_var(rs_fill
, (int)temp_size
, (int)temp_size
, (relax_substateT
)0, (symbolS
*)0, temp_repeat
, (char *)0);
775 bzero (p
, (int)temp_size
);
777 * The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX flavoured AS.
778 * The following bizzare behaviour is to be compatible with above.
779 * I guess they tried to take up to 8 bytes from a 4-byte expression
780 * and they forgot to sign extend. Un*x Sux.
782 #define BSD_FILL_SIZE_CROCK_4 (4)
783 md_number_to_chars (p
, temp_fill
, temp_size
> BSD_FILL_SIZE_CROCK_4
? BSD_FILL_SIZE_CROCK_4
: (int)temp_size
);
785 * Note: .fill (),0 emits no frag (since we are asked to .fill 0 bytes)
786 * but emits no error message because it seems a legal thing to do.
787 * It is a degenerate case of .fill but could be emitted by a compiler.
790 demand_empty_rest_of_line();
799 temp
= get_absolute_expression ();
801 as_warn("Block number <0. Ignored.");
802 else if (flagseen
['G'])
803 gdb_block_beg ((long) temp
, frag_now
, (long)(obstack_next_free(& frags
) - frag_now
->fr_literal
));
804 demand_empty_rest_of_line ();
810 register int position
;
813 if (get_absolute_expression_and_terminator (&temp
) != ',') {
814 as_bad("expected comma before position in .gdbblock");
815 --input_line_pointer
;
816 ignore_rest_of_line ();
819 position
= get_absolute_expression ();
821 gdb_block_position ((long) temp
, (long) position
);
822 demand_empty_rest_of_line ();
830 temp
= get_absolute_expression ();
832 as_warn("Block number <0. Ignored.");
833 else if (flagseen
['G'])
834 gdb_block_end ((long) temp
, frag_now
, (long)(obstack_next_free(& frags
) - frag_now
->fr_literal
));
835 demand_empty_rest_of_line ();
844 register symbolS
* symbolP
;
847 name
= input_line_pointer
;
848 c
= get_symbol_end();
849 p
= input_line_pointer
;
850 symbolP
= symbol_find_or_make(name
);
853 if (* input_line_pointer
!= ',') {
854 as_bad("Expected comma after name");
855 ignore_rest_of_line();
858 input_line_pointer
++;
859 if ((temp
= get_absolute_expression ()) < 0) {
860 as_bad("Bad GDB symbol file offset (%d.) <0! Ignored.", temp
);
861 ignore_rest_of_line();
865 gdb_symbols_fixup (symbolP
, (long)temp
);
866 demand_empty_rest_of_line ();
875 if (get_absolute_expression_and_terminator(&file_number
) != ',') {
876 as_bad("expected comman after filenum in .gdbline");
877 ignore_rest_of_line();
880 lineno
=get_absolute_expression();
882 gdb_line(file_number
,lineno
);
883 demand_empty_rest_of_line();
893 if (get_absolute_expression_and_terminator(&file_number
) != ',') {
894 as_bad("expected comma after filenum in .gdblinetab");
895 ignore_rest_of_line();
898 offset
=get_absolute_expression();
900 gdb_line_tab(file_number
,offset
);
901 demand_empty_rest_of_line();
908 register symbolS
* symbolP
;
911 name
= input_line_pointer
;
912 c
= get_symbol_end();
913 symbolP
= symbol_find_or_make(name
);
914 * input_line_pointer
= c
;
916 S_SET_EXTERNAL(symbolP
);
918 input_line_pointer
++;
920 if (*input_line_pointer
=='\n')
924 demand_empty_rest_of_line();
927 void s_lcomm(needs_align
)
928 int needs_align
; /* 1 if this was a ".bss" directive, which may require
929 * a 3rd argument (alignment).
930 * 0 if it was an ".lcomm" (2 args only)
937 register symbolS
* symbolP
;
938 const int max_alignment
= 15;
941 name
= input_line_pointer
;
942 c
= get_symbol_end();
943 p
= input_line_pointer
;
946 if (*input_line_pointer
!= ',') {
947 as_bad("Expected comma after name");
948 ignore_rest_of_line();
952 ++input_line_pointer
;
954 if (*input_line_pointer
== '\n') {
955 as_bad("Missing size expression");
959 if ((temp
= get_absolute_expression ()) < 0) {
960 as_warn("BSS length (%d.) <0! Ignored.", temp
);
961 ignore_rest_of_line();
968 if (*input_line_pointer
!= ',') {
969 as_bad("Expected comma after size");
970 ignore_rest_of_line();
973 input_line_pointer
++;
975 if (*input_line_pointer
== '\n') {
976 as_bad("Missing alignment");
979 align
= get_absolute_expression ();
980 if (align
> max_alignment
){
981 align
= max_alignment
;
982 as_warn("Alignment too large: %d. assumed.", align
);
983 } else if (align
< 0) {
985 as_warn("Alignment negative. 0 assumed.");
988 #define SEG_BSS SEG_E2
989 record_alignment(SEG_E2
, align
);
991 record_alignment(SEG_BSS
, align
);
993 } /* if needs align */
996 symbolP
= symbol_find_or_make(name
);
1000 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1001 S_GET_OTHER(symbolP
) == 0 &&
1002 S_GET_DESC(symbolP
) == 0 &&
1003 #endif /* OBJ_AOUT or OBJ_BOUT */
1004 (((S_GET_SEGMENT(symbolP
) == SEG_BSS
) && (S_GET_VALUE(symbolP
) == local_bss_counter
))
1005 || (!S_IS_DEFINED(symbolP
) && S_GET_VALUE(symbolP
) == 0))) {
1008 align
= ~ ((~0) << align
); /* Convert to a mask */
1010 (local_bss_counter
+ align
) & (~align
);
1013 S_SET_VALUE(symbolP
,local_bss_counter
);
1014 S_SET_SEGMENT(symbolP
, SEG_BSS
);
1016 /* The symbol may already have been created with a preceding
1017 * ".globl" directive -- be careful not to step on storage
1018 * class in that case. Otherwise, set it to static.
1020 if (S_GET_STORAGE_CLASS(symbolP
) != C_EXT
){
1021 S_SET_STORAGE_CLASS(symbolP
, C_STAT
);
1023 #endif /* OBJ_COFF */
1024 symbolP
->sy_frag
= & bss_address_frag
;
1025 local_bss_counter
+= temp
;
1027 as_bad("Ignoring attempt to re-define symbol from %d. to %d.",
1028 S_GET_VALUE(symbolP
), local_bss_counter
);
1030 demand_empty_rest_of_line();
1048 register char *name
;
1051 register segT segment
;
1053 register symbolS
*symbolP
;
1055 /* we permit ANY defined expression: BSD4.2 demands constants */
1056 name
= input_line_pointer
;
1057 c
= get_symbol_end();
1058 p
= input_line_pointer
;
1061 if (* input_line_pointer
!= ',') {
1063 as_bad("Expected comma after name \"%s\"", name
);
1065 ignore_rest_of_line();
1068 input_line_pointer
++;
1069 segment
= expression(& exp
);
1070 if (segment
!= SEG_ABSOLUTE
1071 #ifdef MANY_SEGMENTS
1072 && ! ( segment
>= SEG_E0
&& segment
<= SEG_UNKNOWN
)
1074 && segment
!= SEG_DATA
1075 && segment
!= SEG_TEXT
1076 && segment
!= SEG_BSS
1078 && segment
!= SEG_REGISTER
) {
1079 as_bad("Bad expression: %s", segment_name(segment
));
1080 ignore_rest_of_line();
1084 symbolP
= symbol_find_or_make(name
);
1086 /* FIXME-SOON I pulled a (&& symbolP->sy_other == 0
1087 && symbolP->sy_desc == 0) out of this test
1088 because coff doesn't have those fields, and I
1089 can't see when they'd ever be tripped. I don't
1090 think I understand why they were here so I may
1091 have introduced a bug. As recently as 1.37 didn't
1092 have this test anyway. xoxorich. */
1094 if (S_GET_SEGMENT(symbolP
) == SEG_UNKNOWN
1095 && S_GET_VALUE(symbolP
) == 0) {
1096 /* The name might be an undefined .global symbol; be
1097 sure to keep the "external" bit. */
1098 S_SET_SEGMENT(symbolP
, segment
);
1099 S_SET_VALUE(symbolP
, (valueT
)(exp
.X_add_number
));
1101 as_bad("Symbol %s already defined", name
);
1104 demand_empty_rest_of_line();
1108 register segT segment
;
1110 register long temp_fill
;
1113 * Don't believe the documentation of BSD 4.2 AS.
1114 * There is no such thing as a sub-segment-relative origin.
1115 * Any absolute origin is given a warning, then assumed to be segment-relative.
1116 * Any segmented origin expression ("foo+42") had better be in the right
1117 * segment or the .org is ignored.
1119 * BSD 4.2 AS warns if you try to .org backwards. We cannot because we
1120 * never know sub-segment sizes when we are reading code.
1121 * BSD will crash trying to emit -ve numbers of filler bytes in certain
1122 * .orgs. We don't crash, but see as-write for that code.
1125 * Don't make frag if need_pass_2==1.
1127 segment
= get_known_segmented_expression(&exp
);
1128 if (*input_line_pointer
== ',') {
1129 input_line_pointer
++;
1130 temp_fill
= get_absolute_expression ();
1133 if (! need_pass_2
) {
1134 if (segment
!= now_seg
&& segment
!= SEG_ABSOLUTE
)
1135 as_bad("Invalid segment \"%s\". Segment \"%s\" assumed.",
1136 segment_name(segment
), segment_name(now_seg
));
1137 p
= frag_var (rs_org
, 1, 1, (relax_substateT
)0, exp
. X_add_symbol
,
1138 exp
. X_add_number
, (char *)0);
1140 } /* if (ok to make frag) */
1141 demand_empty_rest_of_line();
1145 register char *name
;
1146 register char delim
;
1147 register char *end_name
;
1148 register symbolS
*symbolP
;
1151 * Especial apologies for the random logic:
1152 * this just grew, and could be parsed much more simply!
1155 name
= input_line_pointer
;
1156 delim
= get_symbol_end();
1157 end_name
= input_line_pointer
;
1161 if (*input_line_pointer
!= ',') {
1163 as_bad("Expected comma after name \"%s\"", name
);
1165 ignore_rest_of_line();
1169 input_line_pointer
++;
1172 if (name
[0]=='.' && name
[1]=='\0') {
1173 /* Turn '. = mumble' into a .org mumble */
1174 register segT segment
;
1178 segment
= get_known_segmented_expression(& exp
);
1181 if (segment
!= now_seg
&& segment
!= SEG_ABSOLUTE
)
1182 as_bad("Invalid segment \"%s\". Segment \"%s\" assumed.",
1183 segment_name(segment
),
1184 segment_name (now_seg
));
1185 ptr
= frag_var(rs_org
, 1, 1, (relax_substateT
)0, exp
.X_add_symbol
,
1186 exp
.X_add_number
, (char *)0);
1188 } /* if (ok to make frag) */
1194 if ((symbolP
= symbol_find(name
)) == NULL
1195 && (symbolP
= md_undefined_symbol(name
)) == NULL
) {
1196 symbolP
= symbol_new(name
,
1199 &zero_address_frag
);
1201 /* "set" symbols are local unless otherwise specified. */
1202 SF_SET_LOCAL(symbolP
);
1203 #endif /* OBJ_COFF */
1205 } /* make a new symbol */
1207 symbol_table_insert(symbolP
);
1210 pseudo_set(symbolP
);
1211 demand_empty_rest_of_line();
1216 register long temp_fill
;
1219 /* Just like .fill, but temp_size = 1 */
1220 if (get_absolute_expression_and_terminator(& temp_repeat
) == ',') {
1221 temp_fill
= get_absolute_expression ();
1223 input_line_pointer
--; /* Backup over what was not a ','. */
1226 if (temp_repeat
<= 0) {
1227 as_warn("Repeat < 0, .space ignored");
1228 ignore_rest_of_line();
1231 if (! need_pass_2
) {
1232 p
= frag_var (rs_fill
, 1, 1, (relax_substateT
)0, (symbolS
*)0,
1233 temp_repeat
, (char *)0);
1236 demand_empty_rest_of_line();
1244 temp
= get_absolute_expression ();
1245 #ifdef MANY_SEGMENTS
1246 subseg_new (SEG_E0
, (subsegT
)temp
);
1248 subseg_new (SEG_TEXT
, (subsegT
)temp
);
1250 demand_empty_rest_of_line();
1254 /*(JF was static, but can't be if machine dependent pseudo-ops are to use it */
1256 void demand_empty_rest_of_line() {
1258 if (is_end_of_line
[*input_line_pointer
]) {
1259 input_line_pointer
++;
1261 ignore_rest_of_line();
1263 /* Return having already swallowed end-of-line. */
1264 } /* Return pointing just after end-of-line. */
1267 ignore_rest_of_line() /* For suspect lines: gives warning. */
1269 if (! is_end_of_line
[* input_line_pointer
])
1271 if (isprint(*input_line_pointer
))
1272 as_bad("Rest of line ignored. First ignored character is `%c'.",
1273 *input_line_pointer
);
1275 as_bad("Rest of line ignored. First ignored character valued 0x%x.",
1276 *input_line_pointer
);
1277 while (input_line_pointer
< buffer_limit
1278 && ! is_end_of_line
[* input_line_pointer
])
1280 input_line_pointer
++;
1283 input_line_pointer
++; /* Return pointing just after end-of-line. */
1284 know(is_end_of_line
[input_line_pointer
[-1]]);
1290 * In: Pointer to a symbol.
1291 * Input_line_pointer->expression.
1293 * Out: Input_line_pointer->just after any whitespace after expression.
1294 * Tried to set symbol to value of expression.
1295 * Will change symbols type, value, and frag;
1296 * May set need_pass_2 == 1.
1299 pseudo_set (symbolP
)
1303 register segT segment
;
1304 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1306 #endif /* OBJ_AOUT or OBJ_BOUT */
1308 know(symbolP
); /* NULL pointer is logic error. */
1309 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1310 ext
=S_IS_EXTERNAL(symbolP
);
1311 #endif /* OBJ_AOUT or OBJ_BOUT */
1313 if ((segment
= expression(& exp
)) == SEG_ABSENT
)
1315 as_bad("Missing expression: absolute 0 assumed");
1316 exp
. X_seg
= SEG_ABSOLUTE
;
1317 exp
. X_add_number
= 0;
1323 as_bad("%s number invalid. Absolute 0 assumed.",
1324 exp
. X_add_number
> 0 ? "Bignum" : "Floating-Point");
1325 S_SET_SEGMENT(symbolP
, SEG_ABSOLUTE
);
1326 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1327 ext
? S_SET_EXTERNAL(symbolP
) :
1328 S_CLEAR_EXTERNAL(symbolP
);
1329 #endif /* OBJ_AOUT or OBJ_BOUT */
1330 S_SET_VALUE(symbolP
, 0);
1331 symbolP
->sy_frag
= & zero_address_frag
;
1335 as_warn("No expression: Using absolute 0");
1336 S_SET_SEGMENT(symbolP
, SEG_ABSOLUTE
);
1337 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1338 ext
? S_SET_EXTERNAL(symbolP
) :
1339 S_CLEAR_EXTERNAL(symbolP
);
1340 #endif /* OBJ_AOUT or OBJ_BOUT */
1341 S_SET_VALUE(symbolP
, 0);
1342 symbolP
->sy_frag
= & zero_address_frag
;
1345 case SEG_DIFFERENCE
:
1346 if (exp
.X_add_symbol
&& exp
.X_subtract_symbol
1347 && (S_GET_SEGMENT(exp
.X_add_symbol
) ==
1348 S_GET_SEGMENT(exp
.X_subtract_symbol
))) {
1349 if (exp
.X_add_symbol
->sy_frag
!= exp
.X_subtract_symbol
->sy_frag
) {
1350 as_bad("Unknown expression: symbols %s and %s are in different frags.",
1351 S_GET_NAME(exp
.X_add_symbol
), S_GET_NAME(exp
.X_subtract_symbol
));
1354 exp
.X_add_number
+=S_GET_VALUE(exp
.X_add_symbol
) -
1355 S_GET_VALUE(exp
.X_subtract_symbol
);
1357 as_bad("Complex expression. Absolute segment assumed.");
1359 S_SET_SEGMENT(symbolP
, SEG_ABSOLUTE
);
1360 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1361 ext
? S_SET_EXTERNAL(symbolP
) :
1362 S_CLEAR_EXTERNAL(symbolP
);
1363 #endif /* OBJ_AOUT or OBJ_BOUT */
1364 S_SET_VALUE(symbolP
, exp
.X_add_number
);
1365 symbolP
->sy_frag
= & zero_address_frag
;
1369 #ifdef MANY_SEGMENTS
1370 S_SET_SEGMENT(symbolP
, segment
);
1373 case SEG_DATA
: S_SET_SEGMENT(symbolP
, SEG_DATA
); break;
1374 case SEG_TEXT
: S_SET_SEGMENT(symbolP
, SEG_TEXT
); break;
1375 case SEG_BSS
: S_SET_SEGMENT(symbolP
, SEG_BSS
); break;
1376 default: as_fatal("failed sanity check.");
1377 } /* switch on segment */
1379 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1381 S_SET_EXTERNAL(symbolP
);
1383 S_CLEAR_EXTERNAL(symbolP
);
1385 #endif /* OBJ_AOUT or OBJ_BOUT */
1387 S_SET_VALUE(symbolP
, exp
.X_add_number
+ S_GET_VALUE(exp
.X_add_symbol
));
1388 symbolP
->sy_frag
= exp
. X_add_symbol
->sy_frag
;
1391 case SEG_PASS1
: /* Not an error. Just try another pass. */
1392 symbolP
->sy_forward
=exp
.X_add_symbol
;
1393 as_bad("Unknown expression");
1394 know(need_pass_2
== 1);
1398 symbolP
->sy_forward
=exp
.X_add_symbol
;
1399 /* as_warn("unknown symbol"); */
1400 /* need_pass_2 = 1; */
1411 * CONStruct more frag of .bytes, or .words etc.
1412 * Should need_pass_2 be 1 then emit no frag(s).
1413 * This understands EXPRESSIONS, as opposed to big_cons().
1417 * This has a split personality. We use expression() to read the
1418 * value. We can detect if the value won't fit in a byte or word.
1419 * But we can't detect if expression() discarded significant digits
1420 * in the case of a long. Not worth the crocks required to fix it.
1423 /* worker to do .byte etc statements */
1424 /* clobbers input_line_pointer, checks */
1427 register unsigned int nbytes
; /* 1=.byte, 2=.word, 4=.long */
1430 register long mask
; /* High-order bits we will left-truncate, */
1431 /* but includes sign bit also. */
1432 register long get
; /* what we get */
1433 register long use
; /* get after truncation. */
1434 register long unmask
; /* what bits we will store */
1436 register segT segment
;
1440 * Input_line_pointer->1st char after pseudo-op-code and could legally
1441 * be a end-of-line. (Or, less legally an eof - which we cope with.)
1443 /* JF << of >= number of bits in the object is undefined. In particular
1444 SPARC (Sun 4) has problems */
1446 if (nbytes
>=sizeof(long)) {
1449 mask
= ~0 << (BITS_PER_CHAR
* nbytes
); /* Don't store these bits. */
1450 } /* bigger than a long */
1452 unmask
= ~mask
; /* Do store these bits. */
1455 "Do this mod if you want every overflow check to assume SIGNED 2's complement data.";
1456 mask
= ~ (unmask
>> 1); /* Includes sign bit now. */
1460 * The following awkward logic is to parse ZERO or more expressions,
1461 * comma seperated. Recall an expression includes its leading &
1462 * trailing blanks. We fake a leading ',' if there is (supposed to
1463 * be) a 1st expression, and keep demanding 1 expression for each ','.
1465 if (is_it_end_of_statement()) {
1466 c
= 0; /* Skip loop. */
1467 input_line_pointer
++; /* Matches end-of-loop 'correction'. */
1470 } /* if the end else fake it */
1474 #ifdef WANT_BITFIELDS
1475 unsigned int bits_available
= BITS_PER_CHAR
* nbytes
;
1476 /* used for error messages and rescanning */
1477 char *hold
= input_line_pointer
;
1478 #endif /* WANT_BITFIELDS */
1480 /* At least scan over the expression. */
1481 segment
= expression(&exp
);
1483 #ifdef WANT_BITFIELDS
1484 /* Some other assemblers, (eg, asm960), allow
1485 bitfields after ".byte" as w:x,y:z, where w and
1486 y are bitwidths and x and y are values. They
1487 then pack them all together. We do a little
1488 better in that we allow them in words, longs,
1489 etc. and we'll pack them in target byte order
1492 The rules are: pack least significat bit first,
1493 if a field doesn't entirely fit, put it in the
1494 next unit. Overflowing the bitfield is
1495 explicitly *not* even a warning. The bitwidth
1496 should be considered a "mask".
1498 FIXME-SOMEDAY: If this is considered generally
1499 useful, this logic should probably be reworked.
1502 if (*input_line_pointer
== ':') { /* bitfields */
1506 unsigned long width
;
1508 if (*input_line_pointer
!= ':') {
1509 input_line_pointer
= hold
;
1511 } /* next piece is not a bitfield */
1513 /* In the general case, we can't allow
1514 full expressions with symbol
1515 differences and such. The relocation
1516 entries for symbols not defined in this
1517 assembly would require arbitrary field
1518 widths, positions, and masks which most
1519 of our current object formats don't
1522 In the specific case where a symbol
1523 *is* defined in this assembly, we
1524 *could* build fixups and track it, but
1525 this could lead to confusion for the
1526 backends. I'm lazy. I'll take any
1527 SEG_ABSOLUTE. I think that means that
1528 you can use a previous .set or
1529 .equ type symbol. xoxorich. */
1531 if (segment
== SEG_ABSENT
) {
1532 as_warn("Using a bit field width of zero.");
1533 exp
.X_add_number
= 0;
1534 segment
= SEG_ABSOLUTE
;
1535 } /* implied zero width bitfield */
1537 if (segment
!= SEG_ABSOLUTE
) {
1538 *input_line_pointer
= '\0';
1539 as_bad("Field width \"%s\" too complex for a bitfield.\n", hold
);
1540 *input_line_pointer
= ':';
1541 demand_empty_rest_of_line();
1545 if ((width
= exp
.X_add_number
) > (BITS_PER_CHAR
* nbytes
)) {
1546 as_warn("Field width %d too big to fit in %d bytes: truncated to %d bits.",
1547 width
, nbytes
, (BITS_PER_CHAR
* nbytes
));
1548 width
= BITS_PER_CHAR
* nbytes
;
1551 if (width
> bits_available
) {
1552 /* FIXME-SOMEDAY: backing up and
1553 reparsing is wasteful */
1554 input_line_pointer
= hold
;
1555 exp
.X_add_number
= value
;
1559 hold
= ++input_line_pointer
; /* skip ':' */
1561 if ((segment
= expression(&exp
)) != SEG_ABSOLUTE
) {
1562 char cache
= *input_line_pointer
;
1564 *input_line_pointer
= '\0';
1565 as_bad("Field value \"%s\" too complex for a bitfield.\n", hold
);
1566 *input_line_pointer
= cache
;
1567 demand_empty_rest_of_line();
1571 value
|= (~(-1 << width
) & exp
.X_add_number
)
1572 << ((BITS_PER_CHAR
* nbytes
) - bits_available
);
1574 if ((bits_available
-= width
) == 0
1575 || is_it_end_of_statement()
1576 || *input_line_pointer
!= ',') {
1578 } /* all the bitfields we're gonna get */
1580 hold
= ++input_line_pointer
;
1581 segment
= expression(&exp
);
1582 } /* forever loop */
1584 exp
.X_add_number
= value
;
1585 segment
= SEG_ABSOLUTE
;
1586 } /* if looks like a bitfield */
1587 #endif /* WANT_BITFIELDS */
1589 if (!need_pass_2
) { /* Still worthwhile making frags. */
1591 /* Don't call this if we are going to junk this pass anyway! */
1592 know(segment
!= SEG_PASS1
);
1594 if (segment
== SEG_DIFFERENCE
&& exp
.X_add_symbol
== NULL
) {
1595 as_bad("Subtracting symbol \"%s\"(segment\"%s\") is too hard. Absolute segment assumed.",
1596 S_GET_NAME(exp
.X_subtract_symbol
),
1597 segment_name(S_GET_SEGMENT(exp
.X_subtract_symbol
)));
1598 segment
= SEG_ABSOLUTE
;
1599 /* Leave exp . X_add_number alone. */
1601 p
= frag_more(nbytes
);
1604 as_bad("%s number invalid. Absolute 0 assumed.",
1605 exp
. X_add_number
> 0 ? "Bignum" : "Floating-Point");
1606 md_number_to_chars (p
, (long)0, nbytes
);
1610 as_warn("0 assumed for missing expression");
1611 exp
. X_add_number
= 0;
1612 know(exp
. X_add_symbol
== NULL
);
1613 /* fall into SEG_ABSOLUTE */
1615 get
= exp
. X_add_number
;
1617 if ((get
& mask
) && (get
& mask
) != mask
)
1618 { /* Leading bits contain both 0s & 1s. */
1619 as_warn("Value 0x%x truncated to 0x%x.", get
, use
);
1621 md_number_to_chars (p
, use
, nbytes
); /* put bytes in right order. */
1624 case SEG_DIFFERENCE
:
1625 #ifndef WORKING_DOT_WORD
1627 struct broken_word
*x
;
1629 x
=(struct broken_word
*)xmalloc(sizeof(struct broken_word
));
1630 x
->next_broken_word
=broken_words
;
1633 x
->word_goes_here
=p
;
1635 x
->add
=exp
.X_add_symbol
;
1636 x
->sub
=exp
.X_subtract_symbol
;
1637 x
->addnum
=exp
.X_add_number
;
1642 /* Else Fall through into. . . */
1647 fix_new_ns32k (frag_now
, p
- frag_now
->fr_literal
, nbytes
,
1648 exp
. X_add_symbol
, exp
. X_subtract_symbol
,
1649 exp
. X_add_number
, 0, 0, 2, 0, 0);
1651 fix_new (frag_now
, p
- frag_now
->fr_literal
, nbytes
,
1652 exp
. X_add_symbol
, exp
. X_subtract_symbol
,
1653 exp
. X_add_number
, 0, RELOC_32
);
1654 #endif /* TC_NS32K */
1656 } /* switch(segment) */
1657 } /* if (!need_pass_2) */
1658 c
= *input_line_pointer
++;
1659 } /* while(c==',') */
1660 input_line_pointer
--; /* Put terminator back into stream. */
1661 demand_empty_rest_of_line();
1667 * CONStruct more frag(s) of .quads, or .octa etc.
1668 * Makes 0 or more new frags.
1669 * If need_pass_2 == 1, generate no frag.
1670 * This understands only bignums, not expressions. Cons() understands
1673 * Constants recognised are '0...'(octal) '0x...'(hex) '...'(decimal).
1675 * This creates objects with struct obstack_control objs, destroying
1676 * any context objs held about a partially completed object. Beware!
1679 * I think it sucks to have 2 different types of integers, with 2
1680 * routines to read them, store them etc.
1681 * It would be nicer to permit bignums in expressions and only
1682 * complain if the result overflowed. However, due to "efficiency"...
1684 /* worker to do .quad etc statements */
1685 /* clobbers input_line_pointer, checks */
1687 /* 8=.quad 16=.octa ... */
1689 void big_cons(nbytes
)
1690 register int nbytes
;
1692 register char c
; /* input_line_pointer->c. */
1694 register long length
; /* Number of chars in an object. */
1695 register int digit
; /* Value of 1 digit. */
1696 register int carry
; /* For multi-precision arithmetic. */
1697 register int work
; /* For multi-precision arithmetic. */
1698 register char * p
; /* For multi-precision arithmetic. */
1700 extern char hex_value
[]; /* In hex_value.c. */
1703 * The following awkward logic is to parse ZERO or more strings,
1704 * comma seperated. Recall an expression includes its leading &
1705 * trailing blanks. We fake a leading ',' if there is (supposed to
1706 * be) a 1st expression, and keep demanding 1 expression for each ','.
1708 if (is_it_end_of_statement())
1710 c
= 0; /* Skip loop. */
1714 c
= ','; /* Do loop. */
1715 -- input_line_pointer
;
1719 ++ input_line_pointer
;
1721 c
= * input_line_pointer
;
1722 /* C contains 1st non-blank character of what we hope is a number. */
1725 c
= * ++ input_line_pointer
;
1726 if (c
== 'x' || c
=='X')
1728 c
= * ++ input_line_pointer
;
1741 * This feature (?) is here to stop people worrying about
1742 * mysterious zero constants: which is what they get when
1743 * they completely omit digits.
1745 if (hex_value
[c
] >= radix
) {
1746 as_bad("Missing digits. 0 assumed.");
1748 bignum_high
= bignum_low
- 1; /* Start constant with 0 chars. */
1749 for(; (digit
= hex_value
[c
]) < radix
; c
= * ++ input_line_pointer
)
1751 /* Multiply existing number by radix, then add digit. */
1753 for (p
=bignum_low
; p
<= bignum_high
; p
++)
1755 work
= (*p
& MASK_CHAR
) * radix
+ carry
;
1756 *p
= work
& MASK_CHAR
;
1757 carry
= work
>> BITS_PER_CHAR
;
1762 * bignum_high
= carry
& MASK_CHAR
;
1763 know((carry
& ~ MASK_CHAR
) == 0);
1766 length
= bignum_high
- bignum_low
+ 1;
1767 if (length
> nbytes
)
1769 as_warn("Most significant bits truncated in integer constant.");
1773 register long leading_zeroes
;
1775 for(leading_zeroes
= nbytes
- length
;
1785 p
= frag_more (nbytes
);
1786 bcopy (bignum_low
, p
, (int)nbytes
);
1788 /* C contains character after number. */
1790 c
= * input_line_pointer
;
1791 /* C contains 1st non-blank character after number. */
1793 demand_empty_rest_of_line();
1796 /* Extend bignum by 1 char. */
1797 static void grow_bignum() {
1798 register long length
;
1801 if (bignum_high
>= bignum_limit
)
1803 length
= bignum_limit
- bignum_low
;
1804 bignum_low
= xrealloc(bignum_low
, length
+ length
);
1805 bignum_high
= bignum_low
+ length
;
1806 bignum_limit
= bignum_low
+ length
+ length
;
1808 } /* grow_bignum(); */
1813 * CONStruct some more frag chars of .floats .ffloats etc.
1814 * Makes 0 or more new frags.
1815 * If need_pass_2 == 1, no frags are emitted.
1816 * This understands only floating literals, not expressions. Sorry.
1818 * A floating constant is defined by atof_generic(), except it is preceded
1819 * by 0d 0f 0g or 0h. After observing the STRANGE way my BSD AS does its
1820 * reading, I decided to be incompatible. This always tries to give you
1821 * rounded bits to the precision of the pseudo-op. Former AS did premature
1822 * truncatation, restored noisy bits instead of trailing 0s AND gave you
1823 * a choice of 2 flavours of noise according to which of 2 floating-point
1824 * scanners you directed AS to use.
1826 * In: input_line_pointer->whitespace before, or '0' of flonum.
1830 void /* JF was static, but can't be if VAX.C is goning to use it */
1831 float_cons(float_type
) /* Worker to do .float etc statements. */
1832 /* Clobbers input_line-pointer, checks end-of-line. */
1833 register int float_type
; /* 'f':.ffloat ... 'F':.float ... */
1837 int length
; /* Number of chars in an object. */
1838 register char * err
; /* Error from scanning floating literal. */
1839 char temp
[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT
];
1842 * The following awkward logic is to parse ZERO or more strings,
1843 * comma seperated. Recall an expression includes its leading &
1844 * trailing blanks. We fake a leading ',' if there is (supposed to
1845 * be) a 1st expression, and keep demanding 1 expression for each ','.
1847 if (is_it_end_of_statement())
1849 c
= 0; /* Skip loop. */
1850 ++ input_line_pointer
; /*->past termintor. */
1854 c
= ','; /* Do loop. */
1858 /* input_line_pointer->1st char of a flonum (we hope!). */
1860 /* Skip any 0{letter} that may be present. Don't even check if the
1861 * letter is legal. Someone may invent a "z" format and this routine
1862 * has no use for such information. Lusers beware: you get
1863 * diagnostics if your input is ill-conditioned.
1866 if (input_line_pointer
[0]=='0' && isalpha(input_line_pointer
[1]))
1867 input_line_pointer
+=2;
1869 err
= md_atof (float_type
, temp
, &length
);
1870 know(length
<= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT
);
1874 as_bad("Bad floating literal: %s", err
);
1875 ignore_rest_of_line();
1876 /* Input_line_pointer->just after end-of-line. */
1877 c
= 0; /* Break out of loop. */
1883 p
= frag_more (length
);
1884 bcopy (temp
, p
, length
);
1887 c
= * input_line_pointer
++;
1888 /* C contains 1st non-white character after number. */
1889 /* input_line_pointer->just after terminator (c). */
1892 -- input_line_pointer
; /*->terminator (is not ','). */
1893 demand_empty_rest_of_line();
1894 } /* float_cons() */
1899 * We read 0 or more ',' seperated, double-quoted strings.
1901 * Caller should have checked need_pass_2 is FALSE because we don't check it.
1905 void stringer(append_zero
) /* Worker to do .ascii etc statements. */
1906 /* Checks end-of-line. */
1907 register int append_zero
; /* 0: don't append '\0', else 1 */
1909 /* register char * p; JF unused */
1910 /* register int length; JF unused */ /* Length of string we read, excluding */
1911 /* trailing '\0' implied by closing quote. */
1912 /* register char * where; JF unused */
1913 /* register fragS * fragP; JF unused */
1914 register unsigned int c
;
1917 * The following awkward logic is to parse ZERO or more strings,
1918 * comma seperated. Recall a string expression includes spaces
1919 * before the opening '\"' and spaces after the closing '\"'.
1920 * We fake a leading ',' if there is (supposed to be)
1921 * a 1st, expression. We keep demanding expressions for each
1924 if (is_it_end_of_statement())
1926 c
= 0; /* Skip loop. */
1927 ++ input_line_pointer
; /* Compensate for end of loop. */
1931 c
= ','; /* Do loop. */
1933 while (c
== ',' || c
== '<' || c
== '"' ) {
1935 switch (*input_line_pointer
) {
1937 ++input_line_pointer
; /*->1st char of string. */
1938 while (is_a_char(c
= next_char_of_string())) {
1939 FRAG_APPEND_1_CHAR(c
);
1942 FRAG_APPEND_1_CHAR(0);
1944 know(input_line_pointer
[-1] == '\"');
1947 input_line_pointer
++;
1948 c
=get_single_number();
1949 FRAG_APPEND_1_CHAR(c
);
1950 if(*input_line_pointer
!= '>') {
1951 as_bad("Expected <nn>");
1953 input_line_pointer
++;
1956 input_line_pointer
++;
1960 c
= *input_line_pointer
;
1963 demand_empty_rest_of_line();
1966 /* FIXME-SOMEDAY: I had trouble here on characters with the
1967 high bits set. We'll probably also have trouble with
1968 multibyte chars, wide chars, etc. Also be careful about
1969 returning values bigger than 1 byte. xoxorich. */
1971 unsigned int next_char_of_string() {
1972 register unsigned int c
;
1974 c
= *input_line_pointer
++ & CHAR_MASK
;
1981 switch (c
= *input_line_pointer
++) {
2010 break; /* As itself. */
2024 for (number
= 0; isdigit(c
); c
= *input_line_pointer
++) {
2025 number
= number
* 8 + c
- '0';
2029 --input_line_pointer
;
2033 /* To be compatible with BSD 4.2 as: give the luser a linefeed!! */
2034 as_warn("Unterminated string: Newline inserted.");
2040 #ifdef ONLY_STANDARD_ESCAPES
2041 as_bad("Bad escaped character in string, '?' assumed");
2043 #endif /* ONLY_STANDARD_ESCAPES */
2046 } /* switch on escaped char */
2051 } /* switch on char */
2053 } /* next_char_of_string() */
2056 get_segmented_expression (expP
)
2057 register expressionS
* expP
;
2059 register segT retval
;
2061 if ((retval
= expression(expP
)) == SEG_PASS1
|| retval
== SEG_ABSENT
|| retval
== SEG_BIG
)
2063 as_bad("Expected address expression: absolute 0 assumed");
2064 retval
= expP
->X_seg
= SEG_ABSOLUTE
;
2065 expP
->X_add_number
= 0;
2066 expP
->X_add_symbol
= expP
->X_subtract_symbol
= 0;
2068 return (retval
); /* SEG_ ABSOLUTE,UNKNOWN,DATA,TEXT,BSS */
2071 static segT
get_known_segmented_expression(expP
)
2072 register expressionS
*expP
;
2074 register segT retval
;
2075 register char * name1
;
2076 register char * name2
;
2078 if ((retval
= get_segmented_expression (expP
)) == SEG_UNKNOWN
)
2080 name1
= expP
->X_add_symbol
? S_GET_NAME(expP
->X_add_symbol
) : "";
2081 name2
= expP
->X_subtract_symbol
?
2082 S_GET_NAME(expP
->X_subtract_symbol
) :
2086 as_warn("Symbols \"%s\" \"%s\" are undefined: absolute 0 assumed.",
2091 as_warn("Symbol \"%s\" undefined: absolute 0 assumed.",
2092 name1
? name1
: name2
);
2094 retval
= expP
->X_seg
= SEG_ABSOLUTE
;
2095 expP
->X_add_number
= 0;
2096 expP
->X_add_symbol
= expP
->X_subtract_symbol
= NULL
;
2098 #ifndef MANY_SEGMENTS
2099 know(retval
== SEG_ABSOLUTE
|| retval
== SEG_DATA
|| retval
== SEG_TEXT
|| retval
== SEG_BSS
|| retval
== SEG_DIFFERENCE
);
2103 } /* get_known_segmented_expression() */
2107 /* static */ long /* JF was static, but can't be if the MD pseudos are to use it */
2108 get_absolute_expression ()
2113 if ((s
= expression(& exp
)) != SEG_ABSOLUTE
)
2115 if (s
!= SEG_ABSENT
)
2117 as_bad("Bad Absolute Expression, absolute 0 assumed.");
2119 exp
. X_add_number
= 0;
2121 return (exp
. X_add_number
);
2124 char /* return terminator */
2125 get_absolute_expression_and_terminator(val_pointer
)
2126 long * val_pointer
; /* return value of expression */
2128 * val_pointer
= get_absolute_expression ();
2129 return (* input_line_pointer
++);
2133 * demand_copy_C_string()
2135 * Like demand_copy_string, but return NULL if the string contains any '\0's.
2136 * Give a warning if that happens.
2139 demand_copy_C_string (len_pointer
)
2144 if ((s
= demand_copy_string(len_pointer
)) != 0)
2148 for (len
= * len_pointer
;
2157 as_bad("This string may not contain \'\\0\'");
2165 * demand_copy_string()
2167 * Demand string, but return a safe (=private) copy of the string.
2168 * Return NULL if we can't read a string here.
2170 static char *demand_copy_string(lenP
)
2173 register unsigned int c
;
2179 if (*input_line_pointer
== '\"') {
2180 input_line_pointer
++; /* Skip opening quote. */
2182 while (is_a_char(c
= next_char_of_string())) {
2183 obstack_1grow(¬es
, c
);
2186 /* JF this next line is so demand_copy_C_string will return a null
2187 termanated string. */
2188 obstack_1grow(¬es
,'\0');
2189 retval
=obstack_finish(¬es
);
2191 as_warn("Missing string");
2193 ignore_rest_of_line();
2197 } /* demand_copy_string() */
2200 * is_it_end_of_statement()
2202 * In: Input_line_pointer->next character.
2204 * Do: Skip input_line_pointer over all whitespace.
2206 * Out: 1 if input_line_pointer->end-of-line.
2208 int is_it_end_of_statement() {
2210 return (is_end_of_line
[* input_line_pointer
]);
2211 } /* is_it_end_of_statement() */
2213 void equals(sym_name
)
2216 register symbolS
*symbolP
; /* symbol we are working with */
2218 input_line_pointer
++;
2219 if (*input_line_pointer
=='=')
2220 input_line_pointer
++;
2222 while(*input_line_pointer
==' ' || *input_line_pointer
=='\t')
2223 input_line_pointer
++;
2225 if (sym_name
[0]=='.' && sym_name
[1]=='\0') {
2226 /* Turn '. = mumble' into a .org mumble */
2227 register segT segment
;
2231 segment
= get_known_segmented_expression(& exp
);
2232 if (! need_pass_2
) {
2233 if (segment
!= now_seg
&& segment
!= SEG_ABSOLUTE
)
2234 as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",
2235 segment_name(segment
),
2236 segment_name(now_seg
));
2237 p
= frag_var(rs_org
, 1, 1, (relax_substateT
)0, exp
.X_add_symbol
,
2238 exp
.X_add_number
, (char *)0);
2240 } /* if (ok to make frag) */
2242 symbolP
=symbol_find_or_make(sym_name
);
2243 pseudo_set(symbolP
);
2247 /* .include -- include a file at this point. */
2259 filename
= demand_copy_string(&i
);
2260 demand_empty_rest_of_line();
2261 path
= xmalloc(i
+ include_dir_maxlen
+ 5 /* slop */);
2262 for (i
= 0; i
< include_dir_count
; i
++) {
2263 strcpy(path
, include_dirs
[i
]);
2265 strcat(path
, filename
);
2266 if (0 != (try = fopen(path
, "r")))
2275 /* malloc Storage leak when file is found on path. FIXME-SOMEDAY. */
2276 newbuf
= input_scrub_include_file (path
, input_line_pointer
);
2277 buffer_limit
= input_scrub_next_buffer (&input_line_pointer
);
2280 void add_include_dir(path
)
2285 if (include_dir_count
== 0)
2287 include_dirs
= (char **)xmalloc (2 * sizeof (*include_dirs
));
2288 include_dirs
[0] = "."; /* Current dir */
2289 include_dir_count
= 2;
2293 include_dir_count
++;
2294 include_dirs
= (char **) realloc(include_dirs
,
2295 include_dir_count
*sizeof (*include_dirs
));
2298 include_dirs
[include_dir_count
-1] = path
; /* New one */
2301 if (i
> include_dir_maxlen
)
2302 include_dir_maxlen
= i
;
2303 } /* add_include_dir() */
2308 extern char is_end_of_line
[];
2310 while (!is_end_of_line
[*input_line_pointer
]) {
2311 ++input_line_pointer
;
2313 ++input_line_pointer
;