expr.c revision 60484
133965Sjdp/* expr.c -operands, expressions- 260484Sobrien Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000 333965Sjdp Free Software Foundation, Inc. 433965Sjdp 533965Sjdp This file is part of GAS, the GNU Assembler. 633965Sjdp 733965Sjdp GAS is free software; you can redistribute it and/or modify 833965Sjdp it under the terms of the GNU General Public License as published by 933965Sjdp the Free Software Foundation; either version 2, or (at your option) 1033965Sjdp any later version. 1133965Sjdp 1233965Sjdp GAS is distributed in the hope that it will be useful, 1333965Sjdp but WITHOUT ANY WARRANTY; without even the implied warranty of 1433965Sjdp MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1533965Sjdp GNU General Public License for more details. 1633965Sjdp 1733965Sjdp You should have received a copy of the GNU General Public License 1833965Sjdp along with GAS; see the file COPYING. If not, write to the Free 1933965Sjdp Software Foundation, 59 Temple Place - Suite 330, Boston, MA 2033965Sjdp 02111-1307, USA. */ 2133965Sjdp 2233965Sjdp/* 2333965Sjdp * This is really a branch office of as-read.c. I split it out to clearly 2433965Sjdp * distinguish the world of expressions from the world of statements. 2533965Sjdp * (It also gives smaller files to re-compile.) 2633965Sjdp * Here, "operand"s are of expressions, not instructions. 2733965Sjdp */ 2833965Sjdp 2933965Sjdp#include <ctype.h> 3033965Sjdp#include <string.h> 3138889Sjdp#define min(a, b) ((a) < (b) ? (a) : (b)) 3233965Sjdp 3333965Sjdp#include "as.h" 3433965Sjdp#include "obstack.h" 3533965Sjdp 3633965Sjdpstatic void floating_constant PARAMS ((expressionS * expressionP)); 3760484Sobrienstatic valueT generic_bignum_to_int32 PARAMS ((void)); 3860484Sobrien#ifdef BFD64 3960484Sobrienstatic valueT generic_bignum_to_int64 PARAMS ((void)); 4060484Sobrien#endif 4133965Sjdpstatic void integer_constant PARAMS ((int radix, expressionS * expressionP)); 4233965Sjdpstatic void mri_char_constant PARAMS ((expressionS *)); 4333965Sjdpstatic void current_location PARAMS ((expressionS *)); 4433965Sjdpstatic void clean_up_expression PARAMS ((expressionS * expressionP)); 4533965Sjdpstatic segT operand PARAMS ((expressionS *)); 4633965Sjdpstatic operatorT operator PARAMS ((void)); 4733965Sjdp 4833965Sjdpextern const char EXP_CHARS[], FLT_CHARS[]; 4933965Sjdp 5033965Sjdp/* We keep a mapping of expression symbols to file positions, so that 5133965Sjdp we can provide better error messages. */ 5233965Sjdp 5333965Sjdpstruct expr_symbol_line 5433965Sjdp{ 5533965Sjdp struct expr_symbol_line *next; 5633965Sjdp symbolS *sym; 5733965Sjdp char *file; 5833965Sjdp unsigned int line; 5933965Sjdp}; 6033965Sjdp 6133965Sjdpstatic struct expr_symbol_line *expr_symbol_lines; 6233965Sjdp 6333965Sjdp/* Build a dummy symbol to hold a complex expression. This is how we 6433965Sjdp build expressions up out of other expressions. The symbol is put 6533965Sjdp into the fake section expr_section. */ 6633965Sjdp 6733965SjdpsymbolS * 6833965Sjdpmake_expr_symbol (expressionP) 6933965Sjdp expressionS *expressionP; 7033965Sjdp{ 7160484Sobrien expressionS zero; 7233965Sjdp const char *fake; 7333965Sjdp symbolS *symbolP; 7433965Sjdp struct expr_symbol_line *n; 7533965Sjdp 7633965Sjdp if (expressionP->X_op == O_symbol 7733965Sjdp && expressionP->X_add_number == 0) 7833965Sjdp return expressionP->X_add_symbol; 7933965Sjdp 8060484Sobrien if (expressionP->X_op == O_big) 8160484Sobrien { 8260484Sobrien /* This won't work, because the actual value is stored in 8360484Sobrien generic_floating_point_number or generic_bignum, and we are 8460484Sobrien going to lose it if we haven't already. */ 8560484Sobrien if (expressionP->X_add_number > 0) 8660484Sobrien as_bad (_("bignum invalid; zero assumed")); 8760484Sobrien else 8860484Sobrien as_bad (_("floating point number invalid; zero assumed")); 8960484Sobrien zero.X_op = O_constant; 9060484Sobrien zero.X_add_number = 0; 9160484Sobrien zero.X_unsigned = 0; 9260484Sobrien clean_up_expression (&zero); 9360484Sobrien expressionP = &zero; 9460484Sobrien } 9560484Sobrien 9633965Sjdp fake = FAKE_LABEL_NAME; 9733965Sjdp 9833965Sjdp /* Putting constant symbols in absolute_section rather than 9933965Sjdp expr_section is convenient for the old a.out code, for which 10033965Sjdp S_GET_SEGMENT does not always retrieve the value put in by 10133965Sjdp S_SET_SEGMENT. */ 10233965Sjdp symbolP = symbol_create (fake, 10333965Sjdp (expressionP->X_op == O_constant 10433965Sjdp ? absolute_section 10533965Sjdp : expr_section), 10633965Sjdp 0, &zero_address_frag); 10760484Sobrien symbol_set_value_expression (symbolP, expressionP); 10833965Sjdp 10933965Sjdp if (expressionP->X_op == O_constant) 11038889Sjdp resolve_symbol_value (symbolP, 1); 11133965Sjdp 11233965Sjdp n = (struct expr_symbol_line *) xmalloc (sizeof *n); 11333965Sjdp n->sym = symbolP; 11433965Sjdp as_where (&n->file, &n->line); 11533965Sjdp n->next = expr_symbol_lines; 11633965Sjdp expr_symbol_lines = n; 11733965Sjdp 11833965Sjdp return symbolP; 11933965Sjdp} 12033965Sjdp 12133965Sjdp/* Return the file and line number for an expr symbol. Return 12233965Sjdp non-zero if something was found, 0 if no information is known for 12333965Sjdp the symbol. */ 12433965Sjdp 12533965Sjdpint 12633965Sjdpexpr_symbol_where (sym, pfile, pline) 12733965Sjdp symbolS *sym; 12833965Sjdp char **pfile; 12933965Sjdp unsigned int *pline; 13033965Sjdp{ 13133965Sjdp register struct expr_symbol_line *l; 13233965Sjdp 13333965Sjdp for (l = expr_symbol_lines; l != NULL; l = l->next) 13433965Sjdp { 13533965Sjdp if (l->sym == sym) 13633965Sjdp { 13733965Sjdp *pfile = l->file; 13833965Sjdp *pline = l->line; 13933965Sjdp return 1; 14033965Sjdp } 14133965Sjdp } 14233965Sjdp 14333965Sjdp return 0; 14433965Sjdp} 14533965Sjdp 14638889Sjdp/* Utilities for building expressions. 14738889Sjdp Since complex expressions are recorded as symbols for use in other 14838889Sjdp expressions these return a symbolS * and not an expressionS *. 14938889Sjdp These explicitly do not take an "add_number" argument. */ 15038889Sjdp/* ??? For completeness' sake one might want expr_build_symbol. 15138889Sjdp It would just return its argument. */ 15238889Sjdp 15338889Sjdp/* Build an expression for an unsigned constant. 15438889Sjdp The corresponding one for signed constants is missing because 15538889Sjdp there's currently no need for it. One could add an unsigned_p flag 15638889Sjdp but that seems more clumsy. */ 15738889Sjdp 15838889SjdpsymbolS * 15938889Sjdpexpr_build_uconstant (value) 16038889Sjdp offsetT value; 16138889Sjdp{ 16238889Sjdp expressionS e; 16338889Sjdp 16438889Sjdp e.X_op = O_constant; 16538889Sjdp e.X_add_number = value; 16638889Sjdp e.X_unsigned = 1; 16738889Sjdp return make_expr_symbol (&e); 16838889Sjdp} 16938889Sjdp 17038889Sjdp/* Build an expression for OP s1. */ 17138889Sjdp 17238889SjdpsymbolS * 17338889Sjdpexpr_build_unary (op, s1) 17438889Sjdp operatorT op; 17538889Sjdp symbolS *s1; 17638889Sjdp{ 17738889Sjdp expressionS e; 17838889Sjdp 17938889Sjdp e.X_op = op; 18038889Sjdp e.X_add_symbol = s1; 18138889Sjdp e.X_add_number = 0; 18238889Sjdp return make_expr_symbol (&e); 18338889Sjdp} 18438889Sjdp 18538889Sjdp/* Build an expression for s1 OP s2. */ 18638889Sjdp 18738889SjdpsymbolS * 18838889Sjdpexpr_build_binary (op, s1, s2) 18938889Sjdp operatorT op; 19038889Sjdp symbolS *s1; 19138889Sjdp symbolS *s2; 19238889Sjdp{ 19338889Sjdp expressionS e; 19438889Sjdp 19538889Sjdp e.X_op = op; 19638889Sjdp e.X_add_symbol = s1; 19738889Sjdp e.X_op_symbol = s2; 19838889Sjdp e.X_add_number = 0; 19938889Sjdp return make_expr_symbol (&e); 20038889Sjdp} 20160484Sobrien 20260484Sobrien/* Build an expression for the current location ('.'). */ 20360484Sobrien 20460484SobriensymbolS * 20560484Sobrienexpr_build_dot () 20660484Sobrien{ 20760484Sobrien expressionS e; 20860484Sobrien 20960484Sobrien current_location (&e); 21060484Sobrien return make_expr_symbol (&e); 21160484Sobrien} 21238889Sjdp 21333965Sjdp/* 21433965Sjdp * Build any floating-point literal here. 21533965Sjdp * Also build any bignum literal here. 21633965Sjdp */ 21733965Sjdp 21833965Sjdp/* Seems atof_machine can backscan through generic_bignum and hit whatever 21933965Sjdp happens to be loaded before it in memory. And its way too complicated 22033965Sjdp for me to fix right. Thus a hack. JF: Just make generic_bignum bigger, 22133965Sjdp and never write into the early words, thus they'll always be zero. 22233965Sjdp I hate Dean's floating-point code. Bleh. */ 22333965SjdpLITTLENUM_TYPE generic_bignum[SIZE_OF_LARGE_NUMBER + 6]; 22433965SjdpFLONUM_TYPE generic_floating_point_number = 22533965Sjdp{ 22633965Sjdp &generic_bignum[6], /* low (JF: Was 0) */ 22733965Sjdp &generic_bignum[SIZE_OF_LARGE_NUMBER + 6 - 1], /* high JF: (added +6) */ 22833965Sjdp 0, /* leader */ 22933965Sjdp 0, /* exponent */ 23033965Sjdp 0 /* sign */ 23133965Sjdp}; 23233965Sjdp/* If nonzero, we've been asked to assemble nan, +inf or -inf */ 23333965Sjdpint generic_floating_point_magic; 23433965Sjdp 23533965Sjdpstatic void 23633965Sjdpfloating_constant (expressionP) 23733965Sjdp expressionS *expressionP; 23833965Sjdp{ 23933965Sjdp /* input_line_pointer->*/ 24033965Sjdp /* floating-point constant. */ 24133965Sjdp int error_code; 24233965Sjdp 24333965Sjdp error_code = atof_generic (&input_line_pointer, ".", EXP_CHARS, 24433965Sjdp &generic_floating_point_number); 24533965Sjdp 24633965Sjdp if (error_code) 24733965Sjdp { 24833965Sjdp if (error_code == ERROR_EXPONENT_OVERFLOW) 24933965Sjdp { 25060484Sobrien as_bad (_("bad floating-point constant: exponent overflow, probably assembling junk")); 25133965Sjdp } 25233965Sjdp else 25333965Sjdp { 25460484Sobrien as_bad (_("bad floating-point constant: unknown error code=%d."), error_code); 25533965Sjdp } 25633965Sjdp } 25733965Sjdp expressionP->X_op = O_big; 25833965Sjdp /* input_line_pointer->just after constant, */ 25933965Sjdp /* which may point to whitespace. */ 26033965Sjdp expressionP->X_add_number = -1; 26133965Sjdp} 26233965Sjdp 26338889Sjdpstatic valueT 26438889Sjdpgeneric_bignum_to_int32 () 26538889Sjdp{ 26638889Sjdp valueT number = 26738889Sjdp ((generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS) 26838889Sjdp | (generic_bignum[0] & LITTLENUM_MASK); 26938889Sjdp number &= 0xffffffff; 27038889Sjdp return number; 27138889Sjdp} 27238889Sjdp 27338889Sjdp#ifdef BFD64 27438889Sjdpstatic valueT 27538889Sjdpgeneric_bignum_to_int64 () 27638889Sjdp{ 27738889Sjdp valueT number = 27838889Sjdp ((((((((valueT) generic_bignum[3] & LITTLENUM_MASK) 27938889Sjdp << LITTLENUM_NUMBER_OF_BITS) 28038889Sjdp | ((valueT) generic_bignum[2] & LITTLENUM_MASK)) 28138889Sjdp << LITTLENUM_NUMBER_OF_BITS) 28238889Sjdp | ((valueT) generic_bignum[1] & LITTLENUM_MASK)) 28338889Sjdp << LITTLENUM_NUMBER_OF_BITS) 28438889Sjdp | ((valueT) generic_bignum[0] & LITTLENUM_MASK)); 28538889Sjdp return number; 28638889Sjdp} 28738889Sjdp#endif 28838889Sjdp 28933965Sjdpstatic void 29033965Sjdpinteger_constant (radix, expressionP) 29133965Sjdp int radix; 29233965Sjdp expressionS *expressionP; 29333965Sjdp{ 29433965Sjdp char *start; /* start of number. */ 29533965Sjdp char *suffix = NULL; 29633965Sjdp char c; 29733965Sjdp valueT number; /* offset or (absolute) value */ 29833965Sjdp short int digit; /* value of next digit in current radix */ 29933965Sjdp short int maxdig = 0;/* highest permitted digit value. */ 30033965Sjdp int too_many_digits = 0; /* if we see >= this number of */ 30133965Sjdp char *name; /* points to name of symbol */ 30233965Sjdp symbolS *symbolP; /* points to symbol */ 30333965Sjdp 30433965Sjdp int small; /* true if fits in 32 bits. */ 30533965Sjdp 30633965Sjdp /* May be bignum, or may fit in 32 bits. */ 30733965Sjdp /* Most numbers fit into 32 bits, and we want this case to be fast. 30833965Sjdp so we pretend it will fit into 32 bits. If, after making up a 32 30933965Sjdp bit number, we realise that we have scanned more digits than 31033965Sjdp comfortably fit into 32 bits, we re-scan the digits coding them 31133965Sjdp into a bignum. For decimal and octal numbers we are 31233965Sjdp conservative: Some numbers may be assumed bignums when in fact 31333965Sjdp they do fit into 32 bits. Numbers of any radix can have excess 31433965Sjdp leading zeros: We strive to recognise this and cast them back 31533965Sjdp into 32 bits. We must check that the bignum really is more than 31633965Sjdp 32 bits, and change it back to a 32-bit number if it fits. The 31733965Sjdp number we are looking for is expected to be positive, but if it 31833965Sjdp fits into 32 bits as an unsigned number, we let it be a 32-bit 31933965Sjdp number. The cavalier approach is for speed in ordinary cases. */ 32033965Sjdp /* This has been extended for 64 bits. We blindly assume that if 32133965Sjdp you're compiling in 64-bit mode, the target is a 64-bit machine. 32233965Sjdp This should be cleaned up. */ 32333965Sjdp 32433965Sjdp#ifdef BFD64 32533965Sjdp#define valuesize 64 32633965Sjdp#else /* includes non-bfd case, mostly */ 32733965Sjdp#define valuesize 32 32833965Sjdp#endif 32933965Sjdp 33060484Sobrien if ((NUMBERS_WITH_SUFFIX || flag_m68k_mri) && radix == 0) 33133965Sjdp { 33233965Sjdp int flt = 0; 33333965Sjdp 33433965Sjdp /* In MRI mode, the number may have a suffix indicating the 33533965Sjdp radix. For that matter, it might actually be a floating 33633965Sjdp point constant. */ 33738889Sjdp for (suffix = input_line_pointer; 33838889Sjdp isalnum ((unsigned char) *suffix); 33938889Sjdp suffix++) 34033965Sjdp { 34133965Sjdp if (*suffix == 'e' || *suffix == 'E') 34233965Sjdp flt = 1; 34333965Sjdp } 34433965Sjdp 34533965Sjdp if (suffix == input_line_pointer) 34633965Sjdp { 34733965Sjdp radix = 10; 34833965Sjdp suffix = NULL; 34933965Sjdp } 35033965Sjdp else 35133965Sjdp { 35233965Sjdp c = *--suffix; 35338889Sjdp if (islower ((unsigned char) c)) 35433965Sjdp c = toupper (c); 35533965Sjdp if (c == 'B') 35633965Sjdp radix = 2; 35733965Sjdp else if (c == 'D') 35833965Sjdp radix = 10; 35933965Sjdp else if (c == 'O' || c == 'Q') 36033965Sjdp radix = 8; 36133965Sjdp else if (c == 'H') 36233965Sjdp radix = 16; 36333965Sjdp else if (suffix[1] == '.' || c == 'E' || flt) 36433965Sjdp { 36533965Sjdp floating_constant (expressionP); 36633965Sjdp return; 36733965Sjdp } 36833965Sjdp else 36933965Sjdp { 37033965Sjdp radix = 10; 37133965Sjdp suffix = NULL; 37233965Sjdp } 37333965Sjdp } 37433965Sjdp } 37533965Sjdp 37633965Sjdp switch (radix) 37733965Sjdp { 37833965Sjdp case 2: 37933965Sjdp maxdig = 2; 38033965Sjdp too_many_digits = valuesize + 1; 38133965Sjdp break; 38233965Sjdp case 8: 38333965Sjdp maxdig = radix = 8; 38433965Sjdp too_many_digits = (valuesize + 2) / 3 + 1; 38533965Sjdp break; 38633965Sjdp case 16: 38733965Sjdp maxdig = radix = 16; 38833965Sjdp too_many_digits = (valuesize + 3) / 4 + 1; 38933965Sjdp break; 39033965Sjdp case 10: 39133965Sjdp maxdig = radix = 10; 39260484Sobrien too_many_digits = (valuesize + 11) / 4; /* very rough */ 39333965Sjdp } 39433965Sjdp#undef valuesize 39533965Sjdp start = input_line_pointer; 39633965Sjdp c = *input_line_pointer++; 39733965Sjdp for (number = 0; 39833965Sjdp (digit = hex_value (c)) < maxdig; 39933965Sjdp c = *input_line_pointer++) 40033965Sjdp { 40133965Sjdp number = number * radix + digit; 40233965Sjdp } 40333965Sjdp /* c contains character after number. */ 40433965Sjdp /* input_line_pointer->char after c. */ 40533965Sjdp small = (input_line_pointer - start - 1) < too_many_digits; 40638889Sjdp 40738889Sjdp if (radix == 16 && c == '_') 40833965Sjdp { 40938889Sjdp /* This is literal of the form 0x333_0_12345678_1. 41038889Sjdp This example is equivalent to 0x00000333000000001234567800000001. */ 41138889Sjdp 41238889Sjdp int num_little_digits = 0; 41338889Sjdp int i; 41438889Sjdp input_line_pointer = start; /*->1st digit. */ 41538889Sjdp 41638889Sjdp know (LITTLENUM_NUMBER_OF_BITS == 16); 41738889Sjdp 41838889Sjdp for (c = '_'; c == '_'; num_little_digits+=2) 41938889Sjdp { 42038889Sjdp 42138889Sjdp /* Convert one 64-bit word. */ 42238889Sjdp int ndigit = 0; 42338889Sjdp number = 0; 42438889Sjdp for (c = *input_line_pointer++; 42538889Sjdp (digit = hex_value (c)) < maxdig; 42638889Sjdp c = *(input_line_pointer++)) 42738889Sjdp { 42838889Sjdp number = number * radix + digit; 42938889Sjdp ndigit++; 43038889Sjdp } 43138889Sjdp 43238889Sjdp /* Check for 8 digit per word max. */ 43338889Sjdp if (ndigit > 8) 43460484Sobrien as_bad (_("A bignum with underscores may not have more than 8 hex digits in any word.")); 43538889Sjdp 43638889Sjdp /* Add this chunk to the bignum. Shift things down 2 little digits.*/ 43738889Sjdp know (LITTLENUM_NUMBER_OF_BITS == 16); 43838889Sjdp for (i = min (num_little_digits + 1, SIZE_OF_LARGE_NUMBER - 1); i >= 2; i--) 43938889Sjdp generic_bignum[i] = generic_bignum[i-2]; 44038889Sjdp 44138889Sjdp /* Add the new digits as the least significant new ones. */ 44238889Sjdp generic_bignum[0] = number & 0xffffffff; 44338889Sjdp generic_bignum[1] = number >> 16; 44438889Sjdp } 44538889Sjdp 44638889Sjdp /* Again, c is char after number, input_line_pointer->after c. */ 44738889Sjdp 44838889Sjdp if (num_little_digits > SIZE_OF_LARGE_NUMBER - 1) 44938889Sjdp num_little_digits = SIZE_OF_LARGE_NUMBER - 1; 45038889Sjdp 45138889Sjdp assert (num_little_digits >= 4); 45238889Sjdp 45338889Sjdp if (num_little_digits != 8) 45460484Sobrien as_bad (_("A bignum with underscores must have exactly 4 words.")); 45538889Sjdp 45638889Sjdp /* We might have some leading zeros. These can be trimmed to give 45738889Sjdp * us a change to fit this constant into a small number. 45838889Sjdp */ 45938889Sjdp while (generic_bignum[num_little_digits-1] == 0 && num_little_digits > 1) 46038889Sjdp num_little_digits--; 46138889Sjdp 46238889Sjdp if (num_little_digits <= 2) 46338889Sjdp { 46438889Sjdp /* will fit into 32 bits. */ 46538889Sjdp number = generic_bignum_to_int32 (); 46638889Sjdp small = 1; 46738889Sjdp } 46838889Sjdp#ifdef BFD64 46938889Sjdp else if (num_little_digits <= 4) 47038889Sjdp { 47138889Sjdp /* Will fit into 64 bits. */ 47238889Sjdp number = generic_bignum_to_int64 (); 47338889Sjdp small = 1; 47438889Sjdp } 47538889Sjdp#endif 47638889Sjdp else 47738889Sjdp { 47838889Sjdp small = 0; 47938889Sjdp number = num_little_digits; /* number of littlenums in the bignum. */ 48038889Sjdp } 48138889Sjdp } 48238889Sjdp else if (!small) 48338889Sjdp { 48433965Sjdp /* 48533965Sjdp * we saw a lot of digits. manufacture a bignum the hard way. 48633965Sjdp */ 48733965Sjdp LITTLENUM_TYPE *leader; /*->high order littlenum of the bignum. */ 48833965Sjdp LITTLENUM_TYPE *pointer; /*->littlenum we are frobbing now. */ 48933965Sjdp long carry; 49033965Sjdp 49133965Sjdp leader = generic_bignum; 49233965Sjdp generic_bignum[0] = 0; 49333965Sjdp generic_bignum[1] = 0; 49438889Sjdp generic_bignum[2] = 0; 49538889Sjdp generic_bignum[3] = 0; 49633965Sjdp input_line_pointer = start; /*->1st digit. */ 49733965Sjdp c = *input_line_pointer++; 49833965Sjdp for (; 49933965Sjdp (carry = hex_value (c)) < maxdig; 50033965Sjdp c = *input_line_pointer++) 50133965Sjdp { 50233965Sjdp for (pointer = generic_bignum; 50333965Sjdp pointer <= leader; 50433965Sjdp pointer++) 50533965Sjdp { 50633965Sjdp long work; 50733965Sjdp 50833965Sjdp work = carry + radix * *pointer; 50933965Sjdp *pointer = work & LITTLENUM_MASK; 51033965Sjdp carry = work >> LITTLENUM_NUMBER_OF_BITS; 51133965Sjdp } 51233965Sjdp if (carry) 51333965Sjdp { 51433965Sjdp if (leader < generic_bignum + SIZE_OF_LARGE_NUMBER - 1) 51533965Sjdp { 51633965Sjdp /* room to grow a longer bignum. */ 51733965Sjdp *++leader = carry; 51833965Sjdp } 51933965Sjdp } 52033965Sjdp } 52133965Sjdp /* again, c is char after number, */ 52233965Sjdp /* input_line_pointer->after c. */ 52333965Sjdp know (LITTLENUM_NUMBER_OF_BITS == 16); 52433965Sjdp if (leader < generic_bignum + 2) 52533965Sjdp { 52633965Sjdp /* will fit into 32 bits. */ 52738889Sjdp number = generic_bignum_to_int32 (); 52833965Sjdp small = 1; 52933965Sjdp } 53038889Sjdp#ifdef BFD64 53138889Sjdp else if (leader < generic_bignum + 4) 53238889Sjdp { 53338889Sjdp /* Will fit into 64 bits. */ 53438889Sjdp number = generic_bignum_to_int64 (); 53538889Sjdp small = 1; 53638889Sjdp } 53738889Sjdp#endif 53833965Sjdp else 53933965Sjdp { 54033965Sjdp number = leader - generic_bignum + 1; /* number of littlenums in the bignum. */ 54133965Sjdp } 54233965Sjdp } 54333965Sjdp 54460484Sobrien if ((NUMBERS_WITH_SUFFIX || flag_m68k_mri) 54560484Sobrien && suffix != NULL 54660484Sobrien && input_line_pointer - 1 == suffix) 54733965Sjdp c = *input_line_pointer++; 54833965Sjdp 54933965Sjdp if (small) 55033965Sjdp { 55133965Sjdp /* 55233965Sjdp * here with number, in correct radix. c is the next char. 55333965Sjdp * note that unlike un*x, we allow "011f" "0x9f" to 55433965Sjdp * both mean the same as the (conventional) "9f". this is simply easier 55533965Sjdp * than checking for strict canonical form. syntax sux! 55633965Sjdp */ 55733965Sjdp 55833965Sjdp if (LOCAL_LABELS_FB && c == 'b') 55933965Sjdp { 56033965Sjdp /* 56133965Sjdp * backward ref to local label. 56233965Sjdp * because it is backward, expect it to be defined. 56333965Sjdp */ 56433965Sjdp /* Construct a local label. */ 56533965Sjdp name = fb_label_name ((int) number, 0); 56633965Sjdp 56733965Sjdp /* seen before, or symbol is defined: ok */ 56833965Sjdp symbolP = symbol_find (name); 56933965Sjdp if ((symbolP != NULL) && (S_IS_DEFINED (symbolP))) 57033965Sjdp { 57133965Sjdp /* local labels are never absolute. don't waste time 57233965Sjdp checking absoluteness. */ 57333965Sjdp know (SEG_NORMAL (S_GET_SEGMENT (symbolP))); 57433965Sjdp 57533965Sjdp expressionP->X_op = O_symbol; 57633965Sjdp expressionP->X_add_symbol = symbolP; 57733965Sjdp } 57833965Sjdp else 57933965Sjdp { 58033965Sjdp /* either not seen or not defined. */ 58133965Sjdp /* @@ Should print out the original string instead of 58233965Sjdp the parsed number. */ 58360484Sobrien as_bad (_("backw. ref to unknown label \"%d:\", 0 assumed."), 58433965Sjdp (int) number); 58533965Sjdp expressionP->X_op = O_constant; 58633965Sjdp } 58733965Sjdp 58833965Sjdp expressionP->X_add_number = 0; 58933965Sjdp } /* case 'b' */ 59033965Sjdp else if (LOCAL_LABELS_FB && c == 'f') 59133965Sjdp { 59233965Sjdp /* 59333965Sjdp * forward reference. expect symbol to be undefined or 59433965Sjdp * unknown. undefined: seen it before. unknown: never seen 59533965Sjdp * it before. 59633965Sjdp * construct a local label name, then an undefined symbol. 59733965Sjdp * don't create a xseg frag for it: caller may do that. 59833965Sjdp * just return it as never seen before. 59933965Sjdp */ 60033965Sjdp name = fb_label_name ((int) number, 1); 60133965Sjdp symbolP = symbol_find_or_make (name); 60233965Sjdp /* we have no need to check symbol properties. */ 60333965Sjdp#ifndef many_segments 60433965Sjdp /* since "know" puts its arg into a "string", we 60533965Sjdp can't have newlines in the argument. */ 60633965Sjdp know (S_GET_SEGMENT (symbolP) == undefined_section || S_GET_SEGMENT (symbolP) == text_section || S_GET_SEGMENT (symbolP) == data_section); 60733965Sjdp#endif 60833965Sjdp expressionP->X_op = O_symbol; 60933965Sjdp expressionP->X_add_symbol = symbolP; 61033965Sjdp expressionP->X_add_number = 0; 61133965Sjdp } /* case 'f' */ 61233965Sjdp else if (LOCAL_LABELS_DOLLAR && c == '$') 61333965Sjdp { 61433965Sjdp /* If the dollar label is *currently* defined, then this is just 61533965Sjdp another reference to it. If it is not *currently* defined, 61633965Sjdp then this is a fresh instantiation of that number, so create 61733965Sjdp it. */ 61833965Sjdp 61933965Sjdp if (dollar_label_defined ((long) number)) 62033965Sjdp { 62133965Sjdp name = dollar_label_name ((long) number, 0); 62233965Sjdp symbolP = symbol_find (name); 62333965Sjdp know (symbolP != NULL); 62433965Sjdp } 62533965Sjdp else 62633965Sjdp { 62733965Sjdp name = dollar_label_name ((long) number, 1); 62833965Sjdp symbolP = symbol_find_or_make (name); 62933965Sjdp } 63033965Sjdp 63133965Sjdp expressionP->X_op = O_symbol; 63233965Sjdp expressionP->X_add_symbol = symbolP; 63333965Sjdp expressionP->X_add_number = 0; 63433965Sjdp } /* case '$' */ 63533965Sjdp else 63633965Sjdp { 63733965Sjdp expressionP->X_op = O_constant; 63833965Sjdp#ifdef TARGET_WORD_SIZE 63933965Sjdp /* Sign extend NUMBER. */ 64033965Sjdp number |= (-(number >> (TARGET_WORD_SIZE - 1))) << (TARGET_WORD_SIZE - 1); 64133965Sjdp#endif 64233965Sjdp expressionP->X_add_number = number; 64333965Sjdp input_line_pointer--; /* restore following character. */ 64433965Sjdp } /* really just a number */ 64533965Sjdp } 64633965Sjdp else 64733965Sjdp { 64833965Sjdp /* not a small number */ 64933965Sjdp expressionP->X_op = O_big; 65033965Sjdp expressionP->X_add_number = number; /* number of littlenums */ 65133965Sjdp input_line_pointer--; /*->char following number. */ 65233965Sjdp } 65333965Sjdp} 65433965Sjdp 65533965Sjdp/* Parse an MRI multi character constant. */ 65633965Sjdp 65733965Sjdpstatic void 65833965Sjdpmri_char_constant (expressionP) 65933965Sjdp expressionS *expressionP; 66033965Sjdp{ 66133965Sjdp int i; 66233965Sjdp 66333965Sjdp if (*input_line_pointer == '\'' 66433965Sjdp && input_line_pointer[1] != '\'') 66533965Sjdp { 66633965Sjdp expressionP->X_op = O_constant; 66733965Sjdp expressionP->X_add_number = 0; 66833965Sjdp return; 66933965Sjdp } 67033965Sjdp 67133965Sjdp /* In order to get the correct byte ordering, we must build the 67233965Sjdp number in reverse. */ 67333965Sjdp for (i = SIZE_OF_LARGE_NUMBER - 1; i >= 0; i--) 67433965Sjdp { 67533965Sjdp int j; 67633965Sjdp 67733965Sjdp generic_bignum[i] = 0; 67833965Sjdp for (j = 0; j < CHARS_PER_LITTLENUM; j++) 67933965Sjdp { 68033965Sjdp if (*input_line_pointer == '\'') 68133965Sjdp { 68233965Sjdp if (input_line_pointer[1] != '\'') 68333965Sjdp break; 68433965Sjdp ++input_line_pointer; 68533965Sjdp } 68633965Sjdp generic_bignum[i] <<= 8; 68733965Sjdp generic_bignum[i] += *input_line_pointer; 68833965Sjdp ++input_line_pointer; 68933965Sjdp } 69033965Sjdp 69133965Sjdp if (i < SIZE_OF_LARGE_NUMBER - 1) 69233965Sjdp { 69333965Sjdp /* If there is more than one littlenum, left justify the 69433965Sjdp last one to make it match the earlier ones. If there is 69533965Sjdp only one, we can just use the value directly. */ 69633965Sjdp for (; j < CHARS_PER_LITTLENUM; j++) 69733965Sjdp generic_bignum[i] <<= 8; 69833965Sjdp } 69933965Sjdp 70033965Sjdp if (*input_line_pointer == '\'' 70133965Sjdp && input_line_pointer[1] != '\'') 70233965Sjdp break; 70333965Sjdp } 70433965Sjdp 70533965Sjdp if (i < 0) 70633965Sjdp { 70760484Sobrien as_bad (_("Character constant too large")); 70833965Sjdp i = 0; 70933965Sjdp } 71033965Sjdp 71133965Sjdp if (i > 0) 71233965Sjdp { 71333965Sjdp int c; 71433965Sjdp int j; 71533965Sjdp 71633965Sjdp c = SIZE_OF_LARGE_NUMBER - i; 71733965Sjdp for (j = 0; j < c; j++) 71833965Sjdp generic_bignum[j] = generic_bignum[i + j]; 71933965Sjdp i = c; 72033965Sjdp } 72133965Sjdp 72233965Sjdp know (LITTLENUM_NUMBER_OF_BITS == 16); 72333965Sjdp if (i > 2) 72433965Sjdp { 72533965Sjdp expressionP->X_op = O_big; 72633965Sjdp expressionP->X_add_number = i; 72733965Sjdp } 72833965Sjdp else 72933965Sjdp { 73033965Sjdp expressionP->X_op = O_constant; 73133965Sjdp if (i < 2) 73233965Sjdp expressionP->X_add_number = generic_bignum[0] & LITTLENUM_MASK; 73333965Sjdp else 73433965Sjdp expressionP->X_add_number = 73533965Sjdp (((generic_bignum[1] & LITTLENUM_MASK) 73633965Sjdp << LITTLENUM_NUMBER_OF_BITS) 73733965Sjdp | (generic_bignum[0] & LITTLENUM_MASK)); 73833965Sjdp } 73933965Sjdp 74033965Sjdp /* Skip the final closing quote. */ 74133965Sjdp ++input_line_pointer; 74233965Sjdp} 74333965Sjdp 74433965Sjdp/* Return an expression representing the current location. This 74533965Sjdp handles the magic symbol `.'. */ 74633965Sjdp 74733965Sjdpstatic void 74833965Sjdpcurrent_location (expressionp) 74933965Sjdp expressionS *expressionp; 75033965Sjdp{ 75133965Sjdp if (now_seg == absolute_section) 75233965Sjdp { 75333965Sjdp expressionp->X_op = O_constant; 75433965Sjdp expressionp->X_add_number = abs_section_offset; 75533965Sjdp } 75633965Sjdp else 75733965Sjdp { 75833965Sjdp symbolS *symbolp; 75933965Sjdp 76033965Sjdp symbolp = symbol_new (FAKE_LABEL_NAME, now_seg, 76133965Sjdp (valueT) frag_now_fix (), 76233965Sjdp frag_now); 76333965Sjdp expressionp->X_op = O_symbol; 76433965Sjdp expressionp->X_add_symbol = symbolp; 76533965Sjdp expressionp->X_add_number = 0; 76633965Sjdp } 76733965Sjdp} 76833965Sjdp 76933965Sjdp/* 77033965Sjdp * Summary of operand(). 77133965Sjdp * 77233965Sjdp * in: Input_line_pointer points to 1st char of operand, which may 77333965Sjdp * be a space. 77433965Sjdp * 77533965Sjdp * out: A expressionS. 77633965Sjdp * The operand may have been empty: in this case X_op == O_absent. 77733965Sjdp * Input_line_pointer->(next non-blank) char after operand. 77833965Sjdp */ 77933965Sjdp 78033965Sjdpstatic segT 78133965Sjdpoperand (expressionP) 78233965Sjdp expressionS *expressionP; 78333965Sjdp{ 78433965Sjdp char c; 78533965Sjdp symbolS *symbolP; /* points to symbol */ 78633965Sjdp char *name; /* points to name of symbol */ 78733965Sjdp segT segment; 78833965Sjdp 78933965Sjdp /* All integers are regarded as unsigned unless they are negated. 79033965Sjdp This is because the only thing which cares whether a number is 79133965Sjdp unsigned is the code in emit_expr which extends constants into 79233965Sjdp bignums. It should only sign extend negative numbers, so that 79333965Sjdp something like ``.quad 0x80000000'' is not sign extended even 79433965Sjdp though it appears negative if valueT is 32 bits. */ 79533965Sjdp expressionP->X_unsigned = 1; 79633965Sjdp 79733965Sjdp /* digits, assume it is a bignum. */ 79833965Sjdp 79933965Sjdp SKIP_WHITESPACE (); /* leading whitespace is part of operand. */ 80033965Sjdp c = *input_line_pointer++; /* input_line_pointer->past char in c. */ 80133965Sjdp 80233965Sjdp switch (c) 80333965Sjdp { 80433965Sjdp case '1': 80533965Sjdp case '2': 80633965Sjdp case '3': 80733965Sjdp case '4': 80833965Sjdp case '5': 80933965Sjdp case '6': 81033965Sjdp case '7': 81133965Sjdp case '8': 81233965Sjdp case '9': 81333965Sjdp input_line_pointer--; 81433965Sjdp 81560484Sobrien integer_constant ((NUMBERS_WITH_SUFFIX || flag_m68k_mri) 81660484Sobrien ? 0 : 10, 81760484Sobrien expressionP); 81833965Sjdp break; 81933965Sjdp 82033965Sjdp case '0': 82133965Sjdp /* non-decimal radix */ 82233965Sjdp 82360484Sobrien if (NUMBERS_WITH_SUFFIX || flag_m68k_mri) 82433965Sjdp { 82533965Sjdp char *s; 82633965Sjdp 82733965Sjdp /* Check for a hex constant. */ 82833965Sjdp for (s = input_line_pointer; hex_p (*s); s++) 82933965Sjdp ; 83033965Sjdp if (*s == 'h' || *s == 'H') 83133965Sjdp { 83233965Sjdp --input_line_pointer; 83333965Sjdp integer_constant (0, expressionP); 83433965Sjdp break; 83533965Sjdp } 83660484Sobrien } 83733965Sjdp c = *input_line_pointer; 83833965Sjdp switch (c) 83933965Sjdp { 84033965Sjdp case 'o': 84133965Sjdp case 'O': 84233965Sjdp case 'q': 84333965Sjdp case 'Q': 84433965Sjdp case '8': 84533965Sjdp case '9': 84660484Sobrien if (NUMBERS_WITH_SUFFIX || flag_m68k_mri) 84733965Sjdp { 84833965Sjdp integer_constant (0, expressionP); 84933965Sjdp break; 85033965Sjdp } 85133965Sjdp /* Fall through. */ 85233965Sjdp default: 85333965Sjdp default_case: 85433965Sjdp if (c && strchr (FLT_CHARS, c)) 85533965Sjdp { 85633965Sjdp input_line_pointer++; 85733965Sjdp floating_constant (expressionP); 85838889Sjdp expressionP->X_add_number = 85938889Sjdp - (isupper ((unsigned char) c) ? tolower (c) : c); 86033965Sjdp } 86133965Sjdp else 86233965Sjdp { 86333965Sjdp /* The string was only zero */ 86433965Sjdp expressionP->X_op = O_constant; 86533965Sjdp expressionP->X_add_number = 0; 86633965Sjdp } 86733965Sjdp 86833965Sjdp break; 86933965Sjdp 87033965Sjdp case 'x': 87133965Sjdp case 'X': 87233965Sjdp if (flag_m68k_mri) 87333965Sjdp goto default_case; 87433965Sjdp input_line_pointer++; 87533965Sjdp integer_constant (16, expressionP); 87633965Sjdp break; 87733965Sjdp 87833965Sjdp case 'b': 87960484Sobrien if (LOCAL_LABELS_FB && ! (flag_m68k_mri || NUMBERS_WITH_SUFFIX)) 88033965Sjdp { 88133965Sjdp /* This code used to check for '+' and '-' here, and, in 88233965Sjdp some conditions, fall through to call 88333965Sjdp integer_constant. However, that didn't make sense, 88433965Sjdp as integer_constant only accepts digits. */ 88533965Sjdp /* Some of our code elsewhere does permit digits greater 88633965Sjdp than the expected base; for consistency, do the same 88733965Sjdp here. */ 88833965Sjdp if (input_line_pointer[1] < '0' 88933965Sjdp || input_line_pointer[1] > '9') 89033965Sjdp { 89133965Sjdp /* Parse this as a back reference to label 0. */ 89233965Sjdp input_line_pointer--; 89333965Sjdp integer_constant (10, expressionP); 89433965Sjdp break; 89533965Sjdp } 89633965Sjdp /* Otherwise, parse this as a binary number. */ 89733965Sjdp } 89833965Sjdp /* Fall through. */ 89933965Sjdp case 'B': 90033965Sjdp input_line_pointer++; 90160484Sobrien if (flag_m68k_mri || NUMBERS_WITH_SUFFIX) 90233965Sjdp goto default_case; 90333965Sjdp integer_constant (2, expressionP); 90433965Sjdp break; 90533965Sjdp 90633965Sjdp case '0': 90733965Sjdp case '1': 90833965Sjdp case '2': 90933965Sjdp case '3': 91033965Sjdp case '4': 91133965Sjdp case '5': 91233965Sjdp case '6': 91333965Sjdp case '7': 91460484Sobrien integer_constant ((flag_m68k_mri || NUMBERS_WITH_SUFFIX) 91560484Sobrien ? 0 : 8, 91660484Sobrien expressionP); 91733965Sjdp break; 91833965Sjdp 91933965Sjdp case 'f': 92033965Sjdp if (LOCAL_LABELS_FB) 92133965Sjdp { 92233965Sjdp /* If it says "0f" and it could possibly be a floating point 92333965Sjdp number, make it one. Otherwise, make it a local label, 92433965Sjdp and try to deal with parsing the rest later. */ 92533965Sjdp if (!input_line_pointer[1] 92660484Sobrien || (is_end_of_line[0xff & input_line_pointer[1]]) 92760484Sobrien || strchr (FLT_CHARS, 'f') == NULL) 92833965Sjdp goto is_0f_label; 92933965Sjdp { 93033965Sjdp char *cp = input_line_pointer + 1; 93133965Sjdp int r = atof_generic (&cp, ".", EXP_CHARS, 93233965Sjdp &generic_floating_point_number); 93333965Sjdp switch (r) 93433965Sjdp { 93533965Sjdp case 0: 93633965Sjdp case ERROR_EXPONENT_OVERFLOW: 93733965Sjdp if (*cp == 'f' || *cp == 'b') 93833965Sjdp /* looks like a difference expression */ 93933965Sjdp goto is_0f_label; 94060484Sobrien else if (cp == input_line_pointer + 1) 94160484Sobrien /* No characters has been accepted -- looks like 94260484Sobrien end of operand. */ 94360484Sobrien goto is_0f_label; 94433965Sjdp else 94533965Sjdp goto is_0f_float; 94633965Sjdp default: 94760484Sobrien as_fatal (_("expr.c(operand): bad atof_generic return val %d"), 94833965Sjdp r); 94933965Sjdp } 95033965Sjdp } 95133965Sjdp 95233965Sjdp /* Okay, now we've sorted it out. We resume at one of these 95333965Sjdp two labels, depending on what we've decided we're probably 95433965Sjdp looking at. */ 95533965Sjdp is_0f_label: 95633965Sjdp input_line_pointer--; 95733965Sjdp integer_constant (10, expressionP); 95833965Sjdp break; 95933965Sjdp 96033965Sjdp is_0f_float: 96133965Sjdp /* fall through */ 96233965Sjdp ; 96333965Sjdp } 96433965Sjdp 96533965Sjdp case 'd': 96633965Sjdp case 'D': 96760484Sobrien if (flag_m68k_mri || NUMBERS_WITH_SUFFIX) 96833965Sjdp { 96933965Sjdp integer_constant (0, expressionP); 97033965Sjdp break; 97133965Sjdp } 97233965Sjdp /* Fall through. */ 97333965Sjdp case 'F': 97433965Sjdp case 'r': 97533965Sjdp case 'e': 97633965Sjdp case 'E': 97733965Sjdp case 'g': 97833965Sjdp case 'G': 97933965Sjdp input_line_pointer++; 98033965Sjdp floating_constant (expressionP); 98138889Sjdp expressionP->X_add_number = 98238889Sjdp - (isupper ((unsigned char) c) ? tolower (c) : c); 98333965Sjdp break; 98433965Sjdp 98533965Sjdp case '$': 98633965Sjdp if (LOCAL_LABELS_DOLLAR) 98733965Sjdp { 98833965Sjdp integer_constant (10, expressionP); 98933965Sjdp break; 99033965Sjdp } 99133965Sjdp else 99233965Sjdp goto default_case; 99333965Sjdp } 99433965Sjdp 99533965Sjdp break; 99633965Sjdp 99733965Sjdp case '(': 99860484Sobrien#ifndef NEED_INDEX_OPERATOR 99933965Sjdp case '[': 100060484Sobrien#endif 100133965Sjdp /* didn't begin with digit & not a name */ 100233965Sjdp segment = expression (expressionP); 100333965Sjdp /* Expression() will pass trailing whitespace */ 100433965Sjdp if ((c == '(' && *input_line_pointer++ != ')') 100533965Sjdp || (c == '[' && *input_line_pointer++ != ']')) 100633965Sjdp { 100760484Sobrien as_bad (_("Missing ')' assumed")); 100833965Sjdp input_line_pointer--; 100933965Sjdp } 101033965Sjdp SKIP_WHITESPACE (); 101133965Sjdp /* here with input_line_pointer->char after "(...)" */ 101233965Sjdp return segment; 101333965Sjdp 101460484Sobrien#ifdef TC_M68K 101533965Sjdp case 'E': 101633965Sjdp if (! flag_m68k_mri || *input_line_pointer != '\'') 101733965Sjdp goto de_fault; 101860484Sobrien as_bad (_("EBCDIC constants are not supported")); 101933965Sjdp /* Fall through. */ 102033965Sjdp case 'A': 102133965Sjdp if (! flag_m68k_mri || *input_line_pointer != '\'') 102233965Sjdp goto de_fault; 102333965Sjdp ++input_line_pointer; 102433965Sjdp /* Fall through. */ 102560484Sobrien#endif 102633965Sjdp case '\'': 102733965Sjdp if (! flag_m68k_mri) 102833965Sjdp { 102933965Sjdp /* Warning: to conform to other people's assemblers NO 103033965Sjdp ESCAPEMENT is permitted for a single quote. The next 103133965Sjdp character, parity errors and all, is taken as the value 103233965Sjdp of the operand. VERY KINKY. */ 103333965Sjdp expressionP->X_op = O_constant; 103433965Sjdp expressionP->X_add_number = *input_line_pointer++; 103533965Sjdp break; 103633965Sjdp } 103733965Sjdp 103833965Sjdp mri_char_constant (expressionP); 103933965Sjdp break; 104033965Sjdp 104133965Sjdp case '+': 104233965Sjdp (void) operand (expressionP); 104333965Sjdp break; 104433965Sjdp 104560484Sobrien#ifdef TC_M68K 104633965Sjdp case '"': 104733965Sjdp /* Double quote is the bitwise not operator in MRI mode. */ 104833965Sjdp if (! flag_m68k_mri) 104933965Sjdp goto de_fault; 105033965Sjdp /* Fall through. */ 105160484Sobrien#endif 105233965Sjdp case '~': 105333965Sjdp /* ~ is permitted to start a label on the Delta. */ 105433965Sjdp if (is_name_beginner (c)) 105533965Sjdp goto isname; 105633965Sjdp case '!': 105733965Sjdp case '-': 105833965Sjdp { 105933965Sjdp operand (expressionP); 106033965Sjdp if (expressionP->X_op == O_constant) 106133965Sjdp { 106233965Sjdp /* input_line_pointer -> char after operand */ 106333965Sjdp if (c == '-') 106433965Sjdp { 106533965Sjdp expressionP->X_add_number = - expressionP->X_add_number; 106633965Sjdp /* Notice: '-' may overflow: no warning is given. This is 106733965Sjdp compatible with other people's assemblers. Sigh. */ 106833965Sjdp expressionP->X_unsigned = 0; 106933965Sjdp } 107033965Sjdp else if (c == '~' || c == '"') 107133965Sjdp expressionP->X_add_number = ~ expressionP->X_add_number; 107233965Sjdp else 107333965Sjdp expressionP->X_add_number = ! expressionP->X_add_number; 107433965Sjdp } 107533965Sjdp else if (expressionP->X_op != O_illegal 107633965Sjdp && expressionP->X_op != O_absent) 107733965Sjdp { 107833965Sjdp expressionP->X_add_symbol = make_expr_symbol (expressionP); 107933965Sjdp if (c == '-') 108033965Sjdp expressionP->X_op = O_uminus; 108133965Sjdp else if (c == '~' || c == '"') 108233965Sjdp expressionP->X_op = O_bit_not; 108333965Sjdp else 108433965Sjdp expressionP->X_op = O_logical_not; 108533965Sjdp expressionP->X_add_number = 0; 108633965Sjdp } 108733965Sjdp else 108860484Sobrien as_warn (_("Unary operator %c ignored because bad operand follows"), 108933965Sjdp c); 109033965Sjdp } 109133965Sjdp break; 109233965Sjdp 109360484Sobrien#if defined (DOLLAR_DOT) || defined (TC_M68K) 109433965Sjdp case '$': 109533965Sjdp /* $ is the program counter when in MRI mode, or when DOLLAR_DOT 109633965Sjdp is defined. */ 109733965Sjdp#ifndef DOLLAR_DOT 109833965Sjdp if (! flag_m68k_mri) 109933965Sjdp goto de_fault; 110033965Sjdp#endif 110133965Sjdp if (flag_m68k_mri && hex_p (*input_line_pointer)) 110233965Sjdp { 110333965Sjdp /* In MRI mode, $ is also used as the prefix for a 110433965Sjdp hexadecimal constant. */ 110533965Sjdp integer_constant (16, expressionP); 110633965Sjdp break; 110733965Sjdp } 110833965Sjdp 110933965Sjdp if (is_part_of_name (*input_line_pointer)) 111033965Sjdp goto isname; 111133965Sjdp 111233965Sjdp current_location (expressionP); 111333965Sjdp break; 111460484Sobrien#endif 111533965Sjdp 111633965Sjdp case '.': 111733965Sjdp if (!is_part_of_name (*input_line_pointer)) 111833965Sjdp { 111933965Sjdp current_location (expressionP); 112033965Sjdp break; 112133965Sjdp } 112233965Sjdp else if ((strncasecmp (input_line_pointer, "startof.", 8) == 0 112333965Sjdp && ! is_part_of_name (input_line_pointer[8])) 112433965Sjdp || (strncasecmp (input_line_pointer, "sizeof.", 7) == 0 112533965Sjdp && ! is_part_of_name (input_line_pointer[7]))) 112633965Sjdp { 112733965Sjdp int start; 112833965Sjdp 112933965Sjdp start = (input_line_pointer[1] == 't' 113033965Sjdp || input_line_pointer[1] == 'T'); 113133965Sjdp input_line_pointer += start ? 8 : 7; 113233965Sjdp SKIP_WHITESPACE (); 113333965Sjdp if (*input_line_pointer != '(') 113460484Sobrien as_bad (_("syntax error in .startof. or .sizeof.")); 113533965Sjdp else 113633965Sjdp { 113733965Sjdp char *buf; 113833965Sjdp 113933965Sjdp ++input_line_pointer; 114033965Sjdp SKIP_WHITESPACE (); 114133965Sjdp name = input_line_pointer; 114233965Sjdp c = get_symbol_end (); 114333965Sjdp 114433965Sjdp buf = (char *) xmalloc (strlen (name) + 10); 114533965Sjdp if (start) 114633965Sjdp sprintf (buf, ".startof.%s", name); 114733965Sjdp else 114833965Sjdp sprintf (buf, ".sizeof.%s", name); 114933965Sjdp symbolP = symbol_make (buf); 115033965Sjdp free (buf); 115133965Sjdp 115233965Sjdp expressionP->X_op = O_symbol; 115333965Sjdp expressionP->X_add_symbol = symbolP; 115433965Sjdp expressionP->X_add_number = 0; 115533965Sjdp 115633965Sjdp *input_line_pointer = c; 115733965Sjdp SKIP_WHITESPACE (); 115833965Sjdp if (*input_line_pointer != ')') 115960484Sobrien as_bad (_("syntax error in .startof. or .sizeof.")); 116033965Sjdp else 116133965Sjdp ++input_line_pointer; 116233965Sjdp } 116333965Sjdp break; 116433965Sjdp } 116533965Sjdp else 116633965Sjdp { 116733965Sjdp goto isname; 116833965Sjdp } 116933965Sjdp case ',': 117033965Sjdp case '\n': 117133965Sjdp case '\0': 117233965Sjdp eol: 117333965Sjdp /* can't imagine any other kind of operand */ 117433965Sjdp expressionP->X_op = O_absent; 117533965Sjdp input_line_pointer--; 117633965Sjdp break; 117733965Sjdp 117860484Sobrien#ifdef TC_M68K 117933965Sjdp case '%': 118033965Sjdp if (! flag_m68k_mri) 118133965Sjdp goto de_fault; 118233965Sjdp integer_constant (2, expressionP); 118333965Sjdp break; 118433965Sjdp 118533965Sjdp case '@': 118633965Sjdp if (! flag_m68k_mri) 118733965Sjdp goto de_fault; 118833965Sjdp integer_constant (8, expressionP); 118933965Sjdp break; 119033965Sjdp 119133965Sjdp case ':': 119233965Sjdp if (! flag_m68k_mri) 119333965Sjdp goto de_fault; 119433965Sjdp 119533965Sjdp /* In MRI mode, this is a floating point constant represented 119633965Sjdp using hexadecimal digits. */ 119733965Sjdp 119833965Sjdp ++input_line_pointer; 119933965Sjdp integer_constant (16, expressionP); 120033965Sjdp break; 120133965Sjdp 120233965Sjdp case '*': 120333965Sjdp if (! flag_m68k_mri || is_part_of_name (*input_line_pointer)) 120433965Sjdp goto de_fault; 120533965Sjdp 120633965Sjdp current_location (expressionP); 120733965Sjdp break; 120860484Sobrien#endif 120933965Sjdp 121033965Sjdp default: 121160484Sobrien#ifdef TC_M68K 121233965Sjdp de_fault: 121360484Sobrien#endif 121433965Sjdp if (is_end_of_line[(unsigned char) c]) 121533965Sjdp goto eol; 121633965Sjdp if (is_name_beginner (c)) /* here if did not begin with a digit */ 121733965Sjdp { 121833965Sjdp /* 121933965Sjdp * Identifier begins here. 122033965Sjdp * This is kludged for speed, so code is repeated. 122133965Sjdp */ 122233965Sjdp isname: 122333965Sjdp name = --input_line_pointer; 122433965Sjdp c = get_symbol_end (); 122533965Sjdp 122633965Sjdp#ifdef md_parse_name 122733965Sjdp /* This is a hook for the backend to parse certain names 122833965Sjdp specially in certain contexts. If a name always has a 122933965Sjdp specific value, it can often be handled by simply 123033965Sjdp entering it in the symbol table. */ 123133965Sjdp if (md_parse_name (name, expressionP)) 123233965Sjdp { 123333965Sjdp *input_line_pointer = c; 123433965Sjdp break; 123533965Sjdp } 123633965Sjdp#endif 123733965Sjdp 123833965Sjdp#ifdef TC_I960 123933965Sjdp /* The MRI i960 assembler permits 124033965Sjdp lda sizeof code,g13 124133965Sjdp FIXME: This should use md_parse_name. */ 124233965Sjdp if (flag_mri 124333965Sjdp && (strcasecmp (name, "sizeof") == 0 124433965Sjdp || strcasecmp (name, "startof") == 0)) 124533965Sjdp { 124633965Sjdp int start; 124733965Sjdp char *buf; 124833965Sjdp 124933965Sjdp start = (name[1] == 't' 125033965Sjdp || name[1] == 'T'); 125133965Sjdp 125233965Sjdp *input_line_pointer = c; 125333965Sjdp SKIP_WHITESPACE (); 125433965Sjdp 125533965Sjdp name = input_line_pointer; 125633965Sjdp c = get_symbol_end (); 125733965Sjdp 125833965Sjdp buf = (char *) xmalloc (strlen (name) + 10); 125933965Sjdp if (start) 126033965Sjdp sprintf (buf, ".startof.%s", name); 126133965Sjdp else 126233965Sjdp sprintf (buf, ".sizeof.%s", name); 126333965Sjdp symbolP = symbol_make (buf); 126433965Sjdp free (buf); 126533965Sjdp 126633965Sjdp expressionP->X_op = O_symbol; 126733965Sjdp expressionP->X_add_symbol = symbolP; 126833965Sjdp expressionP->X_add_number = 0; 126933965Sjdp 127033965Sjdp *input_line_pointer = c; 127133965Sjdp SKIP_WHITESPACE (); 127233965Sjdp 127333965Sjdp break; 127433965Sjdp } 127533965Sjdp#endif 127633965Sjdp 127733965Sjdp symbolP = symbol_find_or_make (name); 127833965Sjdp 127933965Sjdp /* If we have an absolute symbol or a reg, then we know its 128033965Sjdp value now. */ 128133965Sjdp segment = S_GET_SEGMENT (symbolP); 128233965Sjdp if (segment == absolute_section) 128333965Sjdp { 128433965Sjdp expressionP->X_op = O_constant; 128533965Sjdp expressionP->X_add_number = S_GET_VALUE (symbolP); 128633965Sjdp } 128733965Sjdp else if (segment == reg_section) 128833965Sjdp { 128933965Sjdp expressionP->X_op = O_register; 129033965Sjdp expressionP->X_add_number = S_GET_VALUE (symbolP); 129133965Sjdp } 129233965Sjdp else 129333965Sjdp { 129433965Sjdp expressionP->X_op = O_symbol; 129533965Sjdp expressionP->X_add_symbol = symbolP; 129633965Sjdp expressionP->X_add_number = 0; 129733965Sjdp } 129833965Sjdp *input_line_pointer = c; 129933965Sjdp } 130033965Sjdp else 130133965Sjdp { 130233965Sjdp /* Let the target try to parse it. Success is indicated by changing 130333965Sjdp the X_op field to something other than O_absent and pointing 130433965Sjdp input_line_pointer passed the expression. If it can't parse the 130533965Sjdp expression, X_op and input_line_pointer should be unchanged. */ 130633965Sjdp expressionP->X_op = O_absent; 130733965Sjdp --input_line_pointer; 130833965Sjdp md_operand (expressionP); 130933965Sjdp if (expressionP->X_op == O_absent) 131033965Sjdp { 131133965Sjdp ++input_line_pointer; 131260484Sobrien as_bad (_("Bad expression")); 131333965Sjdp expressionP->X_op = O_constant; 131433965Sjdp expressionP->X_add_number = 0; 131533965Sjdp } 131633965Sjdp } 131733965Sjdp break; 131833965Sjdp } 131933965Sjdp 132033965Sjdp /* 132133965Sjdp * It is more 'efficient' to clean up the expressionS when they are created. 132233965Sjdp * Doing it here saves lines of code. 132333965Sjdp */ 132433965Sjdp clean_up_expression (expressionP); 132533965Sjdp SKIP_WHITESPACE (); /*->1st char after operand. */ 132633965Sjdp know (*input_line_pointer != ' '); 132733965Sjdp 132833965Sjdp /* The PA port needs this information. */ 132933965Sjdp if (expressionP->X_add_symbol) 133060484Sobrien symbol_mark_used (expressionP->X_add_symbol); 133133965Sjdp 133233965Sjdp switch (expressionP->X_op) 133333965Sjdp { 133433965Sjdp default: 133533965Sjdp return absolute_section; 133633965Sjdp case O_symbol: 133733965Sjdp return S_GET_SEGMENT (expressionP->X_add_symbol); 133833965Sjdp case O_register: 133933965Sjdp return reg_section; 134033965Sjdp } 134133965Sjdp} /* operand() */ 134233965Sjdp 134333965Sjdp/* Internal. Simplify a struct expression for use by expr() */ 134433965Sjdp 134533965Sjdp/* 134633965Sjdp * In: address of a expressionS. 134733965Sjdp * The X_op field of the expressionS may only take certain values. 134833965Sjdp * Elsewise we waste time special-case testing. Sigh. Ditto SEG_ABSENT. 134933965Sjdp * Out: expressionS may have been modified: 135033965Sjdp * 'foo-foo' symbol references cancelled to 0, 135133965Sjdp * which changes X_op from O_subtract to O_constant. 135233965Sjdp * Unused fields zeroed to help expr(). 135333965Sjdp */ 135433965Sjdp 135533965Sjdpstatic void 135633965Sjdpclean_up_expression (expressionP) 135733965Sjdp expressionS *expressionP; 135833965Sjdp{ 135933965Sjdp switch (expressionP->X_op) 136033965Sjdp { 136133965Sjdp case O_illegal: 136233965Sjdp case O_absent: 136333965Sjdp expressionP->X_add_number = 0; 136433965Sjdp /* Fall through. */ 136533965Sjdp case O_big: 136633965Sjdp case O_constant: 136733965Sjdp case O_register: 136833965Sjdp expressionP->X_add_symbol = NULL; 136933965Sjdp /* Fall through. */ 137033965Sjdp case O_symbol: 137133965Sjdp case O_uminus: 137233965Sjdp case O_bit_not: 137333965Sjdp expressionP->X_op_symbol = NULL; 137433965Sjdp break; 137533965Sjdp case O_subtract: 137633965Sjdp if (expressionP->X_op_symbol == expressionP->X_add_symbol 137760484Sobrien || ((symbol_get_frag (expressionP->X_op_symbol) 137860484Sobrien == symbol_get_frag (expressionP->X_add_symbol)) 137933965Sjdp && SEG_NORMAL (S_GET_SEGMENT (expressionP->X_add_symbol)) 138033965Sjdp && (S_GET_VALUE (expressionP->X_op_symbol) 138133965Sjdp == S_GET_VALUE (expressionP->X_add_symbol)))) 138233965Sjdp { 138333965Sjdp addressT diff = (S_GET_VALUE (expressionP->X_add_symbol) 138433965Sjdp - S_GET_VALUE (expressionP->X_op_symbol)); 138533965Sjdp 138633965Sjdp expressionP->X_op = O_constant; 138733965Sjdp expressionP->X_add_symbol = NULL; 138833965Sjdp expressionP->X_op_symbol = NULL; 138933965Sjdp expressionP->X_add_number += diff; 139033965Sjdp } 139133965Sjdp break; 139233965Sjdp default: 139333965Sjdp break; 139433965Sjdp } 139533965Sjdp} 139633965Sjdp 139733965Sjdp/* Expression parser. */ 139833965Sjdp 139933965Sjdp/* 140033965Sjdp * We allow an empty expression, and just assume (absolute,0) silently. 140133965Sjdp * Unary operators and parenthetical expressions are treated as operands. 140233965Sjdp * As usual, Q==quantity==operand, O==operator, X==expression mnemonics. 140333965Sjdp * 140433965Sjdp * We used to do a aho/ullman shift-reduce parser, but the logic got so 140533965Sjdp * warped that I flushed it and wrote a recursive-descent parser instead. 140633965Sjdp * Now things are stable, would anybody like to write a fast parser? 140733965Sjdp * Most expressions are either register (which does not even reach here) 140833965Sjdp * or 1 symbol. Then "symbol+constant" and "symbol-symbol" are common. 140933965Sjdp * So I guess it doesn't really matter how inefficient more complex expressions 141033965Sjdp * are parsed. 141133965Sjdp * 141233965Sjdp * After expr(RANK,resultP) input_line_pointer->operator of rank <= RANK. 141333965Sjdp * Also, we have consumed any leading or trailing spaces (operand does that) 141433965Sjdp * and done all intervening operators. 141533965Sjdp * 141633965Sjdp * This returns the segment of the result, which will be 141733965Sjdp * absolute_section or the segment of a symbol. 141833965Sjdp */ 141933965Sjdp 142033965Sjdp#undef __ 142133965Sjdp#define __ O_illegal 142233965Sjdp 142360484Sobrienstatic const operatorT op_encoding[256] = 142433965Sjdp{ /* maps ASCII->operators */ 142533965Sjdp 142633965Sjdp __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, 142733965Sjdp __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, 142833965Sjdp 142933965Sjdp __, O_bit_or_not, __, __, __, O_modulus, O_bit_and, __, 143033965Sjdp __, __, O_multiply, O_add, __, O_subtract, __, O_divide, 143133965Sjdp __, __, __, __, __, __, __, __, 143233965Sjdp __, __, __, __, O_lt, __, O_gt, __, 143333965Sjdp __, __, __, __, __, __, __, __, 143433965Sjdp __, __, __, __, __, __, __, __, 143533965Sjdp __, __, __, __, __, __, __, __, 143660484Sobrien __, __, __, 143760484Sobrien#ifdef NEED_INDEX_OPERATOR 143860484Sobrien O_index, 143960484Sobrien#else 144060484Sobrien __, 144160484Sobrien#endif 144260484Sobrien __, __, O_bit_exclusive_or, __, 144333965Sjdp __, __, __, __, __, __, __, __, 144433965Sjdp __, __, __, __, __, __, __, __, 144533965Sjdp __, __, __, __, __, __, __, __, 144633965Sjdp __, __, __, __, O_bit_inclusive_or, __, __, __, 144733965Sjdp 144833965Sjdp __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, 144933965Sjdp __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, 145033965Sjdp __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, 145133965Sjdp __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, 145233965Sjdp __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, 145333965Sjdp __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, 145433965Sjdp __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, 145533965Sjdp __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __ 145633965Sjdp}; 145733965Sjdp 145833965Sjdp 145933965Sjdp/* 146033965Sjdp * Rank Examples 146133965Sjdp * 0 operand, (expression) 146233965Sjdp * 1 || 146333965Sjdp * 2 && 146433965Sjdp * 3 = <> < <= >= > 146533965Sjdp * 4 + - 146633965Sjdp * 5 used for * / % in MRI mode 146733965Sjdp * 6 & ^ ! | 146833965Sjdp * 7 * / % << >> 146933965Sjdp * 8 unary - unary ~ 147033965Sjdp */ 147133965Sjdpstatic operator_rankT op_rank[] = 147233965Sjdp{ 147333965Sjdp 0, /* O_illegal */ 147433965Sjdp 0, /* O_absent */ 147533965Sjdp 0, /* O_constant */ 147633965Sjdp 0, /* O_symbol */ 147733965Sjdp 0, /* O_symbol_rva */ 147833965Sjdp 0, /* O_register */ 147933965Sjdp 0, /* O_bit */ 148060484Sobrien 9, /* O_uminus */ 148160484Sobrien 9, /* O_bit_not */ 148260484Sobrien 9, /* O_logical_not */ 148360484Sobrien 8, /* O_multiply */ 148460484Sobrien 8, /* O_divide */ 148560484Sobrien 8, /* O_modulus */ 148660484Sobrien 8, /* O_left_shift */ 148760484Sobrien 8, /* O_right_shift */ 148860484Sobrien 7, /* O_bit_inclusive_or */ 148960484Sobrien 7, /* O_bit_or_not */ 149060484Sobrien 7, /* O_bit_exclusive_or */ 149160484Sobrien 7, /* O_bit_and */ 149260484Sobrien 5, /* O_add */ 149360484Sobrien 5, /* O_subtract */ 149460484Sobrien 4, /* O_eq */ 149560484Sobrien 4, /* O_ne */ 149660484Sobrien 4, /* O_lt */ 149760484Sobrien 4, /* O_le */ 149860484Sobrien 4, /* O_ge */ 149960484Sobrien 4, /* O_gt */ 150060484Sobrien 3, /* O_logical_and */ 150160484Sobrien 2, /* O_logical_or */ 150260484Sobrien 1, /* O_index */ 150360484Sobrien 0, /* O_md1 */ 150460484Sobrien 0, /* O_md2 */ 150560484Sobrien 0, /* O_md3 */ 150660484Sobrien 0, /* O_md4 */ 150760484Sobrien 0, /* O_md5 */ 150860484Sobrien 0, /* O_md6 */ 150960484Sobrien 0, /* O_md7 */ 151060484Sobrien 0, /* O_md8 */ 151160484Sobrien 0, /* O_md9 */ 151260484Sobrien 0, /* O_md10 */ 151360484Sobrien 0, /* O_md11 */ 151460484Sobrien 0, /* O_md12 */ 151560484Sobrien 0, /* O_md13 */ 151660484Sobrien 0, /* O_md14 */ 151760484Sobrien 0, /* O_md15 */ 151860484Sobrien 0, /* O_md16 */ 151933965Sjdp}; 152033965Sjdp 152160484Sobrien/* Unfortunately, in MRI mode for the m68k, multiplication and 152260484Sobrien division have lower precedence than the bit wise operators. This 152360484Sobrien function sets the operator precedences correctly for the current 152460484Sobrien mode. Also, MRI uses a different bit_not operator, and this fixes 152560484Sobrien that as well. */ 152633965Sjdp 152760484Sobrien#define STANDARD_MUL_PRECEDENCE (7) 152860484Sobrien#define MRI_MUL_PRECEDENCE (5) 152960484Sobrien 153033965Sjdpvoid 153160484Sobrienexpr_set_precedence () 153233965Sjdp{ 153333965Sjdp if (flag_m68k_mri) 153433965Sjdp { 153560484Sobrien op_rank[O_multiply] = MRI_MUL_PRECEDENCE; 153660484Sobrien op_rank[O_divide] = MRI_MUL_PRECEDENCE; 153760484Sobrien op_rank[O_modulus] = MRI_MUL_PRECEDENCE; 153833965Sjdp } 153960484Sobrien else 154060484Sobrien { 154160484Sobrien op_rank[O_multiply] = STANDARD_MUL_PRECEDENCE; 154260484Sobrien op_rank[O_divide] = STANDARD_MUL_PRECEDENCE; 154360484Sobrien op_rank[O_modulus] = STANDARD_MUL_PRECEDENCE; 154460484Sobrien } 154560484Sobrien} 154633965Sjdp 154760484Sobrien/* Initialize the expression parser. */ 154860484Sobrien 154960484Sobrienvoid 155060484Sobrienexpr_begin () 155160484Sobrien{ 155260484Sobrien expr_set_precedence (); 155360484Sobrien 155433965Sjdp /* Verify that X_op field is wide enough. */ 155533965Sjdp { 155633965Sjdp expressionS e; 155733965Sjdp e.X_op = O_max; 155833965Sjdp assert (e.X_op == O_max); 155933965Sjdp } 156033965Sjdp} 156133965Sjdp 156233965Sjdp/* Return the encoding for the operator at INPUT_LINE_POINTER. 156333965Sjdp Advance INPUT_LINE_POINTER to the last character in the operator 156433965Sjdp (i.e., don't change it for a single character operator). */ 156533965Sjdp 156633965Sjdpstatic inline operatorT 156733965Sjdpoperator () 156833965Sjdp{ 156933965Sjdp int c; 157033965Sjdp operatorT ret; 157133965Sjdp 157260484Sobrien c = *input_line_pointer & 0xff; 157333965Sjdp 157433965Sjdp switch (c) 157533965Sjdp { 157633965Sjdp default: 157733965Sjdp return op_encoding[c]; 157833965Sjdp 157933965Sjdp case '<': 158033965Sjdp switch (input_line_pointer[1]) 158133965Sjdp { 158233965Sjdp default: 158333965Sjdp return op_encoding[c]; 158433965Sjdp case '<': 158533965Sjdp ret = O_left_shift; 158633965Sjdp break; 158733965Sjdp case '>': 158833965Sjdp ret = O_ne; 158933965Sjdp break; 159033965Sjdp case '=': 159133965Sjdp ret = O_le; 159233965Sjdp break; 159333965Sjdp } 159433965Sjdp ++input_line_pointer; 159533965Sjdp return ret; 159633965Sjdp 159738889Sjdp case '=': 159838889Sjdp if (input_line_pointer[1] != '=') 159938889Sjdp return op_encoding[c]; 160038889Sjdp 160138889Sjdp ++input_line_pointer; 160238889Sjdp return O_eq; 160338889Sjdp 160433965Sjdp case '>': 160533965Sjdp switch (input_line_pointer[1]) 160633965Sjdp { 160733965Sjdp default: 160833965Sjdp return op_encoding[c]; 160933965Sjdp case '>': 161033965Sjdp ret = O_right_shift; 161133965Sjdp break; 161233965Sjdp case '=': 161333965Sjdp ret = O_ge; 161433965Sjdp break; 161533965Sjdp } 161633965Sjdp ++input_line_pointer; 161733965Sjdp return ret; 161833965Sjdp 161933965Sjdp case '!': 162033965Sjdp /* We accept !! as equivalent to ^ for MRI compatibility. */ 162133965Sjdp if (input_line_pointer[1] != '!') 162233965Sjdp { 162333965Sjdp if (flag_m68k_mri) 162433965Sjdp return O_bit_inclusive_or; 162533965Sjdp return op_encoding[c]; 162633965Sjdp } 162733965Sjdp ++input_line_pointer; 162833965Sjdp return O_bit_exclusive_or; 162933965Sjdp 163033965Sjdp case '|': 163133965Sjdp if (input_line_pointer[1] != '|') 163233965Sjdp return op_encoding[c]; 163333965Sjdp 163433965Sjdp ++input_line_pointer; 163533965Sjdp return O_logical_or; 163633965Sjdp 163733965Sjdp case '&': 163833965Sjdp if (input_line_pointer[1] != '&') 163933965Sjdp return op_encoding[c]; 164033965Sjdp 164133965Sjdp ++input_line_pointer; 164233965Sjdp return O_logical_and; 164333965Sjdp } 164433965Sjdp 164533965Sjdp /*NOTREACHED*/ 164638889Sjdp} 164733965Sjdp 164833965Sjdp/* Parse an expression. */ 164933965Sjdp 165033965SjdpsegT 165160484Sobrienexpr (rankarg, resultP) 165260484Sobrien int rankarg; /* Larger # is higher rank. */ 165333965Sjdp expressionS *resultP; /* Deliver result here. */ 165433965Sjdp{ 165560484Sobrien operator_rankT rank = (operator_rankT) rankarg; 165633965Sjdp segT retval; 165733965Sjdp expressionS right; 165833965Sjdp operatorT op_left; 165933965Sjdp operatorT op_right; 166033965Sjdp 166133965Sjdp know (rank >= 0); 166233965Sjdp 166333965Sjdp retval = operand (resultP); 166433965Sjdp 166533965Sjdp know (*input_line_pointer != ' '); /* Operand() gobbles spaces. */ 166633965Sjdp 166733965Sjdp op_left = operator (); 166833965Sjdp while (op_left != O_illegal && op_rank[(int) op_left] > rank) 166933965Sjdp { 167033965Sjdp segT rightseg; 167133965Sjdp 167233965Sjdp input_line_pointer++; /*->after 1st character of operator. */ 167333965Sjdp 167433965Sjdp rightseg = expr (op_rank[(int) op_left], &right); 167533965Sjdp if (right.X_op == O_absent) 167633965Sjdp { 167760484Sobrien as_warn (_("missing operand; zero assumed")); 167833965Sjdp right.X_op = O_constant; 167933965Sjdp right.X_add_number = 0; 168033965Sjdp right.X_add_symbol = NULL; 168133965Sjdp right.X_op_symbol = NULL; 168233965Sjdp } 168333965Sjdp 168433965Sjdp know (*input_line_pointer != ' '); 168533965Sjdp 168660484Sobrien if (op_left == O_index) 168760484Sobrien { 168860484Sobrien if (*input_line_pointer != ']') 168960484Sobrien as_bad ("missing right bracket"); 169060484Sobrien else 169160484Sobrien { 169260484Sobrien ++input_line_pointer; 169360484Sobrien SKIP_WHITESPACE (); 169460484Sobrien } 169560484Sobrien } 169660484Sobrien 169733965Sjdp if (retval == undefined_section) 169833965Sjdp { 169933965Sjdp if (SEG_NORMAL (rightseg)) 170033965Sjdp retval = rightseg; 170133965Sjdp } 170233965Sjdp else if (! SEG_NORMAL (retval)) 170333965Sjdp retval = rightseg; 170433965Sjdp else if (SEG_NORMAL (rightseg) 170533965Sjdp && retval != rightseg 170633965Sjdp#ifdef DIFF_EXPR_OK 170733965Sjdp && op_left != O_subtract 170833965Sjdp#endif 170933965Sjdp ) 171060484Sobrien as_bad (_("operation combines symbols in different segments")); 171133965Sjdp 171233965Sjdp op_right = operator (); 171333965Sjdp 171433965Sjdp know (op_right == O_illegal || op_rank[(int) op_right] <= op_rank[(int) op_left]); 171533965Sjdp know ((int) op_left >= (int) O_multiply 171633965Sjdp && (int) op_left <= (int) O_logical_or); 171733965Sjdp 171833965Sjdp /* input_line_pointer->after right-hand quantity. */ 171933965Sjdp /* left-hand quantity in resultP */ 172033965Sjdp /* right-hand quantity in right. */ 172133965Sjdp /* operator in op_left. */ 172233965Sjdp 172333965Sjdp if (resultP->X_op == O_big) 172433965Sjdp { 172560484Sobrien if (resultP->X_add_number > 0) 172660484Sobrien as_warn (_("left operand is a bignum; integer 0 assumed")); 172760484Sobrien else 172860484Sobrien as_warn (_("left operand is a float; integer 0 assumed")); 172933965Sjdp resultP->X_op = O_constant; 173033965Sjdp resultP->X_add_number = 0; 173133965Sjdp resultP->X_add_symbol = NULL; 173233965Sjdp resultP->X_op_symbol = NULL; 173333965Sjdp } 173433965Sjdp if (right.X_op == O_big) 173533965Sjdp { 173660484Sobrien if (right.X_add_number > 0) 173760484Sobrien as_warn (_("right operand is a bignum; integer 0 assumed")); 173860484Sobrien else 173960484Sobrien as_warn (_("right operand is a float; integer 0 assumed")); 174033965Sjdp right.X_op = O_constant; 174133965Sjdp right.X_add_number = 0; 174233965Sjdp right.X_add_symbol = NULL; 174333965Sjdp right.X_op_symbol = NULL; 174433965Sjdp } 174533965Sjdp 174633965Sjdp /* Optimize common cases. */ 174733965Sjdp if (op_left == O_add && right.X_op == O_constant) 174833965Sjdp { 174933965Sjdp /* X + constant. */ 175033965Sjdp resultP->X_add_number += right.X_add_number; 175133965Sjdp } 175233965Sjdp /* This case comes up in PIC code. */ 175333965Sjdp else if (op_left == O_subtract 175433965Sjdp && right.X_op == O_symbol 175533965Sjdp && resultP->X_op == O_symbol 175660484Sobrien && (symbol_get_frag (right.X_add_symbol) 175760484Sobrien == symbol_get_frag (resultP->X_add_symbol)) 175833965Sjdp && SEG_NORMAL (S_GET_SEGMENT (right.X_add_symbol))) 175933965Sjdp 176033965Sjdp { 176133965Sjdp resultP->X_add_number -= right.X_add_number; 176233965Sjdp resultP->X_add_number += (S_GET_VALUE (resultP->X_add_symbol) 176333965Sjdp - S_GET_VALUE (right.X_add_symbol)); 176433965Sjdp resultP->X_op = O_constant; 176533965Sjdp resultP->X_add_symbol = 0; 176633965Sjdp } 176733965Sjdp else if (op_left == O_subtract && right.X_op == O_constant) 176833965Sjdp { 176933965Sjdp /* X - constant. */ 177033965Sjdp resultP->X_add_number -= right.X_add_number; 177133965Sjdp } 177233965Sjdp else if (op_left == O_add && resultP->X_op == O_constant) 177333965Sjdp { 177433965Sjdp /* Constant + X. */ 177533965Sjdp resultP->X_op = right.X_op; 177633965Sjdp resultP->X_add_symbol = right.X_add_symbol; 177733965Sjdp resultP->X_op_symbol = right.X_op_symbol; 177833965Sjdp resultP->X_add_number += right.X_add_number; 177933965Sjdp retval = rightseg; 178033965Sjdp } 178133965Sjdp else if (resultP->X_op == O_constant && right.X_op == O_constant) 178233965Sjdp { 178333965Sjdp /* Constant OP constant. */ 178433965Sjdp offsetT v = right.X_add_number; 178533965Sjdp if (v == 0 && (op_left == O_divide || op_left == O_modulus)) 178633965Sjdp { 178760484Sobrien as_warn (_("division by zero")); 178833965Sjdp v = 1; 178933965Sjdp } 179033965Sjdp switch (op_left) 179133965Sjdp { 179233965Sjdp default: abort (); 179333965Sjdp case O_multiply: resultP->X_add_number *= v; break; 179433965Sjdp case O_divide: resultP->X_add_number /= v; break; 179533965Sjdp case O_modulus: resultP->X_add_number %= v; break; 179633965Sjdp case O_left_shift: resultP->X_add_number <<= v; break; 179733965Sjdp case O_right_shift: 179833965Sjdp /* We always use unsigned shifts, to avoid relying on 179933965Sjdp characteristics of the compiler used to compile gas. */ 180033965Sjdp resultP->X_add_number = 180133965Sjdp (offsetT) ((valueT) resultP->X_add_number >> (valueT) v); 180233965Sjdp break; 180333965Sjdp case O_bit_inclusive_or: resultP->X_add_number |= v; break; 180433965Sjdp case O_bit_or_not: resultP->X_add_number |= ~v; break; 180533965Sjdp case O_bit_exclusive_or: resultP->X_add_number ^= v; break; 180633965Sjdp case O_bit_and: resultP->X_add_number &= v; break; 180733965Sjdp case O_add: resultP->X_add_number += v; break; 180833965Sjdp case O_subtract: resultP->X_add_number -= v; break; 180933965Sjdp case O_eq: 181033965Sjdp resultP->X_add_number = 181133965Sjdp resultP->X_add_number == v ? ~ (offsetT) 0 : 0; 181233965Sjdp break; 181333965Sjdp case O_ne: 181433965Sjdp resultP->X_add_number = 181533965Sjdp resultP->X_add_number != v ? ~ (offsetT) 0 : 0; 181633965Sjdp break; 181733965Sjdp case O_lt: 181833965Sjdp resultP->X_add_number = 181933965Sjdp resultP->X_add_number < v ? ~ (offsetT) 0 : 0; 182033965Sjdp break; 182133965Sjdp case O_le: 182233965Sjdp resultP->X_add_number = 182333965Sjdp resultP->X_add_number <= v ? ~ (offsetT) 0 : 0; 182433965Sjdp break; 182533965Sjdp case O_ge: 182633965Sjdp resultP->X_add_number = 182733965Sjdp resultP->X_add_number >= v ? ~ (offsetT) 0 : 0; 182833965Sjdp break; 182933965Sjdp case O_gt: 183033965Sjdp resultP->X_add_number = 183133965Sjdp resultP->X_add_number > v ? ~ (offsetT) 0 : 0; 183233965Sjdp break; 183333965Sjdp case O_logical_and: 183433965Sjdp resultP->X_add_number = resultP->X_add_number && v; 183533965Sjdp break; 183633965Sjdp case O_logical_or: 183733965Sjdp resultP->X_add_number = resultP->X_add_number || v; 183833965Sjdp break; 183933965Sjdp } 184033965Sjdp } 184133965Sjdp else if (resultP->X_op == O_symbol 184233965Sjdp && right.X_op == O_symbol 184333965Sjdp && (op_left == O_add 184433965Sjdp || op_left == O_subtract 184533965Sjdp || (resultP->X_add_number == 0 184633965Sjdp && right.X_add_number == 0))) 184733965Sjdp { 184833965Sjdp /* Symbol OP symbol. */ 184933965Sjdp resultP->X_op = op_left; 185033965Sjdp resultP->X_op_symbol = right.X_add_symbol; 185133965Sjdp if (op_left == O_add) 185233965Sjdp resultP->X_add_number += right.X_add_number; 185333965Sjdp else if (op_left == O_subtract) 185433965Sjdp resultP->X_add_number -= right.X_add_number; 185533965Sjdp } 185633965Sjdp else 185733965Sjdp { 185833965Sjdp /* The general case. */ 185933965Sjdp resultP->X_add_symbol = make_expr_symbol (resultP); 186033965Sjdp resultP->X_op_symbol = make_expr_symbol (&right); 186133965Sjdp resultP->X_op = op_left; 186233965Sjdp resultP->X_add_number = 0; 186333965Sjdp resultP->X_unsigned = 1; 186433965Sjdp } 186533965Sjdp 186633965Sjdp op_left = op_right; 186733965Sjdp } /* While next operator is >= this rank. */ 186833965Sjdp 186933965Sjdp /* The PA port needs this information. */ 187033965Sjdp if (resultP->X_add_symbol) 187160484Sobrien symbol_mark_used (resultP->X_add_symbol); 187233965Sjdp 187333965Sjdp return resultP->X_op == O_constant ? absolute_section : retval; 187433965Sjdp} 187533965Sjdp 187633965Sjdp/* 187733965Sjdp * get_symbol_end() 187833965Sjdp * 187933965Sjdp * This lives here because it belongs equally in expr.c & read.c. 188033965Sjdp * Expr.c is just a branch office read.c anyway, and putting it 188133965Sjdp * here lessens the crowd at read.c. 188233965Sjdp * 188333965Sjdp * Assume input_line_pointer is at start of symbol name. 188433965Sjdp * Advance input_line_pointer past symbol name. 188533965Sjdp * Turn that character into a '\0', returning its former value. 188633965Sjdp * This allows a string compare (RMS wants symbol names to be strings) 188733965Sjdp * of the symbol name. 188833965Sjdp * There will always be a char following symbol name, because all good 188933965Sjdp * lines end in end-of-line. 189033965Sjdp */ 189133965Sjdpchar 189233965Sjdpget_symbol_end () 189333965Sjdp{ 189433965Sjdp char c; 189533965Sjdp 189633965Sjdp /* We accept \001 in a name in case this is being called with a 189733965Sjdp constructed string. */ 189833965Sjdp if (is_name_beginner (c = *input_line_pointer++) || c == '\001') 189960484Sobrien { 190060484Sobrien while (is_part_of_name (c = *input_line_pointer++) 190160484Sobrien || c == '\001') 190260484Sobrien ; 190360484Sobrien if (is_name_ender (c)) 190460484Sobrien c = *input_line_pointer++; 190560484Sobrien } 190633965Sjdp *--input_line_pointer = 0; 190733965Sjdp return (c); 190833965Sjdp} 190933965Sjdp 191033965Sjdp 191133965Sjdpunsigned int 191233965Sjdpget_single_number () 191333965Sjdp{ 191433965Sjdp expressionS exp; 191533965Sjdp operand (&exp); 191633965Sjdp return exp.X_add_number; 191733965Sjdp 191833965Sjdp} 191933965Sjdp 192033965Sjdp/* end of expr.c */ 1921