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