/* Definitions of target machine for GNU compiler, for MMIX.
- Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
Contributed by Hans-Peter Nilsson (hp@bitrange.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#define MMIX_FRAME_POINTER_REGNUM 253
#define MMIX_STACK_POINTER_REGNUM 254
#define MMIX_LAST_GENERAL_REGISTER 255
-#define MMIX_INCOMING_RETURN_ADDRESS_REGNUM 259
+#define MMIX_INCOMING_RETURN_ADDRESS_REGNUM MMIX_rJ_REGNUM
#define MMIX_HIMULT_REGNUM 258
-#define MMIX_REMAINDER_REGNUM 260
+#define MMIX_REMAINDER_REGNUM MMIX_rR_REGNUM
#define MMIX_ARG_POINTER_REGNUM 261
-#define MMIX_LAST_REGISTER_FILE_REGNUM 31
+#define MMIX_rO_REGNUM 262
+#define MMIX_LAST_STACK_REGISTER_REGNUM 31
/* Four registers; "ideally, these registers should be call-clobbered", so
just grab a bunch of the common clobbered registers. FIXME: Last
/* Declarations for helper variables that are not tied to a particular
target macro. */
-extern struct rtx_def *mmix_compare_op0;
-extern struct rtx_def *mmix_compare_op1;
+extern GTY(()) rtx mmix_compare_op0;
+extern GTY(()) rtx mmix_compare_op1;
/* Per-function machine data. This is normally an opaque type just
defined and used in the tm.c file, but we need to see the definition in
mmix.md too. */
-struct machine_function
+struct machine_function GTY(())
{
- int has_call_value_without_parameters;
int has_landing_pad;
+ int highest_saved_stack_register;
+ int in_prologue;
};
/* For these target macros, there is no generic documentation here. You
/* Node: Driver */
-/* When both ABI:s work, this is how we tell them apart in code. The
- GNU abi is implied the default. Also implied in TARGET_DEFAULT. */
-#define CPP_SPEC \
- "%{mabi=gnu:-D__MMIX_ABI_GNU__\
- %{mabi=mmixware:\
- %eoptions -mabi=mmixware and -mabi=gnu are mutually exclusive}}\
- %{!mabi=gnu:-D__MMIX_ABI_MMIXWARE__}"
-
/* User symbols are in the same name-space as built-in symbols, but we
don't need the built-in symbols, so remove those and instead apply
stricter operand checking. Don't warn when expanding insns. */
/* Pass on -mset-program-start=N and -mset-data-start=M to the linker.
Provide default program start 0x100 unless -mno-set-program-start.
- Link to ELF if requested. */
+ Don't do this if linking relocatably, with -r. For a final link,
+ produce mmo, unless ELF is requested or when linking relocatably. */
#define LINK_SPEC \
"%{mset-program-start=*:--defsym __.MMIX.start..text=%*}\
%{mset-data-start=*:--defsym __.MMIX.start..data=%*}\
%{!mset-program-start=*:\
- %{!mno-set-program-start:--defsym __.MMIX.start..text=0x100}}\
- %{!melf:-m mmo}%{melf:-m elf64mmix}"
+ %{!mno-set-program-start:\
+ %{!r:--defsym __.MMIX.start..text=0x100}}}\
+ %{!melf:%{!r:-m mmo}}%{melf|r:-m elf64mmix}"
/* Put unused option values here. */
extern const char *mmix_cc1_ignored_option;
#define TARGET_OPTIONS \
{{"set-program-start=", &mmix_cc1_ignored_option, \
- N_("Set start-address of the program") }, \
+ N_("Set start-address of the program"), 0}, \
{"set-data-start=", &mmix_cc1_ignored_option, \
- N_("Set start-address of data")}}
+ N_("Set start-address of data"), 0} }
/* FIXME: There's no provision for profiling here. */
#define STARTFILE_SPEC \
/* Node: Run-time Target */
/* Define __LONG_MAX__, since we're advised not to change glimits.h. */
-#define CPP_PREDEFINES "-D__mmix__ -D__MMIX__ -D__LONG_MAX__=9223372036854775807L"
+#define TARGET_CPU_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__mmix__"); \
+ builtin_define ("__MMIX__"); \
+ if (TARGET_ABI_GNU) \
+ builtin_define ("__MMIX_ABI_GNU__"); \
+ else \
+ builtin_define ("__MMIX_ABI_MMIXWARE__"); \
+ } \
+ while (0)
extern int target_flags;
#define TARGET_MASK_ZERO_EXTEND 8
#define TARGET_MASK_KNUTH_DIVISION 16
#define TARGET_MASK_TOPLEVEL_SYMBOLS 32
+#define TARGET_MASK_BRANCH_PREDICT 64
+#define TARGET_MASK_USE_RETURN_INSN 128
+
+/* We use the term "base address" since that's what Knuth uses. The base
+ address goes in a global register. When addressing, it's more like
+ "base address plus offset", with the offset being 0..255 from the base,
+ which itself can be a symbol plus an offset. The effect is like having
+ a constant pool in global registers, code offsetting from those
+ registers (automatically causing a request for a suitable constant base
+ address register) without having to know the specific register or the
+ specific offset. The setback is that there's a limited number of
+ registers, and you'll not find out until link time whether you
+ should have compiled with -mno-base-addresses. */
+#define TARGET_MASK_BASE_ADDRESSES 128
/* FIXME: Get rid of this one. */
#define TARGET_LIBFUNC (target_flags & TARGET_MASK_LIBFUNCS)
#define TARGET_ZERO_EXTEND (target_flags & TARGET_MASK_ZERO_EXTEND)
#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_BASE_ADDRESSES (target_flags & TARGET_MASK_BASE_ADDRESSES)
+#define TARGET_USE_RETURN_INSN (target_flags & TARGET_MASK_USE_RETURN_INSN)
-#define TARGET_DEFAULT 0
+#define TARGET_DEFAULT \
+ (TARGET_MASK_BRANCH_PREDICT | TARGET_MASK_BASE_ADDRESSES \
+ | TARGET_MASK_USE_RETURN_INSN)
-/* FIXME: Provide a way to *load* the epsilon register.
- Kill some of these; preferrably the -mint=* ones. */
+/* FIXME: Provide a way to *load* the epsilon register. */
#define TARGET_SWITCHES \
{{"libfuncs", TARGET_MASK_LIBFUNCS, \
N_("For intrinsics library: pass all parameters in registers")}, \
{"no-knuthdiv", -TARGET_MASK_KNUTH_DIVISION, ""}, \
{"toplevel-symbols", TARGET_MASK_TOPLEVEL_SYMBOLS, \
N_("Prepend global symbols with \":\" (for use with PREFIX)")}, \
- {"no-toplevel-symbols", 0, \
+ {"no-toplevel-symbols", -TARGET_MASK_TOPLEVEL_SYMBOLS, \
N_("Do not provide a default start-address 0x100 of the program")}, \
{"elf", 0, \
N_("Link to emit program in ELF format (rather than mmo)")}, \
+ {"branch-predict", TARGET_MASK_BRANCH_PREDICT, \
+ 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")}, \
+ {"base-addresses", TARGET_MASK_BASE_ADDRESSES, \
+ N_("Use addresses that allocate global registers")}, \
+ {"no-base-addresses", -TARGET_MASK_BASE_ADDRESSES, \
+ N_("Do not use addresses that allocate global registers")}, \
+ {"single-exit", -TARGET_MASK_USE_RETURN_INSN, \
+ N_("Generate a single exit point for each function")}, \
+ {"no-single-exit", TARGET_MASK_USE_RETURN_INSN, \
+ N_("Do not generate a single exit point for each function")}, \
{"", TARGET_DEFAULT, ""}}
/* Unfortunately, this must not reference anything in "mmix.c". */
#define TARGET_VERSION \
- fprintf (stderr, " (MMIX) 2001-09-01")
+ fprintf (stderr, " (MMIX)")
#define OVERRIDE_OPTIONS mmix_override_options ()
/* Node: Storage Layout */
-/* I see no bitfield instructions. Anyway, the common order is from low
+/* I see no bit-field instructions. Anyway, the common order is from low
to high, as the power of two, hence little-endian. */
#define BITS_BIG_ENDIAN 0
#define BYTES_BIG_ENDIAN 1
#define WORDS_BIG_ENDIAN 1
#define FLOAT_WORDS_BIG_ENDIAN 1
-#define BITS_PER_UNIT 8
-#define BITS_PER_WORD 64
#define UNITS_PER_WORD 8
-#define POINTER_SIZE 64
-
-/* FIXME: This macro is correlated to MAX_FIXED_MODE_SIZE in that
- e.g. this macro must not be 8 (default, UNITS_PER_WORD) when
- MAX_FIXED_MODE_SIZE is 64 (default, DImode), or really: this must be
- set manually if MAX_FIXED_MODE_SIZE is not at least twice the register
- size. By setting it to 4, we don't have to worry about TImode things
- yet. Revisit, perhaps get TImode going or get some solution that does
- not mandate TImode or lie in other ways. */
-#define MIN_UNITS_PER_WORD 4
/* FIXME: Promotion of modes currently generates slow code, extending
before every operation. */
+/* I'm a little bit undecided about this one. It might be beneficial to
+ promote all operations. */
-#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \
+#define PROMOTE_FUNCTION_MODE(MODE, UNSIGNEDP, TYPE) \
do { \
if (GET_MODE_CLASS (MODE) == MODE_INT \
&& GET_MODE_SIZE (MODE) < 8) \
} \
} while (0)
-#define PROMOTE_FUNCTION_ARGS
-
-#if 0
-/* Apparently not doing TRT if int < register-size. FIXME: Perhaps
- FUNCTION_VALUE and LIBCALL_VALUE needs tweaking as some ports say. */
-#define PROMOTE_FUNCTION_RETURN
-#endif
-
-/* I'm a little bit undecided about this one. It might be beneficial to
- promote all operations. */
-#define PROMOTE_FOR_CALL_ONLY
-
/* We need to align everything to 64 bits that can affect the alignment
of other types. Since address N is interpreted in MMIX as (N modulo
access_size), we must align. */
#define DEFAULT_SIGNED_CHAR 1
-/* I have no rationale for this other than pointing at Alpha. */
-#define WCHAR_TYPE "unsigned int"
-#define WCHAR_TYPE_SIZE 32
-
/* Node: Register Basics */
/* We tell GCC about all 256 general registers, and we also include
- rD, rE, rH, rJ and rR (in that order) so we can describe what insns
+ rD, rE, rH, rJ, rR and rO (in that order) so we can describe what insns
clobber them. We use a faked register for the argument pointer. It is
always eliminated towards the frame-pointer or the stack-pointer, never
output in assembly. Any fixed register would do for this, like $255,
but future debugging is easier when using a separate register. It
counts as a global register for pseudorandom reasons. */
-#define FIRST_PSEUDO_REGISTER 262
+#define FIRST_PSEUDO_REGISTER 263
/* We treat general registers with no assigned purpose as fixed. The
stack pointer, $254, is also fixed. Register $255 is referred to as a
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
- 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, \
- 1, 1, 0, 0, 0, 1 \
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, \
+ 1, 1, 0, 0, 0, 1, 1 \
}
/* General registers are fixed and therefore "historically" marked
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, \
- 1, 1, 1, 1, 1, 1 \
+ 1, 1, 1, 1, 1, 1, 1 \
}
#define CONDITIONAL_REGISTER_USAGE mmix_conditional_register_usage ()
-/* No LOCAL_REGNO, INCOMING_REGNO or OUTGOING_REGNO, since those macros
- are not usable for MMIX: it doesn't have a fixed register window size.
- FIXME: Perhaps we should say something about $0..$15 may sometimes be
- the incoming $16..$31. Those macros need better documentation; it
- looks like they're just bogus and that FUNCTION_INCOMING_ARG_REGNO_P
- and FUNCTION_OUTGOING_VALUE should be used where they're used. For the
+/* No INCOMING_REGNO or OUTGOING_REGNO, since those macros are not usable
+ for MMIX: it doesn't have a fixed register window size. FIXME: Perhaps
+ we should say something about $0..$15 may sometimes be the incoming
+ $16..$31. Those macros need better documentation; it looks like
+ they're just bogus and that FUNCTION_INCOMING_ARG_REGNO_P and
+ FUNCTION_OUTGOING_VALUE should be used where they're used. For the
moment, do nothing; things seem to work anyway. */
+/* Defining LOCAL_REGNO is necessary in presence of prologue/epilogue,
+ else GCC will be confused that those registers aren't saved and
+ restored. */
+#define LOCAL_REGNO(REGNO) mmix_local_regno (REGNO)
/* Node: Allocation Order */
24, 25, 26, 27, 28, 29, 30, 31, \
\
252, 251, 250, 249, 248, 247, \
- 246, 245, 244, 243, 242, 241, 240, 239, \
- 238, 237, 236, 235, 234, 233, 232, 231, \
\
253, \
\
208, 209, 210, 211, 212, 213, 214, 215, \
216, 217, 218, 219, 220, 221, 222, 223, \
224, 225, 226, 227, 228, 229, 230, 231, \
- 254, 255, 256, 257, 261 \
+ 232, 233, 234, 235, 236, 237, 238, 239, \
+ 240, 241, 242, 243, 244, 245, 246, \
+ \
+ 254, 255, 256, 257, 261, 262 \
}
/* As a convenience, we put this nearby, for ease of comparison.
assuming it is referenced a very limited number of times. Other global
and fixed registers come next; they are never allocated. */
#define MMIX_GNU_ABI_REG_ALLOC_ORDER \
-{ 252, 251, 250, 249, 248, 247, 246, \
+ { 252, 251, 250, 249, 248, 247, 246, \
245, 244, 243, 242, 241, 240, 239, 238, \
- 237, 236, 235, 234, 233, 232, \
+ 237, 236, 235, 234, 233, 232, 231, \
\
0, 1, 2, 3, 4, 5, 6, 7, \
8, 9, 10, 11, 12, 13, 14, 15, \
200, 201, 202, 203, 204, 205, 206, 207, \
208, 209, 210, 211, 212, 213, 214, 215, \
216, 217, 218, 219, 220, 221, 222, 223, \
- 224, 225, 226, 227, 228, 229, 230, 231, \
- 254, 255, 256, 257, 261 \
+ 224, 225, 226, 227, 228, 229, 230, \
+ \
+ 254, 255, 256, 257, 261, 262 \
}
/* The default one. */
/* Node: Register Classes */
enum reg_class
-{
- NO_REGS, GENERAL_REGS, REMAINDER_REG, HIMULT_REG,
- SYSTEM_REGS, ALL_REGS, LIM_REG_CLASSES
-};
+ {
+ NO_REGS, GENERAL_REGS, REMAINDER_REG, HIMULT_REG,
+ SYSTEM_REGS, ALL_REGS, LIM_REG_CLASSES
+ };
#define N_REG_CLASSES (int) LIM_REG_CLASSES
{~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 0x20}, \
{0, 0, 0, 0, 0, 0, 0, 0, 0x10}, \
{0, 0, 0, 0, 0, 0, 0, 0, 4}, \
- {0, 0, 0, 0, 0, 0, 0, 0, 0x3f}, \
- {~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 0x3f}}
+ {0, 0, 0, 0, 0, 0, 0, 0, 0x7f}, \
+ {~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 0x7f}}
#define REGNO_REG_CLASS(REGNO) \
((REGNO) <= MMIX_LAST_GENERAL_REGISTER \
mmix_const_ok_for_letter_p (VALUE, C)
#define EXTRA_CONSTRAINT(VALUE, C) \
- mmix_extra_constraint (VALUE, C)
+ mmix_extra_constraint (VALUE, C, MMIX_REG_OK_STRICT)
/* Do we need anything serious here? Yes, any FLOT constant. */
#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
#define STARTING_FRAME_OFFSET \
mmix_starting_frame_offset ()
-/* There is a stack slot between the frame-pointer and the first
- parameter, where the return address is sometimes stored. FIXME:
- Unnecessary. */
-#define FIRST_PARM_OFFSET(FUNDECL) 8
+#define FIRST_PARM_OFFSET(FUNDECL) 0
#define DYNAMIC_CHAIN_ADDRESS(FRAMEADDR) \
mmix_dynamic_chain_address (FRAMEADDR)
/* Node: Elimination */
/* FIXME: Is this requirement built-in? Anyway, we should try to get rid
of it; we can deduce the value. */
-#define FRAME_POINTER_REQUIRED (nonlocal_goto_stack_level != NULL_RTX)
+#define FRAME_POINTER_REQUIRED current_function_has_nonlocal_label
/* The frame-pointer is stored in a location that either counts to the
offset of incoming parameters, or that counts to the offset of the
#define CAN_ELIMINATE(FROM, TO) 1
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
- (OFFSET) = mmix_initial_elimination_offset (FROM, TO);
+ (OFFSET) = mmix_initial_elimination_offset (FROM, TO)
/* Node: Stack Arguments */
#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
mmix_function_arg (&(CUM), MODE, TYPE, NAMED, 1)
-#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
- mmix_function_arg_pass_by_reference (&(CUM), MODE, TYPE, NAMED)
-
-/* This *sounds* good, but does not seem to be implemented correctly to
- be a win; at least it wasn't in 2.7.2. FIXME: Check and perhaps
- replace with a big comment. */
-#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) 1
+typedef struct { int regs; int lib; } CUMULATIVE_ARGS;
-typedef struct { int regs; int lib; int now_varargs; } CUMULATIVE_ARGS;
-
-#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
- ((CUM).regs = 0, (CUM).lib = ((LIBNAME) != 0), (CUM).now_varargs = 0)
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
+ ((CUM).regs = 0, (CUM).lib = ((LIBNAME) != 0))
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
((CUM).regs \
- = ((MUST_PASS_IN_STACK (MODE, TYPE)) \
+ = ((targetm.calls.must_pass_in_stack (MODE, TYPE)) \
|| (MMIX_FUNCTION_ARG_SIZE (MODE, TYPE) > 8 \
&& !TARGET_LIBFUNC && !(CUM).lib)) \
? (MMIX_MAX_ARGS_IN_REGS) + 1 \
mmix_function_outgoing_value (VALTYPE, FUNC)
#define LIBCALL_VALUE(MODE) \
- gen_rtx_REG (MODE, MMIX_OUTGOING_RETURN_VALUE_REGNUM)
+ gen_rtx_REG (MODE, MMIX_RETURN_VALUE_REGNUM)
#define FUNCTION_VALUE_REGNO_P(REGNO) \
- ((REGNO) == MMIX_OUTGOING_RETURN_VALUE_REGNUM)
-
-
-/* Node: Aggregate Return */
-
-#define STRUCT_VALUE_REGNUM MMIX_STRUCT_VALUE_REGNUM
+ mmix_function_value_regno_p (REGNO)
/* Node: Caller Saves */
#define EPILOGUE_USES(REGNO) \
((REGNO) == MMIX_INCOMING_RETURN_ADDRESS_REGNUM)
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
- mmix_asm_output_mi_thunk (FILE, THUNK_FNDECL, DELTA, FUNCTION)
-
-
/* Node: Profiling */
#define FUNCTION_PROFILER(FILE, LABELNO) \
mmix_function_profiler (FILE, LABELNO)
-/* Node: Varargs */
-
-/* For the moment, let's stick to pushing argument registers on the stack.
- Later, we can parse all arguments in registers, to improve
- performance. */
-#define SETUP_INCOMING_VARARGS(A, M, T, P, S) \
- mmix_setup_incoming_varargs(&(A), M, T, &(P), S)
-
-/* FIXME: This and other EXPAND_BUILTIN_VA_... target macros are not
- documented, although used by several targets. */
-#define EXPAND_BUILTIN_VA_ARG(VALIST, TYPE) \
- mmix_expand_builtin_va_arg (VALIST, TYPE)
-
/* Node: Trampolines */
#define TRAMPOLINE_TEMPLATE(FILE) \
mmix_initialize_trampoline (ADDR, FNADDR, STATIC_CHAIN)
-/* Node: Library Calls */
-
-#define TARGET_MEM_FUNCTIONS
-
-
/* Node: Addressing Modes */
#define CONSTANT_ADDRESS_P(X) \
#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_BASE_P (X)
-#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)
-
#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)
#define LEGITIMATE_CONSTANT_P(X) \
/* Node: Condition Code */
-#define EXTRA_CC_MODES \
- CC(CC_UNSmode, "CC_UNS") \
- CC(CC_FPmode, "CC_FP") \
- CC(CC_FPEQmode, "CC_FPEQ") \
- CC(CC_FUNmode, "CC_FUN")
-
#define SELECT_CC_MODE(OP, X, Y) \
mmix_select_cc_mode (OP, X, Y)
-#define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
- mmix_canonicalize_comparison (&(CODE), &(OP0), &(OP1));
+/* A definition of CANONICALIZE_COMPARISON that changed LE and GT
+ comparisons with -1 to LT and GE respectively, and LT, LTU, GE or GEU
+ comparisons with 256 to 255 and LE, LEU, GT and GTU has been
+ ineffective; the code path for performing the changes did not trig for
+ neither the GCC testsuite nor ghostscript-6.52 nor Knuth's mmix.tar.gz
+ itself (core GCC functionality supposedly handling it) with sources
+ from 2002-06-06. */
#define REVERSIBLE_CC_MODE(MODE) \
mmix_reversible_cc_mode (MODE)
/* Node: Costs */
-/* This one takes on both the RTX_COSTS and CONST_COSTS tasks. */
-#define DEFAULT_RTX_COSTS(X, CODE, OUTER_CODE) \
- { \
- int mmix_rtx_cost; \
- if (mmix_rtx_cost_recalculated (X, CODE, OUTER_CODE, \
- &mmix_rtx_cost)) \
- return mmix_rtx_cost; \
- }
-
-#define ADDRESS_COST(ADDRESS) mmix_address_cost (ADDRESS)
-
/* The special registers can only move to and from general regs, and we
need to check that their constraints match, so say 3 for them. */
/* WARNING: gcc-2.7.2.2 i686-pc-linux-gnulibc1 (as shipped with RH 4.2)
#define DATA_SECTION_ASM_OP \
mmix_data_section_asm_op ()
-/* Stuff copied from elfos.h. */
-#define EXTRA_SECTIONS in_const
-
-#define EXTRA_SECTION_FUNCTIONS \
- CONST_SECTION_FUNCTION
-
-#define READONLY_DATA_SECTION() const_section ()
-
-#define CONST_SECTION_ASM_OP "\t.section\t.rodata"
-
-#define CONST_SECTION_FUNCTION \
-void \
-const_section () \
-{ \
- if (in_section != in_const) \
- { \
- fprintf (asm_out_file, "%s\n", CONST_SECTION_ASM_OP); \
- in_section = in_const; \
- } \
-}
-
-#undef SELECT_RTX_SECTION
-#define SELECT_RTX_SECTION(MODE, RTX, ALIGN) const_section ()
-
-#define SELECT_SECTION(DECL, RELOC, ALIGN) \
- mmix_select_section (DECL, RELOC, ALIGN)
-
-#define ENCODE_SECTION_INFO(DECL) \
- mmix_encode_section_info (DECL)
-
-#define STRIP_NAME_ENCODING(VAR, SYM_NAME) \
- (VAR) = mmix_strip_name_encoding (SYM_NAME)
-
-#define UNIQUE_SECTION(DECL, RELOC) \
- mmix_unique_section (decl, reloc)
+#define READONLY_DATA_SECTION_ASM_OP "\t.section\t.rodata"
/* Node: PIC */
/* (empty) */
/* Node: File Framework */
-#define ASM_FILE_START(STREAM) \
- mmix_asm_file_start (STREAM)
-
-#define ASM_FILE_END(STREAM) \
- mmix_asm_file_end (STREAM)
-
-#define ASM_IDENTIFY_GCC(STREAM) \
- mmix_asm_identify_gcc (STREAM)
-
/* While any other punctuation character but ";" would do, we prefer "%"
or "!"; "!" is an unary operator and so will not be mistakenly included
in correctly formed expressions. The hash character adds mass; catches
#define OUTPUT_QUOTED_STRING(STREAM, STRING) \
mmix_output_quoted_string (STREAM, STRING, strlen (STRING))
-#define ASM_OUTPUT_SOURCE_LINE(STREAM, LINE) \
- mmix_asm_output_source_line (STREAM, LINE)
-
#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
-
/* Node: Data Output */
#define ASM_OUTPUT_ASCII(STREAM, PTR, LEN) \
#define ASM_OUTPUT_LABEL(STREAM, NAME) \
mmix_asm_output_label (STREAM, NAME)
+#define ASM_OUTPUT_INTERNAL_LABEL(STREAM, NAME) \
+ mmix_asm_output_internal_label (STREAM, NAME)
+
#define ASM_DECLARE_REGISTER_GLOBAL(STREAM, DECL, REGNO, NAME) \
mmix_asm_declare_register_global (STREAM, DECL, REGNO, NAME)
-#define ASM_GLOBALIZE_LABEL(STREAM, NAME) \
- mmix_asm_globalize_label (STREAM, NAME)
+#define GLOBAL_ASM_OP "\t.global "
#define ASM_WEAKEN_LABEL(STREAM, NAME) \
mmix_asm_weaken_label (STREAM, NAME)
#define ASM_OUTPUT_LABELREF(STREAM, NAME) \
mmix_asm_output_labelref (STREAM, NAME)
-#define ASM_OUTPUT_INTERNAL_LABEL(STREAM, PREFIX, NUM) \
- mmix_asm_output_internal_label (STREAM, PREFIX, NUM)
-
/* We insert a ":" to disambiguate against user symbols like L5. */
#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \
sprintf (LABEL, "*%s:%ld", PREFIX, (long)(NUM))
":" is seen in the object file; we don't really want that mmixal
feature visible there. We don't want the default, which uses a dot;
that'd be incompatible with mmixal. */
-#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
- ((OUTPUT) = (char *) alloca (strlen ((NAME)) + 2 + 10), \
- sprintf ((OUTPUT), "%s::%d", (NAME), (LABELNO)))
+#define ASM_PN_FORMAT "%s::%lu"
#define ASM_OUTPUT_DEF(STREAM, NAME, VALUE) \
mmix_asm_output_def (STREAM, NAME, VALUE)
-#define ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL(STREAM, SY, HI, LO) \
- mmix_asm_output_define_label_difference_symbol (STREAM, SY, HI, LO)
-
-
/* Node: Macros for Initialization */
-/* We're compiling to ELF and linking to MMO; all ELF features that GCC
- care for are there. FIXME: Are they? */
+/* We're compiling to ELF and linking to MMO; fundamental ELF features
+ that GCC depend on are there. */
/* These must be constant strings, since they're used in crtstuff.c. */
#define INIT_SECTION_ASM_OP "\t.section .init,\"ax\" ! mmixal-incompatible"
"$232", "$233", "$234", "$235", "$236", "$237", "$238", "$239", \
"$240", "$241", "$242", "$243", "$244", "$245", "$246", "$247", \
"$248", "$249", "$250", "$251", "$252", "$253", "$254", "$255", \
- ":rD", ":rE", ":rH", ":rJ", ":rR", "ap_!BAD!"}
+ ":rD", ":rE", ":rH", ":rJ", ":rR", "ap_!BAD!", ":rO"}
#define ADDITIONAL_REGISTER_NAMES \
{{"sp", 254}, {":sp", 254}, {"rD", 256}, {"rE", 257}, \
- {"rH", 258}, {"rJ", 259}}
+ {"rH", 258}, {"rJ", MMIX_rJ_REGNUM}, {"rO", MMIX_rO_REGNUM}}
#define PRINT_OPERAND(STREAM, X, CODE) \
mmix_print_operand (STREAM, X, CODE)
#define PRINT_OPERAND_ADDRESS(STREAM, X) \
mmix_print_operand_address (STREAM, X)
-#if 0
-#define USER_LABEL_PREFIX "_"
-#endif
-
#define ASM_OUTPUT_REG_PUSH(STREAM, REGNO) \
mmix_asm_output_reg_push (STREAM, REGNO)
/* Node: SDB and DWARF */
-#define DWARF2_DEBUGGING_INFO
+#define DWARF2_DEBUGGING_INFO 1
#define DWARF2_ASM_LINE_DEBUG_INFO 1
-/* Node: Cross-compilation */
-
-/* FIXME: I don't know whether it is best to tweak emit-rtl.c to handle
- the case where sizeof (float) == word_size / 2 on the target, or to fix
- real.h to define REAL_ARITHMETIC in that case. Anyway, it should be
- documented that a target can define this to force emulation. Note that
- we don't check #ifdef CROSS_COMPILE here; not even if mmix gets
- self-hosted must we do that. Case gcc.c-torture/compile/930611-1.c. */
-#define REAL_ARITHMETIC
-
-
/* Node: Misc */
#define PREDICATE_CODES \
SUBREG, REG, PLUS}}, \
{"mmix_reg_or_constant_operand", \
{CONST_INT, CONST_DOUBLE, SUBREG, REG}}, \
- {"mmix_reg_or_8bit_or_256_operand", \
- {CONST_INT, CONST_DOUBLE, SUBREG, REG}}, \
{"mmix_reg_or_8bit_operand", \
{CONST_INT, CONST_DOUBLE, SUBREG, REG}}, \
{"mmix_reg_or_0_operand", \
than "unsigned int", and we have signed characters. FIXME: measure. */
#define LOAD_EXTEND_OP(MODE) (TARGET_ZERO_EXTEND ? ZERO_EXTEND : SIGN_EXTEND)
-/* Whatever. I don't really know. This has worked before. It's also
- what everybody else is using. */
-#define EASY_DIV_EXPR TRUNC_DIV_EXPR
-
#define MOVE_MAX 8
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-/* We have a choice here too. */
-#if 0
-/* FIXME: Revisit, we don't have scc expanders yet. */
-#define STORE_FLAG_VALUE 1
-#endif
+/* ??? MMIX allows a choice of STORE_FLAG_VALUE. Revisit later,
+ we don't have scc expanders yet. */
#define Pmode DImode
#define FUNCTION_MODE QImode
-/* When in due time we *will* have some specific headers. */
#define NO_IMPLICIT_EXTERN_C
-#define HANDLE_SYSV_PRAGMA
+#define HANDLE_SYSV_PRAGMA 1
/* These are checked. */
#define DOLLARS_IN_IDENTIFIERS 0