read.c revision 60484
133965Sjdp/* read.c - read a source file - 260484Sobrien Copyright (C) 1986, 87, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 360484Sobrien 2000 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 5660484Sobrien/* Set by the object-format or the target. */ 5760484Sobrien#ifndef TC_IMPLICIT_LCOMM_ALIGNMENT 5860484Sobrien#define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) \ 5960484Sobrien do { \ 6060484Sobrien if ((SIZE) >= 8) \ 6160484Sobrien (P2VAR) = 3; \ 6260484Sobrien else if ((SIZE) >= 4) \ 6360484Sobrien (P2VAR) = 2; \ 6460484Sobrien else if ((SIZE) >= 2) \ 6560484Sobrien (P2VAR) = 1; \ 6660484Sobrien else \ 6760484Sobrien (P2VAR) = 0; \ 6860484Sobrien } while (0) 6960484Sobrien#endif 7060484Sobrien 7133965Sjdp/* The NOP_OPCODE is for the alignment fill value. 7233965Sjdp * fill it a nop instruction so that the disassembler does not choke 7333965Sjdp * on it 7433965Sjdp */ 7533965Sjdp#ifndef NOP_OPCODE 7633965Sjdp#define NOP_OPCODE 0x00 7733965Sjdp#endif 7833965Sjdp 7933965Sjdpchar *input_line_pointer; /*->next char of source file to parse. */ 8033965Sjdp 8133965Sjdp#if BITS_PER_CHAR != 8 8233965Sjdp/* The following table is indexed by[(char)] and will break if 8333965Sjdp a char does not have exactly 256 states (hopefully 0:255!)! */ 8433965Sjdpdie horribly; 8533965Sjdp#endif 8633965Sjdp 8733965Sjdp#ifndef LEX_AT 8833965Sjdp/* The m88k unfortunately uses @ as a label beginner. */ 8933965Sjdp#define LEX_AT 0 9033965Sjdp#endif 9133965Sjdp 9233965Sjdp#ifndef LEX_BR 9333965Sjdp/* The RS/6000 assembler uses {,},[,] as parts of symbol names. */ 9433965Sjdp#define LEX_BR 0 9533965Sjdp#endif 9633965Sjdp 9733965Sjdp#ifndef LEX_PCT 9833965Sjdp/* The Delta 68k assembler permits % inside label names. */ 9933965Sjdp#define LEX_PCT 0 10033965Sjdp#endif 10133965Sjdp 10233965Sjdp#ifndef LEX_QM 10333965Sjdp/* The PowerPC Windows NT assemblers permits ? inside label names. */ 10433965Sjdp#define LEX_QM 0 10533965Sjdp#endif 10633965Sjdp 10760484Sobrien#ifndef LEX_HASH 10860484Sobrien#define LEX_HASH 0 10960484Sobrien#endif 11060484Sobrien 11133965Sjdp#ifndef LEX_DOLLAR 11233965Sjdp/* The a29k assembler does not permits labels to start with $. */ 11333965Sjdp#define LEX_DOLLAR 3 11433965Sjdp#endif 11533965Sjdp 11633965Sjdp#ifndef LEX_TILDE 11733965Sjdp/* The Delta 68k assembler permits ~ at start of label names. */ 11833965Sjdp#define LEX_TILDE 0 11933965Sjdp#endif 12033965Sjdp 12133965Sjdp/* used by is_... macros. our ctype[] */ 12233965Sjdpchar lex_type[256] = 12333965Sjdp{ 12433965Sjdp 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */ 12533965Sjdp 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ[\]^_ */ 12660484Sobrien 0, 0, 0, LEX_HASH, LEX_DOLLAR, LEX_PCT, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */ 12733965Sjdp 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, LEX_QM, /* 0123456789:;<=>? */ 12833965Sjdp LEX_AT, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */ 12933965Sjdp 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, 0, 3, /* PQRSTUVWXYZ[\]^_ */ 13033965Sjdp 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* `abcdefghijklmno */ 13133965Sjdp 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, LEX_TILDE, 0, /* pqrstuvwxyz{|}~. */ 13260484Sobrien 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 13360484Sobrien 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 13460484Sobrien 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 13560484Sobrien 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 13660484Sobrien 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 13760484Sobrien 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 13860484Sobrien 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 13960484Sobrien 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 14033965Sjdp}; 14133965Sjdp 14233965Sjdp 14333965Sjdp/* 14433965Sjdp * In: a character. 14533965Sjdp * Out: 1 if this character ends a line. 14633965Sjdp */ 14760484Sobrien#define Z_ (0) 14833965Sjdpchar is_end_of_line[256] = 14933965Sjdp{ 15033965Sjdp#ifdef CR_EOL 15160484Sobrien 99, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, 99, Z_, Z_, 99, Z_, Z_, /* @abcdefghijklmno */ 15233965Sjdp#else 15360484Sobrien 99, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, 99, Z_, Z_, Z_, Z_, Z_, /* @abcdefghijklmno */ 15433965Sjdp#endif 15560484Sobrien Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */ 15633965Sjdp#ifdef TC_HPPA 15760484Sobrien Z_,99, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* _!"#$%&'()*+,-./ */ 15860484Sobrien Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* 0123456789:;<=>? */ 15933965Sjdp#else 16060484Sobrien Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */ 16160484Sobrien Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, 99, Z_, Z_, Z_, Z_, /* 0123456789:;<=>? */ 16233965Sjdp#endif 16360484Sobrien Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */ 16460484Sobrien Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */ 16560484Sobrien Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */ 16660484Sobrien Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */ 16760484Sobrien Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */ 16860484Sobrien Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */ 16960484Sobrien Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */ 17060484Sobrien Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */ 17160484Sobrien Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */ 17233965Sjdp}; 17360484Sobrien#undef Z_ 17433965Sjdp 17533965Sjdp/* Functions private to this file. */ 17633965Sjdp 17733965Sjdpstatic char *buffer; /* 1st char of each buffer of lines is here. */ 17833965Sjdpstatic char *buffer_limit; /*->1 + last char in buffer. */ 17933965Sjdp 18033965Sjdp/* TARGET_BYTES_BIG_ENDIAN is required to be defined to either 0 or 1 in the 18133965Sjdp tc-<CPU>.h file. See the "Porting GAS" section of the internals manual. */ 18233965Sjdpint target_big_endian = TARGET_BYTES_BIG_ENDIAN; 18333965Sjdp 18433965Sjdpstatic char *old_buffer; /* JF a hack */ 18533965Sjdpstatic char *old_input; 18633965Sjdpstatic char *old_limit; 18733965Sjdp 18838889Sjdp/* Variables for handling include file directory table. */ 18933965Sjdp 19038889Sjdpchar **include_dirs; /* Table of pointers to directories to 19133965Sjdp search for .include's */ 19238889Sjdpint include_dir_count; /* How many are in the table */ 19338889Sjdpint include_dir_maxlen = 1;/* Length of longest in table */ 19433965Sjdp 19533965Sjdp#ifndef WORKING_DOT_WORD 19633965Sjdpstruct broken_word *broken_words; 19733965Sjdpint new_broken_words; 19833965Sjdp#endif 19933965Sjdp 20033965Sjdp/* The current offset into the absolute section. We don't try to 20133965Sjdp build frags in the absolute section, since no data can be stored 20233965Sjdp there. We just keep track of the current offset. */ 20333965SjdpaddressT abs_section_offset; 20433965Sjdp 20533965Sjdp/* If this line had an MRI style label, it is stored in this variable. 20633965Sjdp This is used by some of the MRI pseudo-ops. */ 20733965SjdpsymbolS *line_label; 20833965Sjdp 20933965Sjdp/* This global variable is used to support MRI common sections. We 21033965Sjdp translate such sections into a common symbol. This variable is 21133965Sjdp non-NULL when we are in an MRI common section. */ 21233965SjdpsymbolS *mri_common_symbol; 21333965Sjdp 21433965Sjdp/* In MRI mode, after a dc.b pseudo-op with an odd number of bytes, we 21533965Sjdp need to align to an even byte boundary unless the next pseudo-op is 21633965Sjdp dc.b, ds.b, or dcb.b. This variable is set to 1 if an alignment 21733965Sjdp may be needed. */ 21833965Sjdpstatic int mri_pending_align; 21933965Sjdp 22038889Sjdp#ifndef NO_LISTING 22138889Sjdp#ifdef OBJ_ELF 22238889Sjdp/* This variable is set to be non-zero if the next string we see might 22338889Sjdp be the name of the source file in DWARF debugging information. See 22438889Sjdp the comment in emit_expr for the format we look for. */ 22538889Sjdpstatic int dwarf_file_string; 22638889Sjdp#endif 22738889Sjdp#endif 22838889Sjdp 22933965Sjdpstatic void cons_worker PARAMS ((int, int)); 23060484Sobrienstatic int scrub_from_string PARAMS ((char *, int)); 23133965Sjdpstatic void do_align PARAMS ((int, char *, int, int)); 23233965Sjdpstatic void s_align PARAMS ((int, int)); 23360484Sobrienstatic void s_lcomm_internal PARAMS ((int, int)); 23433965Sjdpstatic int hex_float PARAMS ((int, char *)); 23560484Sobrienstatic inline int sizeof_sleb128 PARAMS ((offsetT)); 23660484Sobrienstatic inline int sizeof_uleb128 PARAMS ((valueT)); 23760484Sobrienstatic inline int output_sleb128 PARAMS ((char *, offsetT)); 23860484Sobrienstatic inline int output_uleb128 PARAMS ((char *, valueT)); 23960484Sobrienstatic inline int output_big_sleb128 PARAMS ((char *, LITTLENUM_TYPE *, int)); 24060484Sobrienstatic inline int output_big_uleb128 PARAMS ((char *, LITTLENUM_TYPE *, int)); 24160484Sobrienstatic int output_big_leb128 PARAMS ((char *, LITTLENUM_TYPE *, int, int)); 24233965Sjdpstatic void do_org PARAMS ((segT, expressionS *, int)); 24333965Sjdpchar *demand_copy_string PARAMS ((int *lenP)); 24433965Sjdpstatic segT get_segmented_expression PARAMS ((expressionS *expP)); 24533965Sjdpstatic segT get_known_segmented_expression PARAMS ((expressionS * expP)); 24633965Sjdpstatic void pobegin PARAMS ((void)); 24733965Sjdpstatic int get_line_sb PARAMS ((sb *)); 24860484Sobrienstatic void generate_file_debug PARAMS ((void)); 24933965Sjdp 25033965Sjdp 25133965Sjdpvoid 25233965Sjdpread_begin () 25333965Sjdp{ 25433965Sjdp const char *p; 25533965Sjdp 25633965Sjdp pobegin (); 25733965Sjdp obj_read_begin_hook (); 25833965Sjdp 25933965Sjdp /* Something close -- but not too close -- to a multiple of 1024. 26033965Sjdp The debugging malloc I'm using has 24 bytes of overhead. */ 26133965Sjdp obstack_begin (¬es, chunksize); 26233965Sjdp obstack_begin (&cond_obstack, chunksize); 26333965Sjdp 26433965Sjdp /* Use machine dependent syntax */ 26533965Sjdp for (p = line_separator_chars; *p; p++) 26633965Sjdp is_end_of_line[(unsigned char) *p] = 1; 26733965Sjdp /* Use more. FIXME-SOMEDAY. */ 26833965Sjdp 26933965Sjdp if (flag_mri) 27033965Sjdp lex_type['?'] = 3; 27133965Sjdp} 27233965Sjdp 27333965Sjdp/* set up pseudo-op tables */ 27433965Sjdp 27533965Sjdpstatic struct hash_control *po_hash; 27633965Sjdp 27733965Sjdpstatic const pseudo_typeS potable[] = 27833965Sjdp{ 27933965Sjdp {"abort", s_abort, 0}, 28033965Sjdp {"align", s_align_ptwo, 0}, 28133965Sjdp {"ascii", stringer, 0}, 28233965Sjdp {"asciz", stringer, 1}, 28333965Sjdp {"balign", s_align_bytes, 0}, 28433965Sjdp {"balignw", s_align_bytes, -2}, 28533965Sjdp {"balignl", s_align_bytes, -4}, 28633965Sjdp/* block */ 28733965Sjdp {"byte", cons, 1}, 28833965Sjdp {"comm", s_comm, 0}, 28933965Sjdp {"common", s_mri_common, 0}, 29033965Sjdp {"common.s", s_mri_common, 1}, 29133965Sjdp {"data", s_data, 0}, 29233965Sjdp {"dc", cons, 2}, 29333965Sjdp {"dc.b", cons, 1}, 29433965Sjdp {"dc.d", float_cons, 'd'}, 29533965Sjdp {"dc.l", cons, 4}, 29633965Sjdp {"dc.s", float_cons, 'f'}, 29733965Sjdp {"dc.w", cons, 2}, 29833965Sjdp {"dc.x", float_cons, 'x'}, 29933965Sjdp {"dcb", s_space, 2}, 30033965Sjdp {"dcb.b", s_space, 1}, 30133965Sjdp {"dcb.d", s_float_space, 'd'}, 30233965Sjdp {"dcb.l", s_space, 4}, 30333965Sjdp {"dcb.s", s_float_space, 'f'}, 30433965Sjdp {"dcb.w", s_space, 2}, 30533965Sjdp {"dcb.x", s_float_space, 'x'}, 30633965Sjdp {"ds", s_space, 2}, 30733965Sjdp {"ds.b", s_space, 1}, 30833965Sjdp {"ds.d", s_space, 8}, 30933965Sjdp {"ds.l", s_space, 4}, 31033965Sjdp {"ds.p", s_space, 12}, 31133965Sjdp {"ds.s", s_space, 4}, 31233965Sjdp {"ds.w", s_space, 2}, 31333965Sjdp {"ds.x", s_space, 12}, 31433965Sjdp {"debug", s_ignore, 0}, 31533965Sjdp#ifdef S_SET_DESC 31633965Sjdp {"desc", s_desc, 0}, 31733965Sjdp#endif 31833965Sjdp/* dim */ 31933965Sjdp {"double", float_cons, 'd'}, 32033965Sjdp/* dsect */ 32133965Sjdp {"eject", listing_eject, 0}, /* Formfeed listing */ 32233965Sjdp {"else", s_else, 0}, 32333965Sjdp {"elsec", s_else, 0}, 32460484Sobrien {"elseif", s_elseif, (int) O_ne}, 32533965Sjdp {"end", s_end, 0}, 32633965Sjdp {"endc", s_endif, 0}, 32760484Sobrien {"endfunc", s_func, 1}, 32833965Sjdp {"endif", s_endif, 0}, 32933965Sjdp/* endef */ 33033965Sjdp {"equ", s_set, 0}, 33133965Sjdp {"equiv", s_set, 1}, 33233965Sjdp {"err", s_err, 0}, 33333965Sjdp {"exitm", s_mexit, 0}, 33433965Sjdp/* extend */ 33533965Sjdp {"extern", s_ignore, 0}, /* We treat all undef as ext */ 33633965Sjdp {"appfile", s_app_file, 1}, 33733965Sjdp {"appline", s_app_line, 0}, 33833965Sjdp {"fail", s_fail, 0}, 33933965Sjdp {"file", s_app_file, 0}, 34033965Sjdp {"fill", s_fill, 0}, 34133965Sjdp {"float", float_cons, 'f'}, 34233965Sjdp {"format", s_ignore, 0}, 34360484Sobrien {"func", s_func, 0}, 34433965Sjdp {"global", s_globl, 0}, 34533965Sjdp {"globl", s_globl, 0}, 34633965Sjdp {"hword", cons, 2}, 34733965Sjdp {"if", s_if, (int) O_ne}, 34833965Sjdp {"ifc", s_ifc, 0}, 34933965Sjdp {"ifdef", s_ifdef, 0}, 35033965Sjdp {"ifeq", s_if, (int) O_eq}, 35133965Sjdp {"ifeqs", s_ifeqs, 0}, 35233965Sjdp {"ifge", s_if, (int) O_ge}, 35333965Sjdp {"ifgt", s_if, (int) O_gt}, 35433965Sjdp {"ifle", s_if, (int) O_le}, 35533965Sjdp {"iflt", s_if, (int) O_lt}, 35633965Sjdp {"ifnc", s_ifc, 1}, 35733965Sjdp {"ifndef", s_ifdef, 1}, 35833965Sjdp {"ifne", s_if, (int) O_ne}, 35933965Sjdp {"ifnes", s_ifeqs, 1}, 36033965Sjdp {"ifnotdef", s_ifdef, 1}, 36133965Sjdp {"include", s_include, 0}, 36233965Sjdp {"int", cons, 4}, 36333965Sjdp {"irp", s_irp, 0}, 36433965Sjdp {"irep", s_irp, 0}, 36533965Sjdp {"irpc", s_irp, 1}, 36633965Sjdp {"irepc", s_irp, 1}, 36733965Sjdp {"lcomm", s_lcomm, 0}, 36833965Sjdp {"lflags", listing_flags, 0}, /* Listing flags */ 36933965Sjdp {"linkonce", s_linkonce, 0}, 37033965Sjdp {"list", listing_list, 1}, /* Turn listing on */ 37133965Sjdp {"llen", listing_psize, 1}, 37233965Sjdp {"long", cons, 4}, 37333965Sjdp {"lsym", s_lsym, 0}, 37433965Sjdp {"macro", s_macro, 0}, 37533965Sjdp {"mexit", s_mexit, 0}, 37633965Sjdp {"mri", s_mri, 0}, 37733965Sjdp {".mri", s_mri, 0}, /* Special case so .mri works in MRI mode. */ 37833965Sjdp {"name", s_ignore, 0}, 37933965Sjdp {"noformat", s_ignore, 0}, 38033965Sjdp {"nolist", listing_list, 0}, /* Turn listing off */ 38133965Sjdp {"nopage", listing_nopage, 0}, 38233965Sjdp {"octa", cons, 16}, 38333965Sjdp {"offset", s_struct, 0}, 38433965Sjdp {"org", s_org, 0}, 38533965Sjdp {"p2align", s_align_ptwo, 0}, 38633965Sjdp {"p2alignw", s_align_ptwo, -2}, 38733965Sjdp {"p2alignl", s_align_ptwo, -4}, 38833965Sjdp {"page", listing_eject, 0}, 38933965Sjdp {"plen", listing_psize, 0}, 39033965Sjdp {"print", s_print, 0}, 39133965Sjdp {"psize", listing_psize, 0}, /* set paper size */ 39233965Sjdp {"purgem", s_purgem, 0}, 39333965Sjdp {"quad", cons, 8}, 39433965Sjdp {"rep", s_rept, 0}, 39533965Sjdp {"rept", s_rept, 0}, 39633965Sjdp {"rva", s_rva, 4}, 39733965Sjdp {"sbttl", listing_title, 1}, /* Subtitle of listing */ 39833965Sjdp/* scl */ 39933965Sjdp/* sect */ 40033965Sjdp {"set", s_set, 0}, 40133965Sjdp {"short", cons, 2}, 40233965Sjdp {"single", float_cons, 'f'}, 40333965Sjdp/* size */ 40433965Sjdp {"space", s_space, 0}, 40533965Sjdp {"skip", s_space, 0}, 40638889Sjdp {"sleb128", s_leb128, 1}, 40733965Sjdp {"spc", s_ignore, 0}, 40833965Sjdp {"stabd", s_stab, 'd'}, 40933965Sjdp {"stabn", s_stab, 'n'}, 41033965Sjdp {"stabs", s_stab, 's'}, 41133965Sjdp {"string", stringer, 1}, 41233965Sjdp {"struct", s_struct, 0}, 41333965Sjdp/* tag */ 41433965Sjdp {"text", s_text, 0}, 41533965Sjdp 41633965Sjdp /* This is for gcc to use. It's only just been added (2/94), so gcc 41733965Sjdp won't be able to use it for a while -- probably a year or more. 41833965Sjdp But once this has been released, check with gcc maintainers 41933965Sjdp before deleting it or even changing the spelling. */ 42033965Sjdp {"this_GCC_requires_the_GNU_assembler", s_ignore, 0}, 42133965Sjdp /* If we're folding case -- done for some targets, not necessarily 42233965Sjdp all -- the above string in an input file will be converted to 42333965Sjdp this one. Match it either way... */ 42433965Sjdp {"this_gcc_requires_the_gnu_assembler", s_ignore, 0}, 42533965Sjdp 42633965Sjdp {"title", listing_title, 0}, /* Listing title */ 42733965Sjdp {"ttl", listing_title, 0}, 42833965Sjdp/* type */ 42938889Sjdp {"uleb128", s_leb128, 0}, 43033965Sjdp/* use */ 43133965Sjdp/* val */ 43233965Sjdp {"xcom", s_comm, 0}, 43333965Sjdp {"xdef", s_globl, 0}, 43433965Sjdp {"xref", s_ignore, 0}, 43533965Sjdp {"xstabs", s_xstab, 's'}, 43633965Sjdp {"word", cons, 2}, 43733965Sjdp {"zero", s_space, 0}, 43860484Sobrien {NULL, NULL, 0} /* end sentinel */ 43933965Sjdp}; 44033965Sjdp 44133965Sjdpstatic int pop_override_ok = 0; 44233965Sjdpstatic const char *pop_table_name; 44333965Sjdp 44433965Sjdpvoid 44533965Sjdppop_insert (table) 44633965Sjdp const pseudo_typeS *table; 44733965Sjdp{ 44833965Sjdp const char *errtxt; 44933965Sjdp const pseudo_typeS *pop; 45033965Sjdp for (pop = table; pop->poc_name; pop++) 45133965Sjdp { 45233965Sjdp errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop); 45333965Sjdp if (errtxt && (!pop_override_ok || strcmp (errtxt, "exists"))) 45460484Sobrien as_fatal (_("error constructing %s pseudo-op table: %s"), pop_table_name, 45533965Sjdp errtxt); 45633965Sjdp } 45733965Sjdp} 45833965Sjdp 45933965Sjdp#ifndef md_pop_insert 46033965Sjdp#define md_pop_insert() pop_insert(md_pseudo_table) 46133965Sjdp#endif 46233965Sjdp 46333965Sjdp#ifndef obj_pop_insert 46433965Sjdp#define obj_pop_insert() pop_insert(obj_pseudo_table) 46533965Sjdp#endif 46633965Sjdp 46733965Sjdpstatic void 46833965Sjdppobegin () 46933965Sjdp{ 47033965Sjdp po_hash = hash_new (); 47133965Sjdp 47233965Sjdp /* Do the target-specific pseudo ops. */ 47333965Sjdp pop_table_name = "md"; 47433965Sjdp md_pop_insert (); 47533965Sjdp 47633965Sjdp /* Now object specific. Skip any that were in the target table. */ 47733965Sjdp pop_table_name = "obj"; 47833965Sjdp pop_override_ok = 1; 47933965Sjdp obj_pop_insert (); 48033965Sjdp 48133965Sjdp /* Now portable ones. Skip any that we've seen already. */ 48233965Sjdp pop_table_name = "standard"; 48333965Sjdp pop_insert (potable); 48433965Sjdp} 48533965Sjdp 48633965Sjdp#define HANDLE_CONDITIONAL_ASSEMBLY() \ 48733965Sjdp if (ignore_input ()) \ 48833965Sjdp { \ 48933965Sjdp while (! is_end_of_line[(unsigned char) *input_line_pointer++]) \ 49033965Sjdp if (input_line_pointer == buffer_limit) \ 49133965Sjdp break; \ 49233965Sjdp continue; \ 49333965Sjdp } 49433965Sjdp 49533965Sjdp 49633965Sjdp/* This function is used when scrubbing the characters between #APP 49733965Sjdp and #NO_APP. */ 49833965Sjdp 49933965Sjdpstatic char *scrub_string; 50033965Sjdpstatic char *scrub_string_end; 50133965Sjdp 50233965Sjdpstatic int 50360484Sobrienscrub_from_string (buf, buflen) 50460484Sobrien char *buf; 50560484Sobrien int buflen; 50633965Sjdp{ 50760484Sobrien int copy; 50833965Sjdp 50960484Sobrien copy = scrub_string_end - scrub_string; 51060484Sobrien if (copy > buflen) 51160484Sobrien copy = buflen; 51260484Sobrien memcpy (buf, scrub_string, copy); 51360484Sobrien scrub_string += copy; 51460484Sobrien return copy; 51533965Sjdp} 51633965Sjdp 51733965Sjdp/* read_a_source_file() 51833965Sjdp * 51933965Sjdp * We read the file, putting things into a web that 52033965Sjdp * represents what we have been reading. 52133965Sjdp */ 52233965Sjdpvoid 52333965Sjdpread_a_source_file (name) 52433965Sjdp char *name; 52533965Sjdp{ 52633965Sjdp register char c; 52733965Sjdp register char *s; /* string of symbol, '\0' appended */ 52833965Sjdp register int temp; 52933965Sjdp pseudo_typeS *pop; 53033965Sjdp 53133965Sjdp buffer = input_scrub_new_file (name); 53233965Sjdp 53333965Sjdp listing_file (name); 53438889Sjdp listing_newline (NULL); 53538889Sjdp register_dependency (name); 53633965Sjdp 53760484Sobrien /* Generate debugging information before we've read anything in to denote 53860484Sobrien this file as the "main" source file and not a subordinate one 53960484Sobrien (e.g. N_SO vs N_SOL in stabs). */ 54060484Sobrien generate_file_debug (); 54160484Sobrien 54233965Sjdp while ((buffer_limit = input_scrub_next_buffer (&input_line_pointer)) != 0) 54333965Sjdp { /* We have another line to parse. */ 54433965Sjdp know (buffer_limit[-1] == '\n'); /* Must have a sentinel. */ 54533965Sjdp contin: /* JF this goto is my fault I admit it. 54633965Sjdp Someone brave please re-write the whole 54733965Sjdp input section here? Pleeze??? */ 54833965Sjdp while (input_line_pointer < buffer_limit) 54933965Sjdp { 55033965Sjdp /* We have more of this buffer to parse. */ 55133965Sjdp 55233965Sjdp /* 55333965Sjdp * We now have input_line_pointer->1st char of next line. 55433965Sjdp * If input_line_pointer [-1] == '\n' then we just 55533965Sjdp * scanned another line: so bump line counters. 55633965Sjdp */ 55733965Sjdp if (is_end_of_line[(unsigned char) input_line_pointer[-1]]) 55833965Sjdp { 55933965Sjdp#ifdef md_start_line_hook 56033965Sjdp md_start_line_hook (); 56133965Sjdp#endif 56233965Sjdp 56333965Sjdp if (input_line_pointer[-1] == '\n') 56433965Sjdp bump_line_counters (); 56533965Sjdp 56633965Sjdp line_label = NULL; 56733965Sjdp 56860484Sobrien if (LABELS_WITHOUT_COLONS || flag_m68k_mri) 56933965Sjdp { 57033965Sjdp /* Text at the start of a line must be a label, we 57133965Sjdp run down and stick a colon in. */ 57233965Sjdp if (is_name_beginner (*input_line_pointer)) 57333965Sjdp { 57433965Sjdp char *line_start = input_line_pointer; 57533965Sjdp char c; 57633965Sjdp int mri_line_macro; 57733965Sjdp 57833965Sjdp LISTING_NEWLINE (); 57933965Sjdp HANDLE_CONDITIONAL_ASSEMBLY (); 58033965Sjdp 58133965Sjdp c = get_symbol_end (); 58233965Sjdp 58333965Sjdp /* In MRI mode, the EQU and MACRO pseudoops must 58433965Sjdp be handled specially. */ 58533965Sjdp mri_line_macro = 0; 58633965Sjdp if (flag_m68k_mri) 58733965Sjdp { 58833965Sjdp char *rest = input_line_pointer + 1; 58933965Sjdp 59033965Sjdp if (*rest == ':') 59133965Sjdp ++rest; 59233965Sjdp if (*rest == ' ' || *rest == '\t') 59333965Sjdp ++rest; 59433965Sjdp if ((strncasecmp (rest, "EQU", 3) == 0 59533965Sjdp || strncasecmp (rest, "SET", 3) == 0) 59633965Sjdp && (rest[3] == ' ' || rest[3] == '\t')) 59733965Sjdp { 59833965Sjdp input_line_pointer = rest + 3; 59933965Sjdp equals (line_start, 60033965Sjdp strncasecmp (rest, "SET", 3) == 0); 60133965Sjdp continue; 60233965Sjdp } 60333965Sjdp if (strncasecmp (rest, "MACRO", 5) == 0 60433965Sjdp && (rest[5] == ' ' 60533965Sjdp || rest[5] == '\t' 60633965Sjdp || is_end_of_line[(unsigned char) rest[5]])) 60733965Sjdp mri_line_macro = 1; 60833965Sjdp } 60933965Sjdp 61033965Sjdp /* In MRI mode, we need to handle the MACRO 61133965Sjdp pseudo-op specially: we don't want to put the 61233965Sjdp symbol in the symbol table. */ 61360484Sobrien if (! mri_line_macro 61460484Sobrien#ifdef TC_START_LABEL_WITHOUT_COLON 61560484Sobrien && TC_START_LABEL_WITHOUT_COLON(c, 61660484Sobrien input_line_pointer) 61760484Sobrien#endif 61860484Sobrien ) 61933965Sjdp line_label = colon (line_start); 62033965Sjdp else 62133965Sjdp line_label = symbol_create (line_start, 62233965Sjdp absolute_section, 62333965Sjdp (valueT) 0, 62433965Sjdp &zero_address_frag); 62533965Sjdp 62633965Sjdp *input_line_pointer = c; 62733965Sjdp if (c == ':') 62833965Sjdp input_line_pointer++; 62933965Sjdp } 63033965Sjdp } 63133965Sjdp } 63233965Sjdp 63333965Sjdp /* 63433965Sjdp * We are at the begining of a line, or similar place. 63533965Sjdp * We expect a well-formed assembler statement. 63633965Sjdp * A "symbol-name:" is a statement. 63733965Sjdp * 63833965Sjdp * Depending on what compiler is used, the order of these tests 63933965Sjdp * may vary to catch most common case 1st. 64033965Sjdp * Each test is independent of all other tests at the (top) level. 64133965Sjdp * PLEASE make a compiler that doesn't use this assembler. 64233965Sjdp * It is crufty to waste a compiler's time encoding things for this 64333965Sjdp * assembler, which then wastes more time decoding it. 64433965Sjdp * (And communicating via (linear) files is silly! 64533965Sjdp * If you must pass stuff, please pass a tree!) 64633965Sjdp */ 64733965Sjdp if ((c = *input_line_pointer++) == '\t' 64833965Sjdp || c == ' ' 64933965Sjdp || c == '\f' 65033965Sjdp || c == 0) 65133965Sjdp { 65233965Sjdp c = *input_line_pointer++; 65333965Sjdp } 65433965Sjdp know (c != ' '); /* No further leading whitespace. */ 65538889Sjdp 65638889Sjdp#ifndef NO_LISTING 65738889Sjdp /* If listing is on, and we are expanding a macro, then give 65838889Sjdp the listing code the contents of the expanded line. */ 65938889Sjdp if (listing) 66038889Sjdp { 66138889Sjdp if ((listing & LISTING_MACEXP) && macro_nest > 0) 66238889Sjdp { 66338889Sjdp char *copy; 66438889Sjdp int len; 66538889Sjdp 66638889Sjdp /* Find the end of the current expanded macro line. */ 66738889Sjdp for (s = input_line_pointer-1; *s ; ++s) 66838889Sjdp if (is_end_of_line[(unsigned char) *s]) 66938889Sjdp break; 67038889Sjdp 67138889Sjdp /* Copy it for safe keeping. Also give an indication of 67238889Sjdp how much macro nesting is involved at this point. */ 67338889Sjdp len = s - (input_line_pointer-1); 67438889Sjdp copy = (char *) xmalloc (len + macro_nest + 2); 67538889Sjdp memset (copy, '>', macro_nest); 67638889Sjdp copy[macro_nest] = ' '; 67738889Sjdp memcpy (copy + macro_nest + 1, input_line_pointer-1, len); 67838889Sjdp copy[macro_nest+1+len] = '\0'; 67938889Sjdp 68038889Sjdp /* Install the line with the listing facility. */ 68138889Sjdp listing_newline (copy); 68238889Sjdp } 68338889Sjdp else 68438889Sjdp listing_newline (NULL); 68538889Sjdp } 68638889Sjdp#endif 68738889Sjdp 68833965Sjdp /* 68933965Sjdp * C is the 1st significant character. 69033965Sjdp * Input_line_pointer points after that character. 69133965Sjdp */ 69233965Sjdp if (is_name_beginner (c)) 69333965Sjdp { 69433965Sjdp /* want user-defined label or pseudo/opcode */ 69533965Sjdp HANDLE_CONDITIONAL_ASSEMBLY (); 69633965Sjdp 69733965Sjdp s = --input_line_pointer; 69833965Sjdp c = get_symbol_end (); /* name's delimiter */ 69933965Sjdp /* 70033965Sjdp * C is character after symbol. 70133965Sjdp * That character's place in the input line is now '\0'. 70233965Sjdp * S points to the beginning of the symbol. 70333965Sjdp * [In case of pseudo-op, s->'.'.] 70433965Sjdp * Input_line_pointer->'\0' where c was. 70533965Sjdp */ 70633965Sjdp if (TC_START_LABEL(c, input_line_pointer)) 70733965Sjdp { 70833965Sjdp if (flag_m68k_mri) 70933965Sjdp { 71033965Sjdp char *rest = input_line_pointer + 1; 71133965Sjdp 71233965Sjdp /* In MRI mode, \tsym: set 0 is permitted. */ 71333965Sjdp 71433965Sjdp if (*rest == ':') 71533965Sjdp ++rest; 71633965Sjdp if (*rest == ' ' || *rest == '\t') 71733965Sjdp ++rest; 71833965Sjdp if ((strncasecmp (rest, "EQU", 3) == 0 71933965Sjdp || strncasecmp (rest, "SET", 3) == 0) 72033965Sjdp && (rest[3] == ' ' || rest[3] == '\t')) 72133965Sjdp { 72233965Sjdp input_line_pointer = rest + 3; 72333965Sjdp equals (s, 1); 72433965Sjdp continue; 72533965Sjdp } 72633965Sjdp } 72733965Sjdp 72833965Sjdp line_label = colon (s); /* user-defined label */ 72933965Sjdp *input_line_pointer++ = ':'; /* Put ':' back for error messages' sake. */ 73033965Sjdp /* Input_line_pointer->after ':'. */ 73133965Sjdp SKIP_WHITESPACE (); 73233965Sjdp 73333965Sjdp 73433965Sjdp } 73533965Sjdp else if (c == '=' 73633965Sjdp || ((c == ' ' || c == '\t') 73733965Sjdp && input_line_pointer[1] == '=' 73833965Sjdp#ifdef TC_EQUAL_IN_INSN 73933965Sjdp && ! TC_EQUAL_IN_INSN (c, input_line_pointer) 74033965Sjdp#endif 74133965Sjdp )) 74233965Sjdp { 74333965Sjdp equals (s, 1); 74433965Sjdp demand_empty_rest_of_line (); 74533965Sjdp } 74633965Sjdp else 74733965Sjdp { /* expect pseudo-op or machine instruction */ 74833965Sjdp pop = NULL; 74933965Sjdp 75033965Sjdp#define IGNORE_OPCODE_CASE 75133965Sjdp#ifdef IGNORE_OPCODE_CASE 75233965Sjdp { 75333965Sjdp char *s2 = s; 75433965Sjdp while (*s2) 75533965Sjdp { 75638889Sjdp if (isupper ((unsigned char) *s2)) 75733965Sjdp *s2 = tolower (*s2); 75833965Sjdp s2++; 75933965Sjdp } 76033965Sjdp } 76133965Sjdp#endif 76233965Sjdp 76360484Sobrien if (NO_PSEUDO_DOT || flag_m68k_mri) 76433965Sjdp { 76533965Sjdp /* The MRI assembler and the m88k use pseudo-ops 76633965Sjdp without a period. */ 76733965Sjdp pop = (pseudo_typeS *) hash_find (po_hash, s); 76833965Sjdp if (pop != NULL && pop->poc_handler == NULL) 76933965Sjdp pop = NULL; 77033965Sjdp } 77133965Sjdp 77233965Sjdp if (pop != NULL 77333965Sjdp || (! flag_m68k_mri && *s == '.')) 77433965Sjdp { 77533965Sjdp /* 77633965Sjdp * PSEUDO - OP. 77733965Sjdp * 77833965Sjdp * WARNING: c has next char, which may be end-of-line. 77933965Sjdp * We lookup the pseudo-op table with s+1 because we 78033965Sjdp * already know that the pseudo-op begins with a '.'. 78133965Sjdp */ 78233965Sjdp 78333965Sjdp if (pop == NULL) 78433965Sjdp pop = (pseudo_typeS *) hash_find (po_hash, s + 1); 78533965Sjdp 78633965Sjdp /* In MRI mode, we may need to insert an 78733965Sjdp automatic alignment directive. What a hack 78833965Sjdp this is. */ 78933965Sjdp if (mri_pending_align 79033965Sjdp && (pop == NULL 79133965Sjdp || ! ((pop->poc_handler == cons 79233965Sjdp && pop->poc_val == 1) 79333965Sjdp || (pop->poc_handler == s_space 79433965Sjdp && pop->poc_val == 1) 79533965Sjdp#ifdef tc_conditional_pseudoop 79633965Sjdp || tc_conditional_pseudoop (pop) 79733965Sjdp#endif 79833965Sjdp || pop->poc_handler == s_if 79933965Sjdp || pop->poc_handler == s_ifdef 80033965Sjdp || pop->poc_handler == s_ifc 80133965Sjdp || pop->poc_handler == s_ifeqs 80233965Sjdp || pop->poc_handler == s_else 80333965Sjdp || pop->poc_handler == s_endif 80433965Sjdp || pop->poc_handler == s_globl 80533965Sjdp || pop->poc_handler == s_ignore))) 80633965Sjdp { 80733965Sjdp do_align (1, (char *) NULL, 0, 0); 80833965Sjdp mri_pending_align = 0; 80933965Sjdp if (line_label != NULL) 81033965Sjdp { 81160484Sobrien symbol_set_frag (line_label, frag_now); 81233965Sjdp S_SET_VALUE (line_label, frag_now_fix ()); 81333965Sjdp } 81433965Sjdp } 81533965Sjdp 81633965Sjdp /* Print the error msg now, while we still can */ 81733965Sjdp if (pop == NULL) 81833965Sjdp { 81960484Sobrien as_bad (_("Unknown pseudo-op: `%s'"), s); 82033965Sjdp *input_line_pointer = c; 82133965Sjdp s_ignore (0); 82233965Sjdp continue; 82333965Sjdp } 82433965Sjdp 82533965Sjdp /* Put it back for error messages etc. */ 82633965Sjdp *input_line_pointer = c; 82733965Sjdp /* The following skip of whitespace is compulsory. 82833965Sjdp A well shaped space is sometimes all that separates 82933965Sjdp keyword from operands. */ 83033965Sjdp if (c == ' ' || c == '\t') 83133965Sjdp input_line_pointer++; 83233965Sjdp /* 83333965Sjdp * Input_line is restored. 83433965Sjdp * Input_line_pointer->1st non-blank char 83533965Sjdp * after pseudo-operation. 83633965Sjdp */ 83733965Sjdp (*pop->poc_handler) (pop->poc_val); 83833965Sjdp 83933965Sjdp /* If that was .end, just get out now. */ 84033965Sjdp if (pop->poc_handler == s_end) 84133965Sjdp goto quit; 84233965Sjdp } 84333965Sjdp else 84433965Sjdp { 84533965Sjdp int inquote = 0; 84660484Sobrien#ifdef QUOTES_IN_INSN 84760484Sobrien int inescape = 0; 84860484Sobrien#endif 84933965Sjdp 85033965Sjdp /* WARNING: c has char, which may be end-of-line. */ 85133965Sjdp /* Also: input_line_pointer->`\0` where c was. */ 85233965Sjdp *input_line_pointer = c; 85333965Sjdp while (!is_end_of_line[(unsigned char) *input_line_pointer] 85433965Sjdp || inquote 85533965Sjdp#ifdef TC_EOL_IN_INSN 85633965Sjdp || TC_EOL_IN_INSN (input_line_pointer) 85733965Sjdp#endif 85833965Sjdp ) 85933965Sjdp { 86033965Sjdp if (flag_m68k_mri && *input_line_pointer == '\'') 86133965Sjdp inquote = ! inquote; 86260484Sobrien#ifdef QUOTES_IN_INSN 86360484Sobrien if (inescape) 86460484Sobrien inescape = 0; 86560484Sobrien else if (*input_line_pointer == '"') 86660484Sobrien inquote = ! inquote; 86760484Sobrien else if (*input_line_pointer == '\\') 86860484Sobrien inescape = 1; 86960484Sobrien#endif 87033965Sjdp input_line_pointer++; 87133965Sjdp } 87233965Sjdp 87333965Sjdp c = *input_line_pointer; 87433965Sjdp *input_line_pointer = '\0'; 87533965Sjdp 87660484Sobrien generate_lineno_debug (); 87738889Sjdp 87833965Sjdp if (macro_defined) 87933965Sjdp { 88033965Sjdp sb out; 88133965Sjdp const char *err; 88260484Sobrien macro_entry *macro; 88333965Sjdp 88460484Sobrien if (check_macro (s, &out, '\0', &err, ¯o)) 88533965Sjdp { 88633965Sjdp if (err != NULL) 88760484Sobrien as_bad ("%s", err); 88833965Sjdp *input_line_pointer++ = c; 88933965Sjdp input_scrub_include_sb (&out, 89060484Sobrien input_line_pointer, 1); 89133965Sjdp sb_kill (&out); 89233965Sjdp buffer_limit = 89333965Sjdp input_scrub_next_buffer (&input_line_pointer); 89460484Sobrien#ifdef md_macro_info 89560484Sobrien md_macro_info (macro); 89660484Sobrien#endif 89733965Sjdp continue; 89833965Sjdp } 89933965Sjdp } 90033965Sjdp 90133965Sjdp if (mri_pending_align) 90233965Sjdp { 90333965Sjdp do_align (1, (char *) NULL, 0, 0); 90433965Sjdp mri_pending_align = 0; 90533965Sjdp if (line_label != NULL) 90633965Sjdp { 90760484Sobrien symbol_set_frag (line_label, frag_now); 90833965Sjdp S_SET_VALUE (line_label, frag_now_fix ()); 90933965Sjdp } 91033965Sjdp } 91133965Sjdp 91233965Sjdp md_assemble (s); /* Assemble 1 instruction. */ 91333965Sjdp 91433965Sjdp *input_line_pointer++ = c; 91533965Sjdp 91633965Sjdp /* We resume loop AFTER the end-of-line from 91733965Sjdp this instruction. */ 91833965Sjdp } /* if (*s=='.') */ 91933965Sjdp } /* if c==':' */ 92033965Sjdp continue; 92133965Sjdp } /* if (is_name_beginner(c) */ 92233965Sjdp 92333965Sjdp 92433965Sjdp /* Empty statement? */ 92533965Sjdp if (is_end_of_line[(unsigned char) c]) 92633965Sjdp continue; 92733965Sjdp 92833965Sjdp if ((LOCAL_LABELS_DOLLAR || LOCAL_LABELS_FB) 92938889Sjdp && isdigit ((unsigned char) c)) 93033965Sjdp { 93133965Sjdp /* local label ("4:") */ 93233965Sjdp char *backup = input_line_pointer; 93333965Sjdp 93433965Sjdp HANDLE_CONDITIONAL_ASSEMBLY (); 93533965Sjdp 93633965Sjdp temp = c - '0'; 93733965Sjdp 93838889Sjdp while (isdigit ((unsigned char) *input_line_pointer)) 93933965Sjdp { 94033965Sjdp temp = (temp * 10) + *input_line_pointer - '0'; 94133965Sjdp ++input_line_pointer; 94233965Sjdp } /* read the whole number */ 94333965Sjdp 94433965Sjdp if (LOCAL_LABELS_DOLLAR 94533965Sjdp && *input_line_pointer == '$' 94633965Sjdp && *(input_line_pointer + 1) == ':') 94733965Sjdp { 94833965Sjdp input_line_pointer += 2; 94933965Sjdp 95033965Sjdp if (dollar_label_defined (temp)) 95133965Sjdp { 95260484Sobrien as_fatal (_("label \"%d$\" redefined"), temp); 95333965Sjdp } 95433965Sjdp 95533965Sjdp define_dollar_label (temp); 95633965Sjdp colon (dollar_label_name (temp, 0)); 95733965Sjdp continue; 95833965Sjdp } 95933965Sjdp 96033965Sjdp if (LOCAL_LABELS_FB 96133965Sjdp && *input_line_pointer++ == ':') 96233965Sjdp { 96333965Sjdp fb_label_instance_inc (temp); 96433965Sjdp colon (fb_label_name (temp, 0)); 96533965Sjdp continue; 96633965Sjdp } 96733965Sjdp 96833965Sjdp input_line_pointer = backup; 96933965Sjdp } /* local label ("4:") */ 97033965Sjdp 97133965Sjdp if (c && strchr (line_comment_chars, c)) 97233965Sjdp { /* Its a comment. Better say APP or NO_APP */ 97333965Sjdp char *ends; 97433965Sjdp char *new_buf; 97533965Sjdp char *new_tmp; 97633965Sjdp unsigned int new_length; 97733965Sjdp char *tmp_buf = 0; 97833965Sjdp 97933965Sjdp bump_line_counters (); 98033965Sjdp s = input_line_pointer; 98133965Sjdp if (strncmp (s, "APP\n", 4)) 98233965Sjdp continue; /* We ignore it */ 98333965Sjdp s += 4; 98433965Sjdp 98533965Sjdp ends = strstr (s, "#NO_APP\n"); 98633965Sjdp 98733965Sjdp if (!ends) 98833965Sjdp { 98933965Sjdp unsigned int tmp_len; 99033965Sjdp unsigned int num; 99133965Sjdp 99233965Sjdp /* The end of the #APP wasn't in this buffer. We 99333965Sjdp keep reading in buffers until we find the #NO_APP 99433965Sjdp that goes with this #APP There is one. The specs 99533965Sjdp guarentee it. . . */ 99633965Sjdp tmp_len = buffer_limit - s; 99733965Sjdp tmp_buf = xmalloc (tmp_len + 1); 99833965Sjdp memcpy (tmp_buf, s, tmp_len); 99933965Sjdp do 100033965Sjdp { 100133965Sjdp new_tmp = input_scrub_next_buffer (&buffer); 100233965Sjdp if (!new_tmp) 100333965Sjdp break; 100433965Sjdp else 100533965Sjdp buffer_limit = new_tmp; 100633965Sjdp input_line_pointer = buffer; 100733965Sjdp ends = strstr (buffer, "#NO_APP\n"); 100833965Sjdp if (ends) 100933965Sjdp num = ends - buffer; 101033965Sjdp else 101133965Sjdp num = buffer_limit - buffer; 101233965Sjdp 101333965Sjdp tmp_buf = xrealloc (tmp_buf, tmp_len + num); 101433965Sjdp memcpy (tmp_buf + tmp_len, buffer, num); 101533965Sjdp tmp_len += num; 101633965Sjdp } 101733965Sjdp while (!ends); 101833965Sjdp 101933965Sjdp input_line_pointer = ends ? ends + 8 : NULL; 102033965Sjdp 102133965Sjdp s = tmp_buf; 102233965Sjdp ends = s + tmp_len; 102333965Sjdp 102433965Sjdp } 102533965Sjdp else 102633965Sjdp { 102733965Sjdp input_line_pointer = ends + 8; 102833965Sjdp } 102933965Sjdp 103033965Sjdp scrub_string = s; 103133965Sjdp scrub_string_end = ends; 103233965Sjdp 103333965Sjdp new_length = ends - s; 103433965Sjdp new_buf = (char *) xmalloc (new_length); 103533965Sjdp new_tmp = new_buf; 103633965Sjdp for (;;) 103733965Sjdp { 103833965Sjdp int space; 103933965Sjdp int size; 104033965Sjdp 104133965Sjdp space = (new_buf + new_length) - new_tmp; 104233965Sjdp size = do_scrub_chars (scrub_from_string, new_tmp, space); 104333965Sjdp 104433965Sjdp if (size < space) 104533965Sjdp { 104633965Sjdp new_tmp += size; 104733965Sjdp break; 104833965Sjdp } 104933965Sjdp 105033965Sjdp new_buf = xrealloc (new_buf, new_length + 100); 105133965Sjdp new_tmp = new_buf + new_length; 105233965Sjdp new_length += 100; 105333965Sjdp } 105433965Sjdp 105533965Sjdp if (tmp_buf) 105633965Sjdp free (tmp_buf); 105733965Sjdp old_buffer = buffer; 105833965Sjdp old_input = input_line_pointer; 105933965Sjdp old_limit = buffer_limit; 106033965Sjdp buffer = new_buf; 106133965Sjdp input_line_pointer = new_buf; 106233965Sjdp buffer_limit = new_tmp; 106333965Sjdp continue; 106433965Sjdp } 106533965Sjdp 106633965Sjdp HANDLE_CONDITIONAL_ASSEMBLY (); 106733965Sjdp 106833965Sjdp#ifdef tc_unrecognized_line 106933965Sjdp if (tc_unrecognized_line (c)) 107033965Sjdp continue; 107133965Sjdp#endif 107233965Sjdp 107333965Sjdp /* as_warn("Junk character %d.",c); Now done by ignore_rest */ 107433965Sjdp input_line_pointer--; /* Report unknown char as ignored. */ 107533965Sjdp ignore_rest_of_line (); 107633965Sjdp } /* while (input_line_pointer<buffer_limit) */ 107733965Sjdp 107833965Sjdp#ifdef md_after_pass_hook 107933965Sjdp md_after_pass_hook (); 108033965Sjdp#endif 108133965Sjdp 108233965Sjdp if (old_buffer) 108333965Sjdp { 108433965Sjdp free (buffer); 108533965Sjdp bump_line_counters (); 108633965Sjdp if (old_input != 0) 108733965Sjdp { 108833965Sjdp buffer = old_buffer; 108933965Sjdp input_line_pointer = old_input; 109033965Sjdp buffer_limit = old_limit; 109133965Sjdp old_buffer = 0; 109233965Sjdp goto contin; 109333965Sjdp } 109433965Sjdp } 109533965Sjdp } /* while (more buffers to scan) */ 109633965Sjdp 109733965Sjdp quit: 109833965Sjdp 109933965Sjdp#ifdef md_cleanup 110033965Sjdp md_cleanup(); 110133965Sjdp#endif 110233965Sjdp input_scrub_close (); /* Close the input file */ 110333965Sjdp} 110433965Sjdp 110533965Sjdp/* For most MRI pseudo-ops, the line actually ends at the first 110633965Sjdp nonquoted space. This function looks for that point, stuffs a null 110733965Sjdp in, and sets *STOPCP to the character that used to be there, and 110833965Sjdp returns the location. 110933965Sjdp 111033965Sjdp Until I hear otherwise, I am going to assume that this is only true 111133965Sjdp for the m68k MRI assembler. */ 111233965Sjdp 111333965Sjdpchar * 111433965Sjdpmri_comment_field (stopcp) 111533965Sjdp char *stopcp; 111633965Sjdp{ 111733965Sjdp#ifdef TC_M68K 111833965Sjdp 111933965Sjdp char *s; 112033965Sjdp int inquote = 0; 112133965Sjdp 112233965Sjdp know (flag_m68k_mri); 112333965Sjdp 112433965Sjdp for (s = input_line_pointer; 112533965Sjdp ((! is_end_of_line[(unsigned char) *s] && *s != ' ' && *s != '\t') 112633965Sjdp || inquote); 112733965Sjdp s++) 112833965Sjdp { 112933965Sjdp if (*s == '\'') 113033965Sjdp inquote = ! inquote; 113133965Sjdp } 113233965Sjdp *stopcp = *s; 113333965Sjdp *s = '\0'; 113433965Sjdp return s; 113533965Sjdp 113633965Sjdp#else 113733965Sjdp 113833965Sjdp char *s; 113933965Sjdp 114033965Sjdp for (s = input_line_pointer; ! is_end_of_line[(unsigned char) *s]; s++) 114133965Sjdp ; 114233965Sjdp *stopcp = *s; 114333965Sjdp *s = '\0'; 114433965Sjdp return s; 114533965Sjdp 114633965Sjdp#endif 114733965Sjdp 114833965Sjdp} 114933965Sjdp 115033965Sjdp/* Skip to the end of an MRI comment field. */ 115133965Sjdp 115233965Sjdpvoid 115333965Sjdpmri_comment_end (stop, stopc) 115433965Sjdp char *stop; 115533965Sjdp int stopc; 115633965Sjdp{ 115733965Sjdp know (flag_mri); 115833965Sjdp 115933965Sjdp input_line_pointer = stop; 116033965Sjdp *stop = stopc; 116133965Sjdp while (! is_end_of_line[(unsigned char) *input_line_pointer]) 116233965Sjdp ++input_line_pointer; 116333965Sjdp} 116433965Sjdp 116533965Sjdpvoid 116633965Sjdps_abort (ignore) 116760484Sobrien int ignore ATTRIBUTE_UNUSED; 116833965Sjdp{ 116960484Sobrien as_fatal (_(".abort detected. Abandoning ship.")); 117033965Sjdp} 117133965Sjdp 117233965Sjdp/* Guts of .align directive. N is the power of two to which to align. 117333965Sjdp FILL may be NULL, or it may point to the bytes of the fill pattern. 117433965Sjdp LEN is the length of whatever FILL points to, if anything. MAX is 117533965Sjdp the maximum number of characters to skip when doing the alignment, 117633965Sjdp or 0 if there is no maximum. */ 117733965Sjdp 117833965Sjdpstatic void 117933965Sjdpdo_align (n, fill, len, max) 118033965Sjdp int n; 118133965Sjdp char *fill; 118233965Sjdp int len; 118333965Sjdp int max; 118433965Sjdp{ 118533965Sjdp char default_fill; 118633965Sjdp 118733965Sjdp#ifdef md_do_align 118833965Sjdp md_do_align (n, fill, len, max, just_record_alignment); 118933965Sjdp#endif 119033965Sjdp 119133965Sjdp if (fill == NULL) 119233965Sjdp { 119360484Sobrien if (subseg_text_p (now_seg)) 119433965Sjdp default_fill = NOP_OPCODE; 119533965Sjdp else 119633965Sjdp default_fill = 0; 119733965Sjdp fill = &default_fill; 119833965Sjdp len = 1; 119933965Sjdp } 120033965Sjdp 120133965Sjdp /* Only make a frag if we HAVE to. . . */ 120233965Sjdp if (n != 0 && !need_pass_2) 120333965Sjdp { 120433965Sjdp if (len <= 1) 120533965Sjdp frag_align (n, *fill, max); 120633965Sjdp else 120733965Sjdp frag_align_pattern (n, fill, len, max); 120833965Sjdp } 120933965Sjdp 121033965Sjdp#ifdef md_do_align 121133965Sjdp just_record_alignment: 121233965Sjdp#endif 121333965Sjdp 121460484Sobrien record_alignment (now_seg, n - OCTETS_PER_BYTE_POWER); 121533965Sjdp} 121633965Sjdp 121733965Sjdp/* Handle the .align pseudo-op. A positive ARG is a default alignment 121833965Sjdp (in bytes). A negative ARG is the negative of the length of the 121933965Sjdp fill pattern. BYTES_P is non-zero if the alignment value should be 122033965Sjdp interpreted as the byte boundary, rather than the power of 2. */ 122133965Sjdp 122233965Sjdpstatic void 122333965Sjdps_align (arg, bytes_p) 122433965Sjdp int arg; 122533965Sjdp int bytes_p; 122633965Sjdp{ 122733965Sjdp register unsigned int align; 122833965Sjdp char *stop = NULL; 122933965Sjdp char stopc; 123033965Sjdp offsetT fill = 0; 123133965Sjdp int max; 123233965Sjdp int fill_p; 123333965Sjdp 123433965Sjdp if (flag_mri) 123533965Sjdp stop = mri_comment_field (&stopc); 123633965Sjdp 123733965Sjdp if (is_end_of_line[(unsigned char) *input_line_pointer]) 123833965Sjdp { 123933965Sjdp if (arg < 0) 124033965Sjdp align = 0; 124133965Sjdp else 124233965Sjdp align = arg; /* Default value from pseudo-op table */ 124333965Sjdp } 124433965Sjdp else 124533965Sjdp { 124633965Sjdp align = get_absolute_expression (); 124733965Sjdp SKIP_WHITESPACE (); 124833965Sjdp } 124933965Sjdp 125033965Sjdp if (bytes_p) 125133965Sjdp { 125233965Sjdp /* Convert to a power of 2. */ 125333965Sjdp if (align != 0) 125433965Sjdp { 125533965Sjdp unsigned int i; 125633965Sjdp 125733965Sjdp for (i = 0; (align & 1) == 0; align >>= 1, ++i) 125833965Sjdp ; 125933965Sjdp if (align != 1) 126060484Sobrien as_bad (_("Alignment not a power of 2")); 126133965Sjdp align = i; 126233965Sjdp } 126333965Sjdp } 126433965Sjdp 126533965Sjdp if (align > 15) 126633965Sjdp { 126733965Sjdp align = 15; 126860484Sobrien as_bad (_("Alignment too large: %u assumed"), align); 126933965Sjdp } 127033965Sjdp 127133965Sjdp if (*input_line_pointer != ',') 127233965Sjdp { 127333965Sjdp fill_p = 0; 127433965Sjdp max = 0; 127533965Sjdp } 127633965Sjdp else 127733965Sjdp { 127833965Sjdp ++input_line_pointer; 127933965Sjdp if (*input_line_pointer == ',') 128033965Sjdp fill_p = 0; 128133965Sjdp else 128233965Sjdp { 128333965Sjdp fill = get_absolute_expression (); 128433965Sjdp SKIP_WHITESPACE (); 128533965Sjdp fill_p = 1; 128633965Sjdp } 128733965Sjdp 128833965Sjdp if (*input_line_pointer != ',') 128933965Sjdp max = 0; 129033965Sjdp else 129133965Sjdp { 129233965Sjdp ++input_line_pointer; 129333965Sjdp max = get_absolute_expression (); 129433965Sjdp } 129533965Sjdp } 129633965Sjdp 129733965Sjdp if (! fill_p) 129833965Sjdp { 129933965Sjdp if (arg < 0) 130060484Sobrien as_warn (_("expected fill pattern missing")); 130133965Sjdp do_align (align, (char *) NULL, 0, max); 130233965Sjdp } 130333965Sjdp else 130433965Sjdp { 130533965Sjdp int fill_len; 130633965Sjdp 130733965Sjdp if (arg >= 0) 130833965Sjdp fill_len = 1; 130933965Sjdp else 131033965Sjdp fill_len = - arg; 131133965Sjdp if (fill_len <= 1) 131233965Sjdp { 131333965Sjdp char fill_char; 131433965Sjdp 131533965Sjdp fill_char = fill; 131633965Sjdp do_align (align, &fill_char, fill_len, max); 131733965Sjdp } 131833965Sjdp else 131933965Sjdp { 132033965Sjdp char ab[16]; 132133965Sjdp 132238889Sjdp if ((size_t) fill_len > sizeof ab) 132333965Sjdp abort (); 132433965Sjdp md_number_to_chars (ab, fill, fill_len); 132533965Sjdp do_align (align, ab, fill_len, max); 132633965Sjdp } 132733965Sjdp } 132833965Sjdp 132960484Sobrien demand_empty_rest_of_line (); 133060484Sobrien 133133965Sjdp if (flag_mri) 133233965Sjdp mri_comment_end (stop, stopc); 133333965Sjdp} 133433965Sjdp 133533965Sjdp/* Handle the .align pseudo-op on machines where ".align 4" means 133633965Sjdp align to a 4 byte boundary. */ 133733965Sjdp 133833965Sjdpvoid 133933965Sjdps_align_bytes (arg) 134033965Sjdp int arg; 134133965Sjdp{ 134233965Sjdp s_align (arg, 1); 134333965Sjdp} 134433965Sjdp 134538889Sjdp/* Handle the .align pseudo-op on machines where ".align 4" means align 134633965Sjdp to a 2**4 boundary. */ 134733965Sjdp 134833965Sjdpvoid 134933965Sjdps_align_ptwo (arg) 135033965Sjdp int arg; 135133965Sjdp{ 135233965Sjdp s_align (arg, 0); 135333965Sjdp} 135433965Sjdp 135533965Sjdpvoid 135633965Sjdps_comm (ignore) 135760484Sobrien int ignore ATTRIBUTE_UNUSED; 135833965Sjdp{ 135933965Sjdp register char *name; 136033965Sjdp register char c; 136133965Sjdp register char *p; 136233965Sjdp offsetT temp; 136333965Sjdp register symbolS *symbolP; 136433965Sjdp char *stop = NULL; 136533965Sjdp char stopc; 136633965Sjdp 136733965Sjdp if (flag_mri) 136833965Sjdp stop = mri_comment_field (&stopc); 136933965Sjdp 137033965Sjdp name = input_line_pointer; 137133965Sjdp c = get_symbol_end (); 137233965Sjdp /* just after name is now '\0' */ 137333965Sjdp p = input_line_pointer; 137433965Sjdp *p = c; 137533965Sjdp SKIP_WHITESPACE (); 137633965Sjdp if (*input_line_pointer != ',') 137733965Sjdp { 137860484Sobrien as_bad (_("Expected comma after symbol-name: rest of line ignored.")); 137960484Sobrien ignore_rest_of_line (); 138033965Sjdp if (flag_mri) 138133965Sjdp mri_comment_end (stop, stopc); 138233965Sjdp return; 138333965Sjdp } 138433965Sjdp input_line_pointer++; /* skip ',' */ 138533965Sjdp if ((temp = get_absolute_expression ()) < 0) 138633965Sjdp { 138760484Sobrien as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp); 138860484Sobrien ignore_rest_of_line (); 138933965Sjdp if (flag_mri) 139033965Sjdp mri_comment_end (stop, stopc); 139133965Sjdp return; 139233965Sjdp } 139333965Sjdp *p = 0; 139433965Sjdp symbolP = symbol_find_or_make (name); 139533965Sjdp *p = c; 139633965Sjdp if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP)) 139733965Sjdp { 139860484Sobrien as_bad (_("Ignoring attempt to re-define symbol `%s'."), 139933965Sjdp S_GET_NAME (symbolP)); 140060484Sobrien ignore_rest_of_line (); 140133965Sjdp if (flag_mri) 140233965Sjdp mri_comment_end (stop, stopc); 140333965Sjdp return; 140433965Sjdp } 140533965Sjdp if (S_GET_VALUE (symbolP)) 140633965Sjdp { 140733965Sjdp if (S_GET_VALUE (symbolP) != (valueT) temp) 140860484Sobrien as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."), 140933965Sjdp S_GET_NAME (symbolP), 141033965Sjdp (long) S_GET_VALUE (symbolP), 141133965Sjdp (long) temp); 141233965Sjdp } 141333965Sjdp else 141433965Sjdp { 141533965Sjdp S_SET_VALUE (symbolP, (valueT) temp); 141633965Sjdp S_SET_EXTERNAL (symbolP); 141733965Sjdp } 141833965Sjdp#ifdef OBJ_VMS 141933965Sjdp { 142033965Sjdp extern int flag_one; 142133965Sjdp if ( (!temp) || !flag_one) 142233965Sjdp S_GET_OTHER(symbolP) = const_flag; 142333965Sjdp } 142433965Sjdp#endif /* not OBJ_VMS */ 142533965Sjdp know (symbolP->sy_frag == &zero_address_frag); 142633965Sjdp 142760484Sobrien demand_empty_rest_of_line (); 142860484Sobrien 142933965Sjdp if (flag_mri) 143033965Sjdp mri_comment_end (stop, stopc); 143133965Sjdp} /* s_comm() */ 143233965Sjdp 143333965Sjdp/* The MRI COMMON pseudo-op. We handle this by creating a common 143433965Sjdp symbol with the appropriate name. We make s_space do the right 143533965Sjdp thing by increasing the size. */ 143633965Sjdp 143733965Sjdpvoid 143833965Sjdps_mri_common (small) 143960484Sobrien int small ATTRIBUTE_UNUSED; 144033965Sjdp{ 144133965Sjdp char *name; 144233965Sjdp char c; 144333965Sjdp char *alc = NULL; 144433965Sjdp symbolS *sym; 144533965Sjdp offsetT align; 144633965Sjdp char *stop = NULL; 144733965Sjdp char stopc; 144833965Sjdp 144933965Sjdp if (! flag_mri) 145033965Sjdp { 145133965Sjdp s_comm (0); 145233965Sjdp return; 145333965Sjdp } 145433965Sjdp 145533965Sjdp stop = mri_comment_field (&stopc); 145633965Sjdp 145733965Sjdp SKIP_WHITESPACE (); 145833965Sjdp 145933965Sjdp name = input_line_pointer; 146033965Sjdp if (! isdigit ((unsigned char) *name)) 146133965Sjdp c = get_symbol_end (); 146233965Sjdp else 146333965Sjdp { 146433965Sjdp do 146533965Sjdp { 146633965Sjdp ++input_line_pointer; 146733965Sjdp } 146833965Sjdp while (isdigit ((unsigned char) *input_line_pointer)); 146933965Sjdp c = *input_line_pointer; 147033965Sjdp *input_line_pointer = '\0'; 147133965Sjdp 147233965Sjdp if (line_label != NULL) 147333965Sjdp { 147433965Sjdp alc = (char *) xmalloc (strlen (S_GET_NAME (line_label)) 147533965Sjdp + (input_line_pointer - name) 147633965Sjdp + 1); 147733965Sjdp sprintf (alc, "%s%s", name, S_GET_NAME (line_label)); 147833965Sjdp name = alc; 147933965Sjdp } 148033965Sjdp } 148133965Sjdp 148233965Sjdp sym = symbol_find_or_make (name); 148333965Sjdp *input_line_pointer = c; 148433965Sjdp if (alc != NULL) 148533965Sjdp free (alc); 148633965Sjdp 148733965Sjdp if (*input_line_pointer != ',') 148833965Sjdp align = 0; 148933965Sjdp else 149033965Sjdp { 149133965Sjdp ++input_line_pointer; 149233965Sjdp align = get_absolute_expression (); 149333965Sjdp } 149433965Sjdp 149533965Sjdp if (S_IS_DEFINED (sym) && ! S_IS_COMMON (sym)) 149633965Sjdp { 149760484Sobrien as_bad (_("attempt to re-define symbol `%s'"), S_GET_NAME (sym)); 149860484Sobrien ignore_rest_of_line (); 149933965Sjdp mri_comment_end (stop, stopc); 150033965Sjdp return; 150133965Sjdp } 150233965Sjdp 150333965Sjdp S_SET_EXTERNAL (sym); 150433965Sjdp mri_common_symbol = sym; 150533965Sjdp 150633965Sjdp#ifdef S_SET_ALIGN 150733965Sjdp if (align != 0) 150833965Sjdp S_SET_ALIGN (sym, align); 150933965Sjdp#endif 151033965Sjdp 151133965Sjdp if (line_label != NULL) 151233965Sjdp { 151360484Sobrien expressionS exp; 151460484Sobrien exp.X_op = O_symbol; 151560484Sobrien exp.X_add_symbol = sym; 151660484Sobrien exp.X_add_number = 0; 151760484Sobrien symbol_set_value_expression (line_label, &exp); 151860484Sobrien symbol_set_frag (line_label, &zero_address_frag); 151933965Sjdp S_SET_SEGMENT (line_label, expr_section); 152033965Sjdp } 152133965Sjdp 152233965Sjdp /* FIXME: We just ignore the small argument, which distinguishes 152333965Sjdp COMMON and COMMON.S. I don't know what we can do about it. */ 152433965Sjdp 152533965Sjdp /* Ignore the type and hptype. */ 152633965Sjdp if (*input_line_pointer == ',') 152733965Sjdp input_line_pointer += 2; 152833965Sjdp if (*input_line_pointer == ',') 152933965Sjdp input_line_pointer += 2; 153033965Sjdp 153160484Sobrien demand_empty_rest_of_line (); 153260484Sobrien 153333965Sjdp mri_comment_end (stop, stopc); 153433965Sjdp} 153533965Sjdp 153633965Sjdpvoid 153733965Sjdps_data (ignore) 153860484Sobrien int ignore ATTRIBUTE_UNUSED; 153933965Sjdp{ 154033965Sjdp segT section; 154133965Sjdp register int temp; 154233965Sjdp 154333965Sjdp temp = get_absolute_expression (); 154433965Sjdp if (flag_readonly_data_in_text) 154533965Sjdp { 154633965Sjdp section = text_section; 154733965Sjdp temp += 1000; 154833965Sjdp } 154933965Sjdp else 155033965Sjdp section = data_section; 155133965Sjdp 155233965Sjdp subseg_set (section, (subsegT) temp); 155333965Sjdp 155433965Sjdp#ifdef OBJ_VMS 155533965Sjdp const_flag = 0; 155633965Sjdp#endif 155733965Sjdp demand_empty_rest_of_line (); 155833965Sjdp} 155933965Sjdp 156033965Sjdp/* Handle the .appfile pseudo-op. This is automatically generated by 156133965Sjdp do_scrub_chars when a preprocessor # line comment is seen with a 156233965Sjdp file name. This default definition may be overridden by the object 156333965Sjdp or CPU specific pseudo-ops. This function is also the default 156433965Sjdp definition for .file; the APPFILE argument is 1 for .appfile, 0 for 156533965Sjdp .file. */ 156633965Sjdp 156733965Sjdpvoid 156833965Sjdps_app_file (appfile) 156933965Sjdp int appfile; 157033965Sjdp{ 157133965Sjdp register char *s; 157233965Sjdp int length; 157333965Sjdp 157433965Sjdp /* Some assemblers tolerate immediately following '"' */ 157533965Sjdp if ((s = demand_copy_string (&length)) != 0) 157633965Sjdp { 157733965Sjdp /* If this is a fake .appfile, a fake newline was inserted into 157833965Sjdp the buffer. Passing -2 to new_logical_line tells it to 157933965Sjdp account for it. */ 158038889Sjdp int may_omit 158138889Sjdp = (! new_logical_line (s, appfile ? -2 : -1) && appfile); 158233965Sjdp 158333965Sjdp /* In MRI mode, the preprocessor may have inserted an extraneous 158433965Sjdp backquote. */ 158533965Sjdp if (flag_m68k_mri 158633965Sjdp && *input_line_pointer == '\'' 158733965Sjdp && is_end_of_line[(unsigned char) input_line_pointer[1]]) 158833965Sjdp ++input_line_pointer; 158933965Sjdp 159033965Sjdp demand_empty_rest_of_line (); 159138889Sjdp if (! may_omit) 159238889Sjdp { 159333965Sjdp#ifdef LISTING 159438889Sjdp if (listing) 159538889Sjdp listing_source_file (s); 159633965Sjdp#endif 159738889Sjdp register_dependency (s); 159833965Sjdp#ifdef obj_app_file 159938889Sjdp obj_app_file (s); 160033965Sjdp#endif 160138889Sjdp } 160238889Sjdp } 160333965Sjdp} 160433965Sjdp 160533965Sjdp/* Handle the .appline pseudo-op. This is automatically generated by 160633965Sjdp do_scrub_chars when a preprocessor # line comment is seen. This 160733965Sjdp default definition may be overridden by the object or CPU specific 160833965Sjdp pseudo-ops. */ 160933965Sjdp 161033965Sjdpvoid 161133965Sjdps_app_line (ignore) 161260484Sobrien int ignore ATTRIBUTE_UNUSED; 161333965Sjdp{ 161433965Sjdp int l; 161533965Sjdp 161633965Sjdp /* The given number is that of the next line. */ 161733965Sjdp l = get_absolute_expression () - 1; 161833965Sjdp if (l < 0) 161933965Sjdp /* Some of the back ends can't deal with non-positive line numbers. 162033965Sjdp Besides, it's silly. */ 162160484Sobrien as_warn (_("Line numbers must be positive; line number %d rejected."), l+1); 162233965Sjdp else 162333965Sjdp { 162433965Sjdp new_logical_line ((char *) NULL, l); 162533965Sjdp#ifdef LISTING 162633965Sjdp if (listing) 162733965Sjdp listing_source_line (l); 162833965Sjdp#endif 162933965Sjdp } 163033965Sjdp demand_empty_rest_of_line (); 163133965Sjdp} 163233965Sjdp 163333965Sjdp/* Handle the .end pseudo-op. Actually, the real work is done in 163433965Sjdp read_a_source_file. */ 163533965Sjdp 163633965Sjdpvoid 163733965Sjdps_end (ignore) 163860484Sobrien int ignore ATTRIBUTE_UNUSED; 163933965Sjdp{ 164033965Sjdp if (flag_mri) 164133965Sjdp { 164233965Sjdp /* The MRI assembler permits the start symbol to follow .end, 164333965Sjdp but we don't support that. */ 164433965Sjdp SKIP_WHITESPACE (); 164533965Sjdp if (! is_end_of_line[(unsigned char) *input_line_pointer] 164633965Sjdp && *input_line_pointer != '*' 164733965Sjdp && *input_line_pointer != '!') 164860484Sobrien as_warn (_("start address not supported")); 164933965Sjdp } 165033965Sjdp} 165133965Sjdp 165233965Sjdp/* Handle the .err pseudo-op. */ 165333965Sjdp 165433965Sjdpvoid 165533965Sjdps_err (ignore) 165660484Sobrien int ignore ATTRIBUTE_UNUSED; 165733965Sjdp{ 165860484Sobrien as_bad (_(".err encountered")); 165933965Sjdp demand_empty_rest_of_line (); 166033965Sjdp} 166133965Sjdp 166233965Sjdp/* Handle the MRI fail pseudo-op. */ 166333965Sjdp 166433965Sjdpvoid 166533965Sjdps_fail (ignore) 166660484Sobrien int ignore ATTRIBUTE_UNUSED; 166733965Sjdp{ 166833965Sjdp offsetT temp; 166933965Sjdp char *stop = NULL; 167033965Sjdp char stopc; 167133965Sjdp 167233965Sjdp if (flag_mri) 167333965Sjdp stop = mri_comment_field (&stopc); 167433965Sjdp 167533965Sjdp temp = get_absolute_expression (); 167633965Sjdp if (temp >= 500) 167760484Sobrien as_warn (_(".fail %ld encountered"), (long) temp); 167833965Sjdp else 167960484Sobrien as_bad (_(".fail %ld encountered"), (long) temp); 168033965Sjdp 168160484Sobrien demand_empty_rest_of_line (); 168260484Sobrien 168333965Sjdp if (flag_mri) 168433965Sjdp mri_comment_end (stop, stopc); 168533965Sjdp} 168633965Sjdp 168733965Sjdpvoid 168833965Sjdps_fill (ignore) 168960484Sobrien int ignore ATTRIBUTE_UNUSED; 169033965Sjdp{ 169138889Sjdp expressionS rep_exp; 169238889Sjdp long size = 1; 169338889Sjdp register long fill = 0; 169433965Sjdp char *p; 169533965Sjdp 169633965Sjdp#ifdef md_flush_pending_output 169733965Sjdp md_flush_pending_output (); 169833965Sjdp#endif 169933965Sjdp 170038889Sjdp get_known_segmented_expression (&rep_exp); 170133965Sjdp if (*input_line_pointer == ',') 170233965Sjdp { 170333965Sjdp input_line_pointer++; 170438889Sjdp size = get_absolute_expression (); 170533965Sjdp if (*input_line_pointer == ',') 170633965Sjdp { 170733965Sjdp input_line_pointer++; 170838889Sjdp fill = get_absolute_expression (); 170933965Sjdp } 171033965Sjdp } 171138889Sjdp 171233965Sjdp /* This is to be compatible with BSD 4.2 AS, not for any rational reason. */ 171333965Sjdp#define BSD_FILL_SIZE_CROCK_8 (8) 171438889Sjdp if (size > BSD_FILL_SIZE_CROCK_8) 171533965Sjdp { 171660484Sobrien as_warn (_(".fill size clamped to %d."), BSD_FILL_SIZE_CROCK_8); 171738889Sjdp size = BSD_FILL_SIZE_CROCK_8; 171833965Sjdp } 171938889Sjdp if (size < 0) 172033965Sjdp { 172160484Sobrien as_warn (_("Size negative: .fill ignored.")); 172238889Sjdp size = 0; 172333965Sjdp } 172438889Sjdp else if (rep_exp.X_op == O_constant && rep_exp.X_add_number <= 0) 172533965Sjdp { 172638889Sjdp if (rep_exp.X_add_number < 0) 172760484Sobrien as_warn (_("Repeat < 0, .fill ignored")); 172838889Sjdp size = 0; 172933965Sjdp } 173033965Sjdp 173138889Sjdp if (size && !need_pass_2) 173233965Sjdp { 173338889Sjdp if (rep_exp.X_op == O_constant) 173438889Sjdp { 173538889Sjdp p = frag_var (rs_fill, (int) size, (int) size, 173638889Sjdp (relax_substateT) 0, (symbolS *) 0, 173738889Sjdp (offsetT) rep_exp.X_add_number, 173838889Sjdp (char *) 0); 173938889Sjdp } 174038889Sjdp else 174138889Sjdp { 174238889Sjdp /* We don't have a constant repeat count, so we can't use 174338889Sjdp rs_fill. We can get the same results out of rs_space, 174438889Sjdp but its argument is in bytes, so we must multiply the 174538889Sjdp repeat count by size. */ 174638889Sjdp 174738889Sjdp symbolS *rep_sym; 174838889Sjdp rep_sym = make_expr_symbol (&rep_exp); 174938889Sjdp if (size != 1) 175038889Sjdp { 175138889Sjdp expressionS size_exp; 175238889Sjdp size_exp.X_op = O_constant; 175338889Sjdp size_exp.X_add_number = size; 175438889Sjdp 175538889Sjdp rep_exp.X_op = O_multiply; 175638889Sjdp rep_exp.X_add_symbol = rep_sym; 175738889Sjdp rep_exp.X_op_symbol = make_expr_symbol (&size_exp); 175838889Sjdp rep_exp.X_add_number = 0; 175938889Sjdp rep_sym = make_expr_symbol (&rep_exp); 176038889Sjdp } 176138889Sjdp 176238889Sjdp p = frag_var (rs_space, (int) size, (int) size, 176338889Sjdp (relax_substateT) 0, rep_sym, (offsetT) 0, (char *) 0); 176438889Sjdp } 176538889Sjdp memset (p, 0, (unsigned int) size); 176633965Sjdp /* The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX 176733965Sjdp * flavoured AS. The following bizzare behaviour is to be 176833965Sjdp * compatible with above. I guess they tried to take up to 8 176933965Sjdp * bytes from a 4-byte expression and they forgot to sign 177033965Sjdp * extend. Un*x Sux. */ 177133965Sjdp#define BSD_FILL_SIZE_CROCK_4 (4) 177238889Sjdp md_number_to_chars (p, (valueT) fill, 177338889Sjdp (size > BSD_FILL_SIZE_CROCK_4 177433965Sjdp ? BSD_FILL_SIZE_CROCK_4 177538889Sjdp : (int) size)); 177633965Sjdp /* Note: .fill (),0 emits no frag (since we are asked to .fill 0 bytes) 177733965Sjdp * but emits no error message because it seems a legal thing to do. 177833965Sjdp * It is a degenerate case of .fill but could be emitted by a compiler. 177933965Sjdp */ 178033965Sjdp } 178133965Sjdp demand_empty_rest_of_line (); 178233965Sjdp} 178333965Sjdp 178433965Sjdpvoid 178533965Sjdps_globl (ignore) 178660484Sobrien int ignore ATTRIBUTE_UNUSED; 178733965Sjdp{ 178833965Sjdp char *name; 178933965Sjdp int c; 179033965Sjdp symbolS *symbolP; 179133965Sjdp char *stop = NULL; 179233965Sjdp char stopc; 179333965Sjdp 179433965Sjdp if (flag_mri) 179533965Sjdp stop = mri_comment_field (&stopc); 179633965Sjdp 179733965Sjdp do 179833965Sjdp { 179933965Sjdp name = input_line_pointer; 180033965Sjdp c = get_symbol_end (); 180133965Sjdp symbolP = symbol_find_or_make (name); 180260484Sobrien S_SET_EXTERNAL (symbolP); 180360484Sobrien 180433965Sjdp *input_line_pointer = c; 180533965Sjdp SKIP_WHITESPACE (); 180660484Sobrien c = *input_line_pointer; 180733965Sjdp if (c == ',') 180833965Sjdp { 180933965Sjdp input_line_pointer++; 181033965Sjdp SKIP_WHITESPACE (); 181133965Sjdp if (*input_line_pointer == '\n') 181233965Sjdp c = '\n'; 181333965Sjdp } 181433965Sjdp } 181533965Sjdp while (c == ','); 181633965Sjdp 181760484Sobrien demand_empty_rest_of_line (); 181860484Sobrien 181933965Sjdp if (flag_mri) 182033965Sjdp mri_comment_end (stop, stopc); 182133965Sjdp} 182233965Sjdp 182333965Sjdp/* Handle the MRI IRP and IRPC pseudo-ops. */ 182433965Sjdp 182533965Sjdpvoid 182633965Sjdps_irp (irpc) 182733965Sjdp int irpc; 182833965Sjdp{ 182933965Sjdp char *file; 183033965Sjdp unsigned int line; 183133965Sjdp sb s; 183233965Sjdp const char *err; 183333965Sjdp sb out; 183433965Sjdp 183533965Sjdp as_where (&file, &line); 183633965Sjdp 183733965Sjdp sb_new (&s); 183833965Sjdp while (! is_end_of_line[(unsigned char) *input_line_pointer]) 183933965Sjdp sb_add_char (&s, *input_line_pointer++); 184033965Sjdp 184133965Sjdp sb_new (&out); 184233965Sjdp 184333965Sjdp err = expand_irp (irpc, 0, &s, &out, get_line_sb, '\0'); 184433965Sjdp if (err != NULL) 184533965Sjdp as_bad_where (file, line, "%s", err); 184633965Sjdp 184733965Sjdp sb_kill (&s); 184833965Sjdp 184960484Sobrien input_scrub_include_sb (&out, input_line_pointer, 1); 185033965Sjdp sb_kill (&out); 185133965Sjdp buffer_limit = input_scrub_next_buffer (&input_line_pointer); 185233965Sjdp} 185333965Sjdp 185433965Sjdp/* Handle the .linkonce pseudo-op. This tells the assembler to mark 185533965Sjdp the section to only be linked once. However, this is not supported 185633965Sjdp by most object file formats. This takes an optional argument, 185733965Sjdp which is what to do about duplicates. */ 185833965Sjdp 185933965Sjdpvoid 186033965Sjdps_linkonce (ignore) 186160484Sobrien int ignore ATTRIBUTE_UNUSED; 186233965Sjdp{ 186333965Sjdp enum linkonce_type type; 186433965Sjdp 186533965Sjdp SKIP_WHITESPACE (); 186633965Sjdp 186733965Sjdp type = LINKONCE_DISCARD; 186833965Sjdp 186933965Sjdp if (! is_end_of_line[(unsigned char) *input_line_pointer]) 187033965Sjdp { 187133965Sjdp char *s; 187233965Sjdp char c; 187333965Sjdp 187433965Sjdp s = input_line_pointer; 187533965Sjdp c = get_symbol_end (); 187633965Sjdp if (strcasecmp (s, "discard") == 0) 187733965Sjdp type = LINKONCE_DISCARD; 187833965Sjdp else if (strcasecmp (s, "one_only") == 0) 187933965Sjdp type = LINKONCE_ONE_ONLY; 188033965Sjdp else if (strcasecmp (s, "same_size") == 0) 188133965Sjdp type = LINKONCE_SAME_SIZE; 188233965Sjdp else if (strcasecmp (s, "same_contents") == 0) 188333965Sjdp type = LINKONCE_SAME_CONTENTS; 188433965Sjdp else 188560484Sobrien as_warn (_("unrecognized .linkonce type `%s'"), s); 188633965Sjdp 188733965Sjdp *input_line_pointer = c; 188833965Sjdp } 188933965Sjdp 189033965Sjdp#ifdef obj_handle_link_once 189133965Sjdp obj_handle_link_once (type); 189233965Sjdp#else /* ! defined (obj_handle_link_once) */ 189333965Sjdp#ifdef BFD_ASSEMBLER 189433965Sjdp { 189533965Sjdp flagword flags; 189633965Sjdp 189733965Sjdp if ((bfd_applicable_section_flags (stdoutput) & SEC_LINK_ONCE) == 0) 189860484Sobrien as_warn (_(".linkonce is not supported for this object file format")); 189933965Sjdp 190033965Sjdp flags = bfd_get_section_flags (stdoutput, now_seg); 190133965Sjdp flags |= SEC_LINK_ONCE; 190233965Sjdp switch (type) 190333965Sjdp { 190433965Sjdp default: 190533965Sjdp abort (); 190633965Sjdp case LINKONCE_DISCARD: 190733965Sjdp flags |= SEC_LINK_DUPLICATES_DISCARD; 190833965Sjdp break; 190933965Sjdp case LINKONCE_ONE_ONLY: 191033965Sjdp flags |= SEC_LINK_DUPLICATES_ONE_ONLY; 191133965Sjdp break; 191233965Sjdp case LINKONCE_SAME_SIZE: 191333965Sjdp flags |= SEC_LINK_DUPLICATES_SAME_SIZE; 191433965Sjdp break; 191533965Sjdp case LINKONCE_SAME_CONTENTS: 191633965Sjdp flags |= SEC_LINK_DUPLICATES_SAME_CONTENTS; 191733965Sjdp break; 191833965Sjdp } 191933965Sjdp if (! bfd_set_section_flags (stdoutput, now_seg, flags)) 192060484Sobrien as_bad (_("bfd_set_section_flags: %s"), 192133965Sjdp bfd_errmsg (bfd_get_error ())); 192233965Sjdp } 192333965Sjdp#else /* ! defined (BFD_ASSEMBLER) */ 192460484Sobrien as_warn (_(".linkonce is not supported for this object file format")); 192533965Sjdp#endif /* ! defined (BFD_ASSEMBLER) */ 192633965Sjdp#endif /* ! defined (obj_handle_link_once) */ 192733965Sjdp 192833965Sjdp demand_empty_rest_of_line (); 192933965Sjdp} 193033965Sjdp 193138889Sjdpstatic void 193238889Sjdps_lcomm_internal (needs_align, bytes_p) 193333965Sjdp /* 1 if this was a ".bss" directive, which may require a 3rd argument 193433965Sjdp (alignment); 0 if it was an ".lcomm" (2 args only) */ 193533965Sjdp int needs_align; 193638889Sjdp /* 1 if the alignment value should be interpreted as the byte boundary, 193738889Sjdp rather than the power of 2. */ 193838889Sjdp int bytes_p; 193933965Sjdp{ 194033965Sjdp register char *name; 194133965Sjdp register char c; 194233965Sjdp register char *p; 194333965Sjdp register int temp; 194433965Sjdp register symbolS *symbolP; 194533965Sjdp segT current_seg = now_seg; 194633965Sjdp subsegT current_subseg = now_subseg; 194733965Sjdp const int max_alignment = 15; 194833965Sjdp int align = 0; 194933965Sjdp segT bss_seg = bss_section; 195033965Sjdp 195133965Sjdp name = input_line_pointer; 195233965Sjdp c = get_symbol_end (); 195333965Sjdp p = input_line_pointer; 195433965Sjdp *p = c; 195533965Sjdp SKIP_WHITESPACE (); 195633965Sjdp 195733965Sjdp /* Accept an optional comma after the name. The comma used to be 195833965Sjdp required, but Irix 5 cc does not generate it. */ 195933965Sjdp if (*input_line_pointer == ',') 196033965Sjdp { 196133965Sjdp ++input_line_pointer; 196233965Sjdp SKIP_WHITESPACE (); 196333965Sjdp } 196433965Sjdp 196533965Sjdp if (*input_line_pointer == '\n') 196633965Sjdp { 196760484Sobrien as_bad (_("Missing size expression")); 196833965Sjdp return; 196933965Sjdp } 197033965Sjdp 197133965Sjdp if ((temp = get_absolute_expression ()) < 0) 197233965Sjdp { 197360484Sobrien as_warn (_("BSS length (%d.) <0! Ignored."), temp); 197433965Sjdp ignore_rest_of_line (); 197533965Sjdp return; 197633965Sjdp } 197733965Sjdp 197833965Sjdp#if defined (TC_MIPS) || defined (TC_ALPHA) 197933965Sjdp if (OUTPUT_FLAVOR == bfd_target_ecoff_flavour 198033965Sjdp || OUTPUT_FLAVOR == bfd_target_elf_flavour) 198133965Sjdp { 198233965Sjdp /* For MIPS and Alpha ECOFF or ELF, small objects are put in .sbss. */ 198333965Sjdp if (temp <= bfd_get_gp_size (stdoutput)) 198433965Sjdp { 198533965Sjdp bss_seg = subseg_new (".sbss", 1); 198633965Sjdp seg_info (bss_seg)->bss = 1; 198733965Sjdp#ifdef BFD_ASSEMBLER 198833965Sjdp if (! bfd_set_section_flags (stdoutput, bss_seg, SEC_ALLOC)) 198960484Sobrien as_warn (_("error setting flags for \".sbss\": %s"), 199033965Sjdp bfd_errmsg (bfd_get_error ())); 199133965Sjdp#endif 199233965Sjdp } 199333965Sjdp } 199433965Sjdp#endif 199560484Sobrien 199633965Sjdp if (!needs_align) 199733965Sjdp { 199860484Sobrien TC_IMPLICIT_LCOMM_ALIGNMENT (temp, align); 199933965Sjdp 200060484Sobrien /* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it. */ 200160484Sobrien if (align) 200260484Sobrien record_alignment(bss_seg, align); 200333965Sjdp } 200433965Sjdp 200533965Sjdp if (needs_align) 200633965Sjdp { 200733965Sjdp align = 0; 200833965Sjdp SKIP_WHITESPACE (); 200933965Sjdp if (*input_line_pointer != ',') 201033965Sjdp { 201160484Sobrien as_bad (_("Expected comma after size")); 201233965Sjdp ignore_rest_of_line (); 201333965Sjdp return; 201433965Sjdp } 201533965Sjdp input_line_pointer++; 201633965Sjdp SKIP_WHITESPACE (); 201733965Sjdp if (*input_line_pointer == '\n') 201833965Sjdp { 201960484Sobrien as_bad (_("Missing alignment")); 202033965Sjdp return; 202133965Sjdp } 202233965Sjdp align = get_absolute_expression (); 202338889Sjdp if (bytes_p) 202438889Sjdp { 202538889Sjdp /* Convert to a power of 2. */ 202638889Sjdp if (align != 0) 202738889Sjdp { 202838889Sjdp unsigned int i; 202938889Sjdp 203038889Sjdp for (i = 0; (align & 1) == 0; align >>= 1, ++i) 203138889Sjdp ; 203238889Sjdp if (align != 1) 203360484Sobrien as_bad (_("Alignment not a power of 2")); 203438889Sjdp align = i; 203538889Sjdp } 203638889Sjdp } 203733965Sjdp if (align > max_alignment) 203833965Sjdp { 203933965Sjdp align = max_alignment; 204060484Sobrien as_warn (_("Alignment too large: %d. assumed."), align); 204133965Sjdp } 204233965Sjdp else if (align < 0) 204333965Sjdp { 204433965Sjdp align = 0; 204560484Sobrien as_warn (_("Alignment negative. 0 assumed.")); 204633965Sjdp } 204733965Sjdp record_alignment (bss_seg, align); 204833965Sjdp } /* if needs align */ 204933965Sjdp else 205033965Sjdp { 205133965Sjdp /* Assume some objects may require alignment on some systems. */ 205233965Sjdp#if defined (TC_ALPHA) && ! defined (VMS) 205333965Sjdp if (temp > 1) 205433965Sjdp { 205533965Sjdp align = ffs (temp) - 1; 205633965Sjdp if (temp % (1 << align)) 205733965Sjdp abort (); 205833965Sjdp } 205933965Sjdp#endif 206033965Sjdp } 206133965Sjdp 206233965Sjdp *p = 0; 206333965Sjdp symbolP = symbol_find_or_make (name); 206433965Sjdp *p = c; 206533965Sjdp 206633965Sjdp if ( 206760484Sobrien#if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT) \ 206860484Sobrien || defined (OBJ_BOUT) || defined (OBJ_MAYBE_BOUT)) 206960484Sobrien#ifdef BFD_ASSEMBLER 207060484Sobrien (OUTPUT_FLAVOR != bfd_target_aout_flavour 207160484Sobrien || (S_GET_OTHER (symbolP) == 0 && S_GET_DESC (symbolP) == 0)) && 207260484Sobrien#else 207360484Sobrien (S_GET_OTHER (symbolP) == 0 && S_GET_DESC (symbolP) == 0) && 207460484Sobrien#endif 207560484Sobrien#endif 207660484Sobrien (S_GET_SEGMENT (symbolP) == bss_seg 207760484Sobrien || (!S_IS_DEFINED (symbolP) && S_GET_VALUE (symbolP) == 0))) 207833965Sjdp { 207933965Sjdp char *pfrag; 208033965Sjdp 208133965Sjdp subseg_set (bss_seg, 1); 208233965Sjdp 208333965Sjdp if (align) 208433965Sjdp frag_align (align, 0, 0); 208533965Sjdp /* detach from old frag */ 208633965Sjdp if (S_GET_SEGMENT (symbolP) == bss_seg) 208760484Sobrien symbol_get_frag (symbolP)->fr_symbol = NULL; 208833965Sjdp 208960484Sobrien symbol_set_frag (symbolP, frag_now); 209033965Sjdp pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP, 209133965Sjdp (offsetT) temp, (char *) 0); 209233965Sjdp *pfrag = 0; 209333965Sjdp 209433965Sjdp S_SET_SEGMENT (symbolP, bss_seg); 209533965Sjdp 209633965Sjdp#ifdef OBJ_COFF 209733965Sjdp /* The symbol may already have been created with a preceding 209833965Sjdp ".globl" directive -- be careful not to step on storage class 209933965Sjdp in that case. Otherwise, set it to static. */ 210033965Sjdp if (S_GET_STORAGE_CLASS (symbolP) != C_EXT) 210133965Sjdp { 210233965Sjdp S_SET_STORAGE_CLASS (symbolP, C_STAT); 210333965Sjdp } 210433965Sjdp#endif /* OBJ_COFF */ 210533965Sjdp 210633965Sjdp#ifdef S_SET_SIZE 210733965Sjdp S_SET_SIZE (symbolP, temp); 210833965Sjdp#endif 210933965Sjdp } 211033965Sjdp else 211160484Sobrien as_bad (_("Ignoring attempt to re-define symbol `%s'."), 211233965Sjdp S_GET_NAME (symbolP)); 211333965Sjdp 211433965Sjdp subseg_set (current_seg, current_subseg); 211533965Sjdp 211633965Sjdp demand_empty_rest_of_line (); 211738889Sjdp} /* s_lcomm_internal() */ 211833965Sjdp 211938889Sjdpvoid 212038889Sjdps_lcomm (needs_align) 212138889Sjdp int needs_align; 212238889Sjdp{ 212338889Sjdp s_lcomm_internal (needs_align, 0); 212438889Sjdp} 212538889Sjdp 212638889Sjdpvoid s_lcomm_bytes (needs_align) 212738889Sjdp int needs_align; 212838889Sjdp{ 212938889Sjdp s_lcomm_internal (needs_align, 1); 213038889Sjdp} 213138889Sjdp 213233965Sjdpvoid 213333965Sjdps_lsym (ignore) 213460484Sobrien int ignore ATTRIBUTE_UNUSED; 213533965Sjdp{ 213633965Sjdp register char *name; 213733965Sjdp register char c; 213833965Sjdp register char *p; 213933965Sjdp expressionS exp; 214033965Sjdp register symbolS *symbolP; 214133965Sjdp 214233965Sjdp /* we permit ANY defined expression: BSD4.2 demands constants */ 214333965Sjdp name = input_line_pointer; 214433965Sjdp c = get_symbol_end (); 214533965Sjdp p = input_line_pointer; 214633965Sjdp *p = c; 214733965Sjdp SKIP_WHITESPACE (); 214833965Sjdp if (*input_line_pointer != ',') 214933965Sjdp { 215033965Sjdp *p = 0; 215160484Sobrien as_bad (_("Expected comma after name \"%s\""), name); 215233965Sjdp *p = c; 215333965Sjdp ignore_rest_of_line (); 215433965Sjdp return; 215533965Sjdp } 215633965Sjdp input_line_pointer++; 215733965Sjdp expression (&exp); 215833965Sjdp if (exp.X_op != O_constant 215933965Sjdp && exp.X_op != O_register) 216033965Sjdp { 216160484Sobrien as_bad (_("bad expression")); 216233965Sjdp ignore_rest_of_line (); 216333965Sjdp return; 216433965Sjdp } 216533965Sjdp *p = 0; 216633965Sjdp symbolP = symbol_find_or_make (name); 216733965Sjdp 216833965Sjdp /* FIXME-SOON I pulled a (&& symbolP->sy_other == 0 && 216933965Sjdp symbolP->sy_desc == 0) out of this test because coff doesn't have 217033965Sjdp those fields, and I can't see when they'd ever be tripped. I 217133965Sjdp don't think I understand why they were here so I may have 217233965Sjdp introduced a bug. As recently as 1.37 didn't have this test 217333965Sjdp anyway. xoxorich. */ 217433965Sjdp 217533965Sjdp if (S_GET_SEGMENT (symbolP) == undefined_section 217633965Sjdp && S_GET_VALUE (symbolP) == 0) 217733965Sjdp { 217833965Sjdp /* The name might be an undefined .global symbol; be sure to 217933965Sjdp keep the "external" bit. */ 218033965Sjdp S_SET_SEGMENT (symbolP, 218133965Sjdp (exp.X_op == O_constant 218233965Sjdp ? absolute_section 218333965Sjdp : reg_section)); 218433965Sjdp S_SET_VALUE (symbolP, (valueT) exp.X_add_number); 218533965Sjdp } 218633965Sjdp else 218733965Sjdp { 218860484Sobrien as_bad (_("Symbol %s already defined"), name); 218933965Sjdp } 219033965Sjdp *p = c; 219133965Sjdp demand_empty_rest_of_line (); 219233965Sjdp} /* s_lsym() */ 219333965Sjdp 219433965Sjdp/* Read a line into an sb. */ 219533965Sjdp 219633965Sjdpstatic int 219733965Sjdpget_line_sb (line) 219833965Sjdp sb *line; 219933965Sjdp{ 220033965Sjdp char quote1, quote2, inquote; 220133965Sjdp 220233965Sjdp if (input_line_pointer[-1] == '\n') 220333965Sjdp bump_line_counters (); 220433965Sjdp 220533965Sjdp if (input_line_pointer >= buffer_limit) 220633965Sjdp { 220733965Sjdp buffer_limit = input_scrub_next_buffer (&input_line_pointer); 220833965Sjdp if (buffer_limit == 0) 220933965Sjdp return 0; 221033965Sjdp } 221133965Sjdp 221233965Sjdp /* If app.c sets any other characters to LEX_IS_STRINGQUOTE, this 221333965Sjdp code needs to be changed. */ 221433965Sjdp if (! flag_m68k_mri) 221533965Sjdp quote1 = '"'; 221633965Sjdp else 221733965Sjdp quote1 = '\0'; 221833965Sjdp 221933965Sjdp quote2 = '\0'; 222033965Sjdp if (flag_m68k_mri) 222133965Sjdp quote2 = '\''; 222233965Sjdp#ifdef LEX_IS_STRINGQUOTE 222333965Sjdp quote2 = '\''; 222433965Sjdp#endif 222533965Sjdp 222633965Sjdp inquote = '\0'; 222733965Sjdp while (! is_end_of_line[(unsigned char) *input_line_pointer] 222833965Sjdp || (inquote != '\0' && *input_line_pointer != '\n')) 222933965Sjdp { 223033965Sjdp if (inquote == *input_line_pointer) 223133965Sjdp inquote = '\0'; 223233965Sjdp else if (inquote == '\0') 223333965Sjdp { 223433965Sjdp if (*input_line_pointer == quote1) 223533965Sjdp inquote = quote1; 223633965Sjdp else if (*input_line_pointer == quote2) 223733965Sjdp inquote = quote2; 223833965Sjdp } 223933965Sjdp sb_add_char (line, *input_line_pointer++); 224033965Sjdp } 224138889Sjdp while (input_line_pointer < buffer_limit 224238889Sjdp && is_end_of_line[(unsigned char) *input_line_pointer]) 224333965Sjdp { 224433965Sjdp if (input_line_pointer[-1] == '\n') 224533965Sjdp bump_line_counters (); 224633965Sjdp ++input_line_pointer; 224733965Sjdp } 224833965Sjdp return 1; 224933965Sjdp} 225033965Sjdp 225133965Sjdp/* Define a macro. This is an interface to macro.c, which is shared 225233965Sjdp between gas and gasp. */ 225333965Sjdp 225433965Sjdpvoid 225533965Sjdps_macro (ignore) 225660484Sobrien int ignore ATTRIBUTE_UNUSED; 225733965Sjdp{ 225833965Sjdp char *file; 225933965Sjdp unsigned int line; 226033965Sjdp sb s; 226133965Sjdp sb label; 226233965Sjdp const char *err; 226333965Sjdp const char *name; 226433965Sjdp 226533965Sjdp as_where (&file, &line); 226633965Sjdp 226733965Sjdp sb_new (&s); 226833965Sjdp while (! is_end_of_line[(unsigned char) *input_line_pointer]) 226933965Sjdp sb_add_char (&s, *input_line_pointer++); 227033965Sjdp 227133965Sjdp sb_new (&label); 227233965Sjdp if (line_label != NULL) 227333965Sjdp sb_add_string (&label, S_GET_NAME (line_label)); 227433965Sjdp 227533965Sjdp err = define_macro (0, &s, &label, get_line_sb, &name); 227633965Sjdp if (err != NULL) 227733965Sjdp as_bad_where (file, line, "%s", err); 227833965Sjdp else 227933965Sjdp { 228033965Sjdp if (line_label != NULL) 228133965Sjdp { 228233965Sjdp S_SET_SEGMENT (line_label, undefined_section); 228333965Sjdp S_SET_VALUE (line_label, 0); 228460484Sobrien symbol_set_frag (line_label, &zero_address_frag); 228533965Sjdp } 228633965Sjdp 228760484Sobrien if (((NO_PSEUDO_DOT || flag_m68k_mri) 228833965Sjdp && hash_find (po_hash, name) != NULL) 228933965Sjdp || (! flag_m68k_mri 229033965Sjdp && *name == '.' 229133965Sjdp && hash_find (po_hash, name + 1) != NULL)) 229260484Sobrien as_warn (_("attempt to redefine pseudo-op `%s' ignored"), 229333965Sjdp name); 229433965Sjdp } 229533965Sjdp 229633965Sjdp sb_kill (&s); 229733965Sjdp} 229833965Sjdp 229933965Sjdp/* Handle the .mexit pseudo-op, which immediately exits a macro 230033965Sjdp expansion. */ 230133965Sjdp 230233965Sjdpvoid 230333965Sjdps_mexit (ignore) 230460484Sobrien int ignore ATTRIBUTE_UNUSED; 230533965Sjdp{ 230633965Sjdp cond_exit_macro (macro_nest); 230733965Sjdp buffer_limit = input_scrub_next_buffer (&input_line_pointer); 230833965Sjdp} 230933965Sjdp 231033965Sjdp/* Switch in and out of MRI mode. */ 231133965Sjdp 231233965Sjdpvoid 231333965Sjdps_mri (ignore) 231460484Sobrien int ignore ATTRIBUTE_UNUSED; 231533965Sjdp{ 231633965Sjdp int on, old_flag; 231733965Sjdp 231833965Sjdp on = get_absolute_expression (); 231933965Sjdp old_flag = flag_mri; 232033965Sjdp if (on != 0) 232133965Sjdp { 232233965Sjdp flag_mri = 1; 232333965Sjdp#ifdef TC_M68K 232433965Sjdp flag_m68k_mri = 1; 232533965Sjdp#endif 232660484Sobrien macro_mri_mode (1); 232733965Sjdp } 232833965Sjdp else 232933965Sjdp { 233033965Sjdp flag_mri = 0; 233160484Sobrien#ifdef TC_M68K 233233965Sjdp flag_m68k_mri = 0; 233360484Sobrien#endif 233460484Sobrien macro_mri_mode (0); 233533965Sjdp } 233633965Sjdp 233760484Sobrien /* Operator precedence changes in m68k MRI mode, so we need to 233860484Sobrien update the operator rankings. */ 233960484Sobrien expr_set_precedence (); 234060484Sobrien 234133965Sjdp#ifdef MRI_MODE_CHANGE 234233965Sjdp if (on != old_flag) 234333965Sjdp MRI_MODE_CHANGE (on); 234433965Sjdp#endif 234533965Sjdp 234633965Sjdp demand_empty_rest_of_line (); 234733965Sjdp} 234833965Sjdp 234933965Sjdp/* Handle changing the location counter. */ 235033965Sjdp 235133965Sjdpstatic void 235233965Sjdpdo_org (segment, exp, fill) 235333965Sjdp segT segment; 235433965Sjdp expressionS *exp; 235533965Sjdp int fill; 235633965Sjdp{ 235733965Sjdp if (segment != now_seg && segment != absolute_section) 235860484Sobrien as_bad (_("invalid segment \"%s\"; segment \"%s\" assumed"), 235933965Sjdp segment_name (segment), segment_name (now_seg)); 236033965Sjdp 236133965Sjdp if (now_seg == absolute_section) 236233965Sjdp { 236333965Sjdp if (fill != 0) 236460484Sobrien as_warn (_("ignoring fill value in absolute section")); 236533965Sjdp if (exp->X_op != O_constant) 236633965Sjdp { 236760484Sobrien as_bad (_("only constant offsets supported in absolute section")); 236833965Sjdp exp->X_add_number = 0; 236933965Sjdp } 237033965Sjdp abs_section_offset = exp->X_add_number; 237133965Sjdp } 237233965Sjdp else 237333965Sjdp { 237433965Sjdp char *p; 237533965Sjdp 237633965Sjdp p = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp->X_add_symbol, 237760484Sobrien exp->X_add_number * OCTETS_PER_BYTE, (char *) NULL); 237833965Sjdp *p = fill; 237933965Sjdp } 238033965Sjdp} 238133965Sjdp 238233965Sjdpvoid 238333965Sjdps_org (ignore) 238460484Sobrien int ignore ATTRIBUTE_UNUSED; 238533965Sjdp{ 238633965Sjdp register segT segment; 238733965Sjdp expressionS exp; 238833965Sjdp register long temp_fill; 238933965Sjdp 239060484Sobrien#ifdef md_flush_pending_output 239160484Sobrien md_flush_pending_output (); 239260484Sobrien#endif 239360484Sobrien 239433965Sjdp /* The m68k MRI assembler has a different meaning for .org. It 239533965Sjdp means to create an absolute section at a given address. We can't 239633965Sjdp support that--use a linker script instead. */ 239733965Sjdp if (flag_m68k_mri) 239833965Sjdp { 239960484Sobrien as_bad (_("MRI style ORG pseudo-op not supported")); 240033965Sjdp ignore_rest_of_line (); 240133965Sjdp return; 240233965Sjdp } 240333965Sjdp 240433965Sjdp /* Don't believe the documentation of BSD 4.2 AS. There is no such 240533965Sjdp thing as a sub-segment-relative origin. Any absolute origin is 240633965Sjdp given a warning, then assumed to be segment-relative. Any 240733965Sjdp segmented origin expression ("foo+42") had better be in the right 240833965Sjdp segment or the .org is ignored. 240933965Sjdp 241033965Sjdp BSD 4.2 AS warns if you try to .org backwards. We cannot because 241133965Sjdp we never know sub-segment sizes when we are reading code. BSD 241233965Sjdp will crash trying to emit negative numbers of filler bytes in 241333965Sjdp certain .orgs. We don't crash, but see as-write for that code. 241433965Sjdp 241533965Sjdp Don't make frag if need_pass_2==1. */ 241633965Sjdp segment = get_known_segmented_expression (&exp); 241733965Sjdp if (*input_line_pointer == ',') 241833965Sjdp { 241933965Sjdp input_line_pointer++; 242033965Sjdp temp_fill = get_absolute_expression (); 242133965Sjdp } 242233965Sjdp else 242333965Sjdp temp_fill = 0; 242433965Sjdp 242533965Sjdp if (!need_pass_2) 242633965Sjdp do_org (segment, &exp, temp_fill); 242733965Sjdp 242833965Sjdp demand_empty_rest_of_line (); 242933965Sjdp} /* s_org() */ 243033965Sjdp 243133965Sjdp/* Handle parsing for the MRI SECT/SECTION pseudo-op. This should be 243233965Sjdp called by the obj-format routine which handles section changing 243333965Sjdp when in MRI mode. It will create a new section, and return it. It 243433965Sjdp will set *TYPE to the section type: one of 'C' (code), 'D' (data), 243533965Sjdp 'M' (mixed), or 'R' (romable). If BFD_ASSEMBLER is defined, the 243633965Sjdp flags will be set in the section. */ 243733965Sjdp 243833965Sjdpvoid 243933965Sjdps_mri_sect (type) 244060484Sobrien char *type ATTRIBUTE_UNUSED; 244133965Sjdp{ 244233965Sjdp#ifdef TC_M68K 244333965Sjdp 244433965Sjdp char *name; 244533965Sjdp char c; 244633965Sjdp segT seg; 244733965Sjdp 244833965Sjdp SKIP_WHITESPACE (); 244933965Sjdp 245033965Sjdp name = input_line_pointer; 245133965Sjdp if (! isdigit ((unsigned char) *name)) 245233965Sjdp c = get_symbol_end (); 245333965Sjdp else 245433965Sjdp { 245533965Sjdp do 245633965Sjdp { 245733965Sjdp ++input_line_pointer; 245833965Sjdp } 245933965Sjdp while (isdigit ((unsigned char) *input_line_pointer)); 246033965Sjdp c = *input_line_pointer; 246133965Sjdp *input_line_pointer = '\0'; 246233965Sjdp } 246333965Sjdp 246433965Sjdp name = xstrdup (name); 246533965Sjdp 246633965Sjdp *input_line_pointer = c; 246733965Sjdp 246833965Sjdp seg = subseg_new (name, 0); 246933965Sjdp 247033965Sjdp if (*input_line_pointer == ',') 247133965Sjdp { 247233965Sjdp int align; 247333965Sjdp 247433965Sjdp ++input_line_pointer; 247533965Sjdp align = get_absolute_expression (); 247633965Sjdp record_alignment (seg, align); 247733965Sjdp } 247833965Sjdp 247933965Sjdp *type = 'C'; 248033965Sjdp if (*input_line_pointer == ',') 248133965Sjdp { 248233965Sjdp c = *++input_line_pointer; 248333965Sjdp c = toupper ((unsigned char) c); 248433965Sjdp if (c == 'C' || c == 'D' || c == 'M' || c == 'R') 248533965Sjdp *type = c; 248633965Sjdp else 248760484Sobrien as_bad (_("unrecognized section type")); 248833965Sjdp ++input_line_pointer; 248933965Sjdp 249033965Sjdp#ifdef BFD_ASSEMBLER 249133965Sjdp { 249233965Sjdp flagword flags; 249333965Sjdp 249433965Sjdp flags = SEC_NO_FLAGS; 249533965Sjdp if (*type == 'C') 249633965Sjdp flags = SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE; 249733965Sjdp else if (*type == 'D' || *type == 'M') 249833965Sjdp flags = SEC_ALLOC | SEC_LOAD | SEC_DATA; 249933965Sjdp else if (*type == 'R') 250033965Sjdp flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_READONLY | SEC_ROM; 250133965Sjdp if (flags != SEC_NO_FLAGS) 250233965Sjdp { 250333965Sjdp if (! bfd_set_section_flags (stdoutput, seg, flags)) 250460484Sobrien as_warn (_("error setting flags for \"%s\": %s"), 250533965Sjdp bfd_section_name (stdoutput, seg), 250633965Sjdp bfd_errmsg (bfd_get_error ())); 250733965Sjdp } 250833965Sjdp } 250933965Sjdp#endif 251033965Sjdp } 251133965Sjdp 251233965Sjdp /* Ignore the HP type. */ 251333965Sjdp if (*input_line_pointer == ',') 251433965Sjdp input_line_pointer += 2; 251533965Sjdp 251633965Sjdp demand_empty_rest_of_line (); 251733965Sjdp 251833965Sjdp#else /* ! TC_M68K */ 251933965Sjdp#ifdef TC_I960 252033965Sjdp 252133965Sjdp char *name; 252233965Sjdp char c; 252333965Sjdp segT seg; 252433965Sjdp 252533965Sjdp SKIP_WHITESPACE (); 252633965Sjdp 252733965Sjdp name = input_line_pointer; 252833965Sjdp c = get_symbol_end (); 252933965Sjdp 253033965Sjdp name = xstrdup (name); 253133965Sjdp 253233965Sjdp *input_line_pointer = c; 253333965Sjdp 253433965Sjdp seg = subseg_new (name, 0); 253533965Sjdp 253633965Sjdp if (*input_line_pointer != ',') 253733965Sjdp *type = 'C'; 253833965Sjdp else 253933965Sjdp { 254033965Sjdp char *sectype; 254133965Sjdp 254233965Sjdp ++input_line_pointer; 254333965Sjdp SKIP_WHITESPACE (); 254433965Sjdp sectype = input_line_pointer; 254533965Sjdp c = get_symbol_end (); 254633965Sjdp if (*sectype == '\0') 254733965Sjdp *type = 'C'; 254833965Sjdp else if (strcasecmp (sectype, "text") == 0) 254933965Sjdp *type = 'C'; 255033965Sjdp else if (strcasecmp (sectype, "data") == 0) 255133965Sjdp *type = 'D'; 255233965Sjdp else if (strcasecmp (sectype, "romdata") == 0) 255333965Sjdp *type = 'R'; 255433965Sjdp else 255560484Sobrien as_warn (_("unrecognized section type `%s'"), sectype); 255633965Sjdp *input_line_pointer = c; 255733965Sjdp } 255833965Sjdp 255933965Sjdp if (*input_line_pointer == ',') 256033965Sjdp { 256133965Sjdp char *seccmd; 256233965Sjdp 256333965Sjdp ++input_line_pointer; 256433965Sjdp SKIP_WHITESPACE (); 256533965Sjdp seccmd = input_line_pointer; 256633965Sjdp c = get_symbol_end (); 256733965Sjdp if (strcasecmp (seccmd, "absolute") == 0) 256833965Sjdp { 256960484Sobrien as_bad (_("absolute sections are not supported")); 257033965Sjdp *input_line_pointer = c; 257133965Sjdp ignore_rest_of_line (); 257233965Sjdp return; 257333965Sjdp } 257433965Sjdp else if (strcasecmp (seccmd, "align") == 0) 257533965Sjdp { 257633965Sjdp int align; 257733965Sjdp 257833965Sjdp *input_line_pointer = c; 257933965Sjdp align = get_absolute_expression (); 258033965Sjdp record_alignment (seg, align); 258133965Sjdp } 258233965Sjdp else 258333965Sjdp { 258460484Sobrien as_warn (_("unrecognized section command `%s'"), seccmd); 258533965Sjdp *input_line_pointer = c; 258633965Sjdp } 258733965Sjdp } 258833965Sjdp 258933965Sjdp demand_empty_rest_of_line (); 259033965Sjdp 259133965Sjdp#else /* ! TC_I960 */ 259233965Sjdp /* The MRI assembler seems to use different forms of .sect for 259333965Sjdp different targets. */ 259460484Sobrien as_bad ("MRI mode not supported for this target"); 259560484Sobrien ignore_rest_of_line (); 259633965Sjdp#endif /* ! TC_I960 */ 259733965Sjdp#endif /* ! TC_M68K */ 259833965Sjdp} 259933965Sjdp 260033965Sjdp/* Handle the .print pseudo-op. */ 260133965Sjdp 260233965Sjdpvoid 260333965Sjdps_print (ignore) 260460484Sobrien int ignore ATTRIBUTE_UNUSED; 260533965Sjdp{ 260633965Sjdp char *s; 260733965Sjdp int len; 260833965Sjdp 260933965Sjdp s = demand_copy_C_string (&len); 261033965Sjdp printf ("%s\n", s); 261133965Sjdp demand_empty_rest_of_line (); 261233965Sjdp} 261333965Sjdp 261433965Sjdp/* Handle the .purgem pseudo-op. */ 261533965Sjdp 261633965Sjdpvoid 261733965Sjdps_purgem (ignore) 261860484Sobrien int ignore ATTRIBUTE_UNUSED; 261933965Sjdp{ 262033965Sjdp if (is_it_end_of_statement ()) 262133965Sjdp { 262233965Sjdp demand_empty_rest_of_line (); 262333965Sjdp return; 262433965Sjdp } 262533965Sjdp 262633965Sjdp do 262733965Sjdp { 262833965Sjdp char *name; 262933965Sjdp char c; 263033965Sjdp 263133965Sjdp SKIP_WHITESPACE (); 263233965Sjdp name = input_line_pointer; 263333965Sjdp c = get_symbol_end (); 263433965Sjdp delete_macro (name); 263533965Sjdp *input_line_pointer = c; 263633965Sjdp SKIP_WHITESPACE (); 263733965Sjdp } 263833965Sjdp while (*input_line_pointer++ == ','); 263933965Sjdp 264033965Sjdp --input_line_pointer; 264133965Sjdp demand_empty_rest_of_line (); 264233965Sjdp} 264333965Sjdp 264433965Sjdp/* Handle the .rept pseudo-op. */ 264533965Sjdp 264633965Sjdpvoid 264733965Sjdps_rept (ignore) 264860484Sobrien int ignore ATTRIBUTE_UNUSED; 264933965Sjdp{ 265033965Sjdp int count; 265160484Sobrien 265260484Sobrien count = get_absolute_expression (); 265360484Sobrien 265460484Sobrien do_repeat(count, "REPT", "ENDR"); 265560484Sobrien} 265660484Sobrien 265760484Sobrien/* This function provides a generic repeat block implementation. It allows 265860484Sobrien different directives to be used as the start/end keys. */ 265960484Sobrien 266060484Sobrienvoid 266160484Sobriendo_repeat (count, start, end) 266260484Sobrien int count; 266360484Sobrien const char *start; 266460484Sobrien const char *end; 266560484Sobrien{ 266633965Sjdp sb one; 266733965Sjdp sb many; 266833965Sjdp 266933965Sjdp sb_new (&one); 267060484Sobrien if (! buffer_and_nest (start, end, &one, get_line_sb)) 267133965Sjdp { 267260484Sobrien as_bad (_("%s without %s"), start, end); 267333965Sjdp return; 267433965Sjdp } 267533965Sjdp 267633965Sjdp sb_new (&many); 267733965Sjdp while (count-- > 0) 267833965Sjdp sb_add_sb (&many, &one); 267933965Sjdp 268033965Sjdp sb_kill (&one); 268133965Sjdp 268260484Sobrien input_scrub_include_sb (&many, input_line_pointer, 1); 268333965Sjdp sb_kill (&many); 268433965Sjdp buffer_limit = input_scrub_next_buffer (&input_line_pointer); 268533965Sjdp} 268633965Sjdp 268760484Sobrien/* Skip to end of current repeat loop; EXTRA indicates how many additional 268860484Sobrien input buffers to skip. Assumes that conditionals preceding the loop end 268960484Sobrien are properly nested. 269060484Sobrien 269160484Sobrien This function makes it easier to implement a premature "break" out of the 269260484Sobrien loop. The EXTRA arg accounts for other buffers we might have inserted, 269360484Sobrien such as line substitutions. */ 269460484Sobrien 269560484Sobrienvoid 269660484Sobrienend_repeat (extra) 269760484Sobrien int extra; 269860484Sobrien{ 269960484Sobrien cond_exit_macro (macro_nest); 270060484Sobrien while (extra-- >= 0) 270160484Sobrien buffer_limit = input_scrub_next_buffer (&input_line_pointer); 270260484Sobrien} 270360484Sobrien 270433965Sjdp/* Handle the .equ, .equiv and .set directives. If EQUIV is 1, then 270533965Sjdp this is .equiv, and it is an error if the symbol is already 270633965Sjdp defined. */ 270733965Sjdp 270833965Sjdpvoid 270933965Sjdps_set (equiv) 271033965Sjdp int equiv; 271133965Sjdp{ 271233965Sjdp register char *name; 271333965Sjdp register char delim; 271433965Sjdp register char *end_name; 271533965Sjdp register symbolS *symbolP; 271633965Sjdp 271733965Sjdp /* 271833965Sjdp * Especial apologies for the random logic: 271933965Sjdp * this just grew, and could be parsed much more simply! 272033965Sjdp * Dean in haste. 272133965Sjdp */ 272233965Sjdp name = input_line_pointer; 272333965Sjdp delim = get_symbol_end (); 272433965Sjdp end_name = input_line_pointer; 272533965Sjdp *end_name = delim; 272633965Sjdp SKIP_WHITESPACE (); 272733965Sjdp 272833965Sjdp if (*input_line_pointer != ',') 272933965Sjdp { 273033965Sjdp *end_name = 0; 273160484Sobrien as_bad (_("Expected comma after name \"%s\""), name); 273233965Sjdp *end_name = delim; 273333965Sjdp ignore_rest_of_line (); 273433965Sjdp return; 273533965Sjdp } 273633965Sjdp 273733965Sjdp input_line_pointer++; 273833965Sjdp *end_name = 0; 273933965Sjdp 274033965Sjdp if (name[0] == '.' && name[1] == '\0') 274133965Sjdp { 274233965Sjdp /* Turn '. = mumble' into a .org mumble */ 274333965Sjdp register segT segment; 274433965Sjdp expressionS exp; 274533965Sjdp 274633965Sjdp segment = get_known_segmented_expression (&exp); 274733965Sjdp 274833965Sjdp if (!need_pass_2) 274933965Sjdp do_org (segment, &exp, 0); 275033965Sjdp 275133965Sjdp *end_name = delim; 275233965Sjdp return; 275333965Sjdp } 275433965Sjdp 275533965Sjdp if ((symbolP = symbol_find (name)) == NULL 275633965Sjdp && (symbolP = md_undefined_symbol (name)) == NULL) 275733965Sjdp { 275838889Sjdp#ifndef NO_LISTING 275938889Sjdp /* When doing symbol listings, play games with dummy fragments living 276038889Sjdp outside the normal fragment chain to record the file and line info 276138889Sjdp for this symbol. */ 276238889Sjdp if (listing & LISTING_SYMBOLS) 276338889Sjdp { 276438889Sjdp extern struct list_info_struct *listing_tail; 276538889Sjdp fragS *dummy_frag = (fragS *) xmalloc (sizeof(fragS)); 276638889Sjdp memset (dummy_frag, 0, sizeof(fragS)); 276738889Sjdp dummy_frag->fr_type = rs_fill; 276838889Sjdp dummy_frag->line = listing_tail; 276938889Sjdp symbolP = symbol_new (name, undefined_section, 0, dummy_frag); 277038889Sjdp dummy_frag->fr_symbol = symbolP; 277138889Sjdp } 277238889Sjdp else 277338889Sjdp#endif 277438889Sjdp symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag); 277538889Sjdp 277633965Sjdp#ifdef OBJ_COFF 277733965Sjdp /* "set" symbols are local unless otherwise specified. */ 277833965Sjdp SF_SET_LOCAL (symbolP); 277933965Sjdp#endif /* OBJ_COFF */ 278033965Sjdp 278133965Sjdp } /* make a new symbol */ 278233965Sjdp 278333965Sjdp symbol_table_insert (symbolP); 278433965Sjdp 278533965Sjdp *end_name = delim; 278633965Sjdp 278733965Sjdp if (equiv 278833965Sjdp && S_IS_DEFINED (symbolP) 278933965Sjdp && S_GET_SEGMENT (symbolP) != reg_section) 279060484Sobrien as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP)); 279133965Sjdp 279233965Sjdp pseudo_set (symbolP); 279333965Sjdp demand_empty_rest_of_line (); 279433965Sjdp} /* s_set() */ 279533965Sjdp 279633965Sjdpvoid 279733965Sjdps_space (mult) 279833965Sjdp int mult; 279933965Sjdp{ 280033965Sjdp expressionS exp; 280133965Sjdp expressionS val; 280233965Sjdp char *p = 0; 280333965Sjdp char *stop = NULL; 280433965Sjdp char stopc; 280533965Sjdp int bytes; 280633965Sjdp 280733965Sjdp#ifdef md_flush_pending_output 280833965Sjdp md_flush_pending_output (); 280933965Sjdp#endif 281033965Sjdp 281133965Sjdp if (flag_mri) 281233965Sjdp stop = mri_comment_field (&stopc); 281333965Sjdp 281433965Sjdp /* In m68k MRI mode, we need to align to a word boundary, unless 281533965Sjdp this is ds.b. */ 281633965Sjdp if (flag_m68k_mri && mult > 1) 281733965Sjdp { 281833965Sjdp if (now_seg == absolute_section) 281933965Sjdp { 282033965Sjdp abs_section_offset += abs_section_offset & 1; 282133965Sjdp if (line_label != NULL) 282233965Sjdp S_SET_VALUE (line_label, abs_section_offset); 282333965Sjdp } 282433965Sjdp else if (mri_common_symbol != NULL) 282533965Sjdp { 282633965Sjdp valueT val; 282733965Sjdp 282833965Sjdp val = S_GET_VALUE (mri_common_symbol); 282933965Sjdp if ((val & 1) != 0) 283033965Sjdp { 283133965Sjdp S_SET_VALUE (mri_common_symbol, val + 1); 283233965Sjdp if (line_label != NULL) 283333965Sjdp { 283460484Sobrien expressionS *symexp; 283560484Sobrien 283660484Sobrien symexp = symbol_get_value_expression (line_label); 283760484Sobrien know (symexp->X_op == O_symbol); 283860484Sobrien know (symexp->X_add_symbol == mri_common_symbol); 283960484Sobrien symexp->X_add_number += 1; 284033965Sjdp } 284133965Sjdp } 284233965Sjdp } 284333965Sjdp else 284433965Sjdp { 284533965Sjdp do_align (1, (char *) NULL, 0, 0); 284633965Sjdp if (line_label != NULL) 284733965Sjdp { 284860484Sobrien symbol_set_frag (line_label, frag_now); 284933965Sjdp S_SET_VALUE (line_label, frag_now_fix ()); 285033965Sjdp } 285133965Sjdp } 285233965Sjdp } 285333965Sjdp 285433965Sjdp bytes = mult; 285533965Sjdp 285633965Sjdp expression (&exp); 285733965Sjdp 285833965Sjdp SKIP_WHITESPACE (); 285933965Sjdp if (*input_line_pointer == ',') 286033965Sjdp { 286133965Sjdp ++input_line_pointer; 286233965Sjdp expression (&val); 286333965Sjdp } 286433965Sjdp else 286533965Sjdp { 286633965Sjdp val.X_op = O_constant; 286733965Sjdp val.X_add_number = 0; 286833965Sjdp } 286933965Sjdp 287033965Sjdp if (val.X_op != O_constant 287133965Sjdp || val.X_add_number < - 0x80 287233965Sjdp || val.X_add_number > 0xff 287333965Sjdp || (mult != 0 && mult != 1 && val.X_add_number != 0)) 287433965Sjdp { 287533965Sjdp if (exp.X_op != O_constant) 287660484Sobrien as_bad (_("Unsupported variable size or fill value")); 287733965Sjdp else 287833965Sjdp { 287933965Sjdp offsetT i; 288033965Sjdp 288133965Sjdp if (mult == 0) 288233965Sjdp mult = 1; 288333965Sjdp bytes = mult * exp.X_add_number; 288433965Sjdp for (i = 0; i < exp.X_add_number; i++) 288533965Sjdp emit_expr (&val, mult); 288633965Sjdp } 288733965Sjdp } 288833965Sjdp else 288933965Sjdp { 289033965Sjdp if (exp.X_op == O_constant) 289133965Sjdp { 289233965Sjdp long repeat; 289333965Sjdp 289433965Sjdp repeat = exp.X_add_number; 289533965Sjdp if (mult) 289633965Sjdp repeat *= mult; 289733965Sjdp bytes = repeat; 289833965Sjdp if (repeat <= 0) 289933965Sjdp { 290060484Sobrien if (! flag_mri) 290160484Sobrien as_warn (_(".space repeat count is zero, ignored")); 290260484Sobrien else if (repeat < 0) 290360484Sobrien as_warn (_(".space repeat count is negative, ignored")); 290433965Sjdp goto getout; 290533965Sjdp } 290633965Sjdp 290733965Sjdp /* If we are in the absolute section, just bump the offset. */ 290833965Sjdp if (now_seg == absolute_section) 290933965Sjdp { 291033965Sjdp abs_section_offset += repeat; 291133965Sjdp goto getout; 291233965Sjdp } 291333965Sjdp 291433965Sjdp /* If we are secretly in an MRI common section, then 291533965Sjdp creating space just increases the size of the common 291633965Sjdp symbol. */ 291733965Sjdp if (mri_common_symbol != NULL) 291833965Sjdp { 291933965Sjdp S_SET_VALUE (mri_common_symbol, 292033965Sjdp S_GET_VALUE (mri_common_symbol) + repeat); 292133965Sjdp goto getout; 292233965Sjdp } 292333965Sjdp 292433965Sjdp if (!need_pass_2) 292533965Sjdp p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0, 292633965Sjdp (offsetT) repeat, (char *) 0); 292733965Sjdp } 292833965Sjdp else 292933965Sjdp { 293033965Sjdp if (now_seg == absolute_section) 293133965Sjdp { 293260484Sobrien as_bad (_("space allocation too complex in absolute section")); 293333965Sjdp subseg_set (text_section, 0); 293433965Sjdp } 293533965Sjdp if (mri_common_symbol != NULL) 293633965Sjdp { 293760484Sobrien as_bad (_("space allocation too complex in common section")); 293833965Sjdp mri_common_symbol = NULL; 293933965Sjdp } 294033965Sjdp if (!need_pass_2) 294133965Sjdp p = frag_var (rs_space, 1, 1, (relax_substateT) 0, 294233965Sjdp make_expr_symbol (&exp), (offsetT) 0, (char *) 0); 294333965Sjdp } 294433965Sjdp 294533965Sjdp if (p) 294633965Sjdp *p = val.X_add_number; 294733965Sjdp } 294833965Sjdp 294933965Sjdp getout: 295033965Sjdp 295133965Sjdp /* In MRI mode, after an odd number of bytes, we must align to an 295233965Sjdp even word boundary, unless the next instruction is a dc.b, ds.b 295333965Sjdp or dcb.b. */ 295433965Sjdp if (flag_mri && (bytes & 1) != 0) 295533965Sjdp mri_pending_align = 1; 295633965Sjdp 295760484Sobrien demand_empty_rest_of_line (); 295860484Sobrien 295933965Sjdp if (flag_mri) 296033965Sjdp mri_comment_end (stop, stopc); 296133965Sjdp} 296233965Sjdp 296333965Sjdp/* This is like s_space, but the value is a floating point number with 296433965Sjdp the given precision. This is for the MRI dcb.s pseudo-op and 296533965Sjdp friends. */ 296633965Sjdp 296733965Sjdpvoid 296833965Sjdps_float_space (float_type) 296933965Sjdp int float_type; 297033965Sjdp{ 297133965Sjdp offsetT count; 297233965Sjdp int flen; 297333965Sjdp char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT]; 297433965Sjdp char *stop = NULL; 297533965Sjdp char stopc; 297633965Sjdp 297733965Sjdp if (flag_mri) 297833965Sjdp stop = mri_comment_field (&stopc); 297933965Sjdp 298033965Sjdp count = get_absolute_expression (); 298133965Sjdp 298233965Sjdp SKIP_WHITESPACE (); 298333965Sjdp if (*input_line_pointer != ',') 298433965Sjdp { 298560484Sobrien as_bad (_("missing value")); 298660484Sobrien ignore_rest_of_line (); 298733965Sjdp if (flag_mri) 298833965Sjdp mri_comment_end (stop, stopc); 298933965Sjdp return; 299033965Sjdp } 299133965Sjdp 299233965Sjdp ++input_line_pointer; 299333965Sjdp 299433965Sjdp SKIP_WHITESPACE (); 299533965Sjdp 299633965Sjdp /* Skip any 0{letter} that may be present. Don't even check if the 299733965Sjdp * letter is legal. */ 299838889Sjdp if (input_line_pointer[0] == '0' 299938889Sjdp && isalpha ((unsigned char) input_line_pointer[1])) 300033965Sjdp input_line_pointer += 2; 300133965Sjdp 300233965Sjdp /* Accept :xxxx, where the x's are hex digits, for a floating point 300333965Sjdp with the exact digits specified. */ 300433965Sjdp if (input_line_pointer[0] == ':') 300533965Sjdp { 300633965Sjdp flen = hex_float (float_type, temp); 300733965Sjdp if (flen < 0) 300833965Sjdp { 300960484Sobrien ignore_rest_of_line (); 301033965Sjdp if (flag_mri) 301133965Sjdp mri_comment_end (stop, stopc); 301233965Sjdp return; 301333965Sjdp } 301433965Sjdp } 301533965Sjdp else 301633965Sjdp { 301733965Sjdp char *err; 301833965Sjdp 301933965Sjdp err = md_atof (float_type, temp, &flen); 302033965Sjdp know (flen <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT); 302133965Sjdp know (flen > 0); 302233965Sjdp if (err) 302333965Sjdp { 302460484Sobrien as_bad (_("Bad floating literal: %s"), err); 302560484Sobrien ignore_rest_of_line (); 302633965Sjdp if (flag_mri) 302733965Sjdp mri_comment_end (stop, stopc); 302833965Sjdp return; 302933965Sjdp } 303033965Sjdp } 303133965Sjdp 303233965Sjdp while (--count >= 0) 303333965Sjdp { 303433965Sjdp char *p; 303533965Sjdp 303633965Sjdp p = frag_more (flen); 303733965Sjdp memcpy (p, temp, (unsigned int) flen); 303833965Sjdp } 303933965Sjdp 304060484Sobrien demand_empty_rest_of_line (); 304160484Sobrien 304233965Sjdp if (flag_mri) 304333965Sjdp mri_comment_end (stop, stopc); 304433965Sjdp} 304533965Sjdp 304633965Sjdp/* Handle the .struct pseudo-op, as found in MIPS assemblers. */ 304733965Sjdp 304833965Sjdpvoid 304933965Sjdps_struct (ignore) 305060484Sobrien int ignore ATTRIBUTE_UNUSED; 305133965Sjdp{ 305233965Sjdp char *stop = NULL; 305333965Sjdp char stopc; 305433965Sjdp 305533965Sjdp if (flag_mri) 305633965Sjdp stop = mri_comment_field (&stopc); 305733965Sjdp abs_section_offset = get_absolute_expression (); 305833965Sjdp subseg_set (absolute_section, 0); 305960484Sobrien demand_empty_rest_of_line (); 306033965Sjdp if (flag_mri) 306133965Sjdp mri_comment_end (stop, stopc); 306233965Sjdp} 306333965Sjdp 306433965Sjdpvoid 306533965Sjdps_text (ignore) 306660484Sobrien int ignore ATTRIBUTE_UNUSED; 306733965Sjdp{ 306833965Sjdp register int temp; 306933965Sjdp 307033965Sjdp temp = get_absolute_expression (); 307133965Sjdp subseg_set (text_section, (subsegT) temp); 307233965Sjdp demand_empty_rest_of_line (); 307333965Sjdp#ifdef OBJ_VMS 307433965Sjdp const_flag &= ~IN_DEFAULT_SECTION; 307533965Sjdp#endif 307633965Sjdp} /* s_text() */ 307733965Sjdp 307833965Sjdp 307933965Sjdpvoid 308033965Sjdpdemand_empty_rest_of_line () 308133965Sjdp{ 308233965Sjdp SKIP_WHITESPACE (); 308333965Sjdp if (is_end_of_line[(unsigned char) *input_line_pointer]) 308433965Sjdp { 308533965Sjdp input_line_pointer++; 308633965Sjdp } 308733965Sjdp else 308833965Sjdp { 308933965Sjdp ignore_rest_of_line (); 309033965Sjdp } 309133965Sjdp /* Return having already swallowed end-of-line. */ 309233965Sjdp} /* Return pointing just after end-of-line. */ 309333965Sjdp 309433965Sjdpvoid 309533965Sjdpignore_rest_of_line () /* For suspect lines: gives warning. */ 309633965Sjdp{ 309733965Sjdp if (!is_end_of_line[(unsigned char) *input_line_pointer]) 309833965Sjdp { 309938889Sjdp if (isprint ((unsigned char) *input_line_pointer)) 310060484Sobrien as_bad (_("Rest of line ignored. First ignored character is `%c'."), 310133965Sjdp *input_line_pointer); 310233965Sjdp else 310360484Sobrien as_bad (_("Rest of line ignored. First ignored character valued 0x%x."), 310433965Sjdp *input_line_pointer); 310533965Sjdp while (input_line_pointer < buffer_limit 310633965Sjdp && !is_end_of_line[(unsigned char) *input_line_pointer]) 310733965Sjdp { 310833965Sjdp input_line_pointer++; 310933965Sjdp } 311033965Sjdp } 311133965Sjdp input_line_pointer++; /* Return pointing just after end-of-line. */ 311233965Sjdp know (is_end_of_line[(unsigned char) input_line_pointer[-1]]); 311333965Sjdp} 311433965Sjdp 311560484Sobrienvoid 311660484Sobriendiscard_rest_of_line () 311760484Sobrien{ 311860484Sobrien while (input_line_pointer < buffer_limit 311960484Sobrien && !is_end_of_line[(unsigned char) *input_line_pointer]) 312060484Sobrien { 312160484Sobrien input_line_pointer++; 312260484Sobrien } 312360484Sobrien input_line_pointer++; /* Return pointing just after end-of-line. */ 312460484Sobrien know (is_end_of_line[(unsigned char) input_line_pointer[-1]]); 312560484Sobrien} 312660484Sobrien 312733965Sjdp/* 312833965Sjdp * pseudo_set() 312933965Sjdp * 313033965Sjdp * In: Pointer to a symbol. 313133965Sjdp * Input_line_pointer->expression. 313233965Sjdp * 313333965Sjdp * Out: Input_line_pointer->just after any whitespace after expression. 313433965Sjdp * Tried to set symbol to value of expression. 313533965Sjdp * Will change symbols type, value, and frag; 313633965Sjdp */ 313733965Sjdpvoid 313833965Sjdppseudo_set (symbolP) 313933965Sjdp symbolS *symbolP; 314033965Sjdp{ 314133965Sjdp expressionS exp; 314233965Sjdp#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER) 314333965Sjdp int ext; 314433965Sjdp#endif /* OBJ_AOUT or OBJ_BOUT */ 314533965Sjdp 314633965Sjdp know (symbolP); /* NULL pointer is logic error. */ 314733965Sjdp#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER) 314833965Sjdp ext = S_IS_EXTERNAL (symbolP); 314933965Sjdp#endif /* OBJ_AOUT or OBJ_BOUT */ 315033965Sjdp 315133965Sjdp (void) expression (&exp); 315233965Sjdp 315333965Sjdp if (exp.X_op == O_illegal) 315460484Sobrien as_bad (_("illegal expression; zero assumed")); 315533965Sjdp else if (exp.X_op == O_absent) 315660484Sobrien as_bad (_("missing expression; zero assumed")); 315733965Sjdp else if (exp.X_op == O_big) 315860484Sobrien { 315960484Sobrien if (exp.X_add_number > 0) 316060484Sobrien as_bad (_("bignum invalid; zero assumed")); 316160484Sobrien else 316260484Sobrien as_bad (_("floating point number invalid; zero assumed")); 316360484Sobrien } 316433965Sjdp else if (exp.X_op == O_subtract 316533965Sjdp && (S_GET_SEGMENT (exp.X_add_symbol) 316633965Sjdp == S_GET_SEGMENT (exp.X_op_symbol)) 316733965Sjdp && SEG_NORMAL (S_GET_SEGMENT (exp.X_add_symbol)) 316860484Sobrien && (symbol_get_frag (exp.X_add_symbol) 316960484Sobrien == symbol_get_frag (exp.X_op_symbol))) 317033965Sjdp { 317133965Sjdp exp.X_op = O_constant; 317233965Sjdp exp.X_add_number = (S_GET_VALUE (exp.X_add_symbol) 317333965Sjdp - S_GET_VALUE (exp.X_op_symbol)); 317433965Sjdp } 317533965Sjdp 317633965Sjdp switch (exp.X_op) 317733965Sjdp { 317833965Sjdp case O_illegal: 317933965Sjdp case O_absent: 318033965Sjdp case O_big: 318133965Sjdp exp.X_add_number = 0; 318233965Sjdp /* Fall through. */ 318333965Sjdp case O_constant: 318433965Sjdp S_SET_SEGMENT (symbolP, absolute_section); 318533965Sjdp#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER) 318633965Sjdp if (ext) 318733965Sjdp S_SET_EXTERNAL (symbolP); 318833965Sjdp else 318933965Sjdp S_CLEAR_EXTERNAL (symbolP); 319033965Sjdp#endif /* OBJ_AOUT or OBJ_BOUT */ 319133965Sjdp S_SET_VALUE (symbolP, (valueT) exp.X_add_number); 319238889Sjdp if (exp.X_op != O_constant) 319360484Sobrien symbol_set_frag (symbolP, &zero_address_frag); 319433965Sjdp break; 319533965Sjdp 319633965Sjdp case O_register: 319733965Sjdp S_SET_SEGMENT (symbolP, reg_section); 319833965Sjdp S_SET_VALUE (symbolP, (valueT) exp.X_add_number); 319960484Sobrien symbol_set_frag (symbolP, &zero_address_frag); 320033965Sjdp break; 320133965Sjdp 320233965Sjdp case O_symbol: 320333965Sjdp if (S_GET_SEGMENT (exp.X_add_symbol) == undefined_section 320433965Sjdp || exp.X_add_number != 0) 320560484Sobrien symbol_set_value_expression (symbolP, &exp); 320660484Sobrien else if (symbol_section_p (symbolP)) 320760484Sobrien as_bad ("invalid attempt to set value of section symbol"); 320833965Sjdp else 320933965Sjdp { 321033965Sjdp symbolS *s = exp.X_add_symbol; 321133965Sjdp 321233965Sjdp S_SET_SEGMENT (symbolP, S_GET_SEGMENT (s)); 321333965Sjdp#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER) 321433965Sjdp if (ext) 321533965Sjdp S_SET_EXTERNAL (symbolP); 321633965Sjdp else 321733965Sjdp S_CLEAR_EXTERNAL (symbolP); 321833965Sjdp#endif /* OBJ_AOUT or OBJ_BOUT */ 321933965Sjdp S_SET_VALUE (symbolP, 322033965Sjdp exp.X_add_number + S_GET_VALUE (s)); 322160484Sobrien symbol_set_frag (symbolP, symbol_get_frag (s)); 322233965Sjdp copy_symbol_attributes (symbolP, s); 322333965Sjdp } 322433965Sjdp break; 322533965Sjdp 322633965Sjdp default: 322733965Sjdp /* The value is some complex expression. 322833965Sjdp FIXME: Should we set the segment to anything? */ 322960484Sobrien symbol_set_value_expression (symbolP, &exp); 323033965Sjdp break; 323133965Sjdp } 323233965Sjdp} 323333965Sjdp 323433965Sjdp/* 323533965Sjdp * cons() 323633965Sjdp * 323733965Sjdp * CONStruct more frag of .bytes, or .words etc. 323833965Sjdp * Should need_pass_2 be 1 then emit no frag(s). 323933965Sjdp * This understands EXPRESSIONS. 324033965Sjdp * 324133965Sjdp * Bug (?) 324233965Sjdp * 324333965Sjdp * This has a split personality. We use expression() to read the 324433965Sjdp * value. We can detect if the value won't fit in a byte or word. 324533965Sjdp * But we can't detect if expression() discarded significant digits 324633965Sjdp * in the case of a long. Not worth the crocks required to fix it. 324733965Sjdp */ 324833965Sjdp 324933965Sjdp/* Select a parser for cons expressions. */ 325033965Sjdp 325133965Sjdp/* Some targets need to parse the expression in various fancy ways. 325233965Sjdp You can define TC_PARSE_CONS_EXPRESSION to do whatever you like 325333965Sjdp (for example, the HPPA does this). Otherwise, you can define 325433965Sjdp BITFIELD_CONS_EXPRESSIONS to permit bitfields to be specified, or 325533965Sjdp REPEAT_CONS_EXPRESSIONS to permit repeat counts. If none of these 325633965Sjdp are defined, which is the normal case, then only simple expressions 325733965Sjdp are permitted. */ 325833965Sjdp 325960484Sobrien#ifdef TC_M68K 326033965Sjdpstatic void 326133965Sjdpparse_mri_cons PARAMS ((expressionS *exp, unsigned int nbytes)); 326260484Sobrien#endif 326333965Sjdp 326433965Sjdp#ifndef TC_PARSE_CONS_EXPRESSION 326533965Sjdp#ifdef BITFIELD_CONS_EXPRESSIONS 326633965Sjdp#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_bitfield_cons (EXP, NBYTES) 326733965Sjdpstatic void 326833965Sjdpparse_bitfield_cons PARAMS ((expressionS *exp, unsigned int nbytes)); 326933965Sjdp#endif 327033965Sjdp#ifdef REPEAT_CONS_EXPRESSIONS 327133965Sjdp#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_repeat_cons (EXP, NBYTES) 327233965Sjdpstatic void 327333965Sjdpparse_repeat_cons PARAMS ((expressionS *exp, unsigned int nbytes)); 327433965Sjdp#endif 327533965Sjdp 327633965Sjdp/* If we haven't gotten one yet, just call expression. */ 327733965Sjdp#ifndef TC_PARSE_CONS_EXPRESSION 327833965Sjdp#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) expression (EXP) 327933965Sjdp#endif 328033965Sjdp#endif 328133965Sjdp 328233965Sjdp/* worker to do .byte etc statements */ 328333965Sjdp/* clobbers input_line_pointer, checks */ 328433965Sjdp/* end-of-line. */ 328533965Sjdpstatic void 328633965Sjdpcons_worker (nbytes, rva) 328733965Sjdp register int nbytes; /* 1=.byte, 2=.word, 4=.long */ 328833965Sjdp int rva; 328933965Sjdp{ 329033965Sjdp int c; 329133965Sjdp expressionS exp; 329233965Sjdp char *stop = NULL; 329333965Sjdp char stopc; 329433965Sjdp 329533965Sjdp#ifdef md_flush_pending_output 329633965Sjdp md_flush_pending_output (); 329733965Sjdp#endif 329833965Sjdp 329933965Sjdp if (flag_mri) 330033965Sjdp stop = mri_comment_field (&stopc); 330133965Sjdp 330233965Sjdp if (is_it_end_of_statement ()) 330333965Sjdp { 330460484Sobrien demand_empty_rest_of_line (); 330533965Sjdp if (flag_mri) 330633965Sjdp mri_comment_end (stop, stopc); 330733965Sjdp return; 330833965Sjdp } 330933965Sjdp 331033965Sjdp#ifdef md_cons_align 331133965Sjdp md_cons_align (nbytes); 331233965Sjdp#endif 331333965Sjdp 331433965Sjdp c = 0; 331533965Sjdp do 331633965Sjdp { 331760484Sobrien#ifdef TC_M68K 331833965Sjdp if (flag_m68k_mri) 331933965Sjdp parse_mri_cons (&exp, (unsigned int) nbytes); 332033965Sjdp else 332160484Sobrien#endif 332233965Sjdp TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes); 332333965Sjdp 332433965Sjdp if (rva) 332533965Sjdp { 332633965Sjdp if (exp.X_op == O_symbol) 332733965Sjdp exp.X_op = O_symbol_rva; 332833965Sjdp else 332960484Sobrien as_fatal (_("rva without symbol")); 333033965Sjdp } 333133965Sjdp emit_expr (&exp, (unsigned int) nbytes); 333233965Sjdp ++c; 333333965Sjdp } 333433965Sjdp while (*input_line_pointer++ == ','); 333533965Sjdp 333633965Sjdp /* In MRI mode, after an odd number of bytes, we must align to an 333733965Sjdp even word boundary, unless the next instruction is a dc.b, ds.b 333833965Sjdp or dcb.b. */ 333933965Sjdp if (flag_mri && nbytes == 1 && (c & 1) != 0) 334033965Sjdp mri_pending_align = 1; 334133965Sjdp 334233965Sjdp input_line_pointer--; /* Put terminator back into stream. */ 334333965Sjdp 334460484Sobrien demand_empty_rest_of_line (); 334560484Sobrien 334633965Sjdp if (flag_mri) 334733965Sjdp mri_comment_end (stop, stopc); 334833965Sjdp} 334933965Sjdp 335033965Sjdp 335133965Sjdpvoid 335233965Sjdpcons (size) 335333965Sjdp int size; 335433965Sjdp{ 335533965Sjdp cons_worker (size, 0); 335633965Sjdp} 335733965Sjdp 335833965Sjdpvoid 335933965Sjdps_rva (size) 336033965Sjdp int size; 336133965Sjdp{ 336233965Sjdp cons_worker (size, 1); 336333965Sjdp} 336433965Sjdp 336533965Sjdp/* Put the contents of expression EXP into the object file using 336633965Sjdp NBYTES bytes. If need_pass_2 is 1, this does nothing. */ 336733965Sjdp 336833965Sjdpvoid 336933965Sjdpemit_expr (exp, nbytes) 337033965Sjdp expressionS *exp; 337133965Sjdp unsigned int nbytes; 337233965Sjdp{ 337333965Sjdp operatorT op; 337433965Sjdp register char *p; 337533965Sjdp valueT extra_digit = 0; 337633965Sjdp 337733965Sjdp /* Don't do anything if we are going to make another pass. */ 337833965Sjdp if (need_pass_2) 337933965Sjdp return; 338033965Sjdp 338138889Sjdp#ifndef NO_LISTING 338238889Sjdp#ifdef OBJ_ELF 338338889Sjdp /* When gcc emits DWARF 1 debugging pseudo-ops, a line number will 338438889Sjdp appear as a four byte positive constant in the .line section, 338538889Sjdp followed by a 2 byte 0xffff. Look for that case here. */ 338638889Sjdp { 338738889Sjdp static int dwarf_line = -1; 338838889Sjdp 338938889Sjdp if (strcmp (segment_name (now_seg), ".line") != 0) 339038889Sjdp dwarf_line = -1; 339138889Sjdp else if (dwarf_line >= 0 339238889Sjdp && nbytes == 2 339338889Sjdp && exp->X_op == O_constant 339438889Sjdp && (exp->X_add_number == -1 || exp->X_add_number == 0xffff)) 339538889Sjdp listing_source_line ((unsigned int) dwarf_line); 339638889Sjdp else if (nbytes == 4 339738889Sjdp && exp->X_op == O_constant 339838889Sjdp && exp->X_add_number >= 0) 339938889Sjdp dwarf_line = exp->X_add_number; 340038889Sjdp else 340138889Sjdp dwarf_line = -1; 340238889Sjdp } 340338889Sjdp 340438889Sjdp /* When gcc emits DWARF 1 debugging pseudo-ops, a file name will 340538889Sjdp appear as a 2 byte TAG_compile_unit (0x11) followed by a 2 byte 340638889Sjdp AT_sibling (0x12) followed by a four byte address of the sibling 340738889Sjdp followed by a 2 byte AT_name (0x38) followed by the name of the 340838889Sjdp file. We look for that case here. */ 340938889Sjdp { 341038889Sjdp static int dwarf_file = 0; 341138889Sjdp 341238889Sjdp if (strcmp (segment_name (now_seg), ".debug") != 0) 341338889Sjdp dwarf_file = 0; 341438889Sjdp else if (dwarf_file == 0 341538889Sjdp && nbytes == 2 341638889Sjdp && exp->X_op == O_constant 341738889Sjdp && exp->X_add_number == 0x11) 341838889Sjdp dwarf_file = 1; 341938889Sjdp else if (dwarf_file == 1 342038889Sjdp && nbytes == 2 342138889Sjdp && exp->X_op == O_constant 342238889Sjdp && exp->X_add_number == 0x12) 342338889Sjdp dwarf_file = 2; 342438889Sjdp else if (dwarf_file == 2 342538889Sjdp && nbytes == 4) 342638889Sjdp dwarf_file = 3; 342738889Sjdp else if (dwarf_file == 3 342838889Sjdp && nbytes == 2 342938889Sjdp && exp->X_op == O_constant 343038889Sjdp && exp->X_add_number == 0x38) 343138889Sjdp dwarf_file = 4; 343238889Sjdp else 343338889Sjdp dwarf_file = 0; 343438889Sjdp 343538889Sjdp /* The variable dwarf_file_string tells stringer that the string 343638889Sjdp may be the name of the source file. */ 343738889Sjdp if (dwarf_file == 4) 343838889Sjdp dwarf_file_string = 1; 343938889Sjdp else 344038889Sjdp dwarf_file_string = 0; 344138889Sjdp } 344238889Sjdp#endif 344338889Sjdp#endif 344438889Sjdp 344538889Sjdp if (check_eh_frame (exp, &nbytes)) 344638889Sjdp return; 344738889Sjdp 344833965Sjdp op = exp->X_op; 344933965Sjdp 345033965Sjdp /* Allow `.word 0' in the absolute section. */ 345133965Sjdp if (now_seg == absolute_section) 345233965Sjdp { 345333965Sjdp if (op != O_constant || exp->X_add_number != 0) 345460484Sobrien as_bad (_("attempt to store value in absolute section")); 345533965Sjdp abs_section_offset += nbytes; 345633965Sjdp return; 345733965Sjdp } 345833965Sjdp 345933965Sjdp /* Handle a negative bignum. */ 346033965Sjdp if (op == O_uminus 346133965Sjdp && exp->X_add_number == 0 346260484Sobrien && symbol_get_value_expression (exp->X_add_symbol)->X_op == O_big 346360484Sobrien && symbol_get_value_expression (exp->X_add_symbol)->X_add_number > 0) 346433965Sjdp { 346533965Sjdp int i; 346633965Sjdp unsigned long carry; 346733965Sjdp 346860484Sobrien exp = symbol_get_value_expression (exp->X_add_symbol); 346933965Sjdp 347033965Sjdp /* Negate the bignum: one's complement each digit and add 1. */ 347133965Sjdp carry = 1; 347233965Sjdp for (i = 0; i < exp->X_add_number; i++) 347333965Sjdp { 347433965Sjdp unsigned long next; 347533965Sjdp 347633965Sjdp next = (((~ (generic_bignum[i] & LITTLENUM_MASK)) 347733965Sjdp & LITTLENUM_MASK) 347833965Sjdp + carry); 347933965Sjdp generic_bignum[i] = next & LITTLENUM_MASK; 348033965Sjdp carry = next >> LITTLENUM_NUMBER_OF_BITS; 348133965Sjdp } 348233965Sjdp 348333965Sjdp /* We can ignore any carry out, because it will be handled by 348433965Sjdp extra_digit if it is needed. */ 348533965Sjdp 348633965Sjdp extra_digit = (valueT) -1; 348733965Sjdp op = O_big; 348833965Sjdp } 348933965Sjdp 349033965Sjdp if (op == O_absent || op == O_illegal) 349133965Sjdp { 349260484Sobrien as_warn (_("zero assumed for missing expression")); 349333965Sjdp exp->X_add_number = 0; 349433965Sjdp op = O_constant; 349533965Sjdp } 349633965Sjdp else if (op == O_big && exp->X_add_number <= 0) 349733965Sjdp { 349860484Sobrien as_bad (_("floating point number invalid; zero assumed")); 349933965Sjdp exp->X_add_number = 0; 350033965Sjdp op = O_constant; 350133965Sjdp } 350233965Sjdp else if (op == O_register) 350333965Sjdp { 350460484Sobrien as_warn (_("register value used as expression")); 350533965Sjdp op = O_constant; 350633965Sjdp } 350733965Sjdp 350833965Sjdp p = frag_more ((int) nbytes); 350933965Sjdp 351033965Sjdp#ifndef WORKING_DOT_WORD 351133965Sjdp /* If we have the difference of two symbols in a word, save it on 351233965Sjdp the broken_words list. See the code in write.c. */ 351333965Sjdp if (op == O_subtract && nbytes == 2) 351433965Sjdp { 351533965Sjdp struct broken_word *x; 351633965Sjdp 351733965Sjdp x = (struct broken_word *) xmalloc (sizeof (struct broken_word)); 351833965Sjdp x->next_broken_word = broken_words; 351933965Sjdp broken_words = x; 352060484Sobrien x->seg = now_seg; 352160484Sobrien x->subseg = now_subseg; 352233965Sjdp x->frag = frag_now; 352333965Sjdp x->word_goes_here = p; 352433965Sjdp x->dispfrag = 0; 352533965Sjdp x->add = exp->X_add_symbol; 352633965Sjdp x->sub = exp->X_op_symbol; 352733965Sjdp x->addnum = exp->X_add_number; 352833965Sjdp x->added = 0; 352933965Sjdp new_broken_words++; 353033965Sjdp return; 353133965Sjdp } 353233965Sjdp#endif 353333965Sjdp 353433965Sjdp /* If we have an integer, but the number of bytes is too large to 353533965Sjdp pass to md_number_to_chars, handle it as a bignum. */ 353633965Sjdp if (op == O_constant && nbytes > sizeof (valueT)) 353733965Sjdp { 353833965Sjdp valueT val; 353933965Sjdp int gencnt; 354033965Sjdp 354133965Sjdp if (! exp->X_unsigned && exp->X_add_number < 0) 354233965Sjdp extra_digit = (valueT) -1; 354333965Sjdp val = (valueT) exp->X_add_number; 354433965Sjdp gencnt = 0; 354533965Sjdp do 354633965Sjdp { 354733965Sjdp generic_bignum[gencnt] = val & LITTLENUM_MASK; 354833965Sjdp val >>= LITTLENUM_NUMBER_OF_BITS; 354933965Sjdp ++gencnt; 355033965Sjdp } 355133965Sjdp while (val != 0); 355233965Sjdp op = exp->X_op = O_big; 355333965Sjdp exp->X_add_number = gencnt; 355433965Sjdp } 355533965Sjdp 355633965Sjdp if (op == O_constant) 355733965Sjdp { 355833965Sjdp register valueT get; 355933965Sjdp register valueT use; 356033965Sjdp register valueT mask; 356133965Sjdp valueT hibit; 356233965Sjdp register valueT unmask; 356333965Sjdp 356433965Sjdp /* JF << of >= number of bits in the object is undefined. In 356533965Sjdp particular SPARC (Sun 4) has problems */ 356633965Sjdp if (nbytes >= sizeof (valueT)) 356733965Sjdp { 356833965Sjdp mask = 0; 356933965Sjdp if (nbytes > sizeof (valueT)) 357033965Sjdp hibit = 0; 357133965Sjdp else 357233965Sjdp hibit = (valueT) 1 << (nbytes * BITS_PER_CHAR - 1); 357333965Sjdp } 357433965Sjdp else 357533965Sjdp { 357633965Sjdp /* Don't store these bits. */ 357733965Sjdp mask = ~(valueT) 0 << (BITS_PER_CHAR * nbytes); 357833965Sjdp hibit = (valueT) 1 << (nbytes * BITS_PER_CHAR - 1); 357933965Sjdp } 358033965Sjdp 358133965Sjdp unmask = ~mask; /* Do store these bits. */ 358233965Sjdp 358333965Sjdp#ifdef NEVER 358433965Sjdp "Do this mod if you want every overflow check to assume SIGNED 2's complement data."; 358533965Sjdp mask = ~(unmask >> 1); /* Includes sign bit now. */ 358633965Sjdp#endif 358733965Sjdp 358833965Sjdp get = exp->X_add_number; 358933965Sjdp use = get & unmask; 359033965Sjdp if ((get & mask) != 0 359133965Sjdp && ((get & mask) != mask 359233965Sjdp || (get & hibit) == 0)) 359333965Sjdp { /* Leading bits contain both 0s & 1s. */ 359460484Sobrien as_warn (_("Value 0x%lx truncated to 0x%lx."), 359533965Sjdp (unsigned long) get, (unsigned long) use); 359633965Sjdp } 359733965Sjdp /* put bytes in right order. */ 359833965Sjdp md_number_to_chars (p, use, (int) nbytes); 359933965Sjdp } 360033965Sjdp else if (op == O_big) 360133965Sjdp { 360238889Sjdp unsigned int size; 360333965Sjdp LITTLENUM_TYPE *nums; 360433965Sjdp 360533965Sjdp know (nbytes % CHARS_PER_LITTLENUM == 0); 360633965Sjdp 360733965Sjdp size = exp->X_add_number * CHARS_PER_LITTLENUM; 360833965Sjdp if (nbytes < size) 360933965Sjdp { 361060484Sobrien as_warn (_("Bignum truncated to %d bytes"), nbytes); 361133965Sjdp size = nbytes; 361233965Sjdp } 361333965Sjdp 361433965Sjdp if (target_big_endian) 361533965Sjdp { 361633965Sjdp while (nbytes > size) 361733965Sjdp { 361833965Sjdp md_number_to_chars (p, extra_digit, CHARS_PER_LITTLENUM); 361933965Sjdp nbytes -= CHARS_PER_LITTLENUM; 362033965Sjdp p += CHARS_PER_LITTLENUM; 362133965Sjdp } 362233965Sjdp 362333965Sjdp nums = generic_bignum + size / CHARS_PER_LITTLENUM; 362433965Sjdp while (size > 0) 362533965Sjdp { 362633965Sjdp --nums; 362733965Sjdp md_number_to_chars (p, (valueT) *nums, CHARS_PER_LITTLENUM); 362833965Sjdp size -= CHARS_PER_LITTLENUM; 362933965Sjdp p += CHARS_PER_LITTLENUM; 363033965Sjdp } 363133965Sjdp } 363233965Sjdp else 363333965Sjdp { 363433965Sjdp nums = generic_bignum; 363533965Sjdp while (size > 0) 363633965Sjdp { 363733965Sjdp md_number_to_chars (p, (valueT) *nums, CHARS_PER_LITTLENUM); 363833965Sjdp ++nums; 363933965Sjdp size -= CHARS_PER_LITTLENUM; 364033965Sjdp p += CHARS_PER_LITTLENUM; 364133965Sjdp nbytes -= CHARS_PER_LITTLENUM; 364233965Sjdp } 364333965Sjdp 364433965Sjdp while (nbytes > 0) 364533965Sjdp { 364633965Sjdp md_number_to_chars (p, extra_digit, CHARS_PER_LITTLENUM); 364733965Sjdp nbytes -= CHARS_PER_LITTLENUM; 364833965Sjdp p += CHARS_PER_LITTLENUM; 364933965Sjdp } 365033965Sjdp } 365133965Sjdp } 365233965Sjdp else 365333965Sjdp { 365433965Sjdp memset (p, 0, nbytes); 365533965Sjdp 365633965Sjdp /* Now we need to generate a fixS to record the symbol value. 365733965Sjdp This is easy for BFD. For other targets it can be more 365833965Sjdp complex. For very complex cases (currently, the HPPA and 365933965Sjdp NS32K), you can define TC_CONS_FIX_NEW to do whatever you 366033965Sjdp want. For simpler cases, you can define TC_CONS_RELOC to be 366133965Sjdp the name of the reloc code that should be stored in the fixS. 366233965Sjdp If neither is defined, the code uses NO_RELOC if it is 366333965Sjdp defined, and otherwise uses 0. */ 366433965Sjdp 366533965Sjdp#ifdef BFD_ASSEMBLER 366633965Sjdp#ifdef TC_CONS_FIX_NEW 366733965Sjdp TC_CONS_FIX_NEW (frag_now, p - frag_now->fr_literal, nbytes, exp); 366833965Sjdp#else 366933965Sjdp { 367033965Sjdp bfd_reloc_code_real_type r; 367133965Sjdp 367233965Sjdp switch (nbytes) 367333965Sjdp { 367433965Sjdp case 1: 367533965Sjdp r = BFD_RELOC_8; 367633965Sjdp break; 367733965Sjdp case 2: 367833965Sjdp r = BFD_RELOC_16; 367933965Sjdp break; 368033965Sjdp case 4: 368133965Sjdp r = BFD_RELOC_32; 368233965Sjdp break; 368333965Sjdp case 8: 368433965Sjdp r = BFD_RELOC_64; 368533965Sjdp break; 368633965Sjdp default: 368760484Sobrien as_bad (_("unsupported BFD relocation size %u"), nbytes); 368833965Sjdp r = BFD_RELOC_32; 368933965Sjdp break; 369033965Sjdp } 369133965Sjdp fix_new_exp (frag_now, p - frag_now->fr_literal, (int) nbytes, exp, 369233965Sjdp 0, r); 369333965Sjdp } 369433965Sjdp#endif 369533965Sjdp#else 369633965Sjdp#ifdef TC_CONS_FIX_NEW 369733965Sjdp TC_CONS_FIX_NEW (frag_now, p - frag_now->fr_literal, nbytes, exp); 369833965Sjdp#else 369933965Sjdp /* Figure out which reloc number to use. Use TC_CONS_RELOC if 370033965Sjdp it is defined, otherwise use NO_RELOC if it is defined, 370133965Sjdp otherwise use 0. */ 370233965Sjdp#ifndef TC_CONS_RELOC 370333965Sjdp#ifdef NO_RELOC 370433965Sjdp#define TC_CONS_RELOC NO_RELOC 370533965Sjdp#else 370633965Sjdp#define TC_CONS_RELOC 0 370733965Sjdp#endif 370833965Sjdp#endif 370933965Sjdp fix_new_exp (frag_now, p - frag_now->fr_literal, (int) nbytes, exp, 0, 371033965Sjdp TC_CONS_RELOC); 371133965Sjdp#endif /* TC_CONS_FIX_NEW */ 371233965Sjdp#endif /* BFD_ASSEMBLER */ 371333965Sjdp } 371433965Sjdp} 371533965Sjdp 371633965Sjdp#ifdef BITFIELD_CONS_EXPRESSIONS 371733965Sjdp 371833965Sjdp/* i960 assemblers, (eg, asm960), allow bitfields after ".byte" as 371933965Sjdp w:x,y:z, where w and y are bitwidths and x and y are values. They 372033965Sjdp then pack them all together. We do a little better in that we allow 372133965Sjdp them in words, longs, etc. and we'll pack them in target byte order 372233965Sjdp for you. 372333965Sjdp 372433965Sjdp The rules are: pack least significat bit first, if a field doesn't 372533965Sjdp entirely fit, put it in the next unit. Overflowing the bitfield is 372633965Sjdp explicitly *not* even a warning. The bitwidth should be considered 372733965Sjdp a "mask". 372833965Sjdp 372933965Sjdp To use this function the tc-XXX.h file should define 373033965Sjdp BITFIELD_CONS_EXPRESSIONS. */ 373133965Sjdp 373233965Sjdpstatic void 373333965Sjdpparse_bitfield_cons (exp, nbytes) 373433965Sjdp expressionS *exp; 373533965Sjdp unsigned int nbytes; 373633965Sjdp{ 373733965Sjdp unsigned int bits_available = BITS_PER_CHAR * nbytes; 373833965Sjdp char *hold = input_line_pointer; 373933965Sjdp 374033965Sjdp (void) expression (exp); 374133965Sjdp 374233965Sjdp if (*input_line_pointer == ':') 374333965Sjdp { /* bitfields */ 374433965Sjdp long value = 0; 374533965Sjdp 374633965Sjdp for (;;) 374733965Sjdp { 374833965Sjdp unsigned long width; 374933965Sjdp 375033965Sjdp if (*input_line_pointer != ':') 375133965Sjdp { 375233965Sjdp input_line_pointer = hold; 375333965Sjdp break; 375433965Sjdp } /* next piece is not a bitfield */ 375533965Sjdp 375633965Sjdp /* In the general case, we can't allow 375733965Sjdp full expressions with symbol 375833965Sjdp differences and such. The relocation 375933965Sjdp entries for symbols not defined in this 376033965Sjdp assembly would require arbitrary field 376133965Sjdp widths, positions, and masks which most 376233965Sjdp of our current object formats don't 376333965Sjdp support. 376433965Sjdp 376533965Sjdp In the specific case where a symbol 376633965Sjdp *is* defined in this assembly, we 376733965Sjdp *could* build fixups and track it, but 376833965Sjdp this could lead to confusion for the 376933965Sjdp backends. I'm lazy. I'll take any 377033965Sjdp SEG_ABSOLUTE. I think that means that 377133965Sjdp you can use a previous .set or 377233965Sjdp .equ type symbol. xoxorich. */ 377333965Sjdp 377433965Sjdp if (exp->X_op == O_absent) 377533965Sjdp { 377660484Sobrien as_warn (_("using a bit field width of zero")); 377733965Sjdp exp->X_add_number = 0; 377833965Sjdp exp->X_op = O_constant; 377933965Sjdp } /* implied zero width bitfield */ 378033965Sjdp 378133965Sjdp if (exp->X_op != O_constant) 378233965Sjdp { 378333965Sjdp *input_line_pointer = '\0'; 378460484Sobrien as_bad (_("field width \"%s\" too complex for a bitfield"), hold); 378533965Sjdp *input_line_pointer = ':'; 378633965Sjdp demand_empty_rest_of_line (); 378733965Sjdp return; 378833965Sjdp } /* too complex */ 378933965Sjdp 379033965Sjdp if ((width = exp->X_add_number) > (BITS_PER_CHAR * nbytes)) 379133965Sjdp { 379260484Sobrien as_warn (_("field width %lu too big to fit in %d bytes: truncated to %d bits"), 379333965Sjdp width, nbytes, (BITS_PER_CHAR * nbytes)); 379433965Sjdp width = BITS_PER_CHAR * nbytes; 379533965Sjdp } /* too big */ 379633965Sjdp 379733965Sjdp if (width > bits_available) 379833965Sjdp { 379933965Sjdp /* FIXME-SOMEDAY: backing up and reparsing is wasteful. */ 380033965Sjdp input_line_pointer = hold; 380133965Sjdp exp->X_add_number = value; 380233965Sjdp break; 380333965Sjdp } /* won't fit */ 380433965Sjdp 380533965Sjdp hold = ++input_line_pointer; /* skip ':' */ 380633965Sjdp 380733965Sjdp (void) expression (exp); 380833965Sjdp if (exp->X_op != O_constant) 380933965Sjdp { 381033965Sjdp char cache = *input_line_pointer; 381133965Sjdp 381233965Sjdp *input_line_pointer = '\0'; 381360484Sobrien as_bad (_("field value \"%s\" too complex for a bitfield"), hold); 381433965Sjdp *input_line_pointer = cache; 381533965Sjdp demand_empty_rest_of_line (); 381633965Sjdp return; 381733965Sjdp } /* too complex */ 381833965Sjdp 381933965Sjdp value |= ((~(-1 << width) & exp->X_add_number) 382033965Sjdp << ((BITS_PER_CHAR * nbytes) - bits_available)); 382133965Sjdp 382233965Sjdp if ((bits_available -= width) == 0 382333965Sjdp || is_it_end_of_statement () 382433965Sjdp || *input_line_pointer != ',') 382533965Sjdp { 382633965Sjdp break; 382733965Sjdp } /* all the bitfields we're gonna get */ 382833965Sjdp 382933965Sjdp hold = ++input_line_pointer; 383033965Sjdp (void) expression (exp); 383133965Sjdp } /* forever loop */ 383233965Sjdp 383333965Sjdp exp->X_add_number = value; 383433965Sjdp exp->X_op = O_constant; 383533965Sjdp exp->X_unsigned = 1; 383633965Sjdp } /* if looks like a bitfield */ 383733965Sjdp} /* parse_bitfield_cons() */ 383833965Sjdp 383933965Sjdp#endif /* BITFIELD_CONS_EXPRESSIONS */ 384033965Sjdp 384133965Sjdp/* Handle an MRI style string expression. */ 384233965Sjdp 384360484Sobrien#ifdef TC_M68K 384433965Sjdpstatic void 384533965Sjdpparse_mri_cons (exp, nbytes) 384633965Sjdp expressionS *exp; 384733965Sjdp unsigned int nbytes; 384833965Sjdp{ 384933965Sjdp if (*input_line_pointer != '\'' 385033965Sjdp && (input_line_pointer[1] != '\'' 385133965Sjdp || (*input_line_pointer != 'A' 385233965Sjdp && *input_line_pointer != 'E'))) 385333965Sjdp TC_PARSE_CONS_EXPRESSION (exp, nbytes); 385433965Sjdp else 385533965Sjdp { 385638889Sjdp unsigned int scan; 385733965Sjdp unsigned int result = 0; 385833965Sjdp 385933965Sjdp /* An MRI style string. Cut into as many bytes as will fit into 386033965Sjdp a nbyte chunk, left justify if necessary, and separate with 386133965Sjdp commas so we can try again later. */ 386233965Sjdp if (*input_line_pointer == 'A') 386333965Sjdp ++input_line_pointer; 386433965Sjdp else if (*input_line_pointer == 'E') 386533965Sjdp { 386660484Sobrien as_bad (_("EBCDIC constants are not supported")); 386733965Sjdp ++input_line_pointer; 386833965Sjdp } 386933965Sjdp 387033965Sjdp input_line_pointer++; 387133965Sjdp for (scan = 0; scan < nbytes; scan++) 387233965Sjdp { 387333965Sjdp if (*input_line_pointer == '\'') 387433965Sjdp { 387533965Sjdp if (input_line_pointer[1] == '\'') 387633965Sjdp { 387733965Sjdp input_line_pointer++; 387833965Sjdp } 387933965Sjdp else 388033965Sjdp break; 388133965Sjdp } 388233965Sjdp result = (result << 8) | (*input_line_pointer++); 388333965Sjdp } 388433965Sjdp 388533965Sjdp /* Left justify */ 388633965Sjdp while (scan < nbytes) 388733965Sjdp { 388833965Sjdp result <<= 8; 388933965Sjdp scan++; 389033965Sjdp } 389133965Sjdp /* Create correct expression */ 389233965Sjdp exp->X_op = O_constant; 389333965Sjdp exp->X_add_number = result; 389433965Sjdp /* Fake it so that we can read the next char too */ 389533965Sjdp if (input_line_pointer[0] != '\'' || 389633965Sjdp (input_line_pointer[0] == '\'' && input_line_pointer[1] == '\'')) 389733965Sjdp { 389833965Sjdp input_line_pointer -= 2; 389933965Sjdp input_line_pointer[0] = ','; 390033965Sjdp input_line_pointer[1] = '\''; 390133965Sjdp } 390233965Sjdp else 390333965Sjdp input_line_pointer++; 390433965Sjdp } 390533965Sjdp} 390660484Sobrien#endif /* TC_M68K */ 390733965Sjdp 390833965Sjdp#ifdef REPEAT_CONS_EXPRESSIONS 390933965Sjdp 391033965Sjdp/* Parse a repeat expression for cons. This is used by the MIPS 391133965Sjdp assembler. The format is NUMBER:COUNT; NUMBER appears in the 391233965Sjdp object file COUNT times. 391333965Sjdp 391433965Sjdp To use this for a target, define REPEAT_CONS_EXPRESSIONS. */ 391533965Sjdp 391633965Sjdpstatic void 391733965Sjdpparse_repeat_cons (exp, nbytes) 391833965Sjdp expressionS *exp; 391933965Sjdp unsigned int nbytes; 392033965Sjdp{ 392133965Sjdp expressionS count; 392233965Sjdp register int i; 392333965Sjdp 392433965Sjdp expression (exp); 392533965Sjdp 392633965Sjdp if (*input_line_pointer != ':') 392733965Sjdp { 392833965Sjdp /* No repeat count. */ 392933965Sjdp return; 393033965Sjdp } 393133965Sjdp 393233965Sjdp ++input_line_pointer; 393333965Sjdp expression (&count); 393433965Sjdp if (count.X_op != O_constant 393533965Sjdp || count.X_add_number <= 0) 393633965Sjdp { 393760484Sobrien as_warn (_("Unresolvable or nonpositive repeat count; using 1")); 393833965Sjdp return; 393933965Sjdp } 394033965Sjdp 394133965Sjdp /* The cons function is going to output this expression once. So we 394233965Sjdp output it count - 1 times. */ 394333965Sjdp for (i = count.X_add_number - 1; i > 0; i--) 394433965Sjdp emit_expr (exp, nbytes); 394533965Sjdp} 394633965Sjdp 394733965Sjdp#endif /* REPEAT_CONS_EXPRESSIONS */ 394833965Sjdp 394933965Sjdp/* Parse a floating point number represented as a hex constant. This 395033965Sjdp permits users to specify the exact bits they want in the floating 395133965Sjdp point number. */ 395233965Sjdp 395333965Sjdpstatic int 395433965Sjdphex_float (float_type, bytes) 395533965Sjdp int float_type; 395633965Sjdp char *bytes; 395733965Sjdp{ 395833965Sjdp int length; 395933965Sjdp int i; 396033965Sjdp 396133965Sjdp switch (float_type) 396233965Sjdp { 396333965Sjdp case 'f': 396433965Sjdp case 'F': 396533965Sjdp case 's': 396633965Sjdp case 'S': 396733965Sjdp length = 4; 396833965Sjdp break; 396933965Sjdp 397033965Sjdp case 'd': 397133965Sjdp case 'D': 397233965Sjdp case 'r': 397333965Sjdp case 'R': 397433965Sjdp length = 8; 397533965Sjdp break; 397633965Sjdp 397733965Sjdp case 'x': 397833965Sjdp case 'X': 397933965Sjdp length = 12; 398033965Sjdp break; 398133965Sjdp 398233965Sjdp case 'p': 398333965Sjdp case 'P': 398433965Sjdp length = 12; 398533965Sjdp break; 398633965Sjdp 398733965Sjdp default: 398860484Sobrien as_bad (_("Unknown floating type type '%c'"), float_type); 398933965Sjdp return -1; 399033965Sjdp } 399133965Sjdp 399233965Sjdp /* It would be nice if we could go through expression to parse the 399333965Sjdp hex constant, but if we get a bignum it's a pain to sort it into 399433965Sjdp the buffer correctly. */ 399533965Sjdp i = 0; 399633965Sjdp while (hex_p (*input_line_pointer) || *input_line_pointer == '_') 399733965Sjdp { 399833965Sjdp int d; 399933965Sjdp 400033965Sjdp /* The MRI assembler accepts arbitrary underscores strewn about 400133965Sjdp through the hex constant, so we ignore them as well. */ 400233965Sjdp if (*input_line_pointer == '_') 400333965Sjdp { 400433965Sjdp ++input_line_pointer; 400533965Sjdp continue; 400633965Sjdp } 400733965Sjdp 400833965Sjdp if (i >= length) 400933965Sjdp { 401060484Sobrien as_warn (_("Floating point constant too large")); 401133965Sjdp return -1; 401233965Sjdp } 401333965Sjdp d = hex_value (*input_line_pointer) << 4; 401433965Sjdp ++input_line_pointer; 401533965Sjdp while (*input_line_pointer == '_') 401633965Sjdp ++input_line_pointer; 401733965Sjdp if (hex_p (*input_line_pointer)) 401833965Sjdp { 401933965Sjdp d += hex_value (*input_line_pointer); 402033965Sjdp ++input_line_pointer; 402133965Sjdp } 402233965Sjdp if (target_big_endian) 402333965Sjdp bytes[i] = d; 402433965Sjdp else 402533965Sjdp bytes[length - i - 1] = d; 402633965Sjdp ++i; 402733965Sjdp } 402833965Sjdp 402933965Sjdp if (i < length) 403033965Sjdp { 403133965Sjdp if (target_big_endian) 403233965Sjdp memset (bytes + i, 0, length - i); 403333965Sjdp else 403433965Sjdp memset (bytes, 0, length - i); 403533965Sjdp } 403633965Sjdp 403733965Sjdp return length; 403833965Sjdp} 403933965Sjdp 404033965Sjdp/* 404133965Sjdp * float_cons() 404233965Sjdp * 404333965Sjdp * CONStruct some more frag chars of .floats .ffloats etc. 404433965Sjdp * Makes 0 or more new frags. 404533965Sjdp * If need_pass_2 == 1, no frags are emitted. 404633965Sjdp * This understands only floating literals, not expressions. Sorry. 404733965Sjdp * 404833965Sjdp * A floating constant is defined by atof_generic(), except it is preceded 404933965Sjdp * by 0d 0f 0g or 0h. After observing the STRANGE way my BSD AS does its 405033965Sjdp * reading, I decided to be incompatible. This always tries to give you 405133965Sjdp * rounded bits to the precision of the pseudo-op. Former AS did premature 405233965Sjdp * truncatation, restored noisy bits instead of trailing 0s AND gave you 405333965Sjdp * a choice of 2 flavours of noise according to which of 2 floating-point 405433965Sjdp * scanners you directed AS to use. 405533965Sjdp * 405633965Sjdp * In: input_line_pointer->whitespace before, or '0' of flonum. 405733965Sjdp * 405833965Sjdp */ 405933965Sjdp 406033965Sjdpvoid 406133965Sjdpfloat_cons (float_type) 406233965Sjdp /* Clobbers input_line-pointer, checks end-of-line. */ 406333965Sjdp register int float_type; /* 'f':.ffloat ... 'F':.float ... */ 406433965Sjdp{ 406533965Sjdp register char *p; 406633965Sjdp int length; /* Number of chars in an object. */ 406733965Sjdp register char *err; /* Error from scanning floating literal. */ 406833965Sjdp char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT]; 406933965Sjdp 407033965Sjdp if (is_it_end_of_statement ()) 407133965Sjdp { 407233965Sjdp demand_empty_rest_of_line (); 407333965Sjdp return; 407433965Sjdp } 407533965Sjdp 407633965Sjdp#ifdef md_flush_pending_output 407733965Sjdp md_flush_pending_output (); 407833965Sjdp#endif 407933965Sjdp 408033965Sjdp do 408133965Sjdp { 408233965Sjdp /* input_line_pointer->1st char of a flonum (we hope!). */ 408333965Sjdp SKIP_WHITESPACE (); 408433965Sjdp 408533965Sjdp /* Skip any 0{letter} that may be present. Don't even check if the 408633965Sjdp * letter is legal. Someone may invent a "z" format and this routine 408733965Sjdp * has no use for such information. Lusers beware: you get 408833965Sjdp * diagnostics if your input is ill-conditioned. 408933965Sjdp */ 409038889Sjdp if (input_line_pointer[0] == '0' 409138889Sjdp && isalpha ((unsigned char) input_line_pointer[1])) 409233965Sjdp input_line_pointer += 2; 409333965Sjdp 409433965Sjdp /* Accept :xxxx, where the x's are hex digits, for a floating 409533965Sjdp point with the exact digits specified. */ 409633965Sjdp if (input_line_pointer[0] == ':') 409733965Sjdp { 409833965Sjdp ++input_line_pointer; 409933965Sjdp length = hex_float (float_type, temp); 410033965Sjdp if (length < 0) 410133965Sjdp { 410233965Sjdp ignore_rest_of_line (); 410333965Sjdp return; 410433965Sjdp } 410533965Sjdp } 410633965Sjdp else 410733965Sjdp { 410833965Sjdp err = md_atof (float_type, temp, &length); 410933965Sjdp know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT); 411033965Sjdp know (length > 0); 411133965Sjdp if (err) 411233965Sjdp { 411360484Sobrien as_bad (_("Bad floating literal: %s"), err); 411433965Sjdp ignore_rest_of_line (); 411533965Sjdp return; 411633965Sjdp } 411733965Sjdp } 411833965Sjdp 411933965Sjdp if (!need_pass_2) 412033965Sjdp { 412133965Sjdp int count; 412233965Sjdp 412333965Sjdp count = 1; 412433965Sjdp 412533965Sjdp#ifdef REPEAT_CONS_EXPRESSIONS 412633965Sjdp if (*input_line_pointer == ':') 412733965Sjdp { 412833965Sjdp expressionS count_exp; 412933965Sjdp 413033965Sjdp ++input_line_pointer; 413133965Sjdp expression (&count_exp); 413233965Sjdp if (count_exp.X_op != O_constant 413333965Sjdp || count_exp.X_add_number <= 0) 413433965Sjdp { 413560484Sobrien as_warn (_("unresolvable or nonpositive repeat count; using 1")); 413633965Sjdp } 413733965Sjdp else 413833965Sjdp count = count_exp.X_add_number; 413933965Sjdp } 414033965Sjdp#endif 414133965Sjdp 414233965Sjdp while (--count >= 0) 414333965Sjdp { 414433965Sjdp p = frag_more (length); 414533965Sjdp memcpy (p, temp, (unsigned int) length); 414633965Sjdp } 414733965Sjdp } 414833965Sjdp SKIP_WHITESPACE (); 414933965Sjdp } 415033965Sjdp while (*input_line_pointer++ == ','); 415133965Sjdp 415233965Sjdp --input_line_pointer; /* Put terminator back into stream. */ 415333965Sjdp demand_empty_rest_of_line (); 415433965Sjdp} /* float_cons() */ 415533965Sjdp 415638889Sjdp/* Return the size of a LEB128 value */ 415738889Sjdp 415838889Sjdpstatic inline int 415938889Sjdpsizeof_sleb128 (value) 416038889Sjdp offsetT value; 416138889Sjdp{ 416238889Sjdp register int size = 0; 416338889Sjdp register unsigned byte; 416438889Sjdp 416538889Sjdp do 416638889Sjdp { 416738889Sjdp byte = (value & 0x7f); 416838889Sjdp /* Sadly, we cannot rely on typical arithmetic right shift behaviour. 416938889Sjdp Fortunately, we can structure things so that the extra work reduces 417038889Sjdp to a noop on systems that do things "properly". */ 417138889Sjdp value = (value >> 7) | ~(-(offsetT)1 >> 7); 417238889Sjdp size += 1; 417338889Sjdp } 417438889Sjdp while (!(((value == 0) && ((byte & 0x40) == 0)) 417538889Sjdp || ((value == -1) && ((byte & 0x40) != 0)))); 417638889Sjdp 417738889Sjdp return size; 417838889Sjdp} 417938889Sjdp 418038889Sjdpstatic inline int 418138889Sjdpsizeof_uleb128 (value) 418238889Sjdp valueT value; 418338889Sjdp{ 418438889Sjdp register int size = 0; 418538889Sjdp register unsigned byte; 418638889Sjdp 418738889Sjdp do 418838889Sjdp { 418938889Sjdp byte = (value & 0x7f); 419038889Sjdp value >>= 7; 419138889Sjdp size += 1; 419238889Sjdp } 419338889Sjdp while (value != 0); 419438889Sjdp 419538889Sjdp return size; 419638889Sjdp} 419738889Sjdp 419860484Sobrienint 419938889Sjdpsizeof_leb128 (value, sign) 420038889Sjdp valueT value; 420138889Sjdp int sign; 420238889Sjdp{ 420338889Sjdp if (sign) 420438889Sjdp return sizeof_sleb128 ((offsetT) value); 420538889Sjdp else 420638889Sjdp return sizeof_uleb128 (value); 420738889Sjdp} 420838889Sjdp 420938889Sjdp/* Output a LEB128 value. */ 421038889Sjdp 421138889Sjdpstatic inline int 421238889Sjdpoutput_sleb128 (p, value) 421338889Sjdp char *p; 421438889Sjdp offsetT value; 421538889Sjdp{ 421638889Sjdp register char *orig = p; 421738889Sjdp register int more; 421838889Sjdp 421938889Sjdp do 422038889Sjdp { 422138889Sjdp unsigned byte = (value & 0x7f); 422238889Sjdp 422338889Sjdp /* Sadly, we cannot rely on typical arithmetic right shift behaviour. 422438889Sjdp Fortunately, we can structure things so that the extra work reduces 422538889Sjdp to a noop on systems that do things "properly". */ 422638889Sjdp value = (value >> 7) | ~(-(offsetT)1 >> 7); 422738889Sjdp 422838889Sjdp more = !((((value == 0) && ((byte & 0x40) == 0)) 422938889Sjdp || ((value == -1) && ((byte & 0x40) != 0)))); 423038889Sjdp if (more) 423138889Sjdp byte |= 0x80; 423238889Sjdp 423338889Sjdp *p++ = byte; 423438889Sjdp } 423538889Sjdp while (more); 423638889Sjdp 423738889Sjdp return p - orig; 423838889Sjdp} 423938889Sjdp 424038889Sjdpstatic inline int 424138889Sjdpoutput_uleb128 (p, value) 424238889Sjdp char *p; 424338889Sjdp valueT value; 424438889Sjdp{ 424538889Sjdp char *orig = p; 424638889Sjdp 424738889Sjdp do 424838889Sjdp { 424938889Sjdp unsigned byte = (value & 0x7f); 425038889Sjdp value >>= 7; 425138889Sjdp if (value != 0) 425238889Sjdp /* More bytes to follow. */ 425338889Sjdp byte |= 0x80; 425438889Sjdp 425538889Sjdp *p++ = byte; 425638889Sjdp } 425738889Sjdp while (value != 0); 425838889Sjdp 425938889Sjdp return p - orig; 426038889Sjdp} 426138889Sjdp 426260484Sobrienint 426338889Sjdpoutput_leb128 (p, value, sign) 426438889Sjdp char *p; 426538889Sjdp valueT value; 426638889Sjdp int sign; 426738889Sjdp{ 426838889Sjdp if (sign) 426938889Sjdp return output_sleb128 (p, (offsetT) value); 427038889Sjdp else 427138889Sjdp return output_uleb128 (p, value); 427238889Sjdp} 427338889Sjdp 427438889Sjdp/* Do the same for bignums. We combine sizeof with output here in that 427538889Sjdp we don't output for NULL values of P. It isn't really as critical as 427638889Sjdp for "normal" values that this be streamlined. */ 427738889Sjdp 427860484Sobrienstatic inline int 427938889Sjdpoutput_big_sleb128 (p, bignum, size) 428038889Sjdp char *p; 428138889Sjdp LITTLENUM_TYPE *bignum; 428238889Sjdp int size; 428338889Sjdp{ 428438889Sjdp char *orig = p; 428538889Sjdp valueT val = 0; 428638889Sjdp int loaded = 0; 428738889Sjdp unsigned byte; 428838889Sjdp 428938889Sjdp /* Strip leading sign extensions off the bignum. */ 429038889Sjdp while (size > 0 && bignum[size-1] == (LITTLENUM_TYPE)-1) 429138889Sjdp size--; 429238889Sjdp 429338889Sjdp do 429438889Sjdp { 429538889Sjdp if (loaded < 7 && size > 0) 429638889Sjdp { 429738889Sjdp val |= (*bignum << loaded); 429838889Sjdp loaded += 8 * CHARS_PER_LITTLENUM; 429938889Sjdp size--; 430038889Sjdp bignum++; 430138889Sjdp } 430238889Sjdp 430338889Sjdp byte = val & 0x7f; 430438889Sjdp loaded -= 7; 430538889Sjdp val >>= 7; 430638889Sjdp 430738889Sjdp if (size == 0) 430838889Sjdp { 430938889Sjdp if ((val == 0 && (byte & 0x40) == 0) 431038889Sjdp || (~(val | ~(((valueT)1 << loaded) - 1)) == 0 431138889Sjdp && (byte & 0x40) != 0)) 431238889Sjdp byte |= 0x80; 431338889Sjdp } 431438889Sjdp 431538889Sjdp if (orig) 431638889Sjdp *p = byte; 431738889Sjdp p++; 431838889Sjdp } 431938889Sjdp while (byte & 0x80); 432038889Sjdp 432138889Sjdp return p - orig; 432238889Sjdp} 432338889Sjdp 432460484Sobrienstatic inline int 432538889Sjdpoutput_big_uleb128 (p, bignum, size) 432638889Sjdp char *p; 432738889Sjdp LITTLENUM_TYPE *bignum; 432838889Sjdp int size; 432938889Sjdp{ 433038889Sjdp char *orig = p; 433138889Sjdp valueT val = 0; 433238889Sjdp int loaded = 0; 433338889Sjdp unsigned byte; 433438889Sjdp 433538889Sjdp /* Strip leading zeros off the bignum. */ 433638889Sjdp /* XXX: Is this needed? */ 433738889Sjdp while (size > 0 && bignum[size-1] == 0) 433838889Sjdp size--; 433938889Sjdp 434038889Sjdp do 434138889Sjdp { 434238889Sjdp if (loaded < 7 && size > 0) 434338889Sjdp { 434438889Sjdp val |= (*bignum << loaded); 434538889Sjdp loaded += 8 * CHARS_PER_LITTLENUM; 434638889Sjdp size--; 434738889Sjdp bignum++; 434838889Sjdp } 434938889Sjdp 435038889Sjdp byte = val & 0x7f; 435138889Sjdp loaded -= 7; 435238889Sjdp val >>= 7; 435338889Sjdp 435438889Sjdp if (size > 0 || val) 435538889Sjdp byte |= 0x80; 435638889Sjdp 435738889Sjdp if (orig) 435838889Sjdp *p = byte; 435938889Sjdp p++; 436038889Sjdp } 436138889Sjdp while (byte & 0x80); 436238889Sjdp 436338889Sjdp return p - orig; 436438889Sjdp} 436538889Sjdp 436660484Sobrienstatic int 436738889Sjdpoutput_big_leb128 (p, bignum, size, sign) 436838889Sjdp char *p; 436938889Sjdp LITTLENUM_TYPE *bignum; 437038889Sjdp int size, sign; 437138889Sjdp{ 437238889Sjdp if (sign) 437338889Sjdp return output_big_sleb128 (p, bignum, size); 437438889Sjdp else 437538889Sjdp return output_big_uleb128 (p, bignum, size); 437638889Sjdp} 437738889Sjdp 437838889Sjdp/* Generate the appropriate fragments for a given expression to emit a 437938889Sjdp leb128 value. */ 438038889Sjdp 438138889Sjdpvoid 438238889Sjdpemit_leb128_expr(exp, sign) 438338889Sjdp expressionS *exp; 438438889Sjdp int sign; 438538889Sjdp{ 438638889Sjdp operatorT op = exp->X_op; 438738889Sjdp 438838889Sjdp if (op == O_absent || op == O_illegal) 438938889Sjdp { 439060484Sobrien as_warn (_("zero assumed for missing expression")); 439138889Sjdp exp->X_add_number = 0; 439238889Sjdp op = O_constant; 439338889Sjdp } 439438889Sjdp else if (op == O_big && exp->X_add_number <= 0) 439538889Sjdp { 439660484Sobrien as_bad (_("floating point number invalid; zero assumed")); 439738889Sjdp exp->X_add_number = 0; 439838889Sjdp op = O_constant; 439938889Sjdp } 440038889Sjdp else if (op == O_register) 440138889Sjdp { 440260484Sobrien as_warn (_("register value used as expression")); 440338889Sjdp op = O_constant; 440438889Sjdp } 440538889Sjdp 440638889Sjdp if (op == O_constant) 440738889Sjdp { 440838889Sjdp /* If we've got a constant, emit the thing directly right now. */ 440938889Sjdp 441038889Sjdp valueT value = exp->X_add_number; 441138889Sjdp int size; 441238889Sjdp char *p; 441338889Sjdp 441438889Sjdp size = sizeof_leb128 (value, sign); 441538889Sjdp p = frag_more (size); 441638889Sjdp output_leb128 (p, value, sign); 441738889Sjdp } 441838889Sjdp else if (op == O_big) 441938889Sjdp { 442038889Sjdp /* O_big is a different sort of constant. */ 442138889Sjdp 442238889Sjdp int size; 442338889Sjdp char *p; 442438889Sjdp 442538889Sjdp size = output_big_leb128 (NULL, generic_bignum, exp->X_add_number, sign); 442638889Sjdp p = frag_more (size); 442738889Sjdp output_big_leb128 (p, generic_bignum, exp->X_add_number, sign); 442838889Sjdp } 442938889Sjdp else 443038889Sjdp { 443138889Sjdp /* Otherwise, we have to create a variable sized fragment and 443238889Sjdp resolve things later. */ 443338889Sjdp 443438889Sjdp frag_var (rs_leb128, sizeof_uleb128 (~(valueT)0), 0, sign, 443538889Sjdp make_expr_symbol (exp), 0, (char *) NULL); 443638889Sjdp } 443738889Sjdp} 443838889Sjdp 443938889Sjdp/* Parse the .sleb128 and .uleb128 pseudos. */ 444038889Sjdp 444138889Sjdpvoid 444238889Sjdps_leb128 (sign) 444338889Sjdp int sign; 444438889Sjdp{ 444538889Sjdp expressionS exp; 444638889Sjdp 444738889Sjdp do { 444838889Sjdp expression (&exp); 444938889Sjdp emit_leb128_expr (&exp, sign); 445038889Sjdp } while (*input_line_pointer++ == ','); 445138889Sjdp 445238889Sjdp input_line_pointer--; 445338889Sjdp demand_empty_rest_of_line (); 445438889Sjdp} 445538889Sjdp 445633965Sjdp/* 445733965Sjdp * stringer() 445833965Sjdp * 445960484Sobrien * We read 0 or more ',' separated, double-quoted strings. 446033965Sjdp * 446133965Sjdp * Caller should have checked need_pass_2 is FALSE because we don't check it. 446233965Sjdp */ 446333965Sjdp 446433965Sjdp 446533965Sjdpvoid 446633965Sjdpstringer (append_zero) /* Worker to do .ascii etc statements. */ 446733965Sjdp /* Checks end-of-line. */ 446833965Sjdp register int append_zero; /* 0: don't append '\0', else 1 */ 446933965Sjdp{ 447033965Sjdp register unsigned int c; 447138889Sjdp char *start; 447233965Sjdp 447333965Sjdp#ifdef md_flush_pending_output 447433965Sjdp md_flush_pending_output (); 447533965Sjdp#endif 447633965Sjdp 447733965Sjdp /* 447833965Sjdp * The following awkward logic is to parse ZERO or more strings, 447960484Sobrien * comma separated. Recall a string expression includes spaces 448033965Sjdp * before the opening '\"' and spaces after the closing '\"'. 448133965Sjdp * We fake a leading ',' if there is (supposed to be) 448233965Sjdp * a 1st, expression. We keep demanding expressions for each 448333965Sjdp * ','. 448433965Sjdp */ 448533965Sjdp if (is_it_end_of_statement ()) 448633965Sjdp { 448733965Sjdp c = 0; /* Skip loop. */ 448833965Sjdp ++input_line_pointer; /* Compensate for end of loop. */ 448933965Sjdp } 449033965Sjdp else 449133965Sjdp { 449233965Sjdp c = ','; /* Do loop. */ 449333965Sjdp } 449433965Sjdp while (c == ',' || c == '<' || c == '"') 449533965Sjdp { 449633965Sjdp SKIP_WHITESPACE (); 449733965Sjdp switch (*input_line_pointer) 449833965Sjdp { 449933965Sjdp case '\"': 450033965Sjdp ++input_line_pointer; /*->1st char of string. */ 450138889Sjdp start = input_line_pointer; 450233965Sjdp while (is_a_char (c = next_char_of_string ())) 450333965Sjdp { 450433965Sjdp FRAG_APPEND_1_CHAR (c); 450533965Sjdp } 450633965Sjdp if (append_zero) 450733965Sjdp { 450833965Sjdp FRAG_APPEND_1_CHAR (0); 450933965Sjdp } 451033965Sjdp know (input_line_pointer[-1] == '\"'); 451138889Sjdp 451238889Sjdp#ifndef NO_LISTING 451338889Sjdp#ifdef OBJ_ELF 451438889Sjdp /* In ELF, when gcc is emitting DWARF 1 debugging output, it 451538889Sjdp will emit .string with a filename in the .debug section 451638889Sjdp after a sequence of constants. See the comment in 451738889Sjdp emit_expr for the sequence. emit_expr will set 451838889Sjdp dwarf_file_string to non-zero if this string might be a 451938889Sjdp source file name. */ 452038889Sjdp if (strcmp (segment_name (now_seg), ".debug") != 0) 452138889Sjdp dwarf_file_string = 0; 452238889Sjdp else if (dwarf_file_string) 452338889Sjdp { 452438889Sjdp c = input_line_pointer[-1]; 452538889Sjdp input_line_pointer[-1] = '\0'; 452638889Sjdp listing_source_file (start); 452738889Sjdp input_line_pointer[-1] = c; 452838889Sjdp } 452938889Sjdp#endif 453038889Sjdp#endif 453138889Sjdp 453233965Sjdp break; 453333965Sjdp case '<': 453433965Sjdp input_line_pointer++; 453533965Sjdp c = get_single_number (); 453633965Sjdp FRAG_APPEND_1_CHAR (c); 453733965Sjdp if (*input_line_pointer != '>') 453833965Sjdp { 453960484Sobrien as_bad (_("Expected <nn>")); 454033965Sjdp } 454133965Sjdp input_line_pointer++; 454233965Sjdp break; 454333965Sjdp case ',': 454433965Sjdp input_line_pointer++; 454533965Sjdp break; 454633965Sjdp } 454733965Sjdp SKIP_WHITESPACE (); 454833965Sjdp c = *input_line_pointer; 454933965Sjdp } 455033965Sjdp 455133965Sjdp demand_empty_rest_of_line (); 455233965Sjdp} /* stringer() */ 455333965Sjdp 455433965Sjdp/* FIXME-SOMEDAY: I had trouble here on characters with the 455533965Sjdp high bits set. We'll probably also have trouble with 455633965Sjdp multibyte chars, wide chars, etc. Also be careful about 455733965Sjdp returning values bigger than 1 byte. xoxorich. */ 455833965Sjdp 455933965Sjdpunsigned int 456033965Sjdpnext_char_of_string () 456133965Sjdp{ 456233965Sjdp register unsigned int c; 456333965Sjdp 456433965Sjdp c = *input_line_pointer++ & CHAR_MASK; 456533965Sjdp switch (c) 456633965Sjdp { 456733965Sjdp case '\"': 456833965Sjdp c = NOT_A_CHAR; 456933965Sjdp break; 457033965Sjdp 457133965Sjdp case '\n': 457260484Sobrien as_warn (_("Unterminated string: Newline inserted.")); 457333965Sjdp bump_line_counters (); 457433965Sjdp break; 457533965Sjdp 457633965Sjdp#ifndef NO_STRING_ESCAPES 457733965Sjdp case '\\': 457833965Sjdp switch (c = *input_line_pointer++) 457933965Sjdp { 458033965Sjdp case 'b': 458133965Sjdp c = '\b'; 458233965Sjdp break; 458333965Sjdp 458433965Sjdp case 'f': 458533965Sjdp c = '\f'; 458633965Sjdp break; 458733965Sjdp 458833965Sjdp case 'n': 458933965Sjdp c = '\n'; 459033965Sjdp break; 459133965Sjdp 459233965Sjdp case 'r': 459333965Sjdp c = '\r'; 459433965Sjdp break; 459533965Sjdp 459633965Sjdp case 't': 459733965Sjdp c = '\t'; 459833965Sjdp break; 459933965Sjdp 460033965Sjdp case 'v': 460133965Sjdp c = '\013'; 460233965Sjdp break; 460333965Sjdp 460433965Sjdp case '\\': 460533965Sjdp case '"': 460633965Sjdp break; /* As itself. */ 460733965Sjdp 460833965Sjdp case '0': 460933965Sjdp case '1': 461033965Sjdp case '2': 461133965Sjdp case '3': 461233965Sjdp case '4': 461333965Sjdp case '5': 461433965Sjdp case '6': 461533965Sjdp case '7': 461633965Sjdp case '8': 461733965Sjdp case '9': 461833965Sjdp { 461933965Sjdp long number; 462033965Sjdp int i; 462133965Sjdp 462233965Sjdp for (i = 0, number = 0; isdigit (c) && i < 3; c = *input_line_pointer++, i++) 462333965Sjdp { 462433965Sjdp number = number * 8 + c - '0'; 462533965Sjdp } 462633965Sjdp c = number & 0xff; 462733965Sjdp } 462833965Sjdp --input_line_pointer; 462933965Sjdp break; 463033965Sjdp 463133965Sjdp case 'x': 463233965Sjdp case 'X': 463333965Sjdp { 463433965Sjdp long number; 463533965Sjdp 463633965Sjdp number = 0; 463733965Sjdp c = *input_line_pointer++; 463833965Sjdp while (isxdigit (c)) 463933965Sjdp { 464033965Sjdp if (isdigit (c)) 464133965Sjdp number = number * 16 + c - '0'; 464233965Sjdp else if (isupper (c)) 464333965Sjdp number = number * 16 + c - 'A' + 10; 464433965Sjdp else 464533965Sjdp number = number * 16 + c - 'a' + 10; 464633965Sjdp c = *input_line_pointer++; 464733965Sjdp } 464833965Sjdp c = number & 0xff; 464933965Sjdp --input_line_pointer; 465033965Sjdp } 465133965Sjdp break; 465233965Sjdp 465333965Sjdp case '\n': 465433965Sjdp /* To be compatible with BSD 4.2 as: give the luser a linefeed!! */ 465560484Sobrien as_warn (_("Unterminated string: Newline inserted.")); 465633965Sjdp c = '\n'; 465733965Sjdp bump_line_counters (); 465833965Sjdp break; 465933965Sjdp 466033965Sjdp default: 466133965Sjdp 466233965Sjdp#ifdef ONLY_STANDARD_ESCAPES 466360484Sobrien as_bad (_("Bad escaped character in string, '?' assumed")); 466433965Sjdp c = '?'; 466533965Sjdp#endif /* ONLY_STANDARD_ESCAPES */ 466633965Sjdp 466733965Sjdp break; 466833965Sjdp } /* switch on escaped char */ 466933965Sjdp break; 467033965Sjdp#endif /* ! defined (NO_STRING_ESCAPES) */ 467133965Sjdp 467233965Sjdp default: 467333965Sjdp break; 467433965Sjdp } /* switch on char */ 467533965Sjdp return (c); 467633965Sjdp} /* next_char_of_string() */ 467733965Sjdp 467833965Sjdpstatic segT 467933965Sjdpget_segmented_expression (expP) 468033965Sjdp register expressionS *expP; 468133965Sjdp{ 468233965Sjdp register segT retval; 468333965Sjdp 468433965Sjdp retval = expression (expP); 468533965Sjdp if (expP->X_op == O_illegal 468633965Sjdp || expP->X_op == O_absent 468733965Sjdp || expP->X_op == O_big) 468833965Sjdp { 468960484Sobrien as_bad (_("expected address expression; zero assumed")); 469033965Sjdp expP->X_op = O_constant; 469133965Sjdp expP->X_add_number = 0; 469233965Sjdp retval = absolute_section; 469333965Sjdp } 469433965Sjdp return retval; 469533965Sjdp} 469633965Sjdp 469733965Sjdpstatic segT 469833965Sjdpget_known_segmented_expression (expP) 469933965Sjdp register expressionS *expP; 470033965Sjdp{ 470133965Sjdp register segT retval; 470233965Sjdp 470333965Sjdp if ((retval = get_segmented_expression (expP)) == undefined_section) 470433965Sjdp { 470533965Sjdp /* There is no easy way to extract the undefined symbol from the 470633965Sjdp expression. */ 470733965Sjdp if (expP->X_add_symbol != NULL 470833965Sjdp && S_GET_SEGMENT (expP->X_add_symbol) != expr_section) 470960484Sobrien as_warn (_("symbol \"%s\" undefined; zero assumed"), 471033965Sjdp S_GET_NAME (expP->X_add_symbol)); 471133965Sjdp else 471260484Sobrien as_warn (_("some symbol undefined; zero assumed")); 471333965Sjdp retval = absolute_section; 471433965Sjdp expP->X_op = O_constant; 471533965Sjdp expP->X_add_number = 0; 471633965Sjdp } 471733965Sjdp know (retval == absolute_section || SEG_NORMAL (retval)); 471833965Sjdp return (retval); 471933965Sjdp} /* get_known_segmented_expression() */ 472033965Sjdp 472133965SjdpoffsetT 472233965Sjdpget_absolute_expression () 472333965Sjdp{ 472433965Sjdp expressionS exp; 472533965Sjdp 472633965Sjdp expression (&exp); 472733965Sjdp if (exp.X_op != O_constant) 472833965Sjdp { 472933965Sjdp if (exp.X_op != O_absent) 473060484Sobrien as_bad (_("bad or irreducible absolute expression; zero assumed")); 473133965Sjdp exp.X_add_number = 0; 473233965Sjdp } 473333965Sjdp return exp.X_add_number; 473433965Sjdp} 473533965Sjdp 473633965Sjdpchar /* return terminator */ 473733965Sjdpget_absolute_expression_and_terminator (val_pointer) 473833965Sjdp long *val_pointer; /* return value of expression */ 473933965Sjdp{ 474033965Sjdp /* FIXME: val_pointer should probably be offsetT *. */ 474133965Sjdp *val_pointer = (long) get_absolute_expression (); 474233965Sjdp return (*input_line_pointer++); 474333965Sjdp} 474433965Sjdp 474533965Sjdp/* 474633965Sjdp * demand_copy_C_string() 474733965Sjdp * 474833965Sjdp * Like demand_copy_string, but return NULL if the string contains any '\0's. 474933965Sjdp * Give a warning if that happens. 475033965Sjdp */ 475133965Sjdpchar * 475233965Sjdpdemand_copy_C_string (len_pointer) 475333965Sjdp int *len_pointer; 475433965Sjdp{ 475533965Sjdp register char *s; 475633965Sjdp 475733965Sjdp if ((s = demand_copy_string (len_pointer)) != 0) 475833965Sjdp { 475933965Sjdp register int len; 476033965Sjdp 476133965Sjdp for (len = *len_pointer; len > 0; len--) 476233965Sjdp { 476333965Sjdp if (*s == 0) 476433965Sjdp { 476533965Sjdp s = 0; 476633965Sjdp len = 1; 476733965Sjdp *len_pointer = 0; 476860484Sobrien as_bad (_("This string may not contain \'\\0\'")); 476933965Sjdp } 477033965Sjdp } 477133965Sjdp } 477233965Sjdp return s; 477333965Sjdp} 477433965Sjdp 477533965Sjdp/* 477633965Sjdp * demand_copy_string() 477733965Sjdp * 477833965Sjdp * Demand string, but return a safe (=private) copy of the string. 477933965Sjdp * Return NULL if we can't read a string here. 478033965Sjdp */ 478133965Sjdpchar * 478233965Sjdpdemand_copy_string (lenP) 478333965Sjdp int *lenP; 478433965Sjdp{ 478533965Sjdp register unsigned int c; 478633965Sjdp register int len; 478733965Sjdp char *retval; 478833965Sjdp 478933965Sjdp len = 0; 479033965Sjdp SKIP_WHITESPACE (); 479133965Sjdp if (*input_line_pointer == '\"') 479233965Sjdp { 479333965Sjdp input_line_pointer++; /* Skip opening quote. */ 479433965Sjdp 479533965Sjdp while (is_a_char (c = next_char_of_string ())) 479633965Sjdp { 479733965Sjdp obstack_1grow (¬es, c); 479833965Sjdp len++; 479933965Sjdp } 480033965Sjdp /* JF this next line is so demand_copy_C_string will return a 480133965Sjdp null terminated string. */ 480233965Sjdp obstack_1grow (¬es, '\0'); 480333965Sjdp retval = obstack_finish (¬es); 480433965Sjdp } 480533965Sjdp else 480633965Sjdp { 480760484Sobrien as_warn (_("Missing string")); 480833965Sjdp retval = NULL; 480933965Sjdp ignore_rest_of_line (); 481033965Sjdp } 481133965Sjdp *lenP = len; 481233965Sjdp return (retval); 481333965Sjdp} /* demand_copy_string() */ 481433965Sjdp 481533965Sjdp/* 481633965Sjdp * is_it_end_of_statement() 481733965Sjdp * 481833965Sjdp * In: Input_line_pointer->next character. 481933965Sjdp * 482033965Sjdp * Do: Skip input_line_pointer over all whitespace. 482133965Sjdp * 482233965Sjdp * Out: 1 if input_line_pointer->end-of-line. 482333965Sjdp*/ 482433965Sjdpint 482533965Sjdpis_it_end_of_statement () 482633965Sjdp{ 482733965Sjdp SKIP_WHITESPACE (); 482833965Sjdp return (is_end_of_line[(unsigned char) *input_line_pointer]); 482933965Sjdp} /* is_it_end_of_statement() */ 483033965Sjdp 483133965Sjdpvoid 483233965Sjdpequals (sym_name, reassign) 483333965Sjdp char *sym_name; 483433965Sjdp int reassign; 483533965Sjdp{ 483633965Sjdp register symbolS *symbolP; /* symbol we are working with */ 483738889Sjdp char *stop = NULL; 483833965Sjdp char stopc; 483933965Sjdp 484033965Sjdp input_line_pointer++; 484133965Sjdp if (*input_line_pointer == '=') 484233965Sjdp input_line_pointer++; 484333965Sjdp 484433965Sjdp while (*input_line_pointer == ' ' || *input_line_pointer == '\t') 484533965Sjdp input_line_pointer++; 484633965Sjdp 484733965Sjdp if (flag_mri) 484833965Sjdp stop = mri_comment_field (&stopc); 484933965Sjdp 485033965Sjdp if (sym_name[0] == '.' && sym_name[1] == '\0') 485133965Sjdp { 485233965Sjdp /* Turn '. = mumble' into a .org mumble */ 485333965Sjdp register segT segment; 485433965Sjdp expressionS exp; 485533965Sjdp 485633965Sjdp segment = get_known_segmented_expression (&exp); 485733965Sjdp if (!need_pass_2) 485833965Sjdp do_org (segment, &exp, 0); 485933965Sjdp } 486033965Sjdp else 486133965Sjdp { 486233965Sjdp symbolP = symbol_find_or_make (sym_name); 486333965Sjdp /* Permit register names to be redefined. */ 486433965Sjdp if (! reassign 486533965Sjdp && S_IS_DEFINED (symbolP) 486633965Sjdp && S_GET_SEGMENT (symbolP) != reg_section) 486760484Sobrien as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP)); 486833965Sjdp pseudo_set (symbolP); 486933965Sjdp } 487033965Sjdp 487133965Sjdp if (flag_mri) 487260484Sobrien { 487360484Sobrien ignore_rest_of_line (); /* check garbage after the expression */ 487460484Sobrien mri_comment_end (stop, stopc); 487560484Sobrien } 487633965Sjdp} /* equals() */ 487733965Sjdp 487833965Sjdp/* .include -- include a file at this point. */ 487933965Sjdp 488033965Sjdp/* ARGSUSED */ 488133965Sjdpvoid 488233965Sjdps_include (arg) 488360484Sobrien int arg ATTRIBUTE_UNUSED; 488433965Sjdp{ 488533965Sjdp char *filename; 488633965Sjdp int i; 488733965Sjdp FILE *try; 488833965Sjdp char *path; 488933965Sjdp 489033965Sjdp if (! flag_m68k_mri) 489138889Sjdp { 489238889Sjdp filename = demand_copy_string (&i); 489338889Sjdp if (filename == NULL) 489438889Sjdp { 489538889Sjdp /* demand_copy_string has already printed an error and 489638889Sjdp called ignore_rest_of_line. */ 489738889Sjdp return; 489838889Sjdp } 489938889Sjdp } 490033965Sjdp else 490133965Sjdp { 490233965Sjdp SKIP_WHITESPACE (); 490333965Sjdp i = 0; 490433965Sjdp while (! is_end_of_line[(unsigned char) *input_line_pointer] 490533965Sjdp && *input_line_pointer != ' ' 490633965Sjdp && *input_line_pointer != '\t') 490733965Sjdp { 490833965Sjdp obstack_1grow (¬es, *input_line_pointer); 490933965Sjdp ++input_line_pointer; 491033965Sjdp ++i; 491133965Sjdp } 491233965Sjdp obstack_1grow (¬es, '\0'); 491333965Sjdp filename = obstack_finish (¬es); 491433965Sjdp while (! is_end_of_line[(unsigned char) *input_line_pointer]) 491533965Sjdp ++input_line_pointer; 491633965Sjdp } 491733965Sjdp demand_empty_rest_of_line (); 491833965Sjdp path = xmalloc ((unsigned long) i + include_dir_maxlen + 5 /* slop */ ); 491933965Sjdp for (i = 0; i < include_dir_count; i++) 492033965Sjdp { 492133965Sjdp strcpy (path, include_dirs[i]); 492233965Sjdp strcat (path, "/"); 492333965Sjdp strcat (path, filename); 492433965Sjdp if (0 != (try = fopen (path, "r"))) 492533965Sjdp { 492633965Sjdp fclose (try); 492733965Sjdp goto gotit; 492833965Sjdp } 492933965Sjdp } 493033965Sjdp free (path); 493133965Sjdp path = filename; 493233965Sjdpgotit: 493333965Sjdp /* malloc Storage leak when file is found on path. FIXME-SOMEDAY. */ 493438889Sjdp register_dependency (path); 493560484Sobrien input_scrub_insert_file (path); 493633965Sjdp} /* s_include() */ 493733965Sjdp 493833965Sjdpvoid 493933965Sjdpadd_include_dir (path) 494033965Sjdp char *path; 494133965Sjdp{ 494233965Sjdp int i; 494333965Sjdp 494433965Sjdp if (include_dir_count == 0) 494533965Sjdp { 494633965Sjdp include_dirs = (char **) xmalloc (2 * sizeof (*include_dirs)); 494733965Sjdp include_dirs[0] = "."; /* Current dir */ 494833965Sjdp include_dir_count = 2; 494933965Sjdp } 495033965Sjdp else 495133965Sjdp { 495233965Sjdp include_dir_count++; 495333965Sjdp include_dirs = (char **) realloc (include_dirs, 495433965Sjdp include_dir_count * sizeof (*include_dirs)); 495533965Sjdp } 495633965Sjdp 495733965Sjdp include_dirs[include_dir_count - 1] = path; /* New one */ 495833965Sjdp 495933965Sjdp i = strlen (path); 496033965Sjdp if (i > include_dir_maxlen) 496133965Sjdp include_dir_maxlen = i; 496233965Sjdp} /* add_include_dir() */ 496360484Sobrien 496460484Sobrien/* Output debugging information to denote the source file. */ 496533965Sjdp 496660484Sobrienstatic void 496760484Sobriengenerate_file_debug () 496860484Sobrien{ 496960484Sobrien if (debug_type == DEBUG_STABS) 497060484Sobrien stabs_generate_asm_file (); 497160484Sobrien} 497260484Sobrien 497360484Sobrien/* Output line number debugging information for the current source line. */ 497460484Sobrien 497560484Sobrienvoid 497660484Sobriengenerate_lineno_debug () 497760484Sobrien{ 497860484Sobrien#ifdef ECOFF_DEBUGGING 497960484Sobrien /* ECOFF assemblers automatically generate debugging information. 498060484Sobrien FIXME: This should probably be handled elsewhere. */ 498160484Sobrien if (debug_type == DEBUG_UNSPECIFIED) 498260484Sobrien { 498360484Sobrien if (ECOFF_DEBUGGING && ecoff_no_current_file ()) 498460484Sobrien debug_type = DEBUG_ECOFF; 498560484Sobrien else 498660484Sobrien debug_type = DEBUG_NONE; 498760484Sobrien } 498860484Sobrien#endif 498960484Sobrien 499060484Sobrien switch (debug_type) 499160484Sobrien { 499260484Sobrien case DEBUG_UNSPECIFIED: 499360484Sobrien case DEBUG_NONE: 499460484Sobrien break; 499560484Sobrien case DEBUG_STABS: 499660484Sobrien stabs_generate_asm_lineno (); 499760484Sobrien break; 499860484Sobrien case DEBUG_ECOFF: 499960484Sobrien ecoff_generate_asm_lineno (); 500060484Sobrien break; 500160484Sobrien case DEBUG_DWARF: 500260484Sobrien case DEBUG_DWARF2: 500360484Sobrien /* FIXME. */ 500460484Sobrien break; 500560484Sobrien } 500660484Sobrien} 500760484Sobrien 500860484Sobrien/* Output debugging information to mark a function entry point or end point. 500960484Sobrien END_P is zero for .func, and non-zero for .endfunc. */ 501060484Sobrien 501160484Sobrienvoid 501260484Sobriens_func (end_p) 501360484Sobrien int end_p; 501460484Sobrien{ 501560484Sobrien do_s_func (end_p, NULL); 501660484Sobrien} 501760484Sobrien 501860484Sobrien/* Subroutine of s_func so targets can choose a different default prefix. 501960484Sobrien If DEFAULT_PREFIX is NULL, use the target's "leading char". */ 502060484Sobrien 502160484Sobrienvoid 502260484Sobriendo_s_func (end_p, default_prefix) 502360484Sobrien int end_p; 502460484Sobrien const char *default_prefix; 502560484Sobrien{ 502660484Sobrien /* Record the current function so that we can issue an error message for 502760484Sobrien misplaced .func,.endfunc, and also so that .endfunc needs no 502860484Sobrien arguments. */ 502960484Sobrien static char *current_name; 503060484Sobrien static char *current_label; 503160484Sobrien 503260484Sobrien if (end_p) 503360484Sobrien { 503460484Sobrien if (current_name == NULL) 503560484Sobrien { 503660484Sobrien as_bad (_("missing .func")); 503760484Sobrien ignore_rest_of_line (); 503860484Sobrien return; 503960484Sobrien } 504060484Sobrien 504160484Sobrien if (debug_type == DEBUG_STABS) 504260484Sobrien stabs_generate_asm_endfunc (current_name, current_label); 504360484Sobrien 504460484Sobrien current_name = current_label = NULL; 504560484Sobrien } 504660484Sobrien else /* ! end_p */ 504760484Sobrien { 504860484Sobrien char *name,*label; 504960484Sobrien char delim1,delim2; 505060484Sobrien 505160484Sobrien if (current_name != NULL) 505260484Sobrien { 505360484Sobrien as_bad (_(".endfunc missing for previous .func")); 505460484Sobrien ignore_rest_of_line (); 505560484Sobrien return; 505660484Sobrien } 505760484Sobrien 505860484Sobrien name = input_line_pointer; 505960484Sobrien delim1 = get_symbol_end (); 506060484Sobrien name = xstrdup (name); 506160484Sobrien *input_line_pointer = delim1; 506260484Sobrien SKIP_WHITESPACE (); 506360484Sobrien if (*input_line_pointer != ',') 506460484Sobrien { 506560484Sobrien if (default_prefix) 506660484Sobrien asprintf (&label, "%s%s", default_prefix, name); 506760484Sobrien else 506860484Sobrien { 506960484Sobrien char leading_char = 0; 507060484Sobrien#ifdef BFD_ASSEMBLER 507160484Sobrien leading_char = bfd_get_symbol_leading_char (stdoutput); 507260484Sobrien#endif 507360484Sobrien /* Missing entry point, use function's name with the leading 507460484Sobrien char prepended. */ 507560484Sobrien if (leading_char) 507660484Sobrien asprintf (&label, "%c%s", leading_char, name); 507760484Sobrien else 507860484Sobrien label = name; 507960484Sobrien } 508060484Sobrien } 508160484Sobrien else 508260484Sobrien { 508360484Sobrien ++input_line_pointer; 508460484Sobrien SKIP_WHITESPACE (); 508560484Sobrien label = input_line_pointer; 508660484Sobrien delim2 = get_symbol_end (); 508760484Sobrien label = xstrdup (label); 508860484Sobrien *input_line_pointer = delim2; 508960484Sobrien } 509060484Sobrien 509160484Sobrien if (debug_type == DEBUG_STABS) 509260484Sobrien stabs_generate_asm_func (name, label); 509360484Sobrien 509460484Sobrien current_name = name; 509560484Sobrien current_label = label; 509660484Sobrien } 509760484Sobrien 509860484Sobrien demand_empty_rest_of_line (); 509960484Sobrien} 510060484Sobrien 510133965Sjdpvoid 510233965Sjdps_ignore (arg) 510360484Sobrien int arg ATTRIBUTE_UNUSED; 510433965Sjdp{ 510533965Sjdp while (!is_end_of_line[(unsigned char) *input_line_pointer]) 510633965Sjdp { 510733965Sjdp ++input_line_pointer; 510833965Sjdp } 510933965Sjdp ++input_line_pointer; 511033965Sjdp} 511133965Sjdp 511233965Sjdp 511333965Sjdpvoid 511433965Sjdpread_print_statistics (file) 511533965Sjdp FILE *file; 511633965Sjdp{ 511733965Sjdp hash_print_statistics (file, "pseudo-op table", po_hash); 511833965Sjdp} 511933965Sjdp 512060484Sobrien/* Inserts the given line into the input stream. 512160484Sobrien 512260484Sobrien This call avoids macro/conditionals nesting checking, since the contents of 512360484Sobrien the line are assumed to replace the contents of a line already scanned. 512460484Sobrien 512560484Sobrien An appropriate use of this function would be substition of input lines when 512660484Sobrien called by md_start_line_hook(). The given line is assumed to already be 512760484Sobrien properly scrubbed. */ 512860484Sobrien 512960484Sobrienvoid 513060484Sobrieninput_scrub_insert_line (line) 513160484Sobrien const char *line; 513260484Sobrien{ 513360484Sobrien sb newline; 513460484Sobrien sb_new (&newline); 513560484Sobrien sb_add_string (&newline, line); 513660484Sobrien input_scrub_include_sb (&newline, input_line_pointer, 0); 513760484Sobrien sb_kill (&newline); 513860484Sobrien buffer_limit = input_scrub_next_buffer (&input_line_pointer); 513960484Sobrien} 514060484Sobrien 514160484Sobrien/* Insert a file into the input stream; the path must resolve to an actual 514260484Sobrien file; no include path searching or dependency registering is performed. */ 514360484Sobrien 514460484Sobrienvoid 514560484Sobrieninput_scrub_insert_file (path) 514660484Sobrien char *path; 514760484Sobrien{ 514860484Sobrien input_scrub_include_file (path, input_line_pointer); 514960484Sobrien buffer_limit = input_scrub_next_buffer (&input_line_pointer); 515060484Sobrien} 515160484Sobrien 515233965Sjdp/* end of read.c */ 5153