Commit 46299de9 by Ian Lance Taylor

Add support for r4650, and permit HI/LO to be allocated

From-SVN: r8774
parent 2839cf45
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
Changes by Michael Meissner, meissner@osf.org. Changes by Michael Meissner, meissner@osf.org.
64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and 64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
Brendan Eich, brendan@microunity.com. Brendan Eich, brendan@microunity.com.
Copyright (C) 1989, 1990, 1991, 1993, 1994 Free Software Foundation, Inc. Copyright (C) 1989, 90, 91, 93, 94, 1995 Free Software Foundation, Inc.
This file is part of GNU CC. This file is part of GNU CC.
...@@ -2818,7 +2818,10 @@ function_arg (cum, mode, type, named) ...@@ -2818,7 +2818,10 @@ function_arg (cum, mode, type, named)
case DFmode: case DFmode:
if (! TARGET_64BIT) if (! TARGET_64BIT)
cum->arg_words += (cum->arg_words & 1); cum->arg_words += (cum->arg_words & 1);
regbase = (cum->gp_reg_found || TARGET_SOFT_FLOAT || cum->arg_number >= 2 regbase = ((cum->gp_reg_found
|| TARGET_SOFT_FLOAT
|| TARGET_SINGLE_FLOAT
|| cum->arg_number >= 2)
? GP_ARG_FIRST ? GP_ARG_FIRST
: FP_ARG_FIRST); : FP_ARG_FIRST);
break; break;
...@@ -3166,6 +3169,10 @@ override_options () ...@@ -3166,6 +3169,10 @@ override_options ()
mips_cpu = PROCESSOR_R4000; mips_cpu = PROCESSOR_R4000;
else if (!strcmp (p, "4600")) else if (!strcmp (p, "4600"))
mips_cpu = PROCESSOR_R4600; mips_cpu = PROCESSOR_R4600;
/* Although the r4650 adds a couple of instructions, it uses
the r4600 pipeline. */
else if (!strcmp (p, "4650"))
mips_cpu = PROCESSOR_R4600;
break; break;
case '6': case '6':
...@@ -3350,12 +3357,14 @@ override_options () ...@@ -3350,12 +3357,14 @@ override_options ()
temp = ((TARGET_FLOAT64 || ((regno & 1) == 0)) temp = ((TARGET_FLOAT64 || ((regno & 1) == 0))
&& (class == MODE_FLOAT && (class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_FLOAT
|| (TARGET_DEBUG_H_MODE && class == MODE_INT))); || (TARGET_DEBUG_H_MODE && class == MODE_INT))
&& (! TARGET_SINGLE_FLOAT || size <= 4));
else if (MD_REG_P (regno)) else if (MD_REG_P (regno))
{ {
if (TARGET_64BIT) if (TARGET_64BIT)
temp = (mode == DImode temp = (mode == DImode
|| mode == SImode
|| (regno == MD_REG_FIRST && mode == TImode)); || (regno == MD_REG_FIRST && mode == TImode));
else else
temp = (mode == SImode temp = (mode == SImode
...@@ -4401,7 +4410,7 @@ compute_frame_size (size) ...@@ -4401,7 +4410,7 @@ compute_frame_size (size)
} }
/* Calculate space needed for fp registers. */ /* Calculate space needed for fp registers. */
if (TARGET_FLOAT64) if (TARGET_FLOAT64 || TARGET_SINGLE_FLOAT)
{ {
fp_inc = 1; fp_inc = 1;
fp_bits = 1; fp_bits = 1;
...@@ -4422,7 +4431,7 @@ compute_frame_size (size) ...@@ -4422,7 +4431,7 @@ compute_frame_size (size)
} }
gp_reg_rounded = MIPS_STACK_ALIGN (gp_reg_size); gp_reg_rounded = MIPS_STACK_ALIGN (gp_reg_size);
total_size += gp_reg_rounded + fp_reg_size; total_size += gp_reg_rounded + MIPS_STACK_ALIGN (fp_reg_size);
if (total_size == extra_size) if (total_size == extra_size)
total_size = extra_size = 0; total_size = extra_size = 0;
...@@ -4626,7 +4635,7 @@ save_restore_insns (store_p, large_reg, large_offset, file) ...@@ -4626,7 +4635,7 @@ save_restore_insns (store_p, large_reg, large_offset, file)
/* Save floating point registers if needed. */ /* Save floating point registers if needed. */
if (fmask) if (fmask)
{ {
int fp_inc = (TARGET_FLOAT64) ? 1 : 2; int fp_inc = (TARGET_FLOAT64 || TARGET_SINGLE_FLOAT) ? 1 : 2;
int fp_size = fp_inc * UNITS_PER_FPREG; int fp_size = fp_inc * UNITS_PER_FPREG;
/* Pick which pointer to use as a base register. */ /* Pick which pointer to use as a base register. */
...@@ -4700,8 +4709,10 @@ save_restore_insns (store_p, large_reg, large_offset, file) ...@@ -4700,8 +4709,10 @@ save_restore_insns (store_p, large_reg, large_offset, file)
{ {
if (file == (FILE *)0) if (file == (FILE *)0)
{ {
rtx reg_rtx = gen_rtx (REG, DFmode, regno); enum machine_mode sz =
rtx mem_rtx = gen_rtx (MEM, DFmode, TARGET_SINGLE_FLOAT ? SFmode : DFmode;
rtx reg_rtx = gen_rtx (REG, sz, regno);
rtx mem_rtx = gen_rtx (MEM, sz,
gen_rtx (PLUS, Pmode, base_reg_rtx, gen_rtx (PLUS, Pmode, base_reg_rtx,
GEN_INT (fp_offset - base_offset))); GEN_INT (fp_offset - base_offset)));
...@@ -4712,7 +4723,9 @@ save_restore_insns (store_p, large_reg, large_offset, file) ...@@ -4712,7 +4723,9 @@ save_restore_insns (store_p, large_reg, large_offset, file)
} }
else else
fprintf (file, "\t%s\t%s,%ld(%s)\n", fprintf (file, "\t%s\t%s,%ld(%s)\n",
(store_p) ? "s.d" : "l.d", (TARGET_SINGLE_FLOAT
? ((store_p) ? "s.s" : "l.s")
: ((store_p) ? "s.d" : "l.d")),
reg_names[regno], reg_names[regno],
fp_offset - base_offset, fp_offset - base_offset,
reg_names[REGNO(base_reg_rtx)]); reg_names[REGNO(base_reg_rtx)]);
...@@ -5376,3 +5389,25 @@ mips_select_section (decl, reloc) ...@@ -5376,3 +5389,25 @@ mips_select_section (decl, reloc)
data_section (); data_section ();
} }
} }
/* Moving the HI or LO register somewhere requires a general register. */
enum reg_class
mips_secondary_reload_class (class, mode, x)
enum reg_class class;
enum machine_mode mode;
rtx x;
{
if (class != HI_REG && class != LO_REG && class != MD_REGS)
return NO_REGS;
if (GET_CODE (x) == REG)
{
int regno = true_regnum (x);
if (regno >= GP_REG_FIRST && regno <= GP_REG_LAST)
return NO_REGS;
}
return GR_REGS;
}
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
Changed by Michael Meissner, meissner@osf.org Changed by Michael Meissner, meissner@osf.org
64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and 64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
Brendan Eich, brendan@microunity.com. Brendan Eich, brendan@microunity.com.
Copyright (C) 1989, 90, 91, 92, 93, 1994 Free Software Foundation, Inc. Copyright (C) 1989, 90, 91, 92, 93, 94, 1995 Free Software Foundation, Inc.
This file is part of GNU CC. This file is part of GNU CC.
...@@ -260,8 +260,8 @@ extern char *mktemp (); ...@@ -260,8 +260,8 @@ extern char *mktemp ();
#define MASK_EMBEDDED_PIC 0x00004000 /* Generate embedded PIC code */ #define MASK_EMBEDDED_PIC 0x00004000 /* Generate embedded PIC code */
#define MASK_EMBEDDED_DATA 0x00008000 /* Reduce RAM usage, not fast code */ #define MASK_EMBEDDED_DATA 0x00008000 /* Reduce RAM usage, not fast code */
#define MASK_BIG_ENDIAN 0x00010000 /* Generate big endian code */ #define MASK_BIG_ENDIAN 0x00010000 /* Generate big endian code */
#define MASK_UNUSED3 0x00020000 #define MASK_SINGLE_FLOAT 0x00020000 /* Only single precision FPU. */
#define MASK_UNUSED2 0x00040000 #define MASK_MAD 0x00040000 /* Generate mad/madu as on 4650. */
#define MASK_UNUSED1 0x00080000 #define MASK_UNUSED1 0x00080000
/* Dummy switches used only in spec's*/ /* Dummy switches used only in spec's*/
...@@ -341,6 +341,11 @@ extern char *mktemp (); ...@@ -341,6 +341,11 @@ extern char *mktemp ();
/* generate big endian code. */ /* generate big endian code. */
#define TARGET_BIG_ENDIAN (target_flags & MASK_BIG_ENDIAN) #define TARGET_BIG_ENDIAN (target_flags & MASK_BIG_ENDIAN)
#define TARGET_SINGLE_FLOAT (target_flags & MASK_SINGLE_FLOAT)
#define TARGET_DOUBLE_FLOAT (! TARGET_SINGLE_FLOAT)
#define TARGET_MAD (target_flags & MASK_MAD)
/* Macro to define tables used to set the flags. /* Macro to define tables used to set the flags.
This is a list in braces of pairs in braces, This is a list in braces of pairs in braces,
each pair being { "NAME", VALUE } each pair being { "NAME", VALUE }
...@@ -383,6 +388,11 @@ extern char *mktemp (); ...@@ -383,6 +388,11 @@ extern char *mktemp ();
{"no-embedded-data", -MASK_EMBEDDED_DATA}, \ {"no-embedded-data", -MASK_EMBEDDED_DATA}, \
{"eb", MASK_BIG_ENDIAN}, \ {"eb", MASK_BIG_ENDIAN}, \
{"el", -MASK_BIG_ENDIAN}, \ {"el", -MASK_BIG_ENDIAN}, \
{"single-float", MASK_SINGLE_FLOAT}, \
{"double-float", -MASK_SINGLE_FLOAT}, \
{"mad", MASK_MAD}, \
{"no-mad", -MASK_MAD}, \
{"4650", MASK_MAD | MASK_SINGLE_FLOAT}, \
{"debug", MASK_DEBUG}, \ {"debug", MASK_DEBUG}, \
{"debuga", MASK_DEBUG_A}, \ {"debuga", MASK_DEBUG_A}, \
{"debugb", MASK_DEBUG_B}, \ {"debugb", MASK_DEBUG_B}, \
...@@ -575,7 +585,7 @@ while (0) ...@@ -575,7 +585,7 @@ while (0)
%{pipe: %e-pipe is not supported.} \ %{pipe: %e-pipe is not supported.} \
%{K}} \ %{K}} \
%{!mmips-as: \ %{!mmips-as: \
%{mcpu=*}} \ %{mcpu=*} %{m4650} %{mmad:-m4650}} \
%{G*} %{EB} %{EL} %{mips1} %{mips2} %{mips3} %{v} \ %{G*} %{EB} %{EL} %{mips1} %{mips2} %{mips3} %{v} \
%{noasmopt:-O0} \ %{noasmopt:-O0} \
%{!noasmopt:%{O:-O2} %{O1:-O2} %{O2:-O2} %{O3:-O3}} \ %{!noasmopt:%{O:-O2} %{O1:-O2} %{O2:-O2} %{O3:-O3}} \
...@@ -594,7 +604,7 @@ while (0) ...@@ -594,7 +604,7 @@ while (0)
%{pipe: %e-pipe is not supported.} \ %{pipe: %e-pipe is not supported.} \
%{K}} \ %{K}} \
%{mgas: \ %{mgas: \
%{mcpu=*}} \ %{mcpu=*} %{m4650} %{mmad:-m4650}} \
%{G*} %{EB} %{EL} %{mips1} %{mips2} %{mips3} %{v} \ %{G*} %{EB} %{EL} %{mips1} %{mips2} %{mips3} %{v} \
%{noasmopt:-O0} \ %{noasmopt:-O0} \
%{!noasmopt:%{O:-O2} %{O1:-O2} %{O2:-O2} %{O3:-O3}} \ %{!noasmopt:%{O:-O2} %{O1:-O2} %{O2:-O2} %{O3:-O3}} \
...@@ -662,7 +672,11 @@ while (0) ...@@ -662,7 +672,11 @@ while (0)
#ifndef CC1_SPEC #ifndef CC1_SPEC
#define CC1_SPEC "\ #define CC1_SPEC "\
%{gline:%{!g:%{!g0:%{!g1:%{!g2: -g1}}}}} \ %{gline:%{!g:%{!g0:%{!g1:%{!g2: -g1}}}}} \
%{mips1:-mfp32 -mgp32}%{mips2:-mfp32 -mgp32}%{mips3:-mfp64 -mgp64} \ %{mips1:-mfp32 -mgp32}%{mips2:-mfp32 -mgp32}\
%{mips3:%{!msingle-float:%{!m4650:-mfp64}} -mgp64} \
%{mfp64:%{msingle-float:%emay not use both -mfp64 and -msingle-float}} \
%{mfp64:%{m4650:%emay not use both -mfp64 and -m4650}} \
%{m4650:-mcpu=r4650} \
%{G*} %{EB:-meb} %{EL:-mel} %{EB:%{EL:%emay not use both -EB and -EL}} \ %{G*} %{EB:-meb} %{EL:-mel} %{EB:%{EL:%emay not use both -EB and -EL}} \
%{pic-none: -mno-half-pic} \ %{pic-none: -mno-half-pic} \
%{pic-lib: -mhalf-pic} \ %{pic-lib: -mhalf-pic} \
...@@ -1138,7 +1152,7 @@ do { \ ...@@ -1138,7 +1152,7 @@ do { \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 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 \ 0, 0, 1 \
} }
...@@ -1211,7 +1225,9 @@ do { \ ...@@ -1211,7 +1225,9 @@ do { \
#define HARD_REGNO_NREGS(REGNO, MODE) \ #define HARD_REGNO_NREGS(REGNO, MODE) \
(! FP_REG_P (REGNO) \ (! FP_REG_P (REGNO) \
? ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) \ ? ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) \
: (((GET_MODE_SIZE (MODE) + 7) / 8) << (TARGET_FLOAT64 == 0))) : (TARGET_SINGLE_FLOAT \
? ((GET_MODE_SIZE (MODE) + UNITS_PER_FPREG - 1) / UNITS_PER_FPREG) \
: (((GET_MODE_SIZE (MODE) + 7) / 8) << (TARGET_FLOAT64 == 0))))
/* Value is 1 if hard register REGNO can hold a value of machine-mode /* Value is 1 if hard register REGNO can hold a value of machine-mode
MODE. In 32 bit mode, require that DImode and DFmode be in even MODE. In 32 bit mode, require that DImode and DFmode be in even
...@@ -1534,6 +1550,16 @@ extern enum reg_class mips_char_to_class[]; ...@@ -1534,6 +1550,16 @@ extern enum reg_class mips_char_to_class[];
&& ((CLASS1 == GR_REGS && CLASS2 == FP_REGS) \ && ((CLASS1 == GR_REGS && CLASS2 == FP_REGS) \
|| (CLASS2 == GR_REGS && CLASS1 == FP_REGS)))) || (CLASS2 == GR_REGS && CLASS1 == FP_REGS))))
/* The HI and LO registers can only be reloaded via the general
registers. */
#define SECONDARY_RELOAD_CLASS(CLASS, MODE, X) \
mips_secondary_reload_class (CLASS, MODE, X)
/* Not declared above, with the other functions, because enum
reg_class is not declared yet. */
extern enum reg_class mips_secondary_reload_class ();
/* Return the maximum number of consecutive registers /* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS. */ needed to represent mode MODE in a register of class CLASS. */
...@@ -1816,9 +1842,11 @@ extern struct mips_frame_info current_frame_info; ...@@ -1816,9 +1842,11 @@ extern struct mips_frame_info current_frame_info;
#define LIBCALL_VALUE(MODE) \ #define LIBCALL_VALUE(MODE) \
gen_rtx (REG, MODE, \ gen_rtx (REG, MODE, \
(GET_MODE_CLASS (MODE) == MODE_FLOAT) \ ((GET_MODE_CLASS (MODE) == MODE_FLOAT \
? FP_RETURN \ && (! TARGET_SINGLE_FLOAT \
: GP_RETURN) || GET_MODE_SIZE (MODE) <= 4)) \
? FP_RETURN \
: GP_RETURN))
/* Define how to find the value returned by a function. /* Define how to find the value returned by a function.
VALTYPE is the data type of the value (as a tree). VALTYPE is the data type of the value (as a tree).
...@@ -2824,7 +2852,11 @@ while (0) ...@@ -2824,7 +2852,11 @@ while (0)
: (FROM) == FP_REGS && (TO) == FP_REGS ? 2 \ : (FROM) == FP_REGS && (TO) == FP_REGS ? 2 \
: (FROM) == GR_REGS && (TO) == FP_REGS ? 4 \ : (FROM) == GR_REGS && (TO) == FP_REGS ? 4 \
: (FROM) == FP_REGS && (TO) == GR_REGS ? 4 \ : (FROM) == FP_REGS && (TO) == GR_REGS ? 4 \
: 6) : (((FROM) == HI_REG || (FROM) == LO_REG || (FROM) == MD_REGS) \
&& (TO) == GR_REGS) ? 6 \
: (((TO) == HI_REG || (TO) == LO_REG || (TO) == MD_REGS) \
&& (FROM) == GR_REGS) ? 6 \
: 12)
#define MEMORY_MOVE_COST(MODE) \ #define MEMORY_MOVE_COST(MODE) \
((mips_cpu == PROCESSOR_R4000 || mips_cpu == PROCESSOR_R6000) ? 6 : 4) ((mips_cpu == PROCESSOR_R4000 || mips_cpu == PROCESSOR_R6000) ? 6 : 4)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment