read.c revision 33965
133965Sjdp/* read.c - read a source file - 233965Sjdp Copyright (C) 1986, 87, 90, 91, 92, 93, 94, 95, 96, 1997 333965Sjdp Free Software Foundation, Inc. 433965Sjdp 533965SjdpThis file is part of GAS, the GNU Assembler. 633965Sjdp 733965SjdpGAS is free software; you can redistribute it and/or modify 833965Sjdpit under the terms of the GNU General Public License as published by 933965Sjdpthe Free Software Foundation; either version 2, or (at your option) 1033965Sjdpany later version. 1133965Sjdp 1233965SjdpGAS is distributed in the hope that it will be useful, 1333965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of 1433965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1533965SjdpGNU General Public License for more details. 1633965Sjdp 1733965SjdpYou should have received a copy of the GNU General Public License 1833965Sjdpalong with GAS; see the file COPYING. If not, write to the Free 1933965SjdpSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA 2033965Sjdp02111-1307, USA. */ 2133965Sjdp 2233965Sjdp#if 0 2333965Sjdp#define MASK_CHAR (0xFF) /* If your chars aren't 8 bits, you will 2433965Sjdp change this a bit. But then, GNU isn't 2533965Sjdp spozed to run on your machine anyway. 2633965Sjdp (RMS is so shortsighted sometimes.) 2733965Sjdp */ 2833965Sjdp#else 2933965Sjdp#define MASK_CHAR ((int)(unsigned char)-1) 3033965Sjdp#endif 3133965Sjdp 3233965Sjdp 3333965Sjdp/* This is the largest known floating point format (for now). It will 3433965Sjdp grow when we do 4361 style flonums. */ 3533965Sjdp 3633965Sjdp#define MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT (16) 3733965Sjdp 3833965Sjdp/* Routines that read assembler source text to build spagetti in memory. 3933965Sjdp Another group of these functions is in the expr.c module. */ 4033965Sjdp 4133965Sjdp/* for isdigit() */ 4233965Sjdp#include <ctype.h> 4333965Sjdp 4433965Sjdp#include "as.h" 4533965Sjdp#include "subsegs.h" 4633965Sjdp#include "sb.h" 4733965Sjdp#include "macro.h" 4833965Sjdp#include "obstack.h" 4933965Sjdp#include "listing.h" 5033965Sjdp#include "ecoff.h" 5133965Sjdp 5233965Sjdp#ifndef TC_START_LABEL 5333965Sjdp#define TC_START_LABEL(x,y) (x==':') 5433965Sjdp#endif 5533965Sjdp 5633965Sjdp/* The NOP_OPCODE is for the alignment fill value. 5733965Sjdp * fill it a nop instruction so that the disassembler does not choke 5833965Sjdp * on it 5933965Sjdp */ 6033965Sjdp#ifndef NOP_OPCODE 6133965Sjdp#define NOP_OPCODE 0x00 6233965Sjdp#endif 6333965Sjdp 6433965Sjdpchar *input_line_pointer; /*->next char of source file to parse. */ 6533965Sjdp 6633965Sjdpint generate_asm_lineno = 0; /* flag to generate line stab for .s file */ 6733965Sjdp 6833965Sjdp#if BITS_PER_CHAR != 8 6933965Sjdp/* The following table is indexed by[(char)] and will break if 7033965Sjdp a char does not have exactly 256 states (hopefully 0:255!)! */ 7133965Sjdpdie horribly; 7233965Sjdp#endif 7333965Sjdp 7433965Sjdp#ifndef LEX_AT 7533965Sjdp/* The m88k unfortunately uses @ as a label beginner. */ 7633965Sjdp#define LEX_AT 0 7733965Sjdp#endif 7833965Sjdp 7933965Sjdp#ifndef LEX_BR 8033965Sjdp/* The RS/6000 assembler uses {,},[,] as parts of symbol names. */ 8133965Sjdp#define LEX_BR 0 8233965Sjdp#endif 8333965Sjdp 8433965Sjdp#ifndef LEX_PCT 8533965Sjdp/* The Delta 68k assembler permits % inside label names. */ 8633965Sjdp#define LEX_PCT 0 8733965Sjdp#endif 8833965Sjdp 8933965Sjdp#ifndef LEX_QM 9033965Sjdp/* The PowerPC Windows NT assemblers permits ? inside label names. */ 9133965Sjdp#define LEX_QM 0 9233965Sjdp#endif 9333965Sjdp 9433965Sjdp#ifndef LEX_DOLLAR 9533965Sjdp/* The a29k assembler does not permits labels to start with $. */ 9633965Sjdp#define LEX_DOLLAR 3 9733965Sjdp#endif 9833965Sjdp 9933965Sjdp#ifndef LEX_TILDE 10033965Sjdp/* The Delta 68k assembler permits ~ at start of label names. */ 10133965Sjdp#define LEX_TILDE 0 10233965Sjdp#endif 10333965Sjdp 10433965Sjdp/* used by is_... macros. our ctype[] */ 10533965Sjdpchar lex_type[256] = 10633965Sjdp{ 10733965Sjdp 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */ 10833965Sjdp 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ[\]^_ */ 10933965Sjdp 0, 0, 0, 0, LEX_DOLLAR, LEX_PCT, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */ 11033965Sjdp 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, LEX_QM, /* 0123456789:;<=>? */ 11133965Sjdp LEX_AT, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */ 11233965Sjdp 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, 0, 3, /* PQRSTUVWXYZ[\]^_ */ 11333965Sjdp 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* `abcdefghijklmno */ 11433965Sjdp 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, LEX_TILDE, 0, /* pqrstuvwxyz{|}~. */ 11533965Sjdp 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11633965Sjdp 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11733965Sjdp 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11833965Sjdp 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11933965Sjdp 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12033965Sjdp 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12133965Sjdp 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12233965Sjdp}; 12333965Sjdp 12433965Sjdp 12533965Sjdp/* 12633965Sjdp * In: a character. 12733965Sjdp * Out: 1 if this character ends a line. 12833965Sjdp */ 12933965Sjdp#define _ (0) 13033965Sjdpchar is_end_of_line[256] = 13133965Sjdp{ 13233965Sjdp#ifdef CR_EOL 13333965Sjdp _, _, _, _, _, _, _, _, _, _, 99, _, _, 99, _, _, /* @abcdefghijklmno */ 13433965Sjdp#else 13533965Sjdp _, _, _, _, _, _, _, _, _, _, 99, _, _, _, _, _, /* @abcdefghijklmno */ 13633965Sjdp#endif 13733965Sjdp _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */ 13833965Sjdp#ifdef TC_HPPA 13933965Sjdp _,99, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* _!"#$%&'()*+,-./ */ 14033965Sjdp _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0123456789:;<=>? */ 14133965Sjdp#else 14233965Sjdp _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */ 14333965Sjdp _, _, _, _, _, _, _, _, _, _, _, 99, _, _, _, _, /* 0123456789:;<=>? */ 14433965Sjdp#endif 14533965Sjdp _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */ 14633965Sjdp _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */ 14733965Sjdp _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */ 14833965Sjdp _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */ 14933965Sjdp _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */ 15033965Sjdp _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */ 15133965Sjdp _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */ 15233965Sjdp _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */ 15333965Sjdp _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */ 15433965Sjdp}; 15533965Sjdp#undef _ 15633965Sjdp 15733965Sjdp/* Functions private to this file. */ 15833965Sjdp 15933965Sjdpstatic char *buffer; /* 1st char of each buffer of lines is here. */ 16033965Sjdpstatic char *buffer_limit; /*->1 + last char in buffer. */ 16133965Sjdp 16233965Sjdp/* TARGET_BYTES_BIG_ENDIAN is required to be defined to either 0 or 1 in the 16333965Sjdp tc-<CPU>.h file. See the "Porting GAS" section of the internals manual. */ 16433965Sjdpint target_big_endian = TARGET_BYTES_BIG_ENDIAN; 16533965Sjdp 16633965Sjdpstatic char *old_buffer; /* JF a hack */ 16733965Sjdpstatic char *old_input; 16833965Sjdpstatic char *old_limit; 16933965Sjdp 17033965Sjdp/* Variables for handling include file directory list. */ 17133965Sjdp 17233965Sjdpchar **include_dirs; /* List of pointers to directories to 17333965Sjdp search for .include's */ 17433965Sjdpint include_dir_count; /* How many are in the list */ 17533965Sjdpint include_dir_maxlen = 1;/* Length of longest in list */ 17633965Sjdp 17733965Sjdp#ifndef WORKING_DOT_WORD 17833965Sjdpstruct broken_word *broken_words; 17933965Sjdpint new_broken_words; 18033965Sjdp#endif 18133965Sjdp 18233965Sjdp/* The current offset into the absolute section. We don't try to 18333965Sjdp build frags in the absolute section, since no data can be stored 18433965Sjdp there. We just keep track of the current offset. */ 18533965SjdpaddressT abs_section_offset; 18633965Sjdp 18733965Sjdp/* If this line had an MRI style label, it is stored in this variable. 18833965Sjdp This is used by some of the MRI pseudo-ops. */ 18933965SjdpsymbolS *line_label; 19033965Sjdp 19133965Sjdp/* This global variable is used to support MRI common sections. We 19233965Sjdp translate such sections into a common symbol. This variable is 19333965Sjdp non-NULL when we are in an MRI common section. */ 19433965SjdpsymbolS *mri_common_symbol; 19533965Sjdp 19633965Sjdp/* In MRI mode, after a dc.b pseudo-op with an odd number of bytes, we 19733965Sjdp need to align to an even byte boundary unless the next pseudo-op is 19833965Sjdp dc.b, ds.b, or dcb.b. This variable is set to 1 if an alignment 19933965Sjdp may be needed. */ 20033965Sjdpstatic int mri_pending_align; 20133965Sjdp 20233965Sjdpstatic void cons_worker PARAMS ((int, int)); 20333965Sjdpstatic int scrub_from_string PARAMS ((char **)); 20433965Sjdpstatic void do_align PARAMS ((int, char *, int, int)); 20533965Sjdpstatic void s_align PARAMS ((int, int)); 20633965Sjdpstatic int hex_float PARAMS ((int, char *)); 20733965Sjdpstatic void do_org PARAMS ((segT, expressionS *, int)); 20833965Sjdpchar *demand_copy_string PARAMS ((int *lenP)); 20933965Sjdpstatic segT get_segmented_expression PARAMS ((expressionS *expP)); 21033965Sjdpstatic segT get_known_segmented_expression PARAMS ((expressionS * expP)); 21133965Sjdpstatic void pobegin PARAMS ((void)); 21233965Sjdpstatic int get_line_sb PARAMS ((sb *)); 21333965Sjdp 21433965Sjdp 21533965Sjdpvoid 21633965Sjdpread_begin () 21733965Sjdp{ 21833965Sjdp const char *p; 21933965Sjdp 22033965Sjdp pobegin (); 22133965Sjdp obj_read_begin_hook (); 22233965Sjdp 22333965Sjdp /* Something close -- but not too close -- to a multiple of 1024. 22433965Sjdp The debugging malloc I'm using has 24 bytes of overhead. */ 22533965Sjdp obstack_begin (¬es, chunksize); 22633965Sjdp obstack_begin (&cond_obstack, chunksize); 22733965Sjdp 22833965Sjdp /* Use machine dependent syntax */ 22933965Sjdp for (p = line_separator_chars; *p; p++) 23033965Sjdp is_end_of_line[(unsigned char) *p] = 1; 23133965Sjdp /* Use more. FIXME-SOMEDAY. */ 23233965Sjdp 23333965Sjdp if (flag_mri) 23433965Sjdp lex_type['?'] = 3; 23533965Sjdp} 23633965Sjdp 23733965Sjdp/* set up pseudo-op tables */ 23833965Sjdp 23933965Sjdpstatic struct hash_control *po_hash; 24033965Sjdp 24133965Sjdpstatic const pseudo_typeS potable[] = 24233965Sjdp{ 24333965Sjdp {"abort", s_abort, 0}, 24433965Sjdp {"align", s_align_ptwo, 0}, 24533965Sjdp {"ascii", stringer, 0}, 24633965Sjdp {"asciz", stringer, 1}, 24733965Sjdp {"balign", s_align_bytes, 0}, 24833965Sjdp {"balignw", s_align_bytes, -2}, 24933965Sjdp {"balignl", s_align_bytes, -4}, 25033965Sjdp/* block */ 25133965Sjdp {"byte", cons, 1}, 25233965Sjdp {"comm", s_comm, 0}, 25333965Sjdp {"common", s_mri_common, 0}, 25433965Sjdp {"common.s", s_mri_common, 1}, 25533965Sjdp {"data", s_data, 0}, 25633965Sjdp {"dc", cons, 2}, 25733965Sjdp {"dc.b", cons, 1}, 25833965Sjdp {"dc.d", float_cons, 'd'}, 25933965Sjdp {"dc.l", cons, 4}, 26033965Sjdp {"dc.s", float_cons, 'f'}, 26133965Sjdp {"dc.w", cons, 2}, 26233965Sjdp {"dc.x", float_cons, 'x'}, 26333965Sjdp {"dcb", s_space, 2}, 26433965Sjdp {"dcb.b", s_space, 1}, 26533965Sjdp {"dcb.d", s_float_space, 'd'}, 26633965Sjdp {"dcb.l", s_space, 4}, 26733965Sjdp {"dcb.s", s_float_space, 'f'}, 26833965Sjdp {"dcb.w", s_space, 2}, 26933965Sjdp {"dcb.x", s_float_space, 'x'}, 27033965Sjdp {"ds", s_space, 2}, 27133965Sjdp {"ds.b", s_space, 1}, 27233965Sjdp {"ds.d", s_space, 8}, 27333965Sjdp {"ds.l", s_space, 4}, 27433965Sjdp {"ds.p", s_space, 12}, 27533965Sjdp {"ds.s", s_space, 4}, 27633965Sjdp {"ds.w", s_space, 2}, 27733965Sjdp {"ds.x", s_space, 12}, 27833965Sjdp {"debug", s_ignore, 0}, 27933965Sjdp#ifdef S_SET_DESC 28033965Sjdp {"desc", s_desc, 0}, 28133965Sjdp#endif 28233965Sjdp/* dim */ 28333965Sjdp {"double", float_cons, 'd'}, 28433965Sjdp/* dsect */ 28533965Sjdp {"eject", listing_eject, 0}, /* Formfeed listing */ 28633965Sjdp {"else", s_else, 0}, 28733965Sjdp {"elsec", s_else, 0}, 28833965Sjdp {"end", s_end, 0}, 28933965Sjdp {"endc", s_endif, 0}, 29033965Sjdp {"endif", s_endif, 0}, 29133965Sjdp/* endef */ 29233965Sjdp {"equ", s_set, 0}, 29333965Sjdp {"equiv", s_set, 1}, 29433965Sjdp {"err", s_err, 0}, 29533965Sjdp {"exitm", s_mexit, 0}, 29633965Sjdp/* extend */ 29733965Sjdp {"extern", s_ignore, 0}, /* We treat all undef as ext */ 29833965Sjdp {"appfile", s_app_file, 1}, 29933965Sjdp {"appline", s_app_line, 0}, 30033965Sjdp {"fail", s_fail, 0}, 30133965Sjdp {"file", s_app_file, 0}, 30233965Sjdp {"fill", s_fill, 0}, 30333965Sjdp {"float", float_cons, 'f'}, 30433965Sjdp {"format", s_ignore, 0}, 30533965Sjdp {"global", s_globl, 0}, 30633965Sjdp {"globl", s_globl, 0}, 30733965Sjdp {"hword", cons, 2}, 30833965Sjdp {"if", s_if, (int) O_ne}, 30933965Sjdp {"ifc", s_ifc, 0}, 31033965Sjdp {"ifdef", s_ifdef, 0}, 31133965Sjdp {"ifeq", s_if, (int) O_eq}, 31233965Sjdp {"ifeqs", s_ifeqs, 0}, 31333965Sjdp {"ifge", s_if, (int) O_ge}, 31433965Sjdp {"ifgt", s_if, (int) O_gt}, 31533965Sjdp {"ifle", s_if, (int) O_le}, 31633965Sjdp {"iflt", s_if, (int) O_lt}, 31733965Sjdp {"ifnc", s_ifc, 1}, 31833965Sjdp {"ifndef", s_ifdef, 1}, 31933965Sjdp {"ifne", s_if, (int) O_ne}, 32033965Sjdp {"ifnes", s_ifeqs, 1}, 32133965Sjdp {"ifnotdef", s_ifdef, 1}, 32233965Sjdp {"include", s_include, 0}, 32333965Sjdp {"int", cons, 4}, 32433965Sjdp {"irp", s_irp, 0}, 32533965Sjdp {"irep", s_irp, 0}, 32633965Sjdp {"irpc", s_irp, 1}, 32733965Sjdp {"irepc", s_irp, 1}, 32833965Sjdp {"lcomm", s_lcomm, 0}, 32933965Sjdp {"lflags", listing_flags, 0}, /* Listing flags */ 33033965Sjdp {"linkonce", s_linkonce, 0}, 33133965Sjdp {"list", listing_list, 1}, /* Turn listing on */ 33233965Sjdp {"llen", listing_psize, 1}, 33333965Sjdp {"long", cons, 4}, 33433965Sjdp {"lsym", s_lsym, 0}, 33533965Sjdp {"macro", s_macro, 0}, 33633965Sjdp {"mexit", s_mexit, 0}, 33733965Sjdp {"mri", s_mri, 0}, 33833965Sjdp {".mri", s_mri, 0}, /* Special case so .mri works in MRI mode. */ 33933965Sjdp {"name", s_ignore, 0}, 34033965Sjdp {"noformat", s_ignore, 0}, 34133965Sjdp {"nolist", listing_list, 0}, /* Turn listing off */ 34233965Sjdp {"nopage", listing_nopage, 0}, 34333965Sjdp {"octa", cons, 16}, 34433965Sjdp {"offset", s_struct, 0}, 34533965Sjdp {"org", s_org, 0}, 34633965Sjdp {"p2align", s_align_ptwo, 0}, 34733965Sjdp {"p2alignw", s_align_ptwo, -2}, 34833965Sjdp {"p2alignl", s_align_ptwo, -4}, 34933965Sjdp {"page", listing_eject, 0}, 35033965Sjdp {"plen", listing_psize, 0}, 35133965Sjdp {"print", s_print, 0}, 35233965Sjdp {"psize", listing_psize, 0}, /* set paper size */ 35333965Sjdp {"purgem", s_purgem, 0}, 35433965Sjdp {"quad", cons, 8}, 35533965Sjdp {"rep", s_rept, 0}, 35633965Sjdp {"rept", s_rept, 0}, 35733965Sjdp {"rva", s_rva, 4}, 35833965Sjdp {"sbttl", listing_title, 1}, /* Subtitle of listing */ 35933965Sjdp/* scl */ 36033965Sjdp/* sect */ 36133965Sjdp {"set", s_set, 0}, 36233965Sjdp {"short", cons, 2}, 36333965Sjdp {"single", float_cons, 'f'}, 36433965Sjdp/* size */ 36533965Sjdp {"space", s_space, 0}, 36633965Sjdp {"skip", s_space, 0}, 36733965Sjdp {"spc", s_ignore, 0}, 36833965Sjdp {"stabd", s_stab, 'd'}, 36933965Sjdp {"stabn", s_stab, 'n'}, 37033965Sjdp {"stabs", s_stab, 's'}, 37133965Sjdp {"string", stringer, 1}, 37233965Sjdp {"struct", s_struct, 0}, 37333965Sjdp/* tag */ 37433965Sjdp {"text", s_text, 0}, 37533965Sjdp 37633965Sjdp /* This is for gcc to use. It's only just been added (2/94), so gcc 37733965Sjdp won't be able to use it for a while -- probably a year or more. 37833965Sjdp But once this has been released, check with gcc maintainers 37933965Sjdp before deleting it or even changing the spelling. */ 38033965Sjdp {"this_GCC_requires_the_GNU_assembler", s_ignore, 0}, 38133965Sjdp /* If we're folding case -- done for some targets, not necessarily 38233965Sjdp all -- the above string in an input file will be converted to 38333965Sjdp this one. Match it either way... */ 38433965Sjdp {"this_gcc_requires_the_gnu_assembler", s_ignore, 0}, 38533965Sjdp 38633965Sjdp {"title", listing_title, 0}, /* Listing title */ 38733965Sjdp {"ttl", listing_title, 0}, 38833965Sjdp/* type */ 38933965Sjdp/* use */ 39033965Sjdp/* val */ 39133965Sjdp {"xcom", s_comm, 0}, 39233965Sjdp {"xdef", s_globl, 0}, 39333965Sjdp {"xref", s_ignore, 0}, 39433965Sjdp {"xstabs", s_xstab, 's'}, 39533965Sjdp {"word", cons, 2}, 39633965Sjdp {"zero", s_space, 0}, 39733965Sjdp {NULL} /* end sentinel */ 39833965Sjdp}; 39933965Sjdp 40033965Sjdpstatic int pop_override_ok = 0; 40133965Sjdpstatic const char *pop_table_name; 40233965Sjdp 40333965Sjdpvoid 40433965Sjdppop_insert (table) 40533965Sjdp const pseudo_typeS *table; 40633965Sjdp{ 40733965Sjdp const char *errtxt; 40833965Sjdp const pseudo_typeS *pop; 40933965Sjdp for (pop = table; pop->poc_name; pop++) 41033965Sjdp { 41133965Sjdp errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop); 41233965Sjdp if (errtxt && (!pop_override_ok || strcmp (errtxt, "exists"))) 41333965Sjdp as_fatal ("error constructing %s pseudo-op table: %s", pop_table_name, 41433965Sjdp errtxt); 41533965Sjdp } 41633965Sjdp} 41733965Sjdp 41833965Sjdp#ifndef md_pop_insert 41933965Sjdp#define md_pop_insert() pop_insert(md_pseudo_table) 42033965Sjdp#endif 42133965Sjdp 42233965Sjdp#ifndef obj_pop_insert 42333965Sjdp#define obj_pop_insert() pop_insert(obj_pseudo_table) 42433965Sjdp#endif 42533965Sjdp 42633965Sjdpstatic void 42733965Sjdppobegin () 42833965Sjdp{ 42933965Sjdp po_hash = hash_new (); 43033965Sjdp 43133965Sjdp /* Do the target-specific pseudo ops. */ 43233965Sjdp pop_table_name = "md"; 43333965Sjdp md_pop_insert (); 43433965Sjdp 43533965Sjdp /* Now object specific. Skip any that were in the target table. */ 43633965Sjdp pop_table_name = "obj"; 43733965Sjdp pop_override_ok = 1; 43833965Sjdp obj_pop_insert (); 43933965Sjdp 44033965Sjdp /* Now portable ones. Skip any that we've seen already. */ 44133965Sjdp pop_table_name = "standard"; 44233965Sjdp pop_insert (potable); 44333965Sjdp} 44433965Sjdp 44533965Sjdp#define HANDLE_CONDITIONAL_ASSEMBLY() \ 44633965Sjdp if (ignore_input ()) \ 44733965Sjdp { \ 44833965Sjdp while (! is_end_of_line[(unsigned char) *input_line_pointer++]) \ 44933965Sjdp if (input_line_pointer == buffer_limit) \ 45033965Sjdp break; \ 45133965Sjdp continue; \ 45233965Sjdp } 45333965Sjdp 45433965Sjdp 45533965Sjdp/* This function is used when scrubbing the characters between #APP 45633965Sjdp and #NO_APP. */ 45733965Sjdp 45833965Sjdpstatic char *scrub_string; 45933965Sjdpstatic char *scrub_string_end; 46033965Sjdp 46133965Sjdpstatic int 46233965Sjdpscrub_from_string (from) 46333965Sjdp char **from; 46433965Sjdp{ 46533965Sjdp int size; 46633965Sjdp 46733965Sjdp *from = scrub_string; 46833965Sjdp size = scrub_string_end - scrub_string; 46933965Sjdp scrub_string = scrub_string_end; 47033965Sjdp return size; 47133965Sjdp} 47233965Sjdp 47333965Sjdp/* read_a_source_file() 47433965Sjdp * 47533965Sjdp * We read the file, putting things into a web that 47633965Sjdp * represents what we have been reading. 47733965Sjdp */ 47833965Sjdpvoid 47933965Sjdpread_a_source_file (name) 48033965Sjdp char *name; 48133965Sjdp{ 48233965Sjdp register char c; 48333965Sjdp register char *s; /* string of symbol, '\0' appended */ 48433965Sjdp register int temp; 48533965Sjdp pseudo_typeS *pop; 48633965Sjdp 48733965Sjdp buffer = input_scrub_new_file (name); 48833965Sjdp 48933965Sjdp listing_file (name); 49033965Sjdp listing_newline (""); 49133965Sjdp 49233965Sjdp while ((buffer_limit = input_scrub_next_buffer (&input_line_pointer)) != 0) 49333965Sjdp { /* We have another line to parse. */ 49433965Sjdp know (buffer_limit[-1] == '\n'); /* Must have a sentinel. */ 49533965Sjdp contin: /* JF this goto is my fault I admit it. 49633965Sjdp Someone brave please re-write the whole 49733965Sjdp input section here? Pleeze??? */ 49833965Sjdp while (input_line_pointer < buffer_limit) 49933965Sjdp { 50033965Sjdp /* We have more of this buffer to parse. */ 50133965Sjdp 50233965Sjdp /* 50333965Sjdp * We now have input_line_pointer->1st char of next line. 50433965Sjdp * If input_line_pointer [-1] == '\n' then we just 50533965Sjdp * scanned another line: so bump line counters. 50633965Sjdp */ 50733965Sjdp if (is_end_of_line[(unsigned char) input_line_pointer[-1]]) 50833965Sjdp { 50933965Sjdp#ifdef md_start_line_hook 51033965Sjdp md_start_line_hook (); 51133965Sjdp#endif 51233965Sjdp 51333965Sjdp if (input_line_pointer[-1] == '\n') 51433965Sjdp bump_line_counters (); 51533965Sjdp 51633965Sjdp line_label = NULL; 51733965Sjdp 51833965Sjdp if (flag_m68k_mri 51933965Sjdp#ifdef LABELS_WITHOUT_COLONS 52033965Sjdp || 1 52133965Sjdp#endif 52233965Sjdp ) 52333965Sjdp { 52433965Sjdp /* Text at the start of a line must be a label, we 52533965Sjdp run down and stick a colon in. */ 52633965Sjdp if (is_name_beginner (*input_line_pointer)) 52733965Sjdp { 52833965Sjdp char *line_start = input_line_pointer; 52933965Sjdp char c; 53033965Sjdp int mri_line_macro; 53133965Sjdp 53233965Sjdp LISTING_NEWLINE (); 53333965Sjdp HANDLE_CONDITIONAL_ASSEMBLY (); 53433965Sjdp 53533965Sjdp c = get_symbol_end (); 53633965Sjdp 53733965Sjdp /* In MRI mode, the EQU and MACRO pseudoops must 53833965Sjdp be handled specially. */ 53933965Sjdp mri_line_macro = 0; 54033965Sjdp if (flag_m68k_mri) 54133965Sjdp { 54233965Sjdp char *rest = input_line_pointer + 1; 54333965Sjdp 54433965Sjdp if (*rest == ':') 54533965Sjdp ++rest; 54633965Sjdp if (*rest == ' ' || *rest == '\t') 54733965Sjdp ++rest; 54833965Sjdp if ((strncasecmp (rest, "EQU", 3) == 0 54933965Sjdp || strncasecmp (rest, "SET", 3) == 0) 55033965Sjdp && (rest[3] == ' ' || rest[3] == '\t')) 55133965Sjdp { 55233965Sjdp input_line_pointer = rest + 3; 55333965Sjdp equals (line_start, 55433965Sjdp strncasecmp (rest, "SET", 3) == 0); 55533965Sjdp continue; 55633965Sjdp } 55733965Sjdp if (strncasecmp (rest, "MACRO", 5) == 0 55833965Sjdp && (rest[5] == ' ' 55933965Sjdp || rest[5] == '\t' 56033965Sjdp || is_end_of_line[(unsigned char) rest[5]])) 56133965Sjdp mri_line_macro = 1; 56233965Sjdp } 56333965Sjdp 56433965Sjdp /* In MRI mode, we need to handle the MACRO 56533965Sjdp pseudo-op specially: we don't want to put the 56633965Sjdp symbol in the symbol table. */ 56733965Sjdp if (! mri_line_macro) 56833965Sjdp line_label = colon (line_start); 56933965Sjdp else 57033965Sjdp line_label = symbol_create (line_start, 57133965Sjdp absolute_section, 57233965Sjdp (valueT) 0, 57333965Sjdp &zero_address_frag); 57433965Sjdp 57533965Sjdp *input_line_pointer = c; 57633965Sjdp if (c == ':') 57733965Sjdp input_line_pointer++; 57833965Sjdp } 57933965Sjdp } 58033965Sjdp } 58133965Sjdp 58233965Sjdp /* 58333965Sjdp * We are at the begining of a line, or similar place. 58433965Sjdp * We expect a well-formed assembler statement. 58533965Sjdp * A "symbol-name:" is a statement. 58633965Sjdp * 58733965Sjdp * Depending on what compiler is used, the order of these tests 58833965Sjdp * may vary to catch most common case 1st. 58933965Sjdp * Each test is independent of all other tests at the (top) level. 59033965Sjdp * PLEASE make a compiler that doesn't use this assembler. 59133965Sjdp * It is crufty to waste a compiler's time encoding things for this 59233965Sjdp * assembler, which then wastes more time decoding it. 59333965Sjdp * (And communicating via (linear) files is silly! 59433965Sjdp * If you must pass stuff, please pass a tree!) 59533965Sjdp */ 59633965Sjdp if ((c = *input_line_pointer++) == '\t' 59733965Sjdp || c == ' ' 59833965Sjdp || c == '\f' 59933965Sjdp || c == 0) 60033965Sjdp { 60133965Sjdp c = *input_line_pointer++; 60233965Sjdp } 60333965Sjdp know (c != ' '); /* No further leading whitespace. */ 60433965Sjdp LISTING_NEWLINE (); 60533965Sjdp /* 60633965Sjdp * C is the 1st significant character. 60733965Sjdp * Input_line_pointer points after that character. 60833965Sjdp */ 60933965Sjdp if (is_name_beginner (c)) 61033965Sjdp { 61133965Sjdp /* want user-defined label or pseudo/opcode */ 61233965Sjdp HANDLE_CONDITIONAL_ASSEMBLY (); 61333965Sjdp 61433965Sjdp s = --input_line_pointer; 61533965Sjdp c = get_symbol_end (); /* name's delimiter */ 61633965Sjdp /* 61733965Sjdp * C is character after symbol. 61833965Sjdp * That character's place in the input line is now '\0'. 61933965Sjdp * S points to the beginning of the symbol. 62033965Sjdp * [In case of pseudo-op, s->'.'.] 62133965Sjdp * Input_line_pointer->'\0' where c was. 62233965Sjdp */ 62333965Sjdp if (TC_START_LABEL(c, input_line_pointer)) 62433965Sjdp { 62533965Sjdp if (flag_m68k_mri) 62633965Sjdp { 62733965Sjdp char *rest = input_line_pointer + 1; 62833965Sjdp 62933965Sjdp /* In MRI mode, \tsym: set 0 is permitted. */ 63033965Sjdp 63133965Sjdp if (*rest == ':') 63233965Sjdp ++rest; 63333965Sjdp if (*rest == ' ' || *rest == '\t') 63433965Sjdp ++rest; 63533965Sjdp if ((strncasecmp (rest, "EQU", 3) == 0 63633965Sjdp || strncasecmp (rest, "SET", 3) == 0) 63733965Sjdp && (rest[3] == ' ' || rest[3] == '\t')) 63833965Sjdp { 63933965Sjdp input_line_pointer = rest + 3; 64033965Sjdp equals (s, 1); 64133965Sjdp continue; 64233965Sjdp } 64333965Sjdp } 64433965Sjdp 64533965Sjdp line_label = colon (s); /* user-defined label */ 64633965Sjdp *input_line_pointer++ = ':'; /* Put ':' back for error messages' sake. */ 64733965Sjdp /* Input_line_pointer->after ':'. */ 64833965Sjdp SKIP_WHITESPACE (); 64933965Sjdp 65033965Sjdp 65133965Sjdp } 65233965Sjdp else if (c == '=' 65333965Sjdp || ((c == ' ' || c == '\t') 65433965Sjdp && input_line_pointer[1] == '=' 65533965Sjdp#ifdef TC_EQUAL_IN_INSN 65633965Sjdp && ! TC_EQUAL_IN_INSN (c, input_line_pointer) 65733965Sjdp#endif 65833965Sjdp )) 65933965Sjdp { 66033965Sjdp equals (s, 1); 66133965Sjdp demand_empty_rest_of_line (); 66233965Sjdp } 66333965Sjdp else 66433965Sjdp { /* expect pseudo-op or machine instruction */ 66533965Sjdp pop = NULL; 66633965Sjdp 66733965Sjdp#define IGNORE_OPCODE_CASE 66833965Sjdp#ifdef IGNORE_OPCODE_CASE 66933965Sjdp { 67033965Sjdp char *s2 = s; 67133965Sjdp while (*s2) 67233965Sjdp { 67333965Sjdp if (isupper (*s2)) 67433965Sjdp *s2 = tolower (*s2); 67533965Sjdp s2++; 67633965Sjdp } 67733965Sjdp } 67833965Sjdp#endif 67933965Sjdp 68033965Sjdp if (flag_m68k_mri 68133965Sjdp#ifdef NO_PSEUDO_DOT 68233965Sjdp || 1 68333965Sjdp#endif 68433965Sjdp ) 68533965Sjdp { 68633965Sjdp /* The MRI assembler and the m88k use pseudo-ops 68733965Sjdp without a period. */ 68833965Sjdp pop = (pseudo_typeS *) hash_find (po_hash, s); 68933965Sjdp if (pop != NULL && pop->poc_handler == NULL) 69033965Sjdp pop = NULL; 69133965Sjdp } 69233965Sjdp 69333965Sjdp if (pop != NULL 69433965Sjdp || (! flag_m68k_mri && *s == '.')) 69533965Sjdp { 69633965Sjdp /* 69733965Sjdp * PSEUDO - OP. 69833965Sjdp * 69933965Sjdp * WARNING: c has next char, which may be end-of-line. 70033965Sjdp * We lookup the pseudo-op table with s+1 because we 70133965Sjdp * already know that the pseudo-op begins with a '.'. 70233965Sjdp */ 70333965Sjdp 70433965Sjdp if (pop == NULL) 70533965Sjdp pop = (pseudo_typeS *) hash_find (po_hash, s + 1); 70633965Sjdp 70733965Sjdp /* In MRI mode, we may need to insert an 70833965Sjdp automatic alignment directive. What a hack 70933965Sjdp this is. */ 71033965Sjdp if (mri_pending_align 71133965Sjdp && (pop == NULL 71233965Sjdp || ! ((pop->poc_handler == cons 71333965Sjdp && pop->poc_val == 1) 71433965Sjdp || (pop->poc_handler == s_space 71533965Sjdp && pop->poc_val == 1) 71633965Sjdp#ifdef tc_conditional_pseudoop 71733965Sjdp || tc_conditional_pseudoop (pop) 71833965Sjdp#endif 71933965Sjdp || pop->poc_handler == s_if 72033965Sjdp || pop->poc_handler == s_ifdef 72133965Sjdp || pop->poc_handler == s_ifc 72233965Sjdp || pop->poc_handler == s_ifeqs 72333965Sjdp || pop->poc_handler == s_else 72433965Sjdp || pop->poc_handler == s_endif 72533965Sjdp || pop->poc_handler == s_globl 72633965Sjdp || pop->poc_handler == s_ignore))) 72733965Sjdp { 72833965Sjdp do_align (1, (char *) NULL, 0, 0); 72933965Sjdp mri_pending_align = 0; 73033965Sjdp if (line_label != NULL) 73133965Sjdp { 73233965Sjdp line_label->sy_frag = frag_now; 73333965Sjdp S_SET_VALUE (line_label, frag_now_fix ()); 73433965Sjdp } 73533965Sjdp } 73633965Sjdp 73733965Sjdp /* Print the error msg now, while we still can */ 73833965Sjdp if (pop == NULL) 73933965Sjdp { 74033965Sjdp as_bad ("Unknown pseudo-op: `%s'", s); 74133965Sjdp *input_line_pointer = c; 74233965Sjdp s_ignore (0); 74333965Sjdp continue; 74433965Sjdp } 74533965Sjdp 74633965Sjdp /* Put it back for error messages etc. */ 74733965Sjdp *input_line_pointer = c; 74833965Sjdp /* The following skip of whitespace is compulsory. 74933965Sjdp A well shaped space is sometimes all that separates 75033965Sjdp keyword from operands. */ 75133965Sjdp if (c == ' ' || c == '\t') 75233965Sjdp input_line_pointer++; 75333965Sjdp /* 75433965Sjdp * Input_line is restored. 75533965Sjdp * Input_line_pointer->1st non-blank char 75633965Sjdp * after pseudo-operation. 75733965Sjdp */ 75833965Sjdp (*pop->poc_handler) (pop->poc_val); 75933965Sjdp 76033965Sjdp /* If that was .end, just get out now. */ 76133965Sjdp if (pop->poc_handler == s_end) 76233965Sjdp goto quit; 76333965Sjdp } 76433965Sjdp else 76533965Sjdp { 76633965Sjdp int inquote = 0; 76733965Sjdp 76833965Sjdp /* WARNING: c has char, which may be end-of-line. */ 76933965Sjdp /* Also: input_line_pointer->`\0` where c was. */ 77033965Sjdp *input_line_pointer = c; 77133965Sjdp while (!is_end_of_line[(unsigned char) *input_line_pointer] 77233965Sjdp || inquote 77333965Sjdp#ifdef TC_EOL_IN_INSN 77433965Sjdp || TC_EOL_IN_INSN (input_line_pointer) 77533965Sjdp#endif 77633965Sjdp ) 77733965Sjdp { 77833965Sjdp if (flag_m68k_mri && *input_line_pointer == '\'') 77933965Sjdp inquote = ! inquote; 78033965Sjdp input_line_pointer++; 78133965Sjdp } 78233965Sjdp 78333965Sjdp c = *input_line_pointer; 78433965Sjdp *input_line_pointer = '\0'; 78533965Sjdp 78633965Sjdp#ifdef OBJ_GENERATE_ASM_LINENO 78733965Sjdp if (generate_asm_lineno == 0) 78833965Sjdp { 78933965Sjdp if (ecoff_no_current_file ()) 79033965Sjdp generate_asm_lineno = 1; 79133965Sjdp } 79233965Sjdp if (generate_asm_lineno == 1) 79333965Sjdp { 79433965Sjdp unsigned int lineno; 79533965Sjdp char *s; 79633965Sjdp 79733965Sjdp as_where (&s, &lineno); 79833965Sjdp OBJ_GENERATE_ASM_LINENO (s, lineno); 79933965Sjdp } 80033965Sjdp#endif 80133965Sjdp 80233965Sjdp if (macro_defined) 80333965Sjdp { 80433965Sjdp sb out; 80533965Sjdp const char *err; 80633965Sjdp 80733965Sjdp if (check_macro (s, &out, '\0', &err)) 80833965Sjdp { 80933965Sjdp if (err != NULL) 81033965Sjdp as_bad (err); 81133965Sjdp *input_line_pointer++ = c; 81233965Sjdp input_scrub_include_sb (&out, 81333965Sjdp input_line_pointer); 81433965Sjdp sb_kill (&out); 81533965Sjdp buffer_limit = 81633965Sjdp input_scrub_next_buffer (&input_line_pointer); 81733965Sjdp continue; 81833965Sjdp } 81933965Sjdp } 82033965Sjdp 82133965Sjdp if (mri_pending_align) 82233965Sjdp { 82333965Sjdp do_align (1, (char *) NULL, 0, 0); 82433965Sjdp mri_pending_align = 0; 82533965Sjdp if (line_label != NULL) 82633965Sjdp { 82733965Sjdp line_label->sy_frag = frag_now; 82833965Sjdp S_SET_VALUE (line_label, frag_now_fix ()); 82933965Sjdp } 83033965Sjdp } 83133965Sjdp 83233965Sjdp md_assemble (s); /* Assemble 1 instruction. */ 83333965Sjdp 83433965Sjdp *input_line_pointer++ = c; 83533965Sjdp 83633965Sjdp /* We resume loop AFTER the end-of-line from 83733965Sjdp this instruction. */ 83833965Sjdp } /* if (*s=='.') */ 83933965Sjdp } /* if c==':' */ 84033965Sjdp continue; 84133965Sjdp } /* if (is_name_beginner(c) */ 84233965Sjdp 84333965Sjdp 84433965Sjdp /* Empty statement? */ 84533965Sjdp if (is_end_of_line[(unsigned char) c]) 84633965Sjdp continue; 84733965Sjdp 84833965Sjdp if ((LOCAL_LABELS_DOLLAR || LOCAL_LABELS_FB) 84933965Sjdp && isdigit (c)) 85033965Sjdp { 85133965Sjdp /* local label ("4:") */ 85233965Sjdp char *backup = input_line_pointer; 85333965Sjdp 85433965Sjdp HANDLE_CONDITIONAL_ASSEMBLY (); 85533965Sjdp 85633965Sjdp temp = c - '0'; 85733965Sjdp 85833965Sjdp while (isdigit (*input_line_pointer)) 85933965Sjdp { 86033965Sjdp temp = (temp * 10) + *input_line_pointer - '0'; 86133965Sjdp ++input_line_pointer; 86233965Sjdp } /* read the whole number */ 86333965Sjdp 86433965Sjdp if (LOCAL_LABELS_DOLLAR 86533965Sjdp && *input_line_pointer == '$' 86633965Sjdp && *(input_line_pointer + 1) == ':') 86733965Sjdp { 86833965Sjdp input_line_pointer += 2; 86933965Sjdp 87033965Sjdp if (dollar_label_defined (temp)) 87133965Sjdp { 87233965Sjdp as_fatal ("label \"%d$\" redefined", temp); 87333965Sjdp } 87433965Sjdp 87533965Sjdp define_dollar_label (temp); 87633965Sjdp colon (dollar_label_name (temp, 0)); 87733965Sjdp continue; 87833965Sjdp } 87933965Sjdp 88033965Sjdp if (LOCAL_LABELS_FB 88133965Sjdp && *input_line_pointer++ == ':') 88233965Sjdp { 88333965Sjdp fb_label_instance_inc (temp); 88433965Sjdp colon (fb_label_name (temp, 0)); 88533965Sjdp continue; 88633965Sjdp } 88733965Sjdp 88833965Sjdp input_line_pointer = backup; 88933965Sjdp } /* local label ("4:") */ 89033965Sjdp 89133965Sjdp if (c && strchr (line_comment_chars, c)) 89233965Sjdp { /* Its a comment. Better say APP or NO_APP */ 89333965Sjdp char *ends; 89433965Sjdp char *new_buf; 89533965Sjdp char *new_tmp; 89633965Sjdp unsigned int new_length; 89733965Sjdp char *tmp_buf = 0; 89833965Sjdp 89933965Sjdp bump_line_counters (); 90033965Sjdp s = input_line_pointer; 90133965Sjdp if (strncmp (s, "APP\n", 4)) 90233965Sjdp continue; /* We ignore it */ 90333965Sjdp s += 4; 90433965Sjdp 90533965Sjdp ends = strstr (s, "#NO_APP\n"); 90633965Sjdp 90733965Sjdp if (!ends) 90833965Sjdp { 90933965Sjdp unsigned int tmp_len; 91033965Sjdp unsigned int num; 91133965Sjdp 91233965Sjdp /* The end of the #APP wasn't in this buffer. We 91333965Sjdp keep reading in buffers until we find the #NO_APP 91433965Sjdp that goes with this #APP There is one. The specs 91533965Sjdp guarentee it. . . */ 91633965Sjdp tmp_len = buffer_limit - s; 91733965Sjdp tmp_buf = xmalloc (tmp_len + 1); 91833965Sjdp memcpy (tmp_buf, s, tmp_len); 91933965Sjdp do 92033965Sjdp { 92133965Sjdp new_tmp = input_scrub_next_buffer (&buffer); 92233965Sjdp if (!new_tmp) 92333965Sjdp break; 92433965Sjdp else 92533965Sjdp buffer_limit = new_tmp; 92633965Sjdp input_line_pointer = buffer; 92733965Sjdp ends = strstr (buffer, "#NO_APP\n"); 92833965Sjdp if (ends) 92933965Sjdp num = ends - buffer; 93033965Sjdp else 93133965Sjdp num = buffer_limit - buffer; 93233965Sjdp 93333965Sjdp tmp_buf = xrealloc (tmp_buf, tmp_len + num); 93433965Sjdp memcpy (tmp_buf + tmp_len, buffer, num); 93533965Sjdp tmp_len += num; 93633965Sjdp } 93733965Sjdp while (!ends); 93833965Sjdp 93933965Sjdp input_line_pointer = ends ? ends + 8 : NULL; 94033965Sjdp 94133965Sjdp s = tmp_buf; 94233965Sjdp ends = s + tmp_len; 94333965Sjdp 94433965Sjdp } 94533965Sjdp else 94633965Sjdp { 94733965Sjdp input_line_pointer = ends + 8; 94833965Sjdp } 94933965Sjdp 95033965Sjdp scrub_string = s; 95133965Sjdp scrub_string_end = ends; 95233965Sjdp 95333965Sjdp new_length = ends - s; 95433965Sjdp new_buf = (char *) xmalloc (new_length); 95533965Sjdp new_tmp = new_buf; 95633965Sjdp for (;;) 95733965Sjdp { 95833965Sjdp int space; 95933965Sjdp int size; 96033965Sjdp 96133965Sjdp space = (new_buf + new_length) - new_tmp; 96233965Sjdp size = do_scrub_chars (scrub_from_string, new_tmp, space); 96333965Sjdp 96433965Sjdp if (size < space) 96533965Sjdp { 96633965Sjdp new_tmp += size; 96733965Sjdp break; 96833965Sjdp } 96933965Sjdp 97033965Sjdp new_buf = xrealloc (new_buf, new_length + 100); 97133965Sjdp new_tmp = new_buf + new_length; 97233965Sjdp new_length += 100; 97333965Sjdp } 97433965Sjdp 97533965Sjdp if (tmp_buf) 97633965Sjdp free (tmp_buf); 97733965Sjdp old_buffer = buffer; 97833965Sjdp old_input = input_line_pointer; 97933965Sjdp old_limit = buffer_limit; 98033965Sjdp buffer = new_buf; 98133965Sjdp input_line_pointer = new_buf; 98233965Sjdp buffer_limit = new_tmp; 98333965Sjdp continue; 98433965Sjdp } 98533965Sjdp 98633965Sjdp HANDLE_CONDITIONAL_ASSEMBLY (); 98733965Sjdp 98833965Sjdp#ifdef tc_unrecognized_line 98933965Sjdp if (tc_unrecognized_line (c)) 99033965Sjdp continue; 99133965Sjdp#endif 99233965Sjdp 99333965Sjdp /* as_warn("Junk character %d.",c); Now done by ignore_rest */ 99433965Sjdp input_line_pointer--; /* Report unknown char as ignored. */ 99533965Sjdp ignore_rest_of_line (); 99633965Sjdp } /* while (input_line_pointer<buffer_limit) */ 99733965Sjdp 99833965Sjdp#ifdef md_after_pass_hook 99933965Sjdp md_after_pass_hook (); 100033965Sjdp#endif 100133965Sjdp 100233965Sjdp if (old_buffer) 100333965Sjdp { 100433965Sjdp free (buffer); 100533965Sjdp bump_line_counters (); 100633965Sjdp if (old_input != 0) 100733965Sjdp { 100833965Sjdp buffer = old_buffer; 100933965Sjdp input_line_pointer = old_input; 101033965Sjdp buffer_limit = old_limit; 101133965Sjdp old_buffer = 0; 101233965Sjdp goto contin; 101333965Sjdp } 101433965Sjdp } 101533965Sjdp } /* while (more buffers to scan) */ 101633965Sjdp 101733965Sjdp quit: 101833965Sjdp 101933965Sjdp#ifdef md_cleanup 102033965Sjdp md_cleanup(); 102133965Sjdp#endif 102233965Sjdp input_scrub_close (); /* Close the input file */ 102333965Sjdp} 102433965Sjdp 102533965Sjdp/* For most MRI pseudo-ops, the line actually ends at the first 102633965Sjdp nonquoted space. This function looks for that point, stuffs a null 102733965Sjdp in, and sets *STOPCP to the character that used to be there, and 102833965Sjdp returns the location. 102933965Sjdp 103033965Sjdp Until I hear otherwise, I am going to assume that this is only true 103133965Sjdp for the m68k MRI assembler. */ 103233965Sjdp 103333965Sjdpchar * 103433965Sjdpmri_comment_field (stopcp) 103533965Sjdp char *stopcp; 103633965Sjdp{ 103733965Sjdp#ifdef TC_M68K 103833965Sjdp 103933965Sjdp char *s; 104033965Sjdp int inquote = 0; 104133965Sjdp 104233965Sjdp know (flag_m68k_mri); 104333965Sjdp 104433965Sjdp for (s = input_line_pointer; 104533965Sjdp ((! is_end_of_line[(unsigned char) *s] && *s != ' ' && *s != '\t') 104633965Sjdp || inquote); 104733965Sjdp s++) 104833965Sjdp { 104933965Sjdp if (*s == '\'') 105033965Sjdp inquote = ! inquote; 105133965Sjdp } 105233965Sjdp *stopcp = *s; 105333965Sjdp *s = '\0'; 105433965Sjdp return s; 105533965Sjdp 105633965Sjdp#else 105733965Sjdp 105833965Sjdp char *s; 105933965Sjdp 106033965Sjdp for (s = input_line_pointer; ! is_end_of_line[(unsigned char) *s]; s++) 106133965Sjdp ; 106233965Sjdp *stopcp = *s; 106333965Sjdp *s = '\0'; 106433965Sjdp return s; 106533965Sjdp 106633965Sjdp#endif 106733965Sjdp 106833965Sjdp} 106933965Sjdp 107033965Sjdp/* Skip to the end of an MRI comment field. */ 107133965Sjdp 107233965Sjdpvoid 107333965Sjdpmri_comment_end (stop, stopc) 107433965Sjdp char *stop; 107533965Sjdp int stopc; 107633965Sjdp{ 107733965Sjdp know (flag_mri); 107833965Sjdp 107933965Sjdp input_line_pointer = stop; 108033965Sjdp *stop = stopc; 108133965Sjdp while (! is_end_of_line[(unsigned char) *input_line_pointer]) 108233965Sjdp ++input_line_pointer; 108333965Sjdp} 108433965Sjdp 108533965Sjdpvoid 108633965Sjdps_abort (ignore) 108733965Sjdp int ignore; 108833965Sjdp{ 108933965Sjdp as_fatal (".abort detected. Abandoning ship."); 109033965Sjdp} 109133965Sjdp 109233965Sjdp/* Guts of .align directive. N is the power of two to which to align. 109333965Sjdp FILL may be NULL, or it may point to the bytes of the fill pattern. 109433965Sjdp LEN is the length of whatever FILL points to, if anything. MAX is 109533965Sjdp the maximum number of characters to skip when doing the alignment, 109633965Sjdp or 0 if there is no maximum. */ 109733965Sjdp 109833965Sjdpstatic void 109933965Sjdpdo_align (n, fill, len, max) 110033965Sjdp int n; 110133965Sjdp char *fill; 110233965Sjdp int len; 110333965Sjdp int max; 110433965Sjdp{ 110533965Sjdp char default_fill; 110633965Sjdp 110733965Sjdp#ifdef md_do_align 110833965Sjdp md_do_align (n, fill, len, max, just_record_alignment); 110933965Sjdp#endif 111033965Sjdp 111133965Sjdp if (fill == NULL) 111233965Sjdp { 111333965Sjdp /* FIXME: Fix this right for BFD! */ 111433965Sjdp if (now_seg != data_section && now_seg != bss_section) 111533965Sjdp default_fill = NOP_OPCODE; 111633965Sjdp else 111733965Sjdp default_fill = 0; 111833965Sjdp fill = &default_fill; 111933965Sjdp len = 1; 112033965Sjdp } 112133965Sjdp 112233965Sjdp /* Only make a frag if we HAVE to. . . */ 112333965Sjdp if (n != 0 && !need_pass_2) 112433965Sjdp { 112533965Sjdp if (len <= 1) 112633965Sjdp frag_align (n, *fill, max); 112733965Sjdp else 112833965Sjdp frag_align_pattern (n, fill, len, max); 112933965Sjdp } 113033965Sjdp 113133965Sjdp#ifdef md_do_align 113233965Sjdp just_record_alignment: 113333965Sjdp#endif 113433965Sjdp 113533965Sjdp record_alignment (now_seg, n); 113633965Sjdp} 113733965Sjdp 113833965Sjdp/* Handle the .align pseudo-op. A positive ARG is a default alignment 113933965Sjdp (in bytes). A negative ARG is the negative of the length of the 114033965Sjdp fill pattern. BYTES_P is non-zero if the alignment value should be 114133965Sjdp interpreted as the byte boundary, rather than the power of 2. */ 114233965Sjdp 114333965Sjdpstatic void 114433965Sjdps_align (arg, bytes_p) 114533965Sjdp int arg; 114633965Sjdp int bytes_p; 114733965Sjdp{ 114833965Sjdp register unsigned int align; 114933965Sjdp char *stop = NULL; 115033965Sjdp char stopc; 115133965Sjdp offsetT fill = 0; 115233965Sjdp int max; 115333965Sjdp int fill_p; 115433965Sjdp 115533965Sjdp if (flag_mri) 115633965Sjdp stop = mri_comment_field (&stopc); 115733965Sjdp 115833965Sjdp if (is_end_of_line[(unsigned char) *input_line_pointer]) 115933965Sjdp { 116033965Sjdp if (arg < 0) 116133965Sjdp align = 0; 116233965Sjdp else 116333965Sjdp align = arg; /* Default value from pseudo-op table */ 116433965Sjdp } 116533965Sjdp else 116633965Sjdp { 116733965Sjdp align = get_absolute_expression (); 116833965Sjdp SKIP_WHITESPACE (); 116933965Sjdp } 117033965Sjdp 117133965Sjdp if (bytes_p) 117233965Sjdp { 117333965Sjdp /* Convert to a power of 2. */ 117433965Sjdp if (align != 0) 117533965Sjdp { 117633965Sjdp unsigned int i; 117733965Sjdp 117833965Sjdp for (i = 0; (align & 1) == 0; align >>= 1, ++i) 117933965Sjdp ; 118033965Sjdp if (align != 1) 118133965Sjdp as_bad ("Alignment not a power of 2"); 118233965Sjdp align = i; 118333965Sjdp } 118433965Sjdp } 118533965Sjdp 118633965Sjdp if (align > 15) 118733965Sjdp { 118833965Sjdp align = 15; 118933965Sjdp as_bad ("Alignment too large: %u assumed", align); 119033965Sjdp } 119133965Sjdp 119233965Sjdp if (*input_line_pointer != ',') 119333965Sjdp { 119433965Sjdp fill_p = 0; 119533965Sjdp max = 0; 119633965Sjdp } 119733965Sjdp else 119833965Sjdp { 119933965Sjdp ++input_line_pointer; 120033965Sjdp if (*input_line_pointer == ',') 120133965Sjdp fill_p = 0; 120233965Sjdp else 120333965Sjdp { 120433965Sjdp fill = get_absolute_expression (); 120533965Sjdp SKIP_WHITESPACE (); 120633965Sjdp fill_p = 1; 120733965Sjdp } 120833965Sjdp 120933965Sjdp if (*input_line_pointer != ',') 121033965Sjdp max = 0; 121133965Sjdp else 121233965Sjdp { 121333965Sjdp ++input_line_pointer; 121433965Sjdp max = get_absolute_expression (); 121533965Sjdp } 121633965Sjdp } 121733965Sjdp 121833965Sjdp if (! fill_p) 121933965Sjdp { 122033965Sjdp if (arg < 0) 122133965Sjdp as_warn ("expected fill pattern missing"); 122233965Sjdp do_align (align, (char *) NULL, 0, max); 122333965Sjdp } 122433965Sjdp else 122533965Sjdp { 122633965Sjdp int fill_len; 122733965Sjdp 122833965Sjdp if (arg >= 0) 122933965Sjdp fill_len = 1; 123033965Sjdp else 123133965Sjdp fill_len = - arg; 123233965Sjdp if (fill_len <= 1) 123333965Sjdp { 123433965Sjdp char fill_char; 123533965Sjdp 123633965Sjdp fill_char = fill; 123733965Sjdp do_align (align, &fill_char, fill_len, max); 123833965Sjdp } 123933965Sjdp else 124033965Sjdp { 124133965Sjdp char ab[16]; 124233965Sjdp 124333965Sjdp if (fill_len > sizeof ab) 124433965Sjdp abort (); 124533965Sjdp md_number_to_chars (ab, fill, fill_len); 124633965Sjdp do_align (align, ab, fill_len, max); 124733965Sjdp } 124833965Sjdp } 124933965Sjdp 125033965Sjdp if (flag_mri) 125133965Sjdp mri_comment_end (stop, stopc); 125233965Sjdp 125333965Sjdp demand_empty_rest_of_line (); 125433965Sjdp} 125533965Sjdp 125633965Sjdp/* Handle the .align pseudo-op on machines where ".align 4" means 125733965Sjdp align to a 4 byte boundary. */ 125833965Sjdp 125933965Sjdpvoid 126033965Sjdps_align_bytes (arg) 126133965Sjdp int arg; 126233965Sjdp{ 126333965Sjdp s_align (arg, 1); 126433965Sjdp} 126533965Sjdp 126633965Sjdp/* Handle the .align pseud-op on machines where ".align 4" means align 126733965Sjdp to a 2**4 boundary. */ 126833965Sjdp 126933965Sjdpvoid 127033965Sjdps_align_ptwo (arg) 127133965Sjdp int arg; 127233965Sjdp{ 127333965Sjdp s_align (arg, 0); 127433965Sjdp} 127533965Sjdp 127633965Sjdpvoid 127733965Sjdps_comm (ignore) 127833965Sjdp int ignore; 127933965Sjdp{ 128033965Sjdp register char *name; 128133965Sjdp register char c; 128233965Sjdp register char *p; 128333965Sjdp offsetT temp; 128433965Sjdp register symbolS *symbolP; 128533965Sjdp char *stop = NULL; 128633965Sjdp char stopc; 128733965Sjdp 128833965Sjdp if (flag_mri) 128933965Sjdp stop = mri_comment_field (&stopc); 129033965Sjdp 129133965Sjdp name = input_line_pointer; 129233965Sjdp c = get_symbol_end (); 129333965Sjdp /* just after name is now '\0' */ 129433965Sjdp p = input_line_pointer; 129533965Sjdp *p = c; 129633965Sjdp SKIP_WHITESPACE (); 129733965Sjdp if (*input_line_pointer != ',') 129833965Sjdp { 129933965Sjdp as_bad ("Expected comma after symbol-name: rest of line ignored."); 130033965Sjdp if (flag_mri) 130133965Sjdp mri_comment_end (stop, stopc); 130233965Sjdp ignore_rest_of_line (); 130333965Sjdp return; 130433965Sjdp } 130533965Sjdp input_line_pointer++; /* skip ',' */ 130633965Sjdp if ((temp = get_absolute_expression ()) < 0) 130733965Sjdp { 130833965Sjdp as_warn (".COMMon length (%ld.) <0! Ignored.", (long) temp); 130933965Sjdp if (flag_mri) 131033965Sjdp mri_comment_end (stop, stopc); 131133965Sjdp ignore_rest_of_line (); 131233965Sjdp return; 131333965Sjdp } 131433965Sjdp *p = 0; 131533965Sjdp symbolP = symbol_find_or_make (name); 131633965Sjdp *p = c; 131733965Sjdp if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP)) 131833965Sjdp { 131933965Sjdp as_bad ("Ignoring attempt to re-define symbol `%s'.", 132033965Sjdp S_GET_NAME (symbolP)); 132133965Sjdp if (flag_mri) 132233965Sjdp mri_comment_end (stop, stopc); 132333965Sjdp ignore_rest_of_line (); 132433965Sjdp return; 132533965Sjdp } 132633965Sjdp if (S_GET_VALUE (symbolP)) 132733965Sjdp { 132833965Sjdp if (S_GET_VALUE (symbolP) != (valueT) temp) 132933965Sjdp as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.", 133033965Sjdp S_GET_NAME (symbolP), 133133965Sjdp (long) S_GET_VALUE (symbolP), 133233965Sjdp (long) temp); 133333965Sjdp } 133433965Sjdp else 133533965Sjdp { 133633965Sjdp S_SET_VALUE (symbolP, (valueT) temp); 133733965Sjdp S_SET_EXTERNAL (symbolP); 133833965Sjdp } 133933965Sjdp#ifdef OBJ_VMS 134033965Sjdp { 134133965Sjdp extern int flag_one; 134233965Sjdp if ( (!temp) || !flag_one) 134333965Sjdp S_GET_OTHER(symbolP) = const_flag; 134433965Sjdp } 134533965Sjdp#endif /* not OBJ_VMS */ 134633965Sjdp know (symbolP->sy_frag == &zero_address_frag); 134733965Sjdp 134833965Sjdp if (flag_mri) 134933965Sjdp mri_comment_end (stop, stopc); 135033965Sjdp 135133965Sjdp demand_empty_rest_of_line (); 135233965Sjdp} /* s_comm() */ 135333965Sjdp 135433965Sjdp/* The MRI COMMON pseudo-op. We handle this by creating a common 135533965Sjdp symbol with the appropriate name. We make s_space do the right 135633965Sjdp thing by increasing the size. */ 135733965Sjdp 135833965Sjdpvoid 135933965Sjdps_mri_common (small) 136033965Sjdp int small; 136133965Sjdp{ 136233965Sjdp char *name; 136333965Sjdp char c; 136433965Sjdp char *alc = NULL; 136533965Sjdp symbolS *sym; 136633965Sjdp offsetT align; 136733965Sjdp char *stop = NULL; 136833965Sjdp char stopc; 136933965Sjdp 137033965Sjdp if (! flag_mri) 137133965Sjdp { 137233965Sjdp s_comm (0); 137333965Sjdp return; 137433965Sjdp } 137533965Sjdp 137633965Sjdp stop = mri_comment_field (&stopc); 137733965Sjdp 137833965Sjdp SKIP_WHITESPACE (); 137933965Sjdp 138033965Sjdp name = input_line_pointer; 138133965Sjdp if (! isdigit ((unsigned char) *name)) 138233965Sjdp c = get_symbol_end (); 138333965Sjdp else 138433965Sjdp { 138533965Sjdp do 138633965Sjdp { 138733965Sjdp ++input_line_pointer; 138833965Sjdp } 138933965Sjdp while (isdigit ((unsigned char) *input_line_pointer)); 139033965Sjdp c = *input_line_pointer; 139133965Sjdp *input_line_pointer = '\0'; 139233965Sjdp 139333965Sjdp if (line_label != NULL) 139433965Sjdp { 139533965Sjdp alc = (char *) xmalloc (strlen (S_GET_NAME (line_label)) 139633965Sjdp + (input_line_pointer - name) 139733965Sjdp + 1); 139833965Sjdp sprintf (alc, "%s%s", name, S_GET_NAME (line_label)); 139933965Sjdp name = alc; 140033965Sjdp } 140133965Sjdp } 140233965Sjdp 140333965Sjdp sym = symbol_find_or_make (name); 140433965Sjdp *input_line_pointer = c; 140533965Sjdp if (alc != NULL) 140633965Sjdp free (alc); 140733965Sjdp 140833965Sjdp if (*input_line_pointer != ',') 140933965Sjdp align = 0; 141033965Sjdp else 141133965Sjdp { 141233965Sjdp ++input_line_pointer; 141333965Sjdp align = get_absolute_expression (); 141433965Sjdp } 141533965Sjdp 141633965Sjdp if (S_IS_DEFINED (sym) && ! S_IS_COMMON (sym)) 141733965Sjdp { 141833965Sjdp as_bad ("attempt to re-define symbol `%s'", S_GET_NAME (sym)); 141933965Sjdp mri_comment_end (stop, stopc); 142033965Sjdp ignore_rest_of_line (); 142133965Sjdp return; 142233965Sjdp } 142333965Sjdp 142433965Sjdp S_SET_EXTERNAL (sym); 142533965Sjdp mri_common_symbol = sym; 142633965Sjdp 142733965Sjdp#ifdef S_SET_ALIGN 142833965Sjdp if (align != 0) 142933965Sjdp S_SET_ALIGN (sym, align); 143033965Sjdp#endif 143133965Sjdp 143233965Sjdp if (line_label != NULL) 143333965Sjdp { 143433965Sjdp line_label->sy_value.X_op = O_symbol; 143533965Sjdp line_label->sy_value.X_add_symbol = sym; 143633965Sjdp line_label->sy_value.X_add_number = S_GET_VALUE (sym); 143733965Sjdp line_label->sy_frag = &zero_address_frag; 143833965Sjdp S_SET_SEGMENT (line_label, expr_section); 143933965Sjdp } 144033965Sjdp 144133965Sjdp /* FIXME: We just ignore the small argument, which distinguishes 144233965Sjdp COMMON and COMMON.S. I don't know what we can do about it. */ 144333965Sjdp 144433965Sjdp /* Ignore the type and hptype. */ 144533965Sjdp if (*input_line_pointer == ',') 144633965Sjdp input_line_pointer += 2; 144733965Sjdp if (*input_line_pointer == ',') 144833965Sjdp input_line_pointer += 2; 144933965Sjdp 145033965Sjdp mri_comment_end (stop, stopc); 145133965Sjdp 145233965Sjdp demand_empty_rest_of_line (); 145333965Sjdp} 145433965Sjdp 145533965Sjdpvoid 145633965Sjdps_data (ignore) 145733965Sjdp int ignore; 145833965Sjdp{ 145933965Sjdp segT section; 146033965Sjdp register int temp; 146133965Sjdp 146233965Sjdp temp = get_absolute_expression (); 146333965Sjdp if (flag_readonly_data_in_text) 146433965Sjdp { 146533965Sjdp section = text_section; 146633965Sjdp temp += 1000; 146733965Sjdp } 146833965Sjdp else 146933965Sjdp section = data_section; 147033965Sjdp 147133965Sjdp subseg_set (section, (subsegT) temp); 147233965Sjdp 147333965Sjdp#ifdef OBJ_VMS 147433965Sjdp const_flag = 0; 147533965Sjdp#endif 147633965Sjdp demand_empty_rest_of_line (); 147733965Sjdp} 147833965Sjdp 147933965Sjdp/* Handle the .appfile pseudo-op. This is automatically generated by 148033965Sjdp do_scrub_chars when a preprocessor # line comment is seen with a 148133965Sjdp file name. This default definition may be overridden by the object 148233965Sjdp or CPU specific pseudo-ops. This function is also the default 148333965Sjdp definition for .file; the APPFILE argument is 1 for .appfile, 0 for 148433965Sjdp .file. */ 148533965Sjdp 148633965Sjdpvoid 148733965Sjdps_app_file (appfile) 148833965Sjdp int appfile; 148933965Sjdp{ 149033965Sjdp register char *s; 149133965Sjdp int length; 149233965Sjdp 149333965Sjdp /* Some assemblers tolerate immediately following '"' */ 149433965Sjdp if ((s = demand_copy_string (&length)) != 0) 149533965Sjdp { 149633965Sjdp /* If this is a fake .appfile, a fake newline was inserted into 149733965Sjdp the buffer. Passing -2 to new_logical_line tells it to 149833965Sjdp account for it. */ 149933965Sjdp new_logical_line (s, appfile ? -2 : -1); 150033965Sjdp 150133965Sjdp /* In MRI mode, the preprocessor may have inserted an extraneous 150233965Sjdp backquote. */ 150333965Sjdp if (flag_m68k_mri 150433965Sjdp && *input_line_pointer == '\'' 150533965Sjdp && is_end_of_line[(unsigned char) input_line_pointer[1]]) 150633965Sjdp ++input_line_pointer; 150733965Sjdp 150833965Sjdp demand_empty_rest_of_line (); 150933965Sjdp#ifdef LISTING 151033965Sjdp if (listing) 151133965Sjdp listing_source_file (s); 151233965Sjdp#endif 151333965Sjdp } 151433965Sjdp#ifdef obj_app_file 151533965Sjdp obj_app_file (s); 151633965Sjdp#endif 151733965Sjdp} 151833965Sjdp 151933965Sjdp/* Handle the .appline pseudo-op. This is automatically generated by 152033965Sjdp do_scrub_chars when a preprocessor # line comment is seen. This 152133965Sjdp default definition may be overridden by the object or CPU specific 152233965Sjdp pseudo-ops. */ 152333965Sjdp 152433965Sjdpvoid 152533965Sjdps_app_line (ignore) 152633965Sjdp int ignore; 152733965Sjdp{ 152833965Sjdp int l; 152933965Sjdp 153033965Sjdp /* The given number is that of the next line. */ 153133965Sjdp l = get_absolute_expression () - 1; 153233965Sjdp if (l < 0) 153333965Sjdp /* Some of the back ends can't deal with non-positive line numbers. 153433965Sjdp Besides, it's silly. */ 153533965Sjdp as_warn ("Line numbers must be positive; line number %d rejected.", l+1); 153633965Sjdp else 153733965Sjdp { 153833965Sjdp new_logical_line ((char *) NULL, l); 153933965Sjdp#ifdef LISTING 154033965Sjdp if (listing) 154133965Sjdp listing_source_line (l); 154233965Sjdp#endif 154333965Sjdp } 154433965Sjdp demand_empty_rest_of_line (); 154533965Sjdp} 154633965Sjdp 154733965Sjdp/* Handle the .end pseudo-op. Actually, the real work is done in 154833965Sjdp read_a_source_file. */ 154933965Sjdp 155033965Sjdpvoid 155133965Sjdps_end (ignore) 155233965Sjdp int ignore; 155333965Sjdp{ 155433965Sjdp if (flag_mri) 155533965Sjdp { 155633965Sjdp /* The MRI assembler permits the start symbol to follow .end, 155733965Sjdp but we don't support that. */ 155833965Sjdp SKIP_WHITESPACE (); 155933965Sjdp if (! is_end_of_line[(unsigned char) *input_line_pointer] 156033965Sjdp && *input_line_pointer != '*' 156133965Sjdp && *input_line_pointer != '!') 156233965Sjdp as_warn ("start address not supported"); 156333965Sjdp } 156433965Sjdp} 156533965Sjdp 156633965Sjdp/* Handle the .err pseudo-op. */ 156733965Sjdp 156833965Sjdpvoid 156933965Sjdps_err (ignore) 157033965Sjdp int ignore; 157133965Sjdp{ 157233965Sjdp as_bad (".err encountered"); 157333965Sjdp demand_empty_rest_of_line (); 157433965Sjdp} 157533965Sjdp 157633965Sjdp/* Handle the MRI fail pseudo-op. */ 157733965Sjdp 157833965Sjdpvoid 157933965Sjdps_fail (ignore) 158033965Sjdp int ignore; 158133965Sjdp{ 158233965Sjdp offsetT temp; 158333965Sjdp char *stop = NULL; 158433965Sjdp char stopc; 158533965Sjdp 158633965Sjdp if (flag_mri) 158733965Sjdp stop = mri_comment_field (&stopc); 158833965Sjdp 158933965Sjdp temp = get_absolute_expression (); 159033965Sjdp if (temp >= 500) 159133965Sjdp as_warn (".fail %ld encountered", (long) temp); 159233965Sjdp else 159333965Sjdp as_bad (".fail %ld encountered", (long) temp); 159433965Sjdp 159533965Sjdp if (flag_mri) 159633965Sjdp mri_comment_end (stop, stopc); 159733965Sjdp 159833965Sjdp demand_empty_rest_of_line (); 159933965Sjdp} 160033965Sjdp 160133965Sjdpvoid 160233965Sjdps_fill (ignore) 160333965Sjdp int ignore; 160433965Sjdp{ 160533965Sjdp long temp_repeat = 0; 160633965Sjdp long temp_size = 1; 160733965Sjdp register long temp_fill = 0; 160833965Sjdp char *p; 160933965Sjdp 161033965Sjdp#ifdef md_flush_pending_output 161133965Sjdp md_flush_pending_output (); 161233965Sjdp#endif 161333965Sjdp 161433965Sjdp temp_repeat = get_absolute_expression (); 161533965Sjdp if (*input_line_pointer == ',') 161633965Sjdp { 161733965Sjdp input_line_pointer++; 161833965Sjdp temp_size = get_absolute_expression (); 161933965Sjdp if (*input_line_pointer == ',') 162033965Sjdp { 162133965Sjdp input_line_pointer++; 162233965Sjdp temp_fill = get_absolute_expression (); 162333965Sjdp } 162433965Sjdp } 162533965Sjdp /* This is to be compatible with BSD 4.2 AS, not for any rational reason. */ 162633965Sjdp#define BSD_FILL_SIZE_CROCK_8 (8) 162733965Sjdp if (temp_size > BSD_FILL_SIZE_CROCK_8) 162833965Sjdp { 162933965Sjdp as_warn (".fill size clamped to %d.", BSD_FILL_SIZE_CROCK_8); 163033965Sjdp temp_size = BSD_FILL_SIZE_CROCK_8; 163133965Sjdp } 163233965Sjdp if (temp_size < 0) 163333965Sjdp { 163433965Sjdp as_warn ("Size negative: .fill ignored."); 163533965Sjdp temp_size = 0; 163633965Sjdp } 163733965Sjdp else if (temp_repeat <= 0) 163833965Sjdp { 163933965Sjdp if (temp_repeat < 0) 164033965Sjdp as_warn ("Repeat < 0, .fill ignored"); 164133965Sjdp temp_size = 0; 164233965Sjdp } 164333965Sjdp 164433965Sjdp if (temp_size && !need_pass_2) 164533965Sjdp { 164633965Sjdp p = frag_var (rs_fill, (int) temp_size, (int) temp_size, 164733965Sjdp (relax_substateT) 0, (symbolS *) 0, (offsetT) temp_repeat, 164833965Sjdp (char *) 0); 164933965Sjdp memset (p, 0, (unsigned int) temp_size); 165033965Sjdp /* The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX 165133965Sjdp * flavoured AS. The following bizzare behaviour is to be 165233965Sjdp * compatible with above. I guess they tried to take up to 8 165333965Sjdp * bytes from a 4-byte expression and they forgot to sign 165433965Sjdp * extend. Un*x Sux. */ 165533965Sjdp#define BSD_FILL_SIZE_CROCK_4 (4) 165633965Sjdp md_number_to_chars (p, (valueT) temp_fill, 165733965Sjdp (temp_size > BSD_FILL_SIZE_CROCK_4 165833965Sjdp ? BSD_FILL_SIZE_CROCK_4 165933965Sjdp : (int) temp_size)); 166033965Sjdp /* Note: .fill (),0 emits no frag (since we are asked to .fill 0 bytes) 166133965Sjdp * but emits no error message because it seems a legal thing to do. 166233965Sjdp * It is a degenerate case of .fill but could be emitted by a compiler. 166333965Sjdp */ 166433965Sjdp } 166533965Sjdp demand_empty_rest_of_line (); 166633965Sjdp} 166733965Sjdp 166833965Sjdpvoid 166933965Sjdps_globl (ignore) 167033965Sjdp int ignore; 167133965Sjdp{ 167233965Sjdp char *name; 167333965Sjdp int c; 167433965Sjdp symbolS *symbolP; 167533965Sjdp char *stop = NULL; 167633965Sjdp char stopc; 167733965Sjdp 167833965Sjdp if (flag_mri) 167933965Sjdp stop = mri_comment_field (&stopc); 168033965Sjdp 168133965Sjdp do 168233965Sjdp { 168333965Sjdp name = input_line_pointer; 168433965Sjdp c = get_symbol_end (); 168533965Sjdp symbolP = symbol_find_or_make (name); 168633965Sjdp *input_line_pointer = c; 168733965Sjdp SKIP_WHITESPACE (); 168833965Sjdp S_SET_EXTERNAL (symbolP); 168933965Sjdp if (c == ',') 169033965Sjdp { 169133965Sjdp input_line_pointer++; 169233965Sjdp SKIP_WHITESPACE (); 169333965Sjdp if (*input_line_pointer == '\n') 169433965Sjdp c = '\n'; 169533965Sjdp } 169633965Sjdp } 169733965Sjdp while (c == ','); 169833965Sjdp 169933965Sjdp if (flag_mri) 170033965Sjdp mri_comment_end (stop, stopc); 170133965Sjdp 170233965Sjdp demand_empty_rest_of_line (); 170333965Sjdp} 170433965Sjdp 170533965Sjdp/* Handle the MRI IRP and IRPC pseudo-ops. */ 170633965Sjdp 170733965Sjdpvoid 170833965Sjdps_irp (irpc) 170933965Sjdp int irpc; 171033965Sjdp{ 171133965Sjdp char *file; 171233965Sjdp unsigned int line; 171333965Sjdp sb s; 171433965Sjdp const char *err; 171533965Sjdp sb out; 171633965Sjdp 171733965Sjdp as_where (&file, &line); 171833965Sjdp 171933965Sjdp sb_new (&s); 172033965Sjdp while (! is_end_of_line[(unsigned char) *input_line_pointer]) 172133965Sjdp sb_add_char (&s, *input_line_pointer++); 172233965Sjdp 172333965Sjdp sb_new (&out); 172433965Sjdp 172533965Sjdp err = expand_irp (irpc, 0, &s, &out, get_line_sb, '\0'); 172633965Sjdp if (err != NULL) 172733965Sjdp as_bad_where (file, line, "%s", err); 172833965Sjdp 172933965Sjdp sb_kill (&s); 173033965Sjdp 173133965Sjdp input_scrub_include_sb (&out, input_line_pointer); 173233965Sjdp sb_kill (&out); 173333965Sjdp buffer_limit = input_scrub_next_buffer (&input_line_pointer); 173433965Sjdp} 173533965Sjdp 173633965Sjdp/* Handle the .linkonce pseudo-op. This tells the assembler to mark 173733965Sjdp the section to only be linked once. However, this is not supported 173833965Sjdp by most object file formats. This takes an optional argument, 173933965Sjdp which is what to do about duplicates. */ 174033965Sjdp 174133965Sjdpvoid 174233965Sjdps_linkonce (ignore) 174333965Sjdp int ignore; 174433965Sjdp{ 174533965Sjdp enum linkonce_type type; 174633965Sjdp 174733965Sjdp SKIP_WHITESPACE (); 174833965Sjdp 174933965Sjdp type = LINKONCE_DISCARD; 175033965Sjdp 175133965Sjdp if (! is_end_of_line[(unsigned char) *input_line_pointer]) 175233965Sjdp { 175333965Sjdp char *s; 175433965Sjdp char c; 175533965Sjdp 175633965Sjdp s = input_line_pointer; 175733965Sjdp c = get_symbol_end (); 175833965Sjdp if (strcasecmp (s, "discard") == 0) 175933965Sjdp type = LINKONCE_DISCARD; 176033965Sjdp else if (strcasecmp (s, "one_only") == 0) 176133965Sjdp type = LINKONCE_ONE_ONLY; 176233965Sjdp else if (strcasecmp (s, "same_size") == 0) 176333965Sjdp type = LINKONCE_SAME_SIZE; 176433965Sjdp else if (strcasecmp (s, "same_contents") == 0) 176533965Sjdp type = LINKONCE_SAME_CONTENTS; 176633965Sjdp else 176733965Sjdp as_warn ("unrecognized .linkonce type `%s'", s); 176833965Sjdp 176933965Sjdp *input_line_pointer = c; 177033965Sjdp } 177133965Sjdp 177233965Sjdp#ifdef obj_handle_link_once 177333965Sjdp obj_handle_link_once (type); 177433965Sjdp#else /* ! defined (obj_handle_link_once) */ 177533965Sjdp#ifdef BFD_ASSEMBLER 177633965Sjdp { 177733965Sjdp flagword flags; 177833965Sjdp 177933965Sjdp if ((bfd_applicable_section_flags (stdoutput) & SEC_LINK_ONCE) == 0) 178033965Sjdp as_warn (".linkonce is not supported for this object file format"); 178133965Sjdp 178233965Sjdp flags = bfd_get_section_flags (stdoutput, now_seg); 178333965Sjdp flags |= SEC_LINK_ONCE; 178433965Sjdp switch (type) 178533965Sjdp { 178633965Sjdp default: 178733965Sjdp abort (); 178833965Sjdp case LINKONCE_DISCARD: 178933965Sjdp flags |= SEC_LINK_DUPLICATES_DISCARD; 179033965Sjdp break; 179133965Sjdp case LINKONCE_ONE_ONLY: 179233965Sjdp flags |= SEC_LINK_DUPLICATES_ONE_ONLY; 179333965Sjdp break; 179433965Sjdp case LINKONCE_SAME_SIZE: 179533965Sjdp flags |= SEC_LINK_DUPLICATES_SAME_SIZE; 179633965Sjdp break; 179733965Sjdp case LINKONCE_SAME_CONTENTS: 179833965Sjdp flags |= SEC_LINK_DUPLICATES_SAME_CONTENTS; 179933965Sjdp break; 180033965Sjdp } 180133965Sjdp if (! bfd_set_section_flags (stdoutput, now_seg, flags)) 180233965Sjdp as_bad ("bfd_set_section_flags: %s", 180333965Sjdp bfd_errmsg (bfd_get_error ())); 180433965Sjdp } 180533965Sjdp#else /* ! defined (BFD_ASSEMBLER) */ 180633965Sjdp as_warn (".linkonce is not supported for this object file format"); 180733965Sjdp#endif /* ! defined (BFD_ASSEMBLER) */ 180833965Sjdp#endif /* ! defined (obj_handle_link_once) */ 180933965Sjdp 181033965Sjdp demand_empty_rest_of_line (); 181133965Sjdp} 181233965Sjdp 181333965Sjdpvoid 181433965Sjdps_lcomm (needs_align) 181533965Sjdp /* 1 if this was a ".bss" directive, which may require a 3rd argument 181633965Sjdp (alignment); 0 if it was an ".lcomm" (2 args only) */ 181733965Sjdp int needs_align; 181833965Sjdp{ 181933965Sjdp register char *name; 182033965Sjdp register char c; 182133965Sjdp register char *p; 182233965Sjdp register int temp; 182333965Sjdp register symbolS *symbolP; 182433965Sjdp segT current_seg = now_seg; 182533965Sjdp subsegT current_subseg = now_subseg; 182633965Sjdp const int max_alignment = 15; 182733965Sjdp int align = 0; 182833965Sjdp segT bss_seg = bss_section; 182933965Sjdp 183033965Sjdp name = input_line_pointer; 183133965Sjdp c = get_symbol_end (); 183233965Sjdp p = input_line_pointer; 183333965Sjdp *p = c; 183433965Sjdp SKIP_WHITESPACE (); 183533965Sjdp 183633965Sjdp /* Accept an optional comma after the name. The comma used to be 183733965Sjdp required, but Irix 5 cc does not generate it. */ 183833965Sjdp if (*input_line_pointer == ',') 183933965Sjdp { 184033965Sjdp ++input_line_pointer; 184133965Sjdp SKIP_WHITESPACE (); 184233965Sjdp } 184333965Sjdp 184433965Sjdp if (*input_line_pointer == '\n') 184533965Sjdp { 184633965Sjdp as_bad ("Missing size expression"); 184733965Sjdp return; 184833965Sjdp } 184933965Sjdp 185033965Sjdp if ((temp = get_absolute_expression ()) < 0) 185133965Sjdp { 185233965Sjdp as_warn ("BSS length (%d.) <0! Ignored.", temp); 185333965Sjdp ignore_rest_of_line (); 185433965Sjdp return; 185533965Sjdp } 185633965Sjdp 185733965Sjdp#if defined (TC_MIPS) || defined (TC_ALPHA) 185833965Sjdp if (OUTPUT_FLAVOR == bfd_target_ecoff_flavour 185933965Sjdp || OUTPUT_FLAVOR == bfd_target_elf_flavour) 186033965Sjdp { 186133965Sjdp /* For MIPS and Alpha ECOFF or ELF, small objects are put in .sbss. */ 186233965Sjdp if (temp <= bfd_get_gp_size (stdoutput)) 186333965Sjdp { 186433965Sjdp bss_seg = subseg_new (".sbss", 1); 186533965Sjdp seg_info (bss_seg)->bss = 1; 186633965Sjdp#ifdef BFD_ASSEMBLER 186733965Sjdp if (! bfd_set_section_flags (stdoutput, bss_seg, SEC_ALLOC)) 186833965Sjdp as_warn ("error setting flags for \".sbss\": %s", 186933965Sjdp bfd_errmsg (bfd_get_error ())); 187033965Sjdp#endif 187133965Sjdp } 187233965Sjdp } 187333965Sjdp#endif 187433965Sjdp if (!needs_align) 187533965Sjdp { 187633965Sjdp /* FIXME. This needs to be machine independent. */ 187733965Sjdp if (temp >= 8) 187833965Sjdp align = 3; 187933965Sjdp else if (temp >= 4) 188033965Sjdp align = 2; 188133965Sjdp else if (temp >= 2) 188233965Sjdp align = 1; 188333965Sjdp else 188433965Sjdp align = 0; 188533965Sjdp 188633965Sjdp#ifdef OBJ_EVAX 188733965Sjdp /* FIXME: This needs to be done in a more general fashion. */ 188833965Sjdp align = 3; 188933965Sjdp#endif 189033965Sjdp 189133965Sjdp record_alignment(bss_seg, align); 189233965Sjdp } 189333965Sjdp 189433965Sjdp if (needs_align) 189533965Sjdp { 189633965Sjdp align = 0; 189733965Sjdp SKIP_WHITESPACE (); 189833965Sjdp if (*input_line_pointer != ',') 189933965Sjdp { 190033965Sjdp as_bad ("Expected comma after size"); 190133965Sjdp ignore_rest_of_line (); 190233965Sjdp return; 190333965Sjdp } 190433965Sjdp input_line_pointer++; 190533965Sjdp SKIP_WHITESPACE (); 190633965Sjdp if (*input_line_pointer == '\n') 190733965Sjdp { 190833965Sjdp as_bad ("Missing alignment"); 190933965Sjdp return; 191033965Sjdp } 191133965Sjdp align = get_absolute_expression (); 191233965Sjdp if (align > max_alignment) 191333965Sjdp { 191433965Sjdp align = max_alignment; 191533965Sjdp as_warn ("Alignment too large: %d. assumed.", align); 191633965Sjdp } 191733965Sjdp else if (align < 0) 191833965Sjdp { 191933965Sjdp align = 0; 192033965Sjdp as_warn ("Alignment negative. 0 assumed."); 192133965Sjdp } 192233965Sjdp record_alignment (bss_seg, align); 192333965Sjdp } /* if needs align */ 192433965Sjdp else 192533965Sjdp { 192633965Sjdp /* Assume some objects may require alignment on some systems. */ 192733965Sjdp#if defined (TC_ALPHA) && ! defined (VMS) 192833965Sjdp if (temp > 1) 192933965Sjdp { 193033965Sjdp align = ffs (temp) - 1; 193133965Sjdp if (temp % (1 << align)) 193233965Sjdp abort (); 193333965Sjdp } 193433965Sjdp#endif 193533965Sjdp } 193633965Sjdp 193733965Sjdp *p = 0; 193833965Sjdp symbolP = symbol_find_or_make (name); 193933965Sjdp *p = c; 194033965Sjdp 194133965Sjdp if ( 194233965Sjdp#if defined(OBJ_AOUT) | defined(OBJ_BOUT) 194333965Sjdp S_GET_OTHER (symbolP) == 0 && 194433965Sjdp S_GET_DESC (symbolP) == 0 && 194533965Sjdp#endif /* OBJ_AOUT or OBJ_BOUT */ 194633965Sjdp (S_GET_SEGMENT (symbolP) == bss_seg 194733965Sjdp || (!S_IS_DEFINED (symbolP) && S_GET_VALUE (symbolP) == 0))) 194833965Sjdp { 194933965Sjdp char *pfrag; 195033965Sjdp 195133965Sjdp subseg_set (bss_seg, 1); 195233965Sjdp 195333965Sjdp if (align) 195433965Sjdp frag_align (align, 0, 0); 195533965Sjdp /* detach from old frag */ 195633965Sjdp if (S_GET_SEGMENT (symbolP) == bss_seg) 195733965Sjdp symbolP->sy_frag->fr_symbol = NULL; 195833965Sjdp 195933965Sjdp symbolP->sy_frag = frag_now; 196033965Sjdp pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP, 196133965Sjdp (offsetT) temp, (char *) 0); 196233965Sjdp *pfrag = 0; 196333965Sjdp 196433965Sjdp S_SET_SEGMENT (symbolP, bss_seg); 196533965Sjdp 196633965Sjdp#ifdef OBJ_COFF 196733965Sjdp /* The symbol may already have been created with a preceding 196833965Sjdp ".globl" directive -- be careful not to step on storage class 196933965Sjdp in that case. Otherwise, set it to static. */ 197033965Sjdp if (S_GET_STORAGE_CLASS (symbolP) != C_EXT) 197133965Sjdp { 197233965Sjdp S_SET_STORAGE_CLASS (symbolP, C_STAT); 197333965Sjdp } 197433965Sjdp#endif /* OBJ_COFF */ 197533965Sjdp 197633965Sjdp#ifdef S_SET_SIZE 197733965Sjdp S_SET_SIZE (symbolP, temp); 197833965Sjdp#endif 197933965Sjdp } 198033965Sjdp else 198133965Sjdp as_bad ("Ignoring attempt to re-define symbol `%s'.", 198233965Sjdp S_GET_NAME (symbolP)); 198333965Sjdp 198433965Sjdp subseg_set (current_seg, current_subseg); 198533965Sjdp 198633965Sjdp demand_empty_rest_of_line (); 198733965Sjdp} /* s_lcomm() */ 198833965Sjdp 198933965Sjdpvoid 199033965Sjdps_lsym (ignore) 199133965Sjdp int ignore; 199233965Sjdp{ 199333965Sjdp register char *name; 199433965Sjdp register char c; 199533965Sjdp register char *p; 199633965Sjdp expressionS exp; 199733965Sjdp register symbolS *symbolP; 199833965Sjdp 199933965Sjdp /* we permit ANY defined expression: BSD4.2 demands constants */ 200033965Sjdp name = input_line_pointer; 200133965Sjdp c = get_symbol_end (); 200233965Sjdp p = input_line_pointer; 200333965Sjdp *p = c; 200433965Sjdp SKIP_WHITESPACE (); 200533965Sjdp if (*input_line_pointer != ',') 200633965Sjdp { 200733965Sjdp *p = 0; 200833965Sjdp as_bad ("Expected comma after name \"%s\"", name); 200933965Sjdp *p = c; 201033965Sjdp ignore_rest_of_line (); 201133965Sjdp return; 201233965Sjdp } 201333965Sjdp input_line_pointer++; 201433965Sjdp expression (&exp); 201533965Sjdp if (exp.X_op != O_constant 201633965Sjdp && exp.X_op != O_register) 201733965Sjdp { 201833965Sjdp as_bad ("bad expression"); 201933965Sjdp ignore_rest_of_line (); 202033965Sjdp return; 202133965Sjdp } 202233965Sjdp *p = 0; 202333965Sjdp symbolP = symbol_find_or_make (name); 202433965Sjdp 202533965Sjdp /* FIXME-SOON I pulled a (&& symbolP->sy_other == 0 && 202633965Sjdp symbolP->sy_desc == 0) out of this test because coff doesn't have 202733965Sjdp those fields, and I can't see when they'd ever be tripped. I 202833965Sjdp don't think I understand why they were here so I may have 202933965Sjdp introduced a bug. As recently as 1.37 didn't have this test 203033965Sjdp anyway. xoxorich. */ 203133965Sjdp 203233965Sjdp if (S_GET_SEGMENT (symbolP) == undefined_section 203333965Sjdp && S_GET_VALUE (symbolP) == 0) 203433965Sjdp { 203533965Sjdp /* The name might be an undefined .global symbol; be sure to 203633965Sjdp keep the "external" bit. */ 203733965Sjdp S_SET_SEGMENT (symbolP, 203833965Sjdp (exp.X_op == O_constant 203933965Sjdp ? absolute_section 204033965Sjdp : reg_section)); 204133965Sjdp S_SET_VALUE (symbolP, (valueT) exp.X_add_number); 204233965Sjdp } 204333965Sjdp else 204433965Sjdp { 204533965Sjdp as_bad ("Symbol %s already defined", name); 204633965Sjdp } 204733965Sjdp *p = c; 204833965Sjdp demand_empty_rest_of_line (); 204933965Sjdp} /* s_lsym() */ 205033965Sjdp 205133965Sjdp/* Read a line into an sb. */ 205233965Sjdp 205333965Sjdpstatic int 205433965Sjdpget_line_sb (line) 205533965Sjdp sb *line; 205633965Sjdp{ 205733965Sjdp char quote1, quote2, inquote; 205833965Sjdp 205933965Sjdp if (input_line_pointer[-1] == '\n') 206033965Sjdp bump_line_counters (); 206133965Sjdp 206233965Sjdp if (input_line_pointer >= buffer_limit) 206333965Sjdp { 206433965Sjdp buffer_limit = input_scrub_next_buffer (&input_line_pointer); 206533965Sjdp if (buffer_limit == 0) 206633965Sjdp return 0; 206733965Sjdp } 206833965Sjdp 206933965Sjdp /* If app.c sets any other characters to LEX_IS_STRINGQUOTE, this 207033965Sjdp code needs to be changed. */ 207133965Sjdp if (! flag_m68k_mri) 207233965Sjdp quote1 = '"'; 207333965Sjdp else 207433965Sjdp quote1 = '\0'; 207533965Sjdp 207633965Sjdp quote2 = '\0'; 207733965Sjdp if (flag_m68k_mri) 207833965Sjdp quote2 = '\''; 207933965Sjdp#ifdef LEX_IS_STRINGQUOTE 208033965Sjdp quote2 = '\''; 208133965Sjdp#endif 208233965Sjdp 208333965Sjdp inquote = '\0'; 208433965Sjdp while (! is_end_of_line[(unsigned char) *input_line_pointer] 208533965Sjdp || (inquote != '\0' && *input_line_pointer != '\n')) 208633965Sjdp { 208733965Sjdp if (inquote == *input_line_pointer) 208833965Sjdp inquote = '\0'; 208933965Sjdp else if (inquote == '\0') 209033965Sjdp { 209133965Sjdp if (*input_line_pointer == quote1) 209233965Sjdp inquote = quote1; 209333965Sjdp else if (*input_line_pointer == quote2) 209433965Sjdp inquote = quote2; 209533965Sjdp } 209633965Sjdp sb_add_char (line, *input_line_pointer++); 209733965Sjdp } 209833965Sjdp while (input_line_pointer < buffer_limit && *input_line_pointer == '\n') 209933965Sjdp { 210033965Sjdp if (input_line_pointer[-1] == '\n') 210133965Sjdp bump_line_counters (); 210233965Sjdp ++input_line_pointer; 210333965Sjdp } 210433965Sjdp return 1; 210533965Sjdp} 210633965Sjdp 210733965Sjdp/* Define a macro. This is an interface to macro.c, which is shared 210833965Sjdp between gas and gasp. */ 210933965Sjdp 211033965Sjdpvoid 211133965Sjdps_macro (ignore) 211233965Sjdp int ignore; 211333965Sjdp{ 211433965Sjdp char *file; 211533965Sjdp unsigned int line; 211633965Sjdp sb s; 211733965Sjdp sb label; 211833965Sjdp const char *err; 211933965Sjdp const char *name; 212033965Sjdp 212133965Sjdp as_where (&file, &line); 212233965Sjdp 212333965Sjdp sb_new (&s); 212433965Sjdp while (! is_end_of_line[(unsigned char) *input_line_pointer]) 212533965Sjdp sb_add_char (&s, *input_line_pointer++); 212633965Sjdp 212733965Sjdp sb_new (&label); 212833965Sjdp if (line_label != NULL) 212933965Sjdp sb_add_string (&label, S_GET_NAME (line_label)); 213033965Sjdp 213133965Sjdp err = define_macro (0, &s, &label, get_line_sb, &name); 213233965Sjdp if (err != NULL) 213333965Sjdp as_bad_where (file, line, "%s", err); 213433965Sjdp else 213533965Sjdp { 213633965Sjdp if (line_label != NULL) 213733965Sjdp { 213833965Sjdp S_SET_SEGMENT (line_label, undefined_section); 213933965Sjdp S_SET_VALUE (line_label, 0); 214033965Sjdp line_label->sy_frag = &zero_address_frag; 214133965Sjdp } 214233965Sjdp 214333965Sjdp if (((flag_m68k_mri 214433965Sjdp#ifdef NO_PSEUDO_DOT 214533965Sjdp || 1 214633965Sjdp#endif 214733965Sjdp ) 214833965Sjdp && hash_find (po_hash, name) != NULL) 214933965Sjdp || (! flag_m68k_mri 215033965Sjdp && *name == '.' 215133965Sjdp && hash_find (po_hash, name + 1) != NULL)) 215233965Sjdp as_warn ("attempt to redefine pseudo-op `%s' ignored", 215333965Sjdp name); 215433965Sjdp } 215533965Sjdp 215633965Sjdp sb_kill (&s); 215733965Sjdp} 215833965Sjdp 215933965Sjdp/* Handle the .mexit pseudo-op, which immediately exits a macro 216033965Sjdp expansion. */ 216133965Sjdp 216233965Sjdpvoid 216333965Sjdps_mexit (ignore) 216433965Sjdp int ignore; 216533965Sjdp{ 216633965Sjdp cond_exit_macro (macro_nest); 216733965Sjdp buffer_limit = input_scrub_next_buffer (&input_line_pointer); 216833965Sjdp} 216933965Sjdp 217033965Sjdp/* Switch in and out of MRI mode. */ 217133965Sjdp 217233965Sjdpvoid 217333965Sjdps_mri (ignore) 217433965Sjdp int ignore; 217533965Sjdp{ 217633965Sjdp int on, old_flag; 217733965Sjdp 217833965Sjdp on = get_absolute_expression (); 217933965Sjdp old_flag = flag_mri; 218033965Sjdp if (on != 0) 218133965Sjdp { 218233965Sjdp flag_mri = 1; 218333965Sjdp#ifdef TC_M68K 218433965Sjdp flag_m68k_mri = 1; 218533965Sjdp#endif 218633965Sjdp } 218733965Sjdp else 218833965Sjdp { 218933965Sjdp flag_mri = 0; 219033965Sjdp flag_m68k_mri = 0; 219133965Sjdp } 219233965Sjdp 219333965Sjdp#ifdef MRI_MODE_CHANGE 219433965Sjdp if (on != old_flag) 219533965Sjdp MRI_MODE_CHANGE (on); 219633965Sjdp#endif 219733965Sjdp 219833965Sjdp demand_empty_rest_of_line (); 219933965Sjdp} 220033965Sjdp 220133965Sjdp/* Handle changing the location counter. */ 220233965Sjdp 220333965Sjdpstatic void 220433965Sjdpdo_org (segment, exp, fill) 220533965Sjdp segT segment; 220633965Sjdp expressionS *exp; 220733965Sjdp int fill; 220833965Sjdp{ 220933965Sjdp if (segment != now_seg && segment != absolute_section) 221033965Sjdp as_bad ("invalid segment \"%s\"; segment \"%s\" assumed", 221133965Sjdp segment_name (segment), segment_name (now_seg)); 221233965Sjdp 221333965Sjdp if (now_seg == absolute_section) 221433965Sjdp { 221533965Sjdp if (fill != 0) 221633965Sjdp as_warn ("ignoring fill value in absolute section"); 221733965Sjdp if (exp->X_op != O_constant) 221833965Sjdp { 221933965Sjdp as_bad ("only constant offsets supported in absolute section"); 222033965Sjdp exp->X_add_number = 0; 222133965Sjdp } 222233965Sjdp abs_section_offset = exp->X_add_number; 222333965Sjdp } 222433965Sjdp else 222533965Sjdp { 222633965Sjdp char *p; 222733965Sjdp 222833965Sjdp p = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp->X_add_symbol, 222933965Sjdp exp->X_add_number, (char *) NULL); 223033965Sjdp *p = fill; 223133965Sjdp } 223233965Sjdp} 223333965Sjdp 223433965Sjdpvoid 223533965Sjdps_org (ignore) 223633965Sjdp int ignore; 223733965Sjdp{ 223833965Sjdp register segT segment; 223933965Sjdp expressionS exp; 224033965Sjdp register long temp_fill; 224133965Sjdp 224233965Sjdp /* The m68k MRI assembler has a different meaning for .org. It 224333965Sjdp means to create an absolute section at a given address. We can't 224433965Sjdp support that--use a linker script instead. */ 224533965Sjdp if (flag_m68k_mri) 224633965Sjdp { 224733965Sjdp as_bad ("MRI style ORG pseudo-op not supported"); 224833965Sjdp ignore_rest_of_line (); 224933965Sjdp return; 225033965Sjdp } 225133965Sjdp 225233965Sjdp /* Don't believe the documentation of BSD 4.2 AS. There is no such 225333965Sjdp thing as a sub-segment-relative origin. Any absolute origin is 225433965Sjdp given a warning, then assumed to be segment-relative. Any 225533965Sjdp segmented origin expression ("foo+42") had better be in the right 225633965Sjdp segment or the .org is ignored. 225733965Sjdp 225833965Sjdp BSD 4.2 AS warns if you try to .org backwards. We cannot because 225933965Sjdp we never know sub-segment sizes when we are reading code. BSD 226033965Sjdp will crash trying to emit negative numbers of filler bytes in 226133965Sjdp certain .orgs. We don't crash, but see as-write for that code. 226233965Sjdp 226333965Sjdp Don't make frag if need_pass_2==1. */ 226433965Sjdp segment = get_known_segmented_expression (&exp); 226533965Sjdp if (*input_line_pointer == ',') 226633965Sjdp { 226733965Sjdp input_line_pointer++; 226833965Sjdp temp_fill = get_absolute_expression (); 226933965Sjdp } 227033965Sjdp else 227133965Sjdp temp_fill = 0; 227233965Sjdp 227333965Sjdp if (!need_pass_2) 227433965Sjdp do_org (segment, &exp, temp_fill); 227533965Sjdp 227633965Sjdp demand_empty_rest_of_line (); 227733965Sjdp} /* s_org() */ 227833965Sjdp 227933965Sjdp/* Handle parsing for the MRI SECT/SECTION pseudo-op. This should be 228033965Sjdp called by the obj-format routine which handles section changing 228133965Sjdp when in MRI mode. It will create a new section, and return it. It 228233965Sjdp will set *TYPE to the section type: one of 'C' (code), 'D' (data), 228333965Sjdp 'M' (mixed), or 'R' (romable). If BFD_ASSEMBLER is defined, the 228433965Sjdp flags will be set in the section. */ 228533965Sjdp 228633965Sjdpvoid 228733965Sjdps_mri_sect (type) 228833965Sjdp char *type; 228933965Sjdp{ 229033965Sjdp#ifdef TC_M68K 229133965Sjdp 229233965Sjdp char *name; 229333965Sjdp char c; 229433965Sjdp segT seg; 229533965Sjdp 229633965Sjdp SKIP_WHITESPACE (); 229733965Sjdp 229833965Sjdp name = input_line_pointer; 229933965Sjdp if (! isdigit ((unsigned char) *name)) 230033965Sjdp c = get_symbol_end (); 230133965Sjdp else 230233965Sjdp { 230333965Sjdp do 230433965Sjdp { 230533965Sjdp ++input_line_pointer; 230633965Sjdp } 230733965Sjdp while (isdigit ((unsigned char) *input_line_pointer)); 230833965Sjdp c = *input_line_pointer; 230933965Sjdp *input_line_pointer = '\0'; 231033965Sjdp } 231133965Sjdp 231233965Sjdp name = xstrdup (name); 231333965Sjdp 231433965Sjdp *input_line_pointer = c; 231533965Sjdp 231633965Sjdp seg = subseg_new (name, 0); 231733965Sjdp 231833965Sjdp if (*input_line_pointer == ',') 231933965Sjdp { 232033965Sjdp int align; 232133965Sjdp 232233965Sjdp ++input_line_pointer; 232333965Sjdp align = get_absolute_expression (); 232433965Sjdp record_alignment (seg, align); 232533965Sjdp } 232633965Sjdp 232733965Sjdp *type = 'C'; 232833965Sjdp if (*input_line_pointer == ',') 232933965Sjdp { 233033965Sjdp c = *++input_line_pointer; 233133965Sjdp c = toupper ((unsigned char) c); 233233965Sjdp if (c == 'C' || c == 'D' || c == 'M' || c == 'R') 233333965Sjdp *type = c; 233433965Sjdp else 233533965Sjdp as_bad ("unrecognized section type"); 233633965Sjdp ++input_line_pointer; 233733965Sjdp 233833965Sjdp#ifdef BFD_ASSEMBLER 233933965Sjdp { 234033965Sjdp flagword flags; 234133965Sjdp 234233965Sjdp flags = SEC_NO_FLAGS; 234333965Sjdp if (*type == 'C') 234433965Sjdp flags = SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE; 234533965Sjdp else if (*type == 'D' || *type == 'M') 234633965Sjdp flags = SEC_ALLOC | SEC_LOAD | SEC_DATA; 234733965Sjdp else if (*type == 'R') 234833965Sjdp flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_READONLY | SEC_ROM; 234933965Sjdp if (flags != SEC_NO_FLAGS) 235033965Sjdp { 235133965Sjdp if (! bfd_set_section_flags (stdoutput, seg, flags)) 235233965Sjdp as_warn ("error setting flags for \"%s\": %s", 235333965Sjdp bfd_section_name (stdoutput, seg), 235433965Sjdp bfd_errmsg (bfd_get_error ())); 235533965Sjdp } 235633965Sjdp } 235733965Sjdp#endif 235833965Sjdp } 235933965Sjdp 236033965Sjdp /* Ignore the HP type. */ 236133965Sjdp if (*input_line_pointer == ',') 236233965Sjdp input_line_pointer += 2; 236333965Sjdp 236433965Sjdp demand_empty_rest_of_line (); 236533965Sjdp 236633965Sjdp#else /* ! TC_M68K */ 236733965Sjdp#ifdef TC_I960 236833965Sjdp 236933965Sjdp char *name; 237033965Sjdp char c; 237133965Sjdp segT seg; 237233965Sjdp 237333965Sjdp SKIP_WHITESPACE (); 237433965Sjdp 237533965Sjdp name = input_line_pointer; 237633965Sjdp c = get_symbol_end (); 237733965Sjdp 237833965Sjdp name = xstrdup (name); 237933965Sjdp 238033965Sjdp *input_line_pointer = c; 238133965Sjdp 238233965Sjdp seg = subseg_new (name, 0); 238333965Sjdp 238433965Sjdp if (*input_line_pointer != ',') 238533965Sjdp *type = 'C'; 238633965Sjdp else 238733965Sjdp { 238833965Sjdp char *sectype; 238933965Sjdp 239033965Sjdp ++input_line_pointer; 239133965Sjdp SKIP_WHITESPACE (); 239233965Sjdp sectype = input_line_pointer; 239333965Sjdp c = get_symbol_end (); 239433965Sjdp if (*sectype == '\0') 239533965Sjdp *type = 'C'; 239633965Sjdp else if (strcasecmp (sectype, "text") == 0) 239733965Sjdp *type = 'C'; 239833965Sjdp else if (strcasecmp (sectype, "data") == 0) 239933965Sjdp *type = 'D'; 240033965Sjdp else if (strcasecmp (sectype, "romdata") == 0) 240133965Sjdp *type = 'R'; 240233965Sjdp else 240333965Sjdp as_warn ("unrecognized section type `%s'", sectype); 240433965Sjdp *input_line_pointer = c; 240533965Sjdp } 240633965Sjdp 240733965Sjdp if (*input_line_pointer == ',') 240833965Sjdp { 240933965Sjdp char *seccmd; 241033965Sjdp 241133965Sjdp ++input_line_pointer; 241233965Sjdp SKIP_WHITESPACE (); 241333965Sjdp seccmd = input_line_pointer; 241433965Sjdp c = get_symbol_end (); 241533965Sjdp if (strcasecmp (seccmd, "absolute") == 0) 241633965Sjdp { 241733965Sjdp as_bad ("absolute sections are not supported"); 241833965Sjdp *input_line_pointer = c; 241933965Sjdp ignore_rest_of_line (); 242033965Sjdp return; 242133965Sjdp } 242233965Sjdp else if (strcasecmp (seccmd, "align") == 0) 242333965Sjdp { 242433965Sjdp int align; 242533965Sjdp 242633965Sjdp *input_line_pointer = c; 242733965Sjdp align = get_absolute_expression (); 242833965Sjdp record_alignment (seg, align); 242933965Sjdp } 243033965Sjdp else 243133965Sjdp { 243233965Sjdp as_warn ("unrecognized section command `%s'", seccmd); 243333965Sjdp *input_line_pointer = c; 243433965Sjdp } 243533965Sjdp } 243633965Sjdp 243733965Sjdp demand_empty_rest_of_line (); 243833965Sjdp 243933965Sjdp#else /* ! TC_I960 */ 244033965Sjdp /* The MRI assembler seems to use different forms of .sect for 244133965Sjdp different targets. */ 244233965Sjdp abort (); 244333965Sjdp#endif /* ! TC_I960 */ 244433965Sjdp#endif /* ! TC_M68K */ 244533965Sjdp} 244633965Sjdp 244733965Sjdp/* Handle the .print pseudo-op. */ 244833965Sjdp 244933965Sjdpvoid 245033965Sjdps_print (ignore) 245133965Sjdp int ignore; 245233965Sjdp{ 245333965Sjdp char *s; 245433965Sjdp int len; 245533965Sjdp 245633965Sjdp s = demand_copy_C_string (&len); 245733965Sjdp printf ("%s\n", s); 245833965Sjdp demand_empty_rest_of_line (); 245933965Sjdp} 246033965Sjdp 246133965Sjdp/* Handle the .purgem pseudo-op. */ 246233965Sjdp 246333965Sjdpvoid 246433965Sjdps_purgem (ignore) 246533965Sjdp int ignore; 246633965Sjdp{ 246733965Sjdp if (is_it_end_of_statement ()) 246833965Sjdp { 246933965Sjdp demand_empty_rest_of_line (); 247033965Sjdp return; 247133965Sjdp } 247233965Sjdp 247333965Sjdp do 247433965Sjdp { 247533965Sjdp char *name; 247633965Sjdp char c; 247733965Sjdp 247833965Sjdp SKIP_WHITESPACE (); 247933965Sjdp name = input_line_pointer; 248033965Sjdp c = get_symbol_end (); 248133965Sjdp delete_macro (name); 248233965Sjdp *input_line_pointer = c; 248333965Sjdp SKIP_WHITESPACE (); 248433965Sjdp } 248533965Sjdp while (*input_line_pointer++ == ','); 248633965Sjdp 248733965Sjdp --input_line_pointer; 248833965Sjdp demand_empty_rest_of_line (); 248933965Sjdp} 249033965Sjdp 249133965Sjdp/* Handle the .rept pseudo-op. */ 249233965Sjdp 249333965Sjdpvoid 249433965Sjdps_rept (ignore) 249533965Sjdp int ignore; 249633965Sjdp{ 249733965Sjdp int count; 249833965Sjdp sb one; 249933965Sjdp sb many; 250033965Sjdp 250133965Sjdp count = get_absolute_expression (); 250233965Sjdp 250333965Sjdp sb_new (&one); 250433965Sjdp if (! buffer_and_nest ("REPT", "ENDR", &one, get_line_sb)) 250533965Sjdp { 250633965Sjdp as_bad ("rept without endr"); 250733965Sjdp return; 250833965Sjdp } 250933965Sjdp 251033965Sjdp sb_new (&many); 251133965Sjdp while (count-- > 0) 251233965Sjdp sb_add_sb (&many, &one); 251333965Sjdp 251433965Sjdp sb_kill (&one); 251533965Sjdp 251633965Sjdp input_scrub_include_sb (&many, input_line_pointer); 251733965Sjdp sb_kill (&many); 251833965Sjdp buffer_limit = input_scrub_next_buffer (&input_line_pointer); 251933965Sjdp} 252033965Sjdp 252133965Sjdp/* Handle the .equ, .equiv and .set directives. If EQUIV is 1, then 252233965Sjdp this is .equiv, and it is an error if the symbol is already 252333965Sjdp defined. */ 252433965Sjdp 252533965Sjdpvoid 252633965Sjdps_set (equiv) 252733965Sjdp int equiv; 252833965Sjdp{ 252933965Sjdp register char *name; 253033965Sjdp register char delim; 253133965Sjdp register char *end_name; 253233965Sjdp register symbolS *symbolP; 253333965Sjdp 253433965Sjdp /* 253533965Sjdp * Especial apologies for the random logic: 253633965Sjdp * this just grew, and could be parsed much more simply! 253733965Sjdp * Dean in haste. 253833965Sjdp */ 253933965Sjdp name = input_line_pointer; 254033965Sjdp delim = get_symbol_end (); 254133965Sjdp end_name = input_line_pointer; 254233965Sjdp *end_name = delim; 254333965Sjdp SKIP_WHITESPACE (); 254433965Sjdp 254533965Sjdp if (*input_line_pointer != ',') 254633965Sjdp { 254733965Sjdp *end_name = 0; 254833965Sjdp as_bad ("Expected comma after name \"%s\"", name); 254933965Sjdp *end_name = delim; 255033965Sjdp ignore_rest_of_line (); 255133965Sjdp return; 255233965Sjdp } 255333965Sjdp 255433965Sjdp input_line_pointer++; 255533965Sjdp *end_name = 0; 255633965Sjdp 255733965Sjdp if (name[0] == '.' && name[1] == '\0') 255833965Sjdp { 255933965Sjdp /* Turn '. = mumble' into a .org mumble */ 256033965Sjdp register segT segment; 256133965Sjdp expressionS exp; 256233965Sjdp 256333965Sjdp segment = get_known_segmented_expression (&exp); 256433965Sjdp 256533965Sjdp if (!need_pass_2) 256633965Sjdp do_org (segment, &exp, 0); 256733965Sjdp 256833965Sjdp *end_name = delim; 256933965Sjdp return; 257033965Sjdp } 257133965Sjdp 257233965Sjdp if ((symbolP = symbol_find (name)) == NULL 257333965Sjdp && (symbolP = md_undefined_symbol (name)) == NULL) 257433965Sjdp { 257533965Sjdp symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag); 257633965Sjdp#ifdef OBJ_COFF 257733965Sjdp /* "set" symbols are local unless otherwise specified. */ 257833965Sjdp SF_SET_LOCAL (symbolP); 257933965Sjdp#endif /* OBJ_COFF */ 258033965Sjdp 258133965Sjdp } /* make a new symbol */ 258233965Sjdp 258333965Sjdp symbol_table_insert (symbolP); 258433965Sjdp 258533965Sjdp *end_name = delim; 258633965Sjdp 258733965Sjdp if (equiv 258833965Sjdp && S_IS_DEFINED (symbolP) 258933965Sjdp && S_GET_SEGMENT (symbolP) != reg_section) 259033965Sjdp as_bad ("symbol `%s' already defined", S_GET_NAME (symbolP)); 259133965Sjdp 259233965Sjdp pseudo_set (symbolP); 259333965Sjdp demand_empty_rest_of_line (); 259433965Sjdp} /* s_set() */ 259533965Sjdp 259633965Sjdpvoid 259733965Sjdps_space (mult) 259833965Sjdp int mult; 259933965Sjdp{ 260033965Sjdp expressionS exp; 260133965Sjdp expressionS val; 260233965Sjdp char *p = 0; 260333965Sjdp char *stop = NULL; 260433965Sjdp char stopc; 260533965Sjdp int bytes; 260633965Sjdp 260733965Sjdp#ifdef md_flush_pending_output 260833965Sjdp md_flush_pending_output (); 260933965Sjdp#endif 261033965Sjdp 261133965Sjdp if (flag_mri) 261233965Sjdp stop = mri_comment_field (&stopc); 261333965Sjdp 261433965Sjdp /* In m68k MRI mode, we need to align to a word boundary, unless 261533965Sjdp this is ds.b. */ 261633965Sjdp if (flag_m68k_mri && mult > 1) 261733965Sjdp { 261833965Sjdp if (now_seg == absolute_section) 261933965Sjdp { 262033965Sjdp abs_section_offset += abs_section_offset & 1; 262133965Sjdp if (line_label != NULL) 262233965Sjdp S_SET_VALUE (line_label, abs_section_offset); 262333965Sjdp } 262433965Sjdp else if (mri_common_symbol != NULL) 262533965Sjdp { 262633965Sjdp valueT val; 262733965Sjdp 262833965Sjdp val = S_GET_VALUE (mri_common_symbol); 262933965Sjdp if ((val & 1) != 0) 263033965Sjdp { 263133965Sjdp S_SET_VALUE (mri_common_symbol, val + 1); 263233965Sjdp if (line_label != NULL) 263333965Sjdp { 263433965Sjdp know (line_label->sy_value.X_op == O_symbol); 263533965Sjdp know (line_label->sy_value.X_add_symbol == mri_common_symbol); 263633965Sjdp line_label->sy_value.X_add_number += 1; 263733965Sjdp } 263833965Sjdp } 263933965Sjdp } 264033965Sjdp else 264133965Sjdp { 264233965Sjdp do_align (1, (char *) NULL, 0, 0); 264333965Sjdp if (line_label != NULL) 264433965Sjdp { 264533965Sjdp line_label->sy_frag = frag_now; 264633965Sjdp S_SET_VALUE (line_label, frag_now_fix ()); 264733965Sjdp } 264833965Sjdp } 264933965Sjdp } 265033965Sjdp 265133965Sjdp bytes = mult; 265233965Sjdp 265333965Sjdp expression (&exp); 265433965Sjdp 265533965Sjdp SKIP_WHITESPACE (); 265633965Sjdp if (*input_line_pointer == ',') 265733965Sjdp { 265833965Sjdp ++input_line_pointer; 265933965Sjdp expression (&val); 266033965Sjdp } 266133965Sjdp else 266233965Sjdp { 266333965Sjdp val.X_op = O_constant; 266433965Sjdp val.X_add_number = 0; 266533965Sjdp } 266633965Sjdp 266733965Sjdp if (val.X_op != O_constant 266833965Sjdp || val.X_add_number < - 0x80 266933965Sjdp || val.X_add_number > 0xff 267033965Sjdp || (mult != 0 && mult != 1 && val.X_add_number != 0)) 267133965Sjdp { 267233965Sjdp if (exp.X_op != O_constant) 267333965Sjdp as_bad ("Unsupported variable size or fill value"); 267433965Sjdp else 267533965Sjdp { 267633965Sjdp offsetT i; 267733965Sjdp 267833965Sjdp if (mult == 0) 267933965Sjdp mult = 1; 268033965Sjdp bytes = mult * exp.X_add_number; 268133965Sjdp for (i = 0; i < exp.X_add_number; i++) 268233965Sjdp emit_expr (&val, mult); 268333965Sjdp } 268433965Sjdp } 268533965Sjdp else 268633965Sjdp { 268733965Sjdp if (exp.X_op == O_constant) 268833965Sjdp { 268933965Sjdp long repeat; 269033965Sjdp 269133965Sjdp repeat = exp.X_add_number; 269233965Sjdp if (mult) 269333965Sjdp repeat *= mult; 269433965Sjdp bytes = repeat; 269533965Sjdp if (repeat <= 0) 269633965Sjdp { 269733965Sjdp if (! flag_mri || repeat < 0) 269833965Sjdp as_warn (".space repeat count is %s, ignored", 269933965Sjdp repeat ? "negative" : "zero"); 270033965Sjdp goto getout; 270133965Sjdp } 270233965Sjdp 270333965Sjdp /* If we are in the absolute section, just bump the offset. */ 270433965Sjdp if (now_seg == absolute_section) 270533965Sjdp { 270633965Sjdp abs_section_offset += repeat; 270733965Sjdp goto getout; 270833965Sjdp } 270933965Sjdp 271033965Sjdp /* If we are secretly in an MRI common section, then 271133965Sjdp creating space just increases the size of the common 271233965Sjdp symbol. */ 271333965Sjdp if (mri_common_symbol != NULL) 271433965Sjdp { 271533965Sjdp S_SET_VALUE (mri_common_symbol, 271633965Sjdp S_GET_VALUE (mri_common_symbol) + repeat); 271733965Sjdp goto getout; 271833965Sjdp } 271933965Sjdp 272033965Sjdp if (!need_pass_2) 272133965Sjdp p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0, 272233965Sjdp (offsetT) repeat, (char *) 0); 272333965Sjdp } 272433965Sjdp else 272533965Sjdp { 272633965Sjdp if (now_seg == absolute_section) 272733965Sjdp { 272833965Sjdp as_bad ("space allocation too complex in absolute section"); 272933965Sjdp subseg_set (text_section, 0); 273033965Sjdp } 273133965Sjdp if (mri_common_symbol != NULL) 273233965Sjdp { 273333965Sjdp as_bad ("space allocation too complex in common section"); 273433965Sjdp mri_common_symbol = NULL; 273533965Sjdp } 273633965Sjdp if (!need_pass_2) 273733965Sjdp p = frag_var (rs_space, 1, 1, (relax_substateT) 0, 273833965Sjdp make_expr_symbol (&exp), (offsetT) 0, (char *) 0); 273933965Sjdp } 274033965Sjdp 274133965Sjdp if (p) 274233965Sjdp *p = val.X_add_number; 274333965Sjdp } 274433965Sjdp 274533965Sjdp getout: 274633965Sjdp 274733965Sjdp /* In MRI mode, after an odd number of bytes, we must align to an 274833965Sjdp even word boundary, unless the next instruction is a dc.b, ds.b 274933965Sjdp or dcb.b. */ 275033965Sjdp if (flag_mri && (bytes & 1) != 0) 275133965Sjdp mri_pending_align = 1; 275233965Sjdp 275333965Sjdp if (flag_mri) 275433965Sjdp mri_comment_end (stop, stopc); 275533965Sjdp 275633965Sjdp demand_empty_rest_of_line (); 275733965Sjdp} 275833965Sjdp 275933965Sjdp/* This is like s_space, but the value is a floating point number with 276033965Sjdp the given precision. This is for the MRI dcb.s pseudo-op and 276133965Sjdp friends. */ 276233965Sjdp 276333965Sjdpvoid 276433965Sjdps_float_space (float_type) 276533965Sjdp int float_type; 276633965Sjdp{ 276733965Sjdp offsetT count; 276833965Sjdp int flen; 276933965Sjdp char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT]; 277033965Sjdp char *stop = NULL; 277133965Sjdp char stopc; 277233965Sjdp 277333965Sjdp if (flag_mri) 277433965Sjdp stop = mri_comment_field (&stopc); 277533965Sjdp 277633965Sjdp count = get_absolute_expression (); 277733965Sjdp 277833965Sjdp SKIP_WHITESPACE (); 277933965Sjdp if (*input_line_pointer != ',') 278033965Sjdp { 278133965Sjdp as_bad ("missing value"); 278233965Sjdp if (flag_mri) 278333965Sjdp mri_comment_end (stop, stopc); 278433965Sjdp ignore_rest_of_line (); 278533965Sjdp return; 278633965Sjdp } 278733965Sjdp 278833965Sjdp ++input_line_pointer; 278933965Sjdp 279033965Sjdp SKIP_WHITESPACE (); 279133965Sjdp 279233965Sjdp /* Skip any 0{letter} that may be present. Don't even check if the 279333965Sjdp * letter is legal. */ 279433965Sjdp if (input_line_pointer[0] == '0' && isalpha (input_line_pointer[1])) 279533965Sjdp input_line_pointer += 2; 279633965Sjdp 279733965Sjdp /* Accept :xxxx, where the x's are hex digits, for a floating point 279833965Sjdp with the exact digits specified. */ 279933965Sjdp if (input_line_pointer[0] == ':') 280033965Sjdp { 280133965Sjdp flen = hex_float (float_type, temp); 280233965Sjdp if (flen < 0) 280333965Sjdp { 280433965Sjdp if (flag_mri) 280533965Sjdp mri_comment_end (stop, stopc); 280633965Sjdp ignore_rest_of_line (); 280733965Sjdp return; 280833965Sjdp } 280933965Sjdp } 281033965Sjdp else 281133965Sjdp { 281233965Sjdp char *err; 281333965Sjdp 281433965Sjdp err = md_atof (float_type, temp, &flen); 281533965Sjdp know (flen <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT); 281633965Sjdp know (flen > 0); 281733965Sjdp if (err) 281833965Sjdp { 281933965Sjdp as_bad ("Bad floating literal: %s", err); 282033965Sjdp if (flag_mri) 282133965Sjdp mri_comment_end (stop, stopc); 282233965Sjdp ignore_rest_of_line (); 282333965Sjdp return; 282433965Sjdp } 282533965Sjdp } 282633965Sjdp 282733965Sjdp while (--count >= 0) 282833965Sjdp { 282933965Sjdp char *p; 283033965Sjdp 283133965Sjdp p = frag_more (flen); 283233965Sjdp memcpy (p, temp, (unsigned int) flen); 283333965Sjdp } 283433965Sjdp 283533965Sjdp if (flag_mri) 283633965Sjdp mri_comment_end (stop, stopc); 283733965Sjdp 283833965Sjdp demand_empty_rest_of_line (); 283933965Sjdp} 284033965Sjdp 284133965Sjdp/* Handle the .struct pseudo-op, as found in MIPS assemblers. */ 284233965Sjdp 284333965Sjdpvoid 284433965Sjdps_struct (ignore) 284533965Sjdp int ignore; 284633965Sjdp{ 284733965Sjdp char *stop = NULL; 284833965Sjdp char stopc; 284933965Sjdp 285033965Sjdp if (flag_mri) 285133965Sjdp stop = mri_comment_field (&stopc); 285233965Sjdp abs_section_offset = get_absolute_expression (); 285333965Sjdp subseg_set (absolute_section, 0); 285433965Sjdp if (flag_mri) 285533965Sjdp mri_comment_end (stop, stopc); 285633965Sjdp demand_empty_rest_of_line (); 285733965Sjdp} 285833965Sjdp 285933965Sjdpvoid 286033965Sjdps_text (ignore) 286133965Sjdp int ignore; 286233965Sjdp{ 286333965Sjdp register int temp; 286433965Sjdp 286533965Sjdp temp = get_absolute_expression (); 286633965Sjdp subseg_set (text_section, (subsegT) temp); 286733965Sjdp demand_empty_rest_of_line (); 286833965Sjdp#ifdef OBJ_VMS 286933965Sjdp const_flag &= ~IN_DEFAULT_SECTION; 287033965Sjdp#endif 287133965Sjdp} /* s_text() */ 287233965Sjdp 287333965Sjdp 287433965Sjdpvoid 287533965Sjdpdemand_empty_rest_of_line () 287633965Sjdp{ 287733965Sjdp SKIP_WHITESPACE (); 287833965Sjdp if (is_end_of_line[(unsigned char) *input_line_pointer]) 287933965Sjdp { 288033965Sjdp input_line_pointer++; 288133965Sjdp } 288233965Sjdp else 288333965Sjdp { 288433965Sjdp ignore_rest_of_line (); 288533965Sjdp } 288633965Sjdp /* Return having already swallowed end-of-line. */ 288733965Sjdp} /* Return pointing just after end-of-line. */ 288833965Sjdp 288933965Sjdpvoid 289033965Sjdpignore_rest_of_line () /* For suspect lines: gives warning. */ 289133965Sjdp{ 289233965Sjdp if (!is_end_of_line[(unsigned char) *input_line_pointer]) 289333965Sjdp { 289433965Sjdp if (isprint (*input_line_pointer)) 289533965Sjdp as_bad ("Rest of line ignored. First ignored character is `%c'.", 289633965Sjdp *input_line_pointer); 289733965Sjdp else 289833965Sjdp as_bad ("Rest of line ignored. First ignored character valued 0x%x.", 289933965Sjdp *input_line_pointer); 290033965Sjdp while (input_line_pointer < buffer_limit 290133965Sjdp && !is_end_of_line[(unsigned char) *input_line_pointer]) 290233965Sjdp { 290333965Sjdp input_line_pointer++; 290433965Sjdp } 290533965Sjdp } 290633965Sjdp input_line_pointer++; /* Return pointing just after end-of-line. */ 290733965Sjdp know (is_end_of_line[(unsigned char) input_line_pointer[-1]]); 290833965Sjdp} 290933965Sjdp 291033965Sjdp/* 291133965Sjdp * pseudo_set() 291233965Sjdp * 291333965Sjdp * In: Pointer to a symbol. 291433965Sjdp * Input_line_pointer->expression. 291533965Sjdp * 291633965Sjdp * Out: Input_line_pointer->just after any whitespace after expression. 291733965Sjdp * Tried to set symbol to value of expression. 291833965Sjdp * Will change symbols type, value, and frag; 291933965Sjdp */ 292033965Sjdpvoid 292133965Sjdppseudo_set (symbolP) 292233965Sjdp symbolS *symbolP; 292333965Sjdp{ 292433965Sjdp expressionS exp; 292533965Sjdp#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER) 292633965Sjdp int ext; 292733965Sjdp#endif /* OBJ_AOUT or OBJ_BOUT */ 292833965Sjdp 292933965Sjdp know (symbolP); /* NULL pointer is logic error. */ 293033965Sjdp#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER) 293133965Sjdp ext = S_IS_EXTERNAL (symbolP); 293233965Sjdp#endif /* OBJ_AOUT or OBJ_BOUT */ 293333965Sjdp 293433965Sjdp (void) expression (&exp); 293533965Sjdp 293633965Sjdp if (exp.X_op == O_illegal) 293733965Sjdp as_bad ("illegal expression; zero assumed"); 293833965Sjdp else if (exp.X_op == O_absent) 293933965Sjdp as_bad ("missing expression; zero assumed"); 294033965Sjdp else if (exp.X_op == O_big) 294133965Sjdp as_bad ("%s number invalid; zero assumed", 294233965Sjdp exp.X_add_number > 0 ? "bignum" : "floating point"); 294333965Sjdp else if (exp.X_op == O_subtract 294433965Sjdp && (S_GET_SEGMENT (exp.X_add_symbol) 294533965Sjdp == S_GET_SEGMENT (exp.X_op_symbol)) 294633965Sjdp && SEG_NORMAL (S_GET_SEGMENT (exp.X_add_symbol)) 294733965Sjdp && exp.X_add_symbol->sy_frag == exp.X_op_symbol->sy_frag) 294833965Sjdp { 294933965Sjdp exp.X_op = O_constant; 295033965Sjdp exp.X_add_number = (S_GET_VALUE (exp.X_add_symbol) 295133965Sjdp - S_GET_VALUE (exp.X_op_symbol)); 295233965Sjdp } 295333965Sjdp 295433965Sjdp switch (exp.X_op) 295533965Sjdp { 295633965Sjdp case O_illegal: 295733965Sjdp case O_absent: 295833965Sjdp case O_big: 295933965Sjdp exp.X_add_number = 0; 296033965Sjdp /* Fall through. */ 296133965Sjdp case O_constant: 296233965Sjdp S_SET_SEGMENT (symbolP, absolute_section); 296333965Sjdp#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER) 296433965Sjdp if (ext) 296533965Sjdp S_SET_EXTERNAL (symbolP); 296633965Sjdp else 296733965Sjdp S_CLEAR_EXTERNAL (symbolP); 296833965Sjdp#endif /* OBJ_AOUT or OBJ_BOUT */ 296933965Sjdp S_SET_VALUE (symbolP, (valueT) exp.X_add_number); 297033965Sjdp symbolP->sy_frag = &zero_address_frag; 297133965Sjdp break; 297233965Sjdp 297333965Sjdp case O_register: 297433965Sjdp S_SET_SEGMENT (symbolP, reg_section); 297533965Sjdp S_SET_VALUE (symbolP, (valueT) exp.X_add_number); 297633965Sjdp symbolP->sy_frag = &zero_address_frag; 297733965Sjdp break; 297833965Sjdp 297933965Sjdp case O_symbol: 298033965Sjdp if (S_GET_SEGMENT (exp.X_add_symbol) == undefined_section 298133965Sjdp || exp.X_add_number != 0) 298233965Sjdp symbolP->sy_value = exp; 298333965Sjdp else 298433965Sjdp { 298533965Sjdp symbolS *s = exp.X_add_symbol; 298633965Sjdp 298733965Sjdp S_SET_SEGMENT (symbolP, S_GET_SEGMENT (s)); 298833965Sjdp#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER) 298933965Sjdp if (ext) 299033965Sjdp S_SET_EXTERNAL (symbolP); 299133965Sjdp else 299233965Sjdp S_CLEAR_EXTERNAL (symbolP); 299333965Sjdp#endif /* OBJ_AOUT or OBJ_BOUT */ 299433965Sjdp S_SET_VALUE (symbolP, 299533965Sjdp exp.X_add_number + S_GET_VALUE (s)); 299633965Sjdp symbolP->sy_frag = s->sy_frag; 299733965Sjdp copy_symbol_attributes (symbolP, s); 299833965Sjdp } 299933965Sjdp break; 300033965Sjdp 300133965Sjdp default: 300233965Sjdp /* The value is some complex expression. 300333965Sjdp FIXME: Should we set the segment to anything? */ 300433965Sjdp symbolP->sy_value = exp; 300533965Sjdp break; 300633965Sjdp } 300733965Sjdp} 300833965Sjdp 300933965Sjdp/* 301033965Sjdp * cons() 301133965Sjdp * 301233965Sjdp * CONStruct more frag of .bytes, or .words etc. 301333965Sjdp * Should need_pass_2 be 1 then emit no frag(s). 301433965Sjdp * This understands EXPRESSIONS. 301533965Sjdp * 301633965Sjdp * Bug (?) 301733965Sjdp * 301833965Sjdp * This has a split personality. We use expression() to read the 301933965Sjdp * value. We can detect if the value won't fit in a byte or word. 302033965Sjdp * But we can't detect if expression() discarded significant digits 302133965Sjdp * in the case of a long. Not worth the crocks required to fix it. 302233965Sjdp */ 302333965Sjdp 302433965Sjdp/* Select a parser for cons expressions. */ 302533965Sjdp 302633965Sjdp/* Some targets need to parse the expression in various fancy ways. 302733965Sjdp You can define TC_PARSE_CONS_EXPRESSION to do whatever you like 302833965Sjdp (for example, the HPPA does this). Otherwise, you can define 302933965Sjdp BITFIELD_CONS_EXPRESSIONS to permit bitfields to be specified, or 303033965Sjdp REPEAT_CONS_EXPRESSIONS to permit repeat counts. If none of these 303133965Sjdp are defined, which is the normal case, then only simple expressions 303233965Sjdp are permitted. */ 303333965Sjdp 303433965Sjdpstatic void 303533965Sjdpparse_mri_cons PARAMS ((expressionS *exp, unsigned int nbytes)); 303633965Sjdp 303733965Sjdp#ifndef TC_PARSE_CONS_EXPRESSION 303833965Sjdp#ifdef BITFIELD_CONS_EXPRESSIONS 303933965Sjdp#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_bitfield_cons (EXP, NBYTES) 304033965Sjdpstatic void 304133965Sjdpparse_bitfield_cons PARAMS ((expressionS *exp, unsigned int nbytes)); 304233965Sjdp#endif 304333965Sjdp#ifdef REPEAT_CONS_EXPRESSIONS 304433965Sjdp#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_repeat_cons (EXP, NBYTES) 304533965Sjdpstatic void 304633965Sjdpparse_repeat_cons PARAMS ((expressionS *exp, unsigned int nbytes)); 304733965Sjdp#endif 304833965Sjdp 304933965Sjdp/* If we haven't gotten one yet, just call expression. */ 305033965Sjdp#ifndef TC_PARSE_CONS_EXPRESSION 305133965Sjdp#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) expression (EXP) 305233965Sjdp#endif 305333965Sjdp#endif 305433965Sjdp 305533965Sjdp/* worker to do .byte etc statements */ 305633965Sjdp/* clobbers input_line_pointer, checks */ 305733965Sjdp/* end-of-line. */ 305833965Sjdpstatic void 305933965Sjdpcons_worker (nbytes, rva) 306033965Sjdp register int nbytes; /* 1=.byte, 2=.word, 4=.long */ 306133965Sjdp int rva; 306233965Sjdp{ 306333965Sjdp int c; 306433965Sjdp expressionS exp; 306533965Sjdp char *stop = NULL; 306633965Sjdp char stopc; 306733965Sjdp 306833965Sjdp#ifdef md_flush_pending_output 306933965Sjdp md_flush_pending_output (); 307033965Sjdp#endif 307133965Sjdp 307233965Sjdp if (flag_mri) 307333965Sjdp stop = mri_comment_field (&stopc); 307433965Sjdp 307533965Sjdp if (is_it_end_of_statement ()) 307633965Sjdp { 307733965Sjdp if (flag_mri) 307833965Sjdp mri_comment_end (stop, stopc); 307933965Sjdp demand_empty_rest_of_line (); 308033965Sjdp return; 308133965Sjdp } 308233965Sjdp 308333965Sjdp#ifdef md_cons_align 308433965Sjdp md_cons_align (nbytes); 308533965Sjdp#endif 308633965Sjdp 308733965Sjdp c = 0; 308833965Sjdp do 308933965Sjdp { 309033965Sjdp if (flag_m68k_mri) 309133965Sjdp parse_mri_cons (&exp, (unsigned int) nbytes); 309233965Sjdp else 309333965Sjdp TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes); 309433965Sjdp 309533965Sjdp if (rva) 309633965Sjdp { 309733965Sjdp if (exp.X_op == O_symbol) 309833965Sjdp exp.X_op = O_symbol_rva; 309933965Sjdp else 310033965Sjdp as_fatal ("rva without symbol"); 310133965Sjdp } 310233965Sjdp emit_expr (&exp, (unsigned int) nbytes); 310333965Sjdp ++c; 310433965Sjdp } 310533965Sjdp while (*input_line_pointer++ == ','); 310633965Sjdp 310733965Sjdp /* In MRI mode, after an odd number of bytes, we must align to an 310833965Sjdp even word boundary, unless the next instruction is a dc.b, ds.b 310933965Sjdp or dcb.b. */ 311033965Sjdp if (flag_mri && nbytes == 1 && (c & 1) != 0) 311133965Sjdp mri_pending_align = 1; 311233965Sjdp 311333965Sjdp input_line_pointer--; /* Put terminator back into stream. */ 311433965Sjdp 311533965Sjdp if (flag_mri) 311633965Sjdp mri_comment_end (stop, stopc); 311733965Sjdp 311833965Sjdp demand_empty_rest_of_line (); 311933965Sjdp} 312033965Sjdp 312133965Sjdp 312233965Sjdpvoid 312333965Sjdpcons (size) 312433965Sjdp int size; 312533965Sjdp{ 312633965Sjdp cons_worker (size, 0); 312733965Sjdp} 312833965Sjdp 312933965Sjdpvoid 313033965Sjdps_rva (size) 313133965Sjdp int size; 313233965Sjdp{ 313333965Sjdp cons_worker (size, 1); 313433965Sjdp} 313533965Sjdp 313633965Sjdp 313733965Sjdp/* Put the contents of expression EXP into the object file using 313833965Sjdp NBYTES bytes. If need_pass_2 is 1, this does nothing. */ 313933965Sjdp 314033965Sjdpvoid 314133965Sjdpemit_expr (exp, nbytes) 314233965Sjdp expressionS *exp; 314333965Sjdp unsigned int nbytes; 314433965Sjdp{ 314533965Sjdp operatorT op; 314633965Sjdp register char *p; 314733965Sjdp valueT extra_digit = 0; 314833965Sjdp 314933965Sjdp /* Don't do anything if we are going to make another pass. */ 315033965Sjdp if (need_pass_2) 315133965Sjdp return; 315233965Sjdp 315333965Sjdp op = exp->X_op; 315433965Sjdp 315533965Sjdp /* Allow `.word 0' in the absolute section. */ 315633965Sjdp if (now_seg == absolute_section) 315733965Sjdp { 315833965Sjdp if (op != O_constant || exp->X_add_number != 0) 315933965Sjdp as_bad ("attempt to store value in absolute section"); 316033965Sjdp abs_section_offset += nbytes; 316133965Sjdp return; 316233965Sjdp } 316333965Sjdp 316433965Sjdp /* Handle a negative bignum. */ 316533965Sjdp if (op == O_uminus 316633965Sjdp && exp->X_add_number == 0 316733965Sjdp && exp->X_add_symbol->sy_value.X_op == O_big 316833965Sjdp && exp->X_add_symbol->sy_value.X_add_number > 0) 316933965Sjdp { 317033965Sjdp int i; 317133965Sjdp unsigned long carry; 317233965Sjdp 317333965Sjdp exp = &exp->X_add_symbol->sy_value; 317433965Sjdp 317533965Sjdp /* Negate the bignum: one's complement each digit and add 1. */ 317633965Sjdp carry = 1; 317733965Sjdp for (i = 0; i < exp->X_add_number; i++) 317833965Sjdp { 317933965Sjdp unsigned long next; 318033965Sjdp 318133965Sjdp next = (((~ (generic_bignum[i] & LITTLENUM_MASK)) 318233965Sjdp & LITTLENUM_MASK) 318333965Sjdp + carry); 318433965Sjdp generic_bignum[i] = next & LITTLENUM_MASK; 318533965Sjdp carry = next >> LITTLENUM_NUMBER_OF_BITS; 318633965Sjdp } 318733965Sjdp 318833965Sjdp /* We can ignore any carry out, because it will be handled by 318933965Sjdp extra_digit if it is needed. */ 319033965Sjdp 319133965Sjdp extra_digit = (valueT) -1; 319233965Sjdp op = O_big; 319333965Sjdp } 319433965Sjdp 319533965Sjdp if (op == O_absent || op == O_illegal) 319633965Sjdp { 319733965Sjdp as_warn ("zero assumed for missing expression"); 319833965Sjdp exp->X_add_number = 0; 319933965Sjdp op = O_constant; 320033965Sjdp } 320133965Sjdp else if (op == O_big && exp->X_add_number <= 0) 320233965Sjdp { 320333965Sjdp as_bad ("floating point number invalid; zero assumed"); 320433965Sjdp exp->X_add_number = 0; 320533965Sjdp op = O_constant; 320633965Sjdp } 320733965Sjdp else if (op == O_register) 320833965Sjdp { 320933965Sjdp as_warn ("register value used as expression"); 321033965Sjdp op = O_constant; 321133965Sjdp } 321233965Sjdp 321333965Sjdp p = frag_more ((int) nbytes); 321433965Sjdp 321533965Sjdp#ifndef WORKING_DOT_WORD 321633965Sjdp /* If we have the difference of two symbols in a word, save it on 321733965Sjdp the broken_words list. See the code in write.c. */ 321833965Sjdp if (op == O_subtract && nbytes == 2) 321933965Sjdp { 322033965Sjdp struct broken_word *x; 322133965Sjdp 322233965Sjdp x = (struct broken_word *) xmalloc (sizeof (struct broken_word)); 322333965Sjdp x->next_broken_word = broken_words; 322433965Sjdp broken_words = x; 322533965Sjdp x->frag = frag_now; 322633965Sjdp x->word_goes_here = p; 322733965Sjdp x->dispfrag = 0; 322833965Sjdp x->add = exp->X_add_symbol; 322933965Sjdp x->sub = exp->X_op_symbol; 323033965Sjdp x->addnum = exp->X_add_number; 323133965Sjdp x->added = 0; 323233965Sjdp new_broken_words++; 323333965Sjdp return; 323433965Sjdp } 323533965Sjdp#endif 323633965Sjdp 323733965Sjdp /* If we have an integer, but the number of bytes is too large to 323833965Sjdp pass to md_number_to_chars, handle it as a bignum. */ 323933965Sjdp if (op == O_constant && nbytes > sizeof (valueT)) 324033965Sjdp { 324133965Sjdp valueT val; 324233965Sjdp int gencnt; 324333965Sjdp 324433965Sjdp if (! exp->X_unsigned && exp->X_add_number < 0) 324533965Sjdp extra_digit = (valueT) -1; 324633965Sjdp val = (valueT) exp->X_add_number; 324733965Sjdp gencnt = 0; 324833965Sjdp do 324933965Sjdp { 325033965Sjdp generic_bignum[gencnt] = val & LITTLENUM_MASK; 325133965Sjdp val >>= LITTLENUM_NUMBER_OF_BITS; 325233965Sjdp ++gencnt; 325333965Sjdp } 325433965Sjdp while (val != 0); 325533965Sjdp op = exp->X_op = O_big; 325633965Sjdp exp->X_add_number = gencnt; 325733965Sjdp } 325833965Sjdp 325933965Sjdp if (op == O_constant) 326033965Sjdp { 326133965Sjdp register valueT get; 326233965Sjdp register valueT use; 326333965Sjdp register valueT mask; 326433965Sjdp valueT hibit; 326533965Sjdp register valueT unmask; 326633965Sjdp 326733965Sjdp /* JF << of >= number of bits in the object is undefined. In 326833965Sjdp particular SPARC (Sun 4) has problems */ 326933965Sjdp if (nbytes >= sizeof (valueT)) 327033965Sjdp { 327133965Sjdp mask = 0; 327233965Sjdp if (nbytes > sizeof (valueT)) 327333965Sjdp hibit = 0; 327433965Sjdp else 327533965Sjdp hibit = (valueT) 1 << (nbytes * BITS_PER_CHAR - 1); 327633965Sjdp } 327733965Sjdp else 327833965Sjdp { 327933965Sjdp /* Don't store these bits. */ 328033965Sjdp mask = ~(valueT) 0 << (BITS_PER_CHAR * nbytes); 328133965Sjdp hibit = (valueT) 1 << (nbytes * BITS_PER_CHAR - 1); 328233965Sjdp } 328333965Sjdp 328433965Sjdp unmask = ~mask; /* Do store these bits. */ 328533965Sjdp 328633965Sjdp#ifdef NEVER 328733965Sjdp "Do this mod if you want every overflow check to assume SIGNED 2's complement data."; 328833965Sjdp mask = ~(unmask >> 1); /* Includes sign bit now. */ 328933965Sjdp#endif 329033965Sjdp 329133965Sjdp get = exp->X_add_number; 329233965Sjdp use = get & unmask; 329333965Sjdp if ((get & mask) != 0 329433965Sjdp && ((get & mask) != mask 329533965Sjdp || (get & hibit) == 0)) 329633965Sjdp { /* Leading bits contain both 0s & 1s. */ 329733965Sjdp as_warn ("Value 0x%lx truncated to 0x%lx.", 329833965Sjdp (unsigned long) get, (unsigned long) use); 329933965Sjdp } 330033965Sjdp /* put bytes in right order. */ 330133965Sjdp md_number_to_chars (p, use, (int) nbytes); 330233965Sjdp } 330333965Sjdp else if (op == O_big) 330433965Sjdp { 330533965Sjdp int size; 330633965Sjdp LITTLENUM_TYPE *nums; 330733965Sjdp 330833965Sjdp know (nbytes % CHARS_PER_LITTLENUM == 0); 330933965Sjdp 331033965Sjdp size = exp->X_add_number * CHARS_PER_LITTLENUM; 331133965Sjdp if (nbytes < size) 331233965Sjdp { 331333965Sjdp as_warn ("Bignum truncated to %d bytes", nbytes); 331433965Sjdp size = nbytes; 331533965Sjdp } 331633965Sjdp 331733965Sjdp if (target_big_endian) 331833965Sjdp { 331933965Sjdp while (nbytes > size) 332033965Sjdp { 332133965Sjdp md_number_to_chars (p, extra_digit, CHARS_PER_LITTLENUM); 332233965Sjdp nbytes -= CHARS_PER_LITTLENUM; 332333965Sjdp p += CHARS_PER_LITTLENUM; 332433965Sjdp } 332533965Sjdp 332633965Sjdp nums = generic_bignum + size / CHARS_PER_LITTLENUM; 332733965Sjdp while (size > 0) 332833965Sjdp { 332933965Sjdp --nums; 333033965Sjdp md_number_to_chars (p, (valueT) *nums, CHARS_PER_LITTLENUM); 333133965Sjdp size -= CHARS_PER_LITTLENUM; 333233965Sjdp p += CHARS_PER_LITTLENUM; 333333965Sjdp } 333433965Sjdp } 333533965Sjdp else 333633965Sjdp { 333733965Sjdp nums = generic_bignum; 333833965Sjdp while (size > 0) 333933965Sjdp { 334033965Sjdp md_number_to_chars (p, (valueT) *nums, CHARS_PER_LITTLENUM); 334133965Sjdp ++nums; 334233965Sjdp size -= CHARS_PER_LITTLENUM; 334333965Sjdp p += CHARS_PER_LITTLENUM; 334433965Sjdp nbytes -= CHARS_PER_LITTLENUM; 334533965Sjdp } 334633965Sjdp 334733965Sjdp while (nbytes > 0) 334833965Sjdp { 334933965Sjdp md_number_to_chars (p, extra_digit, CHARS_PER_LITTLENUM); 335033965Sjdp nbytes -= CHARS_PER_LITTLENUM; 335133965Sjdp p += CHARS_PER_LITTLENUM; 335233965Sjdp } 335333965Sjdp } 335433965Sjdp } 335533965Sjdp else 335633965Sjdp { 335733965Sjdp memset (p, 0, nbytes); 335833965Sjdp 335933965Sjdp /* Now we need to generate a fixS to record the symbol value. 336033965Sjdp This is easy for BFD. For other targets it can be more 336133965Sjdp complex. For very complex cases (currently, the HPPA and 336233965Sjdp NS32K), you can define TC_CONS_FIX_NEW to do whatever you 336333965Sjdp want. For simpler cases, you can define TC_CONS_RELOC to be 336433965Sjdp the name of the reloc code that should be stored in the fixS. 336533965Sjdp If neither is defined, the code uses NO_RELOC if it is 336633965Sjdp defined, and otherwise uses 0. */ 336733965Sjdp 336833965Sjdp#ifdef BFD_ASSEMBLER 336933965Sjdp#ifdef TC_CONS_FIX_NEW 337033965Sjdp TC_CONS_FIX_NEW (frag_now, p - frag_now->fr_literal, nbytes, exp); 337133965Sjdp#else 337233965Sjdp { 337333965Sjdp bfd_reloc_code_real_type r; 337433965Sjdp 337533965Sjdp switch (nbytes) 337633965Sjdp { 337733965Sjdp case 1: 337833965Sjdp r = BFD_RELOC_8; 337933965Sjdp break; 338033965Sjdp case 2: 338133965Sjdp r = BFD_RELOC_16; 338233965Sjdp break; 338333965Sjdp case 4: 338433965Sjdp r = BFD_RELOC_32; 338533965Sjdp break; 338633965Sjdp case 8: 338733965Sjdp r = BFD_RELOC_64; 338833965Sjdp break; 338933965Sjdp default: 339033965Sjdp as_bad ("unsupported BFD relocation size %u", nbytes); 339133965Sjdp r = BFD_RELOC_32; 339233965Sjdp break; 339333965Sjdp } 339433965Sjdp fix_new_exp (frag_now, p - frag_now->fr_literal, (int) nbytes, exp, 339533965Sjdp 0, r); 339633965Sjdp } 339733965Sjdp#endif 339833965Sjdp#else 339933965Sjdp#ifdef TC_CONS_FIX_NEW 340033965Sjdp TC_CONS_FIX_NEW (frag_now, p - frag_now->fr_literal, nbytes, exp); 340133965Sjdp#else 340233965Sjdp /* Figure out which reloc number to use. Use TC_CONS_RELOC if 340333965Sjdp it is defined, otherwise use NO_RELOC if it is defined, 340433965Sjdp otherwise use 0. */ 340533965Sjdp#ifndef TC_CONS_RELOC 340633965Sjdp#ifdef NO_RELOC 340733965Sjdp#define TC_CONS_RELOC NO_RELOC 340833965Sjdp#else 340933965Sjdp#define TC_CONS_RELOC 0 341033965Sjdp#endif 341133965Sjdp#endif 341233965Sjdp fix_new_exp (frag_now, p - frag_now->fr_literal, (int) nbytes, exp, 0, 341333965Sjdp TC_CONS_RELOC); 341433965Sjdp#endif /* TC_CONS_FIX_NEW */ 341533965Sjdp#endif /* BFD_ASSEMBLER */ 341633965Sjdp } 341733965Sjdp} 341833965Sjdp 341933965Sjdp#ifdef BITFIELD_CONS_EXPRESSIONS 342033965Sjdp 342133965Sjdp/* i960 assemblers, (eg, asm960), allow bitfields after ".byte" as 342233965Sjdp w:x,y:z, where w and y are bitwidths and x and y are values. They 342333965Sjdp then pack them all together. We do a little better in that we allow 342433965Sjdp them in words, longs, etc. and we'll pack them in target byte order 342533965Sjdp for you. 342633965Sjdp 342733965Sjdp The rules are: pack least significat bit first, if a field doesn't 342833965Sjdp entirely fit, put it in the next unit. Overflowing the bitfield is 342933965Sjdp explicitly *not* even a warning. The bitwidth should be considered 343033965Sjdp a "mask". 343133965Sjdp 343233965Sjdp To use this function the tc-XXX.h file should define 343333965Sjdp BITFIELD_CONS_EXPRESSIONS. */ 343433965Sjdp 343533965Sjdpstatic void 343633965Sjdpparse_bitfield_cons (exp, nbytes) 343733965Sjdp expressionS *exp; 343833965Sjdp unsigned int nbytes; 343933965Sjdp{ 344033965Sjdp unsigned int bits_available = BITS_PER_CHAR * nbytes; 344133965Sjdp char *hold = input_line_pointer; 344233965Sjdp 344333965Sjdp (void) expression (exp); 344433965Sjdp 344533965Sjdp if (*input_line_pointer == ':') 344633965Sjdp { /* bitfields */ 344733965Sjdp long value = 0; 344833965Sjdp 344933965Sjdp for (;;) 345033965Sjdp { 345133965Sjdp unsigned long width; 345233965Sjdp 345333965Sjdp if (*input_line_pointer != ':') 345433965Sjdp { 345533965Sjdp input_line_pointer = hold; 345633965Sjdp break; 345733965Sjdp } /* next piece is not a bitfield */ 345833965Sjdp 345933965Sjdp /* In the general case, we can't allow 346033965Sjdp full expressions with symbol 346133965Sjdp differences and such. The relocation 346233965Sjdp entries for symbols not defined in this 346333965Sjdp assembly would require arbitrary field 346433965Sjdp widths, positions, and masks which most 346533965Sjdp of our current object formats don't 346633965Sjdp support. 346733965Sjdp 346833965Sjdp In the specific case where a symbol 346933965Sjdp *is* defined in this assembly, we 347033965Sjdp *could* build fixups and track it, but 347133965Sjdp this could lead to confusion for the 347233965Sjdp backends. I'm lazy. I'll take any 347333965Sjdp SEG_ABSOLUTE. I think that means that 347433965Sjdp you can use a previous .set or 347533965Sjdp .equ type symbol. xoxorich. */ 347633965Sjdp 347733965Sjdp if (exp->X_op == O_absent) 347833965Sjdp { 347933965Sjdp as_warn ("using a bit field width of zero"); 348033965Sjdp exp->X_add_number = 0; 348133965Sjdp exp->X_op = O_constant; 348233965Sjdp } /* implied zero width bitfield */ 348333965Sjdp 348433965Sjdp if (exp->X_op != O_constant) 348533965Sjdp { 348633965Sjdp *input_line_pointer = '\0'; 348733965Sjdp as_bad ("field width \"%s\" too complex for a bitfield", hold); 348833965Sjdp *input_line_pointer = ':'; 348933965Sjdp demand_empty_rest_of_line (); 349033965Sjdp return; 349133965Sjdp } /* too complex */ 349233965Sjdp 349333965Sjdp if ((width = exp->X_add_number) > (BITS_PER_CHAR * nbytes)) 349433965Sjdp { 349533965Sjdp as_warn ("field width %lu too big to fit in %d bytes: truncated to %d bits", 349633965Sjdp width, nbytes, (BITS_PER_CHAR * nbytes)); 349733965Sjdp width = BITS_PER_CHAR * nbytes; 349833965Sjdp } /* too big */ 349933965Sjdp 350033965Sjdp if (width > bits_available) 350133965Sjdp { 350233965Sjdp /* FIXME-SOMEDAY: backing up and reparsing is wasteful. */ 350333965Sjdp input_line_pointer = hold; 350433965Sjdp exp->X_add_number = value; 350533965Sjdp break; 350633965Sjdp } /* won't fit */ 350733965Sjdp 350833965Sjdp hold = ++input_line_pointer; /* skip ':' */ 350933965Sjdp 351033965Sjdp (void) expression (exp); 351133965Sjdp if (exp->X_op != O_constant) 351233965Sjdp { 351333965Sjdp char cache = *input_line_pointer; 351433965Sjdp 351533965Sjdp *input_line_pointer = '\0'; 351633965Sjdp as_bad ("field value \"%s\" too complex for a bitfield", hold); 351733965Sjdp *input_line_pointer = cache; 351833965Sjdp demand_empty_rest_of_line (); 351933965Sjdp return; 352033965Sjdp } /* too complex */ 352133965Sjdp 352233965Sjdp value |= ((~(-1 << width) & exp->X_add_number) 352333965Sjdp << ((BITS_PER_CHAR * nbytes) - bits_available)); 352433965Sjdp 352533965Sjdp if ((bits_available -= width) == 0 352633965Sjdp || is_it_end_of_statement () 352733965Sjdp || *input_line_pointer != ',') 352833965Sjdp { 352933965Sjdp break; 353033965Sjdp } /* all the bitfields we're gonna get */ 353133965Sjdp 353233965Sjdp hold = ++input_line_pointer; 353333965Sjdp (void) expression (exp); 353433965Sjdp } /* forever loop */ 353533965Sjdp 353633965Sjdp exp->X_add_number = value; 353733965Sjdp exp->X_op = O_constant; 353833965Sjdp exp->X_unsigned = 1; 353933965Sjdp } /* if looks like a bitfield */ 354033965Sjdp} /* parse_bitfield_cons() */ 354133965Sjdp 354233965Sjdp#endif /* BITFIELD_CONS_EXPRESSIONS */ 354333965Sjdp 354433965Sjdp/* Handle an MRI style string expression. */ 354533965Sjdp 354633965Sjdpstatic void 354733965Sjdpparse_mri_cons (exp, nbytes) 354833965Sjdp expressionS *exp; 354933965Sjdp unsigned int nbytes; 355033965Sjdp{ 355133965Sjdp if (*input_line_pointer != '\'' 355233965Sjdp && (input_line_pointer[1] != '\'' 355333965Sjdp || (*input_line_pointer != 'A' 355433965Sjdp && *input_line_pointer != 'E'))) 355533965Sjdp TC_PARSE_CONS_EXPRESSION (exp, nbytes); 355633965Sjdp else 355733965Sjdp { 355833965Sjdp int scan = 0; 355933965Sjdp unsigned int result = 0; 356033965Sjdp 356133965Sjdp /* An MRI style string. Cut into as many bytes as will fit into 356233965Sjdp a nbyte chunk, left justify if necessary, and separate with 356333965Sjdp commas so we can try again later. */ 356433965Sjdp if (*input_line_pointer == 'A') 356533965Sjdp ++input_line_pointer; 356633965Sjdp else if (*input_line_pointer == 'E') 356733965Sjdp { 356833965Sjdp as_bad ("EBCDIC constants are not supported"); 356933965Sjdp ++input_line_pointer; 357033965Sjdp } 357133965Sjdp 357233965Sjdp input_line_pointer++; 357333965Sjdp for (scan = 0; scan < nbytes; scan++) 357433965Sjdp { 357533965Sjdp if (*input_line_pointer == '\'') 357633965Sjdp { 357733965Sjdp if (input_line_pointer[1] == '\'') 357833965Sjdp { 357933965Sjdp input_line_pointer++; 358033965Sjdp } 358133965Sjdp else 358233965Sjdp break; 358333965Sjdp } 358433965Sjdp result = (result << 8) | (*input_line_pointer++); 358533965Sjdp } 358633965Sjdp 358733965Sjdp /* Left justify */ 358833965Sjdp while (scan < nbytes) 358933965Sjdp { 359033965Sjdp result <<= 8; 359133965Sjdp scan++; 359233965Sjdp } 359333965Sjdp /* Create correct expression */ 359433965Sjdp exp->X_op = O_constant; 359533965Sjdp exp->X_add_number = result; 359633965Sjdp /* Fake it so that we can read the next char too */ 359733965Sjdp if (input_line_pointer[0] != '\'' || 359833965Sjdp (input_line_pointer[0] == '\'' && input_line_pointer[1] == '\'')) 359933965Sjdp { 360033965Sjdp input_line_pointer -= 2; 360133965Sjdp input_line_pointer[0] = ','; 360233965Sjdp input_line_pointer[1] = '\''; 360333965Sjdp } 360433965Sjdp else 360533965Sjdp input_line_pointer++; 360633965Sjdp } 360733965Sjdp} 360833965Sjdp 360933965Sjdp#ifdef REPEAT_CONS_EXPRESSIONS 361033965Sjdp 361133965Sjdp/* Parse a repeat expression for cons. This is used by the MIPS 361233965Sjdp assembler. The format is NUMBER:COUNT; NUMBER appears in the 361333965Sjdp object file COUNT times. 361433965Sjdp 361533965Sjdp To use this for a target, define REPEAT_CONS_EXPRESSIONS. */ 361633965Sjdp 361733965Sjdpstatic void 361833965Sjdpparse_repeat_cons (exp, nbytes) 361933965Sjdp expressionS *exp; 362033965Sjdp unsigned int nbytes; 362133965Sjdp{ 362233965Sjdp expressionS count; 362333965Sjdp register int i; 362433965Sjdp 362533965Sjdp expression (exp); 362633965Sjdp 362733965Sjdp if (*input_line_pointer != ':') 362833965Sjdp { 362933965Sjdp /* No repeat count. */ 363033965Sjdp return; 363133965Sjdp } 363233965Sjdp 363333965Sjdp ++input_line_pointer; 363433965Sjdp expression (&count); 363533965Sjdp if (count.X_op != O_constant 363633965Sjdp || count.X_add_number <= 0) 363733965Sjdp { 363833965Sjdp as_warn ("Unresolvable or nonpositive repeat count; using 1"); 363933965Sjdp return; 364033965Sjdp } 364133965Sjdp 364233965Sjdp /* The cons function is going to output this expression once. So we 364333965Sjdp output it count - 1 times. */ 364433965Sjdp for (i = count.X_add_number - 1; i > 0; i--) 364533965Sjdp emit_expr (exp, nbytes); 364633965Sjdp} 364733965Sjdp 364833965Sjdp#endif /* REPEAT_CONS_EXPRESSIONS */ 364933965Sjdp 365033965Sjdp/* Parse a floating point number represented as a hex constant. This 365133965Sjdp permits users to specify the exact bits they want in the floating 365233965Sjdp point number. */ 365333965Sjdp 365433965Sjdpstatic int 365533965Sjdphex_float (float_type, bytes) 365633965Sjdp int float_type; 365733965Sjdp char *bytes; 365833965Sjdp{ 365933965Sjdp int length; 366033965Sjdp int i; 366133965Sjdp 366233965Sjdp switch (float_type) 366333965Sjdp { 366433965Sjdp case 'f': 366533965Sjdp case 'F': 366633965Sjdp case 's': 366733965Sjdp case 'S': 366833965Sjdp length = 4; 366933965Sjdp break; 367033965Sjdp 367133965Sjdp case 'd': 367233965Sjdp case 'D': 367333965Sjdp case 'r': 367433965Sjdp case 'R': 367533965Sjdp length = 8; 367633965Sjdp break; 367733965Sjdp 367833965Sjdp case 'x': 367933965Sjdp case 'X': 368033965Sjdp length = 12; 368133965Sjdp break; 368233965Sjdp 368333965Sjdp case 'p': 368433965Sjdp case 'P': 368533965Sjdp length = 12; 368633965Sjdp break; 368733965Sjdp 368833965Sjdp default: 368933965Sjdp as_bad ("Unknown floating type type '%c'", float_type); 369033965Sjdp return -1; 369133965Sjdp } 369233965Sjdp 369333965Sjdp /* It would be nice if we could go through expression to parse the 369433965Sjdp hex constant, but if we get a bignum it's a pain to sort it into 369533965Sjdp the buffer correctly. */ 369633965Sjdp i = 0; 369733965Sjdp while (hex_p (*input_line_pointer) || *input_line_pointer == '_') 369833965Sjdp { 369933965Sjdp int d; 370033965Sjdp 370133965Sjdp /* The MRI assembler accepts arbitrary underscores strewn about 370233965Sjdp through the hex constant, so we ignore them as well. */ 370333965Sjdp if (*input_line_pointer == '_') 370433965Sjdp { 370533965Sjdp ++input_line_pointer; 370633965Sjdp continue; 370733965Sjdp } 370833965Sjdp 370933965Sjdp if (i >= length) 371033965Sjdp { 371133965Sjdp as_warn ("Floating point constant too large"); 371233965Sjdp return -1; 371333965Sjdp } 371433965Sjdp d = hex_value (*input_line_pointer) << 4; 371533965Sjdp ++input_line_pointer; 371633965Sjdp while (*input_line_pointer == '_') 371733965Sjdp ++input_line_pointer; 371833965Sjdp if (hex_p (*input_line_pointer)) 371933965Sjdp { 372033965Sjdp d += hex_value (*input_line_pointer); 372133965Sjdp ++input_line_pointer; 372233965Sjdp } 372333965Sjdp if (target_big_endian) 372433965Sjdp bytes[i] = d; 372533965Sjdp else 372633965Sjdp bytes[length - i - 1] = d; 372733965Sjdp ++i; 372833965Sjdp } 372933965Sjdp 373033965Sjdp if (i < length) 373133965Sjdp { 373233965Sjdp if (target_big_endian) 373333965Sjdp memset (bytes + i, 0, length - i); 373433965Sjdp else 373533965Sjdp memset (bytes, 0, length - i); 373633965Sjdp } 373733965Sjdp 373833965Sjdp return length; 373933965Sjdp} 374033965Sjdp 374133965Sjdp/* 374233965Sjdp * float_cons() 374333965Sjdp * 374433965Sjdp * CONStruct some more frag chars of .floats .ffloats etc. 374533965Sjdp * Makes 0 or more new frags. 374633965Sjdp * If need_pass_2 == 1, no frags are emitted. 374733965Sjdp * This understands only floating literals, not expressions. Sorry. 374833965Sjdp * 374933965Sjdp * A floating constant is defined by atof_generic(), except it is preceded 375033965Sjdp * by 0d 0f 0g or 0h. After observing the STRANGE way my BSD AS does its 375133965Sjdp * reading, I decided to be incompatible. This always tries to give you 375233965Sjdp * rounded bits to the precision of the pseudo-op. Former AS did premature 375333965Sjdp * truncatation, restored noisy bits instead of trailing 0s AND gave you 375433965Sjdp * a choice of 2 flavours of noise according to which of 2 floating-point 375533965Sjdp * scanners you directed AS to use. 375633965Sjdp * 375733965Sjdp * In: input_line_pointer->whitespace before, or '0' of flonum. 375833965Sjdp * 375933965Sjdp */ 376033965Sjdp 376133965Sjdpvoid 376233965Sjdpfloat_cons (float_type) 376333965Sjdp /* Clobbers input_line-pointer, checks end-of-line. */ 376433965Sjdp register int float_type; /* 'f':.ffloat ... 'F':.float ... */ 376533965Sjdp{ 376633965Sjdp register char *p; 376733965Sjdp int length; /* Number of chars in an object. */ 376833965Sjdp register char *err; /* Error from scanning floating literal. */ 376933965Sjdp char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT]; 377033965Sjdp 377133965Sjdp if (is_it_end_of_statement ()) 377233965Sjdp { 377333965Sjdp demand_empty_rest_of_line (); 377433965Sjdp return; 377533965Sjdp } 377633965Sjdp 377733965Sjdp#ifdef md_flush_pending_output 377833965Sjdp md_flush_pending_output (); 377933965Sjdp#endif 378033965Sjdp 378133965Sjdp do 378233965Sjdp { 378333965Sjdp /* input_line_pointer->1st char of a flonum (we hope!). */ 378433965Sjdp SKIP_WHITESPACE (); 378533965Sjdp 378633965Sjdp /* Skip any 0{letter} that may be present. Don't even check if the 378733965Sjdp * letter is legal. Someone may invent a "z" format and this routine 378833965Sjdp * has no use for such information. Lusers beware: you get 378933965Sjdp * diagnostics if your input is ill-conditioned. 379033965Sjdp */ 379133965Sjdp if (input_line_pointer[0] == '0' && isalpha (input_line_pointer[1])) 379233965Sjdp input_line_pointer += 2; 379333965Sjdp 379433965Sjdp /* Accept :xxxx, where the x's are hex digits, for a floating 379533965Sjdp point with the exact digits specified. */ 379633965Sjdp if (input_line_pointer[0] == ':') 379733965Sjdp { 379833965Sjdp ++input_line_pointer; 379933965Sjdp length = hex_float (float_type, temp); 380033965Sjdp if (length < 0) 380133965Sjdp { 380233965Sjdp ignore_rest_of_line (); 380333965Sjdp return; 380433965Sjdp } 380533965Sjdp } 380633965Sjdp else 380733965Sjdp { 380833965Sjdp err = md_atof (float_type, temp, &length); 380933965Sjdp know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT); 381033965Sjdp know (length > 0); 381133965Sjdp if (err) 381233965Sjdp { 381333965Sjdp as_bad ("Bad floating literal: %s", err); 381433965Sjdp ignore_rest_of_line (); 381533965Sjdp return; 381633965Sjdp } 381733965Sjdp } 381833965Sjdp 381933965Sjdp if (!need_pass_2) 382033965Sjdp { 382133965Sjdp int count; 382233965Sjdp 382333965Sjdp count = 1; 382433965Sjdp 382533965Sjdp#ifdef REPEAT_CONS_EXPRESSIONS 382633965Sjdp if (*input_line_pointer == ':') 382733965Sjdp { 382833965Sjdp expressionS count_exp; 382933965Sjdp 383033965Sjdp ++input_line_pointer; 383133965Sjdp expression (&count_exp); 383233965Sjdp if (count_exp.X_op != O_constant 383333965Sjdp || count_exp.X_add_number <= 0) 383433965Sjdp { 383533965Sjdp as_warn ("unresolvable or nonpositive repeat count; using 1"); 383633965Sjdp } 383733965Sjdp else 383833965Sjdp count = count_exp.X_add_number; 383933965Sjdp } 384033965Sjdp#endif 384133965Sjdp 384233965Sjdp while (--count >= 0) 384333965Sjdp { 384433965Sjdp p = frag_more (length); 384533965Sjdp memcpy (p, temp, (unsigned int) length); 384633965Sjdp } 384733965Sjdp } 384833965Sjdp SKIP_WHITESPACE (); 384933965Sjdp } 385033965Sjdp while (*input_line_pointer++ == ','); 385133965Sjdp 385233965Sjdp --input_line_pointer; /* Put terminator back into stream. */ 385333965Sjdp demand_empty_rest_of_line (); 385433965Sjdp} /* float_cons() */ 385533965Sjdp 385633965Sjdp/* 385733965Sjdp * stringer() 385833965Sjdp * 385933965Sjdp * We read 0 or more ',' seperated, double-quoted strings. 386033965Sjdp * 386133965Sjdp * Caller should have checked need_pass_2 is FALSE because we don't check it. 386233965Sjdp */ 386333965Sjdp 386433965Sjdp 386533965Sjdpvoid 386633965Sjdpstringer (append_zero) /* Worker to do .ascii etc statements. */ 386733965Sjdp /* Checks end-of-line. */ 386833965Sjdp register int append_zero; /* 0: don't append '\0', else 1 */ 386933965Sjdp{ 387033965Sjdp register unsigned int c; 387133965Sjdp 387233965Sjdp#ifdef md_flush_pending_output 387333965Sjdp md_flush_pending_output (); 387433965Sjdp#endif 387533965Sjdp 387633965Sjdp /* 387733965Sjdp * The following awkward logic is to parse ZERO or more strings, 387833965Sjdp * comma seperated. Recall a string expression includes spaces 387933965Sjdp * before the opening '\"' and spaces after the closing '\"'. 388033965Sjdp * We fake a leading ',' if there is (supposed to be) 388133965Sjdp * a 1st, expression. We keep demanding expressions for each 388233965Sjdp * ','. 388333965Sjdp */ 388433965Sjdp if (is_it_end_of_statement ()) 388533965Sjdp { 388633965Sjdp c = 0; /* Skip loop. */ 388733965Sjdp ++input_line_pointer; /* Compensate for end of loop. */ 388833965Sjdp } 388933965Sjdp else 389033965Sjdp { 389133965Sjdp c = ','; /* Do loop. */ 389233965Sjdp } 389333965Sjdp while (c == ',' || c == '<' || c == '"') 389433965Sjdp { 389533965Sjdp SKIP_WHITESPACE (); 389633965Sjdp switch (*input_line_pointer) 389733965Sjdp { 389833965Sjdp case '\"': 389933965Sjdp ++input_line_pointer; /*->1st char of string. */ 390033965Sjdp while (is_a_char (c = next_char_of_string ())) 390133965Sjdp { 390233965Sjdp FRAG_APPEND_1_CHAR (c); 390333965Sjdp } 390433965Sjdp if (append_zero) 390533965Sjdp { 390633965Sjdp FRAG_APPEND_1_CHAR (0); 390733965Sjdp } 390833965Sjdp know (input_line_pointer[-1] == '\"'); 390933965Sjdp break; 391033965Sjdp case '<': 391133965Sjdp input_line_pointer++; 391233965Sjdp c = get_single_number (); 391333965Sjdp FRAG_APPEND_1_CHAR (c); 391433965Sjdp if (*input_line_pointer != '>') 391533965Sjdp { 391633965Sjdp as_bad ("Expected <nn>"); 391733965Sjdp } 391833965Sjdp input_line_pointer++; 391933965Sjdp break; 392033965Sjdp case ',': 392133965Sjdp input_line_pointer++; 392233965Sjdp break; 392333965Sjdp } 392433965Sjdp SKIP_WHITESPACE (); 392533965Sjdp c = *input_line_pointer; 392633965Sjdp } 392733965Sjdp 392833965Sjdp demand_empty_rest_of_line (); 392933965Sjdp} /* stringer() */ 393033965Sjdp 393133965Sjdp/* FIXME-SOMEDAY: I had trouble here on characters with the 393233965Sjdp high bits set. We'll probably also have trouble with 393333965Sjdp multibyte chars, wide chars, etc. Also be careful about 393433965Sjdp returning values bigger than 1 byte. xoxorich. */ 393533965Sjdp 393633965Sjdpunsigned int 393733965Sjdpnext_char_of_string () 393833965Sjdp{ 393933965Sjdp register unsigned int c; 394033965Sjdp 394133965Sjdp c = *input_line_pointer++ & CHAR_MASK; 394233965Sjdp switch (c) 394333965Sjdp { 394433965Sjdp case '\"': 394533965Sjdp c = NOT_A_CHAR; 394633965Sjdp break; 394733965Sjdp 394833965Sjdp case '\n': 394933965Sjdp as_warn ("Unterminated string: Newline inserted."); 395033965Sjdp bump_line_counters (); 395133965Sjdp break; 395233965Sjdp 395333965Sjdp#ifndef NO_STRING_ESCAPES 395433965Sjdp case '\\': 395533965Sjdp switch (c = *input_line_pointer++) 395633965Sjdp { 395733965Sjdp case 'b': 395833965Sjdp c = '\b'; 395933965Sjdp break; 396033965Sjdp 396133965Sjdp case 'f': 396233965Sjdp c = '\f'; 396333965Sjdp break; 396433965Sjdp 396533965Sjdp case 'n': 396633965Sjdp c = '\n'; 396733965Sjdp break; 396833965Sjdp 396933965Sjdp case 'r': 397033965Sjdp c = '\r'; 397133965Sjdp break; 397233965Sjdp 397333965Sjdp case 't': 397433965Sjdp c = '\t'; 397533965Sjdp break; 397633965Sjdp 397733965Sjdp case 'v': 397833965Sjdp c = '\013'; 397933965Sjdp break; 398033965Sjdp 398133965Sjdp case '\\': 398233965Sjdp case '"': 398333965Sjdp break; /* As itself. */ 398433965Sjdp 398533965Sjdp case '0': 398633965Sjdp case '1': 398733965Sjdp case '2': 398833965Sjdp case '3': 398933965Sjdp case '4': 399033965Sjdp case '5': 399133965Sjdp case '6': 399233965Sjdp case '7': 399333965Sjdp case '8': 399433965Sjdp case '9': 399533965Sjdp { 399633965Sjdp long number; 399733965Sjdp int i; 399833965Sjdp 399933965Sjdp for (i = 0, number = 0; isdigit (c) && i < 3; c = *input_line_pointer++, i++) 400033965Sjdp { 400133965Sjdp number = number * 8 + c - '0'; 400233965Sjdp } 400333965Sjdp c = number & 0xff; 400433965Sjdp } 400533965Sjdp --input_line_pointer; 400633965Sjdp break; 400733965Sjdp 400833965Sjdp case 'x': 400933965Sjdp case 'X': 401033965Sjdp { 401133965Sjdp long number; 401233965Sjdp 401333965Sjdp number = 0; 401433965Sjdp c = *input_line_pointer++; 401533965Sjdp while (isxdigit (c)) 401633965Sjdp { 401733965Sjdp if (isdigit (c)) 401833965Sjdp number = number * 16 + c - '0'; 401933965Sjdp else if (isupper (c)) 402033965Sjdp number = number * 16 + c - 'A' + 10; 402133965Sjdp else 402233965Sjdp number = number * 16 + c - 'a' + 10; 402333965Sjdp c = *input_line_pointer++; 402433965Sjdp } 402533965Sjdp c = number & 0xff; 402633965Sjdp --input_line_pointer; 402733965Sjdp } 402833965Sjdp break; 402933965Sjdp 403033965Sjdp case '\n': 403133965Sjdp /* To be compatible with BSD 4.2 as: give the luser a linefeed!! */ 403233965Sjdp as_warn ("Unterminated string: Newline inserted."); 403333965Sjdp c = '\n'; 403433965Sjdp bump_line_counters (); 403533965Sjdp break; 403633965Sjdp 403733965Sjdp default: 403833965Sjdp 403933965Sjdp#ifdef ONLY_STANDARD_ESCAPES 404033965Sjdp as_bad ("Bad escaped character in string, '?' assumed"); 404133965Sjdp c = '?'; 404233965Sjdp#endif /* ONLY_STANDARD_ESCAPES */ 404333965Sjdp 404433965Sjdp break; 404533965Sjdp } /* switch on escaped char */ 404633965Sjdp break; 404733965Sjdp#endif /* ! defined (NO_STRING_ESCAPES) */ 404833965Sjdp 404933965Sjdp default: 405033965Sjdp break; 405133965Sjdp } /* switch on char */ 405233965Sjdp return (c); 405333965Sjdp} /* next_char_of_string() */ 405433965Sjdp 405533965Sjdpstatic segT 405633965Sjdpget_segmented_expression (expP) 405733965Sjdp register expressionS *expP; 405833965Sjdp{ 405933965Sjdp register segT retval; 406033965Sjdp 406133965Sjdp retval = expression (expP); 406233965Sjdp if (expP->X_op == O_illegal 406333965Sjdp || expP->X_op == O_absent 406433965Sjdp || expP->X_op == O_big) 406533965Sjdp { 406633965Sjdp as_bad ("expected address expression; zero assumed"); 406733965Sjdp expP->X_op = O_constant; 406833965Sjdp expP->X_add_number = 0; 406933965Sjdp retval = absolute_section; 407033965Sjdp } 407133965Sjdp return retval; 407233965Sjdp} 407333965Sjdp 407433965Sjdpstatic segT 407533965Sjdpget_known_segmented_expression (expP) 407633965Sjdp register expressionS *expP; 407733965Sjdp{ 407833965Sjdp register segT retval; 407933965Sjdp 408033965Sjdp if ((retval = get_segmented_expression (expP)) == undefined_section) 408133965Sjdp { 408233965Sjdp /* There is no easy way to extract the undefined symbol from the 408333965Sjdp expression. */ 408433965Sjdp if (expP->X_add_symbol != NULL 408533965Sjdp && S_GET_SEGMENT (expP->X_add_symbol) != expr_section) 408633965Sjdp as_warn ("symbol \"%s\" undefined; zero assumed", 408733965Sjdp S_GET_NAME (expP->X_add_symbol)); 408833965Sjdp else 408933965Sjdp as_warn ("some symbol undefined; zero assumed"); 409033965Sjdp retval = absolute_section; 409133965Sjdp expP->X_op = O_constant; 409233965Sjdp expP->X_add_number = 0; 409333965Sjdp } 409433965Sjdp know (retval == absolute_section || SEG_NORMAL (retval)); 409533965Sjdp return (retval); 409633965Sjdp} /* get_known_segmented_expression() */ 409733965Sjdp 409833965SjdpoffsetT 409933965Sjdpget_absolute_expression () 410033965Sjdp{ 410133965Sjdp expressionS exp; 410233965Sjdp 410333965Sjdp expression (&exp); 410433965Sjdp if (exp.X_op != O_constant) 410533965Sjdp { 410633965Sjdp if (exp.X_op != O_absent) 410733965Sjdp as_bad ("bad or irreducible absolute expression; zero assumed"); 410833965Sjdp exp.X_add_number = 0; 410933965Sjdp } 411033965Sjdp return exp.X_add_number; 411133965Sjdp} 411233965Sjdp 411333965Sjdpchar /* return terminator */ 411433965Sjdpget_absolute_expression_and_terminator (val_pointer) 411533965Sjdp long *val_pointer; /* return value of expression */ 411633965Sjdp{ 411733965Sjdp /* FIXME: val_pointer should probably be offsetT *. */ 411833965Sjdp *val_pointer = (long) get_absolute_expression (); 411933965Sjdp return (*input_line_pointer++); 412033965Sjdp} 412133965Sjdp 412233965Sjdp/* 412333965Sjdp * demand_copy_C_string() 412433965Sjdp * 412533965Sjdp * Like demand_copy_string, but return NULL if the string contains any '\0's. 412633965Sjdp * Give a warning if that happens. 412733965Sjdp */ 412833965Sjdpchar * 412933965Sjdpdemand_copy_C_string (len_pointer) 413033965Sjdp int *len_pointer; 413133965Sjdp{ 413233965Sjdp register char *s; 413333965Sjdp 413433965Sjdp if ((s = demand_copy_string (len_pointer)) != 0) 413533965Sjdp { 413633965Sjdp register int len; 413733965Sjdp 413833965Sjdp for (len = *len_pointer; len > 0; len--) 413933965Sjdp { 414033965Sjdp if (*s == 0) 414133965Sjdp { 414233965Sjdp s = 0; 414333965Sjdp len = 1; 414433965Sjdp *len_pointer = 0; 414533965Sjdp as_bad ("This string may not contain \'\\0\'"); 414633965Sjdp } 414733965Sjdp } 414833965Sjdp } 414933965Sjdp return s; 415033965Sjdp} 415133965Sjdp 415233965Sjdp/* 415333965Sjdp * demand_copy_string() 415433965Sjdp * 415533965Sjdp * Demand string, but return a safe (=private) copy of the string. 415633965Sjdp * Return NULL if we can't read a string here. 415733965Sjdp */ 415833965Sjdpchar * 415933965Sjdpdemand_copy_string (lenP) 416033965Sjdp int *lenP; 416133965Sjdp{ 416233965Sjdp register unsigned int c; 416333965Sjdp register int len; 416433965Sjdp char *retval; 416533965Sjdp 416633965Sjdp len = 0; 416733965Sjdp SKIP_WHITESPACE (); 416833965Sjdp if (*input_line_pointer == '\"') 416933965Sjdp { 417033965Sjdp input_line_pointer++; /* Skip opening quote. */ 417133965Sjdp 417233965Sjdp while (is_a_char (c = next_char_of_string ())) 417333965Sjdp { 417433965Sjdp obstack_1grow (¬es, c); 417533965Sjdp len++; 417633965Sjdp } 417733965Sjdp /* JF this next line is so demand_copy_C_string will return a 417833965Sjdp null terminated string. */ 417933965Sjdp obstack_1grow (¬es, '\0'); 418033965Sjdp retval = obstack_finish (¬es); 418133965Sjdp } 418233965Sjdp else 418333965Sjdp { 418433965Sjdp as_warn ("Missing string"); 418533965Sjdp retval = NULL; 418633965Sjdp ignore_rest_of_line (); 418733965Sjdp } 418833965Sjdp *lenP = len; 418933965Sjdp return (retval); 419033965Sjdp} /* demand_copy_string() */ 419133965Sjdp 419233965Sjdp/* 419333965Sjdp * is_it_end_of_statement() 419433965Sjdp * 419533965Sjdp * In: Input_line_pointer->next character. 419633965Sjdp * 419733965Sjdp * Do: Skip input_line_pointer over all whitespace. 419833965Sjdp * 419933965Sjdp * Out: 1 if input_line_pointer->end-of-line. 420033965Sjdp*/ 420133965Sjdpint 420233965Sjdpis_it_end_of_statement () 420333965Sjdp{ 420433965Sjdp SKIP_WHITESPACE (); 420533965Sjdp return (is_end_of_line[(unsigned char) *input_line_pointer]); 420633965Sjdp} /* is_it_end_of_statement() */ 420733965Sjdp 420833965Sjdpvoid 420933965Sjdpequals (sym_name, reassign) 421033965Sjdp char *sym_name; 421133965Sjdp int reassign; 421233965Sjdp{ 421333965Sjdp register symbolS *symbolP; /* symbol we are working with */ 421433965Sjdp char *stop; 421533965Sjdp char stopc; 421633965Sjdp 421733965Sjdp input_line_pointer++; 421833965Sjdp if (*input_line_pointer == '=') 421933965Sjdp input_line_pointer++; 422033965Sjdp 422133965Sjdp while (*input_line_pointer == ' ' || *input_line_pointer == '\t') 422233965Sjdp input_line_pointer++; 422333965Sjdp 422433965Sjdp if (flag_mri) 422533965Sjdp stop = mri_comment_field (&stopc); 422633965Sjdp 422733965Sjdp if (sym_name[0] == '.' && sym_name[1] == '\0') 422833965Sjdp { 422933965Sjdp /* Turn '. = mumble' into a .org mumble */ 423033965Sjdp register segT segment; 423133965Sjdp expressionS exp; 423233965Sjdp 423333965Sjdp segment = get_known_segmented_expression (&exp); 423433965Sjdp if (!need_pass_2) 423533965Sjdp do_org (segment, &exp, 0); 423633965Sjdp } 423733965Sjdp else 423833965Sjdp { 423933965Sjdp symbolP = symbol_find_or_make (sym_name); 424033965Sjdp /* Permit register names to be redefined. */ 424133965Sjdp if (! reassign 424233965Sjdp && S_IS_DEFINED (symbolP) 424333965Sjdp && S_GET_SEGMENT (symbolP) != reg_section) 424433965Sjdp as_bad ("symbol `%s' already defined", S_GET_NAME (symbolP)); 424533965Sjdp pseudo_set (symbolP); 424633965Sjdp } 424733965Sjdp 424833965Sjdp if (flag_mri) 424933965Sjdp mri_comment_end (stop, stopc); 425033965Sjdp} /* equals() */ 425133965Sjdp 425233965Sjdp/* .include -- include a file at this point. */ 425333965Sjdp 425433965Sjdp/* ARGSUSED */ 425533965Sjdpvoid 425633965Sjdps_include (arg) 425733965Sjdp int arg; 425833965Sjdp{ 425933965Sjdp char *newbuf; 426033965Sjdp char *filename; 426133965Sjdp int i; 426233965Sjdp FILE *try; 426333965Sjdp char *path; 426433965Sjdp 426533965Sjdp if (! flag_m68k_mri) 426633965Sjdp filename = demand_copy_string (&i); 426733965Sjdp else 426833965Sjdp { 426933965Sjdp SKIP_WHITESPACE (); 427033965Sjdp i = 0; 427133965Sjdp while (! is_end_of_line[(unsigned char) *input_line_pointer] 427233965Sjdp && *input_line_pointer != ' ' 427333965Sjdp && *input_line_pointer != '\t') 427433965Sjdp { 427533965Sjdp obstack_1grow (¬es, *input_line_pointer); 427633965Sjdp ++input_line_pointer; 427733965Sjdp ++i; 427833965Sjdp } 427933965Sjdp obstack_1grow (¬es, '\0'); 428033965Sjdp filename = obstack_finish (¬es); 428133965Sjdp while (! is_end_of_line[(unsigned char) *input_line_pointer]) 428233965Sjdp ++input_line_pointer; 428333965Sjdp } 428433965Sjdp demand_empty_rest_of_line (); 428533965Sjdp path = xmalloc ((unsigned long) i + include_dir_maxlen + 5 /* slop */ ); 428633965Sjdp for (i = 0; i < include_dir_count; i++) 428733965Sjdp { 428833965Sjdp strcpy (path, include_dirs[i]); 428933965Sjdp strcat (path, "/"); 429033965Sjdp strcat (path, filename); 429133965Sjdp if (0 != (try = fopen (path, "r"))) 429233965Sjdp { 429333965Sjdp fclose (try); 429433965Sjdp goto gotit; 429533965Sjdp } 429633965Sjdp } 429733965Sjdp free (path); 429833965Sjdp path = filename; 429933965Sjdpgotit: 430033965Sjdp /* malloc Storage leak when file is found on path. FIXME-SOMEDAY. */ 430133965Sjdp newbuf = input_scrub_include_file (path, input_line_pointer); 430233965Sjdp buffer_limit = input_scrub_next_buffer (&input_line_pointer); 430333965Sjdp} /* s_include() */ 430433965Sjdp 430533965Sjdpvoid 430633965Sjdpadd_include_dir (path) 430733965Sjdp char *path; 430833965Sjdp{ 430933965Sjdp int i; 431033965Sjdp 431133965Sjdp if (include_dir_count == 0) 431233965Sjdp { 431333965Sjdp include_dirs = (char **) xmalloc (2 * sizeof (*include_dirs)); 431433965Sjdp include_dirs[0] = "."; /* Current dir */ 431533965Sjdp include_dir_count = 2; 431633965Sjdp } 431733965Sjdp else 431833965Sjdp { 431933965Sjdp include_dir_count++; 432033965Sjdp include_dirs = (char **) realloc (include_dirs, 432133965Sjdp include_dir_count * sizeof (*include_dirs)); 432233965Sjdp } 432333965Sjdp 432433965Sjdp include_dirs[include_dir_count - 1] = path; /* New one */ 432533965Sjdp 432633965Sjdp i = strlen (path); 432733965Sjdp if (i > include_dir_maxlen) 432833965Sjdp include_dir_maxlen = i; 432933965Sjdp} /* add_include_dir() */ 433033965Sjdp 433133965Sjdpvoid 433233965Sjdps_ignore (arg) 433333965Sjdp int arg; 433433965Sjdp{ 433533965Sjdp while (!is_end_of_line[(unsigned char) *input_line_pointer]) 433633965Sjdp { 433733965Sjdp ++input_line_pointer; 433833965Sjdp } 433933965Sjdp ++input_line_pointer; 434033965Sjdp} 434133965Sjdp 434233965Sjdp 434333965Sjdpvoid 434433965Sjdpread_print_statistics (file) 434533965Sjdp FILE *file; 434633965Sjdp{ 434733965Sjdp hash_print_statistics (file, "pseudo-op table", po_hash); 434833965Sjdp} 434933965Sjdp 435033965Sjdp/* end of read.c */ 4351