* language.h (PRINT_LITERAL_FORM): New macro that takes character
[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
b53ccaac
ILT
1259void s_space(mult)
1260int mult;
1261{
fecd2382
RP
1262 long temp_repeat;
1263 register long temp_fill;
1264 register char *p;
f8701a3f 1265
fecd2382
RP
1266 /* Just like .fill, but temp_size = 1 */
1267 if (get_absolute_expression_and_terminator(& temp_repeat) == ',') {
1268 temp_fill = get_absolute_expression ();
1269 } else {
1270 input_line_pointer --; /* Backup over what was not a ','. */
1271 temp_fill = 0;
1272 }
b53ccaac
ILT
1273 if(mult)
1274 {
1275 temp_fill *= mult;
1276 }
fecd2382
RP
1277 if (temp_repeat <= 0) {
1278 as_warn("Repeat < 0, .space ignored");
1279 ignore_rest_of_line();
1280 return;
1281 }
1282 if (! need_pass_2) {
1283 p = frag_var (rs_fill, 1, 1, (relax_substateT)0, (symbolS *)0,
f8701a3f 1284 temp_repeat, (char *)0);
fecd2382
RP
1285 * p = temp_fill;
1286 }
1287 demand_empty_rest_of_line();
1288} /* s_space() */
1289
1290void
f8701a3f 1291s_text()
fecd2382
RP
1292{
1293 register int temp;
f8701a3f 1294
fecd2382 1295 temp = get_absolute_expression ();
a39116f1
RP
1296#ifdef MANY_SEGMENTS
1297 subseg_new (SEG_E0, (subsegT)temp);
1298#else
fecd2382 1299 subseg_new (SEG_TEXT, (subsegT)temp);
a39116f1 1300#endif
fecd2382
RP
1301 demand_empty_rest_of_line();
1302} /* s_text() */
1303
1304\f
1305/*(JF was static, but can't be if machine dependent pseudo-ops are to use it */
1306
1307void demand_empty_rest_of_line() {
1308 SKIP_WHITESPACE();
1309 if (is_end_of_line [*input_line_pointer]) {
1310 input_line_pointer++;
1311 } else {
1312 ignore_rest_of_line();
1313 }
1314 /* Return having already swallowed end-of-line. */
1315} /* Return pointing just after end-of-line. */
1316
1317void
f8701a3f 1318ignore_rest_of_line() /* For suspect lines: gives warning. */
fecd2382 1319{
f8701a3f
SC
1320 if (! is_end_of_line [* input_line_pointer])
1321 {
1322 if (isprint(*input_line_pointer))
1323 as_bad("Rest of line ignored. First ignored character is `%c'.",
1324 *input_line_pointer);
1325 else
1326 as_bad("Rest of line ignored. First ignored character valued 0x%x.",
1327 *input_line_pointer);
1328 while (input_line_pointer < buffer_limit
1329 && ! is_end_of_line [* input_line_pointer])
1330 {
1331 input_line_pointer ++;
1332 }
1333 }
1334 input_line_pointer ++; /* Return pointing just after end-of-line. */
1335 know(is_end_of_line [input_line_pointer [-1]]);
fecd2382
RP
1336}
1337
1338/*
1339 * pseudo_set()
1340 *
1341 * In: Pointer to a symbol.
1342 * Input_line_pointer->expression.
1343 *
1344 * Out: Input_line_pointer->just after any whitespace after expression.
1345 * Tried to set symbol to value of expression.
1346 * Will change symbols type, value, and frag;
1347 * May set need_pass_2 == 1.
1348 */
1349void
f8701a3f
SC
1350pseudo_set (symbolP)
1351 symbolS * symbolP;
fecd2382 1352{
f8701a3f
SC
1353 expressionS exp;
1354 register segT segment;
fecd2382 1355#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
f8701a3f 1356 int ext;
fecd2382 1357#endif /* OBJ_AOUT or OBJ_BOUT */
f8701a3f
SC
1358
1359 know(symbolP); /* NULL pointer is logic error. */
fecd2382 1360#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
f8701a3f 1361 ext=S_IS_EXTERNAL(symbolP);
fecd2382 1362#endif /* OBJ_AOUT or OBJ_BOUT */
f8701a3f
SC
1363
1364 if ((segment = expression(& exp)) == SEG_ABSENT)
1365 {
1366 as_bad("Missing expression: absolute 0 assumed");
1367 exp . X_seg = SEG_ABSOLUTE;
1368 exp . X_add_number = 0;
1369 }
1370
1371 switch (segment)
1372 {
1373 case SEG_REGISTER:
1374 S_SET_SEGMENT(symbolP, SEG_REGISTER);
1375 S_SET_VALUE(symbolP, exp.X_add_number);
1376 symbolP->sy_frag = & zero_address_frag;
1377 break;
1378
1379 case SEG_BIG:
1380 as_bad("%s number invalid. Absolute 0 assumed.",
1381 exp . X_add_number > 0 ? "Bignum" : "Floating-Point");
1382 S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
fecd2382 1383#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
f8701a3f
SC
1384 ext ? S_SET_EXTERNAL(symbolP) :
1385 S_CLEAR_EXTERNAL(symbolP);
fecd2382 1386#endif /* OBJ_AOUT or OBJ_BOUT */
f8701a3f
SC
1387 S_SET_VALUE(symbolP, 0);
1388 symbolP->sy_frag = & zero_address_frag;
1389 break;
1390
1391 case SEG_ABSENT:
1392 as_warn("No expression: Using absolute 0");
1393 S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
fecd2382 1394#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
f8701a3f
SC
1395 ext ? S_SET_EXTERNAL(symbolP) :
1396 S_CLEAR_EXTERNAL(symbolP);
fecd2382 1397#endif /* OBJ_AOUT or OBJ_BOUT */
f8701a3f
SC
1398 S_SET_VALUE(symbolP, 0);
1399 symbolP->sy_frag = & zero_address_frag;
1400 break;
1401
1402 case SEG_DIFFERENCE:
1403 if (exp.X_add_symbol && exp.X_subtract_symbol
1404 && (S_GET_SEGMENT(exp.X_add_symbol) ==
1405 S_GET_SEGMENT(exp.X_subtract_symbol))) {
1406 if (exp.X_add_symbol->sy_frag != exp.X_subtract_symbol->sy_frag) {
1407 as_bad("Unknown expression: symbols %s and %s are in different frags.",
1408 S_GET_NAME(exp.X_add_symbol), S_GET_NAME(exp.X_subtract_symbol));
1409 need_pass_2++;
1410 }
1411 exp.X_add_number+=S_GET_VALUE(exp.X_add_symbol) -
1412 S_GET_VALUE(exp.X_subtract_symbol);
1413 } else
1414 as_bad("Complex expression. Absolute segment assumed.");
1415 case SEG_ABSOLUTE:
1416 S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
fecd2382 1417#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
f8701a3f
SC
1418 ext ? S_SET_EXTERNAL(symbolP) :
1419 S_CLEAR_EXTERNAL(symbolP);
fecd2382 1420#endif /* OBJ_AOUT or OBJ_BOUT */
f8701a3f
SC
1421 S_SET_VALUE(symbolP, exp.X_add_number);
1422 symbolP->sy_frag = & zero_address_frag;
1423 break;
1424
1425 default:
a39116f1 1426#ifdef MANY_SEGMENTS
f8701a3f 1427 S_SET_SEGMENT(symbolP, segment);
a39116f1 1428#else
f8701a3f
SC
1429 switch(segment) {
1430 case SEG_DATA: S_SET_SEGMENT(symbolP, SEG_DATA); break;
1431 case SEG_TEXT: S_SET_SEGMENT(symbolP, SEG_TEXT); break;
1432 case SEG_BSS: S_SET_SEGMENT(symbolP, SEG_BSS); break;
1433
1434 default: as_fatal("failed sanity check.");
1435 } /* switch on segment */
a39116f1 1436#endif
fecd2382 1437#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
f8701a3f
SC
1438 if (ext) {
1439 S_SET_EXTERNAL(symbolP);
1440 } else {
1441 S_CLEAR_EXTERNAL(symbolP);
1442 } /* if external */
fecd2382 1443#endif /* OBJ_AOUT or OBJ_BOUT */
f8701a3f
SC
1444
1445 S_SET_VALUE(symbolP, exp.X_add_number + S_GET_VALUE(exp.X_add_symbol));
1446 symbolP->sy_frag = exp . X_add_symbol->sy_frag;
1447 break;
1448
1449 case SEG_PASS1: /* Not an error. Just try another pass. */
1450 symbolP->sy_forward=exp.X_add_symbol;
1451 as_bad("Unknown expression");
1452 know(need_pass_2 == 1);
1453 break;
1454
1455 case SEG_UNKNOWN:
1456 symbolP->sy_forward=exp.X_add_symbol;
1457 /* as_warn("unknown symbol"); */
1458 /* need_pass_2 = 1; */
1459 break;
1460
1461
1462
1463 }
fecd2382
RP
1464}
1465\f
1466/*
1467 * cons()
1468 *
1469 * CONStruct more frag of .bytes, or .words etc.
1470 * Should need_pass_2 be 1 then emit no frag(s).
1471 * This understands EXPRESSIONS, as opposed to big_cons().
1472 *
1473 * Bug (?)
1474 *
1475 * This has a split personality. We use expression() to read the
1476 * value. We can detect if the value won't fit in a byte or word.
1477 * But we can't detect if expression() discarded significant digits
1478 * in the case of a long. Not worth the crocks required to fix it.
1479 */
1480
f8701a3f
SC
1481 /* worker to do .byte etc statements */
1482 /* clobbers input_line_pointer, checks */
1483 /* end-of-line. */
fecd2382
RP
1484void cons(nbytes)
1485register unsigned int nbytes; /* 1=.byte, 2=.word, 4=.long */
1486{
f8701a3f
SC
1487 register char c;
1488 register long mask; /* High-order bits we will left-truncate, */
1489 /* but includes sign bit also. */
1490 register long get; /* what we get */
1491 register long use; /* get after truncation. */
1492 register long unmask; /* what bits we will store */
1493 register char * p;
1494 register segT segment;
1495 expressionS exp;
1496
1497 /*
1498 * Input_line_pointer->1st char after pseudo-op-code and could legally
1499 * be a end-of-line. (Or, less legally an eof - which we cope with.)
1500 */
1501 /* JF << of >= number of bits in the object is undefined. In particular
1502 SPARC (Sun 4) has problems */
1503
1504 if (nbytes>=sizeof(long)) {
1505 mask = 0;
1506 } else {
1507 mask = ~0 << (BITS_PER_CHAR * nbytes); /* Don't store these bits. */
1508 } /* bigger than a long */
1509
1510 unmask = ~mask; /* Do store these bits. */
1511
fecd2382 1512#ifdef NEVER
f8701a3f
SC
1513 "Do this mod if you want every overflow check to assume SIGNED 2's complement data.";
1514 mask = ~ (unmask >> 1); /* Includes sign bit now. */
fecd2382 1515#endif
f8701a3f
SC
1516
1517 /*
1518 * The following awkward logic is to parse ZERO or more expressions,
1519 * comma seperated. Recall an expression includes its leading &
1520 * trailing blanks. We fake a leading ',' if there is (supposed to
1521 * be) a 1st expression, and keep demanding 1 expression for each ','.
1522 */
1523 if (is_it_end_of_statement()) {
1524 c = 0; /* Skip loop. */
1525 input_line_pointer++; /* Matches end-of-loop 'correction'. */
1526 } else {
1527 c = ',';
1528 } /* if the end else fake it */
1529
1530 /* Do loop. */
1531 while (c == ',') {
fecd2382 1532#ifdef WANT_BITFIELDS
f8701a3f
SC
1533 unsigned int bits_available = BITS_PER_CHAR * nbytes;
1534 /* used for error messages and rescanning */
1535 char *hold = input_line_pointer;
fecd2382 1536#endif /* WANT_BITFIELDS */
f8701a3f
SC
1537#ifdef MRI
1538 if (*input_line_pointer == '\'')
1539 {
1540 /* An MRI style string, cut into as many bytes as will fit
1541 into a nbyte chunk, left justify if necessary, and sepatate
1542 with commas so we can try again later */
1543 int scan = 0;
1544 unsigned int result = 0;
1545 input_line_pointer++;
1546 for (scan = 0; scan < nbytes; scan++)
1547 {
1548 if (*input_line_pointer == '\'')
1549 {
1550 if (input_line_pointer[1] == '\'')
1551 {
1552 input_line_pointer++;
1553 }
1554 else
1555 break;
1556 }
1557 result = (result << 8) | (*input_line_pointer++);
1558 }
1559
1560 /* Left justify */
1561 while (scan < nbytes)
1562 {
1563 result <<=8;
1564 scan++;
1565 }
1566 /* Create correct expression */
1567 exp.X_add_symbol = 0;
1568 exp.X_add_number = result;
1569 exp.X_seg = segment = SEG_ABSOLUTE;
1570 /* Fake it so that we can read the next char too */
1571 if (input_line_pointer[0] != '\'' ||
1572 (input_line_pointer[0] == '\'' && input_line_pointer[1] == '\''))
1573 {
1574 input_line_pointer-=2;
1575 input_line_pointer[0] = ',';
1576 input_line_pointer[1] = '\'';
1577 }
1578 else
1579 input_line_pointer++;
1580
1581 }
1582 else
1583#endif
1584 /* At least scan over the expression. */
1585 segment = expression(&exp);
1586
a39116f1 1587#ifdef WANT_BITFIELDS
f8701a3f
SC
1588 /* Some other assemblers, (eg, asm960), allow
1589 bitfields after ".byte" as w:x,y:z, where w and
1590 y are bitwidths and x and y are values. They
1591 then pack them all together. We do a little
1592 better in that we allow them in words, longs,
1593 etc. and we'll pack them in target byte order
1594 for you.
1595
1596 The rules are: pack least significat bit first,
1597 if a field doesn't entirely fit, put it in the
1598 next unit. Overflowing the bitfield is
1599 explicitly *not* even a warning. The bitwidth
1600 should be considered a "mask".
1601
1602 FIXME-SOMEDAY: If this is considered generally
1603 useful, this logic should probably be reworked.
1604 xoxorich. */
1605
1606 if (*input_line_pointer == ':') { /* bitfields */
1607 long value = 0;
1608
1609 for (;;) {
1610 unsigned long width;
1611
1612 if (*input_line_pointer != ':') {
1613 input_line_pointer = hold;
1614 break;
1615 } /* next piece is not a bitfield */
1616
1617 /* In the general case, we can't allow
1618 full expressions with symbol
1619 differences and such. The relocation
1620 entries for symbols not defined in this
1621 assembly would require arbitrary field
1622 widths, positions, and masks which most
1623 of our current object formats don't
1624 support.
1625
1626 In the specific case where a symbol
1627 *is* defined in this assembly, we
1628 *could* build fixups and track it, but
1629 this could lead to confusion for the
1630 backends. I'm lazy. I'll take any
1631 SEG_ABSOLUTE. I think that means that
1632 you can use a previous .set or
1633 .equ type symbol. xoxorich. */
1634
1635 if (segment == SEG_ABSENT) {
1636 as_warn("Using a bit field width of zero.");
1637 exp.X_add_number = 0;
1638 segment = SEG_ABSOLUTE;
1639 } /* implied zero width bitfield */
1640
1641 if (segment != SEG_ABSOLUTE) {
1642 *input_line_pointer = '\0';
1643 as_bad("Field width \"%s\" too complex for a bitfield.\n", hold);
1644 *input_line_pointer = ':';
1645 demand_empty_rest_of_line();
1646 return;
1647 } /* too complex */
1648
1649 if ((width = exp.X_add_number) > (BITS_PER_CHAR * nbytes)) {
1650 as_warn("Field width %d too big to fit in %d bytes: truncated to %d bits.",
1651 width, nbytes, (BITS_PER_CHAR * nbytes));
1652 width = BITS_PER_CHAR * nbytes;
1653 } /* too big */
1654
1655 if (width > bits_available) {
1656 /* FIXME-SOMEDAY: backing up and
1657 reparsing is wasteful */
1658 input_line_pointer = hold;
1659 exp.X_add_number = value;
1660 break;
1661 } /* won't fit */
1662
1663 hold = ++input_line_pointer; /* skip ':' */
1664
1665 if ((segment = expression(&exp)) != SEG_ABSOLUTE) {
1666 char cache = *input_line_pointer;
1667
1668 *input_line_pointer = '\0';
1669 as_bad("Field value \"%s\" too complex for a bitfield.\n", hold);
1670 *input_line_pointer = cache;
1671 demand_empty_rest_of_line();
1672 return;
1673 } /* too complex */
1674
1675 value |= (~(-1 << width) & exp.X_add_number)
1676 << ((BITS_PER_CHAR * nbytes) - bits_available);
1677
1678 if ((bits_available -= width) == 0
1679 || is_it_end_of_statement()
1680 || *input_line_pointer != ',') {
1681 break;
1682 } /* all the bitfields we're gonna get */
1683
1684 hold = ++input_line_pointer;
1685 segment = expression(&exp);
1686 } /* forever loop */
1687
1688 exp.X_add_number = value;
1689 segment = SEG_ABSOLUTE;
1690 } /* if looks like a bitfield */
a39116f1 1691#endif /* WANT_BITFIELDS */
f8701a3f
SC
1692
1693 if (!need_pass_2) { /* Still worthwhile making frags. */
1694
1695 /* Don't call this if we are going to junk this pass anyway! */
1696 know(segment != SEG_PASS1);
1697
1698 if (segment == SEG_DIFFERENCE && exp.X_add_symbol == NULL) {
1699 as_bad("Subtracting symbol \"%s\"(segment\"%s\") is too hard. Absolute segment assumed.",
1700 S_GET_NAME(exp.X_subtract_symbol),
1701 segment_name(S_GET_SEGMENT(exp.X_subtract_symbol)));
1702 segment = SEG_ABSOLUTE;
1703 /* Leave exp . X_add_number alone. */
1704 }
1705 p = frag_more(nbytes);
1706 switch (segment) {
1707 case SEG_BIG:
1708 as_bad("%s number invalid. Absolute 0 assumed.",
1709 exp . X_add_number > 0 ? "Bignum" : "Floating-Point");
1710 md_number_to_chars (p, (long)0, nbytes);
1711 break;
1712
1713 case SEG_ABSENT:
1714 as_warn("0 assumed for missing expression");
1715 exp . X_add_number = 0;
1716 know(exp . X_add_symbol == NULL);
1717 /* fall into SEG_ABSOLUTE */
1718 case SEG_ABSOLUTE:
1719 get = exp . X_add_number;
1720 use = get & unmask;
1721 if ((get & mask) && (get & mask) != mask)
1722 { /* Leading bits contain both 0s & 1s. */
1723 as_warn("Value 0x%x truncated to 0x%x.", get, use);
1724 }
1725 md_number_to_chars (p, use, nbytes); /* put bytes in right order. */
1726 break;
1727
1728 case SEG_DIFFERENCE:
fecd2382 1729#ifndef WORKING_DOT_WORD
f8701a3f
SC
1730 if (nbytes==2) {
1731 struct broken_word *x;
1732
1733 x=(struct broken_word *)xmalloc(sizeof(struct broken_word));
1734 x->next_broken_word=broken_words;
1735 broken_words=x;
1736 x->frag=frag_now;
1737 x->word_goes_here=p;
1738 x->dispfrag=0;
1739 x->add=exp.X_add_symbol;
1740 x->sub=exp.X_subtract_symbol;
1741 x->addnum=exp.X_add_number;
1742 x->added=0;
1743 new_broken_words++;
1744 break;
1745 }
1746 /* Else Fall through into. . . */
fecd2382 1747#endif
f8701a3f
SC
1748 default:
1749 case SEG_UNKNOWN:
fecd2382 1750#ifdef TC_NS32K
f8701a3f
SC
1751 fix_new_ns32k (frag_now, p - frag_now->fr_literal, nbytes,
1752 exp . X_add_symbol, exp . X_subtract_symbol,
1753 exp . X_add_number, 0, 0, 2, 0, 0);
fecd2382 1754#else
f8701a3f
SC
1755# if defined(TC_SPARC) || defined(TC_A29K)
1756 fix_new (frag_now, p - frag_now->fr_literal, nbytes,
1757 exp . X_add_symbol, exp . X_subtract_symbol,
1758 exp . X_add_number, 0, RELOC_32);
1759# else
1760# if defined(TC_H8300)
1761 fix_new (frag_now, p - frag_now->fr_literal, nbytes,
1762 exp . X_add_symbol, exp . X_subtract_symbol,
1763 exp . X_add_number, 0, R_RELWORD);
1764
1765# else
1766 fix_new (frag_now, p - frag_now->fr_literal, nbytes,
1767 exp . X_add_symbol, exp . X_subtract_symbol,
1768 exp . X_add_number, 0, 0);
1769
1770# endif /* tc_h8300 */
1771# endif /* tc_sparc|tc_a29k */
fecd2382 1772#endif /* TC_NS32K */
f8701a3f
SC
1773 break;
1774 } /* switch(segment) */
1775 } /* if (!need_pass_2) */
1776 c = *input_line_pointer++;
1777 } /* while(c==',') */
1778 input_line_pointer--; /* Put terminator back into stream. */
1779 demand_empty_rest_of_line();
fecd2382
RP
1780} /* cons() */
1781\f
1782/*
1783 * big_cons()
1784 *
1785 * CONStruct more frag(s) of .quads, or .octa etc.
1786 * Makes 0 or more new frags.
1787 * If need_pass_2 == 1, generate no frag.
1788 * This understands only bignums, not expressions. Cons() understands
1789 * expressions.
1790 *
1791 * Constants recognised are '0...'(octal) '0x...'(hex) '...'(decimal).
1792 *
1793 * This creates objects with struct obstack_control objs, destroying
1794 * any context objs held about a partially completed object. Beware!
1795 *
1796 *
1797 * I think it sucks to have 2 different types of integers, with 2
1798 * routines to read them, store them etc.
1799 * It would be nicer to permit bignums in expressions and only
1800 * complain if the result overflowed. However, due to "efficiency"...
1801 */
1802/* worker to do .quad etc statements */
1803/* clobbers input_line_pointer, checks */
1804/* end-of-line. */
1805/* 8=.quad 16=.octa ... */
1806
1807void big_cons(nbytes)
f8701a3f 1808 register int nbytes;
fecd2382 1809{
f8701a3f
SC
1810 register char c; /* input_line_pointer->c. */
1811 register int radix;
1812 register long length; /* Number of chars in an object. */
1813 register int digit; /* Value of 1 digit. */
1814 register int carry; /* For multi-precision arithmetic. */
1815 register int work; /* For multi-precision arithmetic. */
1816 register char * p; /* For multi-precision arithmetic. */
1817
1818 extern char hex_value[]; /* In hex_value.c. */
1819
1820 /*
1821 * The following awkward logic is to parse ZERO or more strings,
1822 * comma seperated. Recall an expression includes its leading &
1823 * trailing blanks. We fake a leading ',' if there is (supposed to
1824 * be) a 1st expression, and keep demanding 1 expression for each ','.
1825 */
1826 if (is_it_end_of_statement())
1827 {
1828 c = 0; /* Skip loop. */
1829 }
1830 else
1831 {
1832 c = ','; /* Do loop. */
1833 -- input_line_pointer;
1834 }
1835 while (c == ',')
1836 {
1837 ++ input_line_pointer;
1838 SKIP_WHITESPACE();
1839 c = * input_line_pointer;
1840 /* C contains 1st non-blank character of what we hope is a number. */
1841 if (c == '0')
1842 {
1843 c = * ++ input_line_pointer;
1844 if (c == 'x' || c=='X')
fecd2382 1845 {
f8701a3f
SC
1846 c = * ++ input_line_pointer;
1847 radix = 16;
fecd2382 1848 }
f8701a3f 1849 else
fecd2382 1850 {
f8701a3f 1851 radix = 8;
fecd2382 1852 }
f8701a3f
SC
1853 }
1854 else
1855 {
1856 radix = 10;
1857 }
1858 /*
1859 * This feature (?) is here to stop people worrying about
1860 * mysterious zero constants: which is what they get when
1861 * they completely omit digits.
1862 */
1863 if (hex_value[c] >= radix) {
1864 as_bad("Missing digits. 0 assumed.");
1865 }
1866 bignum_high = bignum_low - 1; /* Start constant with 0 chars. */
1867 for(; (digit = hex_value [c]) < radix; c = * ++ input_line_pointer)
1868 {
1869 /* Multiply existing number by radix, then add digit. */
1870 carry = digit;
1871 for (p=bignum_low; p <= bignum_high; p++)
fecd2382 1872 {
f8701a3f
SC
1873 work = (*p & MASK_CHAR) * radix + carry;
1874 *p = work & MASK_CHAR;
1875 carry = work >> BITS_PER_CHAR;
fecd2382 1876 }
f8701a3f
SC
1877 if (carry)
1878 {
1879 grow_bignum();
1880 * bignum_high = carry & MASK_CHAR;
1881 know((carry & ~ MASK_CHAR) == 0);
1882 }
1883 }
1884 length = bignum_high - bignum_low + 1;
1885 if (length > nbytes)
1886 {
1887 as_warn("Most significant bits truncated in integer constant.");
1888 }
1889 else
1890 {
1891 register long leading_zeroes;
fecd2382 1892
f8701a3f
SC
1893 for(leading_zeroes = nbytes - length;
1894 leading_zeroes;
1895 leading_zeroes --)
a39116f1 1896 {
f8701a3f
SC
1897 grow_bignum();
1898 * bignum_high = 0;
a39116f1 1899 }
f8701a3f
SC
1900 }
1901 if (! need_pass_2)
1902 {
1903 p = frag_more (nbytes);
1904 bcopy (bignum_low, p, (int)nbytes);
1905 }
1906 /* C contains character after number. */
1907 SKIP_WHITESPACE();
1908 c = * input_line_pointer;
1909 /* C contains 1st non-blank character after number. */
1910 }
1911 demand_empty_rest_of_line();
1912} /* big_cons() */
1913
1914 /* Extend bignum by 1 char. */
1915static void grow_bignum() {
1916 register long length;
1917
1918 bignum_high ++;
1919 if (bignum_high >= bignum_limit)
1920 {
1921 length = bignum_limit - bignum_low;
1922 bignum_low = xrealloc(bignum_low, length + length);
1923 bignum_high = bignum_low + length;
1924 bignum_limit = bignum_low + length + length;
1925 }
fecd2382
RP
1926} /* grow_bignum(); */
1927\f
1928/*
1929 * float_cons()
1930 *
1931 * CONStruct some more frag chars of .floats .ffloats etc.
1932 * Makes 0 or more new frags.
1933 * If need_pass_2 == 1, no frags are emitted.
1934 * This understands only floating literals, not expressions. Sorry.
1935 *
1936 * A floating constant is defined by atof_generic(), except it is preceded
1937 * by 0d 0f 0g or 0h. After observing the STRANGE way my BSD AS does its
1938 * reading, I decided to be incompatible. This always tries to give you
1939 * rounded bits to the precision of the pseudo-op. Former AS did premature
1940 * truncatation, restored noisy bits instead of trailing 0s AND gave you
1941 * a choice of 2 flavours of noise according to which of 2 floating-point
1942 * scanners you directed AS to use.
1943 *
1944 * In: input_line_pointer->whitespace before, or '0' of flonum.
1945 *
1946 */
1947
1948void /* JF was static, but can't be if VAX.C is goning to use it */
f8701a3f
SC
1949float_cons(float_type) /* Worker to do .float etc statements. */
1950 /* Clobbers input_line-pointer, checks end-of-line. */
1951 register int float_type; /* 'f':.ffloat ... 'F':.float ... */
fecd2382 1952{
f8701a3f
SC
1953 register char * p;
1954 register char c;
1955 int length; /* Number of chars in an object. */
1956 register char * err; /* Error from scanning floating literal. */
1957 char temp [MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
1958
1959 /*
1960 * The following awkward logic is to parse ZERO or more strings,
1961 * comma seperated. Recall an expression includes its leading &
1962 * trailing blanks. We fake a leading ',' if there is (supposed to
1963 * be) a 1st expression, and keep demanding 1 expression for each ','.
1964 */
1965 if (is_it_end_of_statement())
1966 {
1967 c = 0; /* Skip loop. */
1968 ++ input_line_pointer; /*->past termintor. */
1969 }
1970 else
1971 {
1972 c = ','; /* Do loop. */
1973 }
1974 while (c == ',')
1975 {
1976 /* input_line_pointer->1st char of a flonum (we hope!). */
1977 SKIP_WHITESPACE();
1978 /* Skip any 0{letter} that may be present. Don't even check if the
1979 * letter is legal. Someone may invent a "z" format and this routine
1980 * has no use for such information. Lusers beware: you get
1981 * diagnostics if your input is ill-conditioned.
1982 */
1983
1984 if (input_line_pointer[0]=='0' && isalpha(input_line_pointer[1]))
1985 input_line_pointer+=2;
1986
1987 err = md_atof (float_type, temp, &length);
1988 know(length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
1989 know(length > 0);
1990 if (* err)
1991 {
1992 as_bad("Bad floating literal: %s", err);
1993 ignore_rest_of_line();
1994 /* Input_line_pointer->just after end-of-line. */
1995 c = 0; /* Break out of loop. */
1996 }
1997 else
1998 {
1999 if (! need_pass_2)
a39116f1 2000 {
f8701a3f
SC
2001 p = frag_more (length);
2002 bcopy (temp, p, length);
a39116f1 2003 }
f8701a3f
SC
2004 SKIP_WHITESPACE();
2005 c = * input_line_pointer ++;
2006 /* C contains 1st non-white character after number. */
2007 /* input_line_pointer->just after terminator (c). */
542e1629 2008 }
f8701a3f
SC
2009 }
2010 -- input_line_pointer; /*->terminator (is not ','). */
2011 demand_empty_rest_of_line();
2012} /* float_cons() */
fecd2382
RP
2013\f
2014/*
2015 * stringer()
2016 *
2017 * We read 0 or more ',' seperated, double-quoted strings.
2018 *
2019 * Caller should have checked need_pass_2 is FALSE because we don't check it.
2020 */
a39116f1
RP
2021
2022
2023void stringer(append_zero ) /* Worker to do .ascii etc statements. */
f8701a3f
SC
2024 /* Checks end-of-line. */
2025 register int append_zero; /* 0: don't append '\0', else 1 */
fecd2382 2026{
f8701a3f
SC
2027 /* register char * p; JF unused */
2028 /* register int length; JF unused */ /* Length of string we read, excluding */
2029 /* trailing '\0' implied by closing quote. */
2030 /* register char * where; JF unused */
2031 /* register fragS * fragP; JF unused */
2032 register unsigned int c;
2033
2034 /*
2035 * The following awkward logic is to parse ZERO or more strings,
2036 * comma seperated. Recall a string expression includes spaces
2037 * before the opening '\"' and spaces after the closing '\"'.
2038 * We fake a leading ',' if there is (supposed to be)
2039 * a 1st, expression. We keep demanding expressions for each
2040 * ','.
2041 */
2042 if (is_it_end_of_statement())
2043 {
2044 c = 0; /* Skip loop. */
2045 ++ input_line_pointer; /* Compensate for end of loop. */
2046 }
2047 else
2048 {
2049 c = ','; /* Do loop. */
2050 }
2051 while (c == ',' || c == '<' || c == '"' ) {
2052 SKIP_WHITESPACE();
2053 switch (*input_line_pointer) {
2054 case '\"':
2055 ++input_line_pointer; /*->1st char of string. */
2056 while (is_a_char(c = next_char_of_string())) {
2057 FRAG_APPEND_1_CHAR(c);
2058 }
2059 if (append_zero) {
2060 FRAG_APPEND_1_CHAR(0);
2061 }
2062 know(input_line_pointer [-1] == '\"');
2063 break;
2064 case '<':
2065 input_line_pointer++;
2066 c =get_single_number();
2067 FRAG_APPEND_1_CHAR(c);
2068 if(*input_line_pointer != '>') {
2069 as_bad("Expected <nn>");
2070 }
2071 input_line_pointer++;
2072 break;
2073 case ',':
2074 input_line_pointer++;
2075 break;
2076 }
2077 SKIP_WHITESPACE();
2078 c = *input_line_pointer;
2079 }
2080
2081 demand_empty_rest_of_line();
fecd2382
RP
2082} /* stringer() */
2083\f
f8701a3f
SC
2084 /* FIXME-SOMEDAY: I had trouble here on characters with the
2085 high bits set. We'll probably also have trouble with
2086 multibyte chars, wide chars, etc. Also be careful about
2087 returning values bigger than 1 byte. xoxorich. */
fecd2382 2088
f8701a3f 2089 unsigned int next_char_of_string() {
fecd2382
RP
2090 register unsigned int c;
2091
2092 c = *input_line_pointer++ & CHAR_MASK;
2093 switch (c) {
2094 case '\"':
2095 c = NOT_A_CHAR;
2096 break;
2097
2098 case '\\':
2099 switch (c = *input_line_pointer++) {
2100 case 'b':
2101 c = '\b';
2102 break;
2103
2104 case 'f':
2105 c = '\f';
2106 break;
2107
2108 case 'n':
2109 c = '\n';
2110 break;
2111
2112 case 'r':
2113 c = '\r';
2114 break;
2115
2116 case 't':
2117 c = '\t';
2118 break;
2119
2120#ifdef BACKSLASH_V
2121 case 'v':
2122 c = '\013';
2123 break;
2124#endif
2125
2126 case '\\':
2127 case '"':
2128 break; /* As itself. */
2129
2130 case '0':
2131 case '1':
2132 case '2':
2133 case '3':
2134 case '4':
2135 case '5':
2136 case '6':
2137 case '7':
2138 case '8':
2139 case '9': {
2140 long number;
2141
2142 for (number = 0; isdigit(c); c = *input_line_pointer++) {
2143 number = number * 8 + c - '0';
2144 }
2145 c = number & 0xff;
2146 }
2147 --input_line_pointer;
2148 break;
2149
2150 case '\n':
2151 /* To be compatible with BSD 4.2 as: give the luser a linefeed!! */
2152 as_warn("Unterminated string: Newline inserted.");
2153 c = '\n';
2154 break;
2155
2156 default:
2157
2158#ifdef ONLY_STANDARD_ESCAPES
2159 as_bad("Bad escaped character in string, '?' assumed");
2160 c = '?';
2161#endif /* ONLY_STANDARD_ESCAPES */
2162
2163 break;
2164 } /* switch on escaped char */
2165 break;
2166
2167 default:
2168 break;
2169 } /* switch on char */
2170 return(c);
2171} /* next_char_of_string() */
2172\f
2173static segT
f8701a3f
SC
2174get_segmented_expression (expP)
2175 register expressionS * expP;
fecd2382 2176{
f8701a3f
SC
2177 register segT retval;
2178
2179 if ((retval = expression(expP)) == SEG_PASS1 || retval == SEG_ABSENT || retval == SEG_BIG)
2180 {
2181 as_bad("Expected address expression: absolute 0 assumed");
2182 retval = expP->X_seg = SEG_ABSOLUTE;
2183 expP->X_add_number = 0;
2184 expP->X_add_symbol = expP->X_subtract_symbol = 0;
2185 }
2186 return (retval); /* SEG_ ABSOLUTE,UNKNOWN,DATA,TEXT,BSS */
fecd2382
RP
2187}
2188
2189static segT get_known_segmented_expression(expP)
2190register expressionS *expP;
2191{
f8701a3f
SC
2192 register segT retval;
2193 register char * name1;
2194 register char * name2;
2195
2196 if ((retval = get_segmented_expression (expP)) == SEG_UNKNOWN)
2197 {
2198 name1 = expP->X_add_symbol ? S_GET_NAME(expP->X_add_symbol) : "";
2199 name2 = expP->X_subtract_symbol ?
2200 S_GET_NAME(expP->X_subtract_symbol) :
2201 "";
2202 if (name1 && name2)
2203 {
2204 as_warn("Symbols \"%s\" \"%s\" are undefined: absolute 0 assumed.",
2205 name1, name2);
2206 }
2207 else
2208 {
2209 as_warn("Symbol \"%s\" undefined: absolute 0 assumed.",
2210 name1 ? name1 : name2);
2211 }
2212 retval = expP->X_seg = SEG_ABSOLUTE;
2213 expP->X_add_number = 0;
2214 expP->X_add_symbol = expP->X_subtract_symbol = NULL;
2215 }
a39116f1 2216#ifndef MANY_SEGMENTS
f8701a3f 2217 know(retval == SEG_ABSOLUTE || retval == SEG_DATA || retval == SEG_TEXT || retval == SEG_BSS || retval == SEG_DIFFERENCE);
a39116f1 2218#endif
f8701a3f
SC
2219 return (retval);
2220
fecd2382
RP
2221} /* get_known_segmented_expression() */
2222
2223
2224
2225/* static */ long /* JF was static, but can't be if the MD pseudos are to use it */
f8701a3f 2226get_absolute_expression ()
fecd2382 2227{
f8701a3f
SC
2228 expressionS exp;
2229 register segT s;
2230
2231 if ((s = expression(& exp)) != SEG_ABSOLUTE)
2232 {
2233 if (s != SEG_ABSENT)
2234 {
2235 as_bad("Bad Absolute Expression, absolute 0 assumed.");
2236 }
2237 exp . X_add_number = 0;
2238 }
2239 return (exp . X_add_number);
fecd2382
RP
2240}
2241
2242char /* return terminator */
f8701a3f
SC
2243get_absolute_expression_and_terminator(val_pointer)
2244 long * val_pointer; /* return value of expression */
fecd2382 2245{
f8701a3f
SC
2246 * val_pointer = get_absolute_expression ();
2247 return (* input_line_pointer ++);
fecd2382
RP
2248}
2249\f
2250/*
2251 * demand_copy_C_string()
2252 *
2253 * Like demand_copy_string, but return NULL if the string contains any '\0's.
2254 * Give a warning if that happens.
2255 */
2256char *
f8701a3f
SC
2257demand_copy_C_string (len_pointer)
2258 int * len_pointer;
fecd2382 2259{
f8701a3f
SC
2260 register char * s;
2261
2262 if ((s = demand_copy_string(len_pointer)) != 0)
2263 {
2264 register int len;
2265
2266 for (len = * len_pointer;
2267 len > 0;
2268 len--)
2269 {
2270 if (* s == 0)
fecd2382 2271 {
f8701a3f
SC
2272 s = 0;
2273 len = 1;
2274 * len_pointer = 0;
2275 as_bad("This string may not contain \'\\0\'");
fecd2382 2276 }
f8701a3f
SC
2277 }
2278 }
2279 return (s);
fecd2382
RP
2280}
2281\f
2282/*
2283 * demand_copy_string()
2284 *
2285 * Demand string, but return a safe (=private) copy of the string.
2286 * Return NULL if we can't read a string here.
2287 */
2288static char *demand_copy_string(lenP)
2289int *lenP;
2290{
2291 register unsigned int c;
2292 register int len;
2293 char *retval;
2294
2295 len = 0;
2296 SKIP_WHITESPACE();
2297 if (*input_line_pointer == '\"') {
2298 input_line_pointer++; /* Skip opening quote. */
2299
2300 while (is_a_char(c = next_char_of_string())) {
2301 obstack_1grow(&notes, c);
2302 len ++;
2303 }
2304 /* JF this next line is so demand_copy_C_string will return a null
2305 termanated string. */
2306 obstack_1grow(&notes,'\0');
2307 retval=obstack_finish(&notes);
2308 } else {
2309 as_warn("Missing string");
2310 retval = NULL;
2311 ignore_rest_of_line();
2312 }
2313 *lenP = len;
2314 return(retval);
2315} /* demand_copy_string() */
2316\f
2317/*
2318 * is_it_end_of_statement()
2319 *
2320 * In: Input_line_pointer->next character.
2321 *
2322 * Do: Skip input_line_pointer over all whitespace.
2323 *
2324 * Out: 1 if input_line_pointer->end-of-line.
f8701a3f 2325*/
a39116f1 2326int is_it_end_of_statement() {
f8701a3f
SC
2327 SKIP_WHITESPACE();
2328 return (is_end_of_line [* input_line_pointer]);
fecd2382
RP
2329} /* is_it_end_of_statement() */
2330
2331void equals(sym_name)
2332char *sym_name;
2333{
f8701a3f
SC
2334 register symbolS *symbolP; /* symbol we are working with */
2335
2336 input_line_pointer++;
2337 if (*input_line_pointer=='=')
2338 input_line_pointer++;
2339
2340 while(*input_line_pointer==' ' || *input_line_pointer=='\t')
2341 input_line_pointer++;
2342
2343 if (sym_name[0]=='.' && sym_name[1]=='\0') {
2344 /* Turn '. = mumble' into a .org mumble */
2345 register segT segment;
2346 expressionS exp;
2347 register char *p;
2348
2349 segment = get_known_segmented_expression(& exp);
2350 if (! need_pass_2) {
2351 if (segment != now_seg && segment != SEG_ABSOLUTE)
2352 as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",
2353 segment_name(segment),
2354 segment_name(now_seg));
2355 p = frag_var(rs_org, 1, 1, (relax_substateT)0, exp.X_add_symbol,
2356 exp.X_add_number, (char *)0);
2357 * p = 0;
2358 } /* if (ok to make frag) */
2359 } else {
2360 symbolP=symbol_find_or_make(sym_name);
2361 pseudo_set(symbolP);
2362 }
fecd2382
RP
2363} /* equals() */
2364
2365/* .include -- include a file at this point. */
2366
2367/* ARGSUSED */
2368void s_include(arg)
2369int arg;
2370{
f8701a3f
SC
2371 char *newbuf;
2372 char *filename;
2373 int i;
2374 FILE *try;
2375 char *path;
2376
2377 filename = demand_copy_string(&i);
2378 demand_empty_rest_of_line();
2379 path = xmalloc(i + include_dir_maxlen + 5 /* slop */);
2380 for (i = 0; i < include_dir_count; i++) {
2381 strcpy(path, include_dirs[i]);
2382 strcat(path, "/");
2383 strcat(path, filename);
2384 if (0 != (try = fopen(path, "r")))
2385 {
2386 fclose (try);
2387 goto gotit;
2388 }
2389 }
2390 free(path);
2391 path = filename;
2392gotit:
2393 /* malloc Storage leak when file is found on path. FIXME-SOMEDAY. */
2394 newbuf = input_scrub_include_file (path, input_line_pointer);
2395 buffer_limit = input_scrub_next_buffer (&input_line_pointer);
fecd2382
RP
2396} /* s_include() */
2397
2398void add_include_dir(path)
2399char *path;
2400{
f8701a3f
SC
2401 int i;
2402
2403 if (include_dir_count == 0)
2404 {
2405 include_dirs = (char **)xmalloc (2 * sizeof (*include_dirs));
2406 include_dirs[0] = "."; /* Current dir */
2407 include_dir_count = 2;
2408 }
2409 else
2410 {
2411 include_dir_count++;
2412 include_dirs = (char **) realloc(include_dirs,
2413 include_dir_count*sizeof (*include_dirs));
2414 }
2415
2416 include_dirs[include_dir_count-1] = path; /* New one */
2417
2418 i = strlen (path);
2419 if (i > include_dir_maxlen)
2420 include_dir_maxlen = i;
fecd2382
RP
2421} /* add_include_dir() */
2422
2423void s_ignore(arg)
2424int arg;
2425{
2426 extern char is_end_of_line[];
f8701a3f 2427
fecd2382
RP
2428 while (!is_end_of_line[*input_line_pointer]) {
2429 ++input_line_pointer;
2430 }
2431 ++input_line_pointer;
f8701a3f 2432
fecd2382
RP
2433 return;
2434} /* s_ignore() */
2435
2436/*
2437 * Local Variables:
2438 * comment-column: 0
2439 * fill-column: 131
2440 * End:
2441 */
2442
2443/* end of read.c */
This page took 0.160199 seconds and 4 git commands to generate.