aboutsummaryrefslogtreecommitdiff
path: root/gcc/genemit.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/genemit.c')
-rw-r--r--gcc/genemit.c46
1 files changed, 38 insertions, 8 deletions
diff --git a/gcc/genemit.c b/gcc/genemit.c
index e92f757..cd85a80 100644
--- a/gcc/genemit.c
+++ b/gcc/genemit.c
@@ -51,6 +51,8 @@ struct clobber_ent
static void output_peephole2_scratches (rtx);
+/* True for <X>_optab if that optab isn't allowed to fail. */
+static bool nofail_optabs[NUM_OPTABS];
static void
print_code (RTX_CODE code)
@@ -285,6 +287,28 @@ gen_emit_seq (rtvec vec, char *used)
}
}
+/* Emit the given C code to the output file. The code is allowed to
+ fail if CAN_FAIL_P. NAME describes what we're generating,
+ for use in error messages. */
+
+static void
+emit_c_code (const char *code, bool can_fail_p, const char *name)
+{
+ if (can_fail_p)
+ printf ("#define FAIL return (end_sequence (), _val)\n");
+ else
+ printf ("#define FAIL _Pragma (\"GCC error \\\"%s cannot FAIL\\\"\")"
+ " (void)0\n", name);
+ printf ("#define DONE return (_val = get_insns (),"
+ "end_sequence (), _val)\n");
+
+ print_md_ptr_loc (code);
+ printf ("%s\n", code);
+
+ printf ("#undef DONE\n");
+ printf ("#undef FAIL\n");
+}
+
/* Generate the `gen_...' function for a DEFINE_INSN. */
static void
@@ -478,8 +502,15 @@ gen_expand (md_rtx_info *info)
/* Output the special code to be executed before the sequence
is generated. */
- print_md_ptr_loc (XSTR (expand, 3));
- printf ("%s\n", XSTR (expand, 3));
+ optab_pattern p;
+ bool can_fail_p = true;
+ if (find_optab (&p, XSTR (expand, 0)))
+ {
+ gcc_assert (p.op < NUM_OPTABS);
+ if (nofail_optabs[p.op])
+ can_fail_p = false;
+ }
+ emit_c_code (XSTR (expand, 3), can_fail_p, XSTR (expand, 0));
/* Output code to copy the arguments back out of `operands'
(unless we aren't going to use them at all). */
@@ -569,10 +600,7 @@ gen_split (md_rtx_info *info)
before the actual construction. */
if (XSTR (split, 3))
- {
- print_md_ptr_loc (XSTR (split, 3));
- printf ("%s\n", XSTR (split, 3));
- }
+ emit_c_code (XSTR (split, 3), true, name);
/* Output code to copy the arguments back out of `operands' */
for (i = 0; i < stats.num_operand_vars; i++)
@@ -724,6 +752,10 @@ main (int argc, char **argv)
if (!init_rtx_reader_args (argc, argv))
return (FATAL_EXIT_CODE);
+#define DEF_INTERNAL_OPTAB_FN(NAME, FLAGS, OPTAB, TYPE) \
+ nofail_optabs[OPTAB##_optab] = true;
+#include "internal-fn.def"
+
/* Assign sequential codes to all entries in the machine description
in parallel with the tables in insn-output.c. */
@@ -764,8 +796,6 @@ from the machine description file `md'. */\n\n");
printf ("#include \"ggc.h\"\n");
printf ("#include \"dumpfile.h\"\n");
printf ("#include \"target.h\"\n\n");
- printf ("#define FAIL return (end_sequence (), _val)\n");
- printf ("#define DONE return (_val = get_insns (), end_sequence (), _val)\n\n");
/* Read the machine description. */