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