1132718Skan/* RTL reader for GCC. 2132718Skan Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999, 2000, 2001, 2002, 3169689Skan 2003, 2004, 2005 490075Sobrien Free Software Foundation, Inc. 590075Sobrien 690075SobrienThis file is part of GCC. 790075Sobrien 890075SobrienGCC is free software; you can redistribute it and/or modify it under 990075Sobrienthe terms of the GNU General Public License as published by the Free 1090075SobrienSoftware Foundation; either version 2, or (at your option) any later 1190075Sobrienversion. 1290075Sobrien 1390075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1490075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or 1590075SobrienFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1690075Sobrienfor more details. 1790075Sobrien 1890075SobrienYou should have received a copy of the GNU General Public License 1990075Sobrienalong with GCC; see the file COPYING. If not, write to the Free 20169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 21169689Skan02110-1301, USA. */ 2290075Sobrien 23132718Skan#include "bconfig.h" 24169689Skan 25169689Skan/* Disable rtl checking; it conflicts with the macro handling. */ 26169689Skan#undef ENABLE_RTL_CHECKING 27169689Skan 2890075Sobrien#include "system.h" 29132718Skan#include "coretypes.h" 30132718Skan#include "tm.h" 3190075Sobrien#include "rtl.h" 3290075Sobrien#include "obstack.h" 3390075Sobrien#include "hashtab.h" 34169689Skan#include "gensupport.h" 3590075Sobrien 3690075Sobrienstatic htab_t md_constants; 3790075Sobrien 38169689Skan/* One element in a singly-linked list of (integer, string) pairs. */ 39169689Skanstruct map_value { 40169689Skan struct map_value *next; 41169689Skan int number; 42169689Skan const char *string; 43169689Skan}; 44169689Skan 45169689Skan/* Maps a macro or attribute name to a list of (integer, string) pairs. 46169689Skan The integers are mode or code values; the strings are either C conditions 47169689Skan or attribute values. */ 48169689Skanstruct mapping { 49169689Skan /* The name of the macro or attribute. */ 50169689Skan const char *name; 51169689Skan 52169689Skan /* The group (modes or codes) to which the macro or attribute belongs. */ 53169689Skan struct macro_group *group; 54169689Skan 55169689Skan /* Gives a unique number to the attribute or macro. Numbers are 56169689Skan allocated consecutively, starting at 0. */ 57169689Skan int index; 58169689Skan 59169689Skan /* The list of (integer, string) pairs. */ 60169689Skan struct map_value *values; 61169689Skan}; 62169689Skan 63169689Skan/* A structure for abstracting the common parts of code and mode macros. */ 64169689Skanstruct macro_group { 65169689Skan /* Tables of "mapping" structures, one for attributes and one for macros. */ 66169689Skan htab_t attrs, macros; 67169689Skan 68169689Skan /* The number of "real" modes or codes (and by extension, the first 69169689Skan number available for use as a macro placeholder). */ 70169689Skan int num_builtins; 71169689Skan 72169689Skan /* Treat the given string as the name of a standard mode or code and 73169689Skan return its integer value. Use the given file for error reporting. */ 74169689Skan int (*find_builtin) (const char *, FILE *); 75169689Skan 76169689Skan /* Return true if the given rtx uses the given mode or code. */ 77169689Skan bool (*uses_macro_p) (rtx, int); 78169689Skan 79169689Skan /* Make the given rtx use the given mode or code. */ 80169689Skan void (*apply_macro) (rtx, int); 81169689Skan}; 82169689Skan 83169689Skan/* Associates PTR (which can be a string, etc.) with the file location 84169689Skan specified by FILENAME and LINENO. */ 85169689Skanstruct ptr_loc { 86169689Skan const void *ptr; 87169689Skan const char *filename; 88169689Skan int lineno; 89169689Skan}; 90169689Skan 91169689Skan/* A structure used to pass data from read_rtx to apply_macro_traverse 92169689Skan via htab_traverse. */ 93169689Skanstruct macro_traverse_data { 94169689Skan /* Instruction queue. */ 95169689Skan rtx queue; 96169689Skan /* Attributes seen for modes. */ 97169689Skan struct map_value *mode_maps; 98169689Skan /* Input file. */ 99169689Skan FILE *infile; 100169689Skan /* The last unknown attribute used as a mode. */ 101169689Skan const char *unknown_mode_attr; 102169689Skan}; 103169689Skan 104169689Skan/* If CODE is the number of a code macro, return a real rtx code that 105169689Skan has the same format. Return CODE otherwise. */ 106169689Skan#define BELLWETHER_CODE(CODE) \ 107169689Skan ((CODE) < NUM_RTX_CODE ? CODE : bellwether_codes[CODE - NUM_RTX_CODE]) 108169689Skan 109132718Skanstatic void fatal_with_file_and_line (FILE *, const char *, ...) 11090075Sobrien ATTRIBUTE_PRINTF_2 ATTRIBUTE_NORETURN; 111132718Skanstatic void fatal_expected_char (FILE *, int, int) ATTRIBUTE_NORETURN; 112169689Skanstatic int find_mode (const char *, FILE *); 113169689Skanstatic bool uses_mode_macro_p (rtx, int); 114169689Skanstatic void apply_mode_macro (rtx, int); 115169689Skanstatic int find_code (const char *, FILE *); 116169689Skanstatic bool uses_code_macro_p (rtx, int); 117169689Skanstatic void apply_code_macro (rtx, int); 118169689Skanstatic const char *apply_macro_to_string (const char *, struct mapping *, int); 119169689Skanstatic rtx apply_macro_to_rtx (rtx, struct mapping *, int, 120169689Skan struct map_value *, FILE *, const char **); 121169689Skanstatic bool uses_macro_p (rtx, struct mapping *); 122169689Skanstatic const char *add_condition_to_string (const char *, const char *); 123169689Skanstatic void add_condition_to_rtx (rtx, const char *); 124169689Skanstatic int apply_macro_traverse (void **, void *); 125169689Skanstatic struct mapping *add_mapping (struct macro_group *, htab_t t, 126169689Skan const char *, FILE *); 127169689Skanstatic struct map_value **add_map_value (struct map_value **, 128169689Skan int, const char *); 129169689Skanstatic void initialize_macros (void); 130132718Skanstatic void read_name (char *, FILE *); 131169689Skanstatic hashval_t leading_ptr_hash (const void *); 132169689Skanstatic int leading_ptr_eq_p (const void *, const void *); 133169689Skanstatic void set_rtx_ptr_loc (const void *, const char *, int); 134169689Skanstatic const struct ptr_loc *get_rtx_ptr_loc (const void *); 135169689Skanstatic char *read_string (FILE *, int); 136169689Skanstatic char *read_quoted_string (FILE *); 137169689Skanstatic char *read_braced_string (FILE *); 138169689Skanstatic void read_escape (FILE *); 139132718Skanstatic hashval_t def_hash (const void *); 140132718Skanstatic int def_name_eq_p (const void *, const void *); 141132718Skanstatic void read_constants (FILE *infile, char *tmp_char); 142169689Skanstatic void read_conditions (FILE *infile, char *tmp_char); 143132718Skanstatic void validate_const_int (FILE *, const char *); 144169689Skanstatic int find_macro (struct macro_group *, const char *, FILE *); 145169689Skanstatic struct mapping *read_mapping (struct macro_group *, htab_t, FILE *); 146169689Skanstatic void check_code_macro (struct mapping *, FILE *); 147169689Skanstatic rtx read_rtx_1 (FILE *, struct map_value **); 148169689Skanstatic rtx read_rtx_variadic (FILE *, struct map_value **, rtx); 14990075Sobrien 150169689Skan/* The mode and code macro structures. */ 151169689Skanstatic struct macro_group modes, codes; 152169689Skan 153169689Skan/* Index I is the value of BELLWETHER_CODE (I + NUM_RTX_CODE). */ 154169689Skanstatic enum rtx_code *bellwether_codes; 155169689Skan 156169689Skan/* Obstack used for allocating RTL strings. */ 157169689Skanstatic struct obstack string_obstack; 158169689Skan 159169689Skan/* A table of ptr_locs, hashed on the PTR field. */ 160169689Skanstatic htab_t ptr_locs; 161169689Skan 162169689Skan/* An obstack for the above. Plain xmalloc is a bit heavyweight for a 163169689Skan small structure like ptr_loc. */ 164169689Skanstatic struct obstack ptr_loc_obstack; 165169689Skan 166169689Skan/* A hash table of triples (A, B, C), where each of A, B and C is a condition 167169689Skan and A is equivalent to "B && C". This is used to keep track of the source 168169689Skan of conditions that are made up of separate rtx strings (such as the split 169169689Skan condition of a define_insn_and_split). */ 170169689Skanstatic htab_t joined_conditions; 171169689Skan 172169689Skan/* An obstack for allocating joined_conditions entries. */ 173169689Skanstatic struct obstack joined_conditions_obstack; 174169689Skan 17590075Sobrien/* Subroutines of read_rtx. */ 17690075Sobrien 17790075Sobrien/* The current line number for the file. */ 17890075Sobrienint read_rtx_lineno = 1; 17990075Sobrien 180169689Skan/* The filename for error reporting. */ 18190075Sobrienconst char *read_rtx_filename = "<unknown>"; 18290075Sobrien 18390075Sobrienstatic void 184132718Skanfatal_with_file_and_line (FILE *infile, const char *msg, ...) 18590075Sobrien{ 18690075Sobrien char context[64]; 18790075Sobrien size_t i; 18890075Sobrien int c; 189132718Skan va_list ap; 19090075Sobrien 191132718Skan va_start (ap, msg); 19290075Sobrien 19390075Sobrien fprintf (stderr, "%s:%d: ", read_rtx_filename, read_rtx_lineno); 19490075Sobrien vfprintf (stderr, msg, ap); 19590075Sobrien putc ('\n', stderr); 19690075Sobrien 19790075Sobrien /* Gather some following context. */ 19890075Sobrien for (i = 0; i < sizeof (context)-1; ++i) 19990075Sobrien { 20090075Sobrien c = getc (infile); 20190075Sobrien if (c == EOF) 20290075Sobrien break; 20390075Sobrien if (c == '\r' || c == '\n') 20490075Sobrien break; 20590075Sobrien context[i] = c; 20690075Sobrien } 20790075Sobrien context[i] = '\0'; 20890075Sobrien 20990075Sobrien fprintf (stderr, "%s:%d: following context is `%s'\n", 21090075Sobrien read_rtx_filename, read_rtx_lineno, context); 21190075Sobrien 212132718Skan va_end (ap); 21390075Sobrien exit (1); 21490075Sobrien} 21590075Sobrien 21690075Sobrien/* Dump code after printing a message. Used when read_rtx finds 21790075Sobrien invalid data. */ 21890075Sobrien 21990075Sobrienstatic void 220132718Skanfatal_expected_char (FILE *infile, int expected_c, int actual_c) 22190075Sobrien{ 22290075Sobrien fatal_with_file_and_line (infile, "expected character `%c', found `%c'", 22390075Sobrien expected_c, actual_c); 22490075Sobrien} 22590075Sobrien 226169689Skan/* Implementations of the macro_group callbacks for modes. */ 227169689Skan 228169689Skanstatic int 229169689Skanfind_mode (const char *name, FILE *infile) 230169689Skan{ 231169689Skan int i; 232169689Skan 233169689Skan for (i = 0; i < NUM_MACHINE_MODES; i++) 234169689Skan if (strcmp (GET_MODE_NAME (i), name) == 0) 235169689Skan return i; 236169689Skan 237169689Skan fatal_with_file_and_line (infile, "unknown mode `%s'", name); 238169689Skan} 239169689Skan 240169689Skanstatic bool 241169689Skanuses_mode_macro_p (rtx x, int mode) 242169689Skan{ 243169689Skan return (int) GET_MODE (x) == mode; 244169689Skan} 245169689Skan 246169689Skanstatic void 247169689Skanapply_mode_macro (rtx x, int mode) 248169689Skan{ 249169689Skan PUT_MODE (x, (enum machine_mode) mode); 250169689Skan} 251169689Skan 252169689Skan/* Implementations of the macro_group callbacks for codes. */ 253169689Skan 254169689Skanstatic int 255169689Skanfind_code (const char *name, FILE *infile) 256169689Skan{ 257169689Skan int i; 258169689Skan 259169689Skan for (i = 0; i < NUM_RTX_CODE; i++) 260169689Skan if (strcmp (GET_RTX_NAME (i), name) == 0) 261169689Skan return i; 262169689Skan 263169689Skan fatal_with_file_and_line (infile, "unknown rtx code `%s'", name); 264169689Skan} 265169689Skan 266169689Skanstatic bool 267169689Skanuses_code_macro_p (rtx x, int code) 268169689Skan{ 269169689Skan return (int) GET_CODE (x) == code; 270169689Skan} 271169689Skan 272169689Skanstatic void 273169689Skanapply_code_macro (rtx x, int code) 274169689Skan{ 275169689Skan PUT_CODE (x, (enum rtx_code) code); 276169689Skan} 277169689Skan 278169689Skan/* Map a code or mode attribute string P to the underlying string for 279169689Skan MACRO and VALUE. */ 280169689Skan 281169689Skanstatic struct map_value * 282169689Skanmap_attr_string (const char *p, struct mapping *macro, int value) 283169689Skan{ 284169689Skan const char *attr; 285169689Skan struct mapping *m; 286169689Skan struct map_value *v; 287169689Skan 288169689Skan /* If there's a "macro:" prefix, check whether the macro name matches. 289169689Skan Set ATTR to the start of the attribute name. */ 290169689Skan attr = strchr (p, ':'); 291169689Skan if (attr == 0) 292169689Skan attr = p; 293169689Skan else 294169689Skan { 295169689Skan if (strncmp (p, macro->name, attr - p) != 0 296169689Skan || macro->name[attr - p] != 0) 297169689Skan return 0; 298169689Skan attr++; 299169689Skan } 300169689Skan 301169689Skan /* Find the attribute specification. */ 302169689Skan m = (struct mapping *) htab_find (macro->group->attrs, &attr); 303169689Skan if (m == 0) 304169689Skan return 0; 305169689Skan 306169689Skan /* Find the attribute value for VALUE. */ 307169689Skan for (v = m->values; v != 0; v = v->next) 308169689Skan if (v->number == value) 309169689Skan break; 310169689Skan 311169689Skan return v; 312169689Skan} 313169689Skan 314169689Skan/* Given an attribute string used as a machine mode, return an index 315169689Skan to store in the machine mode to be translated by 316169689Skan apply_macro_to_rtx. */ 317169689Skan 318169689Skanstatic unsigned int 319169689Skanmode_attr_index (struct map_value **mode_maps, const char *string) 320169689Skan{ 321169689Skan char *p; 322169689Skan struct map_value *mv; 323169689Skan 324169689Skan /* Copy the attribute string into permanent storage, without the 325169689Skan angle brackets around it. */ 326169689Skan obstack_grow0 (&string_obstack, string + 1, strlen (string) - 2); 327169689Skan p = XOBFINISH (&string_obstack, char *); 328169689Skan 329169689Skan mv = XNEW (struct map_value); 330169689Skan mv->number = *mode_maps == 0 ? 0 : (*mode_maps)->number + 1; 331169689Skan mv->string = p; 332169689Skan mv->next = *mode_maps; 333169689Skan *mode_maps = mv; 334169689Skan 335169689Skan /* We return a code which we can map back into this string: the 336169689Skan number of machine modes + the number of mode macros + the index 337169689Skan we just used. */ 338169689Skan return MAX_MACHINE_MODE + htab_elements (modes.macros) + mv->number; 339169689Skan} 340169689Skan 341169689Skan/* Apply MODE_MAPS to the top level of X, expanding cases where an 342169689Skan attribute is used for a mode. MACRO is the current macro we are 343169689Skan expanding, and VALUE is the value to which we are expanding it. 344169689Skan INFILE is used for error messages. This sets *UNKNOWN to true if 345169689Skan we find a mode attribute which has not yet been defined, and does 346169689Skan not change it otherwise. */ 347169689Skan 348169689Skanstatic void 349169689Skanapply_mode_maps (rtx x, struct map_value *mode_maps, struct mapping *macro, 350169689Skan int value, FILE *infile, const char **unknown) 351169689Skan{ 352169689Skan unsigned int offset; 353169689Skan int indx; 354169689Skan struct map_value *pm; 355169689Skan 356169689Skan offset = MAX_MACHINE_MODE + htab_elements (modes.macros); 357169689Skan if (GET_MODE (x) < offset) 358169689Skan return; 359169689Skan 360169689Skan indx = GET_MODE (x) - offset; 361169689Skan for (pm = mode_maps; pm; pm = pm->next) 362169689Skan { 363169689Skan if (pm->number == indx) 364169689Skan { 365169689Skan struct map_value *v; 366169689Skan 367169689Skan v = map_attr_string (pm->string, macro, value); 368169689Skan if (v) 369169689Skan PUT_MODE (x, (enum machine_mode) find_mode (v->string, infile)); 370169689Skan else 371169689Skan *unknown = pm->string; 372169689Skan return; 373169689Skan } 374169689Skan } 375169689Skan} 376169689Skan 377169689Skan/* Given that MACRO is being expanded as VALUE, apply the appropriate 378169689Skan string substitutions to STRING. Return the new string if any changes 379169689Skan were needed, otherwise return STRING itself. */ 380169689Skan 381169689Skanstatic const char * 382169689Skanapply_macro_to_string (const char *string, struct mapping *macro, int value) 383169689Skan{ 384169689Skan char *base, *copy, *p, *start, *end; 385169689Skan struct map_value *v; 386169689Skan 387169689Skan if (string == 0) 388169689Skan return string; 389169689Skan 390169689Skan base = p = copy = ASTRDUP (string); 391169689Skan while ((start = strchr (p, '<')) && (end = strchr (start, '>'))) 392169689Skan { 393169689Skan p = start + 1; 394169689Skan 395169689Skan *end = 0; 396169689Skan v = map_attr_string (p, macro, value); 397169689Skan *end = '>'; 398169689Skan if (v == 0) 399169689Skan continue; 400169689Skan 401169689Skan /* Add everything between the last copied byte and the '<', 402169689Skan then add in the attribute value. */ 403169689Skan obstack_grow (&string_obstack, base, start - base); 404169689Skan obstack_grow (&string_obstack, v->string, strlen (v->string)); 405169689Skan base = end + 1; 406169689Skan } 407169689Skan if (base != copy) 408169689Skan { 409169689Skan obstack_grow (&string_obstack, base, strlen (base) + 1); 410169689Skan copy = XOBFINISH (&string_obstack, char *); 411169689Skan copy_rtx_ptr_loc (copy, string); 412169689Skan return copy; 413169689Skan } 414169689Skan return string; 415169689Skan} 416169689Skan 417169689Skan/* Return a copy of ORIGINAL in which all uses of MACRO have been 418169689Skan replaced by VALUE. MODE_MAPS holds information about attribute 419169689Skan strings used for modes. INFILE is used for error messages. This 420169689Skan sets *UNKNOWN_MODE_ATTR to the value of an unknown mode attribute, 421169689Skan and does not change it otherwise. */ 422169689Skan 423169689Skanstatic rtx 424169689Skanapply_macro_to_rtx (rtx original, struct mapping *macro, int value, 425169689Skan struct map_value *mode_maps, FILE *infile, 426169689Skan const char **unknown_mode_attr) 427169689Skan{ 428169689Skan struct macro_group *group; 429169689Skan const char *format_ptr; 430169689Skan int i, j; 431169689Skan rtx x; 432169689Skan enum rtx_code bellwether_code; 433169689Skan 434169689Skan if (original == 0) 435169689Skan return original; 436169689Skan 437169689Skan /* Create a shallow copy of ORIGINAL. */ 438169689Skan bellwether_code = BELLWETHER_CODE (GET_CODE (original)); 439169689Skan x = rtx_alloc (bellwether_code); 440169689Skan memcpy (x, original, RTX_CODE_SIZE (bellwether_code)); 441169689Skan 442169689Skan /* Change the mode or code itself. */ 443169689Skan group = macro->group; 444169689Skan if (group->uses_macro_p (x, macro->index + group->num_builtins)) 445169689Skan group->apply_macro (x, value); 446169689Skan 447169689Skan if (mode_maps) 448169689Skan apply_mode_maps (x, mode_maps, macro, value, infile, unknown_mode_attr); 449169689Skan 450169689Skan /* Change each string and recursively change each rtx. */ 451169689Skan format_ptr = GET_RTX_FORMAT (bellwether_code); 452169689Skan for (i = 0; format_ptr[i] != 0; i++) 453169689Skan switch (format_ptr[i]) 454169689Skan { 455169689Skan case 'T': 456169689Skan XTMPL (x, i) = apply_macro_to_string (XTMPL (x, i), macro, value); 457169689Skan break; 458169689Skan 459169689Skan case 'S': 460169689Skan case 's': 461169689Skan XSTR (x, i) = apply_macro_to_string (XSTR (x, i), macro, value); 462169689Skan break; 463169689Skan 464169689Skan case 'e': 465169689Skan XEXP (x, i) = apply_macro_to_rtx (XEXP (x, i), macro, value, 466169689Skan mode_maps, infile, 467169689Skan unknown_mode_attr); 468169689Skan break; 469169689Skan 470169689Skan case 'V': 471169689Skan case 'E': 472169689Skan if (XVEC (original, i)) 473169689Skan { 474169689Skan XVEC (x, i) = rtvec_alloc (XVECLEN (original, i)); 475169689Skan for (j = 0; j < XVECLEN (x, i); j++) 476169689Skan XVECEXP (x, i, j) = apply_macro_to_rtx (XVECEXP (original, i, j), 477169689Skan macro, value, mode_maps, 478169689Skan infile, 479169689Skan unknown_mode_attr); 480169689Skan } 481169689Skan break; 482169689Skan 483169689Skan default: 484169689Skan break; 485169689Skan } 486169689Skan return x; 487169689Skan} 488169689Skan 489169689Skan/* Return true if X (or some subexpression of X) uses macro MACRO. */ 490169689Skan 491169689Skanstatic bool 492169689Skanuses_macro_p (rtx x, struct mapping *macro) 493169689Skan{ 494169689Skan struct macro_group *group; 495169689Skan const char *format_ptr; 496169689Skan int i, j; 497169689Skan 498169689Skan if (x == 0) 499169689Skan return false; 500169689Skan 501169689Skan group = macro->group; 502169689Skan if (group->uses_macro_p (x, macro->index + group->num_builtins)) 503169689Skan return true; 504169689Skan 505169689Skan format_ptr = GET_RTX_FORMAT (BELLWETHER_CODE (GET_CODE (x))); 506169689Skan for (i = 0; format_ptr[i] != 0; i++) 507169689Skan switch (format_ptr[i]) 508169689Skan { 509169689Skan case 'e': 510169689Skan if (uses_macro_p (XEXP (x, i), macro)) 511169689Skan return true; 512169689Skan break; 513169689Skan 514169689Skan case 'V': 515169689Skan case 'E': 516169689Skan if (XVEC (x, i)) 517169689Skan for (j = 0; j < XVECLEN (x, i); j++) 518169689Skan if (uses_macro_p (XVECEXP (x, i, j), macro)) 519169689Skan return true; 520169689Skan break; 521169689Skan 522169689Skan default: 523169689Skan break; 524169689Skan } 525169689Skan return false; 526169689Skan} 527169689Skan 528169689Skan/* Return a condition that must satisfy both ORIGINAL and EXTRA. If ORIGINAL 529169689Skan has the form "&& ..." (as used in define_insn_and_splits), assume that 530169689Skan EXTRA is already satisfied. Empty strings are treated like "true". */ 531169689Skan 532169689Skanstatic const char * 533169689Skanadd_condition_to_string (const char *original, const char *extra) 534169689Skan{ 535169689Skan if (original != 0 && original[0] == '&' && original[1] == '&') 536169689Skan return original; 537169689Skan return join_c_conditions (original, extra); 538169689Skan} 539169689Skan 540169689Skan/* Like add_condition, but applied to all conditions in rtx X. */ 541169689Skan 542169689Skanstatic void 543169689Skanadd_condition_to_rtx (rtx x, const char *extra) 544169689Skan{ 545169689Skan switch (GET_CODE (x)) 546169689Skan { 547169689Skan case DEFINE_INSN: 548169689Skan case DEFINE_EXPAND: 549169689Skan XSTR (x, 2) = add_condition_to_string (XSTR (x, 2), extra); 550169689Skan break; 551169689Skan 552169689Skan case DEFINE_SPLIT: 553169689Skan case DEFINE_PEEPHOLE: 554169689Skan case DEFINE_PEEPHOLE2: 555169689Skan case DEFINE_COND_EXEC: 556169689Skan XSTR (x, 1) = add_condition_to_string (XSTR (x, 1), extra); 557169689Skan break; 558169689Skan 559169689Skan case DEFINE_INSN_AND_SPLIT: 560169689Skan XSTR (x, 2) = add_condition_to_string (XSTR (x, 2), extra); 561169689Skan XSTR (x, 4) = add_condition_to_string (XSTR (x, 4), extra); 562169689Skan break; 563169689Skan 564169689Skan default: 565169689Skan break; 566169689Skan } 567169689Skan} 568169689Skan 569169689Skan/* A htab_traverse callback. Search the EXPR_LIST given by DATA 570169689Skan for rtxes that use the macro in *SLOT. Replace each such rtx 571169689Skan with a list of expansions. */ 572169689Skan 573169689Skanstatic int 574169689Skanapply_macro_traverse (void **slot, void *data) 575169689Skan{ 576169689Skan struct macro_traverse_data *mtd = (struct macro_traverse_data *) data; 577169689Skan struct mapping *macro; 578169689Skan struct map_value *v; 579169689Skan rtx elem, new_elem, original, x; 580169689Skan 581169689Skan macro = (struct mapping *) *slot; 582169689Skan for (elem = mtd->queue; elem != 0; elem = XEXP (elem, 1)) 583169689Skan if (uses_macro_p (XEXP (elem, 0), macro)) 584169689Skan { 585169689Skan /* For each macro we expand, we set UNKNOWN_MODE_ATTR to NULL. 586169689Skan If apply_macro_rtx finds an unknown attribute for a mode, 587169689Skan it will set it to the attribute. We want to know whether 588169689Skan the attribute is unknown after we have expanded all 589169689Skan possible macros, so setting it to NULL here gives us the 590169689Skan right result when the hash table traversal is complete. */ 591169689Skan mtd->unknown_mode_attr = NULL; 592169689Skan 593169689Skan original = XEXP (elem, 0); 594169689Skan for (v = macro->values; v != 0; v = v->next) 595169689Skan { 596169689Skan x = apply_macro_to_rtx (original, macro, v->number, 597169689Skan mtd->mode_maps, mtd->infile, 598169689Skan &mtd->unknown_mode_attr); 599169689Skan add_condition_to_rtx (x, v->string); 600169689Skan if (v != macro->values) 601169689Skan { 602169689Skan /* Insert a new EXPR_LIST node after ELEM and put the 603169689Skan new expansion there. */ 604169689Skan new_elem = rtx_alloc (EXPR_LIST); 605169689Skan XEXP (new_elem, 1) = XEXP (elem, 1); 606169689Skan XEXP (elem, 1) = new_elem; 607169689Skan elem = new_elem; 608169689Skan } 609169689Skan XEXP (elem, 0) = x; 610169689Skan } 611169689Skan } 612169689Skan return 1; 613169689Skan} 614169689Skan 615169689Skan/* Add a new "mapping" structure to hashtable TABLE. NAME is the name 616169689Skan of the mapping, GROUP is the group to which it belongs, and INFILE 617169689Skan is the file that defined the mapping. */ 618169689Skan 619169689Skanstatic struct mapping * 620169689Skanadd_mapping (struct macro_group *group, htab_t table, 621169689Skan const char *name, FILE *infile) 622169689Skan{ 623169689Skan struct mapping *m; 624169689Skan void **slot; 625169689Skan 626169689Skan m = XNEW (struct mapping); 627169689Skan m->name = xstrdup (name); 628169689Skan m->group = group; 629169689Skan m->index = htab_elements (table); 630169689Skan m->values = 0; 631169689Skan 632169689Skan slot = htab_find_slot (table, m, INSERT); 633169689Skan if (*slot != 0) 634169689Skan fatal_with_file_and_line (infile, "`%s' already defined", name); 635169689Skan 636169689Skan *slot = m; 637169689Skan return m; 638169689Skan} 639169689Skan 640169689Skan/* Add the pair (NUMBER, STRING) to a list of map_value structures. 641169689Skan END_PTR points to the current null terminator for the list; return 642169689Skan a pointer the new null terminator. */ 643169689Skan 644169689Skanstatic struct map_value ** 645169689Skanadd_map_value (struct map_value **end_ptr, int number, const char *string) 646169689Skan{ 647169689Skan struct map_value *value; 648169689Skan 649169689Skan value = XNEW (struct map_value); 650169689Skan value->next = 0; 651169689Skan value->number = number; 652169689Skan value->string = string; 653169689Skan 654169689Skan *end_ptr = value; 655169689Skan return &value->next; 656169689Skan} 657169689Skan 658169689Skan/* Do one-time initialization of the mode and code attributes. */ 659169689Skan 660169689Skanstatic void 661169689Skaninitialize_macros (void) 662169689Skan{ 663169689Skan struct mapping *lower, *upper; 664169689Skan struct map_value **lower_ptr, **upper_ptr; 665169689Skan char *copy, *p; 666169689Skan int i; 667169689Skan 668169689Skan modes.attrs = htab_create (13, def_hash, def_name_eq_p, 0); 669169689Skan modes.macros = htab_create (13, def_hash, def_name_eq_p, 0); 670169689Skan modes.num_builtins = MAX_MACHINE_MODE; 671169689Skan modes.find_builtin = find_mode; 672169689Skan modes.uses_macro_p = uses_mode_macro_p; 673169689Skan modes.apply_macro = apply_mode_macro; 674169689Skan 675169689Skan codes.attrs = htab_create (13, def_hash, def_name_eq_p, 0); 676169689Skan codes.macros = htab_create (13, def_hash, def_name_eq_p, 0); 677169689Skan codes.num_builtins = NUM_RTX_CODE; 678169689Skan codes.find_builtin = find_code; 679169689Skan codes.uses_macro_p = uses_code_macro_p; 680169689Skan codes.apply_macro = apply_code_macro; 681169689Skan 682169689Skan lower = add_mapping (&modes, modes.attrs, "mode", 0); 683169689Skan upper = add_mapping (&modes, modes.attrs, "MODE", 0); 684169689Skan lower_ptr = &lower->values; 685169689Skan upper_ptr = &upper->values; 686169689Skan for (i = 0; i < MAX_MACHINE_MODE; i++) 687169689Skan { 688169689Skan copy = xstrdup (GET_MODE_NAME (i)); 689169689Skan for (p = copy; *p != 0; p++) 690169689Skan *p = TOLOWER (*p); 691169689Skan 692169689Skan upper_ptr = add_map_value (upper_ptr, i, GET_MODE_NAME (i)); 693169689Skan lower_ptr = add_map_value (lower_ptr, i, copy); 694169689Skan } 695169689Skan 696169689Skan lower = add_mapping (&codes, codes.attrs, "code", 0); 697169689Skan upper = add_mapping (&codes, codes.attrs, "CODE", 0); 698169689Skan lower_ptr = &lower->values; 699169689Skan upper_ptr = &upper->values; 700169689Skan for (i = 0; i < NUM_RTX_CODE; i++) 701169689Skan { 702169689Skan copy = xstrdup (GET_RTX_NAME (i)); 703169689Skan for (p = copy; *p != 0; p++) 704169689Skan *p = TOUPPER (*p); 705169689Skan 706169689Skan lower_ptr = add_map_value (lower_ptr, i, GET_RTX_NAME (i)); 707169689Skan upper_ptr = add_map_value (upper_ptr, i, copy); 708169689Skan } 709169689Skan} 710169689Skan 711169689Skan/* Return a hash value for the pointer pointed to by DEF. */ 712169689Skan 713169689Skanstatic hashval_t 714169689Skanleading_ptr_hash (const void *def) 715169689Skan{ 716169689Skan return htab_hash_pointer (*(const void *const *) def); 717169689Skan} 718169689Skan 719169689Skan/* Return true if DEF1 and DEF2 are pointers to the same pointer. */ 720169689Skan 721169689Skanstatic int 722169689Skanleading_ptr_eq_p (const void *def1, const void *def2) 723169689Skan{ 724169689Skan return *(const void *const *) def1 == *(const void *const *) def2; 725169689Skan} 726169689Skan 727169689Skan/* Associate PTR with the file position given by FILENAME and LINENO. */ 728169689Skan 729169689Skanstatic void 730169689Skanset_rtx_ptr_loc (const void *ptr, const char *filename, int lineno) 731169689Skan{ 732169689Skan struct ptr_loc *loc; 733169689Skan 734169689Skan loc = (struct ptr_loc *) obstack_alloc (&ptr_loc_obstack, 735169689Skan sizeof (struct ptr_loc)); 736169689Skan loc->ptr = ptr; 737169689Skan loc->filename = filename; 738169689Skan loc->lineno = lineno; 739169689Skan *htab_find_slot (ptr_locs, loc, INSERT) = loc; 740169689Skan} 741169689Skan 742169689Skan/* Return the position associated with pointer PTR. Return null if no 743169689Skan position was set. */ 744169689Skan 745169689Skanstatic const struct ptr_loc * 746169689Skanget_rtx_ptr_loc (const void *ptr) 747169689Skan{ 748169689Skan return (const struct ptr_loc *) htab_find (ptr_locs, &ptr); 749169689Skan} 750169689Skan 751169689Skan/* Associate NEW_PTR with the same file position as OLD_PTR. */ 752169689Skan 753169689Skanvoid 754169689Skancopy_rtx_ptr_loc (const void *new_ptr, const void *old_ptr) 755169689Skan{ 756169689Skan const struct ptr_loc *loc = get_rtx_ptr_loc (old_ptr); 757169689Skan if (loc != 0) 758169689Skan set_rtx_ptr_loc (new_ptr, loc->filename, loc->lineno); 759169689Skan} 760169689Skan 761169689Skan/* If PTR is associated with a known file position, print a #line 762169689Skan directive for it. */ 763169689Skan 764169689Skanvoid 765169689Skanprint_rtx_ptr_loc (const void *ptr) 766169689Skan{ 767169689Skan const struct ptr_loc *loc = get_rtx_ptr_loc (ptr); 768169689Skan if (loc != 0) 769169689Skan printf ("#line %d \"%s\"\n", loc->lineno, loc->filename); 770169689Skan} 771169689Skan 772169689Skan/* Return a condition that satisfies both COND1 and COND2. Either string 773169689Skan may be null or empty. */ 774169689Skan 775169689Skanconst char * 776169689Skanjoin_c_conditions (const char *cond1, const char *cond2) 777169689Skan{ 778169689Skan char *result; 779169689Skan const void **entry; 780169689Skan 781169689Skan if (cond1 == 0 || cond1[0] == 0) 782169689Skan return cond2; 783169689Skan 784169689Skan if (cond2 == 0 || cond2[0] == 0) 785169689Skan return cond1; 786169689Skan 787169689Skan result = concat ("(", cond1, ") && (", cond2, ")", NULL); 788169689Skan obstack_ptr_grow (&joined_conditions_obstack, result); 789169689Skan obstack_ptr_grow (&joined_conditions_obstack, cond1); 790169689Skan obstack_ptr_grow (&joined_conditions_obstack, cond2); 791169689Skan entry = XOBFINISH (&joined_conditions_obstack, const void **); 792169689Skan *htab_find_slot (joined_conditions, entry, INSERT) = entry; 793169689Skan return result; 794169689Skan} 795169689Skan 796169689Skan/* Print condition COND, wrapped in brackets. If COND was created by 797169689Skan join_c_conditions, recursively invoke this function for the original 798169689Skan conditions and join the result with "&&". Otherwise print a #line 799169689Skan directive for COND if its original file position is known. */ 800169689Skan 801169689Skanvoid 802169689Skanprint_c_condition (const char *cond) 803169689Skan{ 804169689Skan const char **halves = (const char **) htab_find (joined_conditions, &cond); 805169689Skan if (halves != 0) 806169689Skan { 807169689Skan printf ("("); 808169689Skan print_c_condition (halves[1]); 809169689Skan printf (" && "); 810169689Skan print_c_condition (halves[2]); 811169689Skan printf (")"); 812169689Skan } 813169689Skan else 814169689Skan { 815169689Skan putc ('\n', stdout); 816169689Skan print_rtx_ptr_loc (cond); 817169689Skan printf ("(%s)", cond); 818169689Skan } 819169689Skan} 820169689Skan 82190075Sobrien/* Read chars from INFILE until a non-whitespace char 82290075Sobrien and return that. Comments, both Lisp style and C style, 82390075Sobrien are treated as whitespace. 82490075Sobrien Tools such as genflags use this function. */ 82590075Sobrien 82690075Sobrienint 827132718Skanread_skip_spaces (FILE *infile) 82890075Sobrien{ 82990075Sobrien int c; 83090075Sobrien 83190075Sobrien while (1) 83290075Sobrien { 83390075Sobrien c = getc (infile); 83490075Sobrien switch (c) 83590075Sobrien { 83690075Sobrien case '\n': 83790075Sobrien read_rtx_lineno++; 83890075Sobrien break; 83990075Sobrien 84090075Sobrien case ' ': case '\t': case '\f': case '\r': 84190075Sobrien break; 84290075Sobrien 84390075Sobrien case ';': 84490075Sobrien do 84590075Sobrien c = getc (infile); 84690075Sobrien while (c != '\n' && c != EOF); 84790075Sobrien read_rtx_lineno++; 84890075Sobrien break; 84990075Sobrien 85090075Sobrien case '/': 85190075Sobrien { 85290075Sobrien int prevc; 85390075Sobrien c = getc (infile); 85490075Sobrien if (c != '*') 85590075Sobrien fatal_expected_char (infile, '*', c); 85690075Sobrien 85790075Sobrien prevc = 0; 85890075Sobrien while ((c = getc (infile)) && c != EOF) 85990075Sobrien { 86090075Sobrien if (c == '\n') 86190075Sobrien read_rtx_lineno++; 86290075Sobrien else if (prevc == '*' && c == '/') 86390075Sobrien break; 86490075Sobrien prevc = c; 86590075Sobrien } 86690075Sobrien } 86790075Sobrien break; 86890075Sobrien 86990075Sobrien default: 87090075Sobrien return c; 87190075Sobrien } 87290075Sobrien } 87390075Sobrien} 87490075Sobrien 87590075Sobrien/* Read an rtx code name into the buffer STR[]. 87690075Sobrien It is terminated by any of the punctuation chars of rtx printed syntax. */ 87790075Sobrien 87890075Sobrienstatic void 879132718Skanread_name (char *str, FILE *infile) 88090075Sobrien{ 88190075Sobrien char *p; 88290075Sobrien int c; 88390075Sobrien 88490075Sobrien c = read_skip_spaces (infile); 88590075Sobrien 88690075Sobrien p = str; 88790075Sobrien while (1) 88890075Sobrien { 889169689Skan if (c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\r' || c == EOF) 89090075Sobrien break; 89190075Sobrien if (c == ':' || c == ')' || c == ']' || c == '"' || c == '/' 89290075Sobrien || c == '(' || c == '[') 89390075Sobrien { 89490075Sobrien ungetc (c, infile); 89590075Sobrien break; 89690075Sobrien } 89790075Sobrien *p++ = c; 89890075Sobrien c = getc (infile); 89990075Sobrien } 90090075Sobrien if (p == str) 90190075Sobrien fatal_with_file_and_line (infile, "missing name or number"); 90290075Sobrien if (c == '\n') 90390075Sobrien read_rtx_lineno++; 90490075Sobrien 90590075Sobrien *p = 0; 90690075Sobrien 90790075Sobrien if (md_constants) 90890075Sobrien { 90990075Sobrien /* Do constant expansion. */ 91090075Sobrien struct md_constant *def; 91190075Sobrien 91290075Sobrien p = str; 91390075Sobrien do 91490075Sobrien { 91590075Sobrien struct md_constant tmp_def; 91690075Sobrien 91790075Sobrien tmp_def.name = p; 918169689Skan def = (struct md_constant *) htab_find (md_constants, &tmp_def); 91990075Sobrien if (def) 92090075Sobrien p = def->value; 92190075Sobrien } while (def); 92290075Sobrien if (p != str) 92390075Sobrien strcpy (str, p); 92490075Sobrien } 92590075Sobrien} 92690075Sobrien 92790075Sobrien/* Subroutine of the string readers. Handles backslash escapes. 92890075Sobrien Caller has read the backslash, but not placed it into the obstack. */ 92990075Sobrienstatic void 930169689Skanread_escape (FILE *infile) 93190075Sobrien{ 93290075Sobrien int c = getc (infile); 93390075Sobrien 93490075Sobrien switch (c) 93590075Sobrien { 93690075Sobrien /* Backslash-newline is replaced by nothing, as in C. */ 93790075Sobrien case '\n': 93890075Sobrien read_rtx_lineno++; 93990075Sobrien return; 94090075Sobrien 94190075Sobrien /* \" \' \\ are replaced by the second character. */ 94290075Sobrien case '\\': 94390075Sobrien case '"': 94490075Sobrien case '\'': 94590075Sobrien break; 94690075Sobrien 94790075Sobrien /* Standard C string escapes: 94890075Sobrien \a \b \f \n \r \t \v 94990075Sobrien \[0-7] \x 95090075Sobrien all are passed through to the output string unmolested. 95190075Sobrien In normal use these wind up in a string constant processed 95290075Sobrien by the C compiler, which will translate them appropriately. 95390075Sobrien We do not bother checking that \[0-7] are followed by up to 95490075Sobrien two octal digits, or that \x is followed by N hex digits. 95590075Sobrien \? \u \U are left out because they are not in traditional C. */ 95690075Sobrien case 'a': case 'b': case 'f': case 'n': case 'r': case 't': case 'v': 95790075Sobrien case '0': case '1': case '2': case '3': case '4': case '5': case '6': 95890075Sobrien case '7': case 'x': 959169689Skan obstack_1grow (&string_obstack, '\\'); 96090075Sobrien break; 96190075Sobrien 96290075Sobrien /* \; makes stuff for a C string constant containing 96390075Sobrien newline and tab. */ 96490075Sobrien case ';': 965169689Skan obstack_grow (&string_obstack, "\\n\\t", 4); 96690075Sobrien return; 96790075Sobrien 96890075Sobrien /* pass anything else through, but issue a warning. */ 96990075Sobrien default: 97090075Sobrien fprintf (stderr, "%s:%d: warning: unrecognized escape \\%c\n", 97190075Sobrien read_rtx_filename, read_rtx_lineno, c); 972169689Skan obstack_1grow (&string_obstack, '\\'); 97390075Sobrien break; 97490075Sobrien } 97590075Sobrien 976169689Skan obstack_1grow (&string_obstack, c); 97790075Sobrien} 97890075Sobrien 979117395Skan 98090075Sobrien/* Read a double-quoted string onto the obstack. Caller has scanned 98190075Sobrien the leading quote. */ 98290075Sobrienstatic char * 983169689Skanread_quoted_string (FILE *infile) 98490075Sobrien{ 98590075Sobrien int c; 98690075Sobrien 98790075Sobrien while (1) 98890075Sobrien { 98990075Sobrien c = getc (infile); /* Read the string */ 99090075Sobrien if (c == '\n') 99190075Sobrien read_rtx_lineno++; 99290075Sobrien else if (c == '\\') 99390075Sobrien { 994169689Skan read_escape (infile); 99590075Sobrien continue; 99690075Sobrien } 997169689Skan else if (c == '"' || c == EOF) 99890075Sobrien break; 99990075Sobrien 1000169689Skan obstack_1grow (&string_obstack, c); 100190075Sobrien } 100290075Sobrien 1003169689Skan obstack_1grow (&string_obstack, 0); 1004169689Skan return XOBFINISH (&string_obstack, char *); 100590075Sobrien} 100690075Sobrien 1007169689Skan/* Read a braced string (a la Tcl) onto the string obstack. Caller 1008169689Skan has scanned the leading brace. Note that unlike quoted strings, 100990075Sobrien the outermost braces _are_ included in the string constant. */ 101090075Sobrienstatic char * 1011169689Skanread_braced_string (FILE *infile) 101290075Sobrien{ 101390075Sobrien int c; 101490075Sobrien int brace_depth = 1; /* caller-processed */ 1015132718Skan unsigned long starting_read_rtx_lineno = read_rtx_lineno; 101690075Sobrien 1017169689Skan obstack_1grow (&string_obstack, '{'); 101890075Sobrien while (brace_depth) 101990075Sobrien { 102090075Sobrien c = getc (infile); /* Read the string */ 1021132718Skan 102290075Sobrien if (c == '\n') 102390075Sobrien read_rtx_lineno++; 102490075Sobrien else if (c == '{') 102590075Sobrien brace_depth++; 102690075Sobrien else if (c == '}') 102790075Sobrien brace_depth--; 102890075Sobrien else if (c == '\\') 102990075Sobrien { 1030169689Skan read_escape (infile); 103190075Sobrien continue; 103290075Sobrien } 1033132718Skan else if (c == EOF) 1034132718Skan fatal_with_file_and_line 1035132718Skan (infile, "missing closing } for opening brace on line %lu", 1036132718Skan starting_read_rtx_lineno); 103790075Sobrien 1038169689Skan obstack_1grow (&string_obstack, c); 103990075Sobrien } 1040117395Skan 1041169689Skan obstack_1grow (&string_obstack, 0); 1042169689Skan return XOBFINISH (&string_obstack, char *); 104390075Sobrien} 104490075Sobrien 104590075Sobrien/* Read some kind of string constant. This is the high-level routine 104690075Sobrien used by read_rtx. It handles surrounding parentheses, leading star, 104790075Sobrien and dispatch to the appropriate string constant reader. */ 104890075Sobrien 104990075Sobrienstatic char * 1050169689Skanread_string (FILE *infile, int star_if_braced) 105190075Sobrien{ 105290075Sobrien char *stringbuf; 105390075Sobrien int saw_paren = 0; 1054169689Skan int c, old_lineno; 105590075Sobrien 105690075Sobrien c = read_skip_spaces (infile); 105790075Sobrien if (c == '(') 105890075Sobrien { 105990075Sobrien saw_paren = 1; 106090075Sobrien c = read_skip_spaces (infile); 106190075Sobrien } 106290075Sobrien 1063169689Skan old_lineno = read_rtx_lineno; 106490075Sobrien if (c == '"') 1065169689Skan stringbuf = read_quoted_string (infile); 106690075Sobrien else if (c == '{') 106790075Sobrien { 106890075Sobrien if (star_if_braced) 1069169689Skan obstack_1grow (&string_obstack, '*'); 1070169689Skan stringbuf = read_braced_string (infile); 107190075Sobrien } 107290075Sobrien else 107390075Sobrien fatal_with_file_and_line (infile, "expected `\"' or `{', found `%c'", c); 1074117395Skan 107590075Sobrien if (saw_paren) 107690075Sobrien { 107790075Sobrien c = read_skip_spaces (infile); 107890075Sobrien if (c != ')') 107990075Sobrien fatal_expected_char (infile, ')', c); 108090075Sobrien } 108190075Sobrien 1082169689Skan set_rtx_ptr_loc (stringbuf, read_rtx_filename, old_lineno); 108390075Sobrien return stringbuf; 108490075Sobrien} 108590075Sobrien 108690075Sobrien/* Provide a version of a function to read a long long if the system does 108790075Sobrien not provide one. */ 108890075Sobrien#if HOST_BITS_PER_WIDE_INT > HOST_BITS_PER_LONG && !defined(HAVE_ATOLL) && !defined(HAVE_ATOQ) 1089132718SkanHOST_WIDE_INT atoll (const char *); 1090132718Skan 109190075SobrienHOST_WIDE_INT 1092132718Skanatoll (const char *p) 109390075Sobrien{ 109490075Sobrien int neg = 0; 109590075Sobrien HOST_WIDE_INT tmp_wide; 109690075Sobrien 109790075Sobrien while (ISSPACE (*p)) 109890075Sobrien p++; 109990075Sobrien if (*p == '-') 110090075Sobrien neg = 1, p++; 110190075Sobrien else if (*p == '+') 110290075Sobrien p++; 110390075Sobrien 110490075Sobrien tmp_wide = 0; 110590075Sobrien while (ISDIGIT (*p)) 110690075Sobrien { 110790075Sobrien HOST_WIDE_INT new_wide = tmp_wide*10 + (*p - '0'); 110890075Sobrien if (new_wide < tmp_wide) 110990075Sobrien { 111090075Sobrien /* Return INT_MAX equiv on overflow. */ 111190075Sobrien tmp_wide = (~(unsigned HOST_WIDE_INT) 0) >> 1; 111290075Sobrien break; 111390075Sobrien } 111490075Sobrien tmp_wide = new_wide; 111590075Sobrien p++; 111690075Sobrien } 111790075Sobrien 111890075Sobrien if (neg) 111990075Sobrien tmp_wide = -tmp_wide; 112090075Sobrien return tmp_wide; 112190075Sobrien} 112290075Sobrien#endif 112390075Sobrien 1124169689Skan/* Given an object that starts with a char * name field, return a hash 1125169689Skan code for its name. */ 1126117395Skanstatic hashval_t 1127132718Skandef_hash (const void *def) 112890075Sobrien{ 112990075Sobrien unsigned result, i; 1130169689Skan const char *string = *(const char *const *) def; 113190075Sobrien 1132169689Skan for (result = i = 0; *string++ != '\0'; i++) 113390075Sobrien result += ((unsigned char) *string << (i % CHAR_BIT)); 113490075Sobrien return result; 113590075Sobrien} 113690075Sobrien 1137169689Skan/* Given two objects that start with char * name fields, return true if 1138169689Skan they have the same name. */ 113990075Sobrienstatic int 1140132718Skandef_name_eq_p (const void *def1, const void *def2) 114190075Sobrien{ 1142169689Skan return ! strcmp (*(const char *const *) def1, 1143169689Skan *(const char *const *) def2); 114490075Sobrien} 114590075Sobrien 114690075Sobrien/* INFILE is a FILE pointer to read text from. TMP_CHAR is a buffer suitable 114790075Sobrien to read a name or number into. Process a define_constants directive, 114890075Sobrien starting with the optional space after the "define_constants". */ 114990075Sobrienstatic void 1150132718Skanread_constants (FILE *infile, char *tmp_char) 115190075Sobrien{ 115290075Sobrien int c; 115390075Sobrien htab_t defs; 115490075Sobrien 115590075Sobrien c = read_skip_spaces (infile); 115690075Sobrien if (c != '[') 115790075Sobrien fatal_expected_char (infile, '[', c); 115890075Sobrien defs = md_constants; 115990075Sobrien if (! defs) 116090075Sobrien defs = htab_create (32, def_hash, def_name_eq_p, (htab_del) 0); 116190075Sobrien /* Disable constant expansion during definition processing. */ 116290075Sobrien md_constants = 0; 116390075Sobrien while ( (c = read_skip_spaces (infile)) != ']') 116490075Sobrien { 116590075Sobrien struct md_constant *def; 116690075Sobrien void **entry_ptr; 116790075Sobrien 116890075Sobrien if (c != '(') 116990075Sobrien fatal_expected_char (infile, '(', c); 1170169689Skan def = XNEW (struct md_constant); 117190075Sobrien def->name = tmp_char; 117290075Sobrien read_name (tmp_char, infile); 1173169689Skan entry_ptr = htab_find_slot (defs, def, INSERT); 117490075Sobrien if (! *entry_ptr) 117590075Sobrien def->name = xstrdup (tmp_char); 117690075Sobrien c = read_skip_spaces (infile); 117790075Sobrien ungetc (c, infile); 117890075Sobrien read_name (tmp_char, infile); 117990075Sobrien if (! *entry_ptr) 118090075Sobrien { 118190075Sobrien def->value = xstrdup (tmp_char); 118290075Sobrien *entry_ptr = def; 118390075Sobrien } 118490075Sobrien else 118590075Sobrien { 1186169689Skan def = (struct md_constant *) *entry_ptr; 118790075Sobrien if (strcmp (def->value, tmp_char)) 118890075Sobrien fatal_with_file_and_line (infile, 118990075Sobrien "redefinition of %s, was %s, now %s", 119090075Sobrien def->name, def->value, tmp_char); 119190075Sobrien } 119290075Sobrien c = read_skip_spaces (infile); 119390075Sobrien if (c != ')') 119490075Sobrien fatal_expected_char (infile, ')', c); 119590075Sobrien } 119690075Sobrien md_constants = defs; 119790075Sobrien c = read_skip_spaces (infile); 119890075Sobrien if (c != ')') 119990075Sobrien fatal_expected_char (infile, ')', c); 120090075Sobrien} 120190075Sobrien 120290075Sobrien/* For every constant definition, call CALLBACK with two arguments: 120390075Sobrien a pointer a pointer to the constant definition and INFO. 120490075Sobrien Stops when CALLBACK returns zero. */ 120590075Sobrienvoid 1206132718Skantraverse_md_constants (htab_trav callback, void *info) 120790075Sobrien{ 120890075Sobrien if (md_constants) 120990075Sobrien htab_traverse (md_constants, callback, info); 121090075Sobrien} 1211169689Skan 1212169689Skan/* INFILE is a FILE pointer to read text from. TMP_CHAR is a buffer 1213169689Skan suitable to read a name or number into. Process a 1214169689Skan define_conditions directive, starting with the optional space after 1215169689Skan the "define_conditions". The directive looks like this: 121690075Sobrien 1217169689Skan (define_conditions [ 1218169689Skan (number "string") 1219169689Skan (number "string") 1220169689Skan ... 1221169689Skan ]) 1222169689Skan 1223169689Skan It's not intended to appear in machine descriptions. It is 1224169689Skan generated by (the program generated by) genconditions.c, and 1225169689Skan slipped in at the beginning of the sequence of MD files read by 1226169689Skan most of the other generators. */ 122790075Sobrienstatic void 1228169689Skanread_conditions (FILE *infile, char *tmp_char) 1229169689Skan{ 1230169689Skan int c; 1231169689Skan 1232169689Skan c = read_skip_spaces (infile); 1233169689Skan if (c != '[') 1234169689Skan fatal_expected_char (infile, '[', c); 1235169689Skan 1236169689Skan while ( (c = read_skip_spaces (infile)) != ']') 1237169689Skan { 1238169689Skan char *expr; 1239169689Skan int value; 1240169689Skan 1241169689Skan if (c != '(') 1242169689Skan fatal_expected_char (infile, '(', c); 1243169689Skan 1244169689Skan read_name (tmp_char, infile); 1245169689Skan validate_const_int (infile, tmp_char); 1246169689Skan value = atoi (tmp_char); 1247169689Skan 1248169689Skan c = read_skip_spaces (infile); 1249169689Skan if (c != '"') 1250169689Skan fatal_expected_char (infile, '"', c); 1251169689Skan expr = read_quoted_string (infile); 1252169689Skan 1253169689Skan c = read_skip_spaces (infile); 1254169689Skan if (c != ')') 1255169689Skan fatal_expected_char (infile, ')', c); 1256169689Skan 1257169689Skan add_c_test (expr, value); 1258169689Skan } 1259169689Skan c = read_skip_spaces (infile); 1260169689Skan if (c != ')') 1261169689Skan fatal_expected_char (infile, ')', c); 1262169689Skan} 1263169689Skan 1264169689Skanstatic void 1265132718Skanvalidate_const_int (FILE *infile, const char *string) 126690075Sobrien{ 126790075Sobrien const char *cp; 126890075Sobrien int valid = 1; 126990075Sobrien 127090075Sobrien cp = string; 127190075Sobrien while (*cp && ISSPACE (*cp)) 127290075Sobrien cp++; 127390075Sobrien if (*cp == '-' || *cp == '+') 127490075Sobrien cp++; 127590075Sobrien if (*cp == 0) 127690075Sobrien valid = 0; 127790075Sobrien for (; *cp; cp++) 127890075Sobrien if (! ISDIGIT (*cp)) 127990075Sobrien valid = 0; 128090075Sobrien if (!valid) 128190075Sobrien fatal_with_file_and_line (infile, "invalid decimal constant \"%s\"\n", string); 128290075Sobrien} 128390075Sobrien 1284169689Skan/* Search GROUP for a mode or code called NAME and return its numerical 1285169689Skan identifier. INFILE is the file that contained NAME. */ 1286169689Skan 1287169689Skanstatic int 1288169689Skanfind_macro (struct macro_group *group, const char *name, FILE *infile) 1289169689Skan{ 1290169689Skan struct mapping *m; 1291169689Skan 1292169689Skan m = (struct mapping *) htab_find (group->macros, &name); 1293169689Skan if (m != 0) 1294169689Skan return m->index + group->num_builtins; 1295169689Skan return group->find_builtin (name, infile); 1296169689Skan} 1297169689Skan 1298169689Skan/* Finish reading a declaration of the form: 1299169689Skan 1300169689Skan (define... <name> [<value1> ... <valuen>]) 1301169689Skan 1302169689Skan from INFILE, where each <valuei> is either a bare symbol name or a 1303169689Skan "(<name> <string>)" pair. The "(define..." part has already been read. 1304169689Skan 1305169689Skan Represent the declaration as a "mapping" structure; add it to TABLE 1306169689Skan (which belongs to GROUP) and return it. */ 1307169689Skan 1308169689Skanstatic struct mapping * 1309169689Skanread_mapping (struct macro_group *group, htab_t table, FILE *infile) 1310169689Skan{ 1311169689Skan char tmp_char[256]; 1312169689Skan struct mapping *m; 1313169689Skan struct map_value **end_ptr; 1314169689Skan const char *string; 1315169689Skan int number, c; 1316169689Skan 1317169689Skan /* Read the mapping name and create a structure for it. */ 1318169689Skan read_name (tmp_char, infile); 1319169689Skan m = add_mapping (group, table, tmp_char, infile); 1320169689Skan 1321169689Skan c = read_skip_spaces (infile); 1322169689Skan if (c != '[') 1323169689Skan fatal_expected_char (infile, '[', c); 1324169689Skan 1325169689Skan /* Read each value. */ 1326169689Skan end_ptr = &m->values; 1327169689Skan c = read_skip_spaces (infile); 1328169689Skan do 1329169689Skan { 1330169689Skan if (c != '(') 1331169689Skan { 1332169689Skan /* A bare symbol name that is implicitly paired to an 1333169689Skan empty string. */ 1334169689Skan ungetc (c, infile); 1335169689Skan read_name (tmp_char, infile); 1336169689Skan string = ""; 1337169689Skan } 1338169689Skan else 1339169689Skan { 1340169689Skan /* A "(name string)" pair. */ 1341169689Skan read_name (tmp_char, infile); 1342169689Skan string = read_string (infile, false); 1343169689Skan c = read_skip_spaces (infile); 1344169689Skan if (c != ')') 1345169689Skan fatal_expected_char (infile, ')', c); 1346169689Skan } 1347169689Skan number = group->find_builtin (tmp_char, infile); 1348169689Skan end_ptr = add_map_value (end_ptr, number, string); 1349169689Skan c = read_skip_spaces (infile); 1350169689Skan } 1351169689Skan while (c != ']'); 1352169689Skan 1353169689Skan c = read_skip_spaces (infile); 1354169689Skan if (c != ')') 1355169689Skan fatal_expected_char (infile, ')', c); 1356169689Skan 1357169689Skan return m; 1358169689Skan} 1359169689Skan 1360169689Skan/* Check newly-created code macro MACRO to see whether every code has the 1361169689Skan same format. Initialize the macro's entry in bellwether_codes. */ 1362169689Skan 1363169689Skanstatic void 1364169689Skancheck_code_macro (struct mapping *macro, FILE *infile) 1365169689Skan{ 1366169689Skan struct map_value *v; 1367169689Skan enum rtx_code bellwether; 1368169689Skan 1369169689Skan bellwether = (enum rtx_code) macro->values->number; 1370169689Skan for (v = macro->values->next; v != 0; v = v->next) 1371169689Skan if (strcmp (GET_RTX_FORMAT (bellwether), GET_RTX_FORMAT (v->number)) != 0) 1372169689Skan fatal_with_file_and_line (infile, "code macro `%s' combines " 1373169689Skan "different rtx formats", macro->name); 1374169689Skan 1375169689Skan bellwether_codes = XRESIZEVEC (enum rtx_code, bellwether_codes, 1376169689Skan macro->index + 1); 1377169689Skan bellwether_codes[macro->index] = bellwether; 1378169689Skan} 1379169689Skan 1380169689Skan/* Read an rtx in printed representation from INFILE and store its 1381169689Skan core representation in *X. Also store the line number of the 1382169689Skan opening '(' in *LINENO. Return true on success or false if the 1383169689Skan end of file has been reached. 1384169689Skan 138590075Sobrien read_rtx is not used in the compiler proper, but rather in 138690075Sobrien the utilities gen*.c that construct C code from machine descriptions. */ 138790075Sobrien 1388169689Skanbool 1389169689Skanread_rtx (FILE *infile, rtx *x, int *lineno) 139090075Sobrien{ 1391169689Skan static rtx queue_head, queue_next; 1392169689Skan static int queue_lineno; 1393169689Skan int c; 1394169689Skan 1395169689Skan /* Do one-time initialization. */ 1396169689Skan if (queue_head == 0) 1397169689Skan { 1398169689Skan initialize_macros (); 1399169689Skan obstack_init (&string_obstack); 1400169689Skan queue_head = rtx_alloc (EXPR_LIST); 1401169689Skan ptr_locs = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0); 1402169689Skan obstack_init (&ptr_loc_obstack); 1403169689Skan joined_conditions = htab_create (161, leading_ptr_hash, 1404169689Skan leading_ptr_eq_p, 0); 1405169689Skan obstack_init (&joined_conditions_obstack); 1406169689Skan } 1407169689Skan 1408169689Skan if (queue_next == 0) 1409169689Skan { 1410169689Skan struct map_value *mode_maps; 1411169689Skan struct macro_traverse_data mtd; 1412169689Skan rtx from_file; 1413169689Skan 1414169689Skan c = read_skip_spaces (infile); 1415169689Skan if (c == EOF) 1416169689Skan return false; 1417169689Skan ungetc (c, infile); 1418169689Skan 1419169689Skan queue_lineno = read_rtx_lineno; 1420169689Skan mode_maps = 0; 1421169689Skan from_file = read_rtx_1 (infile, &mode_maps); 1422169689Skan if (from_file == 0) 1423169689Skan return false; /* This confuses a top level (nil) with end of 1424169689Skan file, but a top level (nil) would have 1425169689Skan crashed our caller anyway. */ 1426169689Skan 1427169689Skan queue_next = queue_head; 1428169689Skan XEXP (queue_next, 0) = from_file; 1429169689Skan XEXP (queue_next, 1) = 0; 1430169689Skan 1431169689Skan mtd.queue = queue_next; 1432169689Skan mtd.mode_maps = mode_maps; 1433169689Skan mtd.infile = infile; 1434169689Skan mtd.unknown_mode_attr = mode_maps ? mode_maps->string : NULL; 1435169689Skan htab_traverse (modes.macros, apply_macro_traverse, &mtd); 1436169689Skan htab_traverse (codes.macros, apply_macro_traverse, &mtd); 1437169689Skan if (mtd.unknown_mode_attr) 1438169689Skan fatal_with_file_and_line (infile, 1439169689Skan "undefined attribute '%s' used for mode", 1440169689Skan mtd.unknown_mode_attr); 1441169689Skan } 1442169689Skan 1443169689Skan *x = XEXP (queue_next, 0); 1444169689Skan *lineno = queue_lineno; 1445169689Skan queue_next = XEXP (queue_next, 1); 1446169689Skan 1447169689Skan return true; 1448169689Skan} 1449169689Skan 1450169689Skan/* Subroutine of read_rtx that reads one construct from INFILE but 1451169689Skan doesn't apply any macros. */ 1452169689Skan 1453169689Skanstatic rtx 1454169689Skanread_rtx_1 (FILE *infile, struct map_value **mode_maps) 1455169689Skan{ 1456169689Skan int i; 1457169689Skan RTX_CODE real_code, bellwether_code; 145890075Sobrien const char *format_ptr; 145990075Sobrien /* tmp_char is a buffer used for reading decimal integers 146090075Sobrien and names of rtx types and machine modes. 146190075Sobrien Therefore, 256 must be enough. */ 146290075Sobrien char tmp_char[256]; 146390075Sobrien rtx return_rtx; 146490075Sobrien int c; 146590075Sobrien int tmp_int; 146690075Sobrien HOST_WIDE_INT tmp_wide; 146790075Sobrien 146890075Sobrien /* Linked list structure for making RTXs: */ 146990075Sobrien struct rtx_list 147090075Sobrien { 147190075Sobrien struct rtx_list *next; 147290075Sobrien rtx value; /* Value of this node. */ 147390075Sobrien }; 147490075Sobrien 1475169689Skan again: 1476169689Skan c = read_skip_spaces (infile); /* Should be open paren. */ 147790075Sobrien 1478169689Skan if (c == EOF) 1479169689Skan return 0; 1480169689Skan 148190075Sobrien if (c != '(') 148290075Sobrien fatal_expected_char (infile, '(', c); 148390075Sobrien 148490075Sobrien read_name (tmp_char, infile); 1485169689Skan if (strcmp (tmp_char, "nil") == 0) 148690075Sobrien { 1487169689Skan /* (nil) stands for an expression that isn't there. */ 1488169689Skan c = read_skip_spaces (infile); 1489169689Skan if (c != ')') 1490169689Skan fatal_expected_char (infile, ')', c); 1491169689Skan return 0; 1492169689Skan } 1493169689Skan if (strcmp (tmp_char, "define_constants") == 0) 1494169689Skan { 149590075Sobrien read_constants (infile, tmp_char); 149690075Sobrien goto again; 149790075Sobrien } 1498169689Skan if (strcmp (tmp_char, "define_conditions") == 0) 149990075Sobrien { 1500169689Skan read_conditions (infile, tmp_char); 1501169689Skan goto again; 150290075Sobrien } 1503169689Skan if (strcmp (tmp_char, "define_mode_attr") == 0) 1504169689Skan { 1505169689Skan read_mapping (&modes, modes.attrs, infile); 1506169689Skan goto again; 1507169689Skan } 1508169689Skan if (strcmp (tmp_char, "define_mode_macro") == 0) 1509169689Skan { 1510169689Skan read_mapping (&modes, modes.macros, infile); 1511169689Skan goto again; 1512169689Skan } 1513169689Skan if (strcmp (tmp_char, "define_code_attr") == 0) 1514169689Skan { 1515169689Skan read_mapping (&codes, codes.attrs, infile); 1516169689Skan goto again; 1517169689Skan } 1518169689Skan if (strcmp (tmp_char, "define_code_macro") == 0) 1519169689Skan { 1520169689Skan check_code_macro (read_mapping (&codes, codes.macros, infile), infile); 1521169689Skan goto again; 1522169689Skan } 1523169689Skan real_code = (enum rtx_code) find_macro (&codes, tmp_char, infile); 1524169689Skan bellwether_code = BELLWETHER_CODE (real_code); 152590075Sobrien 152690075Sobrien /* If we end up with an insn expression then we free this space below. */ 1527169689Skan return_rtx = rtx_alloc (bellwether_code); 1528169689Skan format_ptr = GET_RTX_FORMAT (bellwether_code); 1529169689Skan PUT_CODE (return_rtx, real_code); 153090075Sobrien 153190075Sobrien /* If what follows is `: mode ', read it and 153290075Sobrien store the mode in the rtx. */ 153390075Sobrien 153490075Sobrien i = read_skip_spaces (infile); 153590075Sobrien if (i == ':') 153690075Sobrien { 1537169689Skan unsigned int mode; 1538169689Skan 153990075Sobrien read_name (tmp_char, infile); 1540169689Skan if (tmp_char[0] != '<' || tmp_char[strlen (tmp_char) - 1] != '>') 1541169689Skan mode = find_macro (&modes, tmp_char, infile); 1542169689Skan else 1543169689Skan mode = mode_attr_index (mode_maps, tmp_char); 1544169689Skan PUT_MODE (return_rtx, (enum machine_mode) mode); 1545169689Skan if (GET_MODE (return_rtx) != mode) 1546169689Skan fatal_with_file_and_line (infile, "mode too large"); 154790075Sobrien } 154890075Sobrien else 154990075Sobrien ungetc (i, infile); 155090075Sobrien 1551169689Skan for (i = 0; format_ptr[i] != 0; i++) 1552169689Skan switch (format_ptr[i]) 155390075Sobrien { 155490075Sobrien /* 0 means a field for internal use only. 155590075Sobrien Don't expect it to be present in the input. */ 155690075Sobrien case '0': 155790075Sobrien break; 155890075Sobrien 155990075Sobrien case 'e': 156090075Sobrien case 'u': 1561169689Skan XEXP (return_rtx, i) = read_rtx_1 (infile, mode_maps); 156290075Sobrien break; 156390075Sobrien 156490075Sobrien case 'V': 156590075Sobrien /* 'V' is an optional vector: if a closeparen follows, 156690075Sobrien just store NULL for this element. */ 156790075Sobrien c = read_skip_spaces (infile); 156890075Sobrien ungetc (c, infile); 156990075Sobrien if (c == ')') 157090075Sobrien { 157190075Sobrien XVEC (return_rtx, i) = 0; 157290075Sobrien break; 1573117395Skan } 157490075Sobrien /* Now process the vector. */ 157590075Sobrien 157690075Sobrien case 'E': 157790075Sobrien { 157890075Sobrien /* Obstack to store scratch vector in. */ 157990075Sobrien struct obstack vector_stack; 158090075Sobrien int list_counter = 0; 158190075Sobrien rtvec return_vec = NULL_RTVEC; 158290075Sobrien 158390075Sobrien c = read_skip_spaces (infile); 158490075Sobrien if (c != '[') 158590075Sobrien fatal_expected_char (infile, '[', c); 158690075Sobrien 1587169689Skan /* Add expressions to a list, while keeping a count. */ 158890075Sobrien obstack_init (&vector_stack); 158990075Sobrien while ((c = read_skip_spaces (infile)) && c != ']') 159090075Sobrien { 159190075Sobrien ungetc (c, infile); 159290075Sobrien list_counter++; 1593169689Skan obstack_ptr_grow (&vector_stack, read_rtx_1 (infile, mode_maps)); 159490075Sobrien } 159590075Sobrien if (list_counter > 0) 159690075Sobrien { 159790075Sobrien return_vec = rtvec_alloc (list_counter); 159890075Sobrien memcpy (&return_vec->elem[0], obstack_finish (&vector_stack), 159990075Sobrien list_counter * sizeof (rtx)); 160090075Sobrien } 1601169689Skan else if (format_ptr[i] == 'E') 1602169689Skan fatal_with_file_and_line (infile, 1603169689Skan "vector must have at least one element"); 160490075Sobrien XVEC (return_rtx, i) = return_vec; 160590075Sobrien obstack_free (&vector_stack, NULL); 160690075Sobrien /* close bracket gotten */ 160790075Sobrien } 160890075Sobrien break; 160990075Sobrien 161090075Sobrien case 'S': 161190075Sobrien case 'T': 161290075Sobrien case 's': 161390075Sobrien { 161490075Sobrien char *stringbuf; 1615169689Skan int star_if_braced; 161690075Sobrien 1617169689Skan c = read_skip_spaces (infile); 1618169689Skan ungetc (c, infile); 1619169689Skan if (c == ')') 1620169689Skan { 1621169689Skan /* 'S' fields are optional and should be NULL if no string 1622169689Skan was given. Also allow normal 's' and 'T' strings to be 1623169689Skan omitted, treating them in the same way as empty strings. */ 1624169689Skan XSTR (return_rtx, i) = (format_ptr[i] == 'S' ? NULL : ""); 1625169689Skan break; 1626169689Skan } 1627169689Skan 162890075Sobrien /* The output template slot of a DEFINE_INSN, 162990075Sobrien DEFINE_INSN_AND_SPLIT, or DEFINE_PEEPHOLE automatically 163090075Sobrien gets a star inserted as its first character, if it is 163190075Sobrien written with a brace block instead of a string constant. */ 1632169689Skan star_if_braced = (format_ptr[i] == 'T'); 1633117395Skan 1634169689Skan stringbuf = read_string (infile, star_if_braced); 163590075Sobrien 163690075Sobrien /* For insn patterns, we want to provide a default name 163790075Sobrien based on the file and line, like "*foo.md:12", if the 163890075Sobrien given name is blank. These are only for define_insn and 163990075Sobrien define_insn_and_split, to aid debugging. */ 164090075Sobrien if (*stringbuf == '\0' 164190075Sobrien && i == 0 164290075Sobrien && (GET_CODE (return_rtx) == DEFINE_INSN 164390075Sobrien || GET_CODE (return_rtx) == DEFINE_INSN_AND_SPLIT)) 164490075Sobrien { 164590075Sobrien char line_name[20]; 164690075Sobrien const char *fn = (read_rtx_filename ? read_rtx_filename : "rtx"); 164790075Sobrien const char *slash; 164890075Sobrien for (slash = fn; *slash; slash ++) 164990075Sobrien if (*slash == '/' || *slash == '\\' || *slash == ':') 165090075Sobrien fn = slash + 1; 1651169689Skan obstack_1grow (&string_obstack, '*'); 1652169689Skan obstack_grow (&string_obstack, fn, strlen (fn)); 165390075Sobrien sprintf (line_name, ":%d", read_rtx_lineno); 1654169689Skan obstack_grow (&string_obstack, line_name, strlen (line_name)+1); 1655169689Skan stringbuf = XOBFINISH (&string_obstack, char *); 165690075Sobrien } 165790075Sobrien 165890075Sobrien if (star_if_braced) 165990075Sobrien XTMPL (return_rtx, i) = stringbuf; 166090075Sobrien else 166190075Sobrien XSTR (return_rtx, i) = stringbuf; 166290075Sobrien } 166390075Sobrien break; 166490075Sobrien 166590075Sobrien case 'w': 166690075Sobrien read_name (tmp_char, infile); 166790075Sobrien validate_const_int (infile, tmp_char); 166890075Sobrien#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT 166990075Sobrien tmp_wide = atoi (tmp_char); 167090075Sobrien#else 167190075Sobrien#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG 167290075Sobrien tmp_wide = atol (tmp_char); 167390075Sobrien#else 167490075Sobrien /* Prefer atoll over atoq, since the former is in the ISO C99 standard. 167590075Sobrien But prefer not to use our hand-rolled function above either. */ 167690075Sobrien#if defined(HAVE_ATOLL) || !defined(HAVE_ATOQ) 167790075Sobrien tmp_wide = atoll (tmp_char); 167890075Sobrien#else 167990075Sobrien tmp_wide = atoq (tmp_char); 168090075Sobrien#endif 168190075Sobrien#endif 168290075Sobrien#endif 168390075Sobrien XWINT (return_rtx, i) = tmp_wide; 168490075Sobrien break; 168590075Sobrien 168690075Sobrien case 'i': 168790075Sobrien case 'n': 168890075Sobrien read_name (tmp_char, infile); 168990075Sobrien validate_const_int (infile, tmp_char); 169090075Sobrien tmp_int = atoi (tmp_char); 169190075Sobrien XINT (return_rtx, i) = tmp_int; 169290075Sobrien break; 169390075Sobrien 169490075Sobrien default: 1695169689Skan gcc_unreachable (); 169690075Sobrien } 169790075Sobrien 169890075Sobrien c = read_skip_spaces (infile); 169990075Sobrien if (c != ')') 1700169689Skan { 1701169689Skan /* Syntactic sugar for AND and IOR, allowing Lisp-like 1702169689Skan arbitrary number of arguments for them. */ 1703169689Skan if (c == '(' && (GET_CODE (return_rtx) == AND 1704169689Skan || GET_CODE (return_rtx) == IOR)) 1705169689Skan return read_rtx_variadic (infile, mode_maps, return_rtx); 1706169689Skan else 1707169689Skan fatal_expected_char (infile, ')', c); 1708169689Skan } 170990075Sobrien 171090075Sobrien return return_rtx; 171190075Sobrien} 1712169689Skan 1713169689Skan/* Mutually recursive subroutine of read_rtx which reads 1714169689Skan (thing x1 x2 x3 ...) and produces RTL as if 1715169689Skan (thing x1 (thing x2 (thing x3 ...))) had been written. 1716169689Skan When called, FORM is (thing x1 x2), and the file position 1717169689Skan is just past the leading parenthesis of x3. Only works 1718169689Skan for THINGs which are dyadic expressions, e.g. AND, IOR. */ 1719169689Skanstatic rtx 1720169689Skanread_rtx_variadic (FILE *infile, struct map_value **mode_maps, rtx form) 1721169689Skan{ 1722169689Skan char c = '('; 1723169689Skan rtx p = form, q; 1724169689Skan 1725169689Skan do 1726169689Skan { 1727169689Skan ungetc (c, infile); 1728169689Skan 1729169689Skan q = rtx_alloc (GET_CODE (p)); 1730169689Skan PUT_MODE (q, GET_MODE (p)); 1731169689Skan 1732169689Skan XEXP (q, 0) = XEXP (p, 1); 1733169689Skan XEXP (q, 1) = read_rtx_1 (infile, mode_maps); 1734169689Skan 1735169689Skan XEXP (p, 1) = q; 1736169689Skan p = q; 1737169689Skan c = read_skip_spaces (infile); 1738169689Skan } 1739169689Skan while (c == '('); 1740169689Skan 1741169689Skan if (c != ')') 1742169689Skan fatal_expected_char (infile, ')', c); 1743169689Skan 1744169689Skan return form; 1745169689Skan} 1746