📄 rtl.c
字号:
sawclose = 1;}/* Call this function from the debugger to see what X looks like. */voiddebug_rtx (x) rtx x;{ outfile = stderr; print_rtx (x); fprintf (stderr, "\n");}/* External entry point for printing a chain of insns starting with RTX_FIRST onto file OUTF. A blank line separates insns. If RTX_FIRST is not an insn, then it alone is printed, with no newline. */voidprint_rtl (outf, rtx_first) FILE *outf; rtx rtx_first;{ register rtx tmp_rtx; outfile = outf; sawclose = 0; switch (GET_CODE (rtx_first)) { case INSN: case JUMP_INSN: case CALL_INSN: case NOTE: case CODE_LABEL: case BARRIER: for (tmp_rtx = rtx_first; NULL != tmp_rtx; tmp_rtx = NEXT_INSN (tmp_rtx)) { print_rtx (tmp_rtx); fprintf (outfile, "\n"); } break; default: print_rtx (rtx_first); }}/* Subroutines of read_rtx. *//* Dump code after printing a message. Used when read_rtx finds invalid data. */static voiddump_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; /* 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 '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) : (struct rtvec_def *) NULL); 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); j = 0; stringbufsize = 10; stringbuf = (char *) xmalloc (stringbufsize + 1); while (1) { if (j >= stringbufsize - 4) { stringbufsize *= 2; stringbuf = (char *) xrealloc (stringbuf, stringbufsize + 1); } stringbuf[j] = getc (infile); /* Read the string */ if (stringbuf[j] == '\\') { stringbuf[j] = getc (infile); /* Read the string */ /* \; makes stuff for a C string constant containing newline and tab. */ if (stringbuf[j] == ';') { strcpy (&stringbuf[j], "\\n\\t"); j += 3; } } else if (stringbuf[j] == '"') break; j++; } stringbuf[j] = 0; /* NUL terminate the string */ stringbuf = (char *) xrealloc (stringbuf, j + 1); if (saw_paren) { c = read_skip_spaces (infile); if (c != ')') dump_and_abort (')', c, infile); } XSTR (return_rtx, i) = stringbuf; } 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'. */voidinit_rtl (){ 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 *) malloc (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++ = 'i'; *s++ = 0; }#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -