- register int i, j, list_counter;
- RTX_CODE tmp_code;
- register const char *format_ptr;
- /* tmp_char is a buffer used for reading decimal integers
- and names of rtx types and machine modes.
- Therefore, 256 must be enough. */
- char tmp_char[256];
- rtx return_rtx;
- register int c;
- int tmp_int;
- HOST_WIDE_INT tmp_wide;
-
- /* Linked list structure for making RTXs: */
- struct rtx_list
- {
- struct rtx_list *next;
- rtx value; /* Value of this node. */
- };
-
- c = read_skip_spaces (infile); /* Should be open paren. */
- if (c != '(')
- fatal_expected_char (infile, '(', c);
-
- read_name (tmp_char, infile);
-
- tmp_code = UNKNOWN;
-
- for (i = 0; i < NUM_RTX_CODE; i++)
- if (! strcmp (tmp_char, GET_RTX_NAME (i)))
- {
- tmp_code = (RTX_CODE) i; /* get value for name */
- break;
- }
-
- if (tmp_code == UNKNOWN)
- fatal_with_file_and_line (infile, "unknown rtx code `%s'", tmp_char);
-
- /* (NIL) stands for an expression that isn't there. */
- if (tmp_code == NIL)
- {
- /* Discard the closeparen. */
- while ((c = getc (infile)) && c != ')')
- ;
-
- return 0;
- }
-
- /* If we end up with an insn expression then we free this space below. */
- return_rtx = rtx_alloc (tmp_code);
- format_ptr = GET_RTX_FORMAT (GET_CODE (return_rtx));
-
- /* If what follows is `: mode ', read it and
- store the mode in the rtx. */
-
- i = read_skip_spaces (infile);
- if (i == ':')
- {
- read_name (tmp_char, infile);
- for (j = 0; j < NUM_MACHINE_MODES; j++)
- if (! strcmp (GET_MODE_NAME (j), tmp_char))
- break;
-
- if (j == MAX_MACHINE_MODE)
- fatal_with_file_and_line (infile, "unknown mode `%s'", tmp_char);
-
- PUT_MODE (return_rtx, (enum machine_mode) j);
- }
- else
- ungetc (i, infile);
-
- for (i = 0; i < GET_RTX_LENGTH (GET_CODE (return_rtx)); i++)
- switch (*format_ptr++)
- {
- /* 0 means a field for internal use only.
- Don't expect it to be present in the input. */
- case '0':
- break;
-
- case 'e':
- case 'u':
- XEXP (return_rtx, i) = read_rtx (infile);
- break;
-
- case 'V':
- /* 'V' is an optional vector: if a closeparen follows,
- just store NULL for this element. */
- c = read_skip_spaces (infile);
- ungetc (c, infile);
- if (c == ')')
- {
- XVEC (return_rtx, i) = 0;
- break;
- }
- /* Now process the vector. */
-
- case 'E':
- {
- register struct rtx_list *next_rtx, *rtx_list_link;
- struct rtx_list *list_rtx = NULL;
-
- c = read_skip_spaces (infile);
- if (c != '[')
- fatal_expected_char (infile, '[', c);
-
- /* add expressions to a list, while keeping a count */
- next_rtx = NULL;
- list_counter = 0;
- while ((c = read_skip_spaces (infile)) && c != ']')
- {
- ungetc (c, infile);
- list_counter++;
- rtx_list_link = (struct rtx_list *)
- alloca (sizeof (struct rtx_list));
- rtx_list_link->value = read_rtx (infile);
- if (next_rtx == 0)
- list_rtx = rtx_list_link;
- else
- next_rtx->next = rtx_list_link;
- next_rtx = rtx_list_link;
- rtx_list_link->next = 0;
- }
- /* get vector length and allocate it */
- XVEC (return_rtx, i) = (list_counter
- ? rtvec_alloc (list_counter) : NULL_RTVEC);
- if (list_counter > 0)
- {
- next_rtx = list_rtx;
- for (j = 0; j < list_counter; j++,
- next_rtx = next_rtx->next)
- XVECEXP (return_rtx, i, j) = next_rtx->value;
- }
- /* close bracket gotten */
- }
- break;
-
- case 'S':
- /* 'S' is an optional string: if a closeparen follows,
- just store NULL for this element. */
- c = read_skip_spaces (infile);
- ungetc (c, infile);
- if (c == ')')
- {
- XSTR (return_rtx, i) = 0;
- break;
- }
-
- case 's':
- {
- int saw_paren = 0;
- register char *stringbuf;
-
- c = read_skip_spaces (infile);
- if (c == '(')
- {
- saw_paren = 1;
- c = read_skip_spaces (infile);
- }
- if (c != '"')
- fatal_expected_char (infile, '"', c);
-
- while (1)
- {
- c = getc (infile); /* Read the string */
- if (c == '\n')
- read_rtx_lineno++;
- if (c == '\\')
- {
- c = getc (infile); /* Read the string */
- /* \; makes stuff for a C string constant containing
- newline and tab. */
- if (c == ';')
- {
- obstack_grow (rtl_obstack, "\\n\\t", 4);
- continue;
- }
- if (c == '\n')
- read_rtx_lineno++;
- }
- else if (c == '"')
- break;
-
- obstack_1grow (rtl_obstack, c);
- }
-
- obstack_1grow (rtl_obstack, 0);
- stringbuf = (char *) obstack_finish (rtl_obstack);
-
- if (saw_paren)
- {
- c = read_skip_spaces (infile);
- if (c != ')')
- fatal_expected_char (infile, ')', c);
- }
- XSTR (return_rtx, i) = stringbuf;
- }
- break;
-
- case 'w':
- read_name (tmp_char, infile);
-#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
- tmp_wide = atoi (tmp_char);
-#else
-#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
- tmp_wide = atol (tmp_char);
-#else
- /* Prefer atoll over atoq, since the former is in the ISO C9X draft.
- But prefer not to use our hand-rolled function above either. */
-#if defined(HAVE_ATOLL) || !defined(HAVE_ATOQ)
- tmp_wide = atoll (tmp_char);
-#else
- tmp_wide = atoq (tmp_char);
-#endif
-#endif
-#endif
- XWINT (return_rtx, i) = tmp_wide;
- break;
-
- case 'i':
- case 'n':
- read_name (tmp_char, infile);
- tmp_int = atoi (tmp_char);
- XINT (return_rtx, i) = tmp_int;
- break;
-
- default:
- fprintf (stderr,
- "switch format wrong in rtl.read_rtx(). format was: %c.\n",
- format_ptr[-1]);
- fprintf (stderr, "\tfile position: %ld\n", ftell (infile));
- abort ();
- }
-
- c = read_skip_spaces (infile);
- if (c != ')')
- fatal_expected_char (infile, ')', c);
-
- return return_rtx;