+2002-01-05 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * doc/invoke.texi (Option Summary) <MMIX Options>: Document
+ -mbranch-predict, -mreg-stack-fill-bug-workaround and their
+ negatives.
+ (MMIX Options): Ditto. Fix item/itemx typo for -mno-zero-extend.
+ * config/mmix/mmix.c (mmix_target_asm_function_prologue): Rework
+ kludge for pre-october-14th mmix versions to handle new-found bug
+ with PUSHJ/PUSHGO and the register stack.
+ * config/mmix/mmix.h (struct machine_function): Rename member
+ has_call_value_without_parameters to has_call_without_parameters.
+ All referers changed.
+ (TARGET_MASK_REG_STACK_FILL_BUG, TARGET_DEFAULT
+ TARGET_MASK_BRANCH_PREDICT): New macros.
+ (TARGET_SWITCHES): New options -mreg-stack-fill-bug-workaround,
+ -mno-reg-stack-fill-bug-workaround.
+ * config/mmix/mmix.md ("call"): Set struct machine member
+ has_call_without_parameters.
+
Sat Jan 5 02:20:22 CET 2002 Jan Hubicka <jh@suse.cz>
* cfgcleanup.c (thread_jump): Fix handling of reversed branches.
mmix_highest_saved_stack_register = regno;
- /* FIXME: A kludge for the MMIXware ABI. The return value comes back in
- L of the caller, not just the register number of the X field of
- PUSH{J,GO}. So we need to make L agree with that number if there's a
- function call in this function that returns a value but takes no
- parameters (if there were parameters, L would be set to at least the
- first parameter register, $16). A real solution includes a pass to
- test that settings of $15 (MMIX_RETURN_VALUE_REGNUM for the MMIXware
- ABI) dominate all function calls that return a value. This could be
- done in the planned machine_dep_reorg pass to rename all registers. */
- if (! TARGET_ABI_GNU && cfun->machine->has_call_value_without_parameters)
- fprintf (stream, "\tSET %s,%s\n",
- reg_names[MMIX_RETURN_VALUE_REGNUM],
- reg_names[MMIX_RETURN_VALUE_REGNUM]);
+ /* FIXME: Remove this when a corrected mmix version is released.
+
+ This kludge is a work-around for a presumed bug in the mmix simulator
+ (reported to knuth-bug), all versions up and including "Version of 14
+ October 2001". When the circular register stack fills up, the parts
+ that would be overwritten need to be written to memory. If the
+ "filling" instruction is a PUSHJ or PUSHGO, rL == 0 afterwards. That
+ precise condition (rS == rO && rL == 0) is the same as for an empty
+ register stack, which means no more data is written to memory for
+ that round. A hack is to remove the "&& L!=0" from "@<Increase
+ rL@>=" in mmix-sim.w: the register stack isn't empty under normal
+ circumstances, unless SAVE or UNSAVE is used, interrupts are enabled
+ or cases where rS == rO and rL is explicitly written to 0 as in
+ "PUT rL,0".
+
+ A workaround is to make sure PUSHJ or PUSHGO isn't filling up the
+ register stac. This is accomplished if $16 or higher is written
+ before the function call. This doesn't happen from a leaf functions
+ of course. For the MMIXware ABI, this can't happen if all called
+ functions have parameters, because parameters start at $16.
+ Otherwise, and for the GNU ABI, if any register $16 and up is used,
+ we can see if it's mentioned before any function-call without
+ parameters. This isn't too important; the bug will probably be fixed
+ soon and there's an option to not emit the work-around code. The
+ call-with-parameters kludge wouldn't be there if it hadn't been for
+ it being left-over from a previous mmix version.
+
+ The actual code makes sure any register stack fill happens as early
+ as in the function prologue with a "SET $16,$16" (essentially a nop
+ except for the effects on the register stack). */
+ if (TARGET_REG_STACK_FILL_BUG
+ && ((TARGET_ABI_GNU && !leaf_function_p ())
+ || (!TARGET_ABI_GNU
+ && cfun->machine->has_call_without_parameters)))
+ {
+ /* We don't have a specific macro or derivable expression for the
+ first non-call-saved register. If we need it in other places
+ than here (which is temporary code anyway), such a macro should
+ be added. */
+ int flush_regno
+ = TARGET_ABI_GNU ? mmix_highest_saved_stack_register + 2 : 16;
+
+ fprintf (stream, "\tSET %s,%s\n",
+ reg_names[flush_regno], reg_names[flush_regno]);
+ }
}
/* TARGET_ASM_FUNCTION_EPILOGUE. */
mmix.md too. */
struct machine_function
{
- int has_call_value_without_parameters;
+ int has_call_without_parameters;
int has_landing_pad;
};
#define TARGET_MASK_KNUTH_DIVISION 16
#define TARGET_MASK_TOPLEVEL_SYMBOLS 32
#define TARGET_MASK_BRANCH_PREDICT 64
+#define TARGET_MASK_REG_STACK_FILL_BUG 128
/* FIXME: Get rid of this one. */
#define TARGET_LIBFUNC (target_flags & TARGET_MASK_LIBFUNCS)
#define TARGET_KNUTH_DIVISION (target_flags & TARGET_MASK_KNUTH_DIVISION)
#define TARGET_TOPLEVEL_SYMBOLS (target_flags & TARGET_MASK_TOPLEVEL_SYMBOLS)
#define TARGET_BRANCH_PREDICT (target_flags & TARGET_MASK_BRANCH_PREDICT)
+#define TARGET_REG_STACK_FILL_BUG \
+ (target_flags & TARGET_MASK_REG_STACK_FILL_BUG)
-#define TARGET_DEFAULT TARGET_MASK_BRANCH_PREDICT
+#define TARGET_DEFAULT \
+ (TARGET_MASK_BRANCH_PREDICT | TARGET_MASK_REG_STACK_FILL_BUG)
/* FIXME: Provide a way to *load* the epsilon register. */
#define TARGET_SWITCHES \
N_("Use P-mnemonics for branches statically predicted as taken")}, \
{"no-branch-predict", -TARGET_MASK_BRANCH_PREDICT, \
N_("Don't use P-mnemonics for branches")}, \
+ {"reg-stack-fill-bug-workaround", TARGET_MASK_REG_STACK_FILL_BUG, \
+ N_("Work around inconsistent behavior when a PUSHJ or PUSHGO\
+ instruction fills the register stack")}, \
+ {"no-reg-stack-fill-bug-workaround", -TARGET_MASK_REG_STACK_FILL_BUG,\
+ N_("Don't work around inconsistent behavior when a PUSHJ or PUSHGO\
+ instruction fills the register stack")}, \
{"", TARGET_DEFAULT, ""}}
/* Unfortunately, this must not reference anything in "mmix.c". */
error too. */
if (operands[2] == NULL_RTX)
operands[2] = const0_rtx;
+
+ /* FIXME: Documentation bug: operands[3] (operands[2] for 'call') is the
+ *next* argument register, not the number of arguments in registers. */
+ cfun->machine->has_call_without_parameters
+ |= REG_P (operands[2]) && REGNO (operands[2]) == MMIX_FIRST_ARG_REGNUM;
+
operands[4] = gen_rtx_REG (DImode, MMIX_INCOMING_RETURN_ADDRESS_REGNUM);
}")
/* FIXME: Documentation bug: operands[3] (operands[2] for 'call') is the
*next* argument register, not the number of arguments in registers. */
- cfun->machine->has_call_value_without_parameters
+ cfun->machine->has_call_without_parameters
|= REG_P (operands[3]) && REGNO (operands[3]) == MMIX_FIRST_ARG_REGNUM;
operands[5] = gen_rtx_REG (DImode, MMIX_INCOMING_RETURN_ADDRESS_REGNUM);
@gccoptlist{
-mlibfuncs -mno-libfuncs -mepsilon -mno-epsilon -mabi=gnu @gol
-mabi=mmixware -mzero-extend -mknuthdiv -mtoplevel-symbols @gol
--melf}
+-melf -mbranch-predict -mreg-stack-fill-bug-workaround @gol
+-mno-branch-predict -mno-reg-stack-fill-bug-workaround}
@emph{IA-64 Options}
@gccoptlist{
the GNU ABI which uses global registers @code{$231} and up.
@item -mzero-extend
-@item -mno-zero-extend
+@itemx -mno-zero-extend
When reading data from memory in sizes shorter than 64 bits, use (do not
use) zero-extending load instructions by default, rather than
sign-extending ones.
@item -melf
Generate an executable in the ELF format, rather than the default
@samp{mmo} format used by the @command{mmix} simulator.
+
+@item -mbranch-predict
+@itemx -mno-branch-predict
+Use (do not use) the probable-branch instructions, when static branch
+prediction indicates a probable branch.
+
+@item -mreg-stack-fill-bug-workaround
+@itemx -mno-reg-stack-fill-bug-workaround
+Work around (do not work around) an inconsistency in the circular
+register stack mechanism in the @command{mmix} simulator, which
+causes entries in the register stack to not be flushed to memory if
+the instruction causing the fill-up is @code{PUSHJ} or @code{PUSHGO}.
@end table
@node Code Gen Options