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