expr.c revision 130561
133965Sjdp/* expr.c -operands, expressions- 278828Sobrien Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 3130561Sobrien 1999, 2000, 2001, 2002 433965Sjdp Free Software Foundation, Inc. 533965Sjdp 633965Sjdp This file is part of GAS, the GNU Assembler. 733965Sjdp 833965Sjdp GAS is free software; you can redistribute it and/or modify 933965Sjdp it under the terms of the GNU General Public License as published by 1033965Sjdp the Free Software Foundation; either version 2, or (at your option) 1133965Sjdp any later version. 1233965Sjdp 1333965Sjdp GAS is distributed in the hope that it will be useful, 1433965Sjdp but WITHOUT ANY WARRANTY; without even the implied warranty of 1533965Sjdp MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1633965Sjdp GNU General Public License for more details. 1733965Sjdp 1833965Sjdp You should have received a copy of the GNU General Public License 1933965Sjdp along with GAS; see the file COPYING. If not, write to the Free 2033965Sjdp Software Foundation, 59 Temple Place - Suite 330, Boston, MA 2177298Sobrien 02111-1307, USA. */ 2233965Sjdp 2377298Sobrien/* This is really a branch office of as-read.c. I split it out to clearly 2477298Sobrien distinguish the world of expressions from the world of statements. 2577298Sobrien (It also gives smaller files to re-compile.) 2677298Sobrien Here, "operand"s are of expressions, not instructions. */ 2733965Sjdp 2833965Sjdp#include <string.h> 2938889Sjdp#define min(a, b) ((a) < (b) ? (a) : (b)) 3033965Sjdp 3133965Sjdp#include "as.h" 3289857Sobrien#include "safe-ctype.h" 3333965Sjdp#include "obstack.h" 3433965Sjdp 35130561Sobrienstatic void floating_constant (expressionS * expressionP); 36130561Sobrienstatic valueT generic_bignum_to_int32 (void); 3760484Sobrien#ifdef BFD64 38130561Sobrienstatic valueT generic_bignum_to_int64 (void); 3960484Sobrien#endif 40130561Sobrienstatic void integer_constant (int radix, expressionS * expressionP); 41130561Sobrienstatic void mri_char_constant (expressionS *); 42130561Sobrienstatic void current_location (expressionS *); 43130561Sobrienstatic void clean_up_expression (expressionS * expressionP); 44130561Sobrienstatic segT operand (expressionS *); 45130561Sobrienstatic operatorT operator (int *); 4633965Sjdp 4733965Sjdpextern const char EXP_CHARS[], FLT_CHARS[]; 4833965Sjdp 4933965Sjdp/* We keep a mapping of expression symbols to file positions, so that 5033965Sjdp we can provide better error messages. */ 5133965Sjdp 5277298Sobrienstruct expr_symbol_line { 5333965Sjdp struct expr_symbol_line *next; 5433965Sjdp symbolS *sym; 5533965Sjdp char *file; 5633965Sjdp unsigned int line; 5733965Sjdp}; 5833965Sjdp 5933965Sjdpstatic struct expr_symbol_line *expr_symbol_lines; 6033965Sjdp 6133965Sjdp/* Build a dummy symbol to hold a complex expression. This is how we 6233965Sjdp build expressions up out of other expressions. The symbol is put 6333965Sjdp into the fake section expr_section. */ 6433965Sjdp 6533965SjdpsymbolS * 66130561Sobrienmake_expr_symbol (expressionS *expressionP) 6733965Sjdp{ 6860484Sobrien expressionS zero; 6933965Sjdp symbolS *symbolP; 7033965Sjdp struct expr_symbol_line *n; 7133965Sjdp 7233965Sjdp if (expressionP->X_op == O_symbol 7333965Sjdp && expressionP->X_add_number == 0) 7433965Sjdp return expressionP->X_add_symbol; 7533965Sjdp 7660484Sobrien if (expressionP->X_op == O_big) 7760484Sobrien { 7860484Sobrien /* This won't work, because the actual value is stored in 79130561Sobrien generic_floating_point_number or generic_bignum, and we are 80130561Sobrien going to lose it if we haven't already. */ 8160484Sobrien if (expressionP->X_add_number > 0) 8289857Sobrien as_bad (_("bignum invalid")); 8360484Sobrien else 8489857Sobrien as_bad (_("floating point number invalid")); 8560484Sobrien zero.X_op = O_constant; 8660484Sobrien zero.X_add_number = 0; 8760484Sobrien zero.X_unsigned = 0; 8860484Sobrien clean_up_expression (&zero); 8960484Sobrien expressionP = &zero; 9060484Sobrien } 9160484Sobrien 9233965Sjdp /* Putting constant symbols in absolute_section rather than 9333965Sjdp expr_section is convenient for the old a.out code, for which 9433965Sjdp S_GET_SEGMENT does not always retrieve the value put in by 9533965Sjdp S_SET_SEGMENT. */ 96130561Sobrien symbolP = symbol_create (FAKE_LABEL_NAME, 9733965Sjdp (expressionP->X_op == O_constant 9833965Sjdp ? absolute_section 9933965Sjdp : expr_section), 10033965Sjdp 0, &zero_address_frag); 10160484Sobrien symbol_set_value_expression (symbolP, expressionP); 10233965Sjdp 10333965Sjdp if (expressionP->X_op == O_constant) 10489857Sobrien resolve_symbol_value (symbolP); 10533965Sjdp 10633965Sjdp n = (struct expr_symbol_line *) xmalloc (sizeof *n); 10733965Sjdp n->sym = symbolP; 10833965Sjdp as_where (&n->file, &n->line); 10933965Sjdp n->next = expr_symbol_lines; 11033965Sjdp expr_symbol_lines = n; 11133965Sjdp 11233965Sjdp return symbolP; 11333965Sjdp} 11433965Sjdp 11533965Sjdp/* Return the file and line number for an expr symbol. Return 11633965Sjdp non-zero if something was found, 0 if no information is known for 11733965Sjdp the symbol. */ 11833965Sjdp 11933965Sjdpint 120130561Sobrienexpr_symbol_where (symbolS *sym, char **pfile, unsigned int *pline) 12133965Sjdp{ 12233965Sjdp register struct expr_symbol_line *l; 12333965Sjdp 12433965Sjdp for (l = expr_symbol_lines; l != NULL; l = l->next) 12533965Sjdp { 12633965Sjdp if (l->sym == sym) 12733965Sjdp { 12833965Sjdp *pfile = l->file; 12933965Sjdp *pline = l->line; 13033965Sjdp return 1; 13133965Sjdp } 13233965Sjdp } 13333965Sjdp 13433965Sjdp return 0; 13533965Sjdp} 13633965Sjdp 13738889Sjdp/* Utilities for building expressions. 13838889Sjdp Since complex expressions are recorded as symbols for use in other 13938889Sjdp expressions these return a symbolS * and not an expressionS *. 14038889Sjdp These explicitly do not take an "add_number" argument. */ 14138889Sjdp/* ??? For completeness' sake one might want expr_build_symbol. 14238889Sjdp It would just return its argument. */ 14338889Sjdp 14438889Sjdp/* Build an expression for an unsigned constant. 14538889Sjdp The corresponding one for signed constants is missing because 14638889Sjdp there's currently no need for it. One could add an unsigned_p flag 14738889Sjdp but that seems more clumsy. */ 14838889Sjdp 14938889SjdpsymbolS * 150130561Sobrienexpr_build_uconstant (offsetT value) 15138889Sjdp{ 15238889Sjdp expressionS e; 15338889Sjdp 15438889Sjdp e.X_op = O_constant; 15538889Sjdp e.X_add_number = value; 15638889Sjdp e.X_unsigned = 1; 15738889Sjdp return make_expr_symbol (&e); 15838889Sjdp} 15938889Sjdp 16038889Sjdp/* Build an expression for OP s1. */ 16138889Sjdp 16238889SjdpsymbolS * 163130561Sobrienexpr_build_unary (operatorT op, symbolS *s1) 16438889Sjdp{ 16538889Sjdp expressionS e; 16638889Sjdp 16738889Sjdp e.X_op = op; 16838889Sjdp e.X_add_symbol = s1; 16938889Sjdp e.X_add_number = 0; 17038889Sjdp return make_expr_symbol (&e); 17138889Sjdp} 17238889Sjdp 17338889Sjdp/* Build an expression for s1 OP s2. */ 17438889Sjdp 17538889SjdpsymbolS * 176130561Sobrienexpr_build_binary (operatorT op, symbolS *s1, symbolS *s2) 17738889Sjdp{ 17838889Sjdp expressionS e; 17938889Sjdp 18038889Sjdp e.X_op = op; 18138889Sjdp e.X_add_symbol = s1; 18238889Sjdp e.X_op_symbol = s2; 18338889Sjdp e.X_add_number = 0; 18438889Sjdp return make_expr_symbol (&e); 18538889Sjdp} 18660484Sobrien 18760484Sobrien/* Build an expression for the current location ('.'). */ 18860484Sobrien 18960484SobriensymbolS * 190130561Sobrienexpr_build_dot (void) 19160484Sobrien{ 19260484Sobrien expressionS e; 19360484Sobrien 19460484Sobrien current_location (&e); 19560484Sobrien return make_expr_symbol (&e); 19660484Sobrien} 19738889Sjdp 19877298Sobrien/* Build any floating-point literal here. 19977298Sobrien Also build any bignum literal here. */ 20033965Sjdp 20133965Sjdp/* Seems atof_machine can backscan through generic_bignum and hit whatever 20233965Sjdp happens to be loaded before it in memory. And its way too complicated 20333965Sjdp for me to fix right. Thus a hack. JF: Just make generic_bignum bigger, 20433965Sjdp and never write into the early words, thus they'll always be zero. 20533965Sjdp I hate Dean's floating-point code. Bleh. */ 20633965SjdpLITTLENUM_TYPE generic_bignum[SIZE_OF_LARGE_NUMBER + 6]; 20777298Sobrien 20877298SobrienFLONUM_TYPE generic_floating_point_number = { 20977298Sobrien &generic_bignum[6], /* low. (JF: Was 0) */ 21077298Sobrien &generic_bignum[SIZE_OF_LARGE_NUMBER + 6 - 1], /* high. JF: (added +6) */ 21177298Sobrien 0, /* leader. */ 21277298Sobrien 0, /* exponent. */ 21377298Sobrien 0 /* sign. */ 21433965Sjdp}; 21577298Sobrien 21677298Sobrien/* If nonzero, we've been asked to assemble nan, +inf or -inf. */ 21733965Sjdpint generic_floating_point_magic; 21833965Sjdp 21933965Sjdpstatic void 220130561Sobrienfloating_constant (expressionS *expressionP) 22133965Sjdp{ 22277298Sobrien /* input_line_pointer -> floating-point constant. */ 22333965Sjdp int error_code; 22433965Sjdp 22533965Sjdp error_code = atof_generic (&input_line_pointer, ".", EXP_CHARS, 22633965Sjdp &generic_floating_point_number); 22733965Sjdp 22833965Sjdp if (error_code) 22933965Sjdp { 23033965Sjdp if (error_code == ERROR_EXPONENT_OVERFLOW) 23133965Sjdp { 23289857Sobrien as_bad (_("bad floating-point constant: exponent overflow")); 23333965Sjdp } 23433965Sjdp else 23533965Sjdp { 23689857Sobrien as_bad (_("bad floating-point constant: unknown error code=%d"), 23789857Sobrien error_code); 23833965Sjdp } 23933965Sjdp } 24033965Sjdp expressionP->X_op = O_big; 24177298Sobrien /* input_line_pointer -> just after constant, which may point to 24277298Sobrien whitespace. */ 24333965Sjdp expressionP->X_add_number = -1; 24433965Sjdp} 24533965Sjdp 24677298Sobrienstatic valueT 247130561Sobriengeneric_bignum_to_int32 (void) 24838889Sjdp{ 24938889Sjdp valueT number = 25038889Sjdp ((generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS) 25138889Sjdp | (generic_bignum[0] & LITTLENUM_MASK); 25238889Sjdp number &= 0xffffffff; 25338889Sjdp return number; 25438889Sjdp} 25538889Sjdp 25638889Sjdp#ifdef BFD64 25777298Sobrienstatic valueT 258130561Sobriengeneric_bignum_to_int64 (void) 25938889Sjdp{ 26077298Sobrien valueT number = 26177298Sobrien ((((((((valueT) generic_bignum[3] & LITTLENUM_MASK) 26277298Sobrien << LITTLENUM_NUMBER_OF_BITS) 26377298Sobrien | ((valueT) generic_bignum[2] & LITTLENUM_MASK)) 26477298Sobrien << LITTLENUM_NUMBER_OF_BITS) 26577298Sobrien | ((valueT) generic_bignum[1] & LITTLENUM_MASK)) 26677298Sobrien << LITTLENUM_NUMBER_OF_BITS) 26777298Sobrien | ((valueT) generic_bignum[0] & LITTLENUM_MASK)); 26838889Sjdp return number; 26938889Sjdp} 27038889Sjdp#endif 27138889Sjdp 27233965Sjdpstatic void 273130561Sobrieninteger_constant (int radix, expressionS *expressionP) 27433965Sjdp{ 27577298Sobrien char *start; /* Start of number. */ 27633965Sjdp char *suffix = NULL; 27733965Sjdp char c; 27877298Sobrien valueT number; /* Offset or (absolute) value. */ 27977298Sobrien short int digit; /* Value of next digit in current radix. */ 28077298Sobrien short int maxdig = 0; /* Highest permitted digit value. */ 28177298Sobrien int too_many_digits = 0; /* If we see >= this number of. */ 28277298Sobrien char *name; /* Points to name of symbol. */ 28377298Sobrien symbolS *symbolP; /* Points to symbol. */ 28433965Sjdp 28577298Sobrien int small; /* True if fits in 32 bits. */ 28633965Sjdp 28777298Sobrien /* May be bignum, or may fit in 32 bits. */ 28833965Sjdp /* Most numbers fit into 32 bits, and we want this case to be fast. 28933965Sjdp so we pretend it will fit into 32 bits. If, after making up a 32 29033965Sjdp bit number, we realise that we have scanned more digits than 29133965Sjdp comfortably fit into 32 bits, we re-scan the digits coding them 29233965Sjdp into a bignum. For decimal and octal numbers we are 29333965Sjdp conservative: Some numbers may be assumed bignums when in fact 29433965Sjdp they do fit into 32 bits. Numbers of any radix can have excess 29533965Sjdp leading zeros: We strive to recognise this and cast them back 29633965Sjdp into 32 bits. We must check that the bignum really is more than 29733965Sjdp 32 bits, and change it back to a 32-bit number if it fits. The 29833965Sjdp number we are looking for is expected to be positive, but if it 29933965Sjdp fits into 32 bits as an unsigned number, we let it be a 32-bit 30077298Sobrien number. The cavalier approach is for speed in ordinary cases. */ 30133965Sjdp /* This has been extended for 64 bits. We blindly assume that if 30233965Sjdp you're compiling in 64-bit mode, the target is a 64-bit machine. 30333965Sjdp This should be cleaned up. */ 30433965Sjdp 30533965Sjdp#ifdef BFD64 30633965Sjdp#define valuesize 64 30733965Sjdp#else /* includes non-bfd case, mostly */ 30833965Sjdp#define valuesize 32 30933965Sjdp#endif 31033965Sjdp 31160484Sobrien if ((NUMBERS_WITH_SUFFIX || flag_m68k_mri) && radix == 0) 31233965Sjdp { 31333965Sjdp int flt = 0; 31433965Sjdp 31533965Sjdp /* In MRI mode, the number may have a suffix indicating the 316130561Sobrien radix. For that matter, it might actually be a floating 317130561Sobrien point constant. */ 31889857Sobrien for (suffix = input_line_pointer; ISALNUM (*suffix); suffix++) 31933965Sjdp { 32033965Sjdp if (*suffix == 'e' || *suffix == 'E') 32133965Sjdp flt = 1; 32233965Sjdp } 32333965Sjdp 32433965Sjdp if (suffix == input_line_pointer) 32533965Sjdp { 32633965Sjdp radix = 10; 32733965Sjdp suffix = NULL; 32833965Sjdp } 32933965Sjdp else 33033965Sjdp { 33133965Sjdp c = *--suffix; 33289857Sobrien c = TOUPPER (c); 33333965Sjdp if (c == 'B') 33433965Sjdp radix = 2; 33533965Sjdp else if (c == 'D') 33633965Sjdp radix = 10; 33733965Sjdp else if (c == 'O' || c == 'Q') 33833965Sjdp radix = 8; 33933965Sjdp else if (c == 'H') 34033965Sjdp radix = 16; 34133965Sjdp else if (suffix[1] == '.' || c == 'E' || flt) 34233965Sjdp { 34333965Sjdp floating_constant (expressionP); 34433965Sjdp return; 34533965Sjdp } 34633965Sjdp else 34733965Sjdp { 34833965Sjdp radix = 10; 34933965Sjdp suffix = NULL; 35033965Sjdp } 35133965Sjdp } 35233965Sjdp } 35333965Sjdp 35433965Sjdp switch (radix) 35533965Sjdp { 35633965Sjdp case 2: 35733965Sjdp maxdig = 2; 35833965Sjdp too_many_digits = valuesize + 1; 35933965Sjdp break; 36033965Sjdp case 8: 36133965Sjdp maxdig = radix = 8; 36233965Sjdp too_many_digits = (valuesize + 2) / 3 + 1; 36333965Sjdp break; 36433965Sjdp case 16: 36533965Sjdp maxdig = radix = 16; 36633965Sjdp too_many_digits = (valuesize + 3) / 4 + 1; 36733965Sjdp break; 36833965Sjdp case 10: 36933965Sjdp maxdig = radix = 10; 37077298Sobrien too_many_digits = (valuesize + 11) / 4; /* Very rough. */ 37133965Sjdp } 37233965Sjdp#undef valuesize 37333965Sjdp start = input_line_pointer; 37433965Sjdp c = *input_line_pointer++; 37533965Sjdp for (number = 0; 37633965Sjdp (digit = hex_value (c)) < maxdig; 37733965Sjdp c = *input_line_pointer++) 37833965Sjdp { 37933965Sjdp number = number * radix + digit; 38033965Sjdp } 38177298Sobrien /* c contains character after number. */ 38277298Sobrien /* input_line_pointer->char after c. */ 38333965Sjdp small = (input_line_pointer - start - 1) < too_many_digits; 38438889Sjdp 38577298Sobrien if (radix == 16 && c == '_') 38633965Sjdp { 38738889Sjdp /* This is literal of the form 0x333_0_12345678_1. 388130561Sobrien This example is equivalent to 0x00000333000000001234567800000001. */ 38938889Sjdp 39038889Sjdp int num_little_digits = 0; 39138889Sjdp int i; 39277298Sobrien input_line_pointer = start; /* -> 1st digit. */ 39338889Sjdp 39438889Sjdp know (LITTLENUM_NUMBER_OF_BITS == 16); 39538889Sjdp 39677298Sobrien for (c = '_'; c == '_'; num_little_digits += 2) 39738889Sjdp { 39838889Sjdp 39977298Sobrien /* Convert one 64-bit word. */ 40077298Sobrien int ndigit = 0; 40138889Sjdp number = 0; 40238889Sjdp for (c = *input_line_pointer++; 40338889Sjdp (digit = hex_value (c)) < maxdig; 40438889Sjdp c = *(input_line_pointer++)) 40538889Sjdp { 40638889Sjdp number = number * radix + digit; 40738889Sjdp ndigit++; 40838889Sjdp } 40938889Sjdp 41038889Sjdp /* Check for 8 digit per word max. */ 41177298Sobrien if (ndigit > 8) 41289857Sobrien as_bad (_("a bignum with underscores may not have more than 8 hex digits in any word")); 41338889Sjdp 41477298Sobrien /* Add this chunk to the bignum. 41577298Sobrien Shift things down 2 little digits. */ 41638889Sjdp know (LITTLENUM_NUMBER_OF_BITS == 16); 41777298Sobrien for (i = min (num_little_digits + 1, SIZE_OF_LARGE_NUMBER - 1); 41877298Sobrien i >= 2; 41977298Sobrien i--) 42077298Sobrien generic_bignum[i] = generic_bignum[i - 2]; 42138889Sjdp 42277298Sobrien /* Add the new digits as the least significant new ones. */ 42338889Sjdp generic_bignum[0] = number & 0xffffffff; 42438889Sjdp generic_bignum[1] = number >> 16; 42538889Sjdp } 42638889Sjdp 42777298Sobrien /* Again, c is char after number, input_line_pointer->after c. */ 42838889Sjdp 42938889Sjdp if (num_little_digits > SIZE_OF_LARGE_NUMBER - 1) 43038889Sjdp num_little_digits = SIZE_OF_LARGE_NUMBER - 1; 43138889Sjdp 43238889Sjdp assert (num_little_digits >= 4); 43338889Sjdp 43438889Sjdp if (num_little_digits != 8) 43589857Sobrien as_bad (_("a bignum with underscores must have exactly 4 words")); 43638889Sjdp 43738889Sjdp /* We might have some leading zeros. These can be trimmed to give 43877298Sobrien us a change to fit this constant into a small number. */ 43977298Sobrien while (generic_bignum[num_little_digits - 1] == 0 44077298Sobrien && num_little_digits > 1) 44138889Sjdp num_little_digits--; 44277298Sobrien 44338889Sjdp if (num_little_digits <= 2) 44438889Sjdp { 44577298Sobrien /* will fit into 32 bits. */ 44638889Sjdp number = generic_bignum_to_int32 (); 44738889Sjdp small = 1; 44838889Sjdp } 44938889Sjdp#ifdef BFD64 45038889Sjdp else if (num_little_digits <= 4) 45138889Sjdp { 45238889Sjdp /* Will fit into 64 bits. */ 45338889Sjdp number = generic_bignum_to_int64 (); 45438889Sjdp small = 1; 45538889Sjdp } 45638889Sjdp#endif 45738889Sjdp else 45838889Sjdp { 45938889Sjdp small = 0; 46077298Sobrien 46177298Sobrien /* Number of littlenums in the bignum. */ 46277298Sobrien number = num_little_digits; 46338889Sjdp } 46438889Sjdp } 46538889Sjdp else if (!small) 46638889Sjdp { 46777298Sobrien /* We saw a lot of digits. manufacture a bignum the hard way. */ 46877298Sobrien LITTLENUM_TYPE *leader; /* -> high order littlenum of the bignum. */ 46977298Sobrien LITTLENUM_TYPE *pointer; /* -> littlenum we are frobbing now. */ 47033965Sjdp long carry; 47133965Sjdp 47233965Sjdp leader = generic_bignum; 47333965Sjdp generic_bignum[0] = 0; 47433965Sjdp generic_bignum[1] = 0; 47538889Sjdp generic_bignum[2] = 0; 47638889Sjdp generic_bignum[3] = 0; 47777298Sobrien input_line_pointer = start; /* -> 1st digit. */ 47833965Sjdp c = *input_line_pointer++; 47977298Sobrien for (; (carry = hex_value (c)) < maxdig; c = *input_line_pointer++) 48033965Sjdp { 48177298Sobrien for (pointer = generic_bignum; pointer <= leader; pointer++) 48233965Sjdp { 48333965Sjdp long work; 48433965Sjdp 48533965Sjdp work = carry + radix * *pointer; 48633965Sjdp *pointer = work & LITTLENUM_MASK; 48733965Sjdp carry = work >> LITTLENUM_NUMBER_OF_BITS; 48833965Sjdp } 48933965Sjdp if (carry) 49033965Sjdp { 49133965Sjdp if (leader < generic_bignum + SIZE_OF_LARGE_NUMBER - 1) 49233965Sjdp { 49377298Sobrien /* Room to grow a longer bignum. */ 49433965Sjdp *++leader = carry; 49533965Sjdp } 49633965Sjdp } 49733965Sjdp } 49877298Sobrien /* Again, c is char after number. */ 49977298Sobrien /* input_line_pointer -> after c. */ 50033965Sjdp know (LITTLENUM_NUMBER_OF_BITS == 16); 50133965Sjdp if (leader < generic_bignum + 2) 50233965Sjdp { 50377298Sobrien /* Will fit into 32 bits. */ 50438889Sjdp number = generic_bignum_to_int32 (); 50533965Sjdp small = 1; 50633965Sjdp } 50738889Sjdp#ifdef BFD64 50838889Sjdp else if (leader < generic_bignum + 4) 50938889Sjdp { 51038889Sjdp /* Will fit into 64 bits. */ 51138889Sjdp number = generic_bignum_to_int64 (); 51238889Sjdp small = 1; 51338889Sjdp } 51438889Sjdp#endif 51533965Sjdp else 51633965Sjdp { 51777298Sobrien /* Number of littlenums in the bignum. */ 51877298Sobrien number = leader - generic_bignum + 1; 51933965Sjdp } 52033965Sjdp } 52133965Sjdp 52277298Sobrien if ((NUMBERS_WITH_SUFFIX || flag_m68k_mri) 52377298Sobrien && suffix != NULL 52460484Sobrien && input_line_pointer - 1 == suffix) 52533965Sjdp c = *input_line_pointer++; 52633965Sjdp 52733965Sjdp if (small) 52833965Sjdp { 52977298Sobrien /* Here with number, in correct radix. c is the next char. 53077298Sobrien Note that unlike un*x, we allow "011f" "0x9f" to both mean 53177298Sobrien the same as the (conventional) "9f". 53277298Sobrien This is simply easier than checking for strict canonical 53377298Sobrien form. Syntax sux! */ 53433965Sjdp 53533965Sjdp if (LOCAL_LABELS_FB && c == 'b') 53633965Sjdp { 53777298Sobrien /* Backward ref to local label. 53877298Sobrien Because it is backward, expect it to be defined. */ 53933965Sjdp /* Construct a local label. */ 54033965Sjdp name = fb_label_name ((int) number, 0); 54133965Sjdp 54277298Sobrien /* Seen before, or symbol is defined: OK. */ 54333965Sjdp symbolP = symbol_find (name); 54433965Sjdp if ((symbolP != NULL) && (S_IS_DEFINED (symbolP))) 54533965Sjdp { 54677298Sobrien /* Local labels are never absolute. Don't waste time 54777298Sobrien checking absoluteness. */ 54833965Sjdp know (SEG_NORMAL (S_GET_SEGMENT (symbolP))); 54933965Sjdp 55033965Sjdp expressionP->X_op = O_symbol; 55133965Sjdp expressionP->X_add_symbol = symbolP; 55233965Sjdp } 55333965Sjdp else 55433965Sjdp { 55577298Sobrien /* Either not seen or not defined. */ 55633965Sjdp /* @@ Should print out the original string instead of 55733965Sjdp the parsed number. */ 55889857Sobrien as_bad (_("backward ref to unknown label \"%d:\""), 55933965Sjdp (int) number); 56033965Sjdp expressionP->X_op = O_constant; 56133965Sjdp } 56233965Sjdp 56333965Sjdp expressionP->X_add_number = 0; 56433965Sjdp } /* case 'b' */ 56533965Sjdp else if (LOCAL_LABELS_FB && c == 'f') 56633965Sjdp { 56777298Sobrien /* Forward reference. Expect symbol to be undefined or 56877298Sobrien unknown. undefined: seen it before. unknown: never seen 56977298Sobrien it before. 57077298Sobrien 57177298Sobrien Construct a local label name, then an undefined symbol. 57277298Sobrien Don't create a xseg frag for it: caller may do that. 57377298Sobrien Just return it as never seen before. */ 57433965Sjdp name = fb_label_name ((int) number, 1); 57533965Sjdp symbolP = symbol_find_or_make (name); 57677298Sobrien /* We have no need to check symbol properties. */ 57733965Sjdp#ifndef many_segments 57877298Sobrien /* Since "know" puts its arg into a "string", we 57933965Sjdp can't have newlines in the argument. */ 58033965Sjdp know (S_GET_SEGMENT (symbolP) == undefined_section || S_GET_SEGMENT (symbolP) == text_section || S_GET_SEGMENT (symbolP) == data_section); 58133965Sjdp#endif 58233965Sjdp expressionP->X_op = O_symbol; 58333965Sjdp expressionP->X_add_symbol = symbolP; 58433965Sjdp expressionP->X_add_number = 0; 58533965Sjdp } /* case 'f' */ 58633965Sjdp else if (LOCAL_LABELS_DOLLAR && c == '$') 58733965Sjdp { 58833965Sjdp /* If the dollar label is *currently* defined, then this is just 58933965Sjdp another reference to it. If it is not *currently* defined, 59033965Sjdp then this is a fresh instantiation of that number, so create 59133965Sjdp it. */ 59233965Sjdp 59333965Sjdp if (dollar_label_defined ((long) number)) 59433965Sjdp { 59533965Sjdp name = dollar_label_name ((long) number, 0); 59633965Sjdp symbolP = symbol_find (name); 59733965Sjdp know (symbolP != NULL); 59833965Sjdp } 59933965Sjdp else 60033965Sjdp { 60133965Sjdp name = dollar_label_name ((long) number, 1); 60233965Sjdp symbolP = symbol_find_or_make (name); 60333965Sjdp } 60433965Sjdp 60533965Sjdp expressionP->X_op = O_symbol; 60633965Sjdp expressionP->X_add_symbol = symbolP; 60733965Sjdp expressionP->X_add_number = 0; 60833965Sjdp } /* case '$' */ 60933965Sjdp else 61033965Sjdp { 61133965Sjdp expressionP->X_op = O_constant; 61233965Sjdp#ifdef TARGET_WORD_SIZE 61333965Sjdp /* Sign extend NUMBER. */ 61433965Sjdp number |= (-(number >> (TARGET_WORD_SIZE - 1))) << (TARGET_WORD_SIZE - 1); 61533965Sjdp#endif 61633965Sjdp expressionP->X_add_number = number; 61777298Sobrien input_line_pointer--; /* Restore following character. */ 61877298Sobrien } /* Really just a number. */ 61933965Sjdp } 62033965Sjdp else 62133965Sjdp { 62277298Sobrien /* Not a small number. */ 62333965Sjdp expressionP->X_op = O_big; 62477298Sobrien expressionP->X_add_number = number; /* Number of littlenums. */ 62577298Sobrien input_line_pointer--; /* -> char following number. */ 62633965Sjdp } 62733965Sjdp} 62833965Sjdp 62933965Sjdp/* Parse an MRI multi character constant. */ 63033965Sjdp 63133965Sjdpstatic void 632130561Sobrienmri_char_constant (expressionS *expressionP) 63333965Sjdp{ 63433965Sjdp int i; 63533965Sjdp 63633965Sjdp if (*input_line_pointer == '\'' 63733965Sjdp && input_line_pointer[1] != '\'') 63833965Sjdp { 63933965Sjdp expressionP->X_op = O_constant; 64033965Sjdp expressionP->X_add_number = 0; 64133965Sjdp return; 64233965Sjdp } 64333965Sjdp 64433965Sjdp /* In order to get the correct byte ordering, we must build the 64533965Sjdp number in reverse. */ 64633965Sjdp for (i = SIZE_OF_LARGE_NUMBER - 1; i >= 0; i--) 64733965Sjdp { 64833965Sjdp int j; 64933965Sjdp 65033965Sjdp generic_bignum[i] = 0; 65133965Sjdp for (j = 0; j < CHARS_PER_LITTLENUM; j++) 65233965Sjdp { 65333965Sjdp if (*input_line_pointer == '\'') 65433965Sjdp { 65533965Sjdp if (input_line_pointer[1] != '\'') 65633965Sjdp break; 65733965Sjdp ++input_line_pointer; 65833965Sjdp } 65933965Sjdp generic_bignum[i] <<= 8; 66033965Sjdp generic_bignum[i] += *input_line_pointer; 66133965Sjdp ++input_line_pointer; 66233965Sjdp } 66333965Sjdp 66433965Sjdp if (i < SIZE_OF_LARGE_NUMBER - 1) 66533965Sjdp { 66633965Sjdp /* If there is more than one littlenum, left justify the 667130561Sobrien last one to make it match the earlier ones. If there is 668130561Sobrien only one, we can just use the value directly. */ 66933965Sjdp for (; j < CHARS_PER_LITTLENUM; j++) 67033965Sjdp generic_bignum[i] <<= 8; 67133965Sjdp } 67233965Sjdp 67333965Sjdp if (*input_line_pointer == '\'' 67433965Sjdp && input_line_pointer[1] != '\'') 67533965Sjdp break; 67633965Sjdp } 67733965Sjdp 67833965Sjdp if (i < 0) 67933965Sjdp { 68089857Sobrien as_bad (_("character constant too large")); 68133965Sjdp i = 0; 68233965Sjdp } 68333965Sjdp 68433965Sjdp if (i > 0) 68533965Sjdp { 68633965Sjdp int c; 68733965Sjdp int j; 68833965Sjdp 68933965Sjdp c = SIZE_OF_LARGE_NUMBER - i; 69033965Sjdp for (j = 0; j < c; j++) 69133965Sjdp generic_bignum[j] = generic_bignum[i + j]; 69233965Sjdp i = c; 69333965Sjdp } 69433965Sjdp 69533965Sjdp know (LITTLENUM_NUMBER_OF_BITS == 16); 69633965Sjdp if (i > 2) 69733965Sjdp { 69833965Sjdp expressionP->X_op = O_big; 69933965Sjdp expressionP->X_add_number = i; 70033965Sjdp } 70133965Sjdp else 70233965Sjdp { 70333965Sjdp expressionP->X_op = O_constant; 70433965Sjdp if (i < 2) 70533965Sjdp expressionP->X_add_number = generic_bignum[0] & LITTLENUM_MASK; 70633965Sjdp else 70733965Sjdp expressionP->X_add_number = 70833965Sjdp (((generic_bignum[1] & LITTLENUM_MASK) 70933965Sjdp << LITTLENUM_NUMBER_OF_BITS) 71033965Sjdp | (generic_bignum[0] & LITTLENUM_MASK)); 71133965Sjdp } 71233965Sjdp 71333965Sjdp /* Skip the final closing quote. */ 71433965Sjdp ++input_line_pointer; 71533965Sjdp} 71633965Sjdp 71733965Sjdp/* Return an expression representing the current location. This 71833965Sjdp handles the magic symbol `.'. */ 71933965Sjdp 72033965Sjdpstatic void 721130561Sobriencurrent_location (expressionS *expressionp) 72233965Sjdp{ 72333965Sjdp if (now_seg == absolute_section) 72433965Sjdp { 72533965Sjdp expressionp->X_op = O_constant; 72633965Sjdp expressionp->X_add_number = abs_section_offset; 72733965Sjdp } 72833965Sjdp else 72933965Sjdp { 73033965Sjdp expressionp->X_op = O_symbol; 731130561Sobrien expressionp->X_add_symbol = symbol_temp_new_now (); 73233965Sjdp expressionp->X_add_number = 0; 73333965Sjdp } 73433965Sjdp} 73533965Sjdp 73677298Sobrien/* In: Input_line_pointer points to 1st char of operand, which may 73777298Sobrien be a space. 73833965Sjdp 73989857Sobrien Out: An expressionS. 74077298Sobrien The operand may have been empty: in this case X_op == O_absent. 74177298Sobrien Input_line_pointer->(next non-blank) char after operand. */ 74277298Sobrien 74333965Sjdpstatic segT 744130561Sobrienoperand (expressionS *expressionP) 74533965Sjdp{ 74633965Sjdp char c; 74777298Sobrien symbolS *symbolP; /* Points to symbol. */ 74877298Sobrien char *name; /* Points to name of symbol. */ 74933965Sjdp segT segment; 75033965Sjdp 75133965Sjdp /* All integers are regarded as unsigned unless they are negated. 75233965Sjdp This is because the only thing which cares whether a number is 75333965Sjdp unsigned is the code in emit_expr which extends constants into 75433965Sjdp bignums. It should only sign extend negative numbers, so that 75533965Sjdp something like ``.quad 0x80000000'' is not sign extended even 75633965Sjdp though it appears negative if valueT is 32 bits. */ 75733965Sjdp expressionP->X_unsigned = 1; 75833965Sjdp 75977298Sobrien /* Digits, assume it is a bignum. */ 76033965Sjdp 76177298Sobrien SKIP_WHITESPACE (); /* Leading whitespace is part of operand. */ 76277298Sobrien c = *input_line_pointer++; /* input_line_pointer -> past char in c. */ 76333965Sjdp 76477298Sobrien if (is_end_of_line[(unsigned char) c]) 76577298Sobrien goto eol; 76677298Sobrien 76733965Sjdp switch (c) 76833965Sjdp { 76933965Sjdp case '1': 77033965Sjdp case '2': 77133965Sjdp case '3': 77233965Sjdp case '4': 77333965Sjdp case '5': 77433965Sjdp case '6': 77533965Sjdp case '7': 77633965Sjdp case '8': 77733965Sjdp case '9': 77833965Sjdp input_line_pointer--; 77933965Sjdp 78077298Sobrien integer_constant ((NUMBERS_WITH_SUFFIX || flag_m68k_mri) 78177298Sobrien ? 0 : 10, 782104834Sobrien expressionP); 78333965Sjdp break; 78433965Sjdp 78577298Sobrien#ifdef LITERAL_PREFIXDOLLAR_HEX 78677298Sobrien case '$': 78789857Sobrien /* $L is the start of a local label, not a hex constant. */ 78889857Sobrien if (* input_line_pointer == 'L') 78989857Sobrien goto isname; 79077298Sobrien integer_constant (16, expressionP); 79177298Sobrien break; 79277298Sobrien#endif 79377298Sobrien 79477298Sobrien#ifdef LITERAL_PREFIXPERCENT_BIN 79577298Sobrien case '%': 79677298Sobrien integer_constant (2, expressionP); 79777298Sobrien break; 79877298Sobrien#endif 79977298Sobrien 80033965Sjdp case '0': 80177298Sobrien /* Non-decimal radix. */ 80233965Sjdp 80360484Sobrien if (NUMBERS_WITH_SUFFIX || flag_m68k_mri) 80433965Sjdp { 80533965Sjdp char *s; 80633965Sjdp 807130561Sobrien /* Check for a hex or float constant. */ 80833965Sjdp for (s = input_line_pointer; hex_p (*s); s++) 80933965Sjdp ; 810130561Sobrien if (*s == 'h' || *s == 'H' || *input_line_pointer == '.') 81133965Sjdp { 81233965Sjdp --input_line_pointer; 81333965Sjdp integer_constant (0, expressionP); 81433965Sjdp break; 81533965Sjdp } 81677298Sobrien } 81733965Sjdp c = *input_line_pointer; 81833965Sjdp switch (c) 81933965Sjdp { 82033965Sjdp case 'o': 82133965Sjdp case 'O': 82233965Sjdp case 'q': 82333965Sjdp case 'Q': 82433965Sjdp case '8': 82533965Sjdp case '9': 82660484Sobrien if (NUMBERS_WITH_SUFFIX || flag_m68k_mri) 82733965Sjdp { 82833965Sjdp integer_constant (0, expressionP); 82933965Sjdp break; 83033965Sjdp } 83133965Sjdp /* Fall through. */ 83233965Sjdp default: 83333965Sjdp default_case: 83433965Sjdp if (c && strchr (FLT_CHARS, c)) 83533965Sjdp { 83633965Sjdp input_line_pointer++; 83733965Sjdp floating_constant (expressionP); 83889857Sobrien expressionP->X_add_number = - TOLOWER (c); 83933965Sjdp } 84033965Sjdp else 84133965Sjdp { 84277298Sobrien /* The string was only zero. */ 84333965Sjdp expressionP->X_op = O_constant; 84433965Sjdp expressionP->X_add_number = 0; 84533965Sjdp } 84633965Sjdp 84733965Sjdp break; 84833965Sjdp 84933965Sjdp case 'x': 85033965Sjdp case 'X': 85133965Sjdp if (flag_m68k_mri) 85233965Sjdp goto default_case; 85333965Sjdp input_line_pointer++; 85433965Sjdp integer_constant (16, expressionP); 85533965Sjdp break; 85633965Sjdp 85733965Sjdp case 'b': 85860484Sobrien if (LOCAL_LABELS_FB && ! (flag_m68k_mri || NUMBERS_WITH_SUFFIX)) 85933965Sjdp { 86033965Sjdp /* This code used to check for '+' and '-' here, and, in 86133965Sjdp some conditions, fall through to call 86233965Sjdp integer_constant. However, that didn't make sense, 86333965Sjdp as integer_constant only accepts digits. */ 86433965Sjdp /* Some of our code elsewhere does permit digits greater 86533965Sjdp than the expected base; for consistency, do the same 86633965Sjdp here. */ 86733965Sjdp if (input_line_pointer[1] < '0' 86833965Sjdp || input_line_pointer[1] > '9') 86933965Sjdp { 87033965Sjdp /* Parse this as a back reference to label 0. */ 87133965Sjdp input_line_pointer--; 87233965Sjdp integer_constant (10, expressionP); 87333965Sjdp break; 87433965Sjdp } 87533965Sjdp /* Otherwise, parse this as a binary number. */ 87633965Sjdp } 87733965Sjdp /* Fall through. */ 87833965Sjdp case 'B': 87933965Sjdp input_line_pointer++; 88060484Sobrien if (flag_m68k_mri || NUMBERS_WITH_SUFFIX) 88133965Sjdp goto default_case; 88233965Sjdp integer_constant (2, expressionP); 88333965Sjdp break; 88433965Sjdp 88533965Sjdp case '0': 88633965Sjdp case '1': 88733965Sjdp case '2': 88833965Sjdp case '3': 88933965Sjdp case '4': 89033965Sjdp case '5': 89133965Sjdp case '6': 89233965Sjdp case '7': 89360484Sobrien integer_constant ((flag_m68k_mri || NUMBERS_WITH_SUFFIX) 89477298Sobrien ? 0 : 8, 89577298Sobrien expressionP); 89633965Sjdp break; 89733965Sjdp 89833965Sjdp case 'f': 89933965Sjdp if (LOCAL_LABELS_FB) 90033965Sjdp { 90133965Sjdp /* If it says "0f" and it could possibly be a floating point 90233965Sjdp number, make it one. Otherwise, make it a local label, 90333965Sjdp and try to deal with parsing the rest later. */ 90433965Sjdp if (!input_line_pointer[1] 90560484Sobrien || (is_end_of_line[0xff & input_line_pointer[1]]) 90660484Sobrien || strchr (FLT_CHARS, 'f') == NULL) 90733965Sjdp goto is_0f_label; 90833965Sjdp { 90933965Sjdp char *cp = input_line_pointer + 1; 91033965Sjdp int r = atof_generic (&cp, ".", EXP_CHARS, 91133965Sjdp &generic_floating_point_number); 91233965Sjdp switch (r) 91333965Sjdp { 91433965Sjdp case 0: 91533965Sjdp case ERROR_EXPONENT_OVERFLOW: 91633965Sjdp if (*cp == 'f' || *cp == 'b') 91777298Sobrien /* Looks like a difference expression. */ 91833965Sjdp goto is_0f_label; 91960484Sobrien else if (cp == input_line_pointer + 1) 92060484Sobrien /* No characters has been accepted -- looks like 92177298Sobrien end of operand. */ 92260484Sobrien goto is_0f_label; 92333965Sjdp else 92433965Sjdp goto is_0f_float; 92533965Sjdp default: 92660484Sobrien as_fatal (_("expr.c(operand): bad atof_generic return val %d"), 92733965Sjdp r); 92833965Sjdp } 92933965Sjdp } 93033965Sjdp 93133965Sjdp /* Okay, now we've sorted it out. We resume at one of these 93233965Sjdp two labels, depending on what we've decided we're probably 93333965Sjdp looking at. */ 93433965Sjdp is_0f_label: 93533965Sjdp input_line_pointer--; 93633965Sjdp integer_constant (10, expressionP); 93733965Sjdp break; 93833965Sjdp 93933965Sjdp is_0f_float: 94077298Sobrien /* Fall through. */ 94133965Sjdp ; 94233965Sjdp } 94333965Sjdp 94433965Sjdp case 'd': 94533965Sjdp case 'D': 94660484Sobrien if (flag_m68k_mri || NUMBERS_WITH_SUFFIX) 94733965Sjdp { 94833965Sjdp integer_constant (0, expressionP); 94933965Sjdp break; 95033965Sjdp } 95133965Sjdp /* Fall through. */ 95233965Sjdp case 'F': 95333965Sjdp case 'r': 95433965Sjdp case 'e': 95533965Sjdp case 'E': 95633965Sjdp case 'g': 95733965Sjdp case 'G': 95833965Sjdp input_line_pointer++; 95933965Sjdp floating_constant (expressionP); 96089857Sobrien expressionP->X_add_number = - TOLOWER (c); 96133965Sjdp break; 96233965Sjdp 96333965Sjdp case '$': 96433965Sjdp if (LOCAL_LABELS_DOLLAR) 96533965Sjdp { 96633965Sjdp integer_constant (10, expressionP); 96733965Sjdp break; 96833965Sjdp } 96933965Sjdp else 97033965Sjdp goto default_case; 97133965Sjdp } 97233965Sjdp 97333965Sjdp break; 97433965Sjdp 97533965Sjdp case '(': 97660484Sobrien#ifndef NEED_INDEX_OPERATOR 97733965Sjdp case '[': 97860484Sobrien#endif 97977298Sobrien /* Didn't begin with digit & not a name. */ 98033965Sjdp segment = expression (expressionP); 98177298Sobrien /* expression () will pass trailing whitespace. */ 98277298Sobrien if ((c == '(' && *input_line_pointer != ')') 98377298Sobrien || (c == '[' && *input_line_pointer != ']')) 98433965Sjdp { 98577298Sobrien#ifdef RELAX_PAREN_GROUPING 98677298Sobrien if (c != '(') 98777298Sobrien#endif 98889857Sobrien as_bad (_("missing '%c'"), c == '(' ? ')' : ']'); 98933965Sjdp } 99077298Sobrien else 99177298Sobrien input_line_pointer++; 99233965Sjdp SKIP_WHITESPACE (); 99377298Sobrien /* Here with input_line_pointer -> char after "(...)". */ 99433965Sjdp return segment; 99533965Sjdp 99660484Sobrien#ifdef TC_M68K 99733965Sjdp case 'E': 99833965Sjdp if (! flag_m68k_mri || *input_line_pointer != '\'') 99933965Sjdp goto de_fault; 100060484Sobrien as_bad (_("EBCDIC constants are not supported")); 100133965Sjdp /* Fall through. */ 100233965Sjdp case 'A': 100333965Sjdp if (! flag_m68k_mri || *input_line_pointer != '\'') 100433965Sjdp goto de_fault; 100533965Sjdp ++input_line_pointer; 100633965Sjdp /* Fall through. */ 100760484Sobrien#endif 100833965Sjdp case '\'': 100933965Sjdp if (! flag_m68k_mri) 101033965Sjdp { 101133965Sjdp /* Warning: to conform to other people's assemblers NO 101277298Sobrien ESCAPEMENT is permitted for a single quote. The next 101333965Sjdp character, parity errors and all, is taken as the value 101477298Sobrien of the operand. VERY KINKY. */ 101533965Sjdp expressionP->X_op = O_constant; 101633965Sjdp expressionP->X_add_number = *input_line_pointer++; 101733965Sjdp break; 101833965Sjdp } 101933965Sjdp 102033965Sjdp mri_char_constant (expressionP); 102133965Sjdp break; 102233965Sjdp 102333965Sjdp case '+': 1024130561Sobrien /* Do not accept ++e as +(+e). 1025130561Sobrien Disabled, since the preprocessor removes whitespace. */ 1026130561Sobrien if (0 && *input_line_pointer == '+') 1027130561Sobrien goto target_op; 102833965Sjdp (void) operand (expressionP); 102933965Sjdp break; 103033965Sjdp 103160484Sobrien#ifdef TC_M68K 103233965Sjdp case '"': 103333965Sjdp /* Double quote is the bitwise not operator in MRI mode. */ 103433965Sjdp if (! flag_m68k_mri) 103533965Sjdp goto de_fault; 103633965Sjdp /* Fall through. */ 103760484Sobrien#endif 103833965Sjdp case '~': 103977298Sobrien /* '~' is permitted to start a label on the Delta. */ 104033965Sjdp if (is_name_beginner (c)) 104133965Sjdp goto isname; 104233965Sjdp case '!': 104333965Sjdp case '-': 104433965Sjdp { 1045130561Sobrien /* Do not accept --e as -(-e) 1046130561Sobrien Disabled, since the preprocessor removes whitespace. */ 1047130561Sobrien if (0 && c == '-' && *input_line_pointer == '-') 1048130561Sobrien goto target_op; 1049130561Sobrien 105033965Sjdp operand (expressionP); 105133965Sjdp if (expressionP->X_op == O_constant) 105233965Sjdp { 105377298Sobrien /* input_line_pointer -> char after operand. */ 105433965Sjdp if (c == '-') 105533965Sjdp { 105633965Sjdp expressionP->X_add_number = - expressionP->X_add_number; 105777298Sobrien /* Notice: '-' may overflow: no warning is given. 105877298Sobrien This is compatible with other people's 105977298Sobrien assemblers. Sigh. */ 106033965Sjdp expressionP->X_unsigned = 0; 106133965Sjdp } 106233965Sjdp else if (c == '~' || c == '"') 106333965Sjdp expressionP->X_add_number = ~ expressionP->X_add_number; 106433965Sjdp else 106533965Sjdp expressionP->X_add_number = ! expressionP->X_add_number; 106633965Sjdp } 1067130561Sobrien else if (expressionP->X_op == O_big 1068130561Sobrien && expressionP->X_add_number <= 0 1069130561Sobrien && c == '-' 1070130561Sobrien && (generic_floating_point_number.sign == '+' 1071130561Sobrien || generic_floating_point_number.sign == 'P')) 1072130561Sobrien { 1073130561Sobrien /* Negative flonum (eg, -1.000e0). */ 1074130561Sobrien if (generic_floating_point_number.sign == '+') 1075130561Sobrien generic_floating_point_number.sign = '-'; 1076130561Sobrien else 1077130561Sobrien generic_floating_point_number.sign = 'N'; 1078130561Sobrien } 107933965Sjdp else if (expressionP->X_op != O_illegal 108033965Sjdp && expressionP->X_op != O_absent) 108133965Sjdp { 108233965Sjdp expressionP->X_add_symbol = make_expr_symbol (expressionP); 108333965Sjdp if (c == '-') 108433965Sjdp expressionP->X_op = O_uminus; 108533965Sjdp else if (c == '~' || c == '"') 108633965Sjdp expressionP->X_op = O_bit_not; 108733965Sjdp else 108833965Sjdp expressionP->X_op = O_logical_not; 108933965Sjdp expressionP->X_add_number = 0; 109033965Sjdp } 109133965Sjdp else 109260484Sobrien as_warn (_("Unary operator %c ignored because bad operand follows"), 109333965Sjdp c); 109433965Sjdp } 109533965Sjdp break; 109633965Sjdp 109760484Sobrien#if defined (DOLLAR_DOT) || defined (TC_M68K) 109833965Sjdp case '$': 109977298Sobrien /* '$' is the program counter when in MRI mode, or when 1100130561Sobrien DOLLAR_DOT is defined. */ 110133965Sjdp#ifndef DOLLAR_DOT 110233965Sjdp if (! flag_m68k_mri) 110333965Sjdp goto de_fault; 110433965Sjdp#endif 110533965Sjdp if (flag_m68k_mri && hex_p (*input_line_pointer)) 110633965Sjdp { 110777298Sobrien /* In MRI mode, '$' is also used as the prefix for a 1108130561Sobrien hexadecimal constant. */ 110933965Sjdp integer_constant (16, expressionP); 111033965Sjdp break; 111133965Sjdp } 111233965Sjdp 111333965Sjdp if (is_part_of_name (*input_line_pointer)) 111433965Sjdp goto isname; 111533965Sjdp 111633965Sjdp current_location (expressionP); 111733965Sjdp break; 111860484Sobrien#endif 111933965Sjdp 112033965Sjdp case '.': 112133965Sjdp if (!is_part_of_name (*input_line_pointer)) 112233965Sjdp { 112333965Sjdp current_location (expressionP); 112433965Sjdp break; 112533965Sjdp } 112633965Sjdp else if ((strncasecmp (input_line_pointer, "startof.", 8) == 0 112733965Sjdp && ! is_part_of_name (input_line_pointer[8])) 112833965Sjdp || (strncasecmp (input_line_pointer, "sizeof.", 7) == 0 112933965Sjdp && ! is_part_of_name (input_line_pointer[7]))) 113033965Sjdp { 113133965Sjdp int start; 113233965Sjdp 113333965Sjdp start = (input_line_pointer[1] == 't' 113433965Sjdp || input_line_pointer[1] == 'T'); 113533965Sjdp input_line_pointer += start ? 8 : 7; 113633965Sjdp SKIP_WHITESPACE (); 113733965Sjdp if (*input_line_pointer != '(') 113860484Sobrien as_bad (_("syntax error in .startof. or .sizeof.")); 113933965Sjdp else 114033965Sjdp { 114133965Sjdp char *buf; 114233965Sjdp 114333965Sjdp ++input_line_pointer; 114433965Sjdp SKIP_WHITESPACE (); 114533965Sjdp name = input_line_pointer; 114633965Sjdp c = get_symbol_end (); 114733965Sjdp 114833965Sjdp buf = (char *) xmalloc (strlen (name) + 10); 114933965Sjdp if (start) 115033965Sjdp sprintf (buf, ".startof.%s", name); 115133965Sjdp else 115233965Sjdp sprintf (buf, ".sizeof.%s", name); 115333965Sjdp symbolP = symbol_make (buf); 115433965Sjdp free (buf); 115533965Sjdp 115633965Sjdp expressionP->X_op = O_symbol; 115733965Sjdp expressionP->X_add_symbol = symbolP; 115833965Sjdp expressionP->X_add_number = 0; 115933965Sjdp 116033965Sjdp *input_line_pointer = c; 116133965Sjdp SKIP_WHITESPACE (); 116233965Sjdp if (*input_line_pointer != ')') 116360484Sobrien as_bad (_("syntax error in .startof. or .sizeof.")); 116433965Sjdp else 116533965Sjdp ++input_line_pointer; 116633965Sjdp } 116733965Sjdp break; 116833965Sjdp } 116933965Sjdp else 117033965Sjdp { 117133965Sjdp goto isname; 117233965Sjdp } 117377298Sobrien 117433965Sjdp case ',': 117533965Sjdp eol: 117677298Sobrien /* Can't imagine any other kind of operand. */ 117733965Sjdp expressionP->X_op = O_absent; 117833965Sjdp input_line_pointer--; 117933965Sjdp break; 118033965Sjdp 118160484Sobrien#ifdef TC_M68K 118233965Sjdp case '%': 118333965Sjdp if (! flag_m68k_mri) 118433965Sjdp goto de_fault; 118533965Sjdp integer_constant (2, expressionP); 118633965Sjdp break; 118733965Sjdp 118833965Sjdp case '@': 118933965Sjdp if (! flag_m68k_mri) 119033965Sjdp goto de_fault; 119133965Sjdp integer_constant (8, expressionP); 119233965Sjdp break; 119333965Sjdp 119433965Sjdp case ':': 119533965Sjdp if (! flag_m68k_mri) 119633965Sjdp goto de_fault; 119733965Sjdp 119833965Sjdp /* In MRI mode, this is a floating point constant represented 1199130561Sobrien using hexadecimal digits. */ 120033965Sjdp 120133965Sjdp ++input_line_pointer; 120233965Sjdp integer_constant (16, expressionP); 120333965Sjdp break; 120433965Sjdp 120533965Sjdp case '*': 120633965Sjdp if (! flag_m68k_mri || is_part_of_name (*input_line_pointer)) 120733965Sjdp goto de_fault; 120833965Sjdp 120933965Sjdp current_location (expressionP); 121033965Sjdp break; 121160484Sobrien#endif 121233965Sjdp 121333965Sjdp default: 121460484Sobrien#ifdef TC_M68K 121533965Sjdp de_fault: 121660484Sobrien#endif 121777298Sobrien if (is_name_beginner (c)) /* Here if did not begin with a digit. */ 121833965Sjdp { 121977298Sobrien /* Identifier begins here. 122077298Sobrien This is kludged for speed, so code is repeated. */ 122133965Sjdp isname: 122233965Sjdp name = --input_line_pointer; 122333965Sjdp c = get_symbol_end (); 122433965Sjdp 122533965Sjdp#ifdef md_parse_name 122633965Sjdp /* This is a hook for the backend to parse certain names 1227130561Sobrien specially in certain contexts. If a name always has a 1228130561Sobrien specific value, it can often be handled by simply 1229130561Sobrien entering it in the symbol table. */ 123089857Sobrien if (md_parse_name (name, expressionP, &c)) 123133965Sjdp { 123233965Sjdp *input_line_pointer = c; 123333965Sjdp break; 123433965Sjdp } 123533965Sjdp#endif 123633965Sjdp 123733965Sjdp#ifdef TC_I960 123833965Sjdp /* The MRI i960 assembler permits 123933965Sjdp lda sizeof code,g13 124033965Sjdp FIXME: This should use md_parse_name. */ 124133965Sjdp if (flag_mri 124233965Sjdp && (strcasecmp (name, "sizeof") == 0 124333965Sjdp || strcasecmp (name, "startof") == 0)) 124433965Sjdp { 124533965Sjdp int start; 124633965Sjdp char *buf; 124733965Sjdp 124833965Sjdp start = (name[1] == 't' 124933965Sjdp || name[1] == 'T'); 125033965Sjdp 125133965Sjdp *input_line_pointer = c; 125233965Sjdp SKIP_WHITESPACE (); 125333965Sjdp 125433965Sjdp name = input_line_pointer; 125533965Sjdp c = get_symbol_end (); 125633965Sjdp 125733965Sjdp buf = (char *) xmalloc (strlen (name) + 10); 125833965Sjdp if (start) 125933965Sjdp sprintf (buf, ".startof.%s", name); 126033965Sjdp else 126133965Sjdp sprintf (buf, ".sizeof.%s", name); 126233965Sjdp symbolP = symbol_make (buf); 126333965Sjdp free (buf); 126433965Sjdp 126533965Sjdp expressionP->X_op = O_symbol; 126633965Sjdp expressionP->X_add_symbol = symbolP; 126733965Sjdp expressionP->X_add_number = 0; 126833965Sjdp 126933965Sjdp *input_line_pointer = c; 127033965Sjdp SKIP_WHITESPACE (); 127133965Sjdp 127233965Sjdp break; 127377298Sobrien } 127433965Sjdp#endif 127533965Sjdp 127633965Sjdp symbolP = symbol_find_or_make (name); 127733965Sjdp 127833965Sjdp /* If we have an absolute symbol or a reg, then we know its 127933965Sjdp value now. */ 128033965Sjdp segment = S_GET_SEGMENT (symbolP); 128133965Sjdp if (segment == absolute_section) 128233965Sjdp { 128333965Sjdp expressionP->X_op = O_constant; 128433965Sjdp expressionP->X_add_number = S_GET_VALUE (symbolP); 128533965Sjdp } 128633965Sjdp else if (segment == reg_section) 128733965Sjdp { 128833965Sjdp expressionP->X_op = O_register; 128933965Sjdp expressionP->X_add_number = S_GET_VALUE (symbolP); 129033965Sjdp } 129133965Sjdp else 129233965Sjdp { 129333965Sjdp expressionP->X_op = O_symbol; 129433965Sjdp expressionP->X_add_symbol = symbolP; 129533965Sjdp expressionP->X_add_number = 0; 129633965Sjdp } 129733965Sjdp *input_line_pointer = c; 129833965Sjdp } 129933965Sjdp else 130033965Sjdp { 1301130561Sobrien target_op: 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 130477298Sobrien input_line_pointer past 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; 131289857Sobrien as_bad (_("bad expression")); 131333965Sjdp expressionP->X_op = O_constant; 131433965Sjdp expressionP->X_add_number = 0; 131533965Sjdp } 131633965Sjdp } 131733965Sjdp break; 131833965Sjdp } 131933965Sjdp 132077298Sobrien /* It is more 'efficient' to clean up the expressionS when they are 132177298Sobrien created. Doing it here saves lines of code. */ 132233965Sjdp clean_up_expression (expressionP); 132377298Sobrien SKIP_WHITESPACE (); /* -> 1st char after operand. */ 132433965Sjdp know (*input_line_pointer != ' '); 132533965Sjdp 132633965Sjdp /* The PA port needs this information. */ 132733965Sjdp if (expressionP->X_add_symbol) 132860484Sobrien symbol_mark_used (expressionP->X_add_symbol); 132933965Sjdp 133033965Sjdp switch (expressionP->X_op) 133133965Sjdp { 133233965Sjdp default: 133333965Sjdp return absolute_section; 133433965Sjdp case O_symbol: 133533965Sjdp return S_GET_SEGMENT (expressionP->X_add_symbol); 133633965Sjdp case O_register: 133733965Sjdp return reg_section; 133833965Sjdp } 133977298Sobrien} 134033965Sjdp 134177298Sobrien/* Internal. Simplify a struct expression for use by expr (). */ 134233965Sjdp 134389857Sobrien/* In: address of an expressionS. 134477298Sobrien The X_op field of the expressionS may only take certain values. 134577298Sobrien Elsewise we waste time special-case testing. Sigh. Ditto SEG_ABSENT. 134633965Sjdp 134777298Sobrien Out: expressionS may have been modified: 134877298Sobrien Unused fields zeroed to help expr (). */ 134977298Sobrien 135033965Sjdpstatic void 1351130561Sobrienclean_up_expression (expressionS *expressionP) 135233965Sjdp{ 135333965Sjdp switch (expressionP->X_op) 135433965Sjdp { 135533965Sjdp case O_illegal: 135633965Sjdp case O_absent: 135733965Sjdp expressionP->X_add_number = 0; 135833965Sjdp /* Fall through. */ 135933965Sjdp case O_big: 136033965Sjdp case O_constant: 136133965Sjdp case O_register: 136233965Sjdp expressionP->X_add_symbol = NULL; 136333965Sjdp /* Fall through. */ 136433965Sjdp case O_symbol: 136533965Sjdp case O_uminus: 136633965Sjdp case O_bit_not: 136733965Sjdp expressionP->X_op_symbol = NULL; 136833965Sjdp break; 136933965Sjdp default: 137033965Sjdp break; 137133965Sjdp } 137233965Sjdp} 137333965Sjdp 137477298Sobrien/* Expression parser. */ 137533965Sjdp 137677298Sobrien/* We allow an empty expression, and just assume (absolute,0) silently. 137777298Sobrien Unary operators and parenthetical expressions are treated as operands. 137877298Sobrien As usual, Q==quantity==operand, O==operator, X==expression mnemonics. 137933965Sjdp 138089857Sobrien We used to do an aho/ullman shift-reduce parser, but the logic got so 138177298Sobrien warped that I flushed it and wrote a recursive-descent parser instead. 138277298Sobrien Now things are stable, would anybody like to write a fast parser? 138377298Sobrien Most expressions are either register (which does not even reach here) 138477298Sobrien or 1 symbol. Then "symbol+constant" and "symbol-symbol" are common. 138577298Sobrien So I guess it doesn't really matter how inefficient more complex expressions 138677298Sobrien are parsed. 138777298Sobrien 138877298Sobrien After expr(RANK,resultP) input_line_pointer->operator of rank <= RANK. 138977298Sobrien Also, we have consumed any leading or trailing spaces (operand does that) 139077298Sobrien and done all intervening operators. 139177298Sobrien 139277298Sobrien This returns the segment of the result, which will be 139377298Sobrien absolute_section or the segment of a symbol. */ 139477298Sobrien 139533965Sjdp#undef __ 139633965Sjdp#define __ O_illegal 139733965Sjdp 139877298Sobrien/* Maps ASCII -> operators. */ 139977298Sobrienstatic const operatorT op_encoding[256] = { 140033965Sjdp __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, 140133965Sjdp __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, 140233965Sjdp 140333965Sjdp __, O_bit_or_not, __, __, __, O_modulus, O_bit_and, __, 140433965Sjdp __, __, O_multiply, O_add, __, O_subtract, __, O_divide, 140533965Sjdp __, __, __, __, __, __, __, __, 140633965Sjdp __, __, __, __, O_lt, __, O_gt, __, 140733965Sjdp __, __, __, __, __, __, __, __, 140833965Sjdp __, __, __, __, __, __, __, __, 140933965Sjdp __, __, __, __, __, __, __, __, 141060484Sobrien __, __, __, 141160484Sobrien#ifdef NEED_INDEX_OPERATOR 141260484Sobrien O_index, 141360484Sobrien#else 141460484Sobrien __, 141560484Sobrien#endif 141660484Sobrien __, __, O_bit_exclusive_or, __, 141733965Sjdp __, __, __, __, __, __, __, __, 141833965Sjdp __, __, __, __, __, __, __, __, 141933965Sjdp __, __, __, __, __, __, __, __, 142033965Sjdp __, __, __, __, O_bit_inclusive_or, __, __, __, 142133965Sjdp 142233965Sjdp __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, 142333965Sjdp __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, 142433965Sjdp __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, 142533965Sjdp __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, 142633965Sjdp __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, 142733965Sjdp __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, 142833965Sjdp __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, 142933965Sjdp __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __ 143033965Sjdp}; 143133965Sjdp 143277298Sobrien/* Rank Examples 143377298Sobrien 0 operand, (expression) 143477298Sobrien 1 || 143577298Sobrien 2 && 143689857Sobrien 3 == <> < <= >= > 143777298Sobrien 4 + - 143877298Sobrien 5 used for * / % in MRI mode 143977298Sobrien 6 & ^ ! | 144077298Sobrien 7 * / % << >> 144177298Sobrien 8 unary - unary ~ 144277298Sobrien*/ 144377298Sobrienstatic operator_rankT op_rank[] = { 144433965Sjdp 0, /* O_illegal */ 144533965Sjdp 0, /* O_absent */ 144633965Sjdp 0, /* O_constant */ 144733965Sjdp 0, /* O_symbol */ 144833965Sjdp 0, /* O_symbol_rva */ 144933965Sjdp 0, /* O_register */ 145077298Sobrien 0, /* O_big */ 145160484Sobrien 9, /* O_uminus */ 145260484Sobrien 9, /* O_bit_not */ 145360484Sobrien 9, /* O_logical_not */ 145460484Sobrien 8, /* O_multiply */ 145560484Sobrien 8, /* O_divide */ 145660484Sobrien 8, /* O_modulus */ 145760484Sobrien 8, /* O_left_shift */ 145860484Sobrien 8, /* O_right_shift */ 145960484Sobrien 7, /* O_bit_inclusive_or */ 146060484Sobrien 7, /* O_bit_or_not */ 146160484Sobrien 7, /* O_bit_exclusive_or */ 146260484Sobrien 7, /* O_bit_and */ 146360484Sobrien 5, /* O_add */ 146460484Sobrien 5, /* O_subtract */ 146560484Sobrien 4, /* O_eq */ 146660484Sobrien 4, /* O_ne */ 146760484Sobrien 4, /* O_lt */ 146860484Sobrien 4, /* O_le */ 146960484Sobrien 4, /* O_ge */ 147060484Sobrien 4, /* O_gt */ 147160484Sobrien 3, /* O_logical_and */ 147260484Sobrien 2, /* O_logical_or */ 147360484Sobrien 1, /* O_index */ 147460484Sobrien 0, /* O_md1 */ 147560484Sobrien 0, /* O_md2 */ 147660484Sobrien 0, /* O_md3 */ 147760484Sobrien 0, /* O_md4 */ 147860484Sobrien 0, /* O_md5 */ 147960484Sobrien 0, /* O_md6 */ 148060484Sobrien 0, /* O_md7 */ 148160484Sobrien 0, /* O_md8 */ 148260484Sobrien 0, /* O_md9 */ 148360484Sobrien 0, /* O_md10 */ 148460484Sobrien 0, /* O_md11 */ 148560484Sobrien 0, /* O_md12 */ 148660484Sobrien 0, /* O_md13 */ 148760484Sobrien 0, /* O_md14 */ 148860484Sobrien 0, /* O_md15 */ 148960484Sobrien 0, /* O_md16 */ 149033965Sjdp}; 149133965Sjdp 149260484Sobrien/* Unfortunately, in MRI mode for the m68k, multiplication and 149360484Sobrien division have lower precedence than the bit wise operators. This 149460484Sobrien function sets the operator precedences correctly for the current 149560484Sobrien mode. Also, MRI uses a different bit_not operator, and this fixes 149660484Sobrien that as well. */ 149733965Sjdp 149877298Sobrien#define STANDARD_MUL_PRECEDENCE 8 149977298Sobrien#define MRI_MUL_PRECEDENCE 6 150060484Sobrien 150133965Sjdpvoid 1502130561Sobrienexpr_set_precedence (void) 150333965Sjdp{ 150433965Sjdp if (flag_m68k_mri) 150533965Sjdp { 150660484Sobrien op_rank[O_multiply] = MRI_MUL_PRECEDENCE; 150760484Sobrien op_rank[O_divide] = MRI_MUL_PRECEDENCE; 150860484Sobrien op_rank[O_modulus] = MRI_MUL_PRECEDENCE; 150933965Sjdp } 151060484Sobrien else 151160484Sobrien { 151260484Sobrien op_rank[O_multiply] = STANDARD_MUL_PRECEDENCE; 151360484Sobrien op_rank[O_divide] = STANDARD_MUL_PRECEDENCE; 151460484Sobrien op_rank[O_modulus] = STANDARD_MUL_PRECEDENCE; 151560484Sobrien } 151660484Sobrien} 151733965Sjdp 151860484Sobrien/* Initialize the expression parser. */ 151960484Sobrien 152060484Sobrienvoid 1521130561Sobrienexpr_begin (void) 152260484Sobrien{ 152360484Sobrien expr_set_precedence (); 152460484Sobrien 152533965Sjdp /* Verify that X_op field is wide enough. */ 152633965Sjdp { 152733965Sjdp expressionS e; 152833965Sjdp e.X_op = O_max; 152933965Sjdp assert (e.X_op == O_max); 153033965Sjdp } 153133965Sjdp} 153233965Sjdp 153377298Sobrien/* Return the encoding for the operator at INPUT_LINE_POINTER, and 153477298Sobrien sets NUM_CHARS to the number of characters in the operator. 153577298Sobrien Does not advance INPUT_LINE_POINTER. */ 153633965Sjdp 153733965Sjdpstatic inline operatorT 1538130561Sobrienoperator (int *num_chars) 153933965Sjdp{ 154033965Sjdp int c; 154133965Sjdp operatorT ret; 154233965Sjdp 154360484Sobrien c = *input_line_pointer & 0xff; 154477298Sobrien *num_chars = 1; 154533965Sjdp 154677298Sobrien if (is_end_of_line[c]) 154777298Sobrien return O_illegal; 154877298Sobrien 154933965Sjdp switch (c) 155033965Sjdp { 155133965Sjdp default: 155233965Sjdp return op_encoding[c]; 155333965Sjdp 1554130561Sobrien case '+': 1555130561Sobrien case '-': 1556130561Sobrien /* Do not allow a++b and a--b to be a + (+b) and a - (-b) 1557130561Sobrien Disabled, since the preprocessor removes whitespace. */ 1558130561Sobrien if (1 || input_line_pointer[1] != c) 1559130561Sobrien return op_encoding[c]; 1560130561Sobrien return O_illegal; 1561130561Sobrien 156233965Sjdp case '<': 156333965Sjdp switch (input_line_pointer[1]) 156433965Sjdp { 156533965Sjdp default: 156633965Sjdp return op_encoding[c]; 156733965Sjdp case '<': 156833965Sjdp ret = O_left_shift; 156933965Sjdp break; 157033965Sjdp case '>': 157133965Sjdp ret = O_ne; 157233965Sjdp break; 157333965Sjdp case '=': 157433965Sjdp ret = O_le; 157533965Sjdp break; 157633965Sjdp } 157777298Sobrien *num_chars = 2; 157833965Sjdp return ret; 157933965Sjdp 158038889Sjdp case '=': 158138889Sjdp if (input_line_pointer[1] != '=') 158238889Sjdp return op_encoding[c]; 158338889Sjdp 158477298Sobrien *num_chars = 2; 158538889Sjdp return O_eq; 158638889Sjdp 158733965Sjdp case '>': 158833965Sjdp switch (input_line_pointer[1]) 158933965Sjdp { 159033965Sjdp default: 159133965Sjdp return op_encoding[c]; 159233965Sjdp case '>': 159333965Sjdp ret = O_right_shift; 159433965Sjdp break; 159533965Sjdp case '=': 159633965Sjdp ret = O_ge; 159733965Sjdp break; 159833965Sjdp } 159977298Sobrien *num_chars = 2; 160033965Sjdp return ret; 160133965Sjdp 160233965Sjdp case '!': 160333965Sjdp /* We accept !! as equivalent to ^ for MRI compatibility. */ 160433965Sjdp if (input_line_pointer[1] != '!') 160533965Sjdp { 160633965Sjdp if (flag_m68k_mri) 160733965Sjdp return O_bit_inclusive_or; 160833965Sjdp return op_encoding[c]; 160933965Sjdp } 161077298Sobrien *num_chars = 2; 161133965Sjdp return O_bit_exclusive_or; 161233965Sjdp 161333965Sjdp case '|': 161433965Sjdp if (input_line_pointer[1] != '|') 161533965Sjdp return op_encoding[c]; 161633965Sjdp 161777298Sobrien *num_chars = 2; 161833965Sjdp return O_logical_or; 161933965Sjdp 162033965Sjdp case '&': 162133965Sjdp if (input_line_pointer[1] != '&') 162233965Sjdp return op_encoding[c]; 162333965Sjdp 162477298Sobrien *num_chars = 2; 162533965Sjdp return O_logical_and; 162633965Sjdp } 162733965Sjdp 162877298Sobrien /* NOTREACHED */ 162938889Sjdp} 163033965Sjdp 163133965Sjdp/* Parse an expression. */ 163233965Sjdp 163333965SjdpsegT 1634130561Sobrienexpr (int rankarg, /* Larger # is higher rank. */ 1635130561Sobrien expressionS *resultP /* Deliver result here. */) 163633965Sjdp{ 163760484Sobrien operator_rankT rank = (operator_rankT) rankarg; 163833965Sjdp segT retval; 163933965Sjdp expressionS right; 164033965Sjdp operatorT op_left; 164133965Sjdp operatorT op_right; 164277298Sobrien int op_chars; 164333965Sjdp 164433965Sjdp know (rank >= 0); 164533965Sjdp 1646130561Sobrien /* Save the value of dot for the fixup code. */ 1647130561Sobrien if (rank == 0) 1648130561Sobrien dot_value = frag_now_fix (); 1649130561Sobrien 165033965Sjdp retval = operand (resultP); 165133965Sjdp 165277298Sobrien /* operand () gobbles spaces. */ 165377298Sobrien know (*input_line_pointer != ' '); 165433965Sjdp 165577298Sobrien op_left = operator (&op_chars); 165633965Sjdp while (op_left != O_illegal && op_rank[(int) op_left] > rank) 165733965Sjdp { 165833965Sjdp segT rightseg; 165933965Sjdp 166077298Sobrien input_line_pointer += op_chars; /* -> after operator. */ 166133965Sjdp 166233965Sjdp rightseg = expr (op_rank[(int) op_left], &right); 166333965Sjdp if (right.X_op == O_absent) 166433965Sjdp { 166560484Sobrien as_warn (_("missing operand; zero assumed")); 166633965Sjdp right.X_op = O_constant; 166733965Sjdp right.X_add_number = 0; 166833965Sjdp right.X_add_symbol = NULL; 166933965Sjdp right.X_op_symbol = NULL; 167033965Sjdp } 167133965Sjdp 167233965Sjdp know (*input_line_pointer != ' '); 167333965Sjdp 167460484Sobrien if (op_left == O_index) 167560484Sobrien { 167660484Sobrien if (*input_line_pointer != ']') 167760484Sobrien as_bad ("missing right bracket"); 167860484Sobrien else 167960484Sobrien { 168060484Sobrien ++input_line_pointer; 168160484Sobrien SKIP_WHITESPACE (); 168260484Sobrien } 168360484Sobrien } 168460484Sobrien 168577298Sobrien op_right = operator (&op_chars); 168633965Sjdp 168777298Sobrien know (op_right == O_illegal 168877298Sobrien || op_rank[(int) op_right] <= op_rank[(int) op_left]); 168933965Sjdp know ((int) op_left >= (int) O_multiply 169033965Sjdp && (int) op_left <= (int) O_logical_or); 169133965Sjdp 169277298Sobrien /* input_line_pointer->after right-hand quantity. */ 169377298Sobrien /* left-hand quantity in resultP. */ 169477298Sobrien /* right-hand quantity in right. */ 169577298Sobrien /* operator in op_left. */ 169633965Sjdp 169733965Sjdp if (resultP->X_op == O_big) 169833965Sjdp { 169960484Sobrien if (resultP->X_add_number > 0) 170060484Sobrien as_warn (_("left operand is a bignum; integer 0 assumed")); 170160484Sobrien else 170260484Sobrien as_warn (_("left operand is a float; integer 0 assumed")); 170333965Sjdp resultP->X_op = O_constant; 170433965Sjdp resultP->X_add_number = 0; 170533965Sjdp resultP->X_add_symbol = NULL; 170633965Sjdp resultP->X_op_symbol = NULL; 170733965Sjdp } 170833965Sjdp if (right.X_op == O_big) 170933965Sjdp { 171060484Sobrien if (right.X_add_number > 0) 171160484Sobrien as_warn (_("right operand is a bignum; integer 0 assumed")); 171260484Sobrien else 171360484Sobrien as_warn (_("right operand is a float; integer 0 assumed")); 171433965Sjdp right.X_op = O_constant; 171533965Sjdp right.X_add_number = 0; 171633965Sjdp right.X_add_symbol = NULL; 171733965Sjdp right.X_op_symbol = NULL; 171833965Sjdp } 171933965Sjdp 172033965Sjdp /* Optimize common cases. */ 172177298Sobrien#ifdef md_optimize_expr 172277298Sobrien if (md_optimize_expr (resultP, op_left, &right)) 172377298Sobrien { 172477298Sobrien /* Skip. */ 172577298Sobrien ; 172677298Sobrien } 172777298Sobrien else 172877298Sobrien#endif 172933965Sjdp if (op_left == O_add && right.X_op == O_constant) 173033965Sjdp { 173133965Sjdp /* X + constant. */ 173233965Sjdp resultP->X_add_number += right.X_add_number; 173333965Sjdp } 173433965Sjdp /* This case comes up in PIC code. */ 173533965Sjdp else if (op_left == O_subtract 173633965Sjdp && right.X_op == O_symbol 173733965Sjdp && resultP->X_op == O_symbol 173860484Sobrien && (symbol_get_frag (right.X_add_symbol) 173960484Sobrien == symbol_get_frag (resultP->X_add_symbol)) 1740130561Sobrien && (SEG_NORMAL (rightseg) 1741130561Sobrien || right.X_add_symbol == resultP->X_add_symbol)) 174233965Sjdp { 174333965Sjdp resultP->X_add_number -= right.X_add_number; 174433965Sjdp resultP->X_add_number += (S_GET_VALUE (resultP->X_add_symbol) 174533965Sjdp - S_GET_VALUE (right.X_add_symbol)); 174633965Sjdp resultP->X_op = O_constant; 174733965Sjdp resultP->X_add_symbol = 0; 174833965Sjdp } 174933965Sjdp else if (op_left == O_subtract && right.X_op == O_constant) 175033965Sjdp { 175133965Sjdp /* X - constant. */ 175233965Sjdp resultP->X_add_number -= right.X_add_number; 175333965Sjdp } 175433965Sjdp else if (op_left == O_add && resultP->X_op == O_constant) 175533965Sjdp { 175633965Sjdp /* Constant + X. */ 175733965Sjdp resultP->X_op = right.X_op; 175833965Sjdp resultP->X_add_symbol = right.X_add_symbol; 175933965Sjdp resultP->X_op_symbol = right.X_op_symbol; 176033965Sjdp resultP->X_add_number += right.X_add_number; 176133965Sjdp retval = rightseg; 176233965Sjdp } 176333965Sjdp else if (resultP->X_op == O_constant && right.X_op == O_constant) 176433965Sjdp { 176533965Sjdp /* Constant OP constant. */ 176633965Sjdp offsetT v = right.X_add_number; 176733965Sjdp if (v == 0 && (op_left == O_divide || op_left == O_modulus)) 176833965Sjdp { 176960484Sobrien as_warn (_("division by zero")); 177033965Sjdp v = 1; 177133965Sjdp } 177233965Sjdp switch (op_left) 177333965Sjdp { 177433965Sjdp default: abort (); 177533965Sjdp case O_multiply: resultP->X_add_number *= v; break; 177633965Sjdp case O_divide: resultP->X_add_number /= v; break; 177733965Sjdp case O_modulus: resultP->X_add_number %= v; break; 177833965Sjdp case O_left_shift: resultP->X_add_number <<= v; break; 177933965Sjdp case O_right_shift: 178033965Sjdp /* We always use unsigned shifts, to avoid relying on 1781130561Sobrien characteristics of the compiler used to compile gas. */ 178233965Sjdp resultP->X_add_number = 178333965Sjdp (offsetT) ((valueT) resultP->X_add_number >> (valueT) v); 178433965Sjdp break; 178533965Sjdp case O_bit_inclusive_or: resultP->X_add_number |= v; break; 178633965Sjdp case O_bit_or_not: resultP->X_add_number |= ~v; break; 178733965Sjdp case O_bit_exclusive_or: resultP->X_add_number ^= v; break; 178833965Sjdp case O_bit_and: resultP->X_add_number &= v; break; 178933965Sjdp case O_add: resultP->X_add_number += v; break; 179033965Sjdp case O_subtract: resultP->X_add_number -= v; break; 179133965Sjdp case O_eq: 179233965Sjdp resultP->X_add_number = 179333965Sjdp resultP->X_add_number == v ? ~ (offsetT) 0 : 0; 179433965Sjdp break; 179533965Sjdp case O_ne: 179633965Sjdp resultP->X_add_number = 179733965Sjdp resultP->X_add_number != v ? ~ (offsetT) 0 : 0; 179833965Sjdp break; 179933965Sjdp case O_lt: 180033965Sjdp resultP->X_add_number = 180133965Sjdp resultP->X_add_number < v ? ~ (offsetT) 0 : 0; 180233965Sjdp break; 180333965Sjdp case O_le: 180433965Sjdp resultP->X_add_number = 180533965Sjdp resultP->X_add_number <= v ? ~ (offsetT) 0 : 0; 180633965Sjdp break; 180733965Sjdp case O_ge: 180833965Sjdp resultP->X_add_number = 180933965Sjdp resultP->X_add_number >= v ? ~ (offsetT) 0 : 0; 181033965Sjdp break; 181133965Sjdp case O_gt: 181233965Sjdp resultP->X_add_number = 181333965Sjdp resultP->X_add_number > v ? ~ (offsetT) 0 : 0; 181433965Sjdp break; 181533965Sjdp case O_logical_and: 181633965Sjdp resultP->X_add_number = resultP->X_add_number && v; 181733965Sjdp break; 181833965Sjdp case O_logical_or: 181933965Sjdp resultP->X_add_number = resultP->X_add_number || v; 182033965Sjdp break; 182133965Sjdp } 182233965Sjdp } 182333965Sjdp else if (resultP->X_op == O_symbol 182433965Sjdp && right.X_op == O_symbol 182533965Sjdp && (op_left == O_add 182633965Sjdp || op_left == O_subtract 182733965Sjdp || (resultP->X_add_number == 0 182833965Sjdp && right.X_add_number == 0))) 182933965Sjdp { 183033965Sjdp /* Symbol OP symbol. */ 183133965Sjdp resultP->X_op = op_left; 183233965Sjdp resultP->X_op_symbol = right.X_add_symbol; 183333965Sjdp if (op_left == O_add) 183433965Sjdp resultP->X_add_number += right.X_add_number; 183533965Sjdp else if (op_left == O_subtract) 183689857Sobrien { 183789857Sobrien resultP->X_add_number -= right.X_add_number; 183889857Sobrien if (retval == rightseg && SEG_NORMAL (retval)) 183989857Sobrien { 184089857Sobrien retval = absolute_section; 184189857Sobrien rightseg = absolute_section; 184289857Sobrien } 184389857Sobrien } 184433965Sjdp } 184533965Sjdp else 184633965Sjdp { 184733965Sjdp /* The general case. */ 184833965Sjdp resultP->X_add_symbol = make_expr_symbol (resultP); 184933965Sjdp resultP->X_op_symbol = make_expr_symbol (&right); 185033965Sjdp resultP->X_op = op_left; 185133965Sjdp resultP->X_add_number = 0; 185233965Sjdp resultP->X_unsigned = 1; 185333965Sjdp } 185433965Sjdp 185589857Sobrien if (retval != rightseg) 185689857Sobrien { 185789857Sobrien if (! SEG_NORMAL (retval)) 185889857Sobrien { 185989857Sobrien if (retval != undefined_section || SEG_NORMAL (rightseg)) 186089857Sobrien retval = rightseg; 186189857Sobrien } 186289857Sobrien else if (SEG_NORMAL (rightseg) 186389857Sobrien#ifdef DIFF_EXPR_OK 186489857Sobrien && op_left != O_subtract 186589857Sobrien#endif 186689857Sobrien ) 186789857Sobrien as_bad (_("operation combines symbols in different segments")); 186889857Sobrien } 186989857Sobrien 187033965Sjdp op_left = op_right; 187177298Sobrien } /* While next operator is >= this rank. */ 187233965Sjdp 187333965Sjdp /* The PA port needs this information. */ 187433965Sjdp if (resultP->X_add_symbol) 187560484Sobrien symbol_mark_used (resultP->X_add_symbol); 187633965Sjdp 187733965Sjdp return resultP->X_op == O_constant ? absolute_section : retval; 187833965Sjdp} 187933965Sjdp 188077298Sobrien/* This lives here because it belongs equally in expr.c & read.c. 188177298Sobrien expr.c is just a branch office read.c anyway, and putting it 188277298Sobrien here lessens the crowd at read.c. 188377298Sobrien 188477298Sobrien Assume input_line_pointer is at start of symbol name. 188577298Sobrien Advance input_line_pointer past symbol name. 188677298Sobrien Turn that character into a '\0', returning its former value. 188777298Sobrien This allows a string compare (RMS wants symbol names to be strings) 188877298Sobrien of the symbol name. 188977298Sobrien There will always be a char following symbol name, because all good 189077298Sobrien lines end in end-of-line. */ 189177298Sobrien 189233965Sjdpchar 1893130561Sobrienget_symbol_end (void) 189433965Sjdp{ 189533965Sjdp char c; 189633965Sjdp 189733965Sjdp /* We accept \001 in a name in case this is being called with a 189833965Sjdp constructed string. */ 189933965Sjdp if (is_name_beginner (c = *input_line_pointer++) || c == '\001') 190060484Sobrien { 190160484Sobrien while (is_part_of_name (c = *input_line_pointer++) 190260484Sobrien || c == '\001') 190360484Sobrien ; 190460484Sobrien if (is_name_ender (c)) 190560484Sobrien c = *input_line_pointer++; 190660484Sobrien } 190733965Sjdp *--input_line_pointer = 0; 190833965Sjdp return (c); 190933965Sjdp} 191033965Sjdp 191133965Sjdpunsigned int 1912130561Sobrienget_single_number (void) 191333965Sjdp{ 191433965Sjdp expressionS exp; 191533965Sjdp operand (&exp); 191633965Sjdp return exp.X_add_number; 191733965Sjdp} 1918