Remove unused sy_name_offset from ELF_TARGET_SYMBOL_FIELDS.
[deliverable/binutils-gdb.git] / gas / read.c
CommitLineData
fecd2382 1/* read.c - read a source file -
ddb393cf
ILT
2 Copyright (C) 1986, 1987, 1990, 1991, 1993, 1994
3 Free Software Foundation, Inc.
3340f7e5 4
f8701a3f
SC
5This file is part of GAS, the GNU Assembler.
6
7GAS is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GAS is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GAS; see the file COPYING. If not, write to
a2a5a4fa 19the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
fecd2382 20
016e0d42 21#if 0
fecd2382
RP
22#define MASK_CHAR (0xFF) /* If your chars aren't 8 bits, you will
23 change this a bit. But then, GNU isn't
24 spozed to run on your machine anyway.
25 (RMS is so shortsighted sometimes.)
26 */
016e0d42
ILT
27#else
28#define MASK_CHAR ((int)(unsigned char)-1)
29#endif
fecd2382 30
9a7d824a 31
9471a360
KR
32/* This is the largest known floating point format (for now). It will
33 grow when we do 4361 style flonums. */
fecd2382 34
9471a360 35#define MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT (16)
fecd2382 36
016e0d42
ILT
37/* Routines that read assembler source text to build spagetti in memory.
38 Another group of these functions is in the expr.c module. */
fecd2382 39
9471a360 40/* for isdigit() */
6efd877d
KR
41#include <ctype.h>
42
fecd2382 43#include "as.h"
9471a360 44#include "subsegs.h"
7e047ac2
ILT
45#include "sb.h"
46#include "macro.h"
1356d77d 47#include "libiberty.h"
fecd2382 48#include "obstack.h"
9a7d824a
ILT
49#include "listing.h"
50
9a7d824a
ILT
51#ifndef TC_START_LABEL
52#define TC_START_LABEL(x,y) (x==':')
53#endif
fecd2382 54
016e0d42
ILT
55/* The NOP_OPCODE is for the alignment fill value.
56 * fill it a nop instruction so that the disassembler does not choke
57 * on it
58 */
59#ifndef NOP_OPCODE
60#define NOP_OPCODE 0x00
61#endif
62
63char *input_line_pointer; /*->next char of source file to parse. */
fecd2382 64
326d16ca 65int generate_asm_lineno = 0; /* flag to generate line stab for .s file */
daad3bbf 66
fecd2382 67#if BITS_PER_CHAR != 8
6efd877d
KR
68/* The following table is indexed by[(char)] and will break if
69 a char does not have exactly 256 states (hopefully 0:255!)! */
70die horribly;
fecd2382 71#endif
f8701a3f 72
c978e704
ILT
73#ifndef LEX_AT
74/* The m88k unfortunately uses @ as a label beginner. */
75#define LEX_AT 0
76#endif
77
ddb393cf
ILT
78#ifndef LEX_BR
79/* The RS/6000 assembler uses {,},[,] as parts of symbol names. */
80#define LEX_BR 0
81#endif
82
6ef37255
KR
83#ifndef LEX_PCT
84/* The Delta 68k assembler permits % inside label names. */
85#define LEX_PCT 0
86#endif
87
18c9057f
ILT
88#ifndef LEX_QM
89/* The PowerPC Windows NT assemblers permits ? inside label names. */
90#define LEX_QM 0
91#endif
92
016e0d42 93/* used by is_... macros. our ctype[] */
1356d77d 94char lex_type[256] =
016e0d42
ILT
95{
96 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */
97 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ[\]^_ */
6ef37255 98 0, 0, 0, 0, 3, LEX_PCT, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */
18c9057f 99 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, LEX_QM, /* 0123456789:;<=>? */
c978e704 100 LEX_AT, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */
ddb393cf 101 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, 0, 3, /* PQRSTUVWXYZ[\]^_ */
016e0d42 102 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* `abcdefghijklmno */
ddb393cf 103 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, 0, 0, /* pqrstuvwxyz{|}~. */
016e0d42
ILT
104 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
105 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
106 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
107 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
108 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111};
112
113
114/*
fecd2382
RP
115 * In: a character.
116 * Out: 1 if this character ends a line.
117 */
118#define _ (0)
016e0d42
ILT
119char is_end_of_line[256] =
120{
fecd2382 121#ifdef CR_EOL
016e0d42 122 _, _, _, _, _, _, _, _, _, _, 99, _, _, 99, _, _, /* @abcdefghijklmno */
fecd2382 123#else
016e0d42 124 _, _, _, _, _, _, _, _, _, _, 99, _, _, _, _, _, /* @abcdefghijklmno */
fecd2382 125#endif
016e0d42 126 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
40324362
KR
127#ifdef TC_HPPA
128 _,99, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* _!"#$%&'()*+,-./ */
129 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0123456789:;<=>? */
130#else
016e0d42
ILT
131 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
132 _, _, _, _, _, _, _, _, _, _, _, 99, _, _, _, _, /* 0123456789:;<=>? */
40324362 133#endif
016e0d42
ILT
134 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
135 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
136 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
137 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
138 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
139 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
140 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
141 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
142 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
143};
fecd2382
RP
144#undef _
145
016e0d42
ILT
146/* Functions private to this file. */
147
148static char *buffer; /* 1st char of each buffer of lines is here. */
149static char *buffer_limit; /*->1 + last char in buffer. */
fecd2382 150
2209b19c
KR
151#ifdef TARGET_BYTES_BIG_ENDIAN
152/* Hack to deal with tc-*.h defining TARGET_BYTES_BIG_ENDIAN to empty
153 instead of to 0 or 1. */
154#if 5 - TARGET_BYTES_BIG_ENDIAN - 5 == 10
155#undef TARGET_BYTES_BIG_ENDIAN
156#define TARGET_BYTES_BIG_ENDIAN 1
157#endif
158int target_big_endian = TARGET_BYTES_BIG_ENDIAN;
159#else
160int target_big_endian /* = 0 */;
161#endif
9c6d3f66 162
9471a360 163static char *old_buffer; /* JF a hack */
016e0d42
ILT
164static char *old_input;
165static char *old_limit;
fecd2382 166
016e0d42 167/* Variables for handling include file directory list. */
fecd2382 168
016e0d42
ILT
169char **include_dirs; /* List of pointers to directories to
170 search for .include's */
171int include_dir_count; /* How many are in the list */
172int include_dir_maxlen = 1;/* Length of longest in list */
fecd2382
RP
173
174#ifndef WORKING_DOT_WORD
016e0d42 175struct broken_word *broken_words;
9471a360 176int new_broken_words;
fecd2382
RP
177#endif
178
e28c40d7
ILT
179/* The current offset into the absolute section. We don't try to
180 build frags in the absolute section, since no data can be stored
181 there. We just keep track of the current offset. */
182addressT abs_section_offset;
183
1356d77d
ILT
184/* If this line had an MRI style label, it is stored in this variable.
185 This is used by some of the MRI pseudo-ops. */
7e047ac2 186symbolS *line_label;
1356d77d
ILT
187
188/* This global variable is used to support MRI common sections. We
189 translate such sections into a common symbol. This variable is
190 non-NULL when we are in an MRI common section. */
191symbolS *mri_common_symbol;
192
286cb27a
ILT
193/* In MRI mode, after a dc.b pseudo-op with an odd number of bytes, we
194 need to align to an even byte boundary unless the next pseudo-op is
195 dc.b, ds.b, or dcb.b. This variable is set to 1 if an alignment
196 may be needed. */
197static int mri_pending_align;
198
86038ada 199static int scrub_from_string PARAMS ((char **));
286cb27a 200static void do_align PARAMS ((int, char *));
e28c40d7
ILT
201static int hex_float PARAMS ((int, char *));
202static void do_org PARAMS ((segT, expressionS *, int));
6ef37255 203char *demand_copy_string PARAMS ((int *lenP));
016e0d42 204int is_it_end_of_statement PARAMS ((void));
5ac34ac3 205static segT get_segmented_expression PARAMS ((expressionS *expP));
016e0d42 206static segT get_known_segmented_expression PARAMS ((expressionS * expP));
016e0d42 207static void pobegin PARAMS ((void));
7e047ac2 208static int get_line_sb PARAMS ((sb *));
fecd2382 209\f
6efd877d 210
016e0d42
ILT
211void
212read_begin ()
fecd2382 213{
016e0d42 214 const char *p;
f8701a3f 215
6efd877d
KR
216 pobegin ();
217 obj_read_begin_hook ();
f8701a3f 218
4380166d
KR
219 /* Something close -- but not too close -- to a multiple of 1024.
220 The debugging malloc I'm using has 24 bytes of overhead. */
221 obstack_begin (&notes, 5090);
222 obstack_begin (&cond_obstack, 990);
f8701a3f 223
f8701a3f
SC
224 /* Use machine dependent syntax */
225 for (p = line_separator_chars; *p; p++)
58d4951d 226 is_end_of_line[(unsigned char) *p] = 1;
f8701a3f 227 /* Use more. FIXME-SOMEDAY. */
1356d77d
ILT
228
229 if (flag_mri)
230 lex_type['?'] = 3;
fecd2382
RP
231}
232\f
233/* set up pseudo-op tables */
234
1356d77d 235static struct hash_control *po_hash;
fecd2382 236
016e0d42 237static const pseudo_typeS potable[] =
fecd2382 238{
6efd877d
KR
239 {"abort", s_abort, 0},
240 {"align", s_align_ptwo, 0},
241 {"ascii", stringer, 0},
242 {"asciz", stringer, 1},
931a8fab 243 {"balign", s_align_bytes, 0},
f8701a3f 244/* block */
6efd877d
KR
245 {"byte", cons, 1},
246 {"comm", s_comm, 0},
1356d77d
ILT
247 {"common", s_mri_common, 0},
248 {"common.s", s_mri_common, 1},
6efd877d 249 {"data", s_data, 0},
1356d77d
ILT
250 {"dc", cons, 2},
251 {"dc.b", cons, 1},
252 {"dc.d", float_cons, 'd'},
253 {"dc.l", cons, 4},
254 {"dc.s", float_cons, 'f'},
255 {"dc.w", cons, 2},
256 {"dc.x", float_cons, 'x'},
e28c40d7
ILT
257 {"dcb", s_space, 2},
258 {"dcb.b", s_space, 1},
259 {"dcb.d", s_float_space, 'd'},
260 {"dcb.l", s_space, 4},
261 {"dcb.s", s_float_space, 'f'},
262 {"dcb.w", s_space, 2},
263 {"dcb.x", s_float_space, 'x'},
1356d77d
ILT
264 {"ds", s_space, 2},
265 {"ds.b", s_space, 1},
e28c40d7 266 {"ds.d", s_space, 8},
1356d77d 267 {"ds.l", s_space, 4},
e28c40d7
ILT
268 {"ds.p", s_space, 12},
269 {"ds.s", s_space, 4},
1356d77d 270 {"ds.w", s_space, 2},
e28c40d7 271 {"ds.x", s_space, 12},
42ac8fa8 272 {"debug", s_ignore, 0},
604633ae 273#ifdef S_SET_DESC
4064305e 274 {"desc", s_desc, 0},
604633ae 275#endif
f8701a3f 276/* dim */
6efd877d 277 {"double", float_cons, 'd'},
f8701a3f 278/* dsect */
6efd877d
KR
279 {"eject", listing_eject, 0}, /* Formfeed listing */
280 {"else", s_else, 0},
e28c40d7 281 {"elsec", s_else, 0},
6efd877d 282 {"end", s_end, 0},
e28c40d7 283 {"endc", s_endif, 0},
6efd877d 284 {"endif", s_endif, 0},
f8701a3f 285/* endef */
6efd877d 286 {"equ", s_set, 0},
42ac8fa8 287 {"err", s_err, 0},
7e047ac2 288 {"exitm", s_mexit, 0},
f8701a3f 289/* extend */
6efd877d 290 {"extern", s_ignore, 0}, /* We treat all undef as ext */
9a7d824a
ILT
291 {"appfile", s_app_file, 1},
292 {"appline", s_app_line, 0},
e28c40d7 293 {"fail", s_fail, 0},
6efd877d
KR
294 {"file", s_app_file, 0},
295 {"fill", s_fill, 0},
296 {"float", float_cons, 'f'},
e28c40d7 297 {"format", s_ignore, 0},
6efd877d
KR
298 {"global", s_globl, 0},
299 {"globl", s_globl, 0},
300 {"hword", cons, 2},
e28c40d7 301 {"if", s_if, (int) O_ne},
7e047ac2 302 {"ifc", s_ifc, 0},
6efd877d 303 {"ifdef", s_ifdef, 0},
e28c40d7 304 {"ifeq", s_if, (int) O_eq},
6efd877d 305 {"ifeqs", s_ifeqs, 0},
e28c40d7
ILT
306 {"ifge", s_if, (int) O_ge},
307 {"ifgt", s_if, (int) O_gt},
308 {"ifle", s_if, (int) O_le},
309 {"iflt", s_if, (int) O_lt},
7e047ac2 310 {"ifnc", s_ifc, 1},
6efd877d 311 {"ifndef", s_ifdef, 1},
e28c40d7 312 {"ifne", s_if, (int) O_ne},
6efd877d
KR
313 {"ifnes", s_ifeqs, 1},
314 {"ifnotdef", s_ifdef, 1},
315 {"include", s_include, 0},
316 {"int", cons, 4},
7e047ac2 317 {"irp", s_irp, 0},
42ac8fa8 318 {"irep", s_irp, 0},
7e047ac2 319 {"irpc", s_irp, 1},
42ac8fa8 320 {"irepc", s_irp, 1},
6efd877d
KR
321 {"lcomm", s_lcomm, 0},
322 {"lflags", listing_flags, 0}, /* Listing flags */
323 {"list", listing_list, 1}, /* Turn listing on */
e28c40d7 324 {"llen", listing_psize, 1},
6efd877d
KR
325 {"long", cons, 4},
326 {"lsym", s_lsym, 0},
7e047ac2
ILT
327 {"macro", s_macro, 0},
328 {"mexit", s_mexit, 0},
e28c40d7 329 {"noformat", s_ignore, 0},
6efd877d 330 {"nolist", listing_list, 0}, /* Turn listing off */
69e077f3 331 {"nopage", listing_nopage, 0},
80aab579 332 {"octa", cons, 16},
e28c40d7 333 {"offset", s_struct, 0},
6efd877d 334 {"org", s_org, 0},
931a8fab 335 {"p2align", s_align_ptwo, 0},
69e077f3
ILT
336 {"page", listing_eject, 0},
337 {"plen", listing_psize, 0},
42ac8fa8 338 {"print", s_print, 0},
6efd877d 339 {"psize", listing_psize, 0}, /* set paper size */
42ac8fa8 340 {"purgem", s_purgem, 0},
80aab579 341 {"quad", cons, 8},
42ac8fa8 342 {"rep", s_rept, 0},
7e047ac2 343 {"rept", s_rept, 0},
86038ada 344 {"rva", s_rva, 4},
6efd877d 345 {"sbttl", listing_title, 1}, /* Subtitle of listing */
f8701a3f
SC
346/* scl */
347/* sect */
6efd877d
KR
348 {"set", s_set, 0},
349 {"short", cons, 2},
350 {"single", float_cons, 'f'},
f8701a3f 351/* size */
6efd877d 352 {"space", s_space, 0},
e14994d9 353 {"spc", s_ignore, 0},
4064305e
SS
354 {"stabd", s_stab, 'd'},
355 {"stabn", s_stab, 'n'},
356 {"stabs", s_stab, 's'},
ba71c54d 357 {"string", stringer, 1},
e28c40d7 358 {"struct", s_struct, 0},
f8701a3f 359/* tag */
6efd877d 360 {"text", s_text, 0},
6ef37255
KR
361
362 /* This is for gcc to use. It's only just been added (2/94), so gcc
363 won't be able to use it for a while -- probably a year or more.
364 But once this has been released, check with gcc maintainers
365 before deleting it or even changing the spelling. */
366 {"this_GCC_requires_the_GNU_assembler", s_ignore, 0},
367 /* If we're folding case -- done for some targets, not necessarily
368 all -- the above string in an input file will be converted to
369 this one. Match it either way... */
370 {"this_gcc_requires_the_gnu_assembler", s_ignore, 0},
371
6efd877d 372 {"title", listing_title, 0}, /* Listing title */
e14994d9 373 {"ttl", listing_title, 0},
f8701a3f
SC
374/* type */
375/* use */
376/* val */
e14994d9 377 {"xcom", s_comm, 0},
1356d77d 378 {"xdef", s_globl, 0},
e14994d9 379 {"xref", s_ignore, 0},
4064305e 380 {"xstabs", s_xstab, 's'},
6efd877d 381 {"word", cons, 2},
c02fd8dc 382 {"zero", s_space, 0},
6efd877d 383 {NULL} /* end sentinel */
fecd2382
RP
384};
385
2209b19c
KR
386static int pop_override_ok = 0;
387static const char *pop_table_name;
388
389void
390pop_insert (table)
391 const pseudo_typeS *table;
6efd877d 392{
2209b19c 393 const char *errtxt;
6efd877d 394 const pseudo_typeS *pop;
2209b19c
KR
395 for (pop = table; pop->poc_name; pop++)
396 {
397 errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop);
398 if (errtxt && (!pop_override_ok || strcmp (errtxt, "exists")))
399 as_fatal ("error constructing %s pseudo-op table", pop_table_name);
400 }
401}
6efd877d 402
2209b19c
KR
403#ifndef md_pop_insert
404#define md_pop_insert() pop_insert(md_pseudo_table)
405#endif
406
407#ifndef obj_pop_insert
408#define obj_pop_insert() pop_insert(obj_pseudo_table)
409#endif
410
411static void
412pobegin ()
413{
6efd877d
KR
414 po_hash = hash_new ();
415
416 /* Do the target-specific pseudo ops. */
2209b19c
KR
417 pop_table_name = "md";
418 md_pop_insert ();
6efd877d
KR
419
420 /* Now object specific. Skip any that were in the target table. */
2209b19c
KR
421 pop_table_name = "obj";
422 pop_override_ok = 1;
423 obj_pop_insert ();
6efd877d
KR
424
425 /* Now portable ones. Skip any that we've seen already. */
2209b19c
KR
426 pop_table_name = "standard";
427 pop_insert (potable);
428}
fecd2382 429\f
58d4951d
ILT
430#define HANDLE_CONDITIONAL_ASSEMBLY() \
431 if (ignore_input ()) \
432 { \
433 while (! is_end_of_line[(unsigned char) *input_line_pointer++]) \
434 if (input_line_pointer == buffer_limit) \
435 break; \
436 continue; \
f8701a3f 437 }
a39116f1 438
fecd2382 439
86038ada
ILT
440/* This function is used when scrubbing the characters between #APP
441 and #NO_APP. */
442
443static char *scrub_string;
444static char *scrub_string_end;
445
446static int
447scrub_from_string (from)
448 char **from;
449{
450 int size;
451
452 *from = scrub_string;
453 size = scrub_string_end - scrub_string;
454 scrub_string = scrub_string_end;
455 return size;
456}
457
fecd2382
RP
458/* read_a_source_file()
459 *
460 * We read the file, putting things into a web that
461 * represents what we have been reading.
462 */
6efd877d
KR
463void
464read_a_source_file (name)
465 char *name;
fecd2382 466{
f8701a3f 467 register char c;
6efd877d 468 register char *s; /* string of symbol, '\0' appended */
f8701a3f 469 register int temp;
6efd877d 470 pseudo_typeS *pop;
f8701a3f 471
6efd877d 472 buffer = input_scrub_new_file (name);
f8701a3f 473
6efd877d
KR
474 listing_file (name);
475 listing_newline ("");
f8701a3f 476
6efd877d
KR
477 while ((buffer_limit = input_scrub_next_buffer (&input_line_pointer)) != 0)
478 { /* We have another line to parse. */
479 know (buffer_limit[-1] == '\n'); /* Must have a sentinel. */
9471a360
KR
480 contin: /* JF this goto is my fault I admit it.
481 Someone brave please re-write the whole
482 input section here? Pleeze??? */
6efd877d 483 while (input_line_pointer < buffer_limit)
9471a360
KR
484 {
485 /* We have more of this buffer to parse. */
f8701a3f
SC
486
487 /*
488 * We now have input_line_pointer->1st char of next line.
489 * If input_line_pointer [-1] == '\n' then we just
490 * scanned another line: so bump line counters.
491 */
d2550c72 492 if (is_end_of_line[(unsigned char) input_line_pointer[-1]])
6efd877d 493 {
a2a5a4fa
KR
494#ifdef md_start_line_hook
495 md_start_line_hook ();
496#endif
497
385ce433
JL
498 if (input_line_pointer[-1] == '\n')
499 bump_line_counters ();
f8701a3f 500
7e047ac2
ILT
501 line_label = NULL;
502
1356d77d
ILT
503 if (flag_mri
504#ifdef LABELS_WITHOUT_COLONS
505 || 1
506#endif
507 )
6efd877d 508 {
1356d77d
ILT
509 /* Text at the start of a line must be a label, we
510 run down and stick a colon in. */
511 if (is_name_beginner (*input_line_pointer))
512 {
513 char *line_start = input_line_pointer;
7e047ac2
ILT
514 char c;
515
516 HANDLE_CONDITIONAL_ASSEMBLY ();
1356d77d 517
7e047ac2
ILT
518 c = get_symbol_end ();
519
520 /* In MRI mode, the EQU pseudoop must be
521 handled specially. */
522 if (flag_mri)
1356d77d 523 {
7e047ac2
ILT
524 char *rest = input_line_pointer + 1;
525
526 if (*rest == ':')
527 ++rest;
528 if (*rest == ' ' || *rest == '\t')
529 ++rest;
530 if ((strncasecmp (rest, "EQU", 3) == 0
531 || strncasecmp (rest, "SET", 3) == 0)
532 && (rest[3] == ' ' || rest[3] == '\t'))
1356d77d 533 {
7e047ac2
ILT
534 input_line_pointer = rest + 3;
535 equals (line_start);
536 continue;
1356d77d
ILT
537 }
538 }
6efd877d 539
7e047ac2
ILT
540 line_label = colon (line_start);
541
1356d77d
ILT
542 *input_line_pointer = c;
543 if (c == ':')
544 input_line_pointer++;
545 }
6efd877d 546 }
9471a360 547 }
f8701a3f 548
f8701a3f
SC
549 /*
550 * We are at the begining of a line, or similar place.
551 * We expect a well-formed assembler statement.
552 * A "symbol-name:" is a statement.
553 *
554 * Depending on what compiler is used, the order of these tests
555 * may vary to catch most common case 1st.
556 * Each test is independent of all other tests at the (top) level.
557 * PLEASE make a compiler that doesn't use this assembler.
558 * It is crufty to waste a compiler's time encoding things for this
559 * assembler, which then wastes more time decoding it.
560 * (And communicating via (linear) files is silly!
561 * If you must pass stuff, please pass a tree!)
562 */
9471a360
KR
563 if ((c = *input_line_pointer++) == '\t'
564 || c == ' '
565 || c == '\f'
566 || c == 0)
6efd877d
KR
567 {
568 c = *input_line_pointer++;
569 }
570 know (c != ' '); /* No further leading whitespace. */
571 LISTING_NEWLINE ();
f8701a3f
SC
572 /*
573 * C is the 1st significant character.
574 * Input_line_pointer points after that character.
575 */
6efd877d 576 if (is_name_beginner (c))
6ef37255
KR
577 {
578 /* want user-defined label or pseudo/opcode */
6efd877d
KR
579 HANDLE_CONDITIONAL_ASSEMBLY ();
580
f8701a3f 581 s = --input_line_pointer;
6efd877d 582 c = get_symbol_end (); /* name's delimiter */
f8701a3f
SC
583 /*
584 * C is character after symbol.
585 * That character's place in the input line is now '\0'.
586 * S points to the beginning of the symbol.
587 * [In case of pseudo-op, s->'.'.]
588 * Input_line_pointer->'\0' where c was.
589 */
9a7d824a 590 if (TC_START_LABEL(c, input_line_pointer))
6efd877d 591 {
7e047ac2
ILT
592 if (flag_mri)
593 {
594 char *rest = input_line_pointer + 1;
595
596 /* In MRI mode, \tsym: set 0 is permitted. */
597
598 if (*rest == ':')
599 ++rest;
600 if (*rest == ' ' || *rest == '\t')
601 ++rest;
602 if ((strncasecmp (rest, "EQU", 3) == 0
603 || strncasecmp (rest, "SET", 3) == 0)
604 && (rest[3] == ' ' || rest[3] == '\t'))
605 {
606 input_line_pointer = rest + 3;
607 equals (s);
608 continue;
609 }
610 }
611
612 line_label = colon (s); /* user-defined label */
6efd877d 613 *input_line_pointer++ = ':'; /* Put ':' back for error messages' sake. */
f8701a3f 614 /* Input_line_pointer->after ':'. */
6efd877d
KR
615 SKIP_WHITESPACE ();
616
f8701a3f 617
6efd877d 618 }
4064305e
SS
619 else if (c == '='
620 || (input_line_pointer[1] == '='
621#ifdef TC_EQUAL_IN_INSN
622 && ! TC_EQUAL_IN_INSN (c, input_line_pointer)
623#endif
624 ))
9c6d3f66 625 {
6efd877d
KR
626 equals (s);
627 demand_empty_rest_of_line ();
628 }
629 else
630 { /* expect pseudo-op or machine instruction */
8ff6f40e
ILT
631 pop = NULL;
632
d4c8cbd8
JL
633#define IGNORE_OPCODE_CASE
634#ifdef IGNORE_OPCODE_CASE
635 {
636 char *s2 = s;
637 while (*s2)
638 {
639 if (isupper (*s2))
640 *s2 = tolower (*s2);
641 s2++;
642 }
643 }
644#endif
645
42ac8fa8
ILT
646#ifndef MRI_MODE_NEEDS_PSEUDO_DOT
647#define MRI_MODE_NEEDS_PSEUDO_DOT 0
648#endif
649
650 if ((flag_mri && ! MRI_MODE_NEEDS_PSEUDO_DOT)
8ff6f40e 651#ifdef NO_PSEUDO_DOT
1356d77d 652 || 1
8ff6f40e 653#endif
1356d77d
ILT
654 )
655 {
656 /* The MRI assembler and the m88k use pseudo-ops
657 without a period. */
658 pop = (pseudo_typeS *) hash_find (po_hash, s);
659 if (pop != NULL && pop->poc_handler == NULL)
660 pop = NULL;
661 }
8ff6f40e 662
7e047ac2 663 if (pop != NULL
42ac8fa8
ILT
664 || ((! flag_mri || MRI_MODE_NEEDS_PSEUDO_DOT)
665 && *s == '.'))
6efd877d
KR
666 {
667 /*
9471a360
KR
668 * PSEUDO - OP.
669 *
670 * WARNING: c has next char, which may be end-of-line.
671 * We lookup the pseudo-op table with s+1 because we
672 * already know that the pseudo-op begins with a '.'.
673 */
6efd877d 674
8ff6f40e
ILT
675 if (pop == NULL)
676 pop = (pseudo_typeS *) hash_find (po_hash, s + 1);
6efd877d 677
286cb27a
ILT
678 /* In MRI mode, we may need to insert an
679 automatic alignment directive. What a hack
680 this is. */
681 if (mri_pending_align
682 && (pop == NULL
683 || ! ((pop->poc_handler == cons
684 && pop->poc_val == 1)
685 || (pop->poc_handler == s_space
686 && pop->poc_val == 1))))
687 {
688 do_align (1, (char *) NULL);
689 mri_pending_align = 0;
690 }
691
6efd877d 692 /* Print the error msg now, while we still can */
8ff6f40e 693 if (pop == NULL)
6efd877d
KR
694 {
695 as_bad ("Unknown pseudo-op: `%s'", s);
f8701a3f 696 *input_line_pointer = c;
6efd877d 697 s_ignore (0);
46b81190 698 continue;
6efd877d
KR
699 }
700
701 /* Put it back for error messages etc. */
702 *input_line_pointer = c;
9c6d3f66
KR
703 /* The following skip of whitespace is compulsory.
704 A well shaped space is sometimes all that separates
705 keyword from operands. */
6efd877d 706 if (c == ' ' || c == '\t')
d4c8cbd8 707 input_line_pointer++;
6efd877d 708 /*
9471a360
KR
709 * Input_line is restored.
710 * Input_line_pointer->1st non-blank char
711 * after pseudo-operation.
712 */
46b81190 713 (*pop->poc_handler) (pop->poc_val);
e28c40d7
ILT
714
715 /* If that was .end, just get out now. */
716 if (pop->poc_handler == s_end)
717 goto quit;
6efd877d
KR
718 }
719 else
6efd877d 720 { /* machine instruction */
4026c122
ILT
721 int inquote = 0;
722
286cb27a
ILT
723 if (mri_pending_align)
724 {
725 do_align (1, (char *) NULL);
726 mri_pending_align = 0;
727 }
728
6efd877d
KR
729 /* WARNING: c has char, which may be end-of-line. */
730 /* Also: input_line_pointer->`\0` where c was. */
731 *input_line_pointer = c;
58d4951d 732 while (!is_end_of_line[(unsigned char) *input_line_pointer]
4026c122 733 || inquote
4064305e
SS
734#ifdef TC_EOL_IN_INSN
735 || TC_EOL_IN_INSN (input_line_pointer)
736#endif
737 )
6efd877d 738 {
4026c122
ILT
739 if (flag_mri && *input_line_pointer == '\'')
740 inquote = ! inquote;
6efd877d
KR
741 input_line_pointer++;
742 }
f8701a3f 743
6efd877d
KR
744 c = *input_line_pointer;
745 *input_line_pointer = '\0';
f8701a3f 746
326d16ca
KH
747#ifdef OBJ_GENERATE_ASM_LINENO
748 if (generate_asm_lineno == 0)
749 {
f10a96cb 750 if (ecoff_no_current_file ())
326d16ca
KH
751 generate_asm_lineno = 1;
752 }
f10a96cb
ILT
753 if (generate_asm_lineno == 1)
754 {
1b434ced
ILT
755 unsigned int lineno;
756 char *s;
757
daad3bbf 758 as_where (&s, &lineno);
326d16ca 759 OBJ_GENERATE_ASM_LINENO (s, lineno);
f10a96cb 760 }
daad3bbf
KH
761#endif
762
7e047ac2
ILT
763 if (macro_defined)
764 {
765 sb out;
766 const char *err;
767
768 if (check_macro (s, &out, '\0', &err))
769 {
770 if (err != NULL)
771 as_bad (err);
772 *input_line_pointer++ = c;
773 input_scrub_include_sb (&out,
774 input_line_pointer);
775 sb_kill (&out);
776 buffer_limit =
777 input_scrub_next_buffer (&input_line_pointer);
778 continue;
779 }
780 }
781
6efd877d 782 md_assemble (s); /* Assemble 1 instruction. */
f8701a3f 783
6efd877d 784 *input_line_pointer++ = c;
f8701a3f 785
d4c8cbd8
JL
786 /* We resume loop AFTER the end-of-line from
787 this instruction. */
6efd877d 788 } /* if (*s=='.') */
6efd877d 789 } /* if c==':' */
f8701a3f 790 continue;
6efd877d 791 } /* if (is_name_beginner(c) */
f8701a3f 792
f8701a3f 793
d4c8cbd8 794 /* Empty statement? */
58d4951d 795 if (is_end_of_line[(unsigned char) c])
d4c8cbd8 796 continue;
6efd877d 797
9777b772
KR
798 if ((LOCAL_LABELS_DOLLAR || LOCAL_LABELS_FB)
799 && isdigit (c))
d4c8cbd8
JL
800 {
801 /* local label ("4:") */
6efd877d
KR
802 char *backup = input_line_pointer;
803
804 HANDLE_CONDITIONAL_ASSEMBLY ();
805
806 temp = c - '0';
807
808 while (isdigit (*input_line_pointer))
809 {
810 temp = (temp * 10) + *input_line_pointer - '0';
811 ++input_line_pointer;
812 } /* read the whole number */
813
9777b772
KR
814 if (LOCAL_LABELS_DOLLAR
815 && *input_line_pointer == '$'
6efd877d
KR
816 && *(input_line_pointer + 1) == ':')
817 {
818 input_line_pointer += 2;
819
820 if (dollar_label_defined (temp))
821 {
822 as_fatal ("label \"%d$\" redefined", temp);
823 }
824
825 define_dollar_label (temp);
826 colon (dollar_label_name (temp, 0));
827 continue;
828 }
6efd877d 829
9777b772
KR
830 if (LOCAL_LABELS_FB
831 && *input_line_pointer++ == ':')
6efd877d
KR
832 {
833 fb_label_instance_inc (temp);
834 colon (fb_label_name (temp, 0));
835 continue;
836 }
6efd877d
KR
837
838 input_line_pointer = backup;
839 } /* local label ("4:") */
f8701a3f 840
6efd877d
KR
841 if (c && strchr (line_comment_chars, c))
842 { /* Its a comment. Better say APP or NO_APP */
f8701a3f
SC
843 char *ends;
844 char *new_buf;
845 char *new_tmp;
604633ae 846 unsigned int new_length;
f8701a3f 847 char *tmp_buf = 0;
6efd877d
KR
848
849 bump_line_counters ();
850 s = input_line_pointer;
851 if (strncmp (s, "APP\n", 4))
852 continue; /* We ignore it */
853 s += 4;
854
855 ends = strstr (s, "#NO_APP\n");
856
857 if (!ends)
858 {
604633ae
ILT
859 unsigned int tmp_len;
860 unsigned int num;
6efd877d 861
f8701a3f
SC
862 /* The end of the #APP wasn't in this buffer. We
863 keep reading in buffers until we find the #NO_APP
864 that goes with this #APP There is one. The specs
865 guarentee it. . . */
6efd877d 866 tmp_len = buffer_limit - s;
85825401 867 tmp_buf = xmalloc (tmp_len + 1);
4380166d 868 memcpy (tmp_buf, s, tmp_len);
6efd877d
KR
869 do
870 {
871 new_tmp = input_scrub_next_buffer (&buffer);
f8701a3f 872 if (!new_tmp)
6efd877d 873 break;
f8701a3f 874 else
6efd877d 875 buffer_limit = new_tmp;
f8701a3f 876 input_line_pointer = buffer;
6efd877d 877 ends = strstr (buffer, "#NO_APP\n");
f8701a3f 878 if (ends)
6efd877d 879 num = ends - buffer;
f8701a3f 880 else
6efd877d
KR
881 num = buffer_limit - buffer;
882
883 tmp_buf = xrealloc (tmp_buf, tmp_len + num);
9eb5f4b8 884 memcpy (tmp_buf + tmp_len, buffer, num);
6efd877d
KR
885 tmp_len += num;
886 }
887 while (!ends);
888
889 input_line_pointer = ends ? ends + 8 : NULL;
890
891 s = tmp_buf;
892 ends = s + tmp_len;
893
894 }
895 else
896 {
897 input_line_pointer = ends + 8;
898 }
6efd877d
KR
899
900 scrub_string = s;
86038ada
ILT
901 scrub_string_end = ends;
902
903 new_length = ends - s;
904 new_buf = (char *) xmalloc (new_length);
905 new_tmp = new_buf;
6efd877d
KR
906 for (;;)
907 {
86038ada
ILT
908 int space;
909 int size;
f8701a3f 910
86038ada
ILT
911 space = (new_buf + new_length) - new_tmp;
912 size = do_scrub_chars (scrub_from_string, new_tmp, space);
913
914 if (size < space)
6efd877d 915 {
86038ada
ILT
916 new_tmp += size;
917 break;
f8701a3f 918 }
86038ada
ILT
919
920 new_buf = xrealloc (new_buf, new_length + 100);
921 new_tmp = new_buf + new_length;
922 new_length += 100;
fecd2382 923 }
f8701a3f
SC
924
925 if (tmp_buf)
6efd877d
KR
926 free (tmp_buf);
927 old_buffer = buffer;
928 old_input = input_line_pointer;
929 old_limit = buffer_limit;
930 buffer = new_buf;
931 input_line_pointer = new_buf;
932 buffer_limit = new_tmp;
f8701a3f
SC
933 continue;
934 }
935
6efd877d 936 HANDLE_CONDITIONAL_ASSEMBLY ();
f8701a3f
SC
937
938 /* as_warn("Junk character %d.",c); Now done by ignore_rest */
939 input_line_pointer--; /* Report unknown char as ignored. */
6efd877d
KR
940 ignore_rest_of_line ();
941 } /* while (input_line_pointer<buffer_limit) */
a2a5a4fa
KR
942
943#ifdef md_after_pass_hook
944 md_after_pass_hook ();
945#endif
946
6efd877d
KR
947 if (old_buffer)
948 {
86038ada 949 free (buffer);
6efd877d
KR
950 bump_line_counters ();
951 if (old_input != 0)
952 {
953 buffer = old_buffer;
954 input_line_pointer = old_input;
955 buffer_limit = old_limit;
f8701a3f
SC
956 old_buffer = 0;
957 goto contin;
958 }
959 }
6efd877d 960 } /* while (more buffers to scan) */
f8701a3f 961
e28c40d7
ILT
962 quit:
963 input_scrub_close (); /* Close the input file */
4075afe1 964}
fecd2382 965
18c9057f
ILT
966/* For most MRI pseudo-ops, the line actually ends at the first
967 nonquoted space. This function looks for that point, stuffs a null
968 in, and sets *STOPCP to the character that used to be there, and
42ac8fa8
ILT
969 returns the location.
970
971 Until I hear otherwise, I am going to assume that this is only true
972 for the m68k MRI assembler. */
18c9057f
ILT
973
974char *
975mri_comment_field (stopcp)
976 char *stopcp;
977{
42ac8fa8
ILT
978#ifdef TC_M68K
979
18c9057f
ILT
980 char *s;
981 int inquote = 0;
982
983 know (flag_mri);
984
985 for (s = input_line_pointer;
986 ((! is_end_of_line[(unsigned char) *s] && *s != ' ' && *s != '\t')
987 || inquote);
988 s++)
989 {
990 if (*s == '\'')
991 inquote = ! inquote;
992 }
993 *stopcp = *s;
994 *s = '\0';
995 return s;
42ac8fa8
ILT
996
997#else
998
999 char *s;
1000
1001 for (s = input_line_pointer; ! is_end_of_line[(unsigned char) *s]; s++)
1002 ;
1003 *stopcp = *s;
1004 *s = '\0';
1005 return s;
1006
1007#endif
1008
18c9057f
ILT
1009}
1010
1011/* Skip to the end of an MRI comment field. */
1012
1013void
1014mri_comment_end (stop, stopc)
1015 char *stop;
1016 int stopc;
1017{
1018 know (flag_mri);
1019
1020 input_line_pointer = stop;
1021 *stop = stopc;
1022 while (! is_end_of_line[(unsigned char) *input_line_pointer])
1023 ++input_line_pointer;
1024}
1025
6efd877d 1026void
604633ae
ILT
1027s_abort (ignore)
1028 int ignore;
6efd877d
KR
1029{
1030 as_fatal (".abort detected. Abandoning ship.");
4075afe1
KR
1031}
1032
1033/* Guts of .align directive. */
1034static void
1035do_align (n, fill)
1036 int n;
1037 char *fill;
1038{
1039#ifdef md_do_align
1040 md_do_align (n, fill, just_record_alignment);
1041#endif
1042 if (!fill)
1043 {
1044 /* @@ Fix this right for BFD! */
1045 static char zero;
1046 static char nop_opcode = NOP_OPCODE;
1047
1048 if (now_seg != data_section && now_seg != bss_section)
1049 {
1050 fill = &nop_opcode;
1051 }
1052 else
1053 {
1054 fill = &zero;
1055 }
1056 }
1057 /* Only make a frag if we HAVE to. . . */
1058 if (n && !need_pass_2)
1059 frag_align (n, *fill);
1060
c02fd8dc 1061#ifdef md_do_align
4075afe1 1062 just_record_alignment:
c02fd8dc
ILT
1063#endif
1064
4075afe1
KR
1065 record_alignment (now_seg, n);
1066}
fecd2382
RP
1067
1068/* For machines where ".align 4" means align to a 4 byte boundary. */
6efd877d
KR
1069void
1070s_align_bytes (arg)
1071 int arg;
fecd2382 1072{
6efd877d 1073 register unsigned int temp;
4075afe1 1074 char temp_fill;
6efd877d
KR
1075 unsigned int i = 0;
1076 unsigned long max_alignment = 1 << 15;
18c9057f
ILT
1077 char *stop = NULL;
1078 char stopc;
1079
1080 if (flag_mri)
1081 stop = mri_comment_field (&stopc);
f8701a3f 1082
58d4951d 1083 if (is_end_of_line[(unsigned char) *input_line_pointer])
6efd877d
KR
1084 temp = arg; /* Default value from pseudo-op table */
1085 else
1086 temp = get_absolute_expression ();
f8701a3f 1087
6efd877d
KR
1088 if (temp > max_alignment)
1089 {
1090 as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
f8701a3f
SC
1091 }
1092
4075afe1
KR
1093 /* For the sparc, `.align (1<<n)' actually means `.align n' so we
1094 have to convert it. */
6efd877d
KR
1095 if (temp != 0)
1096 {
1097 for (i = 0; (temp & 1) == 0; temp >>= 1, ++i)
1098 ;
f8701a3f 1099 }
6efd877d
KR
1100 if (temp != 1)
1101 as_bad ("Alignment not a power of 2");
f8701a3f 1102
6efd877d
KR
1103 temp = i;
1104 if (*input_line_pointer == ',')
1105 {
1106 input_line_pointer++;
1107 temp_fill = get_absolute_expression ();
4075afe1 1108 do_align (temp, &temp_fill);
f8701a3f 1109 }
6efd877d 1110 else
4075afe1 1111 do_align (temp, (char *) 0);
49864cfa 1112
18c9057f
ILT
1113 if (flag_mri)
1114 mri_comment_end (stop, stopc);
1115
6efd877d 1116 demand_empty_rest_of_line ();
4075afe1 1117}
fecd2382
RP
1118
1119/* For machines where ".align 4" means align to 2**4 boundary. */
6efd877d 1120void
604633ae
ILT
1121s_align_ptwo (ignore)
1122 int ignore;
6efd877d
KR
1123{
1124 register int temp;
4075afe1 1125 char temp_fill;
6efd877d 1126 long max_alignment = 15;
18c9057f
ILT
1127 char *stop = NULL;
1128 char stopc;
1129
1130 if (flag_mri)
1131 stop = mri_comment_field (&stopc);
6efd877d
KR
1132
1133 temp = get_absolute_expression ();
1134 if (temp > max_alignment)
1135 as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
1136 else if (temp < 0)
1137 {
1138 as_bad ("Alignment negative. 0 assumed.");
1139 temp = 0;
1140 }
1141 if (*input_line_pointer == ',')
1142 {
1143 input_line_pointer++;
1144 temp_fill = get_absolute_expression ();
4075afe1 1145 do_align (temp, &temp_fill);
6efd877d
KR
1146 }
1147 else
4075afe1 1148 do_align (temp, (char *) 0);
6efd877d 1149
18c9057f
ILT
1150 if (flag_mri)
1151 mri_comment_end (stop, stopc);
1152
6efd877d 1153 demand_empty_rest_of_line ();
4075afe1 1154}
6efd877d
KR
1155
1156void
604633ae
ILT
1157s_comm (ignore)
1158 int ignore;
6efd877d
KR
1159{
1160 register char *name;
1161 register char c;
1162 register char *p;
58d4951d 1163 offsetT temp;
6efd877d 1164 register symbolS *symbolP;
18c9057f
ILT
1165 char *stop = NULL;
1166 char stopc;
1167
1168 if (flag_mri)
1169 stop = mri_comment_field (&stopc);
6efd877d
KR
1170
1171 name = input_line_pointer;
1172 c = get_symbol_end ();
1173 /* just after name is now '\0' */
1174 p = input_line_pointer;
1175 *p = c;
1176 SKIP_WHITESPACE ();
1177 if (*input_line_pointer != ',')
1178 {
1179 as_bad ("Expected comma after symbol-name: rest of line ignored.");
18c9057f
ILT
1180 if (flag_mri)
1181 mri_comment_end (stop, stopc);
6efd877d
KR
1182 ignore_rest_of_line ();
1183 return;
1184 }
1185 input_line_pointer++; /* skip ',' */
1186 if ((temp = get_absolute_expression ()) < 0)
1187 {
58d4951d 1188 as_warn (".COMMon length (%ld.) <0! Ignored.", (long) temp);
18c9057f
ILT
1189 if (flag_mri)
1190 mri_comment_end (stop, stopc);
6efd877d
KR
1191 ignore_rest_of_line ();
1192 return;
1193 }
1194 *p = 0;
1195 symbolP = symbol_find_or_make (name);
1196 *p = c;
1197 if (S_IS_DEFINED (symbolP))
1198 {
6ef37255
KR
1199 as_bad ("Ignoring attempt to re-define symbol `%s'.",
1200 S_GET_NAME (symbolP));
18c9057f
ILT
1201 if (flag_mri)
1202 mri_comment_end (stop, stopc);
6efd877d
KR
1203 ignore_rest_of_line ();
1204 return;
1205 }
1206 if (S_GET_VALUE (symbolP))
1207 {
58d4951d
ILT
1208 if (S_GET_VALUE (symbolP) != (valueT) temp)
1209 as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.",
6efd877d 1210 S_GET_NAME (symbolP),
58d4951d
ILT
1211 (long) S_GET_VALUE (symbolP),
1212 (long) temp);
6efd877d
KR
1213 }
1214 else
1215 {
58d4951d 1216 S_SET_VALUE (symbolP, (valueT) temp);
6efd877d
KR
1217 S_SET_EXTERNAL (symbolP);
1218 }
9471a360 1219#ifdef OBJ_VMS
def66e24
DM
1220 {
1221 extern int flag_one;
1222 if ( (!temp) || !flag_one)
1223 S_GET_OTHER(symbolP) = const_flag;
1224 }
9471a360 1225#endif /* not OBJ_VMS */
6efd877d 1226 know (symbolP->sy_frag == &zero_address_frag);
18c9057f
ILT
1227
1228 if (flag_mri)
1229 mri_comment_end (stop, stopc);
1230
6efd877d
KR
1231 demand_empty_rest_of_line ();
1232} /* s_comm() */
fecd2382 1233
1356d77d
ILT
1234/* The MRI COMMON pseudo-op. We handle this by creating a common
1235 symbol with the appropriate name. We make s_space do the right
1236 thing by increasing the size. */
1237
1238void
1239s_mri_common (small)
1240 int small;
1241{
1242 char *name;
1243 char c;
1244 char *alc = NULL;
1245 symbolS *sym;
1246 offsetT align;
18c9057f
ILT
1247 char *stop = NULL;
1248 char stopc;
1356d77d
ILT
1249
1250 if (! flag_mri)
1251 {
1252 s_comm (0);
1253 return;
1254 }
1255
18c9057f
ILT
1256 stop = mri_comment_field (&stopc);
1257
1356d77d
ILT
1258 SKIP_WHITESPACE ();
1259
1260 name = input_line_pointer;
1261 if (! isdigit ((unsigned char) *name))
1262 c = get_symbol_end ();
1263 else
1264 {
1265 do
1266 {
1267 ++input_line_pointer;
1268 }
1269 while (isdigit ((unsigned char) *input_line_pointer));
1270 c = *input_line_pointer;
1271 *input_line_pointer = '\0';
1272
7e047ac2 1273 if (line_label != NULL)
1356d77d 1274 {
7e047ac2 1275 alc = (char *) xmalloc (strlen (S_GET_NAME (line_label))
1356d77d
ILT
1276 + (input_line_pointer - name)
1277 + 1);
7e047ac2 1278 sprintf (alc, "%s%s", name, S_GET_NAME (line_label));
1356d77d
ILT
1279 name = alc;
1280 }
1281 }
1282
1283 sym = symbol_find_or_make (name);
1284 *input_line_pointer = c;
1285 if (alc != NULL)
1286 free (alc);
1287
1288 if (*input_line_pointer != ',')
1289 align = 0;
1290 else
1291 {
1292 ++input_line_pointer;
1293 align = get_absolute_expression ();
1294 }
1295
1296 if (S_IS_DEFINED (sym))
1297 {
1298#if defined (S_IS_COMMON) || defined (BFD_ASSEMBLER)
1299 if (! S_IS_COMMON (sym))
1300#endif
1301 {
1302 as_bad ("attempt to re-define symbol `%s'", S_GET_NAME (sym));
18c9057f 1303 mri_comment_end (stop, stopc);
1356d77d
ILT
1304 ignore_rest_of_line ();
1305 return;
1306 }
1307 }
1308
1309 S_SET_EXTERNAL (sym);
1310 mri_common_symbol = sym;
1311
1312#ifdef S_SET_ALIGN
1313 if (align != 0)
1314 S_SET_ALIGN (sym, align);
1315#endif
1316
7e047ac2 1317 if (line_label != NULL)
1356d77d 1318 {
7e047ac2
ILT
1319 line_label->sy_value.X_op = O_symbol;
1320 line_label->sy_value.X_add_symbol = sym;
1321 line_label->sy_value.X_add_number = S_GET_VALUE (sym);
1322 line_label->sy_frag = &zero_address_frag;
1323 S_SET_SEGMENT (line_label, expr_section);
1356d77d
ILT
1324 }
1325
1326 /* FIXME: We just ignore the small argument, which distinguishes
1327 COMMON and COMMON.S. I don't know what we can do about it. */
1328
1329 /* Ignore the type and hptype. */
1330 if (*input_line_pointer == ',')
1331 input_line_pointer += 2;
1332 if (*input_line_pointer == ',')
1333 input_line_pointer += 2;
18c9057f
ILT
1334
1335 mri_comment_end (stop, stopc);
1336
1356d77d
ILT
1337 demand_empty_rest_of_line ();
1338}
1339
fecd2382 1340void
604633ae
ILT
1341s_data (ignore)
1342 int ignore;
fecd2382 1343{
ffffc8fb 1344 segT section;
6efd877d 1345 register int temp;
f8701a3f 1346
6efd877d 1347 temp = get_absolute_expression ();
def66e24 1348 if (flag_readonly_data_in_text)
ffffc8fb
ILT
1349 {
1350 section = text_section;
1351 temp += 1000;
1352 }
1353 else
1354 section = data_section;
1355
ffffc8fb 1356 subseg_set (section, (subsegT) temp);
f8701a3f 1357
9471a360 1358#ifdef OBJ_VMS
6efd877d 1359 const_flag = 0;
fecd2382 1360#endif
6efd877d 1361 demand_empty_rest_of_line ();
fecd2382
RP
1362}
1363
9a7d824a 1364/* Handle the .appfile pseudo-op. This is automatically generated by
86038ada
ILT
1365 do_scrub_chars when a preprocessor # line comment is seen with a
1366 file name. This default definition may be overridden by the object
1367 or CPU specific pseudo-ops. This function is also the default
1368 definition for .file; the APPFILE argument is 1 for .appfile, 0 for
1369 .file. */
9a7d824a 1370
6efd877d 1371void
9a7d824a
ILT
1372s_app_file (appfile)
1373 int appfile;
6efd877d
KR
1374{
1375 register char *s;
1376 int length;
f8701a3f 1377
6efd877d
KR
1378 /* Some assemblers tolerate immediately following '"' */
1379 if ((s = demand_copy_string (&length)) != 0)
1380 {
9a7d824a
ILT
1381 /* If this is a fake .appfile, a fake newline was inserted into
1382 the buffer. Passing -2 to new_logical_line tells it to
1383 account for it. */
1384 new_logical_line (s, appfile ? -2 : -1);
6efd877d 1385 demand_empty_rest_of_line ();
9a7d824a
ILT
1386#ifdef LISTING
1387 if (listing)
1388 listing_source_file (s);
1389#endif
6efd877d 1390 }
2209b19c
KR
1391#ifdef obj_app_file
1392 obj_app_file (s);
40324362
KR
1393#endif
1394}
fecd2382 1395
9a7d824a 1396/* Handle the .appline pseudo-op. This is automatically generated by
86038ada
ILT
1397 do_scrub_chars when a preprocessor # line comment is seen. This
1398 default definition may be overridden by the object or CPU specific
1399 pseudo-ops. */
9a7d824a
ILT
1400
1401void
604633ae
ILT
1402s_app_line (ignore)
1403 int ignore;
9a7d824a
ILT
1404{
1405 int l;
1406
1407 /* The given number is that of the next line. */
1408 l = get_absolute_expression () - 1;
931a8fab
KR
1409 if (l < 0)
1410 /* Some of the back ends can't deal with non-positive line numbers.
1411 Besides, it's silly. */
1412 as_warn ("Line numbers must be positive; line number %d rejected.", l+1);
1413 else
1414 {
1415 new_logical_line ((char *) NULL, l);
9a7d824a 1416#ifdef LISTING
931a8fab
KR
1417 if (listing)
1418 listing_source_line (l);
9a7d824a 1419#endif
931a8fab 1420 }
9a7d824a
ILT
1421 demand_empty_rest_of_line ();
1422}
1423
e28c40d7
ILT
1424/* Handle the .end pseudo-op. Actually, the real work is done in
1425 read_a_source_file. */
1426
1427void
1428s_end (ignore)
1429 int ignore;
1430{
1431 if (flag_mri)
1432 {
1433 /* The MRI assembler permits the start symbol to follow .end,
1434 but we don't support that. */
1435 SKIP_WHITESPACE ();
18c9057f
ILT
1436 if (! is_end_of_line[(unsigned char) *input_line_pointer]
1437 && *input_line_pointer != '*'
1438 && *input_line_pointer != '!')
e28c40d7
ILT
1439 as_warn ("start address not supported");
1440 }
1441}
1442
42ac8fa8
ILT
1443/* Handle the .err pseudo-op. */
1444
1445void
1446s_err (ignore)
1447 int ignore;
1448{
1449 as_bad (".err encountered");
1450 demand_empty_rest_of_line ();
1451}
1452
e28c40d7
ILT
1453/* Handle the MRI fail pseudo-op. */
1454
1455void
1456s_fail (ignore)
1457 int ignore;
1458{
1459 offsetT temp;
18c9057f
ILT
1460 char *stop = NULL;
1461 char stopc;
1462
1463 if (flag_mri)
1464 stop = mri_comment_field (&stopc);
e28c40d7
ILT
1465
1466 temp = get_absolute_expression ();
1467 if (temp >= 500)
1468 as_warn (".fail %ld encountered", (long) temp);
1469 else
1470 as_bad (".fail %ld encountered", (long) temp);
18c9057f
ILT
1471
1472 if (flag_mri)
1473 mri_comment_end (stop, stopc);
1474
e28c40d7
ILT
1475 demand_empty_rest_of_line ();
1476}
1477
6efd877d 1478void
604633ae
ILT
1479s_fill (ignore)
1480 int ignore;
6efd877d
KR
1481{
1482 long temp_repeat = 0;
1483 long temp_size = 1;
1484 register long temp_fill = 0;
1485 char *p;
f8701a3f 1486
7c2d4011 1487
6efd877d
KR
1488 temp_repeat = get_absolute_expression ();
1489 if (*input_line_pointer == ',')
1490 {
1491 input_line_pointer++;
1492 temp_size = get_absolute_expression ();
1493 if (*input_line_pointer == ',')
7c2d4011
SC
1494 {
1495 input_line_pointer++;
6efd877d 1496 temp_fill = get_absolute_expression ();
fecd2382 1497 }
6efd877d 1498 }
c8863a58 1499 /* This is to be compatible with BSD 4.2 AS, not for any rational reason. */
fecd2382 1500#define BSD_FILL_SIZE_CROCK_8 (8)
6efd877d
KR
1501 if (temp_size > BSD_FILL_SIZE_CROCK_8)
1502 {
1503 as_warn (".fill size clamped to %d.", BSD_FILL_SIZE_CROCK_8);
1504 temp_size = BSD_FILL_SIZE_CROCK_8;
1505 }
1506 if (temp_size < 0)
1507 {
1508 as_warn ("Size negative: .fill ignored.");
1509 temp_size = 0;
1510 }
1511 else if (temp_repeat <= 0)
1512 {
1513 as_warn ("Repeat < 0, .fill ignored");
1514 temp_size = 0;
1515 }
7fd3560a 1516
6efd877d
KR
1517 if (temp_size && !need_pass_2)
1518 {
1519 p = frag_var (rs_fill, (int) temp_size, (int) temp_size, (relax_substateT) 0, (symbolS *) 0, temp_repeat, (char *) 0);
604633ae 1520 memset (p, 0, (unsigned int) temp_size);
c8863a58
KR
1521 /* The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX
1522 * flavoured AS. The following bizzare behaviour is to be
1523 * compatible with above. I guess they tried to take up to 8
1524 * bytes from a 4-byte expression and they forgot to sign
1525 * extend. Un*x Sux. */
fecd2382 1526#define BSD_FILL_SIZE_CROCK_4 (4)
604633ae 1527 md_number_to_chars (p, (valueT) temp_fill,
c8863a58
KR
1528 (temp_size > BSD_FILL_SIZE_CROCK_4
1529 ? BSD_FILL_SIZE_CROCK_4
1530 : (int) temp_size));
1531 /* Note: .fill (),0 emits no frag (since we are asked to .fill 0 bytes)
1532 * but emits no error message because it seems a legal thing to do.
1533 * It is a degenerate case of .fill but could be emitted by a compiler.
1534 */
6efd877d 1535 }
6efd877d 1536 demand_empty_rest_of_line ();
f8701a3f
SC
1537}
1538
6efd877d 1539void
604633ae
ILT
1540s_globl (ignore)
1541 int ignore;
6efd877d 1542{
40324362
KR
1543 char *name;
1544 int c;
1545 symbolS *symbolP;
18c9057f
ILT
1546 char *stop = NULL;
1547 char stopc;
1548
1549 if (flag_mri)
1550 stop = mri_comment_field (&stopc);
fecd2382 1551
6efd877d
KR
1552 do
1553 {
1554 name = input_line_pointer;
1555 c = get_symbol_end ();
1556 symbolP = symbol_find_or_make (name);
1557 *input_line_pointer = c;
1558 SKIP_WHITESPACE ();
1559 S_SET_EXTERNAL (symbolP);
1560 if (c == ',')
1561 {
1562 input_line_pointer++;
1563 SKIP_WHITESPACE ();
1564 if (*input_line_pointer == '\n')
1565 c = '\n';
1566 }
1567 }
1568 while (c == ',');
18c9057f
ILT
1569
1570 if (flag_mri)
1571 mri_comment_end (stop, stopc);
1572
6efd877d 1573 demand_empty_rest_of_line ();
40324362 1574}
6efd877d 1575
7e047ac2
ILT
1576/* Handle the MRI IRP and IRPC pseudo-ops. */
1577
1578void
1579s_irp (irpc)
1580 int irpc;
1581{
1582 char *file;
1583 unsigned int line;
1584 sb s;
1585 const char *err;
1586 sb out;
1587
1588 as_where (&file, &line);
1589
1590 sb_new (&s);
1591 while (! is_end_of_line[(unsigned char) *input_line_pointer])
1592 sb_add_char (&s, *input_line_pointer++);
1593
1594 sb_new (&out);
1595
1596 err = expand_irp (irpc, 0, &s, &out, get_line_sb, '\0');
1597 if (err != NULL)
1598 as_bad_where (file, line, "%s", err);
1599
1600 sb_kill (&s);
1601
1602 input_scrub_include_sb (&out, input_line_pointer);
1603 sb_kill (&out);
1604 buffer_limit = input_scrub_next_buffer (&input_line_pointer);
1605}
1606
6efd877d
KR
1607void
1608s_lcomm (needs_align)
c8863a58
KR
1609 /* 1 if this was a ".bss" directive, which may require a 3rd argument
1610 (alignment); 0 if it was an ".lcomm" (2 args only) */
1611 int needs_align;
fecd2382 1612{
6efd877d
KR
1613 register char *name;
1614 register char c;
1615 register char *p;
1616 register int temp;
1617 register symbolS *symbolP;
9a7d824a
ILT
1618 segT current_seg = now_seg;
1619 subsegT current_subseg = now_subseg;
6efd877d
KR
1620 const int max_alignment = 15;
1621 int align = 0;
9a7d824a 1622 segT bss_seg = bss_section;
6efd877d
KR
1623
1624 name = input_line_pointer;
1625 c = get_symbol_end ();
1626 p = input_line_pointer;
1627 *p = c;
1628 SKIP_WHITESPACE ();
46b81190
ILT
1629
1630 /* Accept an optional comma after the name. The comma used to be
1631 required, but Irix 5 cc does not generate it. */
1632 if (*input_line_pointer == ',')
6efd877d 1633 {
46b81190
ILT
1634 ++input_line_pointer;
1635 SKIP_WHITESPACE ();
6efd877d 1636 }
f8701a3f 1637
6efd877d
KR
1638 if (*input_line_pointer == '\n')
1639 {
1640 as_bad ("Missing size expression");
1641 return;
1642 }
f8701a3f 1643
6efd877d
KR
1644 if ((temp = get_absolute_expression ()) < 0)
1645 {
1646 as_warn ("BSS length (%d.) <0! Ignored.", temp);
1647 ignore_rest_of_line ();
1648 return;
1649 }
f8701a3f 1650
2ef7731d 1651#if defined (TC_MIPS) || defined (TC_ALPHA)
a2a5a4fa
KR
1652 if (OUTPUT_FLAVOR == bfd_target_ecoff_flavour
1653 || OUTPUT_FLAVOR == bfd_target_elf_flavour)
46b81190 1654 {
a2a5a4fa
KR
1655 /* For MIPS and Alpha ECOFF or ELF, small objects are put in .sbss. */
1656 if (temp <= bfd_get_gp_size (stdoutput))
1657 {
1658 bss_seg = subseg_new (".sbss", 1);
1659 seg_info (bss_seg)->bss = 1;
1660 }
46b81190 1661 }
9a7d824a 1662#endif
ede7bc1c
SC
1663 if (!needs_align)
1664 {
1665 /* FIXME. This needs to be machine independent. */
9d90491e
ILT
1666 if (temp >= 8)
1667 align = 3;
1668 else if (temp >= 4)
ede7bc1c
SC
1669 align = 2;
1670 else if (temp >= 2)
1671 align = 1;
1672 else
c71a604a 1673 align = 0;
ede7bc1c
SC
1674
1675 record_alignment(bss_seg, align);
1676 }
9a7d824a 1677
6efd877d
KR
1678 if (needs_align)
1679 {
1680 align = 0;
1681 SKIP_WHITESPACE ();
1682 if (*input_line_pointer != ',')
1683 {
1684 as_bad ("Expected comma after size");
1685 ignore_rest_of_line ();
1686 return;
1687 }
1688 input_line_pointer++;
1689 SKIP_WHITESPACE ();
1690 if (*input_line_pointer == '\n')
1691 {
1692 as_bad ("Missing alignment");
1693 return;
1694 }
1695 align = get_absolute_expression ();
1696 if (align > max_alignment)
1697 {
1698 align = max_alignment;
1699 as_warn ("Alignment too large: %d. assumed.", align);
1700 }
1701 else if (align < 0)
1702 {
1703 align = 0;
1704 as_warn ("Alignment negative. 0 assumed.");
1705 }
9a7d824a 1706 record_alignment (bss_seg, align);
6efd877d 1707 } /* if needs align */
4075afe1
KR
1708 else
1709 {
1710 /* Assume some objects may require alignment on some systems. */
1711#ifdef TC_ALPHA
1712 if (temp > 1)
1713 {
1714 align = ffs (temp) - 1;
1715 if (temp % (1 << align))
1716 abort ();
1717 }
1718#endif
1719 }
f8701a3f 1720
6efd877d
KR
1721 *p = 0;
1722 symbolP = symbol_find_or_make (name);
1723 *p = c;
f8701a3f 1724
6efd877d 1725 if (
fecd2382 1726#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
6efd877d
KR
1727 S_GET_OTHER (symbolP) == 0 &&
1728 S_GET_DESC (symbolP) == 0 &&
fecd2382 1729#endif /* OBJ_AOUT or OBJ_BOUT */
9a7d824a 1730 (S_GET_SEGMENT (symbolP) == bss_seg
6efd877d
KR
1731 || (!S_IS_DEFINED (symbolP) && S_GET_VALUE (symbolP) == 0)))
1732 {
604633ae 1733 char *pfrag;
85825401 1734
9a7d824a 1735 subseg_set (bss_seg, 1);
85825401
ILT
1736
1737 if (align)
1738 frag_align (align, 0);
1739 /* detach from old frag */
9a7d824a 1740 if (S_GET_SEGMENT (symbolP) == bss_seg)
85825401
ILT
1741 symbolP->sy_frag->fr_symbol = NULL;
1742
1743 symbolP->sy_frag = frag_now;
604633ae
ILT
1744 pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP,
1745 temp, (char *)0);
1746 *pfrag = 0;
f8701a3f 1747
9a7d824a 1748 S_SET_SEGMENT (symbolP, bss_seg);
85825401 1749
fecd2382 1750#ifdef OBJ_COFF
6efd877d 1751 /* The symbol may already have been created with a preceding
c8863a58
KR
1752 ".globl" directive -- be careful not to step on storage class
1753 in that case. Otherwise, set it to static. */
6efd877d
KR
1754 if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
1755 {
1756 S_SET_STORAGE_CLASS (symbolP, C_STAT);
fecd2382 1757 }
6efd877d 1758#endif /* OBJ_COFF */
6efd877d
KR
1759 }
1760 else
6ef37255
KR
1761 as_bad ("Ignoring attempt to re-define symbol `%s'.",
1762 S_GET_NAME (symbolP));
f8701a3f 1763
9a7d824a 1764 subseg_set (current_seg, current_subseg);
9a7d824a
ILT
1765
1766 demand_empty_rest_of_line ();
6efd877d 1767} /* s_lcomm() */
fecd2382 1768
6efd877d 1769void
604633ae
ILT
1770s_lsym (ignore)
1771 int ignore;
6efd877d
KR
1772{
1773 register char *name;
1774 register char c;
1775 register char *p;
6efd877d
KR
1776 expressionS exp;
1777 register symbolS *symbolP;
1778
1779 /* we permit ANY defined expression: BSD4.2 demands constants */
1780 name = input_line_pointer;
1781 c = get_symbol_end ();
1782 p = input_line_pointer;
1783 *p = c;
1784 SKIP_WHITESPACE ();
1785 if (*input_line_pointer != ',')
1786 {
1787 *p = 0;
1788 as_bad ("Expected comma after name \"%s\"", name);
1789 *p = c;
1790 ignore_rest_of_line ();
1791 return;
1792 }
1793 input_line_pointer++;
b31f2abb
KR
1794 expression (&exp);
1795 if (exp.X_op != O_constant
1796 && exp.X_op != O_register)
1797 {
1798 as_bad ("bad expression");
1799 ignore_rest_of_line ();
1800 return;
1801 }
6efd877d
KR
1802 *p = 0;
1803 symbolP = symbol_find_or_make (name);
f8701a3f 1804
c8863a58
KR
1805 /* FIXME-SOON I pulled a (&& symbolP->sy_other == 0 &&
1806 symbolP->sy_desc == 0) out of this test because coff doesn't have
1807 those fields, and I can't see when they'd ever be tripped. I
1808 don't think I understand why they were here so I may have
1809 introduced a bug. As recently as 1.37 didn't have this test
1810 anyway. xoxorich. */
f8701a3f 1811
9471a360 1812 if (S_GET_SEGMENT (symbolP) == undefined_section
6efd877d
KR
1813 && S_GET_VALUE (symbolP) == 0)
1814 {
c8863a58
KR
1815 /* The name might be an undefined .global symbol; be sure to
1816 keep the "external" bit. */
b31f2abb
KR
1817 S_SET_SEGMENT (symbolP,
1818 (exp.X_op == O_constant
1819 ? absolute_section
1820 : reg_section));
1821 S_SET_VALUE (symbolP, (valueT) exp.X_add_number);
6efd877d
KR
1822 }
1823 else
1824 {
1825 as_bad ("Symbol %s already defined", name);
1826 }
1827 *p = c;
1828 demand_empty_rest_of_line ();
1829} /* s_lsym() */
1830
7e047ac2
ILT
1831/* Read a line into an sb. */
1832
1833static int
1834get_line_sb (line)
1835 sb *line;
1836{
1837 if (input_line_pointer >= buffer_limit)
1838 {
1839 buffer_limit = input_scrub_next_buffer (&input_line_pointer);
1840 if (buffer_limit == 0)
1841 return 0;
1842 }
1843
1844 while (! is_end_of_line[(unsigned char) *input_line_pointer])
1845 sb_add_char (line, *input_line_pointer++);
42ac8fa8
ILT
1846 while (input_line_pointer < buffer_limit
1847 && is_end_of_line[(unsigned char) *input_line_pointer])
7e047ac2
ILT
1848 {
1849 if (*input_line_pointer == '\n')
1850 {
1851 bump_line_counters ();
1852 LISTING_NEWLINE ();
1853 }
1854 ++input_line_pointer;
1855 }
1856 return 1;
1857}
1858
1859/* Define a macro. This is an interface to macro.c, which is shared
1860 between gas and gasp. */
1861
1862void
1863s_macro (ignore)
1864 int ignore;
1865{
1866 char *file;
1867 unsigned int line;
1868 sb s;
1869 sb label;
1870 const char *err;
1871
1872 as_where (&file, &line);
1873
1874 sb_new (&s);
1875 while (! is_end_of_line[(unsigned char) *input_line_pointer])
1876 sb_add_char (&s, *input_line_pointer++);
1877
1878 sb_new (&label);
1879 if (line_label != NULL)
1880 sb_add_string (&label, S_GET_NAME (line_label));
1881
1882 demand_empty_rest_of_line ();
1883
1884 err = define_macro (0, &s, &label, get_line_sb);
1885 if (err != NULL)
1886 as_bad_where (file, line, "%s", err);
1887 else
1888 {
1889 if (line_label != NULL)
1890 {
1891 S_SET_SEGMENT (line_label, undefined_section);
1892 S_SET_VALUE (line_label, 0);
1893 line_label->sy_frag = &zero_address_frag;
1894 }
1895 }
1896
1897 sb_kill (&s);
1898}
1899
1900/* Handle the .mexit pseudo-op, which immediately exits a macro
1901 expansion. */
1902
1903void
1904s_mexit (ignore)
1905 int ignore;
1906{
1907 buffer_limit = input_scrub_next_buffer (&input_line_pointer);
1908}
1909
e28c40d7
ILT
1910/* Handle changing the location counter. */
1911
1912static void
1913do_org (segment, exp, fill)
1914 segT segment;
1915 expressionS *exp;
1916 int fill;
1917{
1918 if (segment != now_seg && segment != absolute_section)
1919 as_bad ("invalid segment \"%s\"; segment \"%s\" assumed",
1920 segment_name (segment), segment_name (now_seg));
1921
1922 if (now_seg == absolute_section)
1923 {
1924 if (fill != 0)
1925 as_warn ("ignoring fill value in absolute section");
1926 if (exp->X_op != O_constant)
1927 {
1928 as_bad ("only constant offsets supported in absolute section");
1929 exp->X_add_number = 0;
1930 }
1931 abs_section_offset = exp->X_add_number;
1932 }
1933 else
1934 {
1935 char *p;
1936
1937 p = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp->X_add_symbol,
1938 exp->X_add_number, (char *) NULL);
1939 *p = fill;
1940 }
1941}
1942
6efd877d 1943void
604633ae
ILT
1944s_org (ignore)
1945 int ignore;
6efd877d
KR
1946{
1947 register segT segment;
1948 expressionS exp;
1949 register long temp_fill;
e28c40d7 1950
42ac8fa8
ILT
1951#ifdef TC_M68K
1952 /* The m68k MRI assembler has a different meaning for .org. It
1953 means to create an absolute section at a given address. We can't
1954 support that--use a linker script instead. */
69e077f3
ILT
1955 if (flag_mri)
1956 {
1957 as_bad ("MRI style ORG pseudo-op not supported");
1958 ignore_rest_of_line ();
1959 return;
1960 }
42ac8fa8 1961#endif
69e077f3 1962
9471a360
KR
1963 /* Don't believe the documentation of BSD 4.2 AS. There is no such
1964 thing as a sub-segment-relative origin. Any absolute origin is
1965 given a warning, then assumed to be segment-relative. Any
1966 segmented origin expression ("foo+42") had better be in the right
1967 segment or the .org is ignored.
1968
1969 BSD 4.2 AS warns if you try to .org backwards. We cannot because
1970 we never know sub-segment sizes when we are reading code. BSD
1971 will crash trying to emit negative numbers of filler bytes in
1972 certain .orgs. We don't crash, but see as-write for that code.
1973
1974 Don't make frag if need_pass_2==1. */
6efd877d
KR
1975 segment = get_known_segmented_expression (&exp);
1976 if (*input_line_pointer == ',')
1977 {
1978 input_line_pointer++;
1979 temp_fill = get_absolute_expression ();
1980 }
1981 else
1982 temp_fill = 0;
e28c40d7 1983
6efd877d 1984 if (!need_pass_2)
e28c40d7
ILT
1985 do_org (segment, &exp, temp_fill);
1986
6efd877d
KR
1987 demand_empty_rest_of_line ();
1988} /* s_org() */
1989
e14994d9
ILT
1990/* Handle parsing for the MRI SECT/SECTION pseudo-op. This should be
1991 called by the obj-format routine which handles section changing
1992 when in MRI mode. It will create a new section, and return it. It
1993 will set *TYPE to the section type: one of '\0' (unspecified), 'C'
1994 (code), 'D' (data), 'M' (mixed), or 'R' (romable). If
1995 BFD_ASSEMBLER is defined, the flags will be set in the section. */
1996
1997void
1998s_mri_sect (type)
1999 char *type;
2000{
42ac8fa8
ILT
2001#ifdef TC_M68K
2002
e14994d9
ILT
2003 char *name;
2004 char c;
2005 segT seg;
2006
2007 SKIP_WHITESPACE ();
2008
2009 name = input_line_pointer;
2010 if (! isdigit ((unsigned char) *name))
2011 c = get_symbol_end ();
2012 else
2013 {
2014 do
2015 {
2016 ++input_line_pointer;
2017 }
2018 while (isdigit ((unsigned char) *input_line_pointer));
2019 c = *input_line_pointer;
2020 *input_line_pointer = '\0';
2021 }
2022
2023 name = strdup (name);
2024 if (name == NULL)
2025 as_fatal ("virtual memory exhausted");
2026
2027 *input_line_pointer = c;
2028
2029 seg = subseg_new (name, 0);
2030
2031 if (*input_line_pointer == ',')
2032 {
2033 int align;
2034
2035 ++input_line_pointer;
2036 align = get_absolute_expression ();
2037 record_alignment (seg, align);
2038 }
2039
2040 *type = '\0';
2041 if (*input_line_pointer == ',')
2042 {
2043 c = *++input_line_pointer;
2044 c = toupper ((unsigned char) c);
2045 if (c == 'C' || c == 'D' || c == 'M' || c == 'R')
2046 *type = c;
2047 else
2048 as_bad ("unrecognized section type");
2049 ++input_line_pointer;
2050
2051#ifdef BFD_ASSEMBLER
2052 {
2053 flagword flags;
2054
2055 flags = SEC_NO_FLAGS;
ca232972 2056 if (*type == 'C')
e14994d9 2057 flags = SEC_CODE;
ca232972 2058 else if (*type == 'D')
e14994d9 2059 flags = SEC_DATA;
ca232972 2060 else if (*type == 'R')
e14994d9
ILT
2061 flags = SEC_ROM;
2062 if (flags != SEC_NO_FLAGS)
2063 {
2064 if (! bfd_set_section_flags (stdoutput, seg, flags))
2065 as_warn ("error setting flags for \"%s\": %s",
ca232972 2066 bfd_section_name (stdoutput, seg),
e14994d9
ILT
2067 bfd_errmsg (bfd_get_error ()));
2068 }
2069 }
2070#endif
2071 }
2072
2073 /* Ignore the HP type. */
2074 if (*input_line_pointer == ',')
2075 input_line_pointer += 2;
2076
2077 demand_empty_rest_of_line ();
42ac8fa8
ILT
2078
2079#else /* ! TC_M68K */
2080#ifdef TC_I960
2081
2082 char *name;
2083 char c;
2084 segT seg;
2085
2086 SKIP_WHITESPACE ();
2087
2088 name = input_line_pointer;
2089 c = get_symbol_end ();
2090
2091 name = strdup (name);
2092 if (name == NULL)
2093 as_fatal ("virtual memory exhausted");
2094
2095 *input_line_pointer = c;
2096
2097 seg = subseg_new (name, 0);
2098
2099 if (*input_line_pointer != ',')
2100 *type = 'C';
2101 else
2102 {
2103 char *sectype;
2104
2105 ++input_line_pointer;
2106 SKIP_WHITESPACE ();
2107 sectype = input_line_pointer;
2108 c = get_symbol_end ();
2109 if (*sectype == '\0')
2110 *type = 'C';
2111 else if (strcasecmp (sectype, "text") == 0)
2112 *type = 'C';
2113 else if (strcasecmp (sectype, "data") == 0)
2114 *type = 'D';
2115 else if (strcasecmp (sectype, "romdata") == 0)
2116 *type = 'R';
2117 else
2118 as_warn ("unrecognized section type `%s'", sectype);
2119 *input_line_pointer = c;
2120 }
2121
2122 if (*input_line_pointer == ',')
2123 {
2124 char *seccmd;
2125
2126 ++input_line_pointer;
2127 SKIP_WHITESPACE ();
2128 seccmd = input_line_pointer;
2129 c = get_symbol_end ();
2130 if (strcasecmp (seccmd, "absolute") == 0)
2131 {
2132 as_bad ("absolute sections are not supported");
2133 *input_line_pointer = c;
2134 ignore_rest_of_line ();
2135 return;
2136 }
2137 else if (strcasecmp (seccmd, "align") == 0)
2138 {
2139 int align;
2140
2141 *input_line_pointer = c;
2142 align = get_absolute_expression ();
2143 record_alignment (seg, align);
2144 }
2145 else
2146 {
2147 as_warn ("unrecognized section command `%s'", seccmd);
2148 *input_line_pointer = c;
2149 }
2150 }
2151
2152 demand_empty_rest_of_line ();
2153
2154#else /* ! TC_I960 */
2155 /* The MRI assembler seems to use different forms of .sect for
2156 different targets. */
2157 abort ();
2158#endif /* ! TC_I960 */
2159#endif /* ! TC_M68K */
2160}
2161
2162/* Handle the .print pseudo-op. */
2163
2164void
2165s_print (ignore)
2166 int ignore;
2167{
2168 char *s;
2169 int len;
2170
2171 s = demand_copy_C_string (&len);
2172 printf ("%s\n", s);
2173 demand_empty_rest_of_line ();
2174}
2175
2176/* Handle the .purgem pseudo-op. */
2177
2178void
2179s_purgem (ignore)
2180 int ignore;
2181{
2182 if (is_it_end_of_statement ())
2183 {
2184 demand_empty_rest_of_line ();
2185 return;
2186 }
2187
2188 do
2189 {
2190 char *name;
2191 char c;
2192
2193 SKIP_WHITESPACE ();
2194 name = input_line_pointer;
2195 c = get_symbol_end ();
2196 delete_macro (name);
2197 *input_line_pointer = c;
2198 SKIP_WHITESPACE ();
2199 }
2200 while (*input_line_pointer++ == ',');
2201
2202 --input_line_pointer;
2203 demand_empty_rest_of_line ();
e14994d9
ILT
2204}
2205
7e047ac2
ILT
2206/* Handle the .rept pseudo-op. */
2207
2208void
2209s_rept (ignore)
2210 int ignore;
2211{
2212 int count;
2213 sb one;
2214 sb many;
2215
2216 count = get_absolute_expression ();
2217
2218 sb_new (&one);
2219 if (! buffer_and_nest ("REPT", "ENDR", &one, get_line_sb))
2220 {
2221 as_bad ("rept without endr");
2222 return;
2223 }
2224
2225 sb_new (&many);
2226 while (count-- > 0)
2227 sb_add_sb (&many, &one);
2228
2229 sb_kill (&one);
2230
2231 input_scrub_include_sb (&many, input_line_pointer);
2232 sb_kill (&many);
2233 buffer_limit = input_scrub_next_buffer (&input_line_pointer);
2234}
2235
6efd877d 2236void
604633ae
ILT
2237s_set (ignore)
2238 int ignore;
6efd877d
KR
2239{
2240 register char *name;
2241 register char delim;
2242 register char *end_name;
2243 register symbolS *symbolP;
2244
2245 /*
c8863a58
KR
2246 * Especial apologies for the random logic:
2247 * this just grew, and could be parsed much more simply!
2248 * Dean in haste.
2249 */
6efd877d
KR
2250 name = input_line_pointer;
2251 delim = get_symbol_end ();
2252 end_name = input_line_pointer;
2253 *end_name = delim;
2254 SKIP_WHITESPACE ();
f8701a3f 2255
6efd877d
KR
2256 if (*input_line_pointer != ',')
2257 {
2258 *end_name = 0;
2259 as_bad ("Expected comma after name \"%s\"", name);
2260 *end_name = delim;
2261 ignore_rest_of_line ();
2262 return;
2263 }
2264
2265 input_line_pointer++;
2266 *end_name = 0;
2267
2268 if (name[0] == '.' && name[1] == '\0')
2269 {
2270 /* Turn '. = mumble' into a .org mumble */
2271 register segT segment;
2272 expressionS exp;
6efd877d
KR
2273
2274 segment = get_known_segmented_expression (&exp);
f8701a3f 2275
6efd877d 2276 if (!need_pass_2)
e28c40d7 2277 do_org (segment, &exp, 0);
6efd877d
KR
2278
2279 *end_name = delim;
2280 return;
2281 }
2282
2283 if ((symbolP = symbol_find (name)) == NULL
2284 && (symbolP = md_undefined_symbol (name)) == NULL)
2285 {
9471a360 2286 symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
fecd2382 2287#ifdef OBJ_COFF
6efd877d
KR
2288 /* "set" symbols are local unless otherwise specified. */
2289 SF_SET_LOCAL (symbolP);
fecd2382 2290#endif /* OBJ_COFF */
f8701a3f 2291
6efd877d 2292 } /* make a new symbol */
f8701a3f 2293
6efd877d 2294 symbol_table_insert (symbolP);
f8701a3f 2295
6efd877d
KR
2296 *end_name = delim;
2297 pseudo_set (symbolP);
2298 demand_empty_rest_of_line ();
2299} /* s_set() */
fecd2382 2300
6efd877d
KR
2301void
2302s_space (mult)
2303 int mult;
b53ccaac 2304{
cd3b81bd 2305 expressionS exp;
931a8fab 2306 long temp_fill;
cd3b81bd 2307 char *p = 0;
3dce804d
ILT
2308 char *stop = NULL;
2309 char stopc;
6efd877d 2310
a2a5a4fa
KR
2311#ifdef md_flush_pending_output
2312 md_flush_pending_output ();
2313#endif
2314
3dce804d 2315 if (flag_mri)
18c9057f 2316 stop = mri_comment_field (&stopc);
3dce804d 2317
6efd877d 2318 /* Just like .fill, but temp_size = 1 */
cd3b81bd 2319 expression (&exp);
931a8fab 2320 if (exp.X_op == O_constant)
6efd877d 2321 {
cd3b81bd
KR
2322 long repeat;
2323
2324 repeat = exp.X_add_number;
2325 if (mult)
2326 repeat *= mult;
2327 if (repeat <= 0)
2328 {
4026c122
ILT
2329 if (! flag_mri || repeat < 0)
2330 as_warn (".space repeat count is %s, ignored",
2331 repeat ? "negative" : "zero");
3dce804d 2332 goto getout;
cd3b81bd
KR
2333 }
2334
e28c40d7
ILT
2335 /* If we are in the absolute section, just bump the offset. */
2336 if (now_seg == absolute_section)
2337 {
2338 abs_section_offset += repeat;
3dce804d 2339 goto getout;
e28c40d7
ILT
2340 }
2341
1356d77d
ILT
2342 /* If we are secretly in an MRI common section, then creating
2343 space just increases the size of the common symbol. */
2344 if (mri_common_symbol != NULL)
2345 {
2346 S_SET_VALUE (mri_common_symbol,
2347 S_GET_VALUE (mri_common_symbol) + repeat);
3dce804d 2348 goto getout;
1356d77d
ILT
2349 }
2350
cd3b81bd
KR
2351 if (!need_pass_2)
2352 p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0,
931a8fab 2353 repeat, (char *) 0);
6efd877d
KR
2354 }
2355 else
2356 {
e28c40d7
ILT
2357 if (now_seg == absolute_section)
2358 {
2359 as_bad ("space allocation too complex in absolute section");
2360 subseg_set (text_section, 0);
2361 }
1356d77d
ILT
2362 if (mri_common_symbol != NULL)
2363 {
2364 as_bad ("space allocation too complex in common section");
2365 mri_common_symbol = NULL;
2366 }
cd3b81bd
KR
2367 if (!need_pass_2)
2368 p = frag_var (rs_space, 1, 1, (relax_substateT) 0,
2369 make_expr_symbol (&exp), 0L, (char *) 0);
6efd877d 2370 }
931a8fab
KR
2371 SKIP_WHITESPACE ();
2372 if (*input_line_pointer == ',')
6efd877d 2373 {
931a8fab 2374 input_line_pointer++;
cd3b81bd 2375 temp_fill = get_absolute_expression ();
6efd877d 2376 }
cd3b81bd 2377 else
6efd877d 2378 {
cd3b81bd 2379 temp_fill = 0;
6efd877d 2380 }
cd3b81bd 2381 if (p)
6efd877d 2382 {
6efd877d
KR
2383 *p = temp_fill;
2384 }
3dce804d
ILT
2385
2386 getout:
2387 if (flag_mri)
18c9057f 2388 mri_comment_end (stop, stopc);
3dce804d 2389
6efd877d 2390 demand_empty_rest_of_line ();
cd3b81bd 2391}
fecd2382 2392
e28c40d7
ILT
2393/* This is like s_space, but the value is a floating point number with
2394 the given precision. This is for the MRI dcb.s pseudo-op and
2395 friends. */
2396
2397void
2398s_float_space (float_type)
2399 int float_type;
2400{
2401 offsetT count;
2402 int flen;
2403 char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
18c9057f
ILT
2404 char *stop = NULL;
2405 char stopc;
2406
2407 if (flag_mri)
2408 stop = mri_comment_field (&stopc);
e28c40d7
ILT
2409
2410 count = get_absolute_expression ();
2411
2412 SKIP_WHITESPACE ();
2413 if (*input_line_pointer != ',')
2414 {
2415 as_bad ("missing value");
18c9057f
ILT
2416 if (flag_mri)
2417 mri_comment_end (stop, stopc);
e28c40d7
ILT
2418 ignore_rest_of_line ();
2419 return;
2420 }
2421
2422 ++input_line_pointer;
2423
2424 SKIP_WHITESPACE ();
2425
2426 /* Skip any 0{letter} that may be present. Don't even check if the
2427 * letter is legal. */
2428 if (input_line_pointer[0] == '0' && isalpha (input_line_pointer[1]))
2429 input_line_pointer += 2;
2430
2431 /* Accept :xxxx, where the x's are hex digits, for a floating point
2432 with the exact digits specified. */
2433 if (input_line_pointer[0] == ':')
2434 {
2435 flen = hex_float (float_type, temp);
2436 if (flen < 0)
2437 {
18c9057f
ILT
2438 if (flag_mri)
2439 mri_comment_end (stop, stopc);
e28c40d7
ILT
2440 ignore_rest_of_line ();
2441 return;
2442 }
2443 }
2444 else
2445 {
2446 char *err;
2447
2448 err = md_atof (float_type, temp, &flen);
2449 know (flen <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
2450 know (flen > 0);
2451 if (err)
2452 {
2453 as_bad ("Bad floating literal: %s", err);
18c9057f
ILT
2454 if (flag_mri)
2455 mri_comment_end (stop, stopc);
e28c40d7
ILT
2456 ignore_rest_of_line ();
2457 return;
2458 }
2459 }
2460
2461 while (--count >= 0)
2462 {
2463 char *p;
2464
2465 p = frag_more (flen);
2466 memcpy (p, temp, (unsigned int) flen);
2467 }
2468
18c9057f
ILT
2469 if (flag_mri)
2470 mri_comment_end (stop, stopc);
2471
e28c40d7
ILT
2472 demand_empty_rest_of_line ();
2473}
2474
2475/* Handle the .struct pseudo-op, as found in MIPS assemblers. */
2476
2477void
2478s_struct (ignore)
2479 int ignore;
2480{
18c9057f
ILT
2481 char *stop = NULL;
2482 char stopc;
2483
2484 if (flag_mri)
2485 stop = mri_comment_field (&stopc);
e28c40d7
ILT
2486 abs_section_offset = get_absolute_expression ();
2487 subseg_set (absolute_section, 0);
18c9057f
ILT
2488 if (flag_mri)
2489 mri_comment_end (stop, stopc);
e28c40d7
ILT
2490 demand_empty_rest_of_line ();
2491}
2492
fecd2382 2493void
604633ae
ILT
2494s_text (ignore)
2495 int ignore;
fecd2382 2496{
6efd877d 2497 register int temp;
f8701a3f 2498
6efd877d 2499 temp = get_absolute_expression ();
9471a360 2500 subseg_set (text_section, (subsegT) temp);
6efd877d 2501 demand_empty_rest_of_line ();
80d80c64
KR
2502#ifdef OBJ_VMS
2503 const_flag &= ~IN_DEFAULT_SECTION;
2504#endif
6efd877d 2505} /* s_text() */
fecd2382 2506\f
6efd877d 2507
6efd877d
KR
2508void
2509demand_empty_rest_of_line ()
2510{
2511 SKIP_WHITESPACE ();
58d4951d 2512 if (is_end_of_line[(unsigned char) *input_line_pointer])
6efd877d
KR
2513 {
2514 input_line_pointer++;
2515 }
2516 else
2517 {
2518 ignore_rest_of_line ();
2519 }
2520 /* Return having already swallowed end-of-line. */
2521} /* Return pointing just after end-of-line. */
fecd2382
RP
2522
2523void
6efd877d 2524ignore_rest_of_line () /* For suspect lines: gives warning. */
fecd2382 2525{
58d4951d 2526 if (!is_end_of_line[(unsigned char) *input_line_pointer])
f8701a3f 2527 {
6efd877d
KR
2528 if (isprint (*input_line_pointer))
2529 as_bad ("Rest of line ignored. First ignored character is `%c'.",
f8701a3f
SC
2530 *input_line_pointer);
2531 else
6efd877d 2532 as_bad ("Rest of line ignored. First ignored character valued 0x%x.",
f8701a3f
SC
2533 *input_line_pointer);
2534 while (input_line_pointer < buffer_limit
58d4951d 2535 && !is_end_of_line[(unsigned char) *input_line_pointer])
f8701a3f 2536 {
6efd877d 2537 input_line_pointer++;
f8701a3f
SC
2538 }
2539 }
6efd877d 2540 input_line_pointer++; /* Return pointing just after end-of-line. */
58d4951d 2541 know (is_end_of_line[(unsigned char) input_line_pointer[-1]]);
fecd2382
RP
2542}
2543
2544/*
2545 * pseudo_set()
2546 *
2547 * In: Pointer to a symbol.
2548 * Input_line_pointer->expression.
2549 *
2550 * Out: Input_line_pointer->just after any whitespace after expression.
2551 * Tried to set symbol to value of expression.
2552 * Will change symbols type, value, and frag;
fecd2382
RP
2553 */
2554void
f8701a3f 2555pseudo_set (symbolP)
6efd877d 2556 symbolS *symbolP;
fecd2382 2557{
6efd877d 2558 expressionS exp;
daad3bbf 2559#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER)
f8701a3f 2560 int ext;
fecd2382 2561#endif /* OBJ_AOUT or OBJ_BOUT */
f8701a3f 2562
6efd877d 2563 know (symbolP); /* NULL pointer is logic error. */
daad3bbf 2564#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER)
6efd877d 2565 ext = S_IS_EXTERNAL (symbolP);
fecd2382 2566#endif /* OBJ_AOUT or OBJ_BOUT */
f8701a3f 2567
5ac34ac3 2568 (void) expression (&exp);
f8701a3f 2569
5ac34ac3
ILT
2570 if (exp.X_op == O_illegal)
2571 as_bad ("illegal expression; zero assumed");
2572 else if (exp.X_op == O_absent)
2573 as_bad ("missing expression; zero assumed");
2574 else if (exp.X_op == O_big)
2575 as_bad ("%s number invalid; zero assumed",
2576 exp.X_add_number > 0 ? "bignum" : "floating point");
2577 else if (exp.X_op == O_subtract
2578 && (S_GET_SEGMENT (exp.X_add_symbol)
2579 == S_GET_SEGMENT (exp.X_op_symbol))
2580 && SEG_NORMAL (S_GET_SEGMENT (exp.X_add_symbol))
2581 && exp.X_add_symbol->sy_frag == exp.X_op_symbol->sy_frag)
9471a360 2582 {
5ac34ac3
ILT
2583 exp.X_op = O_constant;
2584 exp.X_add_number = (S_GET_VALUE (exp.X_add_symbol)
2585 - S_GET_VALUE (exp.X_op_symbol));
9471a360 2586 }
5ac34ac3
ILT
2587
2588 switch (exp.X_op)
9471a360 2589 {
5ac34ac3
ILT
2590 case O_illegal:
2591 case O_absent:
2592 case O_big:
2593 exp.X_add_number = 0;
2594 /* Fall through. */
2595 case O_constant:
9471a360 2596 S_SET_SEGMENT (symbolP, absolute_section);
daad3bbf 2597#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER)
5ac34ac3
ILT
2598 if (ext)
2599 S_SET_EXTERNAL (symbolP);
6efd877d 2600 else
6efd877d 2601 S_CLEAR_EXTERNAL (symbolP);
fecd2382 2602#endif /* OBJ_AOUT or OBJ_BOUT */
604633ae 2603 S_SET_VALUE (symbolP, (valueT) exp.X_add_number);
6efd877d 2604 symbolP->sy_frag = &zero_address_frag;
5ac34ac3 2605 break;
f8701a3f 2606
5ac34ac3
ILT
2607 case O_register:
2608 S_SET_SEGMENT (symbolP, reg_section);
604633ae 2609 S_SET_VALUE (symbolP, (valueT) exp.X_add_number);
5ac34ac3
ILT
2610 symbolP->sy_frag = &zero_address_frag;
2611 break;
2612
2613 case O_symbol:
ef198870
KR
2614 if (S_GET_SEGMENT (exp.X_add_symbol) == undefined_section
2615 || exp.X_add_number != 0)
5ac34ac3 2616 symbolP->sy_value = exp;
6efd877d
KR
2617 else
2618 {
80d80c64
KR
2619 symbolS *s = exp.X_add_symbol;
2620
2621 S_SET_SEGMENT (symbolP, S_GET_SEGMENT (s));
daad3bbf 2622#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER)
5ac34ac3
ILT
2623 if (ext)
2624 S_SET_EXTERNAL (symbolP);
2625 else
2626 S_CLEAR_EXTERNAL (symbolP);
fecd2382 2627#endif /* OBJ_AOUT or OBJ_BOUT */
5ac34ac3 2628 S_SET_VALUE (symbolP,
80d80c64
KR
2629 exp.X_add_number + S_GET_VALUE (s));
2630 symbolP->sy_frag = s->sy_frag;
ef198870 2631 copy_symbol_attributes (symbolP, s);
5ac34ac3
ILT
2632 }
2633 break;
f8701a3f 2634
5ac34ac3
ILT
2635 default:
2636 /* The value is some complex expression.
2637 FIXME: Should we set the segment to anything? */
2638 symbolP->sy_value = exp;
2639 break;
f8701a3f 2640 }
fecd2382
RP
2641}
2642\f
2643/*
2644 * cons()
2645 *
2646 * CONStruct more frag of .bytes, or .words etc.
2647 * Should need_pass_2 be 1 then emit no frag(s).
80aab579 2648 * This understands EXPRESSIONS.
fecd2382
RP
2649 *
2650 * Bug (?)
2651 *
2652 * This has a split personality. We use expression() to read the
2653 * value. We can detect if the value won't fit in a byte or word.
2654 * But we can't detect if expression() discarded significant digits
2655 * in the case of a long. Not worth the crocks required to fix it.
2656 */
2657
40324362
KR
2658/* Select a parser for cons expressions. */
2659
2660/* Some targets need to parse the expression in various fancy ways.
2661 You can define TC_PARSE_CONS_EXPRESSION to do whatever you like
2662 (for example, the HPPA does this). Otherwise, you can define
2663 BITFIELD_CONS_EXPRESSIONS to permit bitfields to be specified, or
2664 REPEAT_CONS_EXPRESSIONS to permit repeat counts. If none of these
2665 are defined, which is the normal case, then only simple expressions
2666 are permitted. */
2667
1356d77d
ILT
2668static void
2669parse_mri_cons PARAMS ((expressionS *exp, unsigned int nbytes));
2670
40324362
KR
2671#ifndef TC_PARSE_CONS_EXPRESSION
2672#ifdef BITFIELD_CONS_EXPRESSIONS
2673#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_bitfield_cons (EXP, NBYTES)
2674static void
2675parse_bitfield_cons PARAMS ((expressionS *exp, unsigned int nbytes));
2676#endif
40324362
KR
2677#ifdef REPEAT_CONS_EXPRESSIONS
2678#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_repeat_cons (EXP, NBYTES)
2679static void
2680parse_repeat_cons PARAMS ((expressionS *exp, unsigned int nbytes));
2681#endif
2682
2683/* If we haven't gotten one yet, just call expression. */
2684#ifndef TC_PARSE_CONS_EXPRESSION
2685#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) expression (EXP)
2686#endif
2687#endif
2688
6efd877d
KR
2689/* worker to do .byte etc statements */
2690/* clobbers input_line_pointer, checks */
2691/* end-of-line. */
86038ada
ILT
2692static void
2693cons_worker (nbytes, rva)
604633ae 2694 register int nbytes; /* 1=.byte, 2=.word, 4=.long */
86038ada 2695 int rva;
fecd2382 2696{
286cb27a 2697 int c;
6efd877d 2698 expressionS exp;
86038ada 2699 char *stop = NULL;
3dce804d 2700 char stopc;
f8701a3f 2701
a2a5a4fa
KR
2702#ifdef md_flush_pending_output
2703 md_flush_pending_output ();
2704#endif
2705
18c9057f
ILT
2706 if (flag_mri)
2707 stop = mri_comment_field (&stopc);
2708
40324362 2709 if (is_it_end_of_statement ())
6efd877d 2710 {
18c9057f 2711 mri_comment_end (stop, stopc);
40324362
KR
2712 demand_empty_rest_of_line ();
2713 return;
6efd877d 2714 }
40324362 2715
286cb27a 2716 c = 0;
40324362 2717 do
6efd877d 2718 {
86038ada
ILT
2719 if (rva)
2720 {
2721 /* If this is an .rva pseudoop then stick
2722 an extra reloc in for this word. */
2723 int reloc;
2724 char *p = frag_more (0);
2725 exp.X_op = O_absent;
2726
2727#ifdef BFD_ASSEMBLER
2728 reloc = BFD_RELOC_RVA;
94a73122
ILT
2729#else
2730#ifdef TC_RVA_RELOC
86038ada
ILT
2731 reloc = TC_RVA_RELOC;
2732#else
2733 abort();
94a73122 2734#endif
86038ada
ILT
2735#endif
2736 fix_new_exp (frag_now, p - frag_now->fr_literal,
2737 nbytes, &exp, 0, reloc);
2738
2739 }
1356d77d
ILT
2740 if (flag_mri)
2741 parse_mri_cons (&exp, (unsigned int) nbytes);
2742 else
2743 TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes);
86038ada 2744 emit_expr (&exp, (unsigned int) nbytes);
286cb27a 2745 ++c;
40324362 2746 }
18c9057f 2747 while (*input_line_pointer++ == ',');
40324362 2748
286cb27a
ILT
2749 /* In MRI mode, after an odd number of bytes, we must align to an
2750 even word boundary, unless the next instruction is a dc.b, ds.b
2751 or dcb.b. */
2752 if (flag_mri && nbytes == 1 && (c & 1) != 0)
2753 mri_pending_align = 1;
2754
40324362 2755 input_line_pointer--; /* Put terminator back into stream. */
86038ada
ILT
2756
2757 if (flag_mri)
18c9057f 2758 mri_comment_end (stop, stopc);
86038ada 2759
40324362 2760 demand_empty_rest_of_line ();
30d3a445 2761}
f8701a3f 2762
86038ada
ILT
2763
2764void
2765cons (size)
2766 int size;
2767{
2768 cons_worker (size, 0);
2769}
2770
2771void
2772s_rva (size)
2773 int size;
2774{
2775 cons_worker (size, 1);
2776}
2777
2778
40324362
KR
2779/* Put the contents of expression EXP into the object file using
2780 NBYTES bytes. If need_pass_2 is 1, this does nothing. */
f8701a3f 2781
40324362
KR
2782void
2783emit_expr (exp, nbytes)
2784 expressionS *exp;
2785 unsigned int nbytes;
2786{
5ac34ac3 2787 operatorT op;
40324362 2788 register char *p;
80aab579 2789 valueT extra_digit = 0;
f8701a3f 2790
40324362
KR
2791 /* Don't do anything if we are going to make another pass. */
2792 if (need_pass_2)
2793 return;
2794
5ac34ac3 2795 op = exp->X_op;
40324362 2796
e28c40d7
ILT
2797 /* Allow `.word 0' in the absolute section. */
2798 if (now_seg == absolute_section)
2799 {
2800 if (op != O_constant || exp->X_add_number != 0)
2801 as_bad ("attempt to store value in absolute section");
2802 abs_section_offset += nbytes;
2803 return;
2804 }
2805
80aab579
ILT
2806 /* Handle a negative bignum. */
2807 if (op == O_uminus
2808 && exp->X_add_number == 0
2809 && exp->X_add_symbol->sy_value.X_op == O_big
2810 && exp->X_add_symbol->sy_value.X_add_number > 0)
2811 {
2812 int i;
2813 unsigned long carry;
2814
2815 exp = &exp->X_add_symbol->sy_value;
2816
2817 /* Negate the bignum: one's complement each digit and add 1. */
2818 carry = 1;
2819 for (i = 0; i < exp->X_add_number; i++)
2820 {
2821 unsigned long next;
2822
2823 next = (((~ (generic_bignum[i] & LITTLENUM_MASK))
2824 & LITTLENUM_MASK)
2825 + carry);
2826 generic_bignum[i] = next & LITTLENUM_MASK;
2827 carry = next >> LITTLENUM_NUMBER_OF_BITS;
2828 }
2829
2830 /* We can ignore any carry out, because it will be handled by
2831 extra_digit if it is needed. */
2832
2833 extra_digit = (valueT) -1;
2834 op = O_big;
2835 }
2836
5ac34ac3 2837 if (op == O_absent || op == O_illegal)
6efd877d 2838 {
5ac34ac3
ILT
2839 as_warn ("zero assumed for missing expression");
2840 exp->X_add_number = 0;
2841 op = O_constant;
6efd877d 2842 }
80aab579 2843 else if (op == O_big && exp->X_add_number <= 0)
6efd877d 2844 {
80aab579 2845 as_bad ("floating point number invalid; zero assumed");
40324362 2846 exp->X_add_number = 0;
5ac34ac3 2847 op = O_constant;
40324362 2848 }
5ac34ac3 2849 else if (op == O_register)
6efd877d 2850 {
5ac34ac3
ILT
2851 as_warn ("register value used as expression");
2852 op = O_constant;
40324362 2853 }
6efd877d 2854
604633ae 2855 p = frag_more ((int) nbytes);
6efd877d 2856
40324362
KR
2857#ifndef WORKING_DOT_WORD
2858 /* If we have the difference of two symbols in a word, save it on
2859 the broken_words list. See the code in write.c. */
5ac34ac3 2860 if (op == O_subtract && nbytes == 2)
40324362
KR
2861 {
2862 struct broken_word *x;
2863
2864 x = (struct broken_word *) xmalloc (sizeof (struct broken_word));
2865 x->next_broken_word = broken_words;
2866 broken_words = x;
2867 x->frag = frag_now;
2868 x->word_goes_here = p;
2869 x->dispfrag = 0;
2870 x->add = exp->X_add_symbol;
5ac34ac3 2871 x->sub = exp->X_op_symbol;
40324362
KR
2872 x->addnum = exp->X_add_number;
2873 x->added = 0;
2874 new_broken_words++;
2875 return;
2876 }
f8701a3f 2877#endif
6efd877d 2878
80aab579
ILT
2879 /* If we have an integer, but the number of bytes is too large to
2880 pass to md_number_to_chars, handle it as a bignum. */
2881 if (op == O_constant && nbytes > sizeof (valueT))
2882 {
2883 valueT val;
2884 int gencnt;
2885
2886 if (! exp->X_unsigned && exp->X_add_number < 0)
2887 extra_digit = (valueT) -1;
2888 val = (valueT) exp->X_add_number;
2889 gencnt = 0;
2890 do
2891 {
2892 generic_bignum[gencnt] = val & LITTLENUM_MASK;
2893 val >>= LITTLENUM_NUMBER_OF_BITS;
2894 ++gencnt;
2895 }
2896 while (val != 0);
2897 op = exp->X_op = O_big;
2898 exp->X_add_number = gencnt;
2899 }
2900
5ac34ac3 2901 if (op == O_constant)
40324362 2902 {
44ce2f32
DE
2903 register valueT get;
2904 register valueT use;
2905 register valueT mask;
2906 register valueT unmask;
40324362
KR
2907
2908 /* JF << of >= number of bits in the object is undefined. In
2909 particular SPARC (Sun 4) has problems */
44ce2f32 2910 if (nbytes >= sizeof (valueT))
40324362
KR
2911 mask = 0;
2912 else
d2550c72 2913 mask = ~(valueT) 0 << (BITS_PER_CHAR * nbytes); /* Don't store these bits. */
6efd877d 2914
40324362 2915 unmask = ~mask; /* Do store these bits. */
6efd877d 2916
40324362
KR
2917#ifdef NEVER
2918 "Do this mod if you want every overflow check to assume SIGNED 2's complement data.";
2919 mask = ~(unmask >> 1); /* Includes sign bit now. */
2920#endif
6efd877d 2921
40324362
KR
2922 get = exp->X_add_number;
2923 use = get & unmask;
2924 if ((get & mask) != 0 && (get & mask) != mask)
2925 { /* Leading bits contain both 0s & 1s. */
58d4951d 2926 as_warn ("Value 0x%lx truncated to 0x%lx.", get, use);
40324362 2927 }
604633ae 2928 /* put bytes in right order. */
44ce2f32 2929 md_number_to_chars (p, use, (int) nbytes);
40324362 2930 }
80aab579
ILT
2931 else if (op == O_big)
2932 {
2933 int size;
2934 LITTLENUM_TYPE *nums;
2935
2936 know (nbytes % CHARS_PER_LITTLENUM == 0);
2937
2938 size = exp->X_add_number * CHARS_PER_LITTLENUM;
2939 if (nbytes < size)
2940 {
2941 as_warn ("Bignum truncated to %d bytes", nbytes);
2942 size = nbytes;
2943 }
2944
2945 if (target_big_endian)
2946 {
2947 while (nbytes > size)
2948 {
2949 md_number_to_chars (p, extra_digit, CHARS_PER_LITTLENUM);
2950 nbytes -= CHARS_PER_LITTLENUM;
2951 p += CHARS_PER_LITTLENUM;
2952 }
2953
2954 nums = generic_bignum + size / CHARS_PER_LITTLENUM;
2955 while (size > 0)
2956 {
2957 --nums;
2958 md_number_to_chars (p, (valueT) *nums, CHARS_PER_LITTLENUM);
2959 size -= CHARS_PER_LITTLENUM;
2960 p += CHARS_PER_LITTLENUM;
2961 }
2962 }
2963 else
2964 {
2965 nums = generic_bignum;
2966 while (size > 0)
2967 {
2968 md_number_to_chars (p, (valueT) *nums, CHARS_PER_LITTLENUM);
2969 ++nums;
2970 size -= CHARS_PER_LITTLENUM;
2971 p += CHARS_PER_LITTLENUM;
2972 nbytes -= CHARS_PER_LITTLENUM;
2973 }
2974
2975 while (nbytes > 0)
2976 {
2977 md_number_to_chars (p, extra_digit, CHARS_PER_LITTLENUM);
2978 nbytes -= CHARS_PER_LITTLENUM;
2979 p += CHARS_PER_LITTLENUM;
2980 }
2981 }
2982 }
40324362
KR
2983 else
2984 {
1fbfe108 2985 memset (p, 0, nbytes);
6efd877d 2986
40324362
KR
2987 /* Now we need to generate a fixS to record the symbol value.
2988 This is easy for BFD. For other targets it can be more
2989 complex. For very complex cases (currently, the HPPA and
2990 NS32K), you can define TC_CONS_FIX_NEW to do whatever you
2991 want. For simpler cases, you can define TC_CONS_RELOC to be
2992 the name of the reloc code that should be stored in the fixS.
2993 If neither is defined, the code uses NO_RELOC if it is
2994 defined, and otherwise uses 0. */
6efd877d 2995
40324362 2996#ifdef BFD_ASSEMBLER
4064305e
SS
2997#ifdef TC_CONS_FIX_NEW
2998 TC_CONS_FIX_NEW (frag_now, p - frag_now->fr_literal, nbytes, exp);
2999#else
604633ae 3000 fix_new_exp (frag_now, p - frag_now->fr_literal, (int) nbytes, exp, 0,
5ac34ac3 3001 /* @@ Should look at CPU word size. */
ba71c54d 3002 nbytes == 2 ? BFD_RELOC_16
86038ada
ILT
3003 : nbytes == 8 ? BFD_RELOC_64
3004 : BFD_RELOC_32);
4064305e 3005#endif
40324362
KR
3006#else
3007#ifdef TC_CONS_FIX_NEW
3008 TC_CONS_FIX_NEW (frag_now, p - frag_now->fr_literal, nbytes, exp);
3009#else
3010 /* Figure out which reloc number to use. Use TC_CONS_RELOC if
3011 it is defined, otherwise use NO_RELOC if it is defined,
3012 otherwise use 0. */
3013#ifndef TC_CONS_RELOC
3014#ifdef NO_RELOC
3015#define TC_CONS_RELOC NO_RELOC
3016#else
3017#define TC_CONS_RELOC 0
3018#endif
3019#endif
80aab579 3020 fix_new_exp (frag_now, p - frag_now->fr_literal, (int) nbytes, exp, 0,
5ac34ac3 3021 TC_CONS_RELOC);
40324362
KR
3022#endif /* TC_CONS_FIX_NEW */
3023#endif /* BFD_ASSEMBLER */
3024 }
3025}
3026\f
3027#ifdef BITFIELD_CONS_EXPRESSIONS
6efd877d 3028
40324362
KR
3029/* i960 assemblers, (eg, asm960), allow bitfields after ".byte" as
3030 w:x,y:z, where w and y are bitwidths and x and y are values. They
3031 then pack them all together. We do a little better in that we allow
3032 them in words, longs, etc. and we'll pack them in target byte order
3033 for you.
6efd877d 3034
40324362
KR
3035 The rules are: pack least significat bit first, if a field doesn't
3036 entirely fit, put it in the next unit. Overflowing the bitfield is
3037 explicitly *not* even a warning. The bitwidth should be considered
3038 a "mask".
6efd877d 3039
40324362
KR
3040 To use this function the tc-XXX.h file should define
3041 BITFIELD_CONS_EXPRESSIONS. */
f8701a3f 3042
40324362
KR
3043static void
3044parse_bitfield_cons (exp, nbytes)
3045 expressionS *exp;
3046 unsigned int nbytes;
3047{
3048 unsigned int bits_available = BITS_PER_CHAR * nbytes;
3049 char *hold = input_line_pointer;
f8701a3f 3050
5ac34ac3 3051 (void) expression (exp);
f8701a3f 3052
40324362
KR
3053 if (*input_line_pointer == ':')
3054 { /* bitfields */
3055 long value = 0;
f8701a3f 3056
40324362
KR
3057 for (;;)
3058 {
3059 unsigned long width;
f8701a3f 3060
40324362
KR
3061 if (*input_line_pointer != ':')
3062 {
3063 input_line_pointer = hold;
3064 break;
3065 } /* next piece is not a bitfield */
3066
3067 /* In the general case, we can't allow
3068 full expressions with symbol
3069 differences and such. The relocation
3070 entries for symbols not defined in this
3071 assembly would require arbitrary field
3072 widths, positions, and masks which most
3073 of our current object formats don't
3074 support.
cd3b81bd 3075
40324362
KR
3076 In the specific case where a symbol
3077 *is* defined in this assembly, we
3078 *could* build fixups and track it, but
3079 this could lead to confusion for the
3080 backends. I'm lazy. I'll take any
3081 SEG_ABSOLUTE. I think that means that
3082 you can use a previous .set or
3083 .equ type symbol. xoxorich. */
3084
5ac34ac3 3085 if (exp->X_op == O_absent)
6efd877d 3086 {
5ac34ac3 3087 as_warn ("using a bit field width of zero");
40324362 3088 exp->X_add_number = 0;
5ac34ac3 3089 exp->X_op = O_constant;
40324362
KR
3090 } /* implied zero width bitfield */
3091
5ac34ac3 3092 if (exp->X_op != O_constant)
6efd877d 3093 {
40324362 3094 *input_line_pointer = '\0';
5ac34ac3 3095 as_bad ("field width \"%s\" too complex for a bitfield", hold);
40324362
KR
3096 *input_line_pointer = ':';
3097 demand_empty_rest_of_line ();
3098 return;
3099 } /* too complex */
3100
3101 if ((width = exp->X_add_number) > (BITS_PER_CHAR * nbytes))
9471a360 3102 {
80aab579 3103 as_warn ("field width %lu too big to fit in %d bytes: truncated to %d bits",
40324362
KR
3104 width, nbytes, (BITS_PER_CHAR * nbytes));
3105 width = BITS_PER_CHAR * nbytes;
3106 } /* too big */
3107
3108 if (width > bits_available)
9471a360 3109 {
40324362
KR
3110 /* FIXME-SOMEDAY: backing up and reparsing is wasteful. */
3111 input_line_pointer = hold;
3112 exp->X_add_number = value;
3113 break;
3114 } /* won't fit */
3115
3116 hold = ++input_line_pointer; /* skip ':' */
3117
5ac34ac3
ILT
3118 (void) expression (exp);
3119 if (exp->X_op != O_constant)
9471a360 3120 {
40324362
KR
3121 char cache = *input_line_pointer;
3122
3123 *input_line_pointer = '\0';
5ac34ac3 3124 as_bad ("field value \"%s\" too complex for a bitfield", hold);
40324362
KR
3125 *input_line_pointer = cache;
3126 demand_empty_rest_of_line ();
3127 return;
3128 } /* too complex */
3129
5ac34ac3
ILT
3130 value |= ((~(-1 << width) & exp->X_add_number)
3131 << ((BITS_PER_CHAR * nbytes) - bits_available));
40324362
KR
3132
3133 if ((bits_available -= width) == 0
3134 || is_it_end_of_statement ()
3135 || *input_line_pointer != ',')
3136 {
3137 break;
3138 } /* all the bitfields we're gonna get */
3139
3140 hold = ++input_line_pointer;
5ac34ac3 3141 (void) expression (exp);
40324362
KR
3142 } /* forever loop */
3143
3144 exp->X_add_number = value;
5ac34ac3 3145 exp->X_op = O_constant;
80aab579 3146 exp->X_unsigned = 1;
40324362
KR
3147 } /* if looks like a bitfield */
3148} /* parse_bitfield_cons() */
3149
3150#endif /* BITFIELD_CONS_EXPRESSIONS */
3151\f
1356d77d 3152/* Handle an MRI style string expression. */
40324362
KR
3153
3154static void
3155parse_mri_cons (exp, nbytes)
3156 expressionS *exp;
3157 unsigned int nbytes;
3158{
1356d77d
ILT
3159 if (*input_line_pointer != '\''
3160 && (input_line_pointer[1] != '\''
3161 || (*input_line_pointer != 'A'
3162 && *input_line_pointer != 'E')))
3163 TC_PARSE_CONS_EXPRESSION (exp, nbytes);
3164 else
40324362 3165 {
40324362
KR
3166 int scan = 0;
3167 unsigned int result = 0;
1356d77d
ILT
3168
3169 /* An MRI style string. Cut into as many bytes as will fit into
3170 a nbyte chunk, left justify if necessary, and separate with
3171 commas so we can try again later. */
3172 if (*input_line_pointer == 'A')
3173 ++input_line_pointer;
3174 else if (*input_line_pointer == 'E')
3175 {
3176 as_bad ("EBCDIC constants are not supported");
3177 ++input_line_pointer;
3178 }
3179
40324362
KR
3180 input_line_pointer++;
3181 for (scan = 0; scan < nbytes; scan++)
3182 {
3183 if (*input_line_pointer == '\'')
3184 {
3185 if (input_line_pointer[1] == '\'')
6efd877d 3186 {
40324362 3187 input_line_pointer++;
f8701a3f 3188 }
40324362
KR
3189 else
3190 break;
9471a360 3191 }
40324362
KR
3192 result = (result << 8) | (*input_line_pointer++);
3193 }
f8701a3f 3194
40324362
KR
3195 /* Left justify */
3196 while (scan < nbytes)
3197 {
3198 result <<= 8;
3199 scan++;
3200 }
3201 /* Create correct expression */
5ac34ac3 3202 exp->X_op = O_constant;
40324362 3203 exp->X_add_number = result;
40324362
KR
3204 /* Fake it so that we can read the next char too */
3205 if (input_line_pointer[0] != '\'' ||
3206 (input_line_pointer[0] == '\'' && input_line_pointer[1] == '\''))
3207 {
3208 input_line_pointer -= 2;
3209 input_line_pointer[0] = ',';
3210 input_line_pointer[1] = '\'';
3211 }
3212 else
3213 input_line_pointer++;
3214 }
40324362 3215}
40324362
KR
3216\f
3217#ifdef REPEAT_CONS_EXPRESSIONS
3218
3219/* Parse a repeat expression for cons. This is used by the MIPS
3220 assembler. The format is NUMBER:COUNT; NUMBER appears in the
3221 object file COUNT times.
3222
3223 To use this for a target, define REPEAT_CONS_EXPRESSIONS. */
3224
3225static void
3226parse_repeat_cons (exp, nbytes)
3227 expressionS *exp;
3228 unsigned int nbytes;
3229{
3230 expressionS count;
40324362
KR
3231 register int i;
3232
3233 expression (exp);
3234
3235 if (*input_line_pointer != ':')
3236 {
3237 /* No repeat count. */
3238 return;
3239 }
3240
3241 ++input_line_pointer;
5ac34ac3
ILT
3242 expression (&count);
3243 if (count.X_op != O_constant
40324362
KR
3244 || count.X_add_number <= 0)
3245 {
3246 as_warn ("Unresolvable or nonpositive repeat count; using 1");
3247 return;
3248 }
3249
3250 /* The cons function is going to output this expression once. So we
3251 output it count - 1 times. */
3252 for (i = count.X_add_number - 1; i > 0; i--)
3253 emit_expr (exp, nbytes);
3254}
3255
3256#endif /* REPEAT_CONS_EXPRESSIONS */
fecd2382 3257\f
e28c40d7
ILT
3258/* Parse a floating point number represented as a hex constant. This
3259 permits users to specify the exact bits they want in the floating
3260 point number. */
3261
3262static int
3263hex_float (float_type, bytes)
3264 int float_type;
3265 char *bytes;
3266{
3267 int length;
3268 int i;
3269
3270 switch (float_type)
3271 {
3272 case 'f':
3273 case 'F':
3274 case 's':
3275 case 'S':
3276 length = 4;
3277 break;
3278
3279 case 'd':
3280 case 'D':
3281 case 'r':
3282 case 'R':
3283 length = 8;
3284 break;
3285
3286 case 'x':
3287 case 'X':
3288 length = 12;
3289 break;
3290
3291 case 'p':
3292 case 'P':
3293 length = 12;
3294 break;
3295
3296 default:
3297 as_bad ("Unknown floating type type '%c'", float_type);
3298 return -1;
3299 }
3300
3301 /* It would be nice if we could go through expression to parse the
3302 hex constant, but if we get a bignum it's a pain to sort it into
3303 the buffer correctly. */
3304 i = 0;
3305 while (hex_p (*input_line_pointer) || *input_line_pointer == '_')
3306 {
3307 int d;
3308
3309 /* The MRI assembler accepts arbitrary underscores strewn about
3310 through the hex constant, so we ignore them as well. */
3311 if (*input_line_pointer == '_')
3312 {
3313 ++input_line_pointer;
3314 continue;
3315 }
3316
3317 if (i >= length)
3318 {
3319 as_warn ("Floating point constant too large");
3320 return -1;
3321 }
3322 d = hex_value (*input_line_pointer) << 4;
3323 ++input_line_pointer;
3324 while (*input_line_pointer == '_')
3325 ++input_line_pointer;
3326 if (hex_p (*input_line_pointer))
3327 {
3328 d += hex_value (*input_line_pointer);
3329 ++input_line_pointer;
3330 }
a920b693
ILT
3331 if (target_big_endian)
3332 bytes[i] = d;
3333 else
3334 bytes[length - i - 1] = d;
3335 ++i;
e28c40d7
ILT
3336 }
3337
3338 if (i < length)
a920b693
ILT
3339 {
3340 if (target_big_endian)
3341 memset (bytes + i, 0, length - i);
3342 else
3343 memset (bytes, 0, length - i);
3344 }
e28c40d7
ILT
3345
3346 return length;
3347}
3348
fecd2382
RP
3349/*
3350 * float_cons()
3351 *
3352 * CONStruct some more frag chars of .floats .ffloats etc.
3353 * Makes 0 or more new frags.
3354 * If need_pass_2 == 1, no frags are emitted.
3355 * This understands only floating literals, not expressions. Sorry.
3356 *
3357 * A floating constant is defined by atof_generic(), except it is preceded
3358 * by 0d 0f 0g or 0h. After observing the STRANGE way my BSD AS does its
3359 * reading, I decided to be incompatible. This always tries to give you
3360 * rounded bits to the precision of the pseudo-op. Former AS did premature
3361 * truncatation, restored noisy bits instead of trailing 0s AND gave you
3362 * a choice of 2 flavours of noise according to which of 2 floating-point
3363 * scanners you directed AS to use.
3364 *
3365 * In: input_line_pointer->whitespace before, or '0' of flonum.
3366 *
3367 */
3368
ba71c54d
KR
3369void
3370float_cons (float_type)
6efd877d 3371 /* Clobbers input_line-pointer, checks end-of-line. */
f8701a3f 3372 register int float_type; /* 'f':.ffloat ... 'F':.float ... */
fecd2382 3373{
6efd877d 3374 register char *p;
6efd877d
KR
3375 int length; /* Number of chars in an object. */
3376 register char *err; /* Error from scanning floating literal. */
3377 char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
f8701a3f 3378
6efd877d 3379 if (is_it_end_of_statement ())
f8701a3f 3380 {
1e9cf565
ILT
3381 demand_empty_rest_of_line ();
3382 return;
f8701a3f 3383 }
1e9cf565
ILT
3384
3385 do
f8701a3f
SC
3386 {
3387 /* input_line_pointer->1st char of a flonum (we hope!). */
6efd877d 3388 SKIP_WHITESPACE ();
1e9cf565 3389
f8701a3f
SC
3390 /* Skip any 0{letter} that may be present. Don't even check if the
3391 * letter is legal. Someone may invent a "z" format and this routine
3392 * has no use for such information. Lusers beware: you get
3393 * diagnostics if your input is ill-conditioned.
3394 */
6efd877d
KR
3395 if (input_line_pointer[0] == '0' && isalpha (input_line_pointer[1]))
3396 input_line_pointer += 2;
f8701a3f 3397
1356d77d
ILT
3398 /* Accept :xxxx, where the x's are hex digits, for a floating
3399 point with the exact digits specified. */
3400 if (input_line_pointer[0] == ':')
f8701a3f 3401 {
e28c40d7
ILT
3402 ++input_line_pointer;
3403 length = hex_float (float_type, temp);
3404 if (length < 0)
1356d77d 3405 {
1356d77d
ILT
3406 ignore_rest_of_line ();
3407 return;
3408 }
1356d77d
ILT
3409 }
3410 else
3411 {
3412 err = md_atof (float_type, temp, &length);
3413 know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
3414 know (length > 0);
3415 if (err)
3416 {
3417 as_bad ("Bad floating literal: %s", err);
3418 ignore_rest_of_line ();
3419 return;
3420 }
f8701a3f 3421 }
1e9cf565
ILT
3422
3423 if (!need_pass_2)
f8701a3f 3424 {
1e9cf565
ILT
3425 int count;
3426
3427 count = 1;
3428
3429#ifdef REPEAT_CONS_EXPRESSIONS
3430 if (*input_line_pointer == ':')
3431 {
1e9cf565
ILT
3432 expressionS count_exp;
3433
3434 ++input_line_pointer;
5ac34ac3
ILT
3435 expression (&count_exp);
3436 if (count_exp.X_op != O_constant
1e9cf565
ILT
3437 || count_exp.X_add_number <= 0)
3438 {
5ac34ac3 3439 as_warn ("unresolvable or nonpositive repeat count; using 1");
1e9cf565
ILT
3440 }
3441 else
3442 count = count_exp.X_add_number;
3443 }
3444#endif
3445
3446 while (--count >= 0)
a39116f1 3447 {
f8701a3f 3448 p = frag_more (length);
604633ae 3449 memcpy (p, temp, (unsigned int) length);
a39116f1 3450 }
542e1629 3451 }
1e9cf565 3452 SKIP_WHITESPACE ();
f8701a3f 3453 }
1e9cf565
ILT
3454 while (*input_line_pointer++ == ',');
3455
3456 --input_line_pointer; /* Put terminator back into stream. */
6efd877d 3457 demand_empty_rest_of_line ();
f8701a3f 3458} /* float_cons() */
fecd2382
RP
3459\f
3460/*
3461 * stringer()
3462 *
3463 * We read 0 or more ',' seperated, double-quoted strings.
3464 *
3465 * Caller should have checked need_pass_2 is FALSE because we don't check it.
3466 */
a39116f1
RP
3467
3468
6efd877d
KR
3469void
3470stringer (append_zero) /* Worker to do .ascii etc statements. */
3471 /* Checks end-of-line. */
f8701a3f 3472 register int append_zero; /* 0: don't append '\0', else 1 */
fecd2382 3473{
f8701a3f 3474 register unsigned int c;
6efd877d 3475
a2a5a4fa
KR
3476#ifdef md_flush_pending_output
3477 md_flush_pending_output ();
3478#endif
3479
f8701a3f
SC
3480 /*
3481 * The following awkward logic is to parse ZERO or more strings,
3482 * comma seperated. Recall a string expression includes spaces
3483 * before the opening '\"' and spaces after the closing '\"'.
3484 * We fake a leading ',' if there is (supposed to be)
3485 * a 1st, expression. We keep demanding expressions for each
3486 * ','.
3487 */
6efd877d
KR
3488 if (is_it_end_of_statement ())
3489 {
3490 c = 0; /* Skip loop. */
3491 ++input_line_pointer; /* Compensate for end of loop. */
3492 }
f8701a3f 3493 else
6efd877d
KR
3494 {
3495 c = ','; /* Do loop. */
3496 }
3497 while (c == ',' || c == '<' || c == '"')
3498 {
3499 SKIP_WHITESPACE ();
3500 switch (*input_line_pointer)
3501 {
3502 case '\"':
3503 ++input_line_pointer; /*->1st char of string. */
3504 while (is_a_char (c = next_char_of_string ()))
3505 {
3506 FRAG_APPEND_1_CHAR (c);
3507 }
3508 if (append_zero)
3509 {
3510 FRAG_APPEND_1_CHAR (0);
3511 }
3512 know (input_line_pointer[-1] == '\"');
3513 break;
3514 case '<':
3515 input_line_pointer++;
3516 c = get_single_number ();
3517 FRAG_APPEND_1_CHAR (c);
3518 if (*input_line_pointer != '>')
3519 {
3520 as_bad ("Expected <nn>");
3521 }
3522 input_line_pointer++;
3523 break;
3524 case ',':
3525 input_line_pointer++;
3526 break;
3527 }
3528 SKIP_WHITESPACE ();
3529 c = *input_line_pointer;
f8701a3f 3530 }
f8701a3f 3531
6efd877d
KR
3532 demand_empty_rest_of_line ();
3533} /* stringer() */
fecd2382 3534\f
6efd877d 3535/* FIXME-SOMEDAY: I had trouble here on characters with the
f8701a3f
SC
3536 high bits set. We'll probably also have trouble with
3537 multibyte chars, wide chars, etc. Also be careful about
3538 returning values bigger than 1 byte. xoxorich. */
fecd2382 3539
6efd877d
KR
3540unsigned int
3541next_char_of_string ()
3542{
3543 register unsigned int c;
3544
3545 c = *input_line_pointer++ & CHAR_MASK;
3546 switch (c)
3547 {
3548 case '\"':
3549 c = NOT_A_CHAR;
3550 break;
3551
ddb393cf 3552#ifndef NO_STRING_ESCAPES
6efd877d
KR
3553 case '\\':
3554 switch (c = *input_line_pointer++)
3555 {
3556 case 'b':
3557 c = '\b';
3558 break;
3559
3560 case 'f':
3561 c = '\f';
3562 break;
3563
3564 case 'n':
3565 c = '\n';
3566 break;
3567
3568 case 'r':
3569 c = '\r';
3570 break;
3571
3572 case 't':
3573 c = '\t';
3574 break;
3575
6efd877d
KR
3576 case 'v':
3577 c = '\013';
3578 break;
6efd877d
KR
3579
3580 case '\\':
3581 case '"':
3582 break; /* As itself. */
3583
3584 case '0':
3585 case '1':
3586 case '2':
3587 case '3':
3588 case '4':
3589 case '5':
3590 case '6':
3591 case '7':
3592 case '8':
3593 case '9':
3594 {
3595 long number;
d4c8cbd8 3596 int i;
6efd877d 3597
d4c8cbd8 3598 for (i = 0, number = 0; isdigit (c) && i < 3; c = *input_line_pointer++, i++)
6efd877d
KR
3599 {
3600 number = number * 8 + c - '0';
3601 }
3602 c = number & 0xff;
3603 }
3604 --input_line_pointer;
3605 break;
3606
d4c8cbd8
JL
3607 case 'x':
3608 case 'X':
3609 {
3610 long number;
3611
3612 number = 0;
3613 c = *input_line_pointer++;
3614 while (isxdigit (c))
3615 {
3616 if (isdigit (c))
3617 number = number * 16 + c - '0';
3618 else if (isupper (c))
3619 number = number * 16 + c - 'A' + 10;
3620 else
3621 number = number * 16 + c - 'a' + 10;
3622 c = *input_line_pointer++;
3623 }
3624 c = number & 0xff;
3625 --input_line_pointer;
3626 }
3627 break;
3628
6efd877d
KR
3629 case '\n':
3630 /* To be compatible with BSD 4.2 as: give the luser a linefeed!! */
3631 as_warn ("Unterminated string: Newline inserted.");
3632 c = '\n';
3633 break;
3634
3635 default:
3636
fecd2382 3637#ifdef ONLY_STANDARD_ESCAPES
6efd877d
KR
3638 as_bad ("Bad escaped character in string, '?' assumed");
3639 c = '?';
fecd2382 3640#endif /* ONLY_STANDARD_ESCAPES */
6efd877d
KR
3641
3642 break;
3643 } /* switch on escaped char */
3644 break;
ddb393cf 3645#endif /* ! defined (NO_STRING_ESCAPES) */
6efd877d
KR
3646
3647 default:
3648 break;
3649 } /* switch on char */
3650 return (c);
3651} /* next_char_of_string() */
fecd2382
RP
3652\f
3653static segT
f8701a3f 3654get_segmented_expression (expP)
6efd877d 3655 register expressionS *expP;
fecd2382 3656{
6efd877d 3657 register segT retval;
f8701a3f 3658
9471a360 3659 retval = expression (expP);
5ac34ac3
ILT
3660 if (expP->X_op == O_illegal
3661 || expP->X_op == O_absent
3662 || expP->X_op == O_big)
f8701a3f 3663 {
5ac34ac3
ILT
3664 as_bad ("expected address expression; zero assumed");
3665 expP->X_op = O_constant;
6efd877d 3666 expP->X_add_number = 0;
5ac34ac3 3667 retval = absolute_section;
f8701a3f 3668 }
5ac34ac3 3669 return retval;
fecd2382
RP
3670}
3671
6efd877d
KR
3672static segT
3673get_known_segmented_expression (expP)
3674 register expressionS *expP;
fecd2382 3675{
6efd877d 3676 register segT retval;
f8701a3f 3677
9471a360 3678 if ((retval = get_segmented_expression (expP)) == undefined_section)
f8701a3f 3679 {
5ac34ac3
ILT
3680 /* There is no easy way to extract the undefined symbol from the
3681 expression. */
3682 if (expP->X_add_symbol != NULL
3683 && S_GET_SEGMENT (expP->X_add_symbol) != expr_section)
3684 as_warn ("symbol \"%s\" undefined; zero assumed",
3685 S_GET_NAME (expP->X_add_symbol));
f8701a3f 3686 else
5ac34ac3
ILT
3687 as_warn ("some symbol undefined; zero assumed");
3688 retval = absolute_section;
3689 expP->X_op = O_constant;
6efd877d 3690 expP->X_add_number = 0;
f8701a3f 3691 }
5ac34ac3 3692 know (retval == absolute_section || SEG_NORMAL (retval));
f8701a3f 3693 return (retval);
fecd2382
RP
3694} /* get_known_segmented_expression() */
3695
58d4951d 3696offsetT
f8701a3f 3697get_absolute_expression ()
fecd2382 3698{
6efd877d 3699 expressionS exp;
f8701a3f 3700
5ac34ac3
ILT
3701 expression (&exp);
3702 if (exp.X_op != O_constant)
f8701a3f 3703 {
5ac34ac3 3704 if (exp.X_op != O_absent)
cd3b81bd 3705 as_bad ("bad or irreducible absolute expression; zero assumed");
6efd877d 3706 exp.X_add_number = 0;
f8701a3f 3707 }
5ac34ac3 3708 return exp.X_add_number;
fecd2382
RP
3709}
3710
6efd877d
KR
3711char /* return terminator */
3712get_absolute_expression_and_terminator (val_pointer)
3713 long *val_pointer; /* return value of expression */
fecd2382 3714{
58d4951d
ILT
3715 /* FIXME: val_pointer should probably be offsetT *. */
3716 *val_pointer = (long) get_absolute_expression ();
6efd877d 3717 return (*input_line_pointer++);
fecd2382
RP
3718}
3719\f
3720/*
3721 * demand_copy_C_string()
3722 *
3723 * Like demand_copy_string, but return NULL if the string contains any '\0's.
3724 * Give a warning if that happens.
3725 */
3726char *
f8701a3f 3727demand_copy_C_string (len_pointer)
6efd877d 3728 int *len_pointer;
fecd2382 3729{
6efd877d 3730 register char *s;
f8701a3f 3731
6efd877d 3732 if ((s = demand_copy_string (len_pointer)) != 0)
f8701a3f
SC
3733 {
3734 register int len;
3735
6efd877d 3736 for (len = *len_pointer;
f8701a3f
SC
3737 len > 0;
3738 len--)
3739 {
6efd877d 3740 if (*s == 0)
fecd2382 3741 {
f8701a3f
SC
3742 s = 0;
3743 len = 1;
6efd877d
KR
3744 *len_pointer = 0;
3745 as_bad ("This string may not contain \'\\0\'");
fecd2382 3746 }
f8701a3f
SC
3747 }
3748 }
3749 return (s);
fecd2382
RP
3750}
3751\f
3752/*
3753 * demand_copy_string()
3754 *
3755 * Demand string, but return a safe (=private) copy of the string.
3756 * Return NULL if we can't read a string here.
3757 */
6ef37255 3758char *
6efd877d
KR
3759demand_copy_string (lenP)
3760 int *lenP;
fecd2382 3761{
6efd877d
KR
3762 register unsigned int c;
3763 register int len;
3764 char *retval;
3765
3766 len = 0;
3767 SKIP_WHITESPACE ();
3768 if (*input_line_pointer == '\"')
3769 {
3770 input_line_pointer++; /* Skip opening quote. */
3771
3772 while (is_a_char (c = next_char_of_string ()))
3773 {
3774 obstack_1grow (&notes, c);
3775 len++;
fecd2382 3776 }
42ac8fa8
ILT
3777 /* JF this next line is so demand_copy_C_string will return a
3778 null terminated string. */
6efd877d
KR
3779 obstack_1grow (&notes, '\0');
3780 retval = obstack_finish (&notes);
3781 }
3782 else
3783 {
3784 as_warn ("Missing string");
3785 retval = NULL;
3786 ignore_rest_of_line ();
3787 }
3788 *lenP = len;
3789 return (retval);
3790} /* demand_copy_string() */
fecd2382
RP
3791\f
3792/*
3793 * is_it_end_of_statement()
3794 *
3795 * In: Input_line_pointer->next character.
3796 *
3797 * Do: Skip input_line_pointer over all whitespace.
3798 *
3799 * Out: 1 if input_line_pointer->end-of-line.
f8701a3f 3800*/
6efd877d
KR
3801int
3802is_it_end_of_statement ()
3803{
3804 SKIP_WHITESPACE ();
58d4951d 3805 return (is_end_of_line[(unsigned char) *input_line_pointer]);
6efd877d 3806} /* is_it_end_of_statement() */
fecd2382 3807
6efd877d
KR
3808void
3809equals (sym_name)
3810 char *sym_name;
fecd2382 3811{
6efd877d 3812 register symbolS *symbolP; /* symbol we are working with */
86038ada 3813 char *stop;
18c9057f 3814 char stopc;
f8701a3f
SC
3815
3816 input_line_pointer++;
6efd877d 3817 if (*input_line_pointer == '=')
f8701a3f
SC
3818 input_line_pointer++;
3819
6efd877d 3820 while (*input_line_pointer == ' ' || *input_line_pointer == '\t')
f8701a3f
SC
3821 input_line_pointer++;
3822
86038ada 3823 if (flag_mri)
18c9057f 3824 stop = mri_comment_field (&stopc);
86038ada 3825
6efd877d
KR
3826 if (sym_name[0] == '.' && sym_name[1] == '\0')
3827 {
3828 /* Turn '. = mumble' into a .org mumble */
3829 register segT segment;
3830 expressionS exp;
f8701a3f 3831
6efd877d
KR
3832 segment = get_known_segmented_expression (&exp);
3833 if (!need_pass_2)
e28c40d7 3834 do_org (segment, &exp, 0);
6efd877d
KR
3835 }
3836 else
3837 {
3838 symbolP = symbol_find_or_make (sym_name);
3839 pseudo_set (symbolP);
3840 }
86038ada
ILT
3841
3842 if (flag_mri)
18c9057f 3843 mri_comment_end (stop, stopc);
6efd877d 3844} /* equals() */
fecd2382
RP
3845
3846/* .include -- include a file at this point. */
3847
3848/* ARGSUSED */
6efd877d
KR
3849void
3850s_include (arg)
3851 int arg;
fecd2382 3852{
f8701a3f
SC
3853 char *newbuf;
3854 char *filename;
3855 int i;
3856 FILE *try;
3857 char *path;
3858
ca232972
ILT
3859 if (! flag_mri)
3860 filename = demand_copy_string (&i);
3861 else
3862 {
3863 SKIP_WHITESPACE ();
3864 i = 0;
3865 while (! is_end_of_line[(unsigned char) *input_line_pointer]
3866 && *input_line_pointer != ' '
3867 && *input_line_pointer != '\t')
3868 {
3869 obstack_1grow (&notes, *input_line_pointer);
3870 ++input_line_pointer;
3871 ++i;
3872 }
3873 obstack_1grow (&notes, '\0');
3874 filename = obstack_finish (&notes);
42ac8fa8
ILT
3875 while (! is_end_of_line[(unsigned char) *input_line_pointer])
3876 ++input_line_pointer;
ca232972 3877 }
6efd877d 3878 demand_empty_rest_of_line ();
604633ae 3879 path = xmalloc ((unsigned long) i + include_dir_maxlen + 5 /* slop */ );
6efd877d
KR
3880 for (i = 0; i < include_dir_count; i++)
3881 {
3882 strcpy (path, include_dirs[i]);
3883 strcat (path, "/");
3884 strcat (path, filename);
f2889110 3885 if (0 != (try = fopen (path, "r")))
6efd877d
KR
3886 {
3887 fclose (try);
3888 goto gotit;
3889 }
3890 }
3891 free (path);
f8701a3f
SC
3892 path = filename;
3893gotit:
3894 /* malloc Storage leak when file is found on path. FIXME-SOMEDAY. */
3895 newbuf = input_scrub_include_file (path, input_line_pointer);
3896 buffer_limit = input_scrub_next_buffer (&input_line_pointer);
6efd877d 3897} /* s_include() */
fecd2382 3898
6efd877d
KR
3899void
3900add_include_dir (path)
3901 char *path;
fecd2382 3902{
f8701a3f
SC
3903 int i;
3904
3905 if (include_dir_count == 0)
3906 {
6efd877d 3907 include_dirs = (char **) xmalloc (2 * sizeof (*include_dirs));
f8701a3f
SC
3908 include_dirs[0] = "."; /* Current dir */
3909 include_dir_count = 2;
3910 }
3911 else
3912 {
3913 include_dir_count++;
6efd877d
KR
3914 include_dirs = (char **) realloc (include_dirs,
3915 include_dir_count * sizeof (*include_dirs));
f8701a3f
SC
3916 }
3917
6efd877d 3918 include_dirs[include_dir_count - 1] = path; /* New one */
f8701a3f 3919
6efd877d
KR
3920 i = strlen (path);
3921 if (i > include_dir_maxlen)
3922 include_dir_maxlen = i;
3923} /* add_include_dir() */
fecd2382 3924
6efd877d
KR
3925void
3926s_ignore (arg)
3927 int arg;
fecd2382 3928{
58d4951d 3929 while (!is_end_of_line[(unsigned char) *input_line_pointer])
6efd877d
KR
3930 {
3931 ++input_line_pointer;
3932 }
3933 ++input_line_pointer;
4064305e
SS
3934}
3935
604633ae 3936
fecd2382 3937/* end of read.c */
This page took 0.390767 seconds and 4 git commands to generate.