📄 rtl.c
字号:
dump_and_abort (expected_c, actual_c, infile) int expected_c, actual_c; FILE *infile;{ int c, i; if (expected_c >= 0) fprintf (stderr, "Expected character %c. Found character %c.", expected_c, actual_c); fprintf (stderr, " At file position: %ld\n", ftell (infile)); fprintf (stderr, "Following characters are:\n\t"); for (i = 0; i < 200; i++) { c = getc (infile); if (EOF == c) break; putc (c, stderr); } fprintf (stderr, "Aborting.\n"); abort ();}/* Read chars from INFILE until a non-whitespace char and return that. Comments, both Lisp style and C style, are treated as whitespace. Tools such as genflags use this function. */intread_skip_spaces (infile) FILE *infile;{ register int c; while (c = getc (infile)) { if (c == ' ' || c == '\n' || c == '\t' || c == '\f') ; else if (c == ';') { while ((c = getc (infile)) && c != '\n') ; } else if (c == '/') { register int prevc; c = getc (infile); if (c != '*') dump_and_abort ('*', c, infile); prevc = 0; while (c = getc (infile)) { if (prevc == '*' && c == '/') break; prevc = c; } } else break; } return c;}/* Read an rtx code name into the buffer STR[]. It is terminated by any of the punctuation chars of rtx printed syntax. */static voidread_name (str, infile) char *str; FILE *infile;{ register char *p; register int c; c = read_skip_spaces(infile); p = str; while (1) { if (c == ' ' || c == '\n' || c == '\t' || c == '\f') break; if (c == ':' || c == ')' || c == ']' || c == '"' || c == '/' || c == '(' || c == '[') { ungetc (c, infile); break; } *p++ = c; c = getc (infile); } if (p == str) { fprintf (stderr, "missing name or number"); dump_and_abort (-1, -1, infile); } *p = 0;}/* Read an rtx in printed representation from INFILE and return an actual rtx in core constructed accordingly. read_rtx is not used in the compiler proper, but rather in the utilities gen*.c that construct C code from machine descriptions. */rtxread_rtx (infile) FILE *infile;{ register int i, j, list_counter; RTX_CODE tmp_code; register 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 != '(') dump_and_abort ('(', c, infile); read_name (tmp_char, infile); tmp_code = UNKNOWN; for (i=0; i < NUM_RTX_CODE; i++) /* @@ might speed this search up */ { if (!(strcmp (tmp_char, GET_RTX_NAME (i)))) { tmp_code = (RTX_CODE) i; /* get value for name */ break; } } if (tmp_code == UNKNOWN) { fprintf (stderr, "Unknown rtx read in rtl.read_rtx(). Code name was %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; } return_rtx = rtx_alloc (tmp_code); /* if we end up with an insn expression then we free this space below. */ 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 == ':') { register int k; read_name (tmp_char, infile); for (k = 0; k < NUM_MACHINE_MODES; k++) if (!strcmp (GET_MODE_NAME (k), tmp_char)) break; PUT_MODE (return_rtx, (enum machine_mode) k ); } 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; c = read_skip_spaces (infile); if (c != '[') dump_and_abort ('[', c, infile); /* 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; int stringbufsize; c = read_skip_spaces (infile); if (c == '(') { saw_paren = 1; c = read_skip_spaces (infile); } if (c != '"') dump_and_abort ('"', c, infile); while (1) { c = getc (infile); /* Read the string */ 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; } } 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 != ')') dump_and_abort (')', c, infile); } 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 tmp_wide = atol (tmp_char);#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 != ')') dump_and_abort (')', c, infile); return return_rtx;}/* This is called once per compilation, before any rtx's are constructed. It initializes the vector `rtx_length', the extra CC modes, if any, and computes certain commonly-used modes. */voidinit_rtl (){ int min_class_size[(int) MAX_MODE_CLASS]; enum machine_mode mode; int i; for (i = 0; i < NUM_RTX_CODE; i++) rtx_length[i] = strlen (rtx_format[i]); /* Make CONST_DOUBLE bigger, if real values are bigger than it normally expects to have room for. Note that REAL_VALUE_TYPE is not defined by default, since tree.h is not included. But the default dfn as `double' would do no harm. */#ifdef REAL_VALUE_TYPE i = sizeof (REAL_VALUE_TYPE) / sizeof (rtunion) + 2; if (rtx_length[(int) CONST_DOUBLE] < i) { char *s = (char *) xmalloc (i + 1); rtx_length[(int) CONST_DOUBLE] = i; rtx_format[(int) CONST_DOUBLE] = s; *s++ = 'e'; *s++ = '0'; /* Set the GET_RTX_FORMAT of CONST_DOUBLE to a string of as many `i's as we now have elements. */ for (i = 0; i < rtx_length[(int) CONST_DOUBLE]; i++) *s++ = 'w'; *s++ = 0; }#endif#ifdef EXTRA_CC_MODES for (i = (int) CCmode + 1; i < (int) MAX_MACHINE_MODE; i++) { mode_class[i] = MODE_CC; mode_size[i] = mode_size[(int) CCmode]; mode_unit_size[i] = mode_unit_size[(int) CCmode]; mode_wider_mode[i - 1] = (enum machine_mode) i; mode_wider_mode[i] = VOIDmode; }#endif /* Find the narrowest mode for each class and compute the word and byte modes. */ for (i = 0; i < (int) MAX_MODE_CLASS; i++) min_class_size[i] = 1000; byte_mode = VOIDmode; word_mode = VOIDmode; for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE; mode = (enum machine_mode) ((int) mode + 1)) { if (GET_MODE_SIZE (mode) < min_class_size[(int) GET_MODE_CLASS (mode)]) { class_narrowest_mode[(int) GET_MODE_CLASS (mode)] = mode; min_class_size[(int) GET_MODE_CLASS (mode)] = GET_MODE_SIZE (mode); } if (GET_MODE_CLASS (mode) == MODE_INT && GET_MODE_BITSIZE (mode) == BITS_PER_UNIT && byte_mode == VOIDmode) byte_mode = mode; if (GET_MODE_CLASS (mode) == MODE_INT && GET_MODE_BITSIZE (mode) == BITS_PER_WORD && word_mode == VOIDmode) word_mode = mode; }}#ifdef memsetgcc_memset (dest, value, len) char *dest; int value; int len;{ while (len-- > 0) *dest++ = value;}#endif /* memset */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -