/* Definitions of target machine for GNU compiler. MIPS version.
Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
- 1999, 2000, 2001 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Contributed by A. Lichnewsky (lich@inria.inria.fr).
Changed by Michael Meissner (meissner@osf.org).
64 bit r4000 support by Ian Lance Taylor (ian@cygnus.com) and
};
extern char mips_reg_names[][8]; /* register names (a0 vs. $4). */
-extern char mips_print_operand_punct[]; /* print_operand punctuation chars */
+extern char mips_print_operand_punct[256]; /* print_operand punctuation chars */
extern const char *current_function_file; /* filename current function is in */
extern int num_source_filenames; /* current .file # */
extern int inside_function; /* != 0 if inside of a function */
extern struct rtx_def *mips_load_reg2; /* 2nd reg to check for load delay */
extern struct rtx_def *mips_load_reg3; /* 3rd reg to check for load delay */
extern struct rtx_def *mips_load_reg4; /* 4th reg to check for load delay */
-extern struct rtx_def *embedded_pic_fnaddr_rtx; /* function address */
extern int mips_string_length; /* length of strings for mips16 */
-extern struct rtx_def *mips16_gp_pseudo_rtx; /* psuedo reg holding $gp */
/* Functions to change what output section we are using. */
extern void rdata_section PARAMS ((void));
#ifndef ENDIAN_SPEC
#if TARGET_ENDIAN_DEFAULT == 0
-#define ENDIAN_SPEC "%{!EB:%{!meb:-EL}} %{EL} %{EB}"
+#define ENDIAN_SPEC "%{!EB:%{!meb:-EL}} %{EB|meb:-EB}"
#else
-#define ENDIAN_SPEC "%{!EL:%{!mel:-EB}} %{EB} %{EL}"
+#define ENDIAN_SPEC "%{!EL:%{!mel:-EB}} %{EL|mel:-EL}"
#endif
#endif
-/* This macro is similar to `TARGET_SWITCHES' but defines names of
- command options that have values. Its definition is an
- initializer with a subgrouping for each command option.
-
- Each subgrouping contains a string constant, that defines the
- fixed part of the option name, and the address of a variable.
- The variable, type `char *', is set to the variable part of the
- given option if the fixed part matches. The actual option name
- is made by appending `-m' to the specified name.
-
- Here is an example which defines `-mshort-data-NUMBER'. If the
- given option is `-mshort-data-512', the variable `m88k_short_data'
- will be set to the string `"512"'.
-
- extern char *m88k_short_data;
- #define TARGET_OPTIONS { { "short-data-", &m88k_short_data } } */
-
#define TARGET_OPTIONS \
{ \
SUBTARGET_TARGET_OPTIONS \
)
/* ISA has conditional trap instructions. */
-#define ISA_HAS_COND_TRAP (mips_isa >= 2)
+#define ISA_HAS_COND_TRAP (mips_isa >= 2 && ! TARGET_MIPS16)
/* ISA has multiply-accumulate instructions, madd and msub. */
#define ISA_HAS_MADD_MSUB (mips_isa == 32 \
#define GAS_ASM_SPEC "%{march=*} %{mtune=*} %{mcpu=*} %{m4650} %{mmad:-m4650} %{m3900} %{v} %{mgp32} %{mgp64} %(abi_gas_asm_spec) %{mabi=32:%{!mips*:-mips1}}"
-/* We use the o32 abi as default for mips1 and mips2. SGI uses n32/n64 for
- mips3 and mips4 by default, however, this is unsupported at this point in
- binutils so we use o64. This should change when n32/n64 is supported. */
-
extern int mips_abi;
#ifndef MIPS_ABI_DEFAULT
#define MIPS_ABI_DEFAULT ABI_32
#endif
-#if MIPS_ABI_DEFAULT == ABI_32
-#define ABI_GAS_ASM_SPEC "%{mabi=*} \
-%{!mabi=*:%{mips3|mips4|mips5|mips64:-mabi=o64} %{!mips3:%{!mips4:%{!mips5:%{!mips64:-mabi=32}}}}}"
-#endif
-
-#if MIPS_ABI_DEFAULT == ABI_N32
-#define ABI_GAS_ASM_SPEC "%{mabi=*} %{!mabi=*:-mabi=n32}"
-#endif
-
-#if MIPS_ABI_DEFAULT == ABI_64
-#define ABI_GAS_ASM_SPEC "%{mabi=*} %{!mabi=*:-mabi=64}"
-#endif
-
-#if MIPS_ABI_DEFAULT == ABI_EABI
-#define ABI_GAS_ASM_SPEC "%{mabi=*} %{!mabi=*:-mabi=eabi}"
-#endif
-
-#if MIPS_ABI_DEFAULT == ABI_O64
-#define ABI_GAS_ASM_SPEC "\
-%{mabi=*} \
-%{!mabi=*:%{mips1|mips2|mips32:-mabi=32} %{!mips1:%{!mips2:%{!mips3:%{!mips32:-mabi=o64}}}}}"
-#endif
-
-#if MIPS_ABI_DEFAULT == ABI_MEABI
-#define ABI_GAS_ASM_SPEC "\
-%{mabi=*} \
-%{!mabi=*:-mabi=meabi }"
-#endif
-
#ifndef ABI_GAS_ASM_SPEC
- #error "Unhandled MIPS_ABI_DEFAULT"
+#define ABI_GAS_ASM_SPEC ""
#endif
/* TARGET_ASM_SPEC is used to select either MIPS_AS_ASM_SPEC or
be overridden by subtargets. */
#ifndef SUBTARGET_CPP_SIZE_SPEC
+
+/* Rules for SIZE_TYPE and PTRDIFF_TYPE are:
+
+ both gp64 and long64 (not the options, but the corresponding flags,
+ so defaults came into play) are required in order to have `long' in
+ SIZE_TYPE and PTRDIFF_TYPE.
+
+ on eabi, -mips1, -mips2 and -mips32 disable gp64, whereas mips3,
+ -mips4, -mips5 and -mips64 enable it.
+
+ on other ABIs, -mips* options do not affect gp32/64, but the
+ default ISA affects the default gp size.
+
+ -mgp32 disables gp64, whereas -mgp64 enables it.
+
+ on eabi, gp64 implies long64.
+
+ -mlong64, and -mabi=64 are the only other ways to enable long64.
+
+*/
+
+#if MIPS_ISA_DEFAULT != 3 && MIPS_ISA_DEFAULT != 4 && MIPS_ISA_DEFAULT != 5 && MIPS_ISA_DEFAULT != 64
+
+/* 32-bit cases first. */
+
+#if MIPS_ABI_DEFAULT == ABI_EABI
#define SUBTARGET_CPP_SIZE_SPEC "\
-%{mlong64:%{!mips1:%{!mips2:%{!mips32:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}}} \
-%{!mlong64:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int}"
+%{mabi=eabi|!mabi=*:\
+ %{mips1|mips2|mips32|mgp32|mlong32: \
+ -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
+ %{mips3|mips4|mips5|mips64|mgp64: \
+ -D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int} \
+ %{!mips3:%{!mips4:%{!mips5:%{!mips64:%{!mgp64: \
+ -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int}}}}}}}}}}} \
+%{mabi=o64:\
+ %{!mgp64|!-mlong64:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{mgp64:%{mlong64:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}} \
+%{mabi=32:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+"
+#define LONG_MAX_SPEC "\
+%{mlong64:-D__LONG_MAX__=9223372036854775807L}\
+%{!mlong64:\
+ %{mabi=eabi|!mabi=*:\
+ %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
+ %{mips3|mips4|mips5|mips64|mgp64: \
+ -D__LONG_MAX__=9223372036854775807L}}}}}}}} \
+"
+#else /* ABI_DEFAULT != ABI_EABI */
+#define LONG_MAX_SPEC "\
+%{mlong64:-D__LONG_MAX__=9223372036854775807L}\
+%{!mlong64:\
+ %{mabi=eabi:\
+ %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
+ %{mips3|mips4|mips5|mips64|mgp64: \
+ -D__LONG_MAX__=9223372036854775807L}}}}}}}} \
+"
#endif
-/* SUBTARGET_CPP_SPEC is passed to the preprocessor. It may be
- overridden by subtargets. */
-#ifndef SUBTARGET_CPP_SPEC
-#define SUBTARGET_CPP_SPEC ""
+#if MIPS_ABI_DEFAULT == ABI_O64
+#define SUBTARGET_CPP_SIZE_SPEC "\
+%{mabi=eabi:\
+ %{mips1|mips2|mips32|mgp32|mlong32: \
+ -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
+ %{mips3|mips4|mips5|mips64|mgp64: \
+ -D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int} \
+ %{!mips3:%{!mips4:%{!mips5:%{!mips64:%{!mgp64: \
+ -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int}}}}}}}}}}} \
+%{mabi=o64|!mabi=*:\
+ %{!mgp64|!-mlong64:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{mgp64:%{mlong64:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}} \
+%{mabi=32:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+%{mabi=meabi:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+"
+#endif
+
+#if MIPS_ABI_DEFAULT == ABI_32
+#define SUBTARGET_CPP_SIZE_SPEC "\
+%{mabi=eabi:\
+ %{mips1|mips2|mips32|mgp32|mlong32: \
+ -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
+ %{mips3|mips4|mips5|mips64|mgp64: \
+ -D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int} \
+ %{!mips3:%{!mips4:%{!mips5:%{!mips64:%{!mgp64: \
+ -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int}}}}}}}}}}} \
+%{mabi=o64:\
+ %{!mgp64|!-mlong64:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{mgp64:%{mlong64:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}} \
+%{mabi=32|!mabi=*:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+%{mabi=meabi:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+"
+#endif
+
+#if MIPS_ABI_DEFAULT == ABI_MEABI
+#define SUBTARGET_CPP_SIZE_SPEC "\
+%{mabi=eabi:\
+ %{mips1|mips2|mips32|mgp32|mlong32: \
+ -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
+ %{mips3|mips4|mips5|mips64|mgp64: \
+ -D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int} \
+ %{!mips3:%{!mips4:%{!mips5:%{!mips64:%{!mgp64: \
+ -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int}}}}}}}}}}} \
+%{mabi=o64:\
+ %{!mgp64|!-mlong64:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{mgp64:%{mlong64:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}} \
+%{mabi=32:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+%{mabi=meabi|!mabi=*:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+"
#endif
-/* If we're using 64bit longs, then we have to define __LONG_MAX__
- correctly. Similarly for 64bit ints and __INT_MAX__. */
-#ifndef LONG_MAX_SPEC
-#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_LONG64)
-#define LONG_MAX_SPEC "%{!mlong32:-D__LONG_MAX__=9223372036854775807L}"
#else
-#define LONG_MAX_SPEC "%{mlong64:-D__LONG_MAX__=9223372036854775807L}"
+
+/* 64-bit default ISA. */
+#if MIPS_ABI_DEFAULT == ABI_EABI
+#define SUBTARGET_CPP_SIZE_SPEC "\
+%{mabi=eabi|!mabi=*: \
+ %{mips1|mips2|mips32|mgp32|mlong32: \
+ -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
+ -D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}}}}} \
+%{mabi=o64:\
+ %{mgp32|!-mlong64:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{!mgp32:%{mlong64:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}} \
+%{mabi=32:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+%{mabi=meabi:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+"
+#define LONG_MAX_SPEC "\
+%{mlong64:-D__LONG_MAX__=9223372036854775807L}\
+%{!mlong64:\
+ %{mabi=eabi|!mabi=*:\
+ %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
+ -D__LONG_MAX__=9223372036854775807L}}}}}}}\
+"
+#else /* ABI_DEFAULT != ABI_EABI */
+#define LONG_MAX_SPEC "\
+%{mlong64:-D__LONG_MAX__=9223372036854775807L}\
+%{!mlong64:\
+ %{mabi=eabi:\
+ %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
+ -D__LONG_MAX__=9223372036854775807L}}}}}}}\
+"
+#endif
+
+#if MIPS_ABI_DEFAULT == ABI_O64
+#define SUBTARGET_CPP_SIZE_SPEC "\
+%{mabi=eabi: \
+ %{mips1|mips2|mips32|mgp32|mlong32: \
+ -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
+ -D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}}}}} \
+%{mabi=o64|!mabi=*:\
+ %{mgp32|!-mlong64:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{!mgp32:%{mlong64:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}} \
+%{mabi=32:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+%{mabi=meabi:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+"
+#endif
+
+#if MIPS_ABI_DEFAULT == ABI_32
+#define SUBTARGET_CPP_SIZE_SPEC "\
+%{mabi=eabi:\
+ %{mips1|mips2|mips32|mgp32|mlong32: \
+ -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
+ -D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}}}}} \
+%{mabi=o64:\
+ %{mgp32|!-mlong64:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{!mgp32:%{mlong64:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}} \
+%{mabi=32|!mabi=*:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+%{mabi=meabi:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+"
+#endif
+
+#if MIPS_ABI_DEFAULT == ABI_MEABI
+#define SUBTARGET_CPP_SIZE_SPEC "\
+%{mabi=eabi:\
+ %{mips1|mips2|mips32|mgp32|mlong32: \
+ -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{!mips1:%{!mips2:%{!mips32:%{!mgp32:%{!mlong32: \
+ -D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}}}}} \
+%{mabi=o64:\
+ %{mgp32|!-mlong64:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+ %{!mgp32:%{mlong64:-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int}}} \
+%{mabi=32:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+%{mabi=meabi|!mabi=*:-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int} \
+"
#endif
+
+#endif
+
+#endif
+
+/* SUBTARGET_CPP_SPEC is passed to the preprocessor. It may be
+ overridden by subtargets. */
+#ifndef SUBTARGET_CPP_SPEC
+#define SUBTARGET_CPP_SPEC ""
#endif
/* Define appropriate macros for fpr register size. */
#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (VOIDmode, GP_REG_FIRST + 31)
/* Describe how we implement __builtin_eh_return. */
-#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + GP_ARG_FIRST : INVALID_REGNUM)
+#define EH_RETURN_DATA_REGNO(N) ((N) < (TARGET_MIPS16 ? 2 : 4) ? (N) + GP_ARG_FIRST : INVALID_REGNUM)
#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, GP_REG_FIRST + 3)
/* Offsets recorded in opcodes are a multiple of this alignment factor.
\f
/* Target machine storage layout */
-/* Define in order to support both big and little endian float formats
- in the same gcc binary. */
-#define REAL_ARITHMETIC
-
/* Define this if most significant bit is lowest numbered
in instructions that operate on numbered bit-fields.
*/
#define LIBGCC2_WORDS_BIG_ENDIAN 0
#endif
-/* Number of bits in an addressable storage unit */
-#define BITS_PER_UNIT 8
-
-/* Width in bits of a "word", which is the contents of a machine register.
- Note that this is not necessarily the width of data type `int';
- if using 16-bit ints on a 68000, this would still be 32.
- But on a machine with 16-bit registers, this would be 16. */
-#define BITS_PER_WORD (TARGET_64BIT ? 64 : 32)
#define MAX_BITS_PER_WORD 64
/* Width of a word, in units (bytes). */
/* For MIPS, width of a floating point register. */
#define UNITS_PER_FPREG (TARGET_FLOAT64 ? 8 : 4)
+/* If register $f0 holds a floating-point value, $f(0 + FP_INC) is
+ the next available register. */
+#define FP_INC (TARGET_FLOAT64 || TARGET_SINGLE_FLOAT ? 1 : 2)
+
+/* The largest size of value that can be held in floating-point registers. */
+#define UNITS_PER_FPVALUE (FP_INC * UNITS_PER_FPREG)
+
/* A C expression for the size in bits of the type `int' on the
target machine. If you don't define this, the default is one
word. */
#define INT_TYPE_SIZE (TARGET_INT64 ? 64 : 32)
-#define MAX_INT_TYPE_SIZE 64
/* Tell the preprocessor the maximum size of wchar_t. */
#ifndef MAX_WCHAR_TYPE_SIZE
#ifndef WCHAR_TYPE_SIZE
-#define MAX_WCHAR_TYPE_SIZE MAX_INT_TYPE_SIZE
+#define MAX_WCHAR_TYPE_SIZE 64
#endif
#endif
words. */
#define LONG_LONG_TYPE_SIZE 64
-/* A C expression for the size in bits of the type `char' on the
- target machine. If you don't define this, the default is one
- quarter of a word. (If this would be less than one storage unit,
- it is rounded up to one unit.) */
-#define CHAR_TYPE_SIZE BITS_PER_UNIT
-
/* A C expression for the size in bits of the type `float' on the
target machine. If you don't define this, the default is one
word. */
#define POINTER_BOUNDARY (Pmode == DImode ? 64 : 32)
/* Allocation boundary (in *bits*) for storing arguments in argument list. */
-#define PARM_BOUNDARY (TARGET_64BIT ? 64 : 32)
+#define PARM_BOUNDARY ((mips_abi == ABI_O64 || mips_abi == ABI_N32 \
+ || mips_abi == ABI_64 \
+ || (mips_abi == ABI_EABI && TARGET_64BIT)) ? 64 : 32)
/* Allocation boundary (in *bits*) for the code of a function. */
#define FUNCTION_BOUNDARY 32
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 \
}
+/* Like `CALL_USED_REGISTERS' but used to overcome a historical
+ problem which makes CALL_USED_REGISTERS *always* include
+ all the FIXED_REGISTERS. Until this problem has been
+ resolved this macro can be used to overcome this situation.
+ In particular, block_propagate() requires this list
+ be acurate, or we can remove registers which should be live.
+ This macro is used in regs_invalidated_by_call. */
+
+
+#define CALL_REALLY_USED_REGISTERS \
+{ /* General registers. */ \
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, \
+ /* Floating-point registers. */ \
+ 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, \
+ /* Others. */ \
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 \
+}
/* Internal macros to classify a register number as to whether it's a
general purpose register, a floating point register, a
#define PIC_OFFSET_TABLE_REGNUM (GP_REG_FIRST + 28)
#define PIC_FUNCTION_ADDR_REGNUM (GP_REG_FIRST + 25)
-
-/* Initialize embedded_pic_fnaddr_rtx before RTL generation for
- each function. We used to do this in FINALIZE_PIC, but FINALIZE_PIC
- isn't always called for static inline functions. */
-#define INIT_EXPANDERS \
-do { \
- embedded_pic_fnaddr_rtx = NULL; \
- mips16_gp_pseudo_rtx = NULL; \
-} while (0)
\f
/* Define the classes of registers for register constraints in the
machine description. Also define ranges of constants.
HI_AND_GR_REGS, /* union classes */
LO_AND_GR_REGS,
HILO_AND_GR_REGS,
+ HI_AND_FP_REGS,
ST_REGS, /* status registers (fp status) */
ALL_REGS, /* all registers */
LIM_REG_CLASSES /* max value + 1 */
"HI_AND_GR_REGS", \
"LO_AND_GR_REGS", \
"HILO_AND_GR_REGS", \
+ "HI_AND_FP_REGS", \
"ST_REGS", \
"ALL_REGS" \
}
{ 0xffffffff, 0x00000000, 0x00000001 }, /* union classes */ \
{ 0xffffffff, 0x00000000, 0x00000002 }, \
{ 0xffffffff, 0x00000000, 0x00000004 }, \
+ { 0x00000000, 0xffffffff, 0x00000001 }, \
{ 0x00000000, 0x00000000, 0x000007f8 }, /* status registers */ \
{ 0xffffffff, 0xffffffff, 0x000007ff } /* all registers */ \
}
'z' FP Status register
'b' All registers */
-extern enum reg_class mips_char_to_class[];
+extern enum reg_class mips_char_to_class[256];
#define REG_CLASS_FROM_LETTER(C) mips_char_to_class[(unsigned char)(C)]
: CLASS_UNITS (MODE, UNITS_PER_WORD))
/* If defined, gives a class of registers that cannot be used as the
- operand of a SUBREG that changes the mode of the object illegally. */
+ operand of a SUBREG that changes the mode of the object illegally.
+ When FP regs are larger than integer regs... Er, anyone remember what
+ goes wrong?
-#define CLASS_CANNOT_CHANGE_MODE \
- (TARGET_FLOAT64 && ! TARGET_64BIT ? FP_REGS : NO_REGS)
+ In little-endian mode, the hi-lo registers are numbered backwards,
+ so (subreg:SI (reg:DI hi) 0) gets the high word instead of the low
+ word as intended. */
+
+#define CLASS_CANNOT_CHANGE_MODE \
+ (TARGET_BIG_ENDIAN \
+ ? (TARGET_FLOAT64 && ! TARGET_64BIT ? FP_REGS : NO_REGS) \
+ : (TARGET_FLOAT64 && ! TARGET_64BIT ? HI_AND_FP_REGS : HI_REG))
/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
to give us MIPS cc compatibility. */
#define RETURN_IN_MEMORY(TYPE) \
- (TYPE_MODE (TYPE) == BLKmode)
+ mips_return_in_memory (TYPE)
\f
-/* A code distinguishing the floating point format of the target
- machine. There are three defined values: IEEE_FLOAT_FORMAT,
- VAX_FLOAT_FORMAT, and UNKNOWN_FLOAT_FORMAT. */
#define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
{ \
if (TARGET_MIPS16) \
sorry ("mips16 function profiling"); \
- fprintf (FILE, "\t.set\tnoreorder\n"); \
fprintf (FILE, "\t.set\tnoat\n"); \
fprintf (FILE, "\tmove\t%s,%s\t\t# save current return address\n", \
reg_names[GP_REG_FIRST + 1], reg_names[GP_REG_FIRST + 31]); \
- fprintf (FILE, "\tjal\t_mcount\n"); \
fprintf (FILE, \
"\t%s\t%s,%s,%d\t\t# _mcount pops 2 words from stack\n", \
TARGET_64BIT ? "dsubu" : "subu", \
reg_names[STACK_POINTER_REGNUM], \
reg_names[STACK_POINTER_REGNUM], \
Pmode == DImode ? 16 : 8); \
- fprintf (FILE, "\t.set\treorder\n"); \
+ fprintf (FILE, "\tjal\t_mcount\n"); \
fprintf (FILE, "\t.set\tat\n"); \
}
If you are changing this macro, you should look at
mips_select_section and see if it needs a similar change. */
-#define ENCODE_SECTION_INFO(DECL) \
+#define ENCODE_SECTION_INFO(DECL, FIRST) \
do \
{ \
if (TARGET_MIPS16) \
{ \
- if (TREE_CODE (DECL) == STRING_CST \
+ if ((FIRST) && TREE_CODE (DECL) == STRING_CST \
&& ! flag_writable_strings \
/* If this string is from a function, and the function will \
go in a gnu linkonce section, then we can't directly \
\
else if (HALF_PIC_P ()) \
{ \
- HALF_PIC_ENCODE (DECL); \
+ if (FIRST) \
+ HALF_PIC_ENCODE (DECL); \
} \
} \
while (0)
Do not define this if the table should contain absolute addresses. */
#define CASE_VECTOR_PC_RELATIVE (TARGET_MIPS16)
-/* Specify the tree operation to be used to convert reals to integers. */
-#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
-
-/* This is the kind of divide that is easiest to do in the general case. */
-#define EASY_DIV_EXPR TRUNC_DIV_EXPR
-
/* Define this as 1 if `char' should by default be signed; else as 0. */
#ifndef DEFAULT_SIGNED_CHAR
#define DEFAULT_SIGNED_CHAR 1
#define STORE_FLAG_VALUE 1
-/* Define this if zero-extension is slow (more than one real instruction). */
-#define SLOW_ZERO_EXTEND
-
/* Define this to be nonzero if shift instructions ignore all but the low-order
few bits. */
#define SHIFT_COUNT_TRUNCATED 1
#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
sprintf ((LABEL), "*%s%s%ld", (LOCAL_LABEL_PREFIX), (PREFIX), (long)(NUM))
-/* This is how to output an assembler line defining a `double' constant. */
-
-#define ASM_OUTPUT_DOUBLE(STREAM,VALUE) \
- mips_output_double (STREAM, VALUE)
-
-
-/* This is how to output an assembler line defining a `float' constant. */
-
-#define ASM_OUTPUT_FLOAT(STREAM,VALUE) \
- mips_output_float (STREAM, VALUE)
-
-
-/* This is how to output an assembler line defining an `int' constant. */
-
-#define ASM_OUTPUT_INT(STREAM,VALUE) \
-do { \
- fprintf (STREAM, "\t.word\t"); \
- output_addr_const (STREAM, (VALUE)); \
- fprintf (STREAM, "\n"); \
-} while (0)
-
-/* Likewise for 64 bit, `char' and `short' constants.
-
- FIXME: operand_subword can't handle some complex constant expressions
- that output_addr_const can (for example it does not call
- simplify_subtraction). Since GAS can handle dword, even for mipsII,
- rely on that to avoid operand_subword for most of the cases where this
- matters. Try gcc.c-torture/compile/930326-1.c with -mips2 -mlong64,
- or the same case with the type of 'i' changed to long long.
-
-*/
-
-#define ASM_OUTPUT_DOUBLE_INT(STREAM,VALUE) \
-do { \
- if (TARGET_64BIT || TARGET_GAS) \
- { \
- fprintf (STREAM, "\t.dword\t"); \
- if (HOST_BITS_PER_WIDE_INT < 64 || GET_CODE (VALUE) != CONST_INT) \
- /* We can't use 'X' for negative numbers, because then we won't \
- get the right value for the upper 32 bits. */ \
- output_addr_const (STREAM, VALUE); \
- else \
- /* We must use 'X', because otherwise LONG_MIN will print as \
- a number that the Irix 6 assembler won't accept. */ \
- print_operand (STREAM, VALUE, 'X'); \
- fprintf (STREAM, "\n"); \
- } \
- else \
- { \
- assemble_integer (operand_subword ((VALUE), 0, 0, DImode), \
- UNITS_PER_WORD, BITS_PER_WORD, 1); \
- assemble_integer (operand_subword ((VALUE), 1, 0, DImode), \
- UNITS_PER_WORD, BITS_PER_WORD, 1); \
- } \
-} while (0)
-
-#define ASM_OUTPUT_SHORT(STREAM,VALUE) \
-{ \
- fprintf (STREAM, "\t.half\t"); \
- output_addr_const (STREAM, (VALUE)); \
- fprintf (STREAM, "\n"); \
-}
-
-#define ASM_OUTPUT_CHAR(STREAM,VALUE) \
-{ \
- fprintf (STREAM, "\t.byte\t"); \
- output_addr_const (STREAM, (VALUE)); \
- fprintf (STREAM, "\n"); \
-}
-
-/* This is how to output an assembler line for a numeric constant byte. */
-
-#define ASM_OUTPUT_BYTE(STREAM,VALUE) \
- fprintf (STREAM, "\t.byte\t0x%x\n", (int)(VALUE))
-
/* This is how to output an element of a case-vector that is absolute. */
#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \