static void genmacro (int idx) { const char *p; const char *sep = ""; int i; /* We write a macro that defines gen_rtx_RTLCODE to be an equivalent to gen_rtx_fmt_FORMAT where FORMAT is the RTX_FORMAT of RTLCODE. */ if (excluded_rtx (idx)) /* Don't define a macro for this code. */ return; bool has_mode_p = !always_void_p (idx); printf ("#define gen_rtx_%s%s(", special_rtx (idx) ? "raw_" : "", defs[idx].enumname); if (has_mode_p) { printf ("MODE"); sep = ", "; } for (p = defs[idx].format, i = 0; *p != 0; p++) if (*p != '0') { printf ("%sARG%d", sep, i++); sep = ", "; } printf (") \\\n gen_rtx_fmt_%s (%s, %s", defs[idx].format, defs[idx].enumname, has_mode_p ? "(MODE)" : "VOIDmode"); for (p = defs[idx].format, i = 0; *p != 0; p++) if (*p != '0') printf (", (ARG%d)", i++); puts (")"); }
static void gen_exp (rtx x, enum rtx_code subroutine_type, char *used) { RTX_CODE code; int i; int len; const char *fmt; const char *sep = ""; if (x == 0) { printf ("NULL_RTX"); return; } code = GET_CODE (x); switch (code) { case MATCH_OPERAND: case MATCH_DUP: if (used) { if (used[XINT (x, 0)]) { printf ("copy_rtx (operand%d)", XINT (x, 0)); return; } used[XINT (x, 0)] = 1; } printf ("operand%d", XINT (x, 0)); return; case MATCH_OP_DUP: printf ("gen_rtx_fmt_"); for (i = 0; i < XVECLEN (x, 1); i++) printf ("e"); printf (" (GET_CODE (operand%d), ", XINT (x, 0)); if (GET_MODE (x) == VOIDmode) printf ("GET_MODE (operand%d)", XINT (x, 0)); else printf ("%smode", GET_MODE_NAME (GET_MODE (x))); for (i = 0; i < XVECLEN (x, 1); i++) { printf (",\n\t\t"); gen_exp (XVECEXP (x, 1, i), subroutine_type, used); } printf (")"); return; case MATCH_OPERATOR: printf ("gen_rtx_fmt_"); for (i = 0; i < XVECLEN (x, 2); i++) printf ("e"); printf (" (GET_CODE (operand%d)", XINT (x, 0)); printf (", %smode", GET_MODE_NAME (GET_MODE (x))); for (i = 0; i < XVECLEN (x, 2); i++) { printf (",\n\t\t"); gen_exp (XVECEXP (x, 2, i), subroutine_type, used); } printf (")"); return; case MATCH_PARALLEL: case MATCH_PAR_DUP: printf ("operand%d", XINT (x, 0)); return; case MATCH_SCRATCH: gen_rtx_scratch (x, subroutine_type); return; case PC: printf ("pc_rtx"); return; case RETURN: printf ("ret_rtx"); return; case SIMPLE_RETURN: printf ("simple_return_rtx"); return; case CLOBBER: if (REG_P (XEXP (x, 0))) { printf ("gen_hard_reg_clobber (%smode, %i)", GET_MODE_NAME (GET_MODE (XEXP (x, 0))), REGNO (XEXP (x, 0))); return; } break; case CC0: printf ("cc0_rtx"); return; case CONST_INT: if (INTVAL (x) == 0) printf ("const0_rtx"); else if (INTVAL (x) == 1) printf ("const1_rtx"); else if (INTVAL (x) == -1) printf ("constm1_rtx"); else if (-MAX_SAVED_CONST_INT <= INTVAL (x) && INTVAL (x) <= MAX_SAVED_CONST_INT) printf ("const_int_rtx[MAX_SAVED_CONST_INT + (%d)]", (int) INTVAL (x)); else if (INTVAL (x) == STORE_FLAG_VALUE) printf ("const_true_rtx"); else { printf ("GEN_INT ("); printf (HOST_WIDE_INT_PRINT_DEC_C, INTVAL (x)); printf (")"); } return; case CONST_DOUBLE: case CONST_FIXED: case CONST_WIDE_INT: /* These shouldn't be written in MD files. Instead, the appropriate routines in varasm.c should be called. */ gcc_unreachable (); default: break; } printf ("gen_rtx_"); print_code (code); printf (" ("); if (!always_void_p (code)) { printf ("%smode", GET_MODE_NAME (GET_MODE (x))); sep = ",\n\t"; } fmt = GET_RTX_FORMAT (code); len = GET_RTX_LENGTH (code); for (i = 0; i < len; i++) { if (fmt[i] == '0') break; fputs (sep, stdout); switch (fmt[i]) { case 'e': case 'u': gen_exp (XEXP (x, i), subroutine_type, used); break; case 'i': printf ("%u", XINT (x, i)); break; case 'r': printf ("%u", REGNO (x)); break; case 's': printf ("\"%s\"", XSTR (x, i)); break; case 'E': { int j; printf ("gen_rtvec (%d", XVECLEN (x, i)); for (j = 0; j < XVECLEN (x, i); j++) { printf (",\n\t\t"); gen_exp (XVECEXP (x, i, j), subroutine_type, used); } printf (")"); break; } default: gcc_unreachable (); } sep = ",\n\t"; } printf (")"); }