Subversion Repositories Kolibri OS

Rev

Rev 5222 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5222 Rev 6324
Line 1... Line 1...
1
/* expr.c -operands, expressions-
1
/* expr.c -operands, expressions-
2
   Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-
 
3
   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011,
-
 
4
   2012 Free Software Foundation, Inc.
2
   Copyright (C) 1987-2015 Free Software Foundation, Inc.
Line 5... Line 3...
5
 
3
 
Line 6... Line 4...
6
   This file is part of GAS, the GNU Assembler.
4
   This file is part of GAS, the GNU Assembler.
7
 
5
 
Line 27... Line 25...
27
 
25
 
Line 28... Line 26...
28
#define min(a, b)       ((a) < (b) ? (a) : (b))
26
#define min(a, b)       ((a) < (b) ? (a) : (b))
29
 
27
 
30
#include "as.h"
-
 
Line 31... Line 28...
31
#include "safe-ctype.h"
28
#include "as.h"
32
#include "obstack.h"
29
#include "safe-ctype.h"
33
 
30
 
34
#ifdef HAVE_LIMITS_H
31
#ifdef HAVE_LIMITS_H
Line 125... Line 122...
125
   the symbol.  */
122
   the symbol.  */
Line 126... Line 123...
126
 
123
 
127
int
124
int
128
expr_symbol_where (symbolS *sym, char **pfile, unsigned int *pline)
125
expr_symbol_where (symbolS *sym, char **pfile, unsigned int *pline)
129
{
126
{
Line 130... Line 127...
130
  register struct expr_symbol_line *l;
127
  struct expr_symbol_line *l;
131
 
128
 
132
  for (l = expr_symbol_lines; l != NULL; l = l->next)
129
  for (l = expr_symbol_lines; l != NULL; l = l->next)
133
    {
130
    {
Line 286... Line 283...
286
#define valuesize 64
283
#define valuesize 64
287
#else /* includes non-bfd case, mostly */
284
#else /* includes non-bfd case, mostly */
288
#define valuesize 32
285
#define valuesize 32
289
#endif
286
#endif
Line -... Line 287...
-
 
287
 
-
 
288
  if (is_end_of_line[(unsigned char) *input_line_pointer])
-
 
289
    {
-
 
290
      expressionP->X_op = O_absent;
-
 
291
      return;
-
 
292
    }
290
 
293
 
291
  if ((NUMBERS_WITH_SUFFIX || flag_m68k_mri) && radix == 0)
294
  if ((NUMBERS_WITH_SUFFIX || flag_m68k_mri) && radix == 0)
292
    {
295
    {
Line 293... Line 296...
293
      int flt = 0;
296
      int flt = 0;
Line 833... Line 836...
833
	  input_line_pointer++;
836
	  input_line_pointer++;
834
	  integer_constant (16, expressionP);
837
	  integer_constant (16, expressionP);
835
	  break;
838
	  break;
Line 836... Line 839...
836
 
839
 
837
	case 'b':
840
	case 'b':
838
	  if (LOCAL_LABELS_FB && ! (flag_m68k_mri || NUMBERS_WITH_SUFFIX))
-
 
839
	    {
-
 
840
	      /* This code used to check for '+' and '-' here, and, in
-
 
841
		 some conditions, fall through to call
-
 
842
		 integer_constant.  However, that didn't make sense,
-
 
843
		 as integer_constant only accepts digits.  */
-
 
844
	      /* Some of our code elsewhere does permit digits greater
-
 
845
		 than the expected base; for consistency, do the same
-
 
846
		 here.  */
841
	  if (LOCAL_LABELS_FB && !flag_m68k_mri
847
	      if (input_line_pointer[1] < '0'
842
	      && input_line_pointer[1] != '0'
848
		  || input_line_pointer[1] > '9')
843
	      && input_line_pointer[1] != '1')
849
		{
844
		{
850
		  /* Parse this as a back reference to label 0.  */
845
		  /* Parse this as a back reference to label 0.  */
851
		  input_line_pointer--;
846
		  input_line_pointer--;
852
		  integer_constant (10, expressionP);
847
		  integer_constant (10, expressionP);
853
		  break;
848
		  break;
854
		}
849
		}
855
	      /* Otherwise, parse this as a binary number.  */
-
 
856
	    }
850
	      /* Otherwise, parse this as a binary number.  */
857
	  /* Fall through.  */
851
	  /* Fall through.  */
-
 
852
	case 'B':
-
 
853
	  if (input_line_pointer[1] == '0'
-
 
854
	      || input_line_pointer[1] == '1')
858
	case 'B':
855
	    {
859
	  input_line_pointer++;
-
 
860
	  if (flag_m68k_mri || NUMBERS_WITH_SUFFIX)
-
 
861
	    goto default_case;
856
	  input_line_pointer++;
862
	  integer_constant (2, expressionP);
857
	      integer_constant (2, expressionP);
-
 
858
	      break;
-
 
859
	    }
-
 
860
	  if (flag_m68k_mri || NUMBERS_WITH_SUFFIX)
-
 
861
	    input_line_pointer++;
Line 863... Line 862...
863
	  break;
862
	    goto default_case;
864
 
863
 
865
	case '0':
864
	case '0':
866
	case '1':
865
	case '1':
Line 876... Line 875...
876
	  break;
875
	  break;
Line 877... Line 876...
877
 
876
 
878
	case 'f':
877
	case 'f':
879
	  if (LOCAL_LABELS_FB)
878
	  if (LOCAL_LABELS_FB)
-
 
879
	    {
-
 
880
	      int is_label = 1;
880
	    {
881
 
881
	      /* If it says "0f" and it could possibly be a floating point
882
	      /* If it says "0f" and it could possibly be a floating point
882
		 number, make it one.  Otherwise, make it a local label,
883
		 number, make it one.  Otherwise, make it a local label,
883
		 and try to deal with parsing the rest later.  */
-
 
884
	      if (!input_line_pointer[1]
884
		 and try to deal with parsing the rest later.  */
885
		  || (is_end_of_line[0xff & input_line_pointer[1]])
885
	      if (!is_end_of_line[(unsigned char) input_line_pointer[1]]
886
		  || strchr (FLT_CHARS, 'f') == NULL)
-
 
887
		goto is_0f_label;
886
		  && strchr (FLT_CHARS, 'f') != NULL)
888
	      {
887
	      {
-
 
888
		char *cp = input_line_pointer + 1;
889
		char *cp = input_line_pointer + 1;
889
 
890
		int r = atof_generic (&cp, ".", EXP_CHARS,
890
		  atof_generic (&cp, ".", EXP_CHARS,
891
				      &generic_floating_point_number);
-
 
892
		switch (r)
-
 
893
		  {
-
 
894
		  case 0:
-
 
895
		  case ERROR_EXPONENT_OVERFLOW:
-
 
896
		    if (*cp == 'f' || *cp == 'b')
-
 
897
		      /* Looks like a difference expression.  */
-
 
898
		      goto is_0f_label;
-
 
899
		    else if (cp == input_line_pointer + 1)
-
 
900
		      /* No characters has been accepted -- looks like
-
 
901
			 end of operand.  */
-
 
902
		      goto is_0f_label;
-
 
903
		    else
-
 
904
		      goto is_0f_float;
-
 
905
		  default:
-
 
906
		    as_fatal (_("expr.c(operand): bad atof_generic return val %d"),
-
 
907
			      r);
-
 
908
		  }
-
 
Line 909... Line 891...
909
	      }
891
				      &generic_floating_point_number);
-
 
892
 
910
 
893
		  /* Was nothing parsed, or does it look like an
-
 
894
		     expression?  */
-
 
895
		  is_label = (cp == input_line_pointer + 1
911
	      /* Okay, now we've sorted it out.  We resume at one of these
896
			      || (cp == input_line_pointer + 2
-
 
897
				  && (cp[-1] == '-' || cp[-1] == '+'))
-
 
898
			      || *cp == 'f'
912
		 two labels, depending on what we've decided we're probably
899
			      || *cp == 'b');
-
 
900
		}
913
		 looking at.  */
901
	      if (is_label)
914
	    is_0f_label:
902
		  {
915
	      input_line_pointer--;
903
	      input_line_pointer--;
916
	      integer_constant (10, expressionP);
-
 
917
	      break;
-
 
918
 
-
 
919
	    is_0f_float:
-
 
920
	      /* Fall through.  */
904
	      integer_constant (10, expressionP);
-
 
905
	      break;
-
 
906
		}
Line 921... Line 907...
921
	      ;
907
	    }
922
	    }
908
	      /* Fall through.  */
923
 
909
 
924
	case 'd':
910
	case 'd':
Line 1022... Line 1008...
1022
	if (expressionP->X_op == O_constant)
1008
	if (expressionP->X_op == O_constant)
1023
	  {
1009
	  {
1024
	    /* input_line_pointer -> char after operand.  */
1010
	    /* input_line_pointer -> char after operand.  */
1025
	    if (c == '-')
1011
	    if (c == '-')
1026
	      {
1012
	      {
-
 
1013
		expressionP->X_add_number
1027
		expressionP->X_add_number = - expressionP->X_add_number;
1014
		  = - (addressT) expressionP->X_add_number;
1028
		/* Notice: '-' may overflow: no warning is given.
1015
		/* Notice: '-' may overflow: no warning is given.
1029
		   This is compatible with other people's
1016
		   This is compatible with other people's
1030
		   assemblers.  Sigh.  */
1017
		   assemblers.  Sigh.  */
1031
		expressionP->X_unsigned = 0;
1018
		expressionP->X_unsigned = 0;
1032
		if (expressionP->X_add_number)
1019
		if (expressionP->X_add_number)
Line 1153... Line 1140...
1153
	    {
1140
	    {
1154
	      char *buf;
1141
	      char *buf;
Line 1155... Line 1142...
1155
 
1142
 
1156
	      ++input_line_pointer;
1143
	      ++input_line_pointer;
1157
	      SKIP_WHITESPACE ();
-
 
1158
	      name = input_line_pointer;
1144
	      SKIP_WHITESPACE ();
Line 1159... Line 1145...
1159
	      c = get_symbol_end ();
1145
	      c = get_symbol_name (& name);
1160
 
1146
 
1161
	      buf = (char *) xmalloc (strlen (name) + 10);
1147
	      buf = (char *) xmalloc (strlen (name) + 10);
1162
	      if (start)
1148
	      if (start)
Line 1169... Line 1155...
1169
	      expressionP->X_op = O_symbol;
1155
	      expressionP->X_op = O_symbol;
1170
	      expressionP->X_add_symbol = symbolP;
1156
	      expressionP->X_add_symbol = symbolP;
1171
	      expressionP->X_add_number = 0;
1157
	      expressionP->X_add_number = 0;
Line 1172... Line 1158...
1172
 
1158
 
1173
	      *input_line_pointer = c;
1159
	      *input_line_pointer = c;
1174
	      SKIP_WHITESPACE ();
1160
	      SKIP_WHITESPACE_AFTER_NAME ();
1175
	      if (*input_line_pointer != ')')
1161
	      if (*input_line_pointer != ')')
1176
		as_bad (_("syntax error in .startof. or .sizeof."));
1162
		as_bad (_("syntax error in .startof. or .sizeof."));
1177
	      else
1163
	      else
1178
		++input_line_pointer;
1164
		++input_line_pointer;
Line 1225... Line 1211...
1225
 
1211
 
1226
    default:
1212
    default:
1227
#if defined(md_need_index_operator) || defined(TC_M68K)
1213
#if defined(md_need_index_operator) || defined(TC_M68K)
1228
    de_fault:
1214
    de_fault:
1229
#endif
1215
#endif
1230
      if (is_name_beginner (c))	/* Here if did not begin with a digit.  */
1216
      if (is_name_beginner (c) || c == '"')	/* Here if did not begin with a digit.  */
1231
	{
1217
	{
1232
	  /* Identifier begins here.
1218
	  /* Identifier begins here.
1233
	     This is kludged for speed, so code is repeated.  */
1219
	     This is kludged for speed, so code is repeated.  */
1234
	isname:
1220
	isname:
1235
	  name = --input_line_pointer;
1221
	  -- input_line_pointer;
Line 1236... Line 1222...
1236
	  c = get_symbol_end ();
1222
	  c = get_symbol_name (&name);
1237
 
1223
 
1238
#ifdef md_operator
1224
#ifdef md_operator
Line 1239... Line 1225...
1239
	  {
1225
	  {
1240
	    operatorT op = md_operator (name, 1, &c);
1226
	    operatorT op = md_operator (name, 1, &c);
1241
 
1227
 
1242
	    switch (op)
1228
	    switch (op)
1243
	      {
1229
	      {
1244
	      case O_uminus:
1230
	      case O_uminus:
1245
		*input_line_pointer = c;
1231
		restore_line_pointer (c);
1246
		c = '-';
1232
		c = '-';
1247
		goto unary;
1233
		goto unary;
1248
	      case O_bit_not:
1234
	      case O_bit_not:
1249
		*input_line_pointer = c;
1235
		restore_line_pointer (c);
1250
		c = '~';
1236
		c = '~';
1251
		goto unary;
1237
		goto unary;
1252
	      case O_logical_not:
1238
	      case O_logical_not:
1253
		*input_line_pointer = c;
1239
		restore_line_pointer (c);
1254
		c = '!';
1240
		c = '!';
1255
		goto unary;
1241
		goto unary;
1256
	      case O_illegal:
1242
	      case O_illegal:
1257
		as_bad (_("invalid use of operator \"%s\""), name);
1243
		as_bad (_("invalid use of operator \"%s\""), name);
1258
		break;
1244
		break;
-
 
1245
	      default:
1259
	      default:
1246
		break;
1260
		break;
1247
	      }
1261
	      }
1248
 
1262
	    if (op != O_absent && op != O_illegal)
1249
	    if (op != O_absent && op != O_illegal)
1263
	      {
1250
	      {
1264
		*input_line_pointer = c;
1251
		restore_line_pointer (c);
1265
		expr (9, expressionP, mode);
1252
		expr (9, expressionP, mode);
1266
		expressionP->X_add_symbol = make_expr_symbol (expressionP);
1253
		expressionP->X_add_symbol = make_expr_symbol (expressionP);
Line 1277... Line 1264...
1277
	     specially in certain contexts.  If a name always has a
1264
	     specially in certain contexts.  If a name always has a
1278
	     specific value, it can often be handled by simply
1265
	     specific value, it can often be handled by simply
1279
	     entering it in the symbol table.  */
1266
	     entering it in the symbol table.  */
1280
	  if (md_parse_name (name, expressionP, mode, &c))
1267
	  if (md_parse_name (name, expressionP, mode, &c))
1281
	    {
1268
	    {
1282
	      *input_line_pointer = c;
1269
	      restore_line_pointer (c);
1283
	      break;
1270
	      break;
1284
	    }
1271
	    }
1285
#endif
1272
#endif
Line 1286... Line 1273...
1286
 
1273
 
Line 1297... Line 1284...
1297
 
1284
 
1298
	      start = (name[1] == 't'
1285
	      start = (name[1] == 't'
Line 1299... Line 1286...
1299
		       || name[1] == 'T');
1286
		       || name[1] == 'T');
1300
 
1287
 
Line 1301... Line -...
1301
	      *input_line_pointer = c;
-
 
1302
	      SKIP_WHITESPACE ();
1288
	      *input_line_pointer = c;
Line 1303... Line 1289...
1303
 
1289
	      SKIP_WHITESPACE_AFTER_NAME ();
1304
	      name = input_line_pointer;
1290
 
1305
	      c = get_symbol_end ();
1291
	      c = get_symbol_name (& name);
1306
 
1292
 
Line 1315... Line 1301...
1315
	      expressionP->X_op = O_symbol;
1301
	      expressionP->X_op = O_symbol;
1316
	      expressionP->X_add_symbol = symbolP;
1302
	      expressionP->X_add_symbol = symbolP;
1317
	      expressionP->X_add_number = 0;
1303
	      expressionP->X_add_number = 0;
Line 1318... Line 1304...
1318
 
1304
 
1319
	      *input_line_pointer = c;
1305
	      *input_line_pointer = c;
1320
	      SKIP_WHITESPACE ();
-
 
1321
 
1306
	      SKIP_WHITESPACE_AFTER_NAME ();
1322
	      break;
1307
	      break;
1323
	    }
1308
	    }
Line 1324... Line 1309...
1324
#endif
1309
#endif
Line 1344... Line 1329...
1344
	    {
1329
	    {
1345
	      expressionP->X_op = O_symbol;
1330
	      expressionP->X_op = O_symbol;
1346
	      expressionP->X_add_symbol = symbolP;
1331
	      expressionP->X_add_symbol = symbolP;
1347
	      expressionP->X_add_number = 0;
1332
	      expressionP->X_add_number = 0;
1348
	    }
1333
	    }
-
 
1334
 
1349
	  *input_line_pointer = c;
1335
	  restore_line_pointer (c);
1350
	}
1336
	}
1351
      else
1337
      else
1352
	{
1338
	{
1353
	  /* Let the target try to parse it.  Success is indicated by changing
1339
	  /* Let the target try to parse it.  Success is indicated by changing
1354
	     the X_op field to something other than O_absent and pointing
1340
	     the X_op field to something other than O_absent and pointing
Line 1600... Line 1586...
1600
    return O_illegal;
1586
    return O_illegal;
Line 1601... Line 1587...
1601
 
1587
 
1602
#ifdef md_operator
1588
#ifdef md_operator
1603
  if (is_name_beginner (c))
1589
  if (is_name_beginner (c))
1604
    {
1590
    {
1605
      char *name = input_line_pointer;
1591
      char *name;
Line 1606... Line 1592...
1606
      char ec = get_symbol_end ();
1592
      char ec = get_symbol_name (& name);
1607
 
1593
 
1608
      ret = md_operator (name, 2, &ec);
1594
      ret = md_operator (name, 2, &ec);
1609
      switch (ret)
1595
      switch (ret)
Line 2329... Line 2315...
2329

2315

2330
/* This lives here because it belongs equally in expr.c & read.c.
2316
/* This lives here because it belongs equally in expr.c & read.c.
2331
   expr.c is just a branch office read.c anyway, and putting it
2317
   expr.c is just a branch office read.c anyway, and putting it
2332
   here lessens the crowd at read.c.
2318
   here lessens the crowd at read.c.
Line 2333... Line 2319...
2333
 
2319
 
-
 
2320
   Assume input_line_pointer is at start of symbol name, or the
2334
   Assume input_line_pointer is at start of symbol name.
2321
    start of a double quote enclosed symbol name.
2335
   Advance input_line_pointer past symbol name.
2322
   Advance input_line_pointer past symbol name.
-
 
2323
   Turn that character into a '\0', returning its former value,
2336
   Turn that character into a '\0', returning its former value.
2324
    which may be the closing double quote.
2337
   This allows a string compare (RMS wants symbol names to be strings)
2325
   This allows a string compare (RMS wants symbol names to be strings)
2338
   of the symbol name.
2326
   of the symbol name.
2339
   There will always be a char following symbol name, because all good
2327
   There will always be a char following symbol name, because all good
Line 2340... Line 2328...
2340
   lines end in end-of-line.  */
2328
   lines end in end-of-line.  */
2341
 
2329
 
2342
char
2330
char
2343
get_symbol_end (void)
2331
get_symbol_name (char ** ilp_return)
Line -... Line 2332...
-
 
2332
{
2344
{
2333
  char c;
2345
  char c;
2334
 
2346
 
2335
  * ilp_return = input_line_pointer;
2347
  /* We accept \001 in a name in case this is being called with a
2336
  /* We accept \001 in a name in case this is being called with a
2348
     constructed string.  */
2337
     constructed string.  */
2349
  if (is_name_beginner (c = *input_line_pointer++) || c == '\001')
2338
  if (is_name_beginner (c = *input_line_pointer++) || c == '\001')
2350
    {
2339
    {
2351
      while (is_part_of_name (c = *input_line_pointer++)
2340
      while (is_part_of_name (c = *input_line_pointer++)
2352
	     || c == '\001')
2341
	     || c == '\001')
2353
	;
2342
	;
-
 
2343
      if (is_name_ender (c))
-
 
2344
	c = *input_line_pointer++;
-
 
2345
    }
-
 
2346
  else if (c == '"')
-
 
2347
    {
-
 
2348
      bfd_boolean backslash_seen;
-
 
2349
 
-
 
2350
      * ilp_return = input_line_pointer;
-
 
2351
      do
-
 
2352
	{
-
 
2353
	  backslash_seen = c == '\\';
-
 
2354
	  c = * input_line_pointer ++;
-
 
2355
	}
-
 
2356
      while (c != 0 && (c != '"' || backslash_seen));
-
 
2357
 
2354
      if (is_name_ender (c))
2358
      if (c == 0)
2355
	c = *input_line_pointer++;
2359
	as_warn (_("missing closing '\"'"));
-
 
2360
    }
-
 
2361
  *--input_line_pointer = 0;
-
 
2362
  return c;
-
 
2363
}
-
 
2364
 
-
 
2365
/* Replace the NUL character pointed to by input_line_pointer
-
 
2366
   with C.  If C is \" then advance past it.  Return the character
-
 
2367
   now pointed to by input_line_pointer.  */
-
 
2368
 
-
 
2369
char
-
 
2370
restore_line_pointer (char c)
-
 
2371
{
-
 
2372
  * input_line_pointer = c;
2356
    }
2373
  if (c == '"')
Line 2357... Line 2374...
2357
  *--input_line_pointer = 0;
2374
    c = * ++ input_line_pointer;
2358
  return (c);
2375
  return c;
2359
}
2376
}