aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authordnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>2002-09-04 01:37:44 +0000
committerdnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>2002-09-04 01:37:44 +0000
commitc5cc674a6c755c0fce26956c01ed5f0d3c8af53a (patch)
tree4e5bb3c9ea566fec6a9b8765feea6eebb0b413b0 /gcc/config
parent9e20f2157d6f65ba22c9a53712fa4f170de1a738 (diff)
Mainline merge 2002-09-03.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/tree-ssa-20020619-branch@56779 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/alpha/alpha.h43
-rw-r--r--gcc/config/alpha/elf.h4
-rw-r--r--gcc/config/alpha/netbsd.h6
-rw-r--r--gcc/config/alpha/vms.h4
-rw-r--r--gcc/config/arc/arc.h8
-rw-r--r--gcc/config/arm/aout.h4
-rw-r--r--gcc/config/arm/arm-protos.h1
-rw-r--r--gcc/config/arm/arm.c24
-rw-r--r--gcc/config/arm/arm.h2
-rw-r--r--gcc/config/arm/coff.h2
-rw-r--r--gcc/config/c4x/c4x.h2
-rw-r--r--gcc/config/chorus.h3
-rw-r--r--gcc/config/darwin.h4
-rw-r--r--gcc/config/dbx.h4
-rw-r--r--gcc/config/dbxcoff.h3
-rw-r--r--gcc/config/dbxelf.h3
-rw-r--r--gcc/config/elfos.h4
-rw-r--r--gcc/config/h8300/h8300.c42
-rw-r--r--gcc/config/h8300/h8300.h2
-rw-r--r--gcc/config/i386/cygwin.h4
-rw-r--r--gcc/config/i386/djgpp.h2
-rw-r--r--gcc/config/i386/gas.h2
-rw-r--r--gcc/config/i386/gstabs.h2
-rw-r--r--gcc/config/i386/i386-coff.h3
-rw-r--r--gcc/config/i386/i386-interix.h4
-rw-r--r--gcc/config/i386/i386.c8
-rw-r--r--gcc/config/i386/i386.md3
-rw-r--r--gcc/config/i386/sco5.h12
-rw-r--r--gcc/config/i386/svr3dbx.h2
-rw-r--r--gcc/config/i386/sysv3.h3
-rw-r--r--gcc/config/i386/win32.h4
-rw-r--r--gcc/config/i386/x86-64.h3
-rw-r--r--gcc/config/i960/i960.h4
-rw-r--r--gcc/config/ia64/ia64.h2
-rw-r--r--gcc/config/interix.h4
-rw-r--r--gcc/config/ip2k/ip2k.c177
-rw-r--r--gcc/config/ip2k/ip2k.h2
-rw-r--r--gcc/config/lynx-ng.h4
-rw-r--r--gcc/config/lynx.h4
-rw-r--r--gcc/config/m32r/m32r.h10
-rw-r--r--gcc/config/m68k/3b1.h2
-rw-r--r--gcc/config/m68k/3b1g.h2
-rw-r--r--gcc/config/m68k/ccur-GAS.h2
-rw-r--r--gcc/config/m68k/coff.h2
-rw-r--r--gcc/config/m68k/hp2bsd.h2
-rw-r--r--gcc/config/m68k/hp310g.h2
-rw-r--r--gcc/config/m68k/hp320g.h2
-rw-r--r--gcc/config/m68k/hp3bsd.h2
-rw-r--r--gcc/config/m68k/hp3bsd44.h2
-rw-r--r--gcc/config/m68k/linux-aout.h2
-rw-r--r--gcc/config/m68k/m68k-aout.h2
-rw-r--r--gcc/config/m68k/mot3300.h2
-rw-r--r--gcc/config/m68k/netbsd.h2
-rw-r--r--gcc/config/m68k/openbsd.h2
-rw-r--r--gcc/config/m68k/pbb.h2
-rw-r--r--gcc/config/m68k/plexus.h2
-rw-r--r--gcc/config/m68k/sun2.h2
-rw-r--r--gcc/config/m68k/sun3.h2
-rw-r--r--gcc/config/m68k/tower-as.h2
-rw-r--r--gcc/config/m68k/vxm68k.h2
-rw-r--r--gcc/config/m88k/aout-dbx.h2
-rw-r--r--gcc/config/m88k/m88k-aout.h2
-rw-r--r--gcc/config/mcore/mcore-elf.h4
-rw-r--r--gcc/config/mcore/mcore-pe.h1
-rw-r--r--gcc/config/mips/elf.h4
-rw-r--r--gcc/config/mips/elf64.h4
-rw-r--r--gcc/config/mips/iris5gas.h8
-rw-r--r--gcc/config/mips/iris6.h4
-rw-r--r--gcc/config/mips/mips.h6
-rw-r--r--gcc/config/mips/netbsd.h16
-rw-r--r--gcc/config/mips/sni-gas.h8
-rw-r--r--gcc/config/mmix/mmix.h2
-rw-r--r--gcc/config/netware.h2
-rw-r--r--gcc/config/ns32k/netbsd.h2
-rw-r--r--gcc/config/pa/pa.c3
-rw-r--r--gcc/config/pa/pa64-hpux.h2
-rw-r--r--gcc/config/pa/som.h6
-rw-r--r--gcc/config/psos.h2
-rw-r--r--gcc/config/romp/romp.h2
-rw-r--r--gcc/config/rs6000/linux64.h1
-rw-r--r--gcc/config/rs6000/rs6000.h4
-rw-r--r--gcc/config/rs6000/sysv4.h2
-rw-r--r--gcc/config/rs6000/xcoff.h2
-rw-r--r--gcc/config/s390/s390-protos.h3
-rw-r--r--gcc/config/s390/s390.c511
-rw-r--r--gcc/config/s390/s390.h11
-rw-r--r--gcc/config/s390/s390.md10
-rw-r--r--gcc/config/sh/coff.h2
-rw-r--r--gcc/config/sh/elf.h1
-rw-r--r--gcc/config/sh/sh.c170
-rw-r--r--gcc/config/sh/sh.h20
-rw-r--r--gcc/config/sh/sh.md737
-rw-r--r--gcc/config/sparc/linux64.h6
-rw-r--r--gcc/config/sparc/liteelf.h6
-rw-r--r--gcc/config/sparc/netbsd.h2
-rw-r--r--gcc/config/sparc/openbsd.h2
-rw-r--r--gcc/config/sparc/pbd.h2
-rw-r--r--gcc/config/sparc/sp64-elf.h2
-rw-r--r--gcc/config/sparc/sp86x-elf.h6
-rw-r--r--gcc/config/sparc/sparc.c3
-rw-r--r--gcc/config/sparc/sparc.h2
-rw-r--r--gcc/config/svr3.h2
-rw-r--r--gcc/config/v850/lib1funcs.asm734
-rw-r--r--gcc/config/v850/t-v85040
-rw-r--r--gcc/config/v850/v850-protos.h34
-rw-r--r--gcc/config/v850/v850.c583
-rw-r--r--gcc/config/v850/v850.h171
-rw-r--r--gcc/config/v850/v850.md665
-rw-r--r--gcc/config/vax/vax.h2
-rw-r--r--gcc/config/vax/vaxv.h2
110 files changed, 3220 insertions, 1062 deletions
diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h
index d90d47618a7..c3bce2ee9f6 100644
--- a/gcc/config/alpha/alpha.h
+++ b/gcc/config/alpha/alpha.h
@@ -69,22 +69,31 @@ Boston, MA 02111-1307, USA. */
builtin_define ("_IEEE_FP_INEXACT"); \
\
/* Macros dependent on the C dialect. */ \
- if (preprocessing_asm_p ()) \
- builtin_define_std ("LANGUAGE_ASSEMBLY"); \
- else if (c_language == clk_c) \
- builtin_define_std ("LANGUAGE_C"); \
- else if (c_language == clk_cplusplus) \
- { \
- builtin_define ("__LANGUAGE_C_PLUS_PLUS"); \
- builtin_define ("__LANGUAGE_C_PLUS_PLUS__");\
- } \
- if (flag_objc) \
- { \
- builtin_define ("__LANGUAGE_OBJECTIVE_C"); \
- builtin_define ("__LANGUAGE_OBJECTIVE_C__");\
- } \
+ SUBTARGET_LANGUAGE_CPP_BUILTINS(); \
} while (0)
+#ifndef SUBTARGET_LANGUAGE_CPP_BUILTINS
+#define SUBTARGET_LANGUAGE_CPP_BUILTINS() \
+ do \
+ { \
+ if (preprocessing_asm_p ()) \
+ builtin_define_std ("LANGUAGE_ASSEMBLY"); \
+ else if (c_language == clk_c) \
+ builtin_define_std ("LANGUAGE_C"); \
+ else if (c_language == clk_cplusplus) \
+ { \
+ builtin_define ("__LANGUAGE_C_PLUS_PLUS"); \
+ builtin_define ("__LANGUAGE_C_PLUS_PLUS__"); \
+ } \
+ if (flag_objc) \
+ { \
+ builtin_define ("__LANGUAGE_OBJECTIVE_C"); \
+ builtin_define ("__LANGUAGE_OBJECTIVE_C__"); \
+ } \
+ } \
+ while (0)
+#endif
+
#define CPP_SPEC "%(cpp_subtarget)"
#ifndef CPP_SUBTARGET_SPEC
@@ -1990,9 +1999,9 @@ do { \
/* Definitions for debugging. */
-#define SDB_DEBUGGING_INFO /* generate info for mips-tfile */
-#define DBX_DEBUGGING_INFO /* generate embedded stabs */
-#define MIPS_DEBUGGING_INFO /* MIPS specific debugging info */
+#define SDB_DEBUGGING_INFO 1 /* generate info for mips-tfile */
+#define DBX_DEBUGGING_INFO 1 /* generate embedded stabs */
+#define MIPS_DEBUGGING_INFO 1 /* MIPS specific debugging info */
#ifndef PREFERRED_DEBUGGING_TYPE /* assume SDB_DEBUGGING_INFO */
#define PREFERRED_DEBUGGING_TYPE SDB_DEBUG
diff --git a/gcc/config/alpha/elf.h b/gcc/config/alpha/elf.h
index 806d95f4420..40d4f4fc510 100644
--- a/gcc/config/alpha/elf.h
+++ b/gcc/config/alpha/elf.h
@@ -27,8 +27,8 @@ Boston, MA 02111-1307, USA. */
/* ??? Move all SDB stuff from alpha.h to osf.h. */
#undef SDB_DEBUGGING_INFO
-#define DBX_DEBUGGING_INFO
-#define DWARF2_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
+#define DWARF2_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
diff --git a/gcc/config/alpha/netbsd.h b/gcc/config/alpha/netbsd.h
index 60e7f1fc7af..4769af88745 100644
--- a/gcc/config/alpha/netbsd.h
+++ b/gcc/config/alpha/netbsd.h
@@ -28,6 +28,12 @@ Boston, MA 02111-1307, USA. */
NETBSD_OS_CPP_BUILTINS_LP64(); \
} while (0)
+
+/* NetBSD doesn't use the LANGUAGE* built-ins. */
+#undef SUBTARGET_LANGUAGE_CPP_BUILTINS
+#define SUBTARGET_LANGUAGE_CPP_BUILTINS() /* nothing */
+
+
/* Show that we need a GP when profiling. */
#undef TARGET_PROFILING_NEEDS_GP
#define TARGET_PROFILING_NEEDS_GP 1
diff --git a/gcc/config/alpha/vms.h b/gcc/config/alpha/vms.h
index b0da28a3cdf..f1b8884df26 100644
--- a/gcc/config/alpha/vms.h
+++ b/gcc/config/alpha/vms.h
@@ -364,8 +364,8 @@ do { \
#undef MIPS_DEBUGGING_INFO
#undef DBX_DEBUGGING_INFO
-#define DWARF2_DEBUGGING_INFO
-#define VMS_DEBUGGING_INFO
+#define DWARF2_DEBUGGING_INFO 1
+#define VMS_DEBUGGING_INFO 1
#define DWARF2_UNWIND_INFO 1
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index d1cfabc520c..7a9d659ac43 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -1311,12 +1311,8 @@ do { if ((LOG) != 0) fprintf (FILE, "\t.align %d\n", 1 << (LOG)); } while (0)
/* Debugging information. */
/* Generate DBX and DWARF debugging information. */
-#ifndef DBX_DEBUGGING_INFO
-#define DBX_DEBUGGING_INFO
-#endif
-#ifndef DWARF_DEBUGGING_INFO
-#define DWARF_DEBUGGING_INFO
-#endif
+#define DBX_DEBUGGING_INFO 1
+#define DWARF_DEBUGGING_INFO 1
/* Prefer STABS (for now). */
#undef PREFERRED_DEBUGGING_TYPE
diff --git a/gcc/config/arm/aout.h b/gcc/config/arm/aout.h
index 3f29b395e03..8f4a6056f98 100644
--- a/gcc/config/arm/aout.h
+++ b/gcc/config/arm/aout.h
@@ -111,9 +111,7 @@ Boston, MA 02111-1307, USA. */
/* Generate DBX debugging information. riscix.h will undefine this because
the native assembler does not support stabs. */
-#ifndef DBX_DEBUGGING_INFO
-#define DBX_DEBUGGING_INFO 1
-#endif
+#define DBX_DEBUGGING_INFO 1
/* Acorn dbx moans about continuation chars, so don't use any. */
#ifndef DBX_CONTIN_LENGTH
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 036ea44fed5..6aaa1307857 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -34,6 +34,7 @@ extern void arm_expand_prologue PARAMS ((void));
/* Used in arm.md, but defined in output.c. */
extern void assemble_align PARAMS ((int));
extern const char * arm_strip_name_encoding PARAMS ((const char *));
+extern void arm_asm_output_labelref PARAMS ((FILE *, const char *));
extern unsigned long arm_current_func_type PARAMS ((void));
extern unsigned int arm_compute_initial_elimination_offset PARAMS ((unsigned int, unsigned int));
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 56c7e276efc..9000cca326b 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -10799,6 +10799,30 @@ arm_strip_name_encoding (name)
return name;
}
+/* If there is a '*' anywhere in the name's prefix, then
+ emit the stripped name verbatim, otherwise prepend an
+ underscore if leading underscores are being used. */
+
+void
+arm_asm_output_labelref (stream, name)
+ FILE * stream;
+ const char * name;
+{
+ int skip;
+ int verbatim = 0;
+
+ while ((skip = arm_get_strip_length (* name)))
+ {
+ verbatim |= (*name == '*');
+ name += skip;
+ }
+
+ if (verbatim)
+ fputs (name, stream);
+ else
+ asm_fprintf (stream, "%U%s", name);
+}
+
rtx aof_pic_label;
#ifdef AOF_ASSEMBLER
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 64e71873148..8ab82671636 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -1858,7 +1858,7 @@ typedef struct
`assemble_name' uses this. */
#undef ASM_OUTPUT_LABELREF
#define ASM_OUTPUT_LABELREF(FILE, NAME) \
- asm_fprintf (FILE, "%U%s", arm_strip_name_encoding (NAME))
+ arm_asm_output_labelref (FILE, NAME)
#define ARM_DECLARE_FUNCTION_SIZE(STREAM, NAME, DECL) \
arm_encode_call_attribute (DECL, SHORT_CALL_FLAG_CHAR)
diff --git a/gcc/config/arm/coff.h b/gcc/config/arm/coff.h
index 263e115311f..0a78268949e 100644
--- a/gcc/config/arm/coff.h
+++ b/gcc/config/arm/coff.h
@@ -40,7 +40,7 @@ Boston, MA 02111-1307, USA. */
#endif
/* This is COFF, but prefer stabs. */
-#define SDB_DEBUGGING_INFO
+#define SDB_DEBUGGING_INFO 1
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
diff --git a/gcc/config/c4x/c4x.h b/gcc/config/c4x/c4x.h
index 80722cc32c6..04d6949a7f8 100644
--- a/gcc/config/c4x/c4x.h
+++ b/gcc/config/c4x/c4x.h
@@ -1892,7 +1892,7 @@ do { \
to avoid conflict with TI's use of .def). */
#define SDB_DELIM "\n"
-#define SDB_DEBUGGING_INFO
+#define SDB_DEBUGGING_INFO 1
/* Don't use octal since this can confuse gas for the c4x. */
#define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\t.type\t0x%x%s", a, SDB_DELIM)
diff --git a/gcc/config/chorus.h b/gcc/config/chorus.h
index 3e6bcca39cc..ae22334d867 100644
--- a/gcc/config/chorus.h
+++ b/gcc/config/chorus.h
@@ -19,8 +19,7 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#undef DWARF2_DEBUGGING_INFO
-#define DWARF2_DEBUGGING_INFO
+#define DWARF2_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index f6ed2946a39..61cbcd8e191 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -105,11 +105,11 @@ Boston, MA 02111-1307, USA. */
/* We use Dbx symbol format. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
/* Also enable Dwarf 2 as an option. */
-#define DWARF2_DEBUGGING_INFO
+#define DWARF2_DEBUGGING_INFO 1
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
diff --git a/gcc/config/dbx.h b/gcc/config/dbx.h
index c5cd3b5f2d0..a9fededbc39 100644
--- a/gcc/config/dbx.h
+++ b/gcc/config/dbx.h
@@ -22,9 +22,7 @@ Boston, MA 02111-1307, USA. */
information. The configure script will add a #include of this file
to tm.h when --with-stabs is used for certain targets. */
-#ifndef DBX_DEBUGGING_INFO
-#define DBX_DEBUGGING_INFO
-#endif
+#define DBX_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
diff --git a/gcc/config/dbxcoff.h b/gcc/config/dbxcoff.h
index 1d5b448879f..25f7e181834 100644
--- a/gcc/config/dbxcoff.h
+++ b/gcc/config/dbxcoff.h
@@ -24,8 +24,7 @@ Boston, MA 02111-1307, USA. */
/* Output DBX (stabs) debugging information if doing -gstabs. */
-#undef DBX_DEBUGGING_INFO
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
/* Generate SDB debugging information by default. */
diff --git a/gcc/config/dbxelf.h b/gcc/config/dbxelf.h
index c1490aeb713..9f8f56a1b01 100644
--- a/gcc/config/dbxelf.h
+++ b/gcc/config/dbxelf.h
@@ -27,8 +27,7 @@ Boston, MA 02111-1307, USA. */
/* Output DBX (stabs) debugging information if doing -gstabs. */
-#undef DBX_DEBUGGING_INFO
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
/* Make LBRAC and RBRAC addresses relative to the start of the
function. The native Solaris stabs debugging format works this
diff --git a/gcc/config/elfos.h b/gcc/config/elfos.h
index 8135ab70a6f..cd20878acee 100644
--- a/gcc/config/elfos.h
+++ b/gcc/config/elfos.h
@@ -60,15 +60,11 @@ Boston, MA 02111-1307, USA. */
/* System V Release 4 uses DWARF debugging info. */
-#ifndef DWARF_DEBUGGING_INFO
#define DWARF_DEBUGGING_INFO 1
-#endif
/* All ELF targets can support DWARF-2. */
-#ifndef DWARF2_DEBUGGING_INFO
#define DWARF2_DEBUGGING_INFO 1
-#endif
/* The GNU tools operate better with dwarf2, and it is required by some
psABI's. Since we don't have any native tools to be compatible with,
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index 841c8b7a641..19520db4333 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -2213,23 +2213,23 @@ static const enum shift_alg shift_alg_hi[3][3][16] = {
/* TARGET_H8300 */
/* 0 1 2 3 4 5 6 7 */
/* 8 9 10 11 12 13 14 15 */
+ { INL, INL, INL, INL, INL, INL, INL, SPC,
+ SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFT */
{ INL, INL, INL, INL, INL, LOP, LOP, SPC,
- SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFT */
+ SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_LSHIFTRT */
{ INL, INL, INL, INL, INL, LOP, LOP, SPC,
- SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_LSHIFTRT */
- { INL, INL, INL, INL, INL, LOP, LOP, SPC,
- SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
+ SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFTRT */
},
{
/* TARGET_H8300H */
/* 0 1 2 3 4 5 6 7 */
/* 8 9 10 11 12 13 14 15 */
- { INL, INL, INL, INL, INL, LOP, LOP, SPC,
+ { INL, INL, INL, INL, INL, INL, INL, SPC,
SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_ASHIFT */
- { INL, INL, INL, INL, INL, LOP, LOP, SPC,
+ { INL, INL, INL, INL, INL, INL, INL, SPC,
SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
- { INL, INL, INL, INL, INL, LOP, LOP, SPC,
- SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
+ { INL, INL, INL, INL, INL, INL, INL, SPC,
+ SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFTRT */
},
{
/* TARGET_H8300S */
@@ -2240,7 +2240,7 @@ static const enum shift_alg shift_alg_hi[3][3][16] = {
{ INL, INL, INL, INL, INL, INL, INL, INL,
SPC, SPC, SPC, SPC, SPC, ROT, ROT, ROT }, /* SHIFT_LSHIFTRT */
{ INL, INL, INL, INL, INL, INL, INL, INL,
- SPC, SPC, SPC, SPC, SPC, LOP, LOP, SPC }, /* SHIFT_ASHIFTRT */
+ SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC }, /* SHIFT_ASHIFTRT */
}
};
@@ -2458,7 +2458,7 @@ get_shift_alg (shift_type, shift_mode, count, info)
goto end;
}
}
- else if (8 <= count && count <= 12)
+ else if (8 <= count && count <= 13)
{
info->remainder = count - 8;
@@ -2484,6 +2484,28 @@ get_shift_alg (shift_type, shift_mode, count, info)
goto end;
}
}
+ else if (count == 14)
+ {
+ switch (shift_type)
+ {
+ case SHIFT_ASHIFT:
+ if (TARGET_H8300)
+ info->special = "mov.b\t%s0,%t0\n\trotr.b\t%t0\n\trotr.b\t%t0\n\tand.b\t#0xC0,%t0\n\tsub.b\t%s0,%s0";
+ goto end;
+ case SHIFT_LSHIFTRT:
+ if (TARGET_H8300)
+ info->special = "mov.b\t%t0,%s0\n\trotl.b\t%s0\n\trotl.b\t%s0\n\tand.b\t#3,%s0\n\tsub.b\t%t0,%t0";
+ goto end;
+ case SHIFT_ASHIFTRT:
+ if (TARGET_H8300)
+ info->special = "mov.b\t%t0,%s0\n\tshll.b\t%s0\n\tsubx.b\t%t0,%t0\n\tshll.b\t%s0\n\tmov.b\t%t0,%s0\n\tbst.b\t#0,%s0";
+ else if (TARGET_H8300H)
+ info->special = "shll.b\t%t0\n\tsubx.b\t%s0,%s0\n\tshll.b\t%t0\n\trotxl.b\t%s0\n\texts.w\t%T0";
+ else /* TARGET_H8300S */
+ info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0\n\tshar.w\t#2,%T0\n\tshar.w\t#2,%T0\n\tshar.w\t#2,%T0";
+ goto end;
+ }
+ }
else if (count == 15)
{
switch (shift_type)
diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h
index 1ef8f78bea4..6781af8484a 100644
--- a/gcc/config/h8300/h8300.h
+++ b/gcc/config/h8300/h8300.h
@@ -1098,7 +1098,7 @@ struct cum_arg
{ {"er0", 0}, {"er1", 1}, {"er2", 2}, {"er3", 3}, {"er4", 4}, \
{"er5", 5}, {"er6", 6}, {"er7", 7}, {"r7", 7} }
-#define SDB_DEBUGGING_INFO
+#define SDB_DEBUGGING_INFO 1
#define SDB_DELIM "\n"
/* Support -gstabs. */
diff --git a/gcc/config/i386/cygwin.h b/gcc/config/i386/cygwin.h
index e849c9b800d..be925413a2b 100644
--- a/gcc/config/i386/cygwin.h
+++ b/gcc/config/i386/cygwin.h
@@ -20,8 +20,8 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#define DBX_DEBUGGING_INFO
-#define SDB_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
+#define SDB_DEBUGGING_INFO 1
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
#define TARGET_VERSION fprintf (stderr, " (x86 Cygwin)");
diff --git a/gcc/config/i386/djgpp.h b/gcc/config/i386/djgpp.h
index 3afafd0ae3c..29b93d96a8c 100644
--- a/gcc/config/i386/djgpp.h
+++ b/gcc/config/i386/djgpp.h
@@ -20,7 +20,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Support generation of DWARF2 debugging info. */
-#define DWARF2_DEBUGGING_INFO
+#define DWARF2_DEBUGGING_INFO 1
/* Don't assume anything about the header files. */
#define NO_IMPLICIT_EXTERN_C
diff --git a/gcc/config/i386/gas.h b/gcc/config/i386/gas.h
index 7c15e0bdb13..075d7498f3e 100644
--- a/gcc/config/i386/gas.h
+++ b/gcc/config/i386/gas.h
@@ -43,7 +43,7 @@ Boston, MA 02111-1307, USA. */
/* Ask for COFF symbols. */
-#define SDB_DEBUGGING_INFO
+#define SDB_DEBUGGING_INFO 1
/* Output #ident as a .ident. */
diff --git a/gcc/config/i386/gstabs.h b/gcc/config/i386/gstabs.h
index 716e37a21f3..e9a621871e3 100644
--- a/gcc/config/i386/gstabs.h
+++ b/gcc/config/i386/gstabs.h
@@ -4,4 +4,4 @@
/* We want to output DBX debugging information. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
diff --git a/gcc/config/i386/i386-coff.h b/gcc/config/i386/i386-coff.h
index d4d155323e5..e8c5de9c65c 100644
--- a/gcc/config/i386/i386-coff.h
+++ b/gcc/config/i386/i386-coff.h
@@ -27,8 +27,7 @@ Boston, MA 02111-1307, USA. */
/* We want to be able to get DBX debugging information via -gstabs. */
-#undef DBX_DEBUGGING_INFO
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE SDB_DEBUG
diff --git a/gcc/config/i386/i386-interix.h b/gcc/config/i386/i386-interix.h
index 02842238bb6..79aafa43344 100644
--- a/gcc/config/i386/i386-interix.h
+++ b/gcc/config/i386/i386-interix.h
@@ -26,8 +26,8 @@ Boston, MA 02111-1307, USA. */
/* The rest must follow. */
-#define DBX_DEBUGGING_INFO
-#define SDB_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
+#define SDB_DEBUGGING_INFO 1
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
#define HANDLE_SYSV_PRAGMA
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 2f66a01230b..730bd3d78e2 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -1592,7 +1592,11 @@ classify_argument (mode, type, classes, bit_offset)
{
int bytes =
(mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
- int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+ int words = (bytes + (bit_offset % 64) / 8 + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+
+ /* Variable sized entities are always passed/returned in memory. */
+ if (bytes < 0)
+ return 0;
if (type && AGGREGATE_TYPE_P (type))
{
@@ -8990,7 +8994,7 @@ ix86_expand_int_movcc (operands)
emit_insn (gen_rtx_SET (VOIDmode, out, tmp));
}
if (out != operands[0])
- emit_move_insn (operands[0], out);
+ emit_move_insn (operands[0], copy_rtx (out));
return 1; /* DONE */
}
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 01e03c3a811..240880ddf9e 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -19819,7 +19819,8 @@
(clobber (reg:DI 36))]
"TARGET_3DNOW"
"femms"
- [(set_attr "type" "mmx")])
+ [(set_attr "type" "mmx")
+ (set_attr "memory" "none")])
(define_insn "pf2id"
[(set (match_operand:V2SI 0 "register_operand" "=y")
diff --git a/gcc/config/i386/sco5.h b/gcc/config/i386/sco5.h
index 9d7c314d5a7..69bf1a77502 100644
--- a/gcc/config/i386/sco5.h
+++ b/gcc/config/i386/sco5.h
@@ -413,16 +413,12 @@ do { \
#define DBX_REGISTER_NUMBER(n) \
((TARGET_ELF) ? svr4_dbx_register_map[n] : dbx_register_map[n])
-#undef DWARF2_DEBUGGING_INFO
-#undef DWARF_DEBUGGING_INFO
-#undef SDB_DEBUGGING_INFO
-#undef DBX_DEBUGGING_INFO
-#undef PREFERRED_DEBUGGING_TYPE
-
#define DWARF2_DEBUGGING_INFO 1
#define DWARF_DEBUGGING_INFO 1
-#define SDB_DEBUGGING_INFO 1
-#define DBX_DEBUGGING_INFO 1
+#define SDB_DEBUGGING_INFO 1
+#define DBX_DEBUGGING_INFO 1
+
+#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE \
((TARGET_ELF) ? DWARF2_DEBUG: SDB_DEBUG)
diff --git a/gcc/config/i386/svr3dbx.h b/gcc/config/i386/svr3dbx.h
index 3357d68591d..4be7a70d06b 100644
--- a/gcc/config/i386/svr3dbx.h
+++ b/gcc/config/i386/svr3dbx.h
@@ -24,7 +24,7 @@ Boston, MA 02111-1307, USA. */
/* We want to output DBX debugging information. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
/* Compensate for botch in dbxout_init/dbxout_source_file which
unconditionally drops the first character from ltext_label_name */
diff --git a/gcc/config/i386/sysv3.h b/gcc/config/i386/sysv3.h
index 67194f4acc5..a55f0e8a95e 100644
--- a/gcc/config/i386/sysv3.h
+++ b/gcc/config/i386/sysv3.h
@@ -53,8 +53,7 @@ Boston, MA 02111-1307, USA. */
/* We want to be able to get DBX debugging information via -gstabs. */
-#undef DBX_DEBUGGING_INFO
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE SDB_DEBUG
diff --git a/gcc/config/i386/win32.h b/gcc/config/i386/win32.h
index 48b38877370..93f58c93f12 100644
--- a/gcc/config/i386/win32.h
+++ b/gcc/config/i386/win32.h
@@ -25,8 +25,8 @@ Boston, MA 02111-1307, USA. */
/* Enable parsing of #pragma pack(push,<n>) and #pragma pack(pop). */
#define HANDLE_PRAGMA_PACK_PUSH_POP 1
-#define DBX_DEBUGGING_INFO
-#define SDB_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
+#define SDB_DEBUGGING_INFO 1
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
#include "i386/unix.h"
diff --git a/gcc/config/i386/x86-64.h b/gcc/config/i386/x86-64.h
index 56e46841729..54efb8144f1 100644
--- a/gcc/config/i386/x86-64.h
+++ b/gcc/config/i386/x86-64.h
@@ -85,9 +85,8 @@ Boston, MA 02111-1307, USA. */
/* i386 System V Release 4 uses DWARF debugging info.
x86-64 ABI specifies DWARF2. */
-#undef DWARF2_DEBUGGING_INFO
#undef DWARF_DEBUGGING_INFO
-#define DWARF2_DEBUGGING_INFO
+#define DWARF2_DEBUGGING_INFO 1
#define DWARF2_UNWIND_INFO 1
/* Incorrectly autodetected in cross compilation. */
#undef HAVE_AS_DWARF2_DEBUG_LINE
diff --git a/gcc/config/i960/i960.h b/gcc/config/i960/i960.h
index d6015618f67..37c9afb8b2a 100644
--- a/gcc/config/i960/i960.h
+++ b/gcc/config/i960/i960.h
@@ -111,10 +111,10 @@ Boston, MA 02111-1307, USA. */
#define TARGET_VERSION fprintf (stderr," (intel 80960)");
/* Generate DBX debugging information. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
/* Generate SDB style debugging information. */
-#define SDB_DEBUGGING_INFO
+#define SDB_DEBUGGING_INFO 1
#define EXTENDED_SDB_BASIC_TYPES
/* Generate DBX_DEBUGGING_INFO by default. */
diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h
index 0a640d0a6e6..71f205d0658 100644
--- a/gcc/config/ia64/ia64.h
+++ b/gcc/config/ia64/ia64.h
@@ -2245,7 +2245,7 @@ do { \
/* Define this macro if GNU CC should produce dwarf version 2 format debugging
output in response to the `-g' option. */
-#define DWARF2_DEBUGGING_INFO
+#define DWARF2_DEBUGGING_INFO 1
#define DWARF2_ASM_LINE_DEBUG_INFO (TARGET_DWARF2_ASM)
diff --git a/gcc/config/interix.h b/gcc/config/interix.h
index 9100e01adb7..e52d184630c 100644
--- a/gcc/config/interix.h
+++ b/gcc/config/interix.h
@@ -90,8 +90,8 @@ for windows/multi thread */
/* Names to predefine in the preprocessor for this target machine. */
-#define DBX_DEBUGGING_INFO
-#define SDB_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
+#define SDB_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
diff --git a/gcc/config/ip2k/ip2k.c b/gcc/config/ip2k/ip2k.c
index a41a7b6d2d1..bcbed3f08d8 100644
--- a/gcc/config/ip2k/ip2k.c
+++ b/gcc/config/ip2k/ip2k.c
@@ -1075,25 +1075,6 @@ ip2k_set_compare (x, y)
rtx x;
rtx y;
{
- /* If we're doing a DImode compare then force any CONST_INT second
- operand to be CONST_DOUBLE. */
- if (GET_MODE (x) == DImode && GET_CODE (y) == CONST_INT)
- {
- rtx value;
- size_t i;
-
- value = rtx_alloc (CONST_DOUBLE);
- PUT_MODE (value, VOIDmode);
-
- CONST_DOUBLE_LOW (value) = INTVAL (y);
- CONST_DOUBLE_HIGH (value) = INTVAL (y) > 0 ? 0 : -1;
-
- for (i = 2; i < (sizeof CONST_DOUBLE_FORMAT - 1); i++)
- XWINT (value, i) = 0;
-
- y = value;
- }
-
ip2k_compare_operands[0] = x;
ip2k_compare_operands[1] = y;
return "";
@@ -1675,6 +1656,8 @@ ip2k_gen_unsigned_comp_branch (insn, code, label)
int imm_cmp = 0;
int can_use_skip = 0;
rtx ninsn;
+ HOST_WIDE_INT const_low;
+ HOST_WIDE_INT const_high;
operands[2] = label;
@@ -2332,10 +2315,10 @@ ip2k_gen_unsigned_comp_branch (insn, code, label)
{
if (INTVAL (operands[0]) == 0)
{
- OUT_AS2 (mov, w, %A0);
- OUT_AS2 (or, w, %B0);
- OUT_AS2 (or, w, %C0);
- OUT_AS2 (or, w, %D0);
+ OUT_AS2 (mov, w, %A1);
+ OUT_AS2 (or, w, %B1);
+ OUT_AS2 (or, w, %C1);
+ OUT_AS2 (or, w, %D1);
OUT_AS1 (snz,);
OUT_AS1 (page, %2);
OUT_AS1 (jmp, %2);
@@ -2377,10 +2360,10 @@ ip2k_gen_unsigned_comp_branch (insn, code, label)
{
if (INTVAL (operands[0]) == 0)
{
- OUT_AS2 (mov, w, %A0);
- OUT_AS2 (or, w, %B0);
- OUT_AS2 (or, w, %C0);
- OUT_AS2 (or, w, %D0);
+ OUT_AS2 (mov, w, %A1);
+ OUT_AS2 (or, w, %B1);
+ OUT_AS2 (or, w, %C1);
+ OUT_AS2 (or, w, %D1);
OUT_AS1 (sz,);
OUT_AS1 (page, %2);
OUT_AS1 (jmp, %2);
@@ -2465,6 +2448,16 @@ ip2k_gen_unsigned_comp_branch (insn, code, label)
break;
case DImode:
+ if (GET_CODE (operands[1]) == CONST_INT)
+ {
+ const_low = INTVAL (operands[1]);
+ const_high = (const_low >= 0) - 1;
+ }
+ else if (GET_CODE (operands[1]) == CONST_DOUBLE)
+ {
+ const_low = CONST_DOUBLE_LOW (operands[1]);
+ const_high = CONST_DOUBLE_HIGH (operands[1]);
+ }
switch (code)
{
case EQ:
@@ -2519,14 +2512,14 @@ ip2k_gen_unsigned_comp_branch (insn, code, label)
{
if (imm_cmp)
{
- s = (CONST_DOUBLE_HIGH (operands[1]) >> 24) & 0xff;
- t = (CONST_DOUBLE_HIGH (operands[1]) >> 16) & 0xff;
- u = (CONST_DOUBLE_HIGH (operands[1]) >> 8) & 0xff;
- v = CONST_DOUBLE_HIGH (operands[1]) & 0xff;
- w = (CONST_DOUBLE_LOW (operands[1]) >> 24) & 0xff;
- x = (CONST_DOUBLE_LOW (operands[1]) >> 16) & 0xff;
- y = (CONST_DOUBLE_LOW (operands[1]) >> 8) & 0xff;
- z = CONST_DOUBLE_LOW (operands[1]) & 0xff;
+ s = (const_high >> 24) & 0xff;
+ t = (const_high >> 16) & 0xff;
+ u = (const_high >> 8) & 0xff;
+ v = const_high & 0xff;
+ w = (const_low >> 24) & 0xff;
+ x = (const_low >> 16) & 0xff;
+ y = (const_low >> 8) & 0xff;
+ z = const_low & 0xff;
}
OUT_AS2 (mov, w, %S1);
@@ -2648,14 +2641,14 @@ ip2k_gen_unsigned_comp_branch (insn, code, label)
{
if (imm_cmp)
{
- s = (CONST_DOUBLE_HIGH (operands[1]) >> 24) & 0xff;
- t = (CONST_DOUBLE_HIGH (operands[1]) >> 16) & 0xff;
- u = (CONST_DOUBLE_HIGH (operands[1]) >> 8) & 0xff;
- v = CONST_DOUBLE_HIGH (operands[1]) & 0xff;
- w = (CONST_DOUBLE_LOW (operands[1]) >> 24) & 0xff;
- x = (CONST_DOUBLE_LOW (operands[1]) >> 16) & 0xff;
- y = (CONST_DOUBLE_LOW (operands[1]) >> 8) & 0xff;
- z = CONST_DOUBLE_LOW (operands[1]) & 0xff;
+ s = (const_high >> 24) & 0xff;
+ t = (const_high >> 16) & 0xff;
+ u = (const_high >> 8) & 0xff;
+ v = const_high & 0xff;
+ w = (const_low >> 24) & 0xff;
+ x = (const_low >> 16) & 0xff;
+ y = (const_low >> 8) & 0xff;
+ z = const_low & 0xff;
}
OUT_AS2 (mov, w, %S1);
@@ -2734,13 +2727,11 @@ ip2k_gen_unsigned_comp_branch (insn, code, label)
if (imm_sub)
{
/* > 0xffffffffffffffff never suceeds! */
- if (((CONST_DOUBLE_HIGH (operands[1]) & 0xffffffff)
- != 0xffffffff)
- || ((CONST_DOUBLE_LOW (operands[1]) & 0xffffffff)
- != 0xffffffff))
+ if (((const_high & 0xffffffff) != 0xffffffff)
+ || ((const_low & 0xffffffff) != 0xffffffff))
{
- operands[3] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) + 1);
- operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1])
+ operands[3] = GEN_INT (const_low + 1);
+ operands[4] = GEN_INT (const_high
+ (INTVAL (operands[3]) ? 0 : 1));
OUT_AS2 (mov, w, %D3);
OUT_AS2 (sub, w, %Z0);
@@ -2790,27 +2781,38 @@ ip2k_gen_unsigned_comp_branch (insn, code, label)
case GEU:
if (imm_sub)
{
- if ((CONST_DOUBLE_HIGH (operands[0]) == 0)
- && (CONST_DOUBLE_LOW (operands[0]) == 0))
+ HOST_WIDE_INT const_low0;
+ HOST_WIDE_INT const_high0;
+
+ if (GET_CODE (operands[0]) == CONST_INT)
{
- OUT_AS2 (mov, w, %S0);
- OUT_AS2 (or, w, %T0);
- OUT_AS2 (or, w, %U0);
- OUT_AS2 (or, w, %V0);
- OUT_AS2 (or, w, %W0);
- OUT_AS2 (or, w, %X0);
- OUT_AS2 (or, w, %Y0);
- OUT_AS2 (or, w, %Z0);
+ const_low0 = INTVAL (operands[0]);
+ const_high0 = (const_low >= 0) - 1;
+ }
+ else if (GET_CODE (operands[0]) == CONST_DOUBLE)
+ {
+ const_low0 = CONST_DOUBLE_LOW (operands[0]);
+ const_high0 = CONST_DOUBLE_HIGH (operands[0]);
+ }
+
+ if (const_high0 == 0 && const_low0 == 0)
+ {
+ OUT_AS2 (mov, w, %S1);
+ OUT_AS2 (or, w, %T1);
+ OUT_AS2 (or, w, %U1);
+ OUT_AS2 (or, w, %V1);
+ OUT_AS2 (or, w, %W1);
+ OUT_AS2 (or, w, %X1);
+ OUT_AS2 (or, w, %Y1);
+ OUT_AS2 (or, w, %Z1);
OUT_AS1 (snz,);
OUT_AS1 (page, %2);
OUT_AS1 (jmp, %2);
}
else
{
- operands[3] = GEN_INT (CONST_DOUBLE_LOW (operands[0]) - 1);
- operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[0])
- - (CONST_DOUBLE_LOW (operands[0])
- ? 1 : 0));
+ operands[3] = GEN_INT (const_low0 - 1);
+ operands[4] = GEN_INT (const_high0 - (const_low0 ? 1 : 0));
OUT_AS2 (mov, w, %D3);
OUT_AS2 (sub, w, %Z1);
OUT_AS2 (mov, w, %C3);
@@ -2859,27 +2861,38 @@ ip2k_gen_unsigned_comp_branch (insn, code, label)
case LTU:
if (imm_sub)
{
- if ((CONST_DOUBLE_HIGH (operands[0]) == 0)
- && (CONST_DOUBLE_LOW (operands[0]) == 0))
+ HOST_WIDE_INT const_low0;
+ HOST_WIDE_INT const_high0;
+
+ if (GET_CODE (operands[0]) == CONST_INT)
+ {
+ const_low0 = INTVAL (operands[0]);
+ const_high0 = (const_low >= 0) - 1;
+ }
+ else if (GET_CODE (operands[0]) == CONST_DOUBLE)
+ {
+ const_low0 = CONST_DOUBLE_LOW (operands[0]);
+ const_high0 = CONST_DOUBLE_HIGH (operands[0]);
+ }
+
+ if (const_high0 == 0 && const_low0 == 0)
{
- OUT_AS2 (mov, w, %S0);
- OUT_AS2 (or, w, %T0);
- OUT_AS2 (or, w, %U0);
- OUT_AS2 (or, w, %V0);
- OUT_AS2 (or, w, %W0);
- OUT_AS2 (or, w, %X0);
- OUT_AS2 (or, w, %Y0);
- OUT_AS2 (or, w, %Z0);
+ OUT_AS2 (mov, w, %S1);
+ OUT_AS2 (or, w, %T1);
+ OUT_AS2 (or, w, %U1);
+ OUT_AS2 (or, w, %V1);
+ OUT_AS2 (or, w, %W1);
+ OUT_AS2 (or, w, %X1);
+ OUT_AS2 (or, w, %Y1);
+ OUT_AS2 (or, w, %Z1);
OUT_AS1 (sz,);
OUT_AS1 (page, %2);
OUT_AS1 (jmp, %2);
}
else
{
- operands[3] = GEN_INT (CONST_DOUBLE_LOW (operands[0]) - 1);
- operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[0])
- - (CONST_DOUBLE_LOW (operands[0])
- ? 1 : 0));
+ operands[3] = GEN_INT (const_low0 - 1);
+ operands[4] = GEN_INT (const_high0 - (const_low0 ? 1 : 0));
OUT_AS2 (mov, w, %D3);
OUT_AS2 (sub, w, %Z1);
OUT_AS2 (mov, w, %C3);
@@ -2928,10 +2941,8 @@ ip2k_gen_unsigned_comp_branch (insn, code, label)
case LEU:
if (imm_sub)
{
- if (((CONST_DOUBLE_HIGH (operands[1]) & 0xffffffff)
- == 0xffffffff)
- && ((CONST_DOUBLE_LOW (operands[1]) & 0xffffffff)
- == 0xffffffff))
+ if (((const_high & 0xffffffff) == 0xffffffff)
+ && ((const_low & 0xffffffff) == 0xffffffff))
{
/* <= 0xffffffffffffffff always suceeds. */
OUT_AS1 (page, %2);
@@ -2939,8 +2950,8 @@ ip2k_gen_unsigned_comp_branch (insn, code, label)
}
else
{
- operands[3] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) + 1);
- operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1])
+ operands[3] = GEN_INT (const_low + 1);
+ operands[4] = GEN_INT (const_high
+ (INTVAL (operands[3]) ? 0 : 1));
OUT_AS2 (mov, w, %D3);
OUT_AS2 (sub, w, %Z0);
diff --git a/gcc/config/ip2k/ip2k.h b/gcc/config/ip2k/ip2k.h
index 379682d87bb..bff715f5f37 100644
--- a/gcc/config/ip2k/ip2k.h
+++ b/gcc/config/ip2k/ip2k.h
@@ -2548,7 +2548,7 @@ extern int ip2k_reorg_merge_qimode;
EQ, LEU, GEU}},\
{"ip2k_signed_comparison_operator", {LT, GT, LE, GE}},
-#define DWARF2_DEBUGGING_INFO 1
+#define DWARF2_DEBUGGING_INFO 1
#define DWARF2_ASM_LINE_DEBUG_INFO 1
diff --git a/gcc/config/lynx-ng.h b/gcc/config/lynx-ng.h
index 3ae07e1d601..9ce425137e1 100644
--- a/gcc/config/lynx-ng.h
+++ b/gcc/config/lynx-ng.h
@@ -54,7 +54,7 @@ Boston, MA 02111-1307, USA. */
/* We want to output DBX debugging information. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
@@ -62,7 +62,7 @@ Boston, MA 02111-1307, USA. */
we can create debuggable SDB/coff files. This won't be needed when
stabs-in-coff works. */
-#define SDB_DEBUGGING_INFO
+#define SDB_DEBUGGING_INFO 1
/* Generate calls to memcpy, memcmp and memset. */
diff --git a/gcc/config/lynx.h b/gcc/config/lynx.h
index 193935ee228..94544be19b0 100644
--- a/gcc/config/lynx.h
+++ b/gcc/config/lynx.h
@@ -58,14 +58,14 @@ Boston, MA 02111-1307, USA. */
/* We want to output DBX (stabs) debugging information normally. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
/* It is convenient to be able to generate standard coff debugging
if requested via -gcoff. */
-#define SDB_DEBUGGING_INFO
+#define SDB_DEBUGGING_INFO 1
/* Be function-relative for block and source line stab directives. */
diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h
index 2b3720dd3be..5b7762ae5ef 100644
--- a/gcc/config/m32r/m32r.h
+++ b/gcc/config/m32r/m32r.h
@@ -1860,13 +1860,9 @@ extern char m32r_punct_chars[256];
/* Debugging information. */
/* Generate DBX and DWARF debugging information. */
-#undef DBX_DEBUGGING_INFO
-#undef DWARF_DEBUGGING_INFO
-#undef DWARF2_DEBUGGING_INFO
-
-#define DBX_DEBUGGING_INFO
-#define DWARF_DEBUGGING_INFO
-#define DWARF2_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
+#define DWARF_DEBUGGING_INFO 1
+#define DWARF2_DEBUGGING_INFO 1
/* Prefer STABS (for now). */
#undef PREFERRED_DEBUGGING_TYPE
diff --git a/gcc/config/m68k/3b1.h b/gcc/config/m68k/3b1.h
index 898ece10c66..d2a1391fd48 100644
--- a/gcc/config/m68k/3b1.h
+++ b/gcc/config/m68k/3b1.h
@@ -52,7 +52,7 @@ Boston, MA 02111-1307, USA. */
/* Make output for SDB. */
-#define SDB_DEBUGGING_INFO
+#define SDB_DEBUGGING_INFO 1
/* The .file command should always begin the output. */
diff --git a/gcc/config/m68k/3b1g.h b/gcc/config/m68k/3b1g.h
index 5aecd462919..5850a8a0d22 100644
--- a/gcc/config/m68k/3b1g.h
+++ b/gcc/config/m68k/3b1g.h
@@ -41,7 +41,7 @@ Boston, MA 02111-1307, USA. */
#define CPP_PREDEFINES "-Dmc68000 -Dmc68k -Dunix -Dunixpc -Asystem=unix -Asystem=svr3 -Acpu=m68k -Amachine=m68k"
/* This is (not really) BSD, so (but) it wants DBX format. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
/* Specify how to pad function arguments.
Value should be `upward', `downward' or `none'.
diff --git a/gcc/config/m68k/ccur-GAS.h b/gcc/config/m68k/ccur-GAS.h
index 08909a83ade..4df5ec4bcd0 100644
--- a/gcc/config/m68k/ccur-GAS.h
+++ b/gcc/config/m68k/ccur-GAS.h
@@ -93,7 +93,7 @@ Boston, MA 02111-1307, USA. */
&& (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
/* This is BSD, so it wants DBX format. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
/* Override parts of m68k.h */
diff --git a/gcc/config/m68k/coff.h b/gcc/config/m68k/coff.h
index 9c677f0fada..88720d78157 100644
--- a/gcc/config/m68k/coff.h
+++ b/gcc/config/m68k/coff.h
@@ -24,7 +24,7 @@ Boston, MA 02111-1307, USA. */
/* Generate sdb debugging information. */
-#define SDB_DEBUGGING_INFO
+#define SDB_DEBUGGING_INFO 1
/* Output DBX (stabs) debugging information if using -gstabs. */
diff --git a/gcc/config/m68k/hp2bsd.h b/gcc/config/m68k/hp2bsd.h
index 769dc28698d..5e4501b83c4 100644
--- a/gcc/config/m68k/hp2bsd.h
+++ b/gcc/config/m68k/hp2bsd.h
@@ -59,7 +59,7 @@ Boston, MA 02111-1307, USA. */
/* This is BSD, so it wants DBX format. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
/* Define subroutines to call to handle multiply, divide, and remainder.
These routines are built into the c-library on the hp200.
diff --git a/gcc/config/m68k/hp310g.h b/gcc/config/m68k/hp310g.h
index c07a73b2cb6..d5c543eb3b2 100644
--- a/gcc/config/m68k/hp310g.h
+++ b/gcc/config/m68k/hp310g.h
@@ -5,7 +5,7 @@
/* This wants DBX format. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
#define USE_GAS
diff --git a/gcc/config/m68k/hp320g.h b/gcc/config/m68k/hp320g.h
index 1e931854e90..b20cc3d03cc 100644
--- a/gcc/config/m68k/hp320g.h
+++ b/gcc/config/m68k/hp320g.h
@@ -5,7 +5,7 @@
/* This wants DBX format. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
#define USE_GAS
diff --git a/gcc/config/m68k/hp3bsd.h b/gcc/config/m68k/hp3bsd.h
index b5c6f33beac..23cc9c71b20 100644
--- a/gcc/config/m68k/hp3bsd.h
+++ b/gcc/config/m68k/hp3bsd.h
@@ -23,7 +23,7 @@
/* This is BSD, so it wants DBX format. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
/* Do not break .stabs pseudos into continuations. */
diff --git a/gcc/config/m68k/hp3bsd44.h b/gcc/config/m68k/hp3bsd44.h
index bf2d37ed1b8..780a639efa5 100644
--- a/gcc/config/m68k/hp3bsd44.h
+++ b/gcc/config/m68k/hp3bsd44.h
@@ -32,7 +32,7 @@
/* This is BSD, so it wants DBX format. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
/* Do not break .stabs pseudos into continuations. */
diff --git a/gcc/config/m68k/linux-aout.h b/gcc/config/m68k/linux-aout.h
index 08e2ef574a3..2be6da806a2 100644
--- a/gcc/config/m68k/linux-aout.h
+++ b/gcc/config/m68k/linux-aout.h
@@ -24,7 +24,7 @@ Boston, MA 02111-1307, USA. */
/* 68020 with 68881 */
#define TARGET_DEFAULT (MASK_BITFIELD|MASK_68881|MASK_68020)
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
#define ASM_COMMENT_START "|"
diff --git a/gcc/config/m68k/m68k-aout.h b/gcc/config/m68k/m68k-aout.h
index b65f9fefcd1..136ae61aec0 100644
--- a/gcc/config/m68k/m68k-aout.h
+++ b/gcc/config/m68k/m68k-aout.h
@@ -25,7 +25,7 @@ Boston, MA 02111-1307, USA. */
#include "m68k/m68kemb.h"
#include "aoutos.h"
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
#undef SDB_DEBUGGING_INFO
/* If defined, a C expression whose value is a string containing the
diff --git a/gcc/config/m68k/mot3300.h b/gcc/config/m68k/mot3300.h
index 8868e6e537d..fb7dffa8fc7 100644
--- a/gcc/config/m68k/mot3300.h
+++ b/gcc/config/m68k/mot3300.h
@@ -120,7 +120,7 @@ Boston, MA 02111-1307, USA. */
/* Make output for SDB. */
-#define SDB_DEBUGGING_INFO
+#define SDB_DEBUGGING_INFO 1
#undef REGISTER_PREFIX
#define REGISTER_PREFIX "%"
diff --git a/gcc/config/m68k/netbsd.h b/gcc/config/m68k/netbsd.h
index 6397014b89f..fcf9f531e5a 100644
--- a/gcc/config/m68k/netbsd.h
+++ b/gcc/config/m68k/netbsd.h
@@ -48,7 +48,7 @@
/* This is BSD, so it wants DBX format. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
/* Do not break .stabs pseudos into continuations. */
diff --git a/gcc/config/m68k/openbsd.h b/gcc/config/m68k/openbsd.h
index ac3b6882c11..666350f8bb2 100644
--- a/gcc/config/m68k/openbsd.h
+++ b/gcc/config/m68k/openbsd.h
@@ -63,7 +63,7 @@ Boston, MA 02111-1307, USA. */
/* Specific options for DBX Output. */
/* This is BSD, so it wants DBX format. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
/* Do not break .stabs pseudos into continuations. */
#define DBX_CONTIN_LENGTH 0
diff --git a/gcc/config/m68k/pbb.h b/gcc/config/m68k/pbb.h
index 01d96bce2c1..6eef2acaf47 100644
--- a/gcc/config/m68k/pbb.h
+++ b/gcc/config/m68k/pbb.h
@@ -47,7 +47,7 @@ Boston, MA 02111-1307, USA. */
/* We want DBX format for use with gdb under COFF. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
/* Generate calls to memcpy, memcmp and memset. */
diff --git a/gcc/config/m68k/plexus.h b/gcc/config/m68k/plexus.h
index 35c8e1a15d7..0fac3e29dc7 100644
--- a/gcc/config/m68k/plexus.h
+++ b/gcc/config/m68k/plexus.h
@@ -85,7 +85,7 @@ Boston, MA 02111-1307, USA. */
#ifdef HAVE_GAS_2_X
#undef DBX_DEBUGGING_INFO
-#define SDB_DEBUGGING_INFO
+#define SDB_DEBUGGING_INFO 1
#undef ASM_FILE_START
#define ASM_FILE_START(FILE) \
diff --git a/gcc/config/m68k/sun2.h b/gcc/config/m68k/sun2.h
index 7c2d48e09e9..0f3dde3aeee 100644
--- a/gcc/config/m68k/sun2.h
+++ b/gcc/config/m68k/sun2.h
@@ -74,4 +74,4 @@ Boston, MA 02111-1307, USA. */
/* This is BSD, so it wants DBX format. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
diff --git a/gcc/config/m68k/sun3.h b/gcc/config/m68k/sun3.h
index 6f29be516f9..e3749eed6c8 100644
--- a/gcc/config/m68k/sun3.h
+++ b/gcc/config/m68k/sun3.h
@@ -161,7 +161,7 @@ Boston, MA 02111-1307, USA. */
/* This is BSD, so it wants DBX format. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
/* Generate calls to memcpy, memcmp and memset. */
#define TARGET_MEM_FUNCTIONS
diff --git a/gcc/config/m68k/tower-as.h b/gcc/config/m68k/tower-as.h
index 6c74368eb76..3e0e9b60f9e 100644
--- a/gcc/config/m68k/tower-as.h
+++ b/gcc/config/m68k/tower-as.h
@@ -68,7 +68,7 @@ Boston, MA 02111-1307, USA. */
/* Turn on SDB debugging info. */
-#define SDB_DEBUGGING_INFO
+#define SDB_DEBUGGING_INFO 1
/* All the ASM_OUTPUT macros need to conform to the Tower as syntax. */
diff --git a/gcc/config/m68k/vxm68k.h b/gcc/config/m68k/vxm68k.h
index 161d063a129..a4daa367afa 100644
--- a/gcc/config/m68k/vxm68k.h
+++ b/gcc/config/m68k/vxm68k.h
@@ -65,7 +65,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
%{!mc68000:%{!m68000:%{!m68010:%{!mc68020:%{!m68020:%{!m68030:%{!m68040:%{!m68020-40:%{!m68302:%{!m68332:%(cpp_subtarget_cpu_default) }}}}}}}}}} \
"
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
#undef SDB_DEBUGGING_INFO
/* These are the official values from WRS. */
diff --git a/gcc/config/m88k/aout-dbx.h b/gcc/config/m88k/aout-dbx.h
index 1b8446ba79b..4eef7d685ba 100644
--- a/gcc/config/m88k/aout-dbx.h
+++ b/gcc/config/m88k/aout-dbx.h
@@ -20,6 +20,6 @@ Boston, MA 02111-1307, USA. */
/* a.out with DBX. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
#define DEFAULT_GDB_EXTENSIONS 0
diff --git a/gcc/config/m88k/m88k-aout.h b/gcc/config/m88k/m88k-aout.h
index aa553764890..50ea8dd3da7 100644
--- a/gcc/config/m88k/m88k-aout.h
+++ b/gcc/config/m88k/m88k-aout.h
@@ -21,7 +21,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#undef SDB_DEBUGGING_INFO
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
#include "m88k/m88k.h"
#include "aoutos.h"
diff --git a/gcc/config/mcore/mcore-elf.h b/gcc/config/mcore/mcore-elf.h
index 8d748031fa6..b4c7ae63d4b 100644
--- a/gcc/config/mcore/mcore-elf.h
+++ b/gcc/config/mcore/mcore-elf.h
@@ -28,17 +28,13 @@ Boston, MA 02111-1307, USA. */
#define SUBTARGET_CPP_PREDEFINES " -D__ELF__"
/* Use DWARF2 debugging info. */
-#ifndef DWARF2_DEBUGGING_INFO
#define DWARF2_DEBUGGING_INFO 1
-#endif
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
/* But allow DWARF 1 if the user wants it. */
-#ifndef DWARF_DEBUGGING_INFO
#define DWARF_DEBUGGING_INFO 1
-#endif
#define EXPORTS_SECTION_ASM_OP "\t.section .exports"
diff --git a/gcc/config/mcore/mcore-pe.h b/gcc/config/mcore/mcore-pe.h
index 6668574458d..a580fc5bfbc 100644
--- a/gcc/config/mcore/mcore-pe.h
+++ b/gcc/config/mcore/mcore-pe.h
@@ -33,7 +33,6 @@ Boston, MA 02111-1307, USA. */
#include "dbxcoff.h"
#undef SDB_DEBUGGING_INFO
-#undef DBX_DEBUGGING_INFO
#define DBX_DEBUGGING_INFO 1
/* Computed in toplev.c. */
diff --git a/gcc/config/mips/elf.h b/gcc/config/mips/elf.h
index 6e9004b6e67..ba2a057e595 100644
--- a/gcc/config/mips/elf.h
+++ b/gcc/config/mips/elf.h
@@ -27,8 +27,8 @@ Boston, MA 02111-1307, USA. */
/* ??? Move all SDB stuff into separate header file. */
#undef SDB_DEBUGGING_INFO
-#define DBX_DEBUGGING_INFO
-#define DWARF2_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
+#define DWARF2_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
diff --git a/gcc/config/mips/elf64.h b/gcc/config/mips/elf64.h
index b7ed0e158e5..414d16f4ef8 100644
--- a/gcc/config/mips/elf64.h
+++ b/gcc/config/mips/elf64.h
@@ -25,8 +25,8 @@ Boston, MA 02111-1307, USA. */
#define OBJECT_FORMAT_ELF
#undef SDB_DEBUGGING_INFO
-#define DBX_DEBUGGING_INFO
-#define DWARF2_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
+#define DWARF2_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
diff --git a/gcc/config/mips/iris5gas.h b/gcc/config/mips/iris5gas.h
index a4985db87a5..7ba65656893 100644
--- a/gcc/config/mips/iris5gas.h
+++ b/gcc/config/mips/iris5gas.h
@@ -1,10 +1,10 @@
/* Definitions of target machine for GNU compiler. Irix version 5 with gas. */
/* Enable debugging. */
-#define DBX_DEBUGGING_INFO
-#define DWARF2_DEBUGGING_INFO
-#define SDB_DEBUGGING_INFO
-#define MIPS_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
+#define DWARF2_DEBUGGING_INFO 1
+#define SDB_DEBUGGING_INFO 1
+#define MIPS_DEBUGGING_INFO 1
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
/* GNU as does handle DWARF2 directives. */
diff --git a/gcc/config/mips/iris6.h b/gcc/config/mips/iris6.h
index 4761aa5a883..ddfea8f1473 100644
--- a/gcc/config/mips/iris6.h
+++ b/gcc/config/mips/iris6.h
@@ -139,8 +139,8 @@ Boston, MA 02111-1307, USA. */
} while (0)
/* Irix 6 uses DWARF-2. */
-#define DWARF2_DEBUGGING_INFO
-#define MIPS_DEBUGGING_INFO
+#define DWARF2_DEBUGGING_INFO 1
+#define MIPS_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index ee5ccf2f48c..c04e6b51a21 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -1220,9 +1220,9 @@ extern int mips_abi;
#endif
-#define SDB_DEBUGGING_INFO /* generate info for mips-tfile */
-#define DBX_DEBUGGING_INFO /* generate stabs (OSF/rose) */
-#define MIPS_DEBUGGING_INFO /* MIPS specific debugging info */
+#define SDB_DEBUGGING_INFO 1 /* generate info for mips-tfile */
+#define DBX_DEBUGGING_INFO 1 /* generate stabs (OSF/rose) */
+#define MIPS_DEBUGGING_INFO 1 /* MIPS specific debugging info */
#ifndef PREFERRED_DEBUGGING_TYPE /* assume SDB_DEBUGGING_INFO */
#define PREFERRED_DEBUGGING_TYPE SDB_DEBUG
diff --git a/gcc/config/mips/netbsd.h b/gcc/config/mips/netbsd.h
index bda60584871..02ba41386e3 100644
--- a/gcc/config/mips/netbsd.h
+++ b/gcc/config/mips/netbsd.h
@@ -22,19 +22,12 @@ Boston, MA 02111-1307, USA. */
/* Define default target values. */
-#ifndef TARGET_ENDIAN_DEFAULT
-#define TARGET_ENDIAN_DEFAULT MASK_BIG_ENDIAN
-#endif
-
-#ifndef MACHINE_TYPE
+#undef MACHINE_TYPE
#if TARGET_ENDIAN_DEFAULT != 0
#define MACHINE_TYPE "NetBSD/mipseb ELF"
#else
#define MACHINE_TYPE "NetBSD/mipsel ELF"
#endif
-#endif
-
-#define TARGET_DEFAULT (MASK_GAS|MASK_ABICALLS)
#define TARGET_OS_CPP_BUILTINS() \
do \
@@ -49,13 +42,6 @@ Boston, MA 02111-1307, USA. */
while (0)
-/* XXX Don't use DWARF-2 debugging info, for now. */
-#undef DBX_DEBUGGING_INFO
-#define DBX_DEBUGGING_INFO
-#undef PREFERRED_DEBUGGING_TYPE
-#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
-
-
/* Include the generic MIPS ELF configuration. */
#include <mips/elf.h>
diff --git a/gcc/config/mips/sni-gas.h b/gcc/config/mips/sni-gas.h
index e79c074405f..5515bfd3c39 100644
--- a/gcc/config/mips/sni-gas.h
+++ b/gcc/config/mips/sni-gas.h
@@ -1,9 +1,9 @@
/* Enable debugging. */
-#define DBX_DEBUGGING_INFO
-#define SDB_DEBUGGING_INFO
-#define MIPS_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
+#define SDB_DEBUGGING_INFO 1
+#define MIPS_DEBUGGING_INFO 1
+#define DWARF_DEBUGGING_INFO 1
-#define DWARF_DEBUGGING_INFO
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF_DEBUG
diff --git a/gcc/config/mmix/mmix.h b/gcc/config/mmix/mmix.h
index 5da23882b9b..59b09b4dccd 100644
--- a/gcc/config/mmix/mmix.h
+++ b/gcc/config/mmix/mmix.h
@@ -1119,7 +1119,7 @@ typedef struct { int regs; int lib; } CUMULATIVE_ARGS;
/* Node: SDB and DWARF */
-#define DWARF2_DEBUGGING_INFO
+#define DWARF2_DEBUGGING_INFO 1
#define DWARF2_ASM_LINE_DEBUG_INFO 1
/* Node: Misc */
diff --git a/gcc/config/netware.h b/gcc/config/netware.h
index 90e85aac1d5..d713ce806d2 100644
--- a/gcc/config/netware.h
+++ b/gcc/config/netware.h
@@ -49,7 +49,7 @@ Boston, MA 02111-1307, USA. */
#undef LIBGCC_SPEC
/* set debugging info */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
#undef SDB_DEBUGGING_INFO
#undef DWARF_DEBUGGING_INFO
#undef XCOFF_DEBUGGING_INFO
diff --git a/gcc/config/ns32k/netbsd.h b/gcc/config/ns32k/netbsd.h
index 28bae88cb88..66ba1cb4724 100644
--- a/gcc/config/ns32k/netbsd.h
+++ b/gcc/config/ns32k/netbsd.h
@@ -88,7 +88,7 @@ Boston, MA 02111-1307, USA. */
/* This is BSD, so it wants DBX format. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
/* Do not break .stabs pseudos into continuations. */
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 9f692537a46..718ad1382a1 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -116,7 +116,8 @@ static void pa_select_section PARAMS ((tree, int, unsigned HOST_WIDE_INT))
ATTRIBUTE_UNUSED;
static void pa_encode_section_info PARAMS ((tree, int));
static const char *pa_strip_name_encoding PARAMS ((const char *));
-static void pa_globalize_label PARAMS ((FILE *, const char *));
+static void pa_globalize_label PARAMS ((FILE *, const char *))
+ ATTRIBUTE_UNUSED;
/* Save the operands last given to a compare for use when we
generate a scc or bcc insn. */
diff --git a/gcc/config/pa/pa64-hpux.h b/gcc/config/pa/pa64-hpux.h
index c82e185434a..f62cd6e0c0d 100644
--- a/gcc/config/pa/pa64-hpux.h
+++ b/gcc/config/pa/pa64-hpux.h
@@ -83,7 +83,7 @@ do { \
/* It looks like DWARF2 will be the easiest debug format to handle on this
platform. */
#define OBJECT_FORMAT_ELF
-#define DWARF2_DEBUGGING_INFO
+#define DWARF2_DEBUGGING_INFO 1
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
/* This isn't quite ready yet. I'm seeing it mess up some line
tables. For example, we're getting lines starting/ending at
diff --git a/gcc/config/pa/som.h b/gcc/config/pa/som.h
index 644c85900b7..e72b7fed64a 100644
--- a/gcc/config/pa/som.h
+++ b/gcc/config/pa/som.h
@@ -365,3 +365,9 @@ do { \
/* SOM does not support the init_priority C++ attribute. */
#undef SUPPORTS_INIT_PRIORITY
#define SUPPORTS_INIT_PRIORITY 0
+
+/* The SOM linker hardcodes paths into binaries. As a result, dotdots
+ must be removed from library prefixes to prevent binaries from depending
+ on the location of the GCC tool directory. The downside is GCC
+ cannot be moved after installation using a symlink. */
+#define ALWAYS_STRIP_DOTDOT 1
diff --git a/gcc/config/psos.h b/gcc/config/psos.h
index 9529a216826..fbe5b96e0bc 100644
--- a/gcc/config/psos.h
+++ b/gcc/config/psos.h
@@ -85,4 +85,4 @@ Boston, MA 02111-1307, USA.
/* For pSOS we use DBX debugging info. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
diff --git a/gcc/config/romp/romp.h b/gcc/config/romp/romp.h
index ce506b0e99b..c5ca82b049d 100644
--- a/gcc/config/romp/romp.h
+++ b/gcc/config/romp/romp.h
@@ -1100,7 +1100,7 @@ struct rt_cargs {int gregs, fregs; };
#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
/* This is BSD, so it wants DBX format. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
/* Define the letter code used in a stabs entry for parameters passed
with the register attribute.
diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
index a1f162e0558..ee469319c7a 100644
--- a/gcc/config/rs6000/linux64.h
+++ b/gcc/config/rs6000/linux64.h
@@ -73,6 +73,7 @@ Boston, MA 02111-1307, USA. */
#define USER_LABEL_PREFIX ""
/* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints. */
+#undef ADJUST_FIELD_ALIGN
#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
(TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
? get_inner_array_type (FIELD) \
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 42aa929b855..f91afcde66a 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -522,7 +522,11 @@ extern int rs6000_default_long_calls;
/* Width of a word, in units (bytes). */
#define UNITS_PER_WORD (! TARGET_POWERPC64 ? 4 : 8)
+#ifdef IN_LIBGCC2
+#define MIN_UNITS_PER_WORD UNITS_PER_WORD
+#else
#define MIN_UNITS_PER_WORD 4
+#endif
#define UNITS_PER_FP_WORD 8
#define UNITS_PER_ALTIVEC_WORD 16
#define UNITS_PER_SPE_WORD 8
diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
index 34cb80eeb26..c753b6899a9 100644
--- a/gcc/config/rs6000/sysv4.h
+++ b/gcc/config/rs6000/sysv4.h
@@ -782,7 +782,7 @@ extern int fixuplabelno;
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
/* Historically we have also supported stabs debugging. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
#define TARGET_ENCODE_SECTION_INFO rs6000_elf_encode_section_info
#define TARGET_STRIP_NAME_ENCODING rs6000_elf_strip_name_encoding
diff --git a/gcc/config/rs6000/xcoff.h b/gcc/config/rs6000/xcoff.h
index 339b25c243a..24e1300c0da 100644
--- a/gcc/config/rs6000/xcoff.h
+++ b/gcc/config/rs6000/xcoff.h
@@ -23,7 +23,7 @@ Boston, MA 02111-1307, USA. */
#define TARGET_OBJECT_FORMAT OBJECT_XCOFF
/* The RS/6000 uses the XCOFF format. */
-#define XCOFF_DEBUGGING_INFO
+#define XCOFF_DEBUGGING_INFO 1
/* Define if the object format being used is COFF or a superset. */
#define OBJECT_FORMAT_COFF
diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index 38c5c0b2035..c44ffb33234 100644
--- a/gcc/config/s390/s390-protos.h
+++ b/gcc/config/s390/s390-protos.h
@@ -24,8 +24,6 @@ Boston, MA 02111-1307, USA. */
extern void optimization_options PARAMS ((int, int));
extern void override_options PARAMS ((void));
extern int s390_arg_frame_offset PARAMS ((void));
-extern void s390_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
-extern void s390_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
extern void s390_emit_prologue PARAMS ((void));
extern void s390_emit_epilogue PARAMS ((void));
extern void s390_function_profiler PARAMS ((FILE *, int));
@@ -72,6 +70,7 @@ extern void s390_trampoline_template PARAMS ((FILE *));
extern void s390_initialize_trampoline PARAMS ((rtx, rtx, rtx));
extern rtx s390_gen_rtx_const_DI PARAMS ((int, int));
extern rtx s390_simplify_dwarf_addr PARAMS ((rtx));
+extern void s390_machine_dependent_reorg PARAMS ((rtx));
#endif /* RTX_CODE */
#ifdef TREE_CODE
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 85952c5bacb..6ee09c542d0 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -61,12 +61,6 @@ static void s390_encode_section_info PARAMS ((tree, int));
#undef TARGET_ASM_INTEGER
#define TARGET_ASM_INTEGER s390_assemble_integer
-#undef TARGET_ASM_FUNCTION_PROLOGUE
-#define TARGET_ASM_FUNCTION_PROLOGUE s390_function_prologue
-
-#undef TARGET_ASM_FUNCTION_EPILOGUE
-#define TARGET_ASM_FUNCTION_EPILOGUE s390_function_epilogue
-
#undef TARGET_ASM_OPEN_PAREN
#define TARGET_ASM_OPEN_PAREN ""
@@ -92,9 +86,6 @@ extern int reload_completed;
/* The alias set for prologue/epilogue register save/restore. */
static int s390_sr_alias_set = 0;
-/* Function count for creating unique internal labels in a compile unit. */
-int s390_function_count = 0;
-
/* Save information from a "cmpxx" operation until the branch or scc is
emitted. */
rtx s390_compare_op0, s390_compare_op1;
@@ -121,7 +112,6 @@ struct s390_address
struct s390_frame
{
int frame_pointer_p;
- int return_reg_saved_p;
int save_fprs_p;
int first_save_gpr;
int first_restore_gpr;
@@ -143,11 +133,13 @@ static void s390_split_branches PARAMS ((void));
static void find_constant_pool_ref PARAMS ((rtx, rtx *));
static void replace_constant_pool_ref PARAMS ((rtx *, rtx, rtx));
static void s390_chunkify_pool PARAMS ((void));
-static int save_fprs_p PARAMS ((void));
+static void s390_optimize_prolog PARAMS ((void));
static int find_unused_clobbered_reg PARAMS ((void));
static void s390_frame_info PARAMS ((struct s390_frame *));
static rtx save_fpr PARAMS ((rtx, int, int));
static rtx restore_fpr PARAMS ((rtx, int, int));
+static rtx save_gprs PARAMS ((rtx, int, int, int));
+static rtx restore_gprs PARAMS ((rtx, int, int, int));
static int s390_function_arg_size PARAMS ((enum machine_mode, tree));
@@ -1269,15 +1261,6 @@ legitimate_reload_constant_p (op)
&& larl_operand (op, VOIDmode))
return 1;
- /* If reload is completed, and we do not already have a
- literal pool, and OP must be forced to the literal
- pool, then something must have gone wrong earlier.
- We *cannot* force the constant any more, because the
- prolog generation already decided we don't need to
- set up the base register. */
- if (reload_completed && !regs_ever_live[BASE_REGISTER])
- abort ();
-
/* Everything else cannot be handled without reload. */
return 0;
}
@@ -1826,7 +1809,8 @@ legitimize_pic_address (orig, reg)
/* Assume GOT offset < 4k. This is handled the same way
in both 31- and 64-bit code (@GOT12). */
- current_function_uses_pic_offset_table = 1;
+ if (reload_in_progress || reload_completed)
+ regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 110);
new = gen_rtx_CONST (Pmode, new);
@@ -1859,7 +1843,8 @@ legitimize_pic_address (orig, reg)
rtx temp = gen_reg_rtx (Pmode);
- current_function_uses_pic_offset_table = 1;
+ if (reload_in_progress || reload_completed)
+ regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, addr), 112);
addr = gen_rtx_CONST (SImode, addr);
@@ -2218,7 +2203,7 @@ s390_output_symbolic_const (file, x)
{
case 100:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
- fprintf (file, "-.LT%X", s390_function_count);
+ fprintf (file, "-.LT%d", current_function_funcdef_no);
break;
case 110:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
@@ -2238,7 +2223,7 @@ s390_output_symbolic_const (file, x)
break;
case 114:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
- fprintf (file, "@PLT-.LT%X", s390_function_count);
+ fprintf (file, "@PLT-.LT%d", current_function_funcdef_no);
break;
default:
output_operand_lossage ("invalid UNSPEC as operand (2)");
@@ -2638,6 +2623,10 @@ s390_split_branches ()
if (TARGET_64BIT)
return;
+ /* We need correct insn addresses. */
+
+ shorten_branches (get_insns ());
+
/* Find all branches that exceed 64KB, and split them. */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
@@ -2668,6 +2657,8 @@ s390_split_branches ()
if (get_attr_length (insn) == 4)
continue;
+ regs_ever_live[RETURN_REGNUM] = 1;
+
if (flag_pic)
{
target = gen_rtx_UNSPEC (SImode, gen_rtvec (1, label), 100);
@@ -3061,6 +3052,14 @@ s390_chunkify_pool ()
if (get_pool_size () < S390_POOL_CHUNK_MAX)
return;
+ if (!TARGET_64BIT)
+ regs_ever_live[RETURN_REGNUM] = 1;
+
+ /* We need correct insn addresses. */
+
+ shorten_branches (get_insns ());
+
+
/* Scan all insns and move literals to pool chunks.
Replace all occurrances of literal pool references
by explicit references to pool chunk entries. */
@@ -3352,17 +3351,17 @@ s390_output_constant_pool (file)
{
if (TARGET_64BIT)
{
- fprintf (file, "\tlarl\t%s,.LT%X\n", reg_names[BASE_REGISTER],
- s390_function_count);
+ fprintf (file, "\tlarl\t%s,.LT%d\n", reg_names[BASE_REGISTER],
+ current_function_funcdef_no);
readonly_data_section ();
ASM_OUTPUT_ALIGN (file, 3);
}
else
{
- fprintf (file, "\tbras\t%s,.LTN%X\n", reg_names[BASE_REGISTER],
- s390_function_count);
+ fprintf (file, "\tbras\t%s,.LTN%d\n", reg_names[BASE_REGISTER],
+ current_function_funcdef_no);
}
- fprintf (file, ".LT%X:\n", s390_function_count);
+ fprintf (file, ".LT%d:\n", current_function_funcdef_no);
s390_pool_count = 0;
output_constant_pool (current_function_name, current_function_decl);
@@ -3371,27 +3370,159 @@ s390_output_constant_pool (file)
if (TARGET_64BIT)
function_section (current_function_decl);
else
- fprintf (file, ".LTN%X:\n", s390_function_count);
+ fprintf (file, ".LTN%d:\n", current_function_funcdef_no);
}
}
-/* Return true if floating point registers need to be saved. */
+/* Rework the prolog/epilog to avoid saving/restoring
+ registers unnecessarily. */
-static int
-save_fprs_p ()
+static void
+s390_optimize_prolog ()
{
- int i;
- if (!TARGET_64BIT)
- return 0;
- for (i=24; i<=31; i++)
+ int save_first, save_last, restore_first, restore_last;
+ int i, j;
+ rtx insn, new_insn, next_insn;
+
+ /* Find first and last gpr to be saved. */
+
+ for (i = 6; i < 16; i++)
+ if (regs_ever_live[i])
+ break;
+
+ for (j = 15; j > i; j--)
+ if (regs_ever_live[j])
+ break;
+
+ if (i == 16)
{
- if (regs_ever_live[i] == 1)
- return 1;
+ /* Nothing to save/restore. */
+ save_first = restore_first = -1;
+ save_last = restore_last = -1;
}
- return 0;
+ else
+ {
+ /* Save/restore from i to j. */
+ save_first = restore_first = i;
+ save_last = restore_last = j;
+ }
+
+ /* Varargs functions need to save gprs 2 to 6. */
+ if (current_function_stdarg)
+ {
+ save_first = 2;
+ if (save_last < 6)
+ save_last = 6;
+ }
+
+
+ /* If all special registers are in fact used, there's nothing we
+ can do, so no point in walking the insn list. */
+ if (i <= BASE_REGISTER && j >= BASE_REGISTER
+ && i <= RETURN_REGNUM && j >= RETURN_REGNUM)
+ return;
+
+
+ /* Search for prolog/epilog insns and replace them. */
+
+ for (insn = get_insns (); insn; insn = next_insn)
+ {
+ int first, last, off;
+ rtx set, base, offset;
+
+ next_insn = NEXT_INSN (insn);
+
+ if (GET_CODE (insn) != INSN)
+ continue;
+ if (GET_CODE (PATTERN (insn)) != PARALLEL)
+ continue;
+
+ if (store_multiple_operation (PATTERN (insn), VOIDmode))
+ {
+ set = XVECEXP (PATTERN (insn), 0, 0);
+ first = REGNO (SET_SRC (set));
+ last = first + XVECLEN (PATTERN (insn), 0) - 1;
+ offset = const0_rtx;
+ base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
+ off = INTVAL (offset) - first * UNITS_PER_WORD;
+
+ if (GET_CODE (base) != REG || off < 0)
+ continue;
+ if (first > BASE_REGISTER && first > RETURN_REGNUM)
+ continue;
+ if (last < BASE_REGISTER && last < RETURN_REGNUM)
+ continue;
+
+ if (save_first != -1)
+ {
+ new_insn = save_gprs (base, off, save_first, save_last);
+ new_insn = emit_insn_before (new_insn, insn);
+ INSN_ADDRESSES_NEW (new_insn, -1);
+ }
+
+ remove_insn (insn);
+ }
+
+ if (load_multiple_operation (PATTERN (insn), VOIDmode))
+ {
+ set = XVECEXP (PATTERN (insn), 0, 0);
+ first = REGNO (SET_DEST (set));
+ last = first + XVECLEN (PATTERN (insn), 0) - 1;
+ offset = const0_rtx;
+ base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
+ off = INTVAL (offset) - first * UNITS_PER_WORD;
+
+ if (GET_CODE (base) != REG || off < 0)
+ continue;
+ if (first > BASE_REGISTER && first > RETURN_REGNUM)
+ continue;
+ if (last < BASE_REGISTER && last < RETURN_REGNUM)
+ continue;
+
+ if (restore_first != -1)
+ {
+ new_insn = restore_gprs (base, off, restore_first, restore_last);
+ new_insn = emit_insn_before (new_insn, insn);
+ INSN_ADDRESSES_NEW (new_insn, -1);
+ }
+
+ remove_insn (insn);
+ }
+ }
+}
+
+/* Perform machine-dependent processing. */
+
+void
+s390_machine_dependent_reorg (first)
+ rtx first ATTRIBUTE_UNUSED;
+{
+ struct s390_frame frame;
+ s390_frame_info (&frame);
+
+ /* Recompute regs_ever_live data for special registers. */
+ regs_ever_live[BASE_REGISTER] = 0;
+ regs_ever_live[RETURN_REGNUM] = 0;
+ regs_ever_live[STACK_POINTER_REGNUM] = frame.frame_size > 0;
+
+ /* If there is (possibly) any pool entry, we need to
+ load the base register.
+ ??? FIXME: this should be more precise. */
+ if (get_pool_size ())
+ regs_ever_live[BASE_REGISTER] = 1;
+
+ /* In non-leaf functions, the prolog/epilog code relies
+ on RETURN_REGNUM being saved in any case. */
+ if (!current_function_is_leaf)
+ regs_ever_live[RETURN_REGNUM] = 1;
+
+ s390_chunkify_pool ();
+ s390_split_branches ();
+ s390_optimize_prolog ();
}
+
/* Find first call clobbered register unsused in a function.
This could be used as base register in a leaf function
or for holding the return address before epilogue. */
@@ -3412,6 +3543,7 @@ static void
s390_frame_info (frame)
struct s390_frame *frame;
{
+ char gprs_ever_live[16];
int i, j;
HOST_WIDE_INT fsize = get_frame_size ();
@@ -3419,7 +3551,14 @@ s390_frame_info (frame)
fatal_error ("Total size of local variables exceeds architecture limit.");
/* fprs 8 - 15 are caller saved for 64 Bit ABI. */
- frame->save_fprs_p = save_fprs_p ();
+ frame->save_fprs_p = 0;
+ if (TARGET_64BIT)
+ for (i = 24; i < 32; i++)
+ if (regs_ever_live[i])
+ {
+ frame->save_fprs_p = 1;
+ break;
+ }
frame->frame_size = fsize + frame->save_fprs_p * 64;
@@ -3431,66 +3570,41 @@ s390_frame_info (frame)
|| current_function_stdarg)
frame->frame_size += STARTING_FRAME_OFFSET;
- /* If we need to allocate a frame, the stack pointer is changed. */
-
- if (frame->frame_size > 0)
- regs_ever_live[STACK_POINTER_REGNUM] = 1;
-
- /* If the literal pool might overflow, the return register might
- be used as temp literal pointer. */
-
- if (!TARGET_64BIT && get_pool_size () >= S390_POOL_CHUNK_MAX / 2)
- regs_ever_live[RETURN_REGNUM] = 1;
-
- /* If there is (possibly) any pool entry, we need to
- load base register. */
-
- if (get_pool_size ()
- || !CONST_OK_FOR_LETTER_P (frame->frame_size, 'K')
- || (!TARGET_64BIT && current_function_uses_pic_offset_table))
- regs_ever_live[BASE_REGISTER] = 1;
-
- /* If we need the GOT pointer, remember to save/restore it. */
-
- if (current_function_uses_pic_offset_table)
- regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
-
/* Frame pointer needed. */
frame->frame_pointer_p = frame_pointer_needed;
- /* Find first and last gpr to be saved. */
+ /* Find first and last gpr to be saved. Note that at this point,
+ we assume the return register and the base register always
+ need to be saved. This is done because the usage of these
+ register might change even after the prolog was emitted.
+ If it turns out later that we really don't need them, the
+ prolog/epilog code is modified again. */
+
+ for (i = 0; i < 16; i++)
+ gprs_ever_live[i] = regs_ever_live[i];
+
+ gprs_ever_live[BASE_REGISTER] = 1;
+ gprs_ever_live[RETURN_REGNUM] = 1;
+ gprs_ever_live[STACK_POINTER_REGNUM] = frame->frame_size > 0;
for (i = 6; i < 16; i++)
- if (regs_ever_live[i])
+ if (gprs_ever_live[i])
break;
for (j = 15; j > i; j--)
- if (regs_ever_live[j])
+ if (gprs_ever_live[j])
break;
-
- if (i == 16)
- {
- /* Nothing to save / restore. */
- frame->first_save_gpr = -1;
- frame->first_restore_gpr = -1;
- frame->last_save_gpr = -1;
- frame->return_reg_saved_p = 0;
- }
- else
- {
- /* Save / Restore from gpr i to j. */
- frame->first_save_gpr = i;
- frame->first_restore_gpr = i;
- frame->last_save_gpr = j;
- frame->return_reg_saved_p = (j >= RETURN_REGNUM && i <= RETURN_REGNUM);
- }
+
+ /* Save / Restore from gpr i to j. */
+ frame->first_save_gpr = i;
+ frame->first_restore_gpr = i;
+ frame->last_save_gpr = j;
+
+ /* Varargs functions need to save gprs 2 to 6. */
if (current_function_stdarg)
- {
- /* Varargs function need to save from gpr 2 to gpr 15. */
- frame->first_save_gpr = 2;
- }
+ frame->first_save_gpr = 2;
}
/* Return offset between argument pointer and frame pointer
@@ -3540,30 +3654,118 @@ restore_fpr (base, offset, regnum)
return emit_move_insn (gen_rtx_REG (DFmode, regnum), addr);
}
-/* Output the function prologue assembly code to the
- stdio stream FILE. The local frame size is passed
- in LSIZE. */
+/* Generate insn to save registers FIRST to LAST into
+ the register save area located at offset OFFSET
+ relative to register BASE. */
-void
-s390_function_prologue (file, lsize)
- FILE *file ATTRIBUTE_UNUSED;
- HOST_WIDE_INT lsize ATTRIBUTE_UNUSED;
+static rtx
+save_gprs (base, offset, first, last)
+ rtx base;
+ int offset;
+ int first;
+ int last;
{
- s390_chunkify_pool ();
- s390_split_branches ();
+ rtx addr, insn, note;
+ int i;
+
+ addr = plus_constant (base, offset + first * UNITS_PER_WORD);
+ addr = gen_rtx_MEM (Pmode, addr);
+ set_mem_alias_set (addr, s390_sr_alias_set);
+
+ /* Special-case single register. */
+ if (first == last)
+ {
+ if (TARGET_64BIT)
+ insn = gen_movdi (addr, gen_rtx_REG (Pmode, first));
+ else
+ insn = gen_movsi (addr, gen_rtx_REG (Pmode, first));
+
+ RTX_FRAME_RELATED_P (insn) = 1;
+ return insn;
+ }
+
+
+ insn = gen_store_multiple (addr,
+ gen_rtx_REG (Pmode, first),
+ GEN_INT (last - first + 1));
+
+
+ /* We need to set the FRAME_RELATED flag on all SETs
+ inside the store-multiple pattern.
+
+ However, we must not emit DWARF records for registers 2..5
+ if they are stored for use by variable arguments ...
+
+ ??? Unfortunately, it is not enough to simply not the the
+ FRAME_RELATED flags for those SETs, because the first SET
+ of the PARALLEL is always treated as if it had the flag
+ set, even if it does not. Therefore we emit a new pattern
+ without those registers as REG_FRAME_RELATED_EXPR note. */
+
+ if (first >= 6)
+ {
+ rtx pat = PATTERN (insn);
+
+ for (i = 0; i < XVECLEN (pat, 0); i++)
+ if (GET_CODE (XVECEXP (pat, 0, i)) == SET)
+ RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1;
+
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+ else if (last >= 6)
+ {
+ addr = plus_constant (base, offset + 6 * UNITS_PER_WORD);
+ note = gen_store_multiple (gen_rtx_MEM (Pmode, addr),
+ gen_rtx_REG (Pmode, 6),
+ GEN_INT (last - 6 + 1));
+ note = PATTERN (note);
+
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+ note, REG_NOTES (insn));
+
+ for (i = 0; i < XVECLEN (note, 0); i++)
+ if (GET_CODE (XVECEXP (note, 0, i)) == SET)
+ RTX_FRAME_RELATED_P (XVECEXP (note, 0, i)) = 1;
+
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+
+ return insn;
}
-/* Output the function epilogue assembly code to the
- stdio stream FILE. The local frame size is passed
- in LSIZE. */
+/* Generate insn to restore registers FIRST to LAST from
+ the register save area located at offset OFFSET
+ relative to register BASE. */
-void
-s390_function_epilogue (file, lsize)
- FILE *file ATTRIBUTE_UNUSED;
- HOST_WIDE_INT lsize ATTRIBUTE_UNUSED;
+static rtx
+restore_gprs (base, offset, first, last)
+ rtx base;
+ int offset;
+ int first;
+ int last;
{
- current_function_uses_pic_offset_table = 0;
- s390_function_count++;
+ rtx addr, insn;
+
+ addr = plus_constant (base, offset + first * UNITS_PER_WORD);
+ addr = gen_rtx_MEM (Pmode, addr);
+ set_mem_alias_set (addr, s390_sr_alias_set);
+
+ /* Special-case single register. */
+ if (first == last)
+ {
+ if (TARGET_64BIT)
+ insn = gen_movdi (gen_rtx_REG (Pmode, first), addr);
+ else
+ insn = gen_movsi (gen_rtx_REG (Pmode, first), addr);
+
+ return insn;
+ }
+
+ insn = gen_load_multiple (gen_rtx_REG (Pmode, first),
+ addr,
+ GEN_INT (last - first + 1));
+ return insn;
}
/* Expand the prologue into a bunch of separate insns. */
@@ -3582,7 +3784,7 @@ s390_emit_prologue ()
/* Choose best register to use for temp use within prologue. */
- if (frame.return_reg_saved_p
+ if (!current_function_is_leaf
&& !has_hard_reg_initial_val (Pmode, RETURN_REGNUM)
&& get_pool_size () < S390_POOL_CHUNK_MAX / 2)
temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
@@ -3591,69 +3793,9 @@ s390_emit_prologue ()
/* Save call saved gprs. */
- if (frame.first_save_gpr != -1)
- {
- addr = plus_constant (stack_pointer_rtx,
- frame.first_save_gpr * UNITS_PER_WORD);
- addr = gen_rtx_MEM (Pmode, addr);
- set_mem_alias_set (addr, s390_sr_alias_set);
-
- if (frame.first_save_gpr != frame.last_save_gpr )
- {
- insn = emit_insn (gen_store_multiple (addr,
- gen_rtx_REG (Pmode, frame.first_save_gpr),
- GEN_INT (frame.last_save_gpr
- - frame.first_save_gpr + 1)));
-
- /* We need to set the FRAME_RELATED flag on all SETs
- inside the store-multiple pattern.
-
- However, we must not emit DWARF records for registers 2..5
- if they are stored for use by variable arguments ...
-
- ??? Unfortunately, it is not enough to simply not the the
- FRAME_RELATED flags for those SETs, because the first SET
- of the PARALLEL is always treated as if it had the flag
- set, even if it does not. Therefore we emit a new pattern
- without those registers as REG_FRAME_RELATED_EXPR note. */
-
- if (frame.first_save_gpr >= 6)
- {
- rtx pat = PATTERN (insn);
-
- for (i = 0; i < XVECLEN (pat, 0); i++)
- if (GET_CODE (XVECEXP (pat, 0, i)) == SET)
- RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1;
-
- RTX_FRAME_RELATED_P (insn) = 1;
- }
- else if (frame.last_save_gpr >= 6)
- {
- rtx note, naddr;
- naddr = plus_constant (stack_pointer_rtx, 6 * UNITS_PER_WORD);
- note = gen_store_multiple (gen_rtx_MEM (Pmode, naddr),
- gen_rtx_REG (Pmode, 6),
- GEN_INT (frame.last_save_gpr - 6 + 1));
- note = PATTERN (note);
-
- REG_NOTES (insn) =
- gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
- note, REG_NOTES (insn));
-
- for (i = 0; i < XVECLEN (note, 0); i++)
- if (GET_CODE (XVECEXP (note, 0, i)) == SET)
- RTX_FRAME_RELATED_P (XVECEXP (note, 0, i)) = 1;
-
- RTX_FRAME_RELATED_P (insn) = 1;
- }
- }
- else
- {
- insn = emit_move_insn (addr,
- gen_rtx_REG (Pmode, frame.first_save_gpr));
- RTX_FRAME_RELATED_P (insn) = 1;
- }
- }
+ insn = save_gprs (stack_pointer_rtx, 0,
+ frame.first_save_gpr, frame.last_save_gpr);
+ emit_insn (insn);
/* Dump constant pool and set constant pool register (13). */
@@ -3765,7 +3907,7 @@ s390_emit_prologue ()
/* Set up got pointer, if needed. */
- if (current_function_uses_pic_offset_table)
+ if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
{
rtx got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
SYMBOL_REF_FLAG (got_symbol) = 1;
@@ -3912,7 +4054,7 @@ s390_emit_epilogue ()
if (frame.first_restore_gpr != -1)
{
- rtx addr;
+ rtx insn, addr;
int i;
/* Check for global register and save them
@@ -3943,8 +4085,7 @@ s390_emit_epilogue ()
/* Fetch return address from stack before load multiple,
this will do good for scheduling. */
- if (frame.last_save_gpr >= RETURN_REGNUM
- && frame.first_restore_gpr < RETURN_REGNUM)
+ if (!current_function_is_leaf)
{
int return_regnum = find_unused_clobbered_reg();
if (!return_regnum)
@@ -3964,23 +4105,9 @@ s390_emit_epilogue ()
emit_insn (gen_blockage());
- addr = plus_constant (frame_pointer,
- offset + frame.first_restore_gpr * UNITS_PER_WORD);
- addr = gen_rtx_MEM (Pmode, addr);
- set_mem_alias_set (addr, s390_sr_alias_set);
-
- if (frame.first_restore_gpr != frame.last_save_gpr)
- {
- emit_insn (gen_load_multiple (
- gen_rtx_REG (Pmode, frame.first_restore_gpr),
- addr,
- GEN_INT (frame.last_save_gpr - frame.first_restore_gpr + 1)));
- }
- else
- {
- emit_move_insn (gen_rtx_REG (Pmode, frame.first_restore_gpr),
- addr);
- }
+ insn = restore_gprs (frame_pointer, offset,
+ frame.first_restore_gpr, frame.last_save_gpr);
+ emit_insn (insn);
}
/* Return to caller. */
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index c5ba4270d37..781dc2ea7e4 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -94,10 +94,6 @@ extern int target_flags;
#define TARGET_IBM_FLOAT 0
#define TARGET_IEEE_FLOAT 1
-/* The current function count for create unique internal labels. */
-
-extern int s390_function_count;
-
/* The amount of space used for outgoing arguments. */
extern int current_function_outgoing_args_size;
@@ -1349,4 +1345,11 @@ extern int s390_pool_overflow;
goto WIN; \
}
+/* In rare cases, correct code generation requires extra machine dependent
+ processing between the second jump optimization pass and delayed branch
+ scheduling. On those machines, define this macro as a C statement to act on
+ the code starting at INSN. */
+
+#define MACHINE_DEPENDENT_REORG(INSN) s390_machine_dependent_reorg (INSN)
+
#endif
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index f8ddc2f82aa..e1612dd1312 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -6228,10 +6228,7 @@
compiler doesn't know about it, because the PLT glue
code uses it. In 64-bit, this is not necessary. */
if (plt_call && !TARGET_64BIT)
- {
- current_function_uses_pic_offset_table = 1;
- use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
- }
+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
DONE;
}")
@@ -6353,10 +6350,7 @@
compiler doesn't know about it, because the PLT glue
code uses it. In 64-bit, this is not necessary. */
if (plt_call && !TARGET_64BIT)
- {
- current_function_uses_pic_offset_table = 1;
- use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
- }
+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
DONE;
}")
diff --git a/gcc/config/sh/coff.h b/gcc/config/sh/coff.h
index 4a742af7710..56399ae630b 100644
--- a/gcc/config/sh/coff.h
+++ b/gcc/config/sh/coff.h
@@ -21,7 +21,7 @@ Boston, MA 02111-1307, USA. */
/* Generate SDB debugging information. */
-#define SDB_DEBUGGING_INFO
+#define SDB_DEBUGGING_INFO 1
/* Output DBX (stabs) debugging information if doing -gstabs. */
diff --git a/gcc/config/sh/elf.h b/gcc/config/sh/elf.h
index a2633512ab2..1c3e3c7a4a3 100644
--- a/gcc/config/sh/elf.h
+++ b/gcc/config/sh/elf.h
@@ -20,7 +20,6 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Generate DWARF2 debugging information and make it the default */
-#undef DWARF2_DEBUGGING_INFO
#define DWARF2_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 3512b970d4d..a6ce2be9d17 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -208,6 +208,8 @@ static const char *sh_strip_name_encoding PARAMS ((const char *));
static void sh_init_builtins PARAMS ((void));
static void sh_media_init_builtins PARAMS ((void));
static rtx sh_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
+static int flow_dependent_p PARAMS ((rtx, rtx));
+static void flow_dependent_p_1 PARAMS ((rtx, rtx, void *));
/* Initialize the GCC target structure. */
@@ -4438,7 +4440,7 @@ calc_live_regs (count_ptr, live_regs_mask)
&& pr_live))
&& reg != STACK_POINTER_REGNUM && reg != ARG_POINTER_REGNUM
&& reg != RETURN_ADDRESS_POINTER_REGNUM
- && reg != T_REG && reg != GBR_REG && reg != FPSCR_REG)
+ && reg != T_REG && reg != GBR_REG)
: (/* Only push those regs which are used and need to be saved. */
regs_ever_live[reg] && ! call_used_regs[reg]))
{
@@ -5675,6 +5677,11 @@ sh_handle_interrupt_handler_attribute (node, name, args, flags, no_add_attrs)
IDENTIFIER_POINTER (name));
*no_add_attrs = true;
}
+ else if (TARGET_SHCOMPACT)
+ {
+ error ("attribute interrupt_handler is not compatible with -m5-compact");
+ *no_add_attrs = true;
+ }
return NULL_TREE;
}
@@ -6994,7 +7001,7 @@ sh_adjust_cost (insn, link, dep_insn, cost)
rtx dep_insn;
int cost;
{
- rtx reg;
+ rtx reg, use_pat;
if (TARGET_SHMEDIA)
{
@@ -7007,49 +7014,119 @@ sh_adjust_cost (insn, link, dep_insn, cost)
&& get_attr_is_mac_media (dep_insn))
cost = 1;
}
- else if (GET_CODE(insn) == CALL_INSN)
+ else if (REG_NOTE_KIND (link) == 0)
{
+ enum attr_type dep_type, type;
+
+ if (recog_memoized (insn) < 0
+ || recog_memoized (dep_insn) < 0)
+ return;
+
+ dep_type = get_attr_type (dep_insn);
+ if (dep_type == TYPE_FLOAD || dep_type == TYPE_PCFLOAD)
+ cost--;
+ if ((dep_type == TYPE_LOAD_SI || dep_type == TYPE_PCLOAD_SI)
+ && (type = get_attr_type (insn)) != TYPE_CALL
+ && type != TYPE_SFUNC)
+ cost--;
+
/* The only input for a call that is timing-critical is the
function's address. */
- rtx call = PATTERN (insn);
-
- if (GET_CODE (call) == PARALLEL)
- call = XVECEXP (call, 0 ,0);
- if (GET_CODE (call) == SET)
- call = SET_SRC (call);
- if (GET_CODE (call) == CALL && GET_CODE (XEXP (call, 0)) == MEM
- && ! reg_set_p (XEXP (XEXP (call, 0), 0), dep_insn))
- cost = 0;
- }
- /* All sfunc calls are parallels with at least four components.
- Exploit this to avoid unnecessary calls to sfunc_uses_reg. */
- else if (GET_CODE (PATTERN (insn)) == PARALLEL
- && XVECLEN (PATTERN (insn), 0) >= 4
- && (reg = sfunc_uses_reg (insn)))
- {
+ if (GET_CODE(insn) == CALL_INSN)
+ {
+ rtx call = PATTERN (insn);
+
+ if (GET_CODE (call) == PARALLEL)
+ call = XVECEXP (call, 0 ,0);
+ if (GET_CODE (call) == SET)
+ call = SET_SRC (call);
+ if (GET_CODE (call) == CALL && GET_CODE (XEXP (call, 0)) == MEM
+ && ! reg_set_p (XEXP (XEXP (call, 0), 0), dep_insn))
+ cost = 0;
+ }
/* Likewise, the most timing critical input for an sfuncs call
is the function address. However, sfuncs typically start
using their arguments pretty quickly.
Assume a four cycle delay before they are needed. */
- if (! reg_set_p (reg, dep_insn))
- cost -= TARGET_SUPERSCALAR ? 40 : 4;
- }
- /* Adjust load_si / pcload_si type insns latency. Use the known
- nominal latency and form of the insn to speed up the check. */
- else if (cost == 3
- && GET_CODE (PATTERN (dep_insn)) == SET
- /* Latency for dmpy type insns is also 3, so check the that
- it's actually a move insn. */
- && general_movsrc_operand (SET_SRC (PATTERN (dep_insn)), SImode))
+ /* All sfunc calls are parallels with at least four components.
+ Exploit this to avoid unnecessary calls to sfunc_uses_reg. */
+ else if (GET_CODE (PATTERN (insn)) == PARALLEL
+ && XVECLEN (PATTERN (insn), 0) >= 4
+ && (reg = sfunc_uses_reg (insn)))
+ {
+ if (! reg_set_p (reg, dep_insn))
+ cost -= 4;
+ }
+ /* When the preceding instruction loads the shift amount of
+ the following SHAD/SHLD, the latency of the load is increased
+ by 1 cycle. */
+ else if (TARGET_SH4
+ && get_attr_type (insn) == TYPE_DYN_SHIFT
+ && get_attr_any_int_load (dep_insn) == ANY_INT_LOAD_YES
+ && reg_overlap_mentioned_p (SET_DEST (PATTERN (dep_insn)),
+ XEXP (SET_SRC (single_set(insn)),
+ 1)))
+ cost++;
+ /* When an LS group instruction with a latency of less than
+ 3 cycles is followed by a double-precision floating-point
+ instruction, FIPR, or FTRV, the latency of the first
+ instruction is increased to 3 cycles. */
+ else if (cost < 3
+ && get_attr_insn_class (dep_insn) == INSN_CLASS_LS_GROUP
+ && get_attr_dfp_comp (insn) == DFP_COMP_YES)
+ cost = 3;
+ /* The lsw register of a double-precision computation is ready one
+ cycle earlier. */
+ else if (reload_completed
+ && get_attr_dfp_comp (dep_insn) == DFP_COMP_YES
+ && (use_pat = single_set (insn))
+ && ! regno_use_in (REGNO (SET_DEST (single_set (dep_insn))),
+ SET_SRC (use_pat)))
+ cost -= 1;
+
+ if (get_attr_any_fp_comp (dep_insn) == ANY_FP_COMP_YES
+ && get_attr_late_fp_use (insn) == LATE_FP_USE_YES)
+ cost -= 1;
+ }
+ /* An anti-dependence penalty of two applies if the first insn is a double
+ precision fadd / fsub / fmul. */
+ else if (REG_NOTE_KIND (link) == REG_DEP_ANTI
+ && recog_memoized (dep_insn) >= 0
+ && get_attr_type (dep_insn) == TYPE_DFP_ARITH
+ /* A lot of alleged anti-flow dependences are fake,
+ so check this one is real. */
+ && flow_dependent_p (dep_insn, insn))
cost = 2;
- else if (cost == 30
- && GET_CODE (PATTERN (dep_insn)) == SET
- && GET_MODE (SET_SRC (PATTERN (dep_insn))) == SImode)
- cost = 20;
+
return cost;
}
+/* Check if INSN is flow-dependent on DEP_INSN. Can also be used to check
+ if DEP_INSN is anti-flow dependent on INSN. */
+static int
+flow_dependent_p (insn, dep_insn)
+ rtx insn, dep_insn;
+{
+ rtx tmp = PATTERN (insn);
+
+ note_stores (PATTERN (dep_insn), flow_dependent_p_1, &tmp);
+ return tmp == NULL_RTX;
+}
+
+/* A helper function for flow_dependent_p called through note_stores. */
+static void
+flow_dependent_p_1 (x, pat, data)
+ rtx x;
+ rtx pat ATTRIBUTE_UNUSED;
+ void *data;
+{
+ rtx * pinsn = (rtx *) data;
+
+ if (*pinsn && reg_referenced_p (x, *pinsn))
+ *pinsn = NULL_RTX;
+}
+
/* For use by ALLOCATE_INITIAL_VALUE. Note that sh.md contains some
'special function' patterns (type sfunc) that clobber pr, but that
do not look like function calls to leaf_function_p. Hence we must
@@ -7060,27 +7137,26 @@ sh_pr_n_sets ()
return REG_N_SETS (TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG);
}
-/* This Function Returns non zero if DFA based scheduler
- interface is to be used.At present supported only for
- SH4. */
+/* This Function returns non zero if the DFA based scheduler interface
+ is to be used. At present this is supported for the SH4 only. */
static int
sh_use_dfa_interface()
{
- if (TARGET_SH4)
- return 1;
- else
- return 0;
+ if (TARGET_HARD_SH4)
+ return 1;
+ else
+ return 0;
}
-/* This function returns "2" that signifies dual issue
- for SH4 processor.To be used by DFA pipeline description. */
+/* This function returns "2" to indicate dual issue for the SH4
+ processor. To be used by the DFA pipeline description. */
static int
sh_issue_rate()
{
- if(TARGET_SH4)
- return 2;
- else
- return 1;
+ if (TARGET_SUPERSCALAR)
+ return 2;
+ else
+ return 1;
}
/* SHmedia requires registers for branches, so we can't generate new
@@ -7225,7 +7301,7 @@ sh_initialize_trampoline (tramp, fnaddr, cxt)
src = gen_rtx_MEM (BLKmode, tramp_templ);
set_mem_align (dst, 256);
set_mem_align (src, 64);
- emit_block_move (dst, src, GEN_INT (fixed_len));
+ emit_block_move (dst, src, GEN_INT (fixed_len), BLOCK_OP_NORMAL);
emit_move_insn (gen_rtx_MEM (Pmode, plus_constant (tramp, fixed_len)),
fnaddr);
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 1ad1306abdc..6f010864fc7 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -472,6 +472,14 @@ do { \
break global alloc, and generates slower code anyway due \
to the pressure on R0. */ \
flag_schedule_insns = 0; \
+ \
+ /* Allocation boundary (in *bits*) for the code of a function. \
+ SH1: 32 bit alignment is faster, because instructions are always \
+ fetched as a pair from a longword boundary. \
+ SH2 .. SH5 : align to cache line start. */ \
+ if (align_functions == 0) \
+ align_functions \
+ = TARGET_SMALLCODE ? FUNCTION_BOUNDARY : (1 << CACHE_LOG) * 8; \
} while (0)
/* Target machine storage layout. */
@@ -532,11 +540,9 @@ do { \
The SH2/3 have 16 byte cache lines, and the SH4 has a 32 byte cache line */
#define CACHE_LOG (TARGET_CACHE32 ? 5 : TARGET_SH2 ? 4 : 2)
-/* Allocation boundary (in *bits*) for the code of a function.
- 32 bit alignment is faster, because instructions are always fetched as a
- pair from a longword boundary. */
-#define FUNCTION_BOUNDARY \
- (TARGET_SMALLCODE ? 16 << TARGET_SHMEDIA : (1 << CACHE_LOG) * 8)
+/* ABI given & required minimum allocation boundary (in *bits*) for the
+ code of a function. */
+#define FUNCTION_BOUNDARY (16 << TARGET_SHMEDIA)
/* On SH5, the lowest bit is used to indicate SHmedia functions, so
the vbit must go into the delta field of
@@ -2018,7 +2024,7 @@ struct sh_args {
: 0)
#define SH5_WOULD_BE_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
- (TARGET_SH5 && (MODE) == BLKmode \
+ (TARGET_SH5 && ((MODE) == BLKmode || (MODE) == TImode) \
&& ((CUM).arg_count[(int) SH_ARG_INT] \
+ (int_size_in_bytes (TYPE) + 7) / 8) > NPARM_REGS (SImode))
@@ -3271,6 +3277,8 @@ extern int rtx_equal_function_value_matters;
#define PROMOTE_FUNCTION_ARGS
#define PROMOTE_FUNCTION_RETURN
+#define MAX_FIXED_MODE_SIZE (TARGET_SH5 ? 128 : 64)
+
/* ??? Define ACCUMULATE_OUTGOING_ARGS? This is more efficient than pushing
and poping arguments. However, we do have push/pop instructions, and
rather limited offsets (4 bits) in load/store instructions, so it isn't
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 7016e74ec48..88b2dc89a9e 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -183,8 +183,10 @@
;; arith3b like above, but might end with a redirected branch
;; load from memory
;; load_si Likewise, SImode variant for general register.
+;; fload Likewise, but load to fp register.
;; store to memory
-;; move register to register
+;; move general purpose register to register
+;; mt_group other sh4 mt instructions
;; fmove register to register, floating point
;; smpy word precision integer multiply
;; dmpy longword or doublelongword precision integer multiply
@@ -194,15 +196,20 @@
;; pstore store of pr reg, which can't be put into delay slot of jsr
;; prget copy pr to register, ditto
;; pcload pc relative load of constant value
+;; pcfload Likewise, but load to fp register.
;; pcload_si Likewise, SImode variant for general register.
;; rte return from exception
;; sfunc special function call with known used registers
;; call function call
;; fp floating point
;; fdiv floating point divide (or square root)
-;; gp_fpul move between general purpose register and fpul
+;; gp_fpul move from general purpose register to fpul
+;; fpul_gp move from fpul to general purpose register
+;; mac_gp move from mac[lh] to general purpose register
;; dfp_arith, dfp_cmp,dfp_conv
+;; ftrc_s fix_truncsfsi2_i4
;; dfdiv double precision floating point divide (or square root)
+;; cwb ic_invalidate_line_i
;; arith_media SHmedia arithmetic, logical, and shift instructions
;; cbranch_media SHmedia conditional branch instructions
;; cmp_media SHmedia compare instructions
@@ -233,30 +240,32 @@
;; nil no-op move, will be deleted.
(define_attr "type"
- "cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,rte,sfunc,call,fp,fdiv,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
+ "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,mem_fpscr,gp_fpscr,cwb,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
(const_string "other"))
;; We define a new attribute namely "insn_class".We use
-;; this for DFA based pipeline description.
-;; Although the "type" attribute covers almost all insn
-;; classes,it is more convenient to define new attribute
-;; for certain reservations.
+;; this for the DFA based pipeline description.
;;
;; mt_group SH4 "mt" group instructions.
;;
-;; ex_group SH4 "ex" group instructions.They mostly
-;; overlap with arithmetic instructions but
-;; new attribute defined to distinguish from
-;; mt group instructions.
+;; ex_group SH4 "ex" group instructions.
+;;
+;; ls_group SH4 "ls" group instructions.
;;
-;; lds_to_fpscr The "type" attribute couldn't sufficiently
-;; distinguish it from others.It is part of
-;; new attribute.Similar case with ldsmem_to_fpscr
-;; and cwb.
(define_attr "insn_class"
- "mt_group,ex_group,lds_to_fpscr,ldsmem_to_fpscr,cwb,none"
- (const_string "none"))
+ "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
+ (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
+ (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
+ (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
+ (eq_attr "type" "cbranch,jump") (const_string "br_group")
+ (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
+ (const_string "fe_group")
+ (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb") (const_string "co_group")]
+ (const_string "none")))
+;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
+;; so these do not belong in an insn group, although they are modeled
+;; with their own define_insn_reservations.
;; Indicate what precision must be selected in fpscr for this insn, if any.
@@ -445,178 +454,6 @@
(and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fdiv")) 13 12)
-;; SH4 scheduling
-;; The SH4 is a dual-issue implementation, thus we have to multiply all
-;; costs by at least two.
-;; There will be single increments of the modeled that don't correspond
-;; to the actual target ;; whenever two insns to be issued depend one a
-;; single resource, and the scheduler picks to be the first one.
-;; If we multiplied the costs just by two, just two of these single
-;; increments would amount to an actual cycle. By picking a larger
-;; factor, we can ameliorate the effect; However, we then have to make sure
-;; that only two insns are modeled as issued per actual cycle.
-;; Moreover, we need a way to specify the latency of insns that don't
-;; use an actual function unit.
-;; We use an 'issue' function unit to do that, and a cost factor of 10.
-
-(define_function_unit "issue" 2 0
- (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "!nil,arith3"))
- 10 10)
-
-(define_function_unit "issue" 2 0
- (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "arith3"))
- 30 30)
-
-;; There is no point in providing exact scheduling information about branches,
-;; because they are at the starts / ends of basic blocks anyways.
-
-;; Some insns cannot be issued before/after another insn in the same cycle,
-;; irrespective of the type of the other insn.
-
-;; default is dual-issue, but can't be paired with an insn that
-;; uses multiple function units.
-(define_function_unit "single_issue" 1 0
- (and (eq_attr "pipe_model" "sh4")
- (eq_attr "type" "!smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul,call,sfunc,arith3,arith3b"))
- 1 10
- [(eq_attr "type" "smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul")])
-
-(define_function_unit "single_issue" 1 0
- (and (eq_attr "pipe_model" "sh4")
- (eq_attr "type" "smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul"))
- 10 10
- [(const_int 1)])
-
-;; arith3 insns are always pairable at the start, but not inecessarily at
-;; the end; however, there doesn't seem to be a way to express that.
-(define_function_unit "single_issue" 1 0
- (and (eq_attr "pipe_model" "sh4")
- (eq_attr "type" "arith3"))
- 30 20
- [(const_int 1)])
-
-;; arith3b insn are pairable at the end and have latency that prevents pairing
-;; with the following branch, but we don't want this latency be respected;
-;; When the following branch is immediately adjacent, we can redirect the
-;; internal branch, which is likly to be a larger win.
-(define_function_unit "single_issue" 1 0
- (and (eq_attr "pipe_model" "sh4")
- (eq_attr "type" "arith3b"))
- 20 20
- [(const_int 1)])
-
-;; calls introduce a longisch delay that is likely to flush the pipelines.
-(define_function_unit "single_issue" 1 0
- (and (eq_attr "pipe_model" "sh4")
- (eq_attr "type" "call,sfunc"))
- 160 160
- [(eq_attr "type" "!call") (eq_attr "type" "call")])
-
-;; Load and store instructions have no alignment peculiarities for the SH4,
-;; but they use the load-store unit, which they share with the fmove type
-;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
-;; Loads have a latency of two.
-;; However, call insns can only paired with a preceding insn, and have
-;; a delay slot, so that we want two more insns to be scheduled between the
-;; load of the function address and the call. This is equivalent to a
-;; latency of three.
-;; We cannot use a conflict list for this, because we need to distinguish
-;; between the actual call address and the function arguments.
-;; ADJUST_COST can only properly handle reductions of the cost, so we
-;; use a latency of three here, which gets multiplied by 10 to yield 30.
-;; We only do this for SImode loads of general registers, to make the work
-;; for ADJUST_COST easier.
-
-;; When specifying different latencies for different insns using the
-;; the same function unit, genattrtab.c assumes a 'FIFO constraint'
-;; so that the blockage is at least READY-COST (E) + 1 - READY-COST (C)
-;; for an executing insn E and a candidate insn C.
-;; Therefore, we define three different function units for load_store:
-;; load_store, load and load_si.
-
-(define_function_unit "load_si" 1 0
- (and (eq_attr "pipe_model" "sh4")
- (eq_attr "type" "load_si,pcload_si")) 30 10)
-(define_function_unit "load" 1 0
- (and (eq_attr "pipe_model" "sh4")
- (eq_attr "type" "load,pcload,pload")) 20 10)
-(define_function_unit "load_store" 1 0
- (and (eq_attr "pipe_model" "sh4")
- (eq_attr "type" "load_si,pcload_si,load,pcload,pload,store,pstore,fmove"))
- 10 10)
-
-(define_function_unit "int" 1 0
- (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "arith,dyn_shift")) 10 10)
-
-;; Again, we have to pretend a lower latency for the "int" unit to avoid a
-;; spurious FIFO constraint; the multiply instructions use the "int"
-;; unit actually only for two cycles.
-(define_function_unit "int" 1 0
- (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "smpy,dmpy")) 20 20)
-
-;; We use a fictous "mpy" unit to express the actual latency.
-(define_function_unit "mpy" 1 0
- (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "smpy,dmpy")) 40 20)
-
-;; Again, we have to pretend a lower latency for the "int" unit to avoid a
-;; spurious FIFO constraint.
-(define_function_unit "int" 1 0
- (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "gp_fpul")) 10 10)
-
-;; We use a fictous "gp_fpul" unit to express the actual latency.
-(define_function_unit "gp_fpul" 1 0
- (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "gp_fpul")) 20 10)
-
-;; ??? multiply uses the floating point unit, but with a two cycle delay.
-;; Thus, a simple single-precision fp operation could finish if issued in
-;; the very next cycle, but stalls when issued two or three cycles later.
-;; Similarily, a divide / sqrt can work without stalls if issued in
-;; the very next cycle, while it would have to block if issued two or
-;; three cycles later.
-;; There is no way to model this with gcc's function units. This problem is
-;; actually mentioned in md.texi. Tackling this problem requires first that
-;; it is possible to speak about the target in an open discussion.
-;;
-;; However, simple double-precision operations always conflict.
-
-(define_function_unit "fp" 1 0
- (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "smpy,dmpy")) 40 40
- [(eq_attr "type" "dfp_cmp,dfp_conv,dfp_arith")])
-
-;; The "fp" unit is for pipeline stages F1 and F2.
-
-(define_function_unit "fp" 1 0
- (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "fp")) 30 10)
-
-;; Again, we have to pretend a lower latency for the "fp" unit to avoid a
-;; spurious FIFO constraint; the bulk of the fdiv type insns executes in
-;; the F3 stage.
-(define_function_unit "fp" 1 0
- (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "fdiv")) 30 10)
-
-;; The "fdiv" function unit models the aggregate effect of the F1, F2 and F3
-;; pipeline stages on the pipelining of fdiv/fsqrt insns.
-;; We also use it to give the actual latency here.
-;; fsqrt is actually one cycle faster than fdiv (and the value used here),
-;; but that will hardly matter in practice for scheduling.
-(define_function_unit "fdiv" 1 0
- (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "fdiv")) 120 100)
-
-;; There is again a late use of the "fp" unit by [d]fdiv type insns
-;; that we can't express.
-
-(define_function_unit "fp" 1 0
- (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "dfp_cmp,dfp_conv")) 40 20)
-
-(define_function_unit "fp" 1 0
- (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "dfp_arith")) 80 60)
-
-(define_function_unit "fp" 1 0
- (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "dfdiv")) 230 10)
-
-(define_function_unit "fdiv" 1 0
- (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "dfdiv")) 230 210)
-
;; SH-5 SHmedia scheduling
;; When executing SHmedia code, the SH-5 is a fairly straightforward
;; single-issue machine. It has four pipelines, the branch unit (br),
@@ -706,6 +543,35 @@
(define_attr "is_mac_media" ""
(if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
+(define_attr "branch_zero" "yes,no"
+ (cond [(eq_attr "type" "!cbranch") (const_string "no")
+ (ne (symbol_ref "(next_active_insn (insn)\
+ == (prev_active_insn\
+ (XEXP (SET_SRC (PATTERN (insn)), 1))))\
+ && get_attr_length (next_active_insn (insn)) == 2")
+ (const_int 0))
+ (const_string "yes")]
+ (const_string "no")))
+
+;; SH4 Double-precision computation with double-precision result -
+;; the two halves are ready at different times.
+(define_attr "dfp_comp" "yes,no"
+ (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
+ (const_string "no")))
+
+;; Insns for which the latency of a preceding fp insn is decreased by one.
+(define_attr "late_fp_use" "yes,no" (const_string "no"))
+;; And feeding insns for which this relevant.
+(define_attr "any_fp_comp" "yes,no"
+ (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
+ (const_string "yes")]
+ (const_string "no")))
+
+(define_attr "any_int_load" "yes,no"
+ (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
+ (const_string "yes")]
+ (const_string "no")))
+
(define_delay
(eq_attr "needs_delay_slot" "yes")
[(eq_attr "in_delay_slot" "yes") (nil) (nil)])
@@ -755,7 +621,7 @@
(const_int 0)))]
"TARGET_SH1"
"tst %1,%0"
- [(set_attr "insn_class" "mt_group")])
+ [(set_attr "type" "mt_group")])
;; ??? Perhaps should only accept reg/constant if the register is reg 0.
;; That would still allow reload to create cmpi instructions, but would
@@ -772,7 +638,7 @@
tst %0,%0
cmp/eq %1,%0
cmp/eq %1,%0"
- [(set_attr "insn_class" "mt_group,mt_group,mt_group")])
+ [(set_attr "type" "mt_group")])
(define_insn "cmpgtsi_t"
[(set (reg:SI T_REG)
@@ -782,7 +648,7 @@
"@
cmp/gt %1,%0
cmp/pl %0"
- [(set_attr "insn_class" "mt_group,mt_group")])
+ [(set_attr "type" "mt_group")])
(define_insn "cmpgesi_t"
[(set (reg:SI T_REG)
@@ -792,7 +658,7 @@
"@
cmp/ge %1,%0
cmp/pz %0"
- [(set_attr "insn_class" "mt_group,mt_group")])
+ [(set_attr "type" "mt_group")])
;; -------------------------------------------------------------------------
;; SImode unsigned integer comparisons
@@ -804,7 +670,7 @@
(match_operand:SI 1 "arith_reg_operand" "r")))]
"TARGET_SH1"
"cmp/hs %1,%0"
- [(set_attr "insn_class" "mt_group")])
+ [(set_attr "type" "mt_group")])
(define_insn "cmpgtusi_t"
[(set (reg:SI T_REG)
@@ -812,7 +678,7 @@
(match_operand:SI 1 "arith_reg_operand" "r")))]
"TARGET_SH1"
"cmp/hi %1,%0"
- [(set_attr "insn_class" "mt_group")])
+ [(set_attr "type" "mt_group")])
;; We save the compare operands in the cmpxx patterns and use them when
;; we generate the branch.
@@ -909,7 +775,7 @@
cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
cmp/pz\\t%S0"
[(set_attr "length" "8,2")
- (set_attr "type" "arith3,arith")])
+ (set_attr "type" "arith3,mt_group")])
;; -------------------------------------------------------------------------
;; DImode unsigned integer comparisons
@@ -1176,8 +1042,7 @@
(ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
"TARGET_SH1"
"addc %2,%0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
(define_insn "addc1"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
@@ -1187,8 +1052,7 @@
(clobber (reg:SI T_REG))]
"TARGET_SH1"
"addc %2,%0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
(define_expand "addsi3"
[(set (match_operand:SI 0 "arith_reg_operand" "")
@@ -1217,8 +1081,7 @@
(match_operand:SI 2 "arith_operand" "rI")))]
"TARGET_SH1"
"add %2,%0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
;; -------------------------------------------------------------------------
;; Subtraction instructions
@@ -1287,8 +1150,7 @@
(gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
"TARGET_SH1"
"subc %2,%0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
(define_insn "subc1"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
@@ -1298,8 +1160,7 @@
(clobber (reg:SI T_REG))]
"TARGET_SH1"
"subc %2,%0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
(define_insn "*subsi3_internal"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
@@ -1307,8 +1168,7 @@
(match_operand:SI 2 "arith_reg_operand" "r")))]
"TARGET_SH1"
"sub %2,%0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
(define_insn "*subsi3_media"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
@@ -1734,6 +1594,14 @@
invariant code motion can move it. */
REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
+ /* expand_binop can't find a suitable code in umul_widen_optab to
+ make a REG_EQUAL note from, so make one here.
+ See also smulsi3_highpart.
+ ??? Alternatively, we could put this at the calling site of expand_binop,
+ i.e. expand_expr. */
+ REG_NOTES (last)
+ = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
+ REG_NOTES (last));
DONE;
}")
@@ -1756,6 +1624,14 @@
invariant code motion can move it. */
REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
+ /* expand_binop can't find a suitable code in umul_widen_optab to
+ make a REG_EQUAL note from, so make one here.
+ See also smulsi3_highpart.
+ ??? Alternatively, we could put this at the calling site of expand_binop,
+ i.e. expand_expr. */
+ REG_NOTES (last)
+ = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
+ REG_NOTES (last));
DONE;
}")
@@ -2019,6 +1895,7 @@
REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
/* expand_binop can't find a suitable code in mul_highpart_optab to
make a REG_EQUAL note from, so make one here.
+ See also {,u}mulhisi.
??? Alternatively, we could put this at the calling site of expand_binop,
i.e. expand_mult_highpart. */
REG_NOTES (last)
@@ -2076,8 +1953,7 @@
(match_operand:SI 2 "logical_operand" "r,L")))]
"TARGET_SH1"
"and %2,%0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
;; If the constant is 255, then emit a extu.b instruction instead of an
;; and, since that will give better code.
@@ -2133,8 +2009,7 @@
(match_operand:SI 2 "logical_operand" "r,L")))]
"TARGET_SH1"
"or %2,%0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
(define_insn "iordi3"
[(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
@@ -2152,8 +2027,7 @@
(match_operand:SI 2 "logical_operand" "L,r")))]
"TARGET_SH1"
"xor %2,%0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
(define_insn "xordi3"
[(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
@@ -2220,8 +2094,7 @@
(lshiftrt:SI (match_dup 1) (const_int 31)))]
"TARGET_SH1"
"rotl %0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
(define_insn "rotlsi3_31"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
@@ -2230,8 +2103,7 @@
(clobber (reg:SI T_REG))]
"TARGET_SH1"
"rotr %0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
(define_insn "rotlsi3_16"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
@@ -2239,8 +2111,7 @@
(const_int 16)))]
"TARGET_SH1"
"swap.w %1,%0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
(define_expand "rotlsi3"
[(set (match_operand:SI 0 "arith_reg_operand" "")
@@ -2304,8 +2175,7 @@
(const_int 8)))]
"TARGET_SH1"
"swap.b %1,%0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
(define_expand "rotlhi3"
[(set (match_operand:HI 0 "arith_reg_operand" "")
@@ -2347,8 +2217,7 @@
(clobber (match_dup 4))])]
"operands[4] = gen_rtx_SCRATCH (SImode);"
[(set_attr "length" "*,*,*,4")
- (set_attr "type" "dyn_shift,arith,arith,arith")
- (set_attr "insn_class" "ex_group,ex_group,ex_group,ex_group")])
+ (set_attr "type" "dyn_shift,arith,arith,arith")])
(define_insn "ashlhi3_k"
[(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
@@ -2358,8 +2227,7 @@
"@
add %0,%0
shll%O2 %0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
(define_insn "ashlsi3_n"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
@@ -2376,8 +2244,7 @@
(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
(const_string "6")]
(const_string "8")))
- (set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ (set_attr "type" "arith")])
(define_split
[(set (match_operand:SI 0 "arith_reg_operand" "")
@@ -2466,8 +2333,7 @@
(clobber (reg:SI T_REG))]
"TARGET_SH1 && INTVAL (operands[2]) == 1"
"shar %0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
;; We can't do HImode right shifts correctly unless we start out with an
;; explicit zero / sign extension; doing that would result in worse overall
@@ -2526,8 +2392,7 @@
(lt:SI (match_dup 1) (const_int 0)))]
"TARGET_SH1"
"shll %0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
(define_insn "ashrsi3_d"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
@@ -2535,8 +2400,7 @@
(neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
"TARGET_SH3"
"shad %2,%0"
- [(set_attr "type" "dyn_shift")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "dyn_shift")])
(define_insn "ashrsi3_n"
[(set (reg:SI R4_REG)
@@ -2587,8 +2451,7 @@
(neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
"TARGET_SH3"
"shld %2,%0"
- [(set_attr "type" "dyn_shift")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "dyn_shift")])
;; Only the single bit shift clobbers the T bit.
@@ -2599,8 +2462,7 @@
(clobber (reg:SI T_REG))]
"TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
"shlr %0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
(define_insn "lshrsi3_k"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
@@ -2609,8 +2471,7 @@
"TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))
&& ! CONST_OK_FOR_M (INTVAL (operands[2]))"
"shlr%O2 %0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
(define_insn "lshrsi3_n"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
@@ -2689,8 +2550,7 @@
"TARGET_SH1"
"shll %R0\;rotcl %S0"
[(set_attr "length" "4")
- (set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ (set_attr "type" "arith")])
(define_insn "ashldi3_media"
[(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
@@ -2730,8 +2590,7 @@
"TARGET_SH1"
"shlr %S0\;rotcr %R0"
[(set_attr "length" "4")
- (set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ (set_attr "type" "arith")])
(define_insn "lshrdi3_media"
[(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
@@ -2771,8 +2630,7 @@
"TARGET_SH1"
"shar %S0\;rotcr %R0"
[(set_attr "length" "4")
- (set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ (set_attr "type" "arith")])
(define_insn "ashrdi3_media"
[(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
@@ -3007,8 +2865,7 @@
(const_int 16))))]
"TARGET_SH1"
"xtrct %1,%0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
(define_insn "xtrct_right"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
@@ -3018,8 +2875,7 @@
(const_int 16))))]
"TARGET_SH1"
"xtrct %2,%0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
;; -------------------------------------------------------------------------
;; Unary arithmetic
@@ -3034,8 +2890,7 @@
(const_int 0)))]
"TARGET_SH1"
"negc %1,%0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
(define_insn "*negdi_media"
[(set (match_operand:DI 0 "arith_reg_operand" "=r")
@@ -3073,16 +2928,14 @@
(neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
"TARGET_SH1"
"neg %1,%0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
(define_insn "one_cmplsi2"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
(not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
"TARGET_SH1"
"not %1,%0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
(define_expand "one_cmpldi2"
[(set (match_operand:DI 0 "arith_reg_operand" "")
@@ -3157,8 +3010,7 @@
(zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
"TARGET_SH1"
"extu.w %1,%0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
(define_insn "*zero_extendhisi2_media"
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -3196,8 +3048,7 @@
(zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
"TARGET_SH1"
"extu.b %1,%0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
(define_insn "*zero_extendqisi2_media"
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -3213,8 +3064,7 @@
(zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
"TARGET_SH1"
"extu.b %1,%0"
- [(set_attr "type" "arith")
- (set_attr "insn_class" "ex_group")])
+ [(set_attr "type" "arith")])
;; -------------------------------------------------------------------------
;; Sign extension instructions
@@ -3288,8 +3138,7 @@
"@
exts.w %1,%0
mov.w %1,%0"
- [(set_attr "type" "arith,load")
- (set_attr "insn_class" "ex_group,*")])
+ [(set_attr "type" "arith,load")])
(define_insn "*extendhisi2_media"
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -3325,8 +3174,7 @@
"@
exts.b %1,%0
mov.b %1,%0"
- [(set_attr "type" "arith,load")
- (set_attr "insn_class" "ex_group,*")])
+ [(set_attr "type" "arith,load")])
(define_insn "*extendqisi2_media"
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -3356,8 +3204,7 @@
"@
exts.b %1,%0
mov.b %1,%0"
- [(set_attr "type" "arith,load")
- (set_attr "insn_class" "ex_group,*")])
+ [(set_attr "type" "arith,load")])
/* It would seem useful to combine the truncXi patterns into the movXi
patterns, but unary operators are ignored when matching constraints,
@@ -3431,6 +3278,7 @@
"TARGET_SH3E && ! TARGET_SH5"
"sts.l fpul,@-r15"
[(set_attr "type" "store")
+ (set_attr "late_fp_use" "yes")
(set_attr "hit_stack" "yes")])
;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
@@ -3506,8 +3354,7 @@
lds.l %1,%0
lds.l %1,%0
fake %1,%0"
- [(set_attr "type" "pcload_si,move,*,load_si,move,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
- (set_attr "insn_class" "*,*,mt_group,*,*,*,*,*,*,*,*,*,*,*,*")
+ [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
(set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
;; t/r must come after r/r, lest reload will try to reload stuff like
@@ -3541,7 +3388,8 @@
lds %1,%0
sts %1,%0
! move optimized away"
- [(set_attr "type" "pcload_si,move,*,load_si,move,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,gp_fpul,nil")
+ [(set_attr "type" "pcload_si,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,nil")
+ (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*")
(set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
(define_insn "movsi_i_lowpart"
@@ -3666,7 +3514,7 @@
"TARGET_HARD_SH4"
"ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
[(set_attr "length" "8")
- (set_attr "insn_class" "cwb")])
+ (set_attr "type" "cwb")])
;; ??? could make arg 0 an offsettable memory operand to allow to save
;; an add in the code that calculates the address.
@@ -4313,7 +4161,8 @@
(if_then_else
(ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
(const_int 10) (const_int 8))])
- (set_attr "type" "fmove,move,pcload,load,store,pcload,load,store,load,load")
+ (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
+ (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
(set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
(const_string "double")
(const_string "none")))])
@@ -5015,7 +4864,8 @@
sts.l %1,%0
lds.l %1,%0
! move optimized away"
- [(set_attr "type" "fmove,move,fmove,fmove,pcload,load,store,pcload,load,store,fmove,fmove,load,*,gp_fpul,gp_fpul,store,load,nil")
+ [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
+ (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
(set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
(set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
(const_string "single")
@@ -7996,8 +7846,8 @@
;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
;; predicate after reload.
-;; The gp_fpul type for r/!c might look a bit odd, but it actually schedules
-;; like a gpr <-> fpul move.
+;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
+;; like a mac -> gpr move.
(define_insn "fpu_switch"
[(set (match_operand:PSI 0 "register_operand" "=c,c,r,c,c,r,m,r")
(match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c"))]
@@ -8016,8 +7866,7 @@
mov.l %1,%0
sts fpscr,%0"
[(set_attr "length" "0,2,2,4,2,2,2,2")
- (set_attr "type" "dfp_conv,dfp_conv,load,dfp_conv,dfp_conv,move,store,gp_fpul")
- (set_attr "insn_class" "ldsmem_to_fpscr,*,*,lds_to_fpscr,*,*,*,*")])
+ (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp")])
(define_split
[(set (reg:PSI FPSCR_REG)
@@ -8363,7 +8212,7 @@
(use (match_operand:PSI 2 "fpscr_operand" "c"))]
"TARGET_SH4"
"ftrc %1,%0"
- [(set_attr "type" "fp")
+ [(set_attr "type" "ftrc_s")
(set_attr "fp_mode" "single")])
;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
@@ -8785,6 +8634,7 @@
"TARGET_SH4"
"ftrc %1,%0"
[(set_attr "type" "dfp_conv")
+ (set_attr "dfp_comp" "no")
(set_attr "fp_mode" "double")])
;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
@@ -9877,6 +9727,7 @@
{
emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
(operands[0], operands[1], operands[2]));
+ DONE;
}")
; This use of vec_select isn't exactly correct according to rtl.texi
@@ -10591,18 +10442,22 @@
(define_cpu_unit "f1_1,f1_2" "fpu_pipe")
-;; The floating point units.
+;; The floating point units (except FS - F2 always precedes it.)
-(define_cpu_unit "F1,F2,F3,FS" "fpu_pipe")
+(define_cpu_unit "F0,F1,F2,F3" "fpu_pipe")
;; This is basically the MA unit of SH4
;; used in LOAD/STORE pipeline.
(define_cpu_unit "memory" "inst_pipeline")
+;; However, there are LS group insns that don't use it, even ones that
+;; complete in 0 cycles. So we use an extra unit for the issue of LS insns.
+(define_cpu_unit "load_store" "inst_pipeline")
+
;; The address calculator used for branch instructions.
-;; This will be reserved with "issue" of branch instructions
-;; and this is to make sure that no two branch instructions
+;; This will be reserved after "issue" of branch instructions
+;; and this is to make sure that no two branch instructions
;; can be issued in parallel.
(define_cpu_unit "pcr_addrcalc" "inst_pipeline")
@@ -10613,26 +10468,57 @@
(define_reservation "issue" "pipe_01|pipe_02")
;; This is to express the locking of D stage.
+;; Note that the issue of a CO group insn also effectively locks the D stage.
(define_reservation "d_lock" "pipe_01+pipe_02")
+;; Every FE instruction but fipr / ftrv starts with issue and this.
+(define_reservation "F01" "F0+F1")
+
;; This is to simplify description where F1,F2,FS
;; are used simultaneously.
-(define_reservation "fpu" "F1+F2+FS")
+(define_reservation "fpu" "F1+F2")
;; This is to highlight the fact that f1
;; cannot overlap with F1.
(exclusion_set "f1_1,f1_2" "F1")
+(define_insn_reservation "nil" 0 (eq_attr "type" "nil") "nothing")
+
;; Although reg moves have a latency of zero
;; we need to highlight that they use D stage
;; for one cycle.
+;; Group: MT
+
(define_insn_reservation "reg_mov" 0
- (eq_attr "type" "move,fmove")
- "issue")
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "move"))
+ "issue")
+
+;; Group: LS
+
+(define_insn_reservation "freg_mov" 0
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "fmove"))
+ "issue+load_store")
+
+;; We don't model all pipeline stages; we model the issue ('D') stage
+;; inasmuch as we allow only two instructions to issue simultanously,
+;; and CO instructions prevent any simultanous issue of another instruction.
+;; (This uses pipe_01 and pipe_02).
+;; Double issue of EX insns is prevented by using the int unit in the EX stage.
+;; Double issue of EX / BR insns is prevented by using the int unit /
+;; pcr_addrcalc unit in the EX stage.
+;; Double issue of BR / LS instructions is prevented by using the
+;; pcr_addrcalc / load_store unit in the issue cycle.
+;; Double issue of FE instructions is prevented by using F0 in the first
+;; pipeline stage after the first D stage.
+;; There is no need to describe the [ES]X / [MN]A / S stages after a D stage
+;; (except in the cases outlined above), nor to describe the FS stage after
+;; the F2 stage.
;; Other MT group intructions(1 step operations)
;; Group: MT
@@ -10640,88 +10526,170 @@
;; Issue Rate: 1
(define_insn_reservation "mt" 1
- (eq_attr "insn_class" "mt_group")
- "issue,nothing")
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "mt_group"))
+ "issue")
;; Fixed Point Arithmetic Instructions(1 step operations)
;; Group: EX
;; Latency: 1
;; Issue Rate: 1
-(define_insn_reservation "simple_arith" 1
- (eq_attr "insn_class" "ex_group")
- "issue,int")
+(define_insn_reservation "sh4_simple_arith" 1
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "insn_class" "ex_group"))
+ "issue,int")
+
+;; Load and store instructions have no alignment peculiarities for the SH4,
+;; but they use the load-store unit, which they share with the fmove type
+;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
+;; Loads have a latency of two.
+;; However, call insns can only paired with a preceding insn, and have
+;; a delay slot, so that we want two more insns to be scheduled between the
+;; load of the function address and the call. This is equivalent to a
+;; latency of three.
+;; ADJUST_COST can only properly handle reductions of the cost, so we
+;; use a latency of three here, which gets multiplied by 10 to yield 30.
+;; We only do this for SImode loads of general registers, to make the work
+;; for ADJUST_COST easier.
;; Load Store instructions. (MOV.[BWL]@(d,GBR)
;; Group: LS
;; Latency: 2
;; Issue Rate: 1
-(define_insn_reservation "load_store" 2
- (eq_attr "type" "load,load_si,pcload,pcload_si,store")
- "issue,memory*2")
+(define_insn_reservation "sh4_load" 2
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "load,pcload"))
+ "issue+load_store,nothing,memory")
+
+;; calls / sfuncs need an extra instruction for their delay slot.
+;; Moreover, estimating the latency for SImode loads as 3 will also allow
+;; adjust_cost to meaningfully bump it back up to 3 if they load the shift
+;; count of a dynamic shift.
+(define_insn_reservation "sh4_load_si" 3
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "load_si,pcload_si"))
+ "issue+load_store,nothing,memory")
+
+;; (define_bypass 2 "sh4_load_si" "!sh4_call")
+
+;; The load latency is upped to three higher if the dependent insn does
+;; double precision computation. We want the 'default' latency to reflect
+;; that increased latency because otherwise the insn priorities won't
+;; allow proper scheduling.
+(define_insn_reservation "sh4_fload" 3
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "fload,pcfload"))
+ "issue+load_store,nothing,memory")
+
+;; (define_bypass 2 "sh4_fload" "!")
+
+(define_insn_reservation "sh4_store" 1
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "store"))
+ "issue+load_store,nothing,memory")
+
+;; Load Store instructions.
+;; Group: LS
+;; Latency: 1
+;; Issue Rate: 1
+
+(define_insn_reservation "sh4_gp_fpul" 1
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "gp_fpul"))
+ "issue+load_store")
+
+;; Load Store instructions.
+;; Group: LS
+;; Latency: 3
+;; Issue Rate: 1
+
+(define_insn_reservation "sh4_fpul_gp" 3
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "fpul_gp"))
+ "issue+load_store")
;; Branch (BF,BF/S,BT,BT/S,BRA)
;; Group: BR
-;; Latency: 2 (or 1) Actually Observed to be 5/7
+;; Latency when taken: 2 (or 1)
;; Issue Rate: 1
;; The latency is 1 when displacement is 0.
-;; This reservation can be further broken into 2
-;; 1. branch_zero : One with latency 1 and in the TEST
-;; part it also checks for 0 (ZERO) displacement
-;; 2. branch: Latency 2.
-
-(define_insn_reservation "branch_zero" 5
- (and (eq_attr "type" "cbranch")
- (eq_attr "length" "2"))
- "(issue+pcr_addrcalc),pcr_addrcalc,nothing")
+;; We can't really do much with the latency, even if we could express it,
+;; but the pairing restrictions are useful to take into account.
+;; ??? If the branch is likely, we might want to fill the delay slot;
+;; if the branch is likely, but not very likely, should we pretend to use
+;; a resource that CO instructions use, to get a pairable delay slot insn?
-(define_insn_reservation "branch" 7
- (eq_attr "type" "cbranch")
- "(issue+pcr_addrcalc),pcr_addrcalc,nothing")
+(define_insn_reservation "sh4_branch" 1
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "cbranch,jump"))
+ "issue+pcr_addrcalc")
;; Branch Far (JMP,RTS,BRAF)
;; Group: CO
;; Latency: 3
;; Issue Rate: 2
-;; Since issue stage (D stage) is blocked for 2nd cycle,
-;; cpu_unit int is reserved since it might be required for far
-;; address calculation.
+;; ??? Scheduling happens before branch shortening, and hence jmp and braf
+;; can't be distinguished from bra for the "jump" pattern.
-(define_insn_reservation "branch_far" 12
- (and (eq_attr "type" "jump,return")
- (eq_attr "length" "6"))
- "d_lock*2,int+pcr_addrcalc,pcr_addrcalc")
+(define_insn_reservation "sh4_return" 3
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "return,jump_ind"))
+ "d_lock*2")
;; RTE
;; Group: CO
-;; atency: 5
+;; Latency: 5
;; Issue Rate: 5
;; this instruction can be executed in any of the pipelines
;; and blocks the pipeline for next 4 stages.
-(define_insn_reservation "return_from_exp" 5
- (eq_attr "type" "rte")
- "(issue+pcr_addrcalc),d_lock*4,int+pcr_addrcalc,nothing")
+(define_insn_reservation "sh4_return_from_exp" 5
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "rte"))
+ "d_lock*5")
;; OCBP, OCBWB
;; Group: CO
-;; Latency: 5
+;; Latency: 1-5
;; Issue Rate: 1
-(define_insn_reservation "ocbwb" 5
- (eq_attr "insn_class" "cwb")
- "issue,(int+memory),memory*5")
+;; cwb is used for the sequence ocbwb @%0; extu.w %0,%2; or %1,%2; mov.l %0,@%2
+;; ocbwb on its own would be "d_lock,nothing,memory*5"
+(define_insn_reservation "ocbwb" 6
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "cwb"))
+ "d_lock*2,(d_lock+memory)*3,issue+load_store+memory,memory*2")
;; LDS to PR,JSR
;; Group: CO
;; Latency: 3
;; Issue Rate: 2
;; The SX stage is blocked for last 2 cycles.
+;; OTOH, the only time that has an effect for insns generated by the compiler
+;; is when lds to PR is followed by sts from PR - and that is highly unlikely -
+;; or when we are doing a function call - and we don't do inter-function
+;; scheduling. For the function call case, it's really best that we end with
+;; something that models an rts.
-(define_insn_reservation "lds_to_pr" 3
- (eq_attr "type" "prset,call,sfunc")
- "(issue+pcr_addrcalc),(issue+int+pcr_addrcalc),(int+pcr_addrcalc)*2")
+(define_insn_reservation "sh4_lds_to_pr" 3
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "prset") )
+ "d_lock*2")
+
+;; calls introduce a longisch delay that is likely to flush the pipelines
+;; of the caller's instructions. Ordinary functions tend to end with a
+;; load to restore a register (in the delay slot of rts), while sfuncs
+;; tend to end with an EX or MT insn. But that is not actually relevant,
+;; since there are no instructions that contend for memory access early.
+;; We could, of course, provide exact scheduling information for specific
+;; sfuncs, if that should prove useful.
+
+(define_insn_reservation "sh4_call" 16
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "call,sfunc"))
+ "d_lock*16")
;; LDS.L to PR
;; Group: CO
@@ -10730,8 +10698,9 @@
;; The SX unit is blocked for last 2 cycles.
(define_insn_reservation "ldsmem_to_pr" 3
- (eq_attr "type" "pload")
- "(issue+pcr_addrcalc),(issue+int+pcr_addrcalc),(int+memory+pcr_addrcalc),(int+pcr_addrcalc)")
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "pload"))
+ "d_lock*2")
;; STS from PR
;; Group: CO
@@ -10740,17 +10709,19 @@
;; The SX unit in second and third cycles.
(define_insn_reservation "sts_from_pr" 2
- (eq_attr "type" "prget")
- "(issue+pcr_addrcalc),(pipe_01+int+pcr_addrcalc),(int+pcr_addrcalc),nothing")
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "prget"))
+ "d_lock*2")
;; STS.L from PR
;; Group: CO
;; Latency: 2
;; Issue Rate: 2
-(define_insn_reservation "prload_mem" 2
- (eq_attr "type" "pstore")
- "(issue+pcr_addrcalc),(pipe_01+int+pcr_addrcalc),(int+memory+pcr_addrcalc),memory")
+(define_insn_reservation "sh4_prstore_mem" 2
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "pstore"))
+ "d_lock*2,nothing,memory")
;; LDS to FPSCR
;; Group: CO
@@ -10758,9 +10729,10 @@
;; Issue Rate: 1
;; F1 is blocked for last three cycles.
-(define_insn_reservation "fpscr_store" 4
- (eq_attr "insn_class" "lds_to_fpscr")
- "issue,int,F1*3")
+(define_insn_reservation "fpscr_load" 4
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "gp_fpscr"))
+ "d_lock,nothing,F1*3")
;; LDS.L to FPSCR
;; Group: CO
@@ -10769,9 +10741,10 @@
;; Issue Rate: 1
;; F1 is blocked for last three cycles.
-(define_insn_reservation "fpscr_store_mem" 4
- (eq_attr "insn_class" "ldsmem_to_fpscr")
- "issue,(int+memory),(F1+memory),F1*2")
+(define_insn_reservation "fpscr_load_mem" 4
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "mem_fpscr"))
+ "d_lock,nothing,(F1+memory),F1*2")
;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
@@ -10780,28 +10753,49 @@
;; Issue Rate: 1
(define_insn_reservation "multi" 4
- (eq_attr "type" "smpy,dmpy")
- "issue,(issue+int+f1_1),(int+f1_1),(f1_1|f1_2)*2,F2,FS")
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "smpy,dmpy"))
+ "d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2")
+
+;; Fixed STS from MACL / MACH
+;; Group: CO
+;; Latency: 3
+;; Issue Rate: 1
+
+(define_insn_reservation "sh4_mac_gp" 3
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "mac_gp"))
+ "d_lock")
;; Single precision floating point computation FCMP/EQ,
-;; FCP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
+;; FCMP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
;; Group: FE
-;; Latency: 4
+;; Latency: 3/4
;; Issue Rate: 1
-(define_insn_reservation "fp_arith" 4
- (eq_attr "type" "fp")
- "issue,F1,F2,FS")
+(define_insn_reservation "fp_arith" 3
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "fp"))
+ "issue,F01,F2")
+
+(define_insn_reservation "fp_arith_ftrc" 3
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "ftrc_s"))
+ "issue,F01,F2")
+
+(define_bypass 1 "fp_arith_ftrc" "sh4_fpul_gp")
;; Single Precision FDIV/SQRT
;; Group: FE
-;; Latency: 12/13
+;; Latency: 12/13 (FDIV); 11/12 (FSQRT)
;; Issue Rate: 1
+;; We describe fdiv here; fsqrt is actually one cycle faster.
-(define_insn_reservation "fp_div" 13
- (eq_attr "type" "fdiv")
- "issue,F1+F3,F1+F2+F3,F3*7,F1+F3,F2,FS")
+(define_insn_reservation "fp_div" 12
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "fdiv"))
+ "issue,F01+F3,F2+F3,F3*7,F1+F3,F2")
;; Double Precision floating point computation
;; (FCNVDS, FCNVSD, FLOAT, FTRC)
@@ -10809,34 +10803,51 @@
;; Latency: (3,4)/5
;; Issue Rate: 1
-(define_insn_reservation "dp_float" 5
- (eq_attr "type" "dfp_conv")
- "issue,F1,F1+F2,F2+FS,FS")
+(define_insn_reservation "dp_float" 4
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "dfp_conv"))
+ "issue,F01,F1+F2,F2")
-;; Double-precision floating-point (FADD ,FMUL,FSUB)
+;; Double-precision floating-point (FADD,FMUL,FSUB)
;; Group: FE
;; Latency: (7,8)/9
;; Issue Rate: 1
-(define_insn_reservation "fp_double_arith" 9
- (eq_attr "type" "dfp_arith")
- "issue,F1,F1+F2,fpu*4,F2+FS,FS")
+(define_insn_reservation "fp_double_arith" 8
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "dfp_arith"))
+ "issue,F01,F1+F2,fpu*4,F2")
;; Double-precision FCMP (FCMP/EQ,FCMP/GT)
-;; Group: FE
+;; Group: CO
;; Latency: 3/5
;; Issue Rate: 2
-(define_insn_reservation "fp_double_cmp" 5
- (eq_attr "type" "dfp_cmp")
- "issue,(issue+F1),F1+F2,F2+FS,FS")
+(define_insn_reservation "fp_double_cmp" 3
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "dfp_cmp"))
+ "d_lock,(d_lock+F01),F1+F2,F2")
;; Double precision FDIV/SQRT
;; Group: FE
;; Latency: (24,25)/26
;; Issue Rate: 1
-(define_insn_reservation "dp_div" 26
- (eq_attr "type" "dfdiv")
- "issue,F1+F3,F1+F2+F3,F2+F3+FS,F3*16,F1+F3,F1+F2+F3,fpu+F3,F2+FS,FS")
+(define_insn_reservation "dp_div" 25
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "dfdiv"))
+ "issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2")
+
+;; Use the branch-not-taken case to model arith3 insns. For the branch taken
+;; case, we'd get a d_lock instead of issue at the end.
+(define_insn_reservation "arith3" 3
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "arith3"))
+ "issue,d_lock+pcr_addrcalc,issue")
+
+;; arith3b insns schedule the same no matter if the branch is taken or not.
+(define_insn_reservation "arith3b" 2
+ (and (eq_attr "pipe_model" "sh4")
+ (eq_attr "type" "arith3"))
+ "issue,d_lock+pcr_addrcalc")
diff --git a/gcc/config/sparc/linux64.h b/gcc/config/sparc/linux64.h
index d29f6aa597d..5bc1994d573 100644
--- a/gcc/config/sparc/linux64.h
+++ b/gcc/config/sparc/linux64.h
@@ -311,11 +311,9 @@ ENDFILE_SPEC_COMMON
/* System V Release 4 uses DWARF debugging info. Buf DWARF1 doesn't do
64-bit anything, so we use DWARF2. */
-#undef DWARF2_DEBUGGING_INFO
#undef DWARF_DEBUGGING_INFO
-#undef DBX_DEBUGGING_INFO
-#define DWARF2_DEBUGGING_INFO
-#define DBX_DEBUGGING_INFO
+#define DWARF2_DEBUGGING_INFO 1
+#define DBX_DEBUGGING_INFO 1
#undef ASM_OUTPUT_ALIGNED_LOCAL
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
diff --git a/gcc/config/sparc/liteelf.h b/gcc/config/sparc/liteelf.h
index 5c93c2d943a..9b6cbaa93ff 100644
--- a/gcc/config/sparc/liteelf.h
+++ b/gcc/config/sparc/liteelf.h
@@ -24,10 +24,8 @@ Boston, MA 02111-1307, USA. */
/* Default to dwarf2 in ELF. */
-#undef DWARF_DEBUGGING_INFO
-#define DWARF_DEBUGGING_INFO
-#undef DWARF2_DEBUGGING_INFO
-#define DWARF2_DEBUGGING_INFO
+#define DWARF_DEBUGGING_INFO 1
+#define DWARF2_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
diff --git a/gcc/config/sparc/netbsd.h b/gcc/config/sparc/netbsd.h
index 8ae4c566349..f6a5244333a 100644
--- a/gcc/config/sparc/netbsd.h
+++ b/gcc/config/sparc/netbsd.h
@@ -29,7 +29,7 @@
/* This is BSD, so it wants DBX format. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
/* This is the char to use for continuation (in case we need to turn
continuation back on). */
diff --git a/gcc/config/sparc/openbsd.h b/gcc/config/sparc/openbsd.h
index dc3728453e5..96d2f149a72 100644
--- a/gcc/config/sparc/openbsd.h
+++ b/gcc/config/sparc/openbsd.h
@@ -43,7 +43,7 @@ Boston, MA 02111-1307, USA. */
/* Specific options for DBX Output. */
/* This is BSD, so it wants DBX format. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
/* This is the char to use for continuation */
#define DBX_CONTIN_CHAR '?'
diff --git a/gcc/config/sparc/pbd.h b/gcc/config/sparc/pbd.h
index 18391abed9a..e7c01c0b48a 100644
--- a/gcc/config/sparc/pbd.h
+++ b/gcc/config/sparc/pbd.h
@@ -27,7 +27,7 @@ Boston, MA 02111-1307, USA. */
/* We want DBX format for use with gdb under COFF. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
/* Generate calls to memcpy, memcmp and memset. */
diff --git a/gcc/config/sparc/sp64-elf.h b/gcc/config/sparc/sp64-elf.h
index caf944b33ff..18187dc64fd 100644
--- a/gcc/config/sparc/sp64-elf.h
+++ b/gcc/config/sparc/sp64-elf.h
@@ -112,7 +112,7 @@ crtbegin.o%s \
GDB doesn't support 64 bit stabs yet and the desired debug format is DWARF
anyway so it is the default. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
diff --git a/gcc/config/sparc/sp86x-elf.h b/gcc/config/sparc/sp86x-elf.h
index 42239a945e1..cb7e8c3f203 100644
--- a/gcc/config/sparc/sp86x-elf.h
+++ b/gcc/config/sparc/sp86x-elf.h
@@ -24,10 +24,8 @@ Boston, MA 02111-1307, USA. */
/* Default to dwarf2 in ELF. */
-#undef DWARF_DEBUGGING_INFO
-#define DWARF_DEBUGGING_INFO
-#undef DWARF2_DEBUGGING_INFO
-#define DWARF2_DEBUGGING_INFO
+#define DWARF_DEBUGGING_INFO 1
+#define DWARF2_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 971b6f2e5f7..4a83b8a5612 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -5347,7 +5347,8 @@ sparc_va_arg (valist, type)
PUT_MODE (tmp, BLKmode);
set_mem_alias_set (tmp, 0);
- dest_addr = emit_block_move (tmp, addr_rtx, GEN_INT (rsize));
+ dest_addr = emit_block_move (tmp, addr_rtx, GEN_INT (rsize),
+ BLOCK_OP_NORMAL);
if (dest_addr != NULL_RTX)
addr_rtx = dest_addr;
else
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index 5c4c9653b13..e14c4f21fe1 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -375,7 +375,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
/* Generate DBX debugging information. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
/* Run-time compilation parameters selecting different hardware subsets. */
diff --git a/gcc/config/svr3.h b/gcc/config/svr3.h
index 13e46b2e4c4..e559c5c59d3 100644
--- a/gcc/config/svr3.h
+++ b/gcc/config/svr3.h
@@ -129,7 +129,7 @@ Boston, MA 02111-1307, USA.
/* System V Release 3 uses COFF debugging info. */
-#define SDB_DEBUGGING_INFO
+#define SDB_DEBUGGING_INFO 1
/* We don't want to output DBX debugging information. */
diff --git a/gcc/config/v850/lib1funcs.asm b/gcc/config/v850/lib1funcs.asm
index 621ba60a486..2415f91830a 100644
--- a/gcc/config/v850/lib1funcs.asm
+++ b/gcc/config/v850/lib1funcs.asm
@@ -1,5 +1,5 @@
/* libgcc routines for NEC V850.
- Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 2002 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -31,70 +31,87 @@ Boston, MA 02111-1307, USA. */
.text
.globl ___mulsi3
.type ___mulsi3,@function
-
-/*
- * #define SHIFT 12
- * #define MASK ((1 << SHIFT) - 1)
- *
- * #define STEP(i, j) \
- * ({ \
- * short a_part = (a >> (i)) & MASK; \
- * short b_part = (b >> (j)) & MASK; \
- * int res = (((int)a_part) * ((int)b_part)); \
- * res; \
- * })
- *
- * int
- * __mulsi3 (unsigned a, unsigned b)
- * {
- * return STEP (0, 0) +
- * ((STEP (SHIFT, 0) + STEP (0, SHIFT)) << SHIFT) +
- * ((STEP (0, 2 * SHIFT) + STEP (SHIFT, SHIFT) + STEP (2 * SHIFT, 0))
- * << (2 * SHIFT));
- * }
- */
-
___mulsi3:
- mov r6,r13
- movea lo(4095),r0,r16
- and r16,r13
- mov r7,r15
- and r16,r15
- mov r13,r10
- mulh r15,r10
- shr 12,r6
- mov r6,r14
- and r16,r14
- mov r14,r11
- mulh r15,r11
- shr 12,r7
- mov r7,r12
- and r16,r12
- shr 12,r7
- and r16,r7
- mulh r13,r7
- shr 12,r6
- mulh r12,r13
- and r16,r6
- add r13,r11
- shl 12,r11
- add r11,r10
- mov r14,r11
- mulh r12,r11
- mulh r15,r6
- add r11,r7
- add r6,r7
- shl 24,r7
- add r7,r10
- jmp [r31]
+#ifdef __v850__
+/*
+ #define SHIFT 12
+ #define MASK ((1 << SHIFT) - 1)
+
+ #define STEP(i, j) \
+ ({ \
+ short a_part = (a >> (i)) & MASK; \
+ short b_part = (b >> (j)) & MASK; \
+ int res = (((int) a_part) * ((int) b_part)); \
+ res; \
+ })
+
+ int
+ __mulsi3 (unsigned a, unsigned b)
+ {
+ return STEP (0, 0) +
+ ((STEP (SHIFT, 0) + STEP (0, SHIFT)) << SHIFT) +
+ ((STEP (0, 2 * SHIFT) + STEP (SHIFT, SHIFT) + STEP (2 * SHIFT, 0))
+ << (2 * SHIFT));
+ }
+*/
+ mov r6, r14
+ movea lo(32767), r0, r10
+ and r10, r14
+ mov r7, r15
+ and r10, r15
+ shr 15, r6
+ mov r6, r13
+ and r10, r13
+ shr 15, r7
+ mov r7, r12
+ and r10, r12
+ shr 15, r6
+ shr 15, r7
+ mov r14, r10
+ mulh r15, r10
+ mov r14, r11
+ mulh r12, r11
+ mov r13, r16
+ mulh r15, r16
+ mulh r14, r7
+ mulh r15, r6
+ add r16, r11
+ mulh r13, r12
+ shl 15, r11
+ add r11, r10
+ add r12, r7
+ add r6, r7
+ shl 30, r7
+ add r7, r10
+ jmp [r31]
+#endif /* __v850__ */
+#if defined(__v850e__) || defined(__v850ea__)
+ /* This routine is almost unneccesarry because gcc
+ generates the MUL instruction for the RTX mulsi3.
+ But if someone wants to link his application with
+ previsously compiled v850 objects then they will
+ need this function. */
+
+ /* It isn't good to put the inst sequence as below;
+ mul r7, r6,
+ mov r6, r10, r0
+ In this case, there is a RAW hazard between them.
+ MUL inst takes 2 cycle in EX stage, then MOV inst
+ must wait 1cycle. */
+ mov r7, r10
+ mul r6, r10, r0
+ jmp [r31]
+#endif /* __v850e__ */
.size ___mulsi3,.-___mulsi3
-#endif
+#endif /* L_mulsi3 */
+
#ifdef L_udivsi3
.text
.global ___udivsi3
.type ___udivsi3,@function
___udivsi3:
+#ifdef __v850__
mov 1,r12
mov 0,r10
cmp r6,r7
@@ -126,6 +143,16 @@ ___udivsi3:
bne .L9
.L8:
jmp [r31]
+
+#else /* defined(__v850e__) */
+
+ /* See comments at end of __mulsi3. */
+ mov r6, r10
+ divu r7, r10, r0
+ jmp [r31]
+
+#endif /* __v850e__ */
+
.size ___udivsi3,.-___udivsi3
#endif
@@ -134,6 +161,7 @@ ___udivsi3:
.globl ___divsi3
.type ___divsi3,@function
___divsi3:
+#ifdef __v850__
add -8,sp
st.w r31,4[sp]
st.w r22,0[sp]
@@ -157,6 +185,16 @@ ___divsi3:
ld.w 4[sp],r31
add 8,sp
jmp [r31]
+
+#else /* defined(__v850e__) */
+
+ /* See comments at end of __mulsi3. */
+ mov r6, r10
+ div r7, r10, r0
+ jmp [r31]
+
+#endif /* __v850e__ */
+
.size ___divsi3,.-___divsi3
#endif
@@ -165,6 +203,7 @@ ___divsi3:
.globl ___umodsi3
.type ___umodsi3,@function
___umodsi3:
+#ifdef __v850__
add -12,sp
st.w r31,8[sp]
st.w r7,4[sp]
@@ -178,6 +217,15 @@ ___umodsi3:
ld.w 8[sp],r31
add 12,sp
jmp [r31]
+
+#else /* defined(__v850e__) */
+
+ /* See comments at end of __mulsi3. */
+ divu r7, r6, r10
+ jmp [r31]
+
+#endif /* __v850e__ */
+
.size ___umodsi3,.-___umodsi3
#endif /* L_umodsi3 */
@@ -186,6 +234,7 @@ ___umodsi3:
.globl ___modsi3
.type ___modsi3,@function
___modsi3:
+#ifdef __v850__
add -12,sp
st.w r31,8[sp]
st.w r7,4[sp]
@@ -199,6 +248,15 @@ ___modsi3:
ld.w 8[sp],r31
add 12,sp
jmp [r31]
+
+#else /* defined(__v850e__) */
+
+ /* See comments at end of __mulsi3. */
+ div r7, r6, r10
+ jmp [r31]
+
+#endif /* __v850e__ */
+
.size ___modsi3,.-___modsi3
#endif /* L_modsi3 */
@@ -1114,7 +1172,7 @@ __return_r29_r31:
.type __save_r31,@function
/* Allocate space and save register 31 on the stack */
/* Also allocate space for the argument save area */
- /* Called via: jalr __save_r29_r31,r10 */
+ /* Called via: jalr __save_r31,r10 */
__save_r31:
addi -20,sp,sp
st.w r31,16[sp]
@@ -1130,7 +1188,7 @@ __return_r31:
ld.w 16[sp],r31
addi 20,sp,sp
jmp [r31]
- .size __return_r29_r31,.-__return_r29_r31
+ .size __return_r31,.-__return_r31
#endif /* L_save_31c */
#ifdef L_save_varargs
@@ -1267,3 +1325,561 @@ __restore_all_interrupt:
jmp [r10]
.size __restore_all_interrupt,.-__restore_all_interrupt
#endif /* L_save_all_interrupt */
+
+
+#if defined __v850e__
+#ifdef L_callt_save_r2_r29
+ /* Put these functions into the call table area. */
+ .call_table_text
+
+ /* Allocate space and save registers 2, 20 .. 29 on the stack. */
+ /* Called via: callt ctoff(__callt_save_r2_r29). */
+ .align 2
+.L_save_r2_r29:
+ add -4, sp
+ st.w r2, 0[sp]
+ prepare {r20 - r29}, 0
+ ctret
+
+ /* Restore saved registers, deallocate stack and return to the user. */
+ /* Called via: callt ctoff(__callt_return_r2_r29). */
+ .align 2
+.L_return_r2_r29:
+ dispose 0, {r20-r29}
+ ld.w 0[sp], r2
+ add 4, sp
+ jmp [r31]
+
+ /* Place the offsets of the start of these routines into the call table. */
+ .call_table_data
+
+ .global __callt_save_r2_r29
+ .type __callt_save_r2_r29,@function
+__callt_save_r2_r29: .short ctoff(.L_save_r2_r29)
+
+ .global __callt_return_r2_r29
+ .type __callt_return_r2_r29,@function
+__callt_return_r2_r29: .short ctoff(.L_return_r2_r29)
+
+#endif /* L_callt_save_r2_r29 */
+
+#ifdef L_callt_save_r2_r31
+ /* Put these functions into the call table area. */
+ .call_table_text
+
+ /* Allocate space and save registers 2 and 20 .. 29, 31 on the stack. */
+ /* Also allocate space for the argument save area. */
+ /* Called via: callt ctoff(__callt_save_r2_r31). */
+ .align 2
+.L_save_r2_r31:
+ add -4, sp
+ st.w r2, 0[sp]
+ prepare {r20 - r29, r31}, 4
+ ctret
+
+ /* Restore saved registers, deallocate stack and return to the user. */
+ /* Called via: callt ctoff(__callt_return_r2_r31). */
+ .align 2
+.L_return_r2_r31:
+ dispose 4, {r20 - r29, r31}
+ ld.w 0[sp], r2
+ addi 4, sp, sp
+ jmp [r31]
+
+ /* Place the offsets of the start of these routines into the call table. */
+ .call_table_data
+
+ .global __callt_save_r2_r31
+ .type __callt_save_r2_r31,@function
+__callt_save_r2_r31: .short ctoff(.L_save_r2_r31)
+
+ .global __callt_return_r2_r31
+ .type __callt_return_r2_r31,@function
+__callt_return_r2_r31: .short ctoff(.L_return_r2_r31)
+
+#endif /* L_callt_save_r2_r31 */
+
+
+#ifdef L_callt_save_r6_r9
+ /* Put these functions into the call table area. */
+ .call_table_text
+
+ /* Save registers r6 - r9 onto the stack in the space reserved for them.
+ Use by variable argument functions.
+ Called via: callt ctoff(__callt_save_r6_r9). */
+ .align 2
+.L_save_r6_r9:
+ mov ep,r1
+ mov sp,ep
+ sst.w r6,0[ep]
+ sst.w r7,4[ep]
+ sst.w r8,8[ep]
+ sst.w r9,12[ep]
+ mov r1,ep
+ ctret
+
+ /* Place the offsets of the start of this routines into the call table. */
+ .call_table_data
+
+ .global __callt_save_r6_r9
+ .type __callt_save_r6_r9,@function
+__callt_save_r6_r9: .short ctoff(.L_save_r6_r9)
+#endif /* L_callt_save_r6_r9 */
+
+
+#ifdef L_callt_save_interrupt
+ /* Put this functions into the call table area */
+ .call_table_text
+
+ /* Save registers r1, ep, gp, r10 on stack and load up with expected values. */
+ /* Called via: callt ctoff(__callt_save_interrupt). */
+ .align 2
+.L_save_interrupt:
+ /* SP has already been moved before callt ctoff(_save_interrupt). */
+ /* addi -24, sp, sp */
+ st.w ep, 0[sp]
+ st.w gp, 4[sp]
+ st.w r1, 8[sp]
+ /* R10 has alread been saved bofore callt ctoff(_save_interrupt). */
+ /* st.w r10, 12[sp] */
+ mov hilo(__ep),ep
+ mov hilo(__gp),gp
+ ctret
+
+ /* Place the offsets of the start of the routine into the call table. */
+ .call_table_data
+ .global __callt_save_interrupt
+ .type __callt_save_interrupt,@function
+__callt_save_interrupt: .short ctoff(.L_save_interrupt)
+
+ .call_table_text
+
+ /* Restore saved registers, deallocate stack and return from the interrupt. */
+ /* Called via: callt ctoff(__callt_restore_itnerrupt). */
+ .text
+ .align 2
+ .globl __return_interrupt
+ .type __return_interrupt,@function
+.L_return_interrupt:
+ ld.w 20[sp], r1
+ ldsr r1, ctpsw
+ ld.w 16[sp], r1
+ ldsr r1, ctpc
+ ld.w 12[sp], r10
+ ld.w 8[sp], r1
+ ld.w 4[sp], gp
+ ld.w 0[sp], ep
+ addi 24, sp, sp
+ reti
+
+ /* Place the offsets of the start of the routine into the call table. */
+ .call_table_data
+
+ .global __callt_return_interrupt
+ .type __callt_return_interrupt,@function
+__callt_return_interrupt: .short ctoff(.L_return_interrupt)
+
+#endif /* L_callt_save_interrupt */
+
+#ifdef L_callt_save_all_interrupt
+ /* Put this functions into the call table area. */
+ .call_table_text
+
+ /* Save all registers except for those saved in __save_interrupt. */
+ /* Allocate enough stack for all of the registers & 16 bytes of space. */
+ /* Called via: callt ctoff(__callt_save_all_interrupt). */
+ .align 2
+.L_save_all_interrupt:
+ addi -60, sp, sp
+ mov ep, r1
+ mov sp, ep
+ sst.w r2, 56[ep]
+ sst.w r5, 52[ep]
+ sst.w r6, 48[ep]
+ sst.w r7, 44[ep]
+ sst.w r8, 40[ep]
+ sst.w r9, 36[ep]
+ sst.w r11, 32[ep]
+ sst.w r12, 28[ep]
+ sst.w r13, 24[ep]
+ sst.w r14, 20[ep]
+ sst.w r15, 16[ep]
+ sst.w r16, 12[ep]
+ sst.w r17, 8[ep]
+ sst.w r18, 4[ep]
+ sst.w r19, 0[ep]
+ mov r1, ep
+
+ prepare {r20 - r29, r31}, 4
+ ctret
+
+ /* Restore all registers saved in __save_all_interrupt. */
+ /* & deallocate the stack space. */
+ /* Called via: callt ctoff(__callt_restore_all_interrupt). */
+ .align 2
+.L_restore_all_interrupt:
+ dispose 4, {r20 - r29, r31}
+
+ mov ep, r1
+ mov sp, ep
+ sld.w 0 [ep], r19
+ sld.w 4 [ep], r18
+ sld.w 8 [ep], r17
+ sld.w 12[ep], r16
+ sld.w 16[ep], r15
+ sld.w 20[ep], r14
+ sld.w 24[ep], r13
+ sld.w 28[ep], r12
+ sld.w 32[ep], r11
+ sld.w 36[ep], r9
+ sld.w 40[ep], r8
+ sld.w 44[ep], r7
+ sld.w 48[ep], r6
+ sld.w 52[ep], r5
+ sld.w 56[ep], r2
+ mov r1, ep
+ addi 60, sp, sp
+ ctret
+
+ /* Place the offsets of the start of these routines into the call table. */
+ .call_table_data
+
+ .global __callt_save_all_interrupt
+ .type __callt_save_all_interrupt,@function
+__callt_save_all_interrupt: .short ctoff(.L_save_all_interrupt)
+
+ .global __callt_restore_all_interrupt
+ .type __callt_restore_all_interrupt,@function
+__callt_restore_all_interrupt: .short ctoff(.L_restore_all_interrupt)
+
+#endif /* L_callt_save_all_interrupt */
+
+
+#define MAKE_CALLT_FUNCS( START ) \
+ .call_table_text ;\
+ .align 2 ;\
+ /* Allocate space and save registers START .. r29 on the stack. */ ;\
+ /* Called via: callt ctoff(__callt_save_START_r29). */ ;\
+.L_save_##START##_r29: ;\
+ prepare { START - r29 }, 0 ;\
+ ctret ;\
+ ;\
+ /* Restore saved registers, deallocate stack and return. */ ;\
+ /* Called via: callt ctoff(__return_START_r29) */ ;\
+ .align 2 ;\
+.L_return_##START##_r29: ;\
+ dispose 0, { START - r29 }, r31 ;\
+ ;\
+ /* Place the offsets of the start of these funcs into the call table. */;\
+ .call_table_data ;\
+ ;\
+ .global __callt_save_##START##_r29 ;\
+ .type __callt_save_##START##_r29,@function ;\
+__callt_save_##START##_r29: .short ctoff(.L_save_##START##_r29 ) ;\
+ ;\
+ .global __callt_return_##START##_r29 ;\
+ .type __callt_return_##START##_r29,@function ;\
+__callt_return_##START##_r29: .short ctoff(.L_return_##START##_r29 )
+
+
+#define MAKE_CALLT_CFUNCS( START ) \
+ .call_table_text ;\
+ .align 2 ;\
+ /* Allocate space and save registers START .. r31 on the stack. */ ;\
+ /* Called via: callt ctoff(__callt_save_START_r31c). */ ;\
+.L_save_##START##_r31c: ;\
+ prepare { START - r29, r31}, 4 ;\
+ ctret ;\
+ ;\
+ /* Restore saved registers, deallocate stack and return. */ ;\
+ /* Called via: callt ctoff(__return_START_r31c). */ ;\
+ .align 2 ;\
+.L_return_##START##_r31c: ;\
+ dispose 4, { START - r29, r31}, r31 ;\
+ ;\
+ /* Place the offsets of the start of these funcs into the call table. */;\
+ .call_table_data ;\
+ ;\
+ .global __callt_save_##START##_r31c ;\
+ .type __callt_save_##START##_r31c,@function ;\
+__callt_save_##START##_r31c: .short ctoff(.L_save_##START##_r31c ) ;\
+ ;\
+ .global __callt_return_##START##_r31c ;\
+ .type __callt_return_##START##_r31c,@function ;\
+__callt_return_##START##_r31c: .short ctoff(.L_return_##START##_r31c )
+
+
+#ifdef L_callt_save_20
+ MAKE_CALLT_FUNCS (r20)
+#endif
+#ifdef L_callt_save_21
+ MAKE_CALLT_FUNCS (r21)
+#endif
+#ifdef L_callt_save_22
+ MAKE_CALLT_FUNCS (r22)
+#endif
+#ifdef L_callt_save_23
+ MAKE_CALLT_FUNCS (r23)
+#endif
+#ifdef L_callt_save_24
+ MAKE_CALLT_FUNCS (r24)
+#endif
+#ifdef L_callt_save_25
+ MAKE_CALLT_FUNCS (r25)
+#endif
+#ifdef L_callt_save_26
+ MAKE_CALLT_FUNCS (r26)
+#endif
+#ifdef L_callt_save_27
+ MAKE_CALLT_FUNCS (r27)
+#endif
+#ifdef L_callt_save_28
+ MAKE_CALLT_FUNCS (r28)
+#endif
+#ifdef L_callt_save_29
+ MAKE_CALLT_FUNCS (r29)
+#endif
+
+#ifdef L_callt_save_20c
+ MAKE_CALLT_CFUNCS (r20)
+#endif
+#ifdef L_callt_save_21c
+ MAKE_CALLT_CFUNCS (r21)
+#endif
+#ifdef L_callt_save_22c
+ MAKE_CALLT_CFUNCS (r22)
+#endif
+#ifdef L_callt_save_23c
+ MAKE_CALLT_CFUNCS (r23)
+#endif
+#ifdef L_callt_save_24c
+ MAKE_CALLT_CFUNCS (r24)
+#endif
+#ifdef L_callt_save_25c
+ MAKE_CALLT_CFUNCS (r25)
+#endif
+#ifdef L_callt_save_26c
+ MAKE_CALLT_CFUNCS (r26)
+#endif
+#ifdef L_callt_save_27c
+ MAKE_CALLT_CFUNCS (r27)
+#endif
+#ifdef L_callt_save_28c
+ MAKE_CALLT_CFUNCS (r28)
+#endif
+#ifdef L_callt_save_29c
+ MAKE_CALLT_CFUNCS (r29)
+#endif
+
+
+#ifdef L_callt_save_31c
+ .call_table_text
+ .align 2
+ /* Allocate space and save register r31 on the stack. */
+ /* Called via: callt ctoff(__callt_save_r31c). */
+.L_callt_save_r31c:
+ prepare {r31}, 4
+ ctret
+
+ /* Restore saved registers, deallocate stack and return. */
+ /* Called via: callt ctoff(__return_r31c). */
+ .align 2
+.L_callt_return_r31c:
+ dispose 4, {r31}, r31
+
+ /* Place the offsets of the start of these funcs into the call table. */
+ .call_table_data
+
+ .global __callt_save_r31c
+ .type __callt_save_r31c,@function
+__callt_save_r31c: .short ctoff(.L_callt_save_r31c)
+
+ .global __callt_return_r31c
+ .type __callt_return_r31c,@function
+__callt_return_r31c: .short ctoff(.L_callt_return_r31c)
+#endif
+
+#endif /* __v850e__ */
+
+/* libgcc2 routines for NEC V850. */
+/* Double Integer Arithmetical Operation. */
+
+#ifdef L_negdi2
+ .text
+ .global ___negdi2
+ .type ___negdi2, @function
+___negdi2:
+ not r6, r10
+ add 1, r10
+ setf l, r6
+ not r7, r11
+ add r6, r11
+ jmp [lp]
+
+ .size ___negdi2,.-___negdi2
+#endif
+
+#ifdef L_cmpdi2
+ .text
+ .global ___cmpdi2
+ .type ___cmpdi2,@function
+___cmpdi2:
+ # Signed comparison bitween each high word.
+ cmp r9, r7
+ be .L_cmpdi_cmp_low
+ setf ge, r10
+ setf gt, r6
+ add r6, r10
+ jmp [lp]
+.L_cmpdi_cmp_low:
+ # Unsigned comparigon bitween each low word.
+ cmp r8, r6
+ setf nl, r10
+ setf h, r6
+ add r6, r10
+ jmp [lp]
+ .size ___cmpdi2, . - ___cmpdi2
+#endif
+
+#ifdef L_ucmpdi2
+ .text
+ .global ___ucmpdi2
+ .type ___ucmpdi2,@function
+___ucmpdi2:
+ cmp r9, r7 # Check if each high word are same.
+ be .L_ucmpdi_check_psw
+ cmp r8, r6 # Compare the word.
+.L_ucmpdi_check_psw:
+ setf nl, r10 #
+ setf h, r6 #
+ add r6, r10 # Add the result of comparison NL and comparison H.
+ jmp [lp]
+ .size ___ucmpdi2, . - ___ucmpdi2
+#endif
+
+#ifdef L_muldi3
+ .text
+ .global ___muldi3
+ .type ___muldi3,@function
+___muldi3:
+#ifdef __v850__
+ jarl __save_r26_r31, r10
+ addi 16, sp, sp
+ mov r6, r5
+ shr 15, r5
+ movea lo(32767), r0, r14
+ and r14, r5
+ mov r8, r10
+ shr 15, r10
+ and r14, r10
+ mov r6, r19
+ shr 30, r19
+ mov r7, r12
+ shl 2, r12
+ or r12, r19
+ and r14, r19
+ mov r8, r13
+ shr 30, r13
+ mov r9, r12
+ shl 2, r12
+ or r12, r13
+ and r14, r13
+ mov r7, r11
+ shr 13, r11
+ and r14, r11
+ mov r9, r31
+ shr 13, r31
+ and r14, r31
+ mov r7, r29
+ shr 28, r29
+ and r14, r29
+ mov r9, r12
+ shr 28, r12
+ and r14, r12
+ and r14, r6
+ and r14, r8
+ mov r6, r14
+ mulh r8, r14
+ mov r6, r16
+ mulh r10, r16
+ mov r6, r18
+ mulh r13, r18
+ mov r6, r15
+ mulh r31, r15
+ mulh r12, r6
+ mov r5, r17
+ mulh r10, r17
+ add -16, sp
+ mov r5, r12
+ mulh r8, r12
+ add r17, r18
+ mov r5, r17
+ mulh r31, r17
+ add r12, r16
+ mov r5, r12
+ mulh r13, r12
+ add r17, r6
+ mov r19, r17
+ add r12, r15
+ mov r19, r12
+ mulh r8, r12
+ mulh r10, r17
+ add r12, r18
+ mov r19, r12
+ mulh r13, r12
+ add r17, r15
+ mov r11, r13
+ mulh r8, r13
+ add r12, r6
+ mov r11, r12
+ mulh r10, r12
+ add r13, r15
+ mulh r29, r8
+ add r12, r6
+ mov r16, r13
+ shl 15, r13
+ add r14, r13
+ mov r18, r12
+ shl 30, r12
+ mov r13, r26
+ add r12, r26
+ shr 15, r14
+ movhi hi(131071), r0, r12
+ movea lo(131071), r12, r13
+ and r13, r14
+ mov r16, r12
+ and r13, r12
+ add r12, r14
+ mov r18, r12
+ shl 15, r12
+ and r13, r12
+ add r12, r14
+ shr 17, r14
+ shr 17, r16
+ add r14, r16
+ shl 13, r15
+ shr 2, r18
+ add r18, r15
+ add r15, r16
+ mov r16, r27
+ add r8, r6
+ shl 28, r6
+ add r6, r27
+ mov r26, r10
+ mov r27, r11
+ jr __return_r26_r31
+#endif /* __v850__ */
+#if defined(__v850e__) || defined(__v850ea__)
+ /* (Ahi << 32 + Alo) * (Bhi << 32 + Blo) */
+ /* r7 r6 r9 r8 */
+ mov r8, r10
+ mulu r7, r8, r0 /* Ahi * Blo */
+ mulu r6, r9, r0 /* Alo * Bhi */
+ mulu r6, r10, r11 /* Alo * Blo */
+ add r8, r11
+ add r9, r11
+ jmp [r31]
+
+#endif /* defined(__v850e__) || defined(__v850ea__) */
+ .size ___muldi3, . - ___muldi3
+#endif
diff --git a/gcc/config/v850/t-v850 b/gcc/config/v850/t-v850
index 2452969f267..030f043f071 100644
--- a/gcc/config/v850/t-v850
+++ b/gcc/config/v850/t-v850
@@ -29,7 +29,38 @@ LIB1ASMFUNCS = _mulsi3 \
_save_31c \
_save_varargs \
_save_interrupt \
- _save_all_interrupt
+ _save_all_interrupt \
+ _callt_save_20 \
+ _callt_save_21 \
+ _callt_save_22 \
+ _callt_save_23 \
+ _callt_save_24 \
+ _callt_save_25 \
+ _callt_save_26 \
+ _callt_save_27 \
+ _callt_save_28 \
+ _callt_save_29 \
+ _callt_save_20c \
+ _callt_save_21c \
+ _callt_save_22c \
+ _callt_save_23c \
+ _callt_save_24c \
+ _callt_save_25c \
+ _callt_save_26c \
+ _callt_save_27c \
+ _callt_save_28c \
+ _callt_save_29c \
+ _callt_save_31c \
+ _callt_save_varargs \
+ _callt_save_interrupt \
+ _callt_save_all_interrupt \
+ _callt_save_r2_r29 \
+ _callt_save_r2_r31 \
+ _callt_save_r6_r9 \
+ _negdi2 \
+ _cmpdi2 \
+ _ucmpdi2 \
+ _muldi3
# We want fine grained libraries, so use the new code to build the
# floating point emulation libraries.
@@ -49,7 +80,12 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
echo '#endif' >> fp-bit.c
cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-TCFLAGS = -Wa,-mwarn-signed-overflow -Wa,-mwarn-unsigned-overflow
+# Create target-specific versions of the libraries
+MULTILIB_OPTIONS = mv850/mv850e
+MULTILIB_DIRNAMES = v850 v850e
+INSTALL_LIBGCC = install-multilib
+
+TCFLAGS = -mno-app-regs -msmall-sld -Wa,-mwarn-signed-overflow -Wa,-mwarn-unsigned-overflow
v850-c.o: $(srcdir)/config/v850/v850-c.c $(RTL_H) $(TREE_H) $(CONFIG_H)
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
diff --git a/gcc/config/v850/v850-protos.h b/gcc/config/v850/v850-protos.h
index 05b740adfd0..bab73ae7e56 100644
--- a/gcc/config/v850/v850-protos.h
+++ b/gcc/config/v850/v850-protos.h
@@ -1,22 +1,22 @@
/* Prototypes for v850.c functions used in the md file & elsewhere.
- Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+ This file is part of GNU CC.
-GNU CC 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 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,
-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.
+ GNU CC 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
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GNU CC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* Function prototypes that cannot exist in v850.h due to dependency
complications. */
@@ -53,6 +53,12 @@ extern void notice_update_cc PARAMS ((rtx, rtx));
extern char * construct_save_jarl PARAMS ((rtx));
extern char * construct_restore_jr PARAMS ((rtx));
#ifdef HAVE_MACHINE_MODES
+extern int reg_or_int9_operand PARAMS ((rtx, Mmode));
+extern int reg_or_const_operand PARAMS ((rtx, Mmode));
+extern char * construct_dispose_instruction PARAMS ((rtx));
+extern char * construct_prepare_instruction PARAMS ((rtx));
+extern int pattern_is_ok_for_prepare PARAMS ((rtx, Mmode));
+extern int pattern_is_ok_for_dispose PARAMS ((rtx, Mmode));
extern int ep_memory_operand PARAMS ((rtx, Mmode, int));
extern int reg_or_0_operand PARAMS ((rtx, Mmode));
extern int reg_or_int5_operand PARAMS ((rtx, Mmode));
diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c
index 80096781ae6..86e80e9887f 100644
--- a/gcc/config/v850/v850.c
+++ b/gcc/config/v850/v850.c
@@ -3,22 +3,22 @@
Free Software Foundation, Inc.
Contributed by Jeff Law (law@cygnus.com).
-This file is part of GNU CC.
+ This file is part of GNU CC.
-GNU CC 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 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,
-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.
+ GNU CC 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
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GNU CC; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
#include "config.h"
#include "system.h"
@@ -142,6 +142,13 @@ override_options ()
}
}
}
+
+ /* Make sure that the US_BIT_SET mask has been correctly initialised. */
+ if ((target_flags & MASK_US_MASK_SET) == 0)
+ {
+ target_flags |= MASK_US_MASK_SET;
+ target_flags &= ~MASK_US_BIT_SET;
+ }
}
@@ -176,6 +183,9 @@ function_arg (cum, mode, type, named)
else
size = GET_MODE_SIZE (mode);
+ if (size < 1)
+ return 0;
+
if (type)
align = TYPE_ALIGN (type) / BITS_PER_UNIT;
else
@@ -696,6 +706,38 @@ print_operand_address (file, addr)
}
}
+/* When assemble_integer is used to emit the offsets for a switch
+ table it can encounter (TRUNCATE:HI (MINUS:SI (LABEL_REF:SI) (LABEL_REF:SI))).
+ output_addr_const will normally barf at this, but it is OK to omit
+ the truncate and just emit the difference of the two labels. The
+ .hword directive will automatically handle the truncation for us.
+
+ Returns 1 if rtx was handled, 0 otherwise. */
+
+int
+v850_output_addr_const_extra (file, x)
+ FILE * file;
+ rtx x;
+{
+ if (GET_CODE (x) != TRUNCATE)
+ return 0;
+
+ x = XEXP (x, 0);
+
+ /* We must also handle the case where the switch table was passed a
+ constant value and so has been collapsed. In this case the first
+ label will have been deleted. In such a case it is OK to emit
+ nothing, since the table will not be used.
+ (cf gcc.c-torture/compile/990801-1.c). */
+ if (GET_CODE (x) == MINUS
+ && GET_CODE (XEXP (x, 0)) == LABEL_REF
+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == CODE_LABEL
+ && INSN_DELETED_P (XEXP (XEXP (x, 0), 0)))
+ return 1;
+
+ output_addr_const (file, x);
+ return 1;
+}
/* Return appropriate code to load up a 1, 2, or 4 integer/floating
point value. */
@@ -716,16 +758,19 @@ output_move_single (operands)
{
HOST_WIDE_INT value = INTVAL (src);
- if (CONST_OK_FOR_J (value)) /* signed 5 bit immediate */
+ if (CONST_OK_FOR_J (value)) /* Signed 5 bit immediate. */
return "mov %1,%0";
- else if (CONST_OK_FOR_K (value)) /* signed 16 bit immediate */
+ else if (CONST_OK_FOR_K (value)) /* Signed 16 bit immediate. */
return "movea lo(%1),%.,%0";
- else if (CONST_OK_FOR_L (value)) /* upper 16 bits were set */
+ else if (CONST_OK_FOR_L (value)) /* Upper 16 bits were set. */
return "movhi hi(%1),%.,%0";
- else /* random constant */
+ /* A random constant. */
+ else if (TARGET_V850E)
+ return "mov %1,%0";
+ else
return "movhi hi(%1),%.,%0\n\tmovea lo(%1),%0,%0";
}
@@ -734,16 +779,21 @@ output_move_single (operands)
HOST_WIDE_INT high, low;
const_double_split (src, &high, &low);
- if (CONST_OK_FOR_J (high)) /* signed 5 bit immediate */
+
+ if (CONST_OK_FOR_J (high)) /* Signed 5 bit immediate. */
return "mov %F1,%0";
- else if (CONST_OK_FOR_K (high)) /* signed 16 bit immediate */
+ else if (CONST_OK_FOR_K (high)) /* Signed 16 bit immediate. */
return "movea lo(%F1),%.,%0";
- else if (CONST_OK_FOR_L (high)) /* upper 16 bits were set */
+ else if (CONST_OK_FOR_L (high)) /* Upper 16 bits were set. */
return "movhi hi(%F1),%.,%0";
- else /* random constant */
+ /* A random constant. */
+ else if (TARGET_V850E)
+ return "mov %F1,%0";
+
+ else
return "movhi hi(%F1),%.,%0\n\tmovea lo(%F1),%0,%0";
}
@@ -757,7 +807,10 @@ output_move_single (operands)
|| GET_CODE (src) == SYMBOL_REF
|| GET_CODE (src) == CONST)
{
- return "movhi hi(%1),%.,%0\n\tmovea lo(%1),%0,%0";
+ if (TARGET_V850E)
+ return "mov hilo(%1),%0";
+ else
+ return "movhi hi(%1),%.,%0\n\tmovea lo(%1),%0,%0";
}
else if (GET_CODE (src) == HIGH)
@@ -881,11 +934,25 @@ ep_memory_offset (mode, unsignedp)
switch (mode)
{
case QImode:
- max_offset = (1 << 7);
+ if (TARGET_SMALL_SLD)
+ max_offset = (1 << 4);
+ else if (TARGET_V850E
+ && ( ( unsignedp && ! TARGET_US_BIT_SET)
+ || (! unsignedp && TARGET_US_BIT_SET)))
+ max_offset = (1 << 4);
+ else
+ max_offset = (1 << 7);
break;
case HImode:
- max_offset = (1 << 8);
+ if (TARGET_SMALL_SLD)
+ max_offset = (1 << 5);
+ else if (TARGET_V850E
+ && ( ( unsignedp && ! TARGET_US_BIT_SET)
+ || (! unsignedp && TARGET_US_BIT_SET)))
+ max_offset = (1 << 5);
+ else
+ max_offset = (1 << 8);
break;
case SImode:
@@ -985,6 +1052,32 @@ reg_or_int5_operand (op, mode)
return register_operand (op, mode);
}
+/* Return true if OP is either a register or a signed nine bit integer. */
+
+int
+reg_or_int9_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) == CONST_INT)
+ return CONST_OK_FOR_O (INTVAL (op));
+
+ return register_operand (op, mode);
+}
+
+/* Return true if OP is either a register or a const integer. */
+
+int
+reg_or_const_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_CODE (op) == CONST_INT)
+ return TRUE;
+
+ return register_operand (op, mode);
+}
+
/* Return true if OP is a valid call operand. */
int
@@ -1129,6 +1222,16 @@ Saved %d bytes (%d uses of register %s) in function %s, starting as insn %d, end
else if (GET_CODE (SET_SRC (pattern)) == MEM)
p_mem = &SET_SRC (pattern);
+ else if (GET_CODE (SET_SRC (pattern)) == SIGN_EXTEND
+ && GET_CODE (XEXP (SET_SRC (pattern), 0)) == MEM)
+ p_mem = &XEXP (SET_SRC (pattern), 0);
+
+ else if (GET_CODE (SET_SRC (pattern)) == ZERO_EXTEND
+ && GET_CODE (XEXP (SET_SRC (pattern), 0)) == MEM)
+ {
+ p_mem = &XEXP (SET_SRC (pattern), 0);
+ unsignedp = TRUE;
+ }
else
p_mem = (rtx *)0;
@@ -1278,6 +1381,16 @@ void v850_reorg (start_insn)
else if (GET_CODE (src) == MEM)
mem = src;
+ else if (GET_CODE (src) == SIGN_EXTEND
+ && GET_CODE (XEXP (src, 0)) == MEM)
+ mem = XEXP (src, 0);
+
+ else if (GET_CODE (src) == ZERO_EXTEND
+ && GET_CODE (XEXP (src, 0)) == MEM)
+ {
+ mem = XEXP (src, 0);
+ unsignedp = TRUE;
+ }
else
mem = NULL_RTX;
@@ -1531,8 +1644,11 @@ expand_prologue ()
/* Save/setup global registers for interrupt functions right now. */
if (interrupt_handler)
{
+ if (TARGET_V850E && ! TARGET_DISABLE_CALLT)
+ emit_insn (gen_callt_save_interrupt ());
+ else
emit_insn (gen_save_interrupt ());
-
+
actual_fsize -= INTERRUPT_FIXED_SAVE_SIZE;
if (((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)
@@ -1544,7 +1660,10 @@ expand_prologue ()
{
if (TARGET_PROLOG_FUNCTION)
{
- emit_insn (gen_save_r6_r9 ());
+ if (TARGET_V850E && ! TARGET_DISABLE_CALLT)
+ emit_insn (gen_save_r6_r9_v850e ());
+ else
+ emit_insn (gen_save_r6_r9 ());
}
else
{
@@ -1656,7 +1775,10 @@ Saved %d bytes via prologue function (%d vs. %d) for function %s\n",
/* Special case interrupt functions that save all registers for a call. */
if (interrupt_handler && ((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)
{
- emit_insn (gen_save_all_interrupt ());
+ if (TARGET_V850E && ! TARGET_DISABLE_CALLT)
+ emit_insn (gen_callt_save_all_interrupt ());
+ else
+ emit_insn (gen_save_all_interrupt ());
}
else
{
@@ -1888,7 +2010,10 @@ Saved %d bytes via epilogue function (%d vs. %d) in function %s\n",
for a call. */
if (interrupt_handler && ((1L << LINK_POINTER_REGNUM) & reg_saved) != 0)
{
- emit_insn (gen_restore_all_interrupt ());
+ if (TARGET_V850E && ! TARGET_DISABLE_CALLT)
+ emit_insn (gen_callt_restore_all_interrupt ());
+ else
+ emit_insn (gen_restore_all_interrupt ());
}
else
{
@@ -1926,7 +2051,12 @@ Saved %d bytes via epilogue function (%d vs. %d) in function %s\n",
/* And return or use reti for interrupt handlers. */
if (interrupt_handler)
- emit_jump_insn (gen_restore_interrupt ());
+ {
+ if (TARGET_V850E && ! TARGET_DISABLE_CALLT)
+ emit_insn (gen_callt_return_interrupt ());
+ else
+ emit_jump_insn (gen_return_interrupt ());
+ }
else if (actual_fsize)
emit_jump_insn (gen_return_internal ());
else
@@ -2233,10 +2363,9 @@ register_is_ok_for_epilogue (op, mode)
rtx op;
enum machine_mode ATTRIBUTE_UNUSED mode;
{
- /* The save/restore routines can only cope with registers 2, and 20 - 31 */
- return (GET_CODE (op) == REG)
- && (((REGNO (op) >= 20) && REGNO (op) <= 31)
- || REGNO (op) == 2);
+ /* The save/restore routines can only cope with registers 20 - 31. */
+ return ((GET_CODE (op) == REG)
+ && (((REGNO (op) >= 20) && REGNO (op) <= 31)));
}
/* Return non-zero if the given RTX is suitable for collapsing into
@@ -2633,7 +2762,7 @@ v850_output_aligned_bss (file, decl, name, size, align)
int align;
{
(*targetm.asm_out.globalize_label) (file, name);
-
+
switch (v850_get_data_area (decl))
{
case DATA_AREA_ZDA:
@@ -2817,6 +2946,392 @@ v850_insert_attributes (decl, attr_ptr)
}
}
}
+
+/* Return non-zero if the given RTX is suitable
+ for collapsing into a DISPOSE instruction. */
+
+int
+pattern_is_ok_for_dispose (op, mode)
+ rtx op;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+ int count = XVECLEN (op, 0);
+ int i;
+
+ /* If there are no registers to restore then
+ the dispose instruction is not suitable. */
+ if (count <= 2)
+ return 0;
+
+ /* The pattern matching has already established that we are performing a
+ function epilogue and that we are popping at least one register. We must
+ now check the remaining entries in the vector to make sure that they are
+ also register pops. There is no good reason why there should ever be
+ anything else in this vector, but being paranoid always helps...
+
+ The test below performs the C equivalent of this machine description
+ pattern match:
+
+ (set (match_operand:SI n "register_is_ok_for_epilogue" "r")
+ (mem:SI (plus:SI (reg:SI 3)
+ (match_operand:SI n "immediate_operand" "i"))))
+ */
+
+ for (i = 3; i < count; i++)
+ {
+ rtx vector_element = XVECEXP (op, 0, i);
+ rtx dest;
+ rtx src;
+ rtx plus;
+
+ if (GET_CODE (vector_element) != SET)
+ return 0;
+
+ dest = SET_DEST (vector_element);
+ src = SET_SRC (vector_element);
+
+ if ( GET_CODE (dest) != REG
+ || GET_MODE (dest) != SImode
+ || ! register_is_ok_for_epilogue (dest, SImode)
+ || GET_CODE (src) != MEM
+ || GET_MODE (src) != SImode)
+ return 0;
+
+ plus = XEXP (src, 0);
+
+ if ( GET_CODE (plus) != PLUS
+ || GET_CODE (XEXP (plus, 0)) != REG
+ || GET_MODE (XEXP (plus, 0)) != SImode
+ || REGNO (XEXP (plus, 0)) != STACK_POINTER_REGNUM
+ || GET_CODE (XEXP (plus, 1)) != CONST_INT)
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Construct a DISPOSE instruction that is the equivalent of
+ the given RTX. We have already verified that this should
+ be possible. */
+
+char *
+construct_dispose_instruction (op)
+ rtx op;
+{
+ int count = XVECLEN (op, 0);
+ int stack_bytes;
+ unsigned long int mask;
+ int i;
+ static char buff[ 100 ]; /* XXX */
+ int use_callt = 0;
+
+ if (count <= 2)
+ {
+ error ("Bogus DISPOSE construction: %d\n", count);
+ return NULL;
+ }
+
+ /* Work out how many bytes to pop off the
+ stack before retrieving registers. */
+ if (GET_CODE (XVECEXP (op, 0, 1)) != SET)
+ abort ();
+ if (GET_CODE (SET_SRC (XVECEXP (op, 0, 1))) != PLUS)
+ abort ();
+ if (GET_CODE (XEXP (SET_SRC (XVECEXP (op, 0, 1)), 1)) != CONST_INT)
+ abort ();
+
+ stack_bytes = INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 1)), 1));
+
+ /* Each pop will remove 4 bytes from the stack... */
+ stack_bytes -= (count - 2) * 4;
+
+ /* Make sure that the amount we are popping
+ will fit into the DISPOSE instruction. */
+ if (stack_bytes > 128)
+ {
+ error ("Too much stack space to dispose of: %d", stack_bytes);
+ return NULL;
+ }
+
+ /* Now compute the bit mask of registers to push. */
+ mask = 0;
+
+ for (i = 2; i < count; i++)
+ {
+ rtx vector_element = XVECEXP (op, 0, i);
+
+ if (GET_CODE (vector_element) != SET)
+ abort ();
+ if (GET_CODE (SET_DEST (vector_element)) != REG)
+ abort ();
+ if (! register_is_ok_for_epilogue (SET_DEST (vector_element), SImode))
+ abort ();
+
+ if (REGNO (SET_DEST (vector_element)) == 2)
+ use_callt = 1;
+ else
+ mask |= 1 << REGNO (SET_DEST (vector_element));
+ }
+
+ if (! TARGET_DISABLE_CALLT
+ && (use_callt || stack_bytes == 0 || stack_bytes == 16))
+ {
+ if (use_callt)
+ {
+ sprintf (buff, "callt ctoff(__callt_return_r2_r%d)", (mask & (1 << 31)) ? 31 : 29);
+ return buff;
+ }
+ else
+ {
+ for (i = 20; i < 32; i++)
+ if (mask & (1 << i))
+ break;
+
+ if (i == 31)
+ sprintf (buff, "callt ctoff(__callt_return_r31c)");
+ else
+ sprintf (buff, "callt ctoff(__callt_return_r%d_r%d%s)",
+ i, (mask & (1 << 31)) ? 31 : 29, stack_bytes ? "c" : "");
+ }
+ }
+ else
+ {
+ static char regs [100]; /* XXX */
+ int done_one;
+
+ /* Generate the DISPOSE instruction. Note we could just issue the
+ bit mask as a number as the assembler can cope with this, but for
+ the sake of our readers we turn it into a textual description. */
+ regs[0] = 0;
+ done_one = 0;
+
+ for (i = 20; i < 32; i++)
+ {
+ if (mask & (1 << i))
+ {
+ int first;
+
+ if (done_one)
+ strcat (regs, ", ");
+ else
+ done_one = 1;
+
+ first = i;
+ strcat (regs, reg_names[ first ]);
+
+ for (i++; i < 32; i++)
+ if ((mask & (1 << i)) == 0)
+ break;
+
+ if (i > first + 1)
+ {
+ strcat (regs, " - ");
+ strcat (regs, reg_names[ i - 1 ] );
+ }
+ }
+ }
+
+ sprintf (buff, "dispose %d {%s}, r31", stack_bytes / 4, regs);
+ }
+
+ return buff;
+}
+
+/* Return non-zero if the given RTX is suitable
+ for collapsing into a PREPARE instruction. */
+
+int
+pattern_is_ok_for_prepare (op, mode)
+ rtx op;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+ int count = XVECLEN (op, 0);
+ int i;
+
+ /* If there are no registers to restore then the prepare instruction
+ is not suitable. */
+ if (count <= 1)
+ return 0;
+
+ /* The pattern matching has already established that we are adjusting the
+ stack and pushing at least one register. We must now check that the
+ remaining entries in the vector to make sure that they are also register
+ pushes.
+
+ The test below performs the C equivalent of this machine description
+ pattern match:
+
+ (set (mem:SI (plus:SI (reg:SI 3)
+ (match_operand:SI 2 "immediate_operand" "i")))
+ (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))
+
+ */
+
+ for (i = 2; i < count; i++)
+ {
+ rtx vector_element = XVECEXP (op, 0, i);
+ rtx dest;
+ rtx src;
+ rtx plus;
+
+ if (GET_CODE (vector_element) != SET)
+ return 0;
+
+ dest = SET_DEST (vector_element);
+ src = SET_SRC (vector_element);
+
+ if ( GET_CODE (dest) != MEM
+ || GET_MODE (dest) != SImode
+ || GET_CODE (src) != REG
+ || GET_MODE (src) != SImode
+ || ! register_is_ok_for_epilogue (src, SImode)
+ )
+ return 0;
+
+ plus = XEXP (dest, 0);
+
+ if ( GET_CODE (plus) != PLUS
+ || GET_CODE (XEXP (plus, 0)) != REG
+ || GET_MODE (XEXP (plus, 0)) != SImode
+ || REGNO (XEXP (plus, 0)) != STACK_POINTER_REGNUM
+ || GET_CODE (XEXP (plus, 1)) != CONST_INT)
+ return 0;
+
+ /* If the register is being pushed somewhere other than the stack
+ space just aquired by the first operand then abandon this quest.
+ Note: the test is <= becuase both values are negative. */
+ if (INTVAL (XEXP (plus, 1))
+ <= INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1)))
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Construct a PREPARE instruction that is the equivalent of
+ the given RTL. We have already verified that this should
+ be possible. */
+
+char *
+construct_prepare_instruction (op)
+ rtx op;
+{
+ int count = XVECLEN (op, 0);
+ int stack_bytes;
+ unsigned long int mask;
+ int i;
+ static char buff[ 100 ]; /* XXX */
+ int use_callt = 0;
+
+ if (count <= 1)
+ {
+ error ("Bogus PREPEARE construction: %d\n", count);
+ return NULL;
+ }
+
+ /* Work out how many bytes to push onto
+ the stack after storing the registers. */
+ if (GET_CODE (XVECEXP (op, 0, 0)) != SET)
+ abort ();
+ if (GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != PLUS)
+ abort ();
+ if (GET_CODE (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1)) != CONST_INT)
+ abort ();
+
+ stack_bytes = INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1));
+
+ /* Each push will put 4 bytes from the stack. */
+ stack_bytes += (count - 1) * 4;
+
+ /* Make sure that the amount we are popping
+ will fit into the DISPOSE instruction. */
+ if (stack_bytes < -128)
+ {
+ error ("Too much stack space to prepare: %d", stack_bytes);
+ return NULL;
+ }
+
+ /* Now compute the bit mask of registers to push. */
+ mask = 0;
+ for (i = 1; i < count; i++)
+ {
+ rtx vector_element = XVECEXP (op, 0, i);
+
+ if (GET_CODE (vector_element) != SET)
+ abort ();
+ if (GET_CODE (SET_SRC (vector_element)) != REG)
+ abort ();
+ if (! register_is_ok_for_epilogue (SET_SRC (vector_element), SImode))
+ abort ();
+
+ if (REGNO (SET_SRC (vector_element)) == 2)
+ use_callt = 1;
+ else
+ mask |= 1 << REGNO (SET_SRC (vector_element));
+ }
+
+ if ((! TARGET_DISABLE_CALLT)
+ && (use_callt || stack_bytes == 0 || stack_bytes == -16))
+ {
+ if (use_callt)
+ {
+ sprintf (buff, "callt ctoff(__callt_save_r2_r%d)", (mask & (1 << 31)) ? 31 : 29 );
+ return buff;
+ }
+
+ for (i = 20; i < 32; i++)
+ if (mask & (1 << i))
+ break;
+
+ if (i == 31)
+ sprintf (buff, "callt ctoff(__callt_save_r31c)");
+ else
+ sprintf (buff, "callt ctoff(__callt_save_r%d_r%d%s)",
+ i, (mask & (1 << 31)) ? 31 : 29, stack_bytes ? "c" : "");
+ }
+ else
+ {
+ static char regs [100]; /* XXX */
+ int done_one;
+
+
+ /* Generate the PREPARE instruction. Note we could just issue the
+ bit mask as a number as the assembler can cope with this, but for
+ the sake of our readers we turn it into a textual description. */
+ regs[0] = 0;
+ done_one = 0;
+
+ for (i = 20; i < 32; i++)
+ {
+ if (mask & (1 << i))
+ {
+ int first;
+
+ if (done_one)
+ strcat (regs, ", ");
+ else
+ done_one = 1;
+
+ first = i;
+ strcat (regs, reg_names[ first ]);
+
+ for (i++; i < 32; i++)
+ if ((mask & (1 << i)) == 0)
+ break;
+
+ if (i > first + 1)
+ {
+ strcat (regs, " - ");
+ strcat (regs, reg_names[ i - 1 ] );
+ }
+ }
+ }
+
+ sprintf (buff, "prepare {%s}, %d", regs, (- stack_bytes) / 4);
+ }
+
+ return buff;
+}
/* Implement `va_arg'. */
diff --git a/gcc/config/v850/v850.h b/gcc/config/v850/v850.h
index aff42cb319e..e1c33f39937 100644
--- a/gcc/config/v850/v850.h
+++ b/gcc/config/v850/v850.h
@@ -3,22 +3,22 @@
Free Software Foundation, Inc.
Contributed by Jeff Law (law@cygnus.com).
-This file is part of GNU CC.
+ This file is part of GNU CC.
-GNU CC 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 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,
-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.
+ GNU CC 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
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GNU CC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
#ifndef GCC_V850_H
#define GCC_V850_H
@@ -31,8 +31,8 @@ Boston, MA 02111-1307, USA. */
#undef STARTFILE_SPEC
#undef ASM_SPEC
-
#define TARGET_CPU_generic 1
+#define TARGET_CPU_v850e 2
#ifndef TARGET_CPU_DEFAULT
#define TARGET_CPU_DEFAULT TARGET_CPU_generic
@@ -43,9 +43,22 @@ Boston, MA 02111-1307, USA. */
#define SUBTARGET_CPP_SPEC "%{!mv*:-D__v850__}"
#define TARGET_VERSION fprintf (stderr, " (NEC V850)");
+/* Choose which processor will be the default.
+ We must pass a -mv850xx option to the assembler if no explicit -mv* option
+ is given, because the assembler's processor default may not be correct. */
+#if TARGET_CPU_DEFAULT == TARGET_CPU_v850e
+#undef MASK_DEFAULT
+#define MASK_DEFAULT MASK_V850E
+#undef SUBTARGET_ASM_SPEC
+#define SUBTARGET_ASM_SPEC "%{!mv*:-mv850e}"
+#undef SUBTARGET_CPP_SPEC
+#define SUBTARGET_CPP_SPEC "%{!mv*:-D__v850e__}"
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (NEC V850E)");
+#endif
#define ASM_SPEC "%{mv*:-mv%*}"
-#define CPP_SPEC "%{mv850ea:-D__v850ea__} %{mv850e:-D__v850e__} %{mv850:-D__v850__} %(subtarget_cpp_spec)"
+#define CPP_SPEC "%{mv850e:-D__v850e__} %{mv850:-D__v850__} %(subtarget_cpp_spec)"
#define EXTRA_SPECS \
{ "subtarget_asm_spec", SUBTARGET_ASM_SPEC }, \
@@ -67,8 +80,16 @@ extern int target_flags;
#define MASK_CPU 0x00000030
#define MASK_V850 0x00000010
+#define MASK_V850E 0x00000020
+#define MASK_SMALL_SLD 0x00000040
#define MASK_BIG_SWITCH 0x00000100
+#define MASK_NO_APP_REGS 0x00000200
+#define MASK_DISABLE_CALLT 0x00000400
+#define MASK_STRICT_ALIGN 0x00000800
+
+#define MASK_US_BIT_SET 0x00001000
+#define MASK_US_MASK_SET 0x00002000
/* Macros used in the machine description to test the flags. */
@@ -107,8 +128,25 @@ extern int target_flags;
/* Whether to emit 2 byte per entry or 4 byte per entry switch tables. */
#define TARGET_BIG_SWITCH (target_flags & MASK_BIG_SWITCH)
-/* General debug flag */
-#define TARGET_DEBUG (target_flags & MASK_DEBUG)
+/* General debug flag. */
+#define TARGET_DEBUG (target_flags & MASK_DEBUG)
+#define TARGET_V850E ((target_flags & MASK_V850E) == MASK_V850E)
+
+#define TARGET_US_BIT_SET (target_flags & MASK_US_BIT_SET)
+
+/* Whether to assume that the SLD.B and SLD.H instructions only have small
+ displacement fields, thus allowing the generated code to run on any of
+ the V850 range of processors. */
+#define TARGET_SMALL_SLD (target_flags & MASK_SMALL_SLD)
+
+/* True if callt will not be used for function prolog & epilog. */
+#define TARGET_DISABLE_CALLT (target_flags & MASK_DISABLE_CALLT)
+
+/* False if r2 and r5 can be used by the compiler. True if r2
+ and r5 are to be fixed registers (for compatibility with GHS). */
+#define TARGET_NO_APP_REGS (target_flags & MASK_NO_APP_REGS)
+
+#define TARGET_STRICT_ALIGN (target_flags & MASK_STRICT_ALIGN)
/* Macro to define tables used to set the flags.
This is a list in braces of pairs in braces,
@@ -134,6 +172,22 @@ extern int target_flags;
{ "v850", MASK_V850, \
N_("Compile for the v850 processor") }, \
{ "v850", -(MASK_V850 ^ MASK_CPU), "" }, \
+ { "v850e", MASK_V850E, N_("Compile for v850e processor") }, \
+ { "v850e", -(MASK_V850E ^ MASK_CPU), "" }, /* Make sure that the other bits are cleared. */ \
+ { "small-sld", MASK_SMALL_SLD, N_("Enable the use of the short load instructions") }, \
+ { "no-small-sld", -MASK_SMALL_SLD, "" }, \
+ { "disable-callt", MASK_DISABLE_CALLT, \
+ N_("Do not use the callt instruction") }, \
+ { "no-disable-callt", -MASK_DISABLE_CALLT, "" }, \
+ { "US-bit-set", (MASK_US_BIT_SET | MASK_US_MASK_SET), "" }, \
+ { "no-US-bit-set", -MASK_US_BIT_SET, "" }, \
+ { "no-US-bit-set", MASK_US_MASK_SET, "" }, \
+ { "app-regs", -MASK_NO_APP_REGS, "" }, \
+ { "no-app-regs", MASK_NO_APP_REGS, \
+ N_("Do not use registers r2 and r5") }, \
+ { "strict-align", MASK_STRICT_ALIGN, \
+ N_("Enfore strict alignment") }, \
+ { "no-strict-align", -MASK_STRICT_ALIGN, "" }, \
{ "big-switch", MASK_BIG_SWITCH, \
N_("Use 4 byte entries in switch tables") },\
{ "", MASK_DEFAULT, ""}}
@@ -207,6 +261,7 @@ extern struct small_memory_info small_memory[(int)SMALL_MEMORY_max];
#define OPTIMIZATION_OPTIONS(LEVEL,SIZE) \
{ \
+ target_flags |= MASK_STRICT_ALIGN; \
if (LEVEL) \
target_flags |= (MASK_EP | MASK_PROLOG_FUNCTION); \
}
@@ -266,7 +321,7 @@ extern struct small_memory_info small_memory[(int)SMALL_MEMORY_max];
/* Define this if move instructions will actually fail to work
when given unaligned data. */
-#define STRICT_ALIGNMENT 1
+#define STRICT_ALIGNMENT TARGET_STRICT_ALIGN
/* Define this as 1 if `char' should by default be signed; else as 0.
@@ -327,6 +382,17 @@ extern struct small_memory_info small_memory[(int)SMALL_MEMORY_max];
0, 1, 3, 4, 5, 30, 32, 33 /* fixed registers */ \
}
+/* If TARGET_NO_APP_REGS is not defined then add r2 and r5 to
+ the pool of fixed registers. See PR 14505. */
+#define CONDITIONAL_REGISTER_USAGE \
+{ \
+ if (TARGET_NO_APP_REGS) \
+ { \
+ fixed_regs[2] = 1; call_used_regs[2] = 1; \
+ fixed_regs[5] = 1; call_used_regs[5] = 1; \
+ } \
+}
+
/* Return number of consecutive hard regs needed starting at reg REGNO
to hold something of mode MODE.
@@ -457,11 +523,11 @@ enum reg_class
#define CONST_OK_FOR_M(VALUE) ((unsigned)(VALUE) < 0x10000)
/* 5 bit unsigned immediate in shift instructions */
#define CONST_OK_FOR_N(VALUE) ((unsigned) (VALUE) <= 31)
+/* 9 bit signed immediate for word multiply instruction. */
+#define CONST_OK_FOR_O(VALUE) ((unsigned) (VALUE) + 0x100 < 0x200)
-#define CONST_OK_FOR_O(VALUE) 0
#define CONST_OK_FOR_P(VALUE) 0
-
#define CONST_OK_FOR_LETTER_P(VALUE, C) \
((C) == 'I' ? CONST_OK_FOR_I (VALUE) : \
(C) == 'J' ? CONST_OK_FOR_J (VALUE) : \
@@ -851,7 +917,7 @@ extern int current_function_anonymous_args;
((C) == 'Q' ? ep_memory_operand (OP, GET_MODE (OP), 0) \
: (C) == 'R' ? special_symbolref_operand (OP, VOIDmode) \
: (C) == 'S' ? (GET_CODE (OP) == SYMBOL_REF && ! ZDA_NAME_P (XSTR (OP, 0))) \
- : (C) == 'T' ? 0 \
+ : (C) == 'T' ? ep_memory_operand(OP,GET_MODE(OP),TRUE) \
: (C) == 'U' ? ((GET_CODE (OP) == SYMBOL_REF && ZDA_NAME_P (XSTR (OP, 0))) \
|| (GET_CODE (OP) == CONST \
&& GET_CODE (XEXP (OP, 0)) == PLUS \
@@ -989,8 +1055,27 @@ do { \
#define RTX_COSTS(RTX,CODE,OUTER_CODE) \
case MOD: \
case DIV: \
+ case UMOD: \
+ case UDIV: \
+ if (TARGET_V850E && optimize_size) \
+ return 6; \
return 60; \
case MULT: \
+ if (TARGET_V850E \
+ && ( GET_MODE (RTX) == SImode \
+ || GET_MODE (RTX) == HImode \
+ || GET_MODE (RTX) == QImode)) \
+ { \
+ if (GET_CODE (XEXP (RTX, 1)) == REG) \
+ return 4; \
+ else if (GET_CODE (XEXP (RTX, 1)) == CONST_INT) \
+ { \
+ if (CONST_OK_FOR_O (INTVAL (XEXP (RTX, 1)))) \
+ return 6; \
+ else if (CONST_OK_FOR_K (INTVAL (XEXP (RTX, 1)))) \
+ return 10; \
+ } \
+ } \
return 20;
/* All addressing modes have the same cost on the V850 series. */
@@ -1136,17 +1221,9 @@ zbss_section () \
#undef USER_LABEL_PREFIX
#define USER_LABEL_PREFIX "_"
-/* When assemble_integer is used to emit the offsets for a switch
- table it can encounter (TRUNCATE:HI (MINUS:SI (LABEL_REF:SI) (LABEL_REF:SI))).
- output_addr_const will normally barf at this, but it is OK to omit
- the truncate and just emit the difference of the two labels. The
- .hword directive will automatically handle the truncation for us. */
-
-#define OUTPUT_ADDR_CONST_EXTRA(FILE, X, FAIL) \
- if (GET_CODE (x) == TRUNCATE) \
- output_addr_const (FILE, XEXP (X, 0)); \
- else \
- goto FAIL;
+#define OUTPUT_ADDR_CONST_EXTRA(FILE, X, FAIL) \
+ if (! v850_output_addr_const_extra (FILE, X)) \
+ goto FAIL
/* This says how to output the assembler to define a global
uninitialized but not common symbol. */
@@ -1243,10 +1320,12 @@ zbss_section () \
/* This is how to output an element of a case-vector that is relative. */
-#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
- fprintf (FILE, "\t%s .L%d-.L%d\n", \
+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
+ fprintf (FILE, "\t%s %s.L%d-.L%d%s\n", \
(TARGET_BIG_SWITCH ? ".long" : ".short"), \
- VALUE, REL)
+ (! TARGET_BIG_SWITCH && TARGET_V850E ? "(" : ""), \
+ VALUE, REL, \
+ (! TARGET_BIG_SWITCH && TARGET_V850E ? ")>>1" : ""))
#define ASM_OUTPUT_ALIGN(FILE, LOG) \
if ((LOG) != 0) \
@@ -1307,6 +1386,23 @@ zbss_section () \
#define STORE_FLAG_VALUE 1
+#define MULDI3_LIBCALL "__muldi3"
+#define UCMPDI2_LIBCALL "__ucmpdi2"
+#define CMPDI2_LIBCALL "__cmpdi2"
+#define NEGDI2_LIBCALL "__negdi2"
+
+#define INIT_TARGET_OPTABS \
+ do \
+ { \
+ cmp_optab->handlers[(int) DImode].libfunc \
+ = init_one_libfunc (CMPDI2_LIBCALL); \
+ ucmp_optab->handlers[(int) DImode].libfunc \
+ = init_one_libfunc (UCMPDI2_LIBCALL); \
+ neg_optab->handlers[(int) DImode].libfunc \
+ = init_one_libfunc (NEGDI2_LIBCALL); \
+ } \
+ while (0)
+
/* Specify the machine mode that pointers have.
After generation of rtl, the compiler makes no further distinction
between pointers and any other objects of this machine mode. */
@@ -1417,6 +1513,8 @@ extern union tree_node * GHS_current_section_names [(int) COUNT_OF_GHS_SECTION_K
#define PREDICATE_CODES \
{ "reg_or_0_operand", { REG, SUBREG, CONST_INT, CONST_DOUBLE }}, \
{ "reg_or_int5_operand", { REG, SUBREG, CONST_INT }}, \
+{ "reg_or_int9_operand", { REG, SUBREG, CONST_INT }}, \
+{ "reg_or_const_operand", { REG, CONST_INT }}, \
{ "call_address_operand", { REG, SYMBOL_REF }}, \
{ "movsi_source_operand", { LABEL_REF, SYMBOL_REF, CONST_INT, \
CONST_DOUBLE, CONST, HIGH, MEM, \
@@ -1426,6 +1524,9 @@ extern union tree_node * GHS_current_section_names [(int) COUNT_OF_GHS_SECTION_K
{ "pattern_is_ok_for_prologue", { PARALLEL }}, \
{ "pattern_is_ok_for_epilogue", { PARALLEL }}, \
{ "register_is_ok_for_epilogue",{ REG }}, \
+{ "pattern_is_ok_for_dispose", { PARALLEL }}, \
+{ "pattern_is_ok_for_prepare", { PARALLEL }}, \
+{ "register_is_ok_for_dispose", { REG }}, \
{ "not_power_of_two_operand", { CONST_INT }},
#endif /* ! GCC_V850_H */
diff --git a/gcc/config/v850/v850.md b/gcc/config/v850/v850.md
index 354dc111ba4..96ece9cfac6 100644
--- a/gcc/config/v850/v850.md
+++ b/gcc/config/v850/v850.md
@@ -1,5 +1,5 @@
;; GCC machine description for NEC V850
-;; Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+;; Copyright (C) 1996, 1997, 1998, 1999, 2002 Free Software Foundation, Inc.
;; Contributed by Jeff Law (law@cygnus.com).
;; This file is part of GNU CC.
@@ -153,6 +153,7 @@
must be done with HIGH & LO_SUM patterns. */
if (CONSTANT_P (operands[1])
&& GET_CODE (operands[1]) != HIGH
+ && ! TARGET_V850E
&& !special_symbolref_operand (operands[1], VOIDmode)
&& !(GET_CODE (operands[1]) == CONST_INT
&& (CONST_OK_FOR_J (INTVAL (operands[1]))
@@ -174,6 +175,24 @@
}
}")
+;; This is the same as the following pattern, except that it includes
+;; support for arbitrary 32 bit immediates.
+
+;; ??? This always loads addresses using hilo. If the only use of this address
+;; was in a load/store, then we would get smaller code if we only loaded the
+;; upper part with hi, and then put the lower part in the load/store insn.
+
+(define_insn "*movsi_internal_v850e"
+ [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,Q,r,r,m,m,r")
+ (match_operand:SI 1 "general_operand" "Jr,K,L,Q,Ir,m,R,r,I,i"))]
+ "TARGET_V850E
+ && (register_operand (operands[0], SImode)
+ || reg_or_0_operand (operands[1], SImode))"
+ "* return output_move_single (operands);"
+ [(set_attr "length" "2,4,4,2,2,4,4,4,4,6")
+ (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
+ (set_attr "type" "other,other,other,load,other,load,other,other,other,other")])
+
(define_insn "*movsi_internal"
[(set (match_operand:SI 0 "general_operand" "=r,r,r,r,Q,r,r,m,m")
(match_operand:SI 1 "movsi_source_operand" "Jr,K,L,Q,Ir,m,R,r,I"))]
@@ -377,6 +396,93 @@
(set_attr "cc" "none_0hit,none_0hit")
(set_attr "type" "mult")])
+;; ??? The scheduling info is probably wrong.
+
+;; ??? This instruction can also generate the 32 bit highpart, but using it
+;; may increase code size counter to the desired result.
+
+;; ??? This instructions can also give a DImode result.
+
+;; ??? There is unsigned version, but it matters only for the DImode/highpart
+;; results.
+
+(define_insn "mulsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (mult:SI (match_operand:SI 1 "register_operand" "%0")
+ (match_operand:SI 2 "reg_or_int9_operand" "rO")))]
+ "TARGET_V850E"
+ "mul %2,%1,%."
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")
+ (set_attr "type" "mult")])
+
+;; ----------------------------------------------------------------------
+;; DIVIDE INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+;; ??? These insns do set the Z/N condition codes, except that they are based
+;; on only one of the two results, so it doesn't seem to make sense to use
+;; them.
+
+;; ??? The scheduling info is probably wrong.
+
+(define_insn "divmodsi4"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (div:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "register_operand" "r")))
+ (set (match_operand:SI 3 "register_operand" "=r")
+ (mod:SI (match_dup 1)
+ (match_dup 2)))]
+ "TARGET_V850E"
+ "div %2,%0,%3"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")
+ (set_attr "type" "other")])
+
+(define_insn "udivmodsi4"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (udiv:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "register_operand" "r")))
+ (set (match_operand:SI 3 "register_operand" "=r")
+ (umod:SI (match_dup 1)
+ (match_dup 2)))]
+ "TARGET_V850E"
+ "divu %2,%0,%3"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")
+ (set_attr "type" "other")])
+
+;; ??? There is a 2 byte instruction for generating only the quotient.
+;; However, it isn't clear how to compute the length field correctly.
+
+(define_insn "divmodhi4"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (div:HI (match_operand:HI 1 "register_operand" "0")
+ (match_operand:HI 2 "register_operand" "r")))
+ (set (match_operand:HI 3 "register_operand" "=r")
+ (mod:HI (match_dup 1)
+ (match_dup 2)))]
+ "TARGET_V850E"
+ "divh %2,%0,%3"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")
+ (set_attr "type" "other")])
+
+;; Half-words are sign-extended by default, so we must zero extend to a word
+;; here before doing the divide.
+
+(define_insn "udivmodhi4"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (udiv:HI (match_operand:HI 1 "register_operand" "0")
+ (match_operand:HI 2 "register_operand" "r")))
+ (set (match_operand:HI 3 "register_operand" "=r")
+ (umod:HI (match_dup 1)
+ (match_dup 2)))]
+ "TARGET_V850E"
+ "zxh %0 ; divhu %2,%0,%3"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")
+ (set_attr "type" "other")])
;; ----------------------------------------------------------------------
;; AND INSTRUCTIONS
@@ -734,6 +840,243 @@
[(set_attr "length" "4")
(set_attr "cc" "none_0hit")])
+;; ----------------------------------------------------------------------
+;; CONDITIONAL MOVE INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+;; Instructions using cc0 aren't allowed to have input reloads, so we must
+;; hide the fact that this instruction uses cc0. We do so by including the
+;; compare instruction inside it.
+
+;; ??? This is very ugly. The right way to do this is to modify cmpsi so
+;; that it doesn't emit RTL, and then modify the bcc/scc patterns so that
+;; they emit RTL for the compare instruction. Unfortunately, this requires
+;; lots of changes that will be hard to sanitise. So for now, cmpsi still
+;; emits RTL, and I get the compare operands here from the previous insn.
+
+(define_expand "movsicc"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (if_then_else:SI
+ (match_operator 1 "comparison_operator"
+ [(match_dup 4) (match_dup 5)])
+ (match_operand:SI 2 "reg_or_const_operand" "rJ")
+ (match_operand:SI 3 "reg_or_const_operand" "rI")))]
+ "TARGET_V850E"
+ "
+{
+ rtx insn = get_last_insn_anywhere ();
+
+ if ( (GET_CODE (operands[2]) == CONST_INT
+ && GET_CODE (operands[3]) == CONST_INT))
+ {
+ int o2 = INTVAL (operands[2]);
+ int o3 = INTVAL (operands[3]);
+
+ if (o2 == 1 && o3 == 0)
+ FAIL; /* setf */
+ if (o3 == 1 && o2 == 0)
+ FAIL; /* setf */
+ if (o2 == 0 && (o3 < -16 || o3 > 15) && exact_log2 (o3) >= 0)
+ FAIL; /* setf + shift */
+ if (o3 == 0 && (o2 < -16 || o2 > 15) && exact_log2 (o2) >=0)
+ FAIL; /* setf + shift */
+ if (o2 != 0)
+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
+ if (o3 !=0 )
+ operands[3] = copy_to_mode_reg (SImode, operands[3]);
+ }
+ else
+ {
+ if (GET_CODE (operands[2]) != REG)
+ operands[2] = copy_to_mode_reg (SImode,operands[2]);
+ if (GET_CODE (operands[3]) != REG)
+ operands[3] = copy_to_mode_reg (SImode, operands[3]);
+ }
+ if (GET_CODE (insn) == INSN
+ && GET_CODE (PATTERN (insn)) == SET
+ && SET_DEST (PATTERN (insn)) == cc0_rtx)
+ {
+ rtx src = SET_SRC (PATTERN (insn));
+
+ if (GET_CODE (src) == COMPARE)
+ {
+ operands[4] = XEXP (src, 0);
+ operands[5] = XEXP (src, 1);
+ }
+ else if (GET_CODE (src) == REG
+ || GET_CODE (src) == SUBREG)
+ {
+ operands[4] = src;
+ operands[5] = const0_rtx;
+ }
+ else
+ abort ();
+ }
+ else
+ abort ();
+}")
+
+;; ??? Clobbering the condition codes is overkill.
+
+;; ??? We sometimes emit an unnecessary compare instruction because the
+;; condition codes may have already been set by an earlier instruction,
+;; but we have no code here to avoid the compare if it is unnecessary.
+
+(define_insn "*movsicc_normal"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (if_then_else:SI
+ (match_operator 1 "comparison_operator"
+ [(match_operand:SI 4 "register_operand" "r")
+ (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
+ (match_operand:SI 2 "reg_or_int5_operand" "rJ")
+ (match_operand:SI 3 "reg_or_0_operand" "rI")))]
+ "TARGET_V850E"
+ "cmp %5,%4 ; cmov %c1,%2,%z3,%0"
+ [(set_attr "length" "6")
+ (set_attr "cc" "clobber")])
+
+(define_insn "*movsicc_reversed"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (if_then_else:SI
+ (match_operator 1 "comparison_operator"
+ [(match_operand:SI 4 "register_operand" "r")
+ (match_operand:SI 5 "reg_or_int5_operand" "rJ")])
+ (match_operand:SI 2 "reg_or_0_operand" "rI")
+ (match_operand:SI 3 "reg_or_int5_operand" "rJ")))]
+ "TARGET_V850E"
+ "cmp %5,%4 ; cmov %C1,%3,%z2,%0"
+ [(set_attr "length" "6")
+ (set_attr "cc" "clobber")])
+
+(define_insn "*movsicc_tst1"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (if_then_else:SI
+ (match_operator 1 "comparison_operator"
+ [(zero_extract:SI
+ (match_operand:QI 2 "memory_operand" "m")
+ (const_int 1)
+ (match_operand 3 "const_int_operand" "n"))
+ (const_int 0)])
+ (match_operand:SI 4 "reg_or_int5_operand" "rJ")
+ (match_operand:SI 5 "reg_or_0_operand" "rI")))]
+ "TARGET_V850E"
+ "tst1 %3,%2 ; cmov %c1,%4,%z5,%0"
+ [(set_attr "length" "8")
+ (set_attr "cc" "clobber")])
+
+(define_insn "*movsicc_tst1_reversed"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (if_then_else:SI
+ (match_operator 1 "comparison_operator"
+ [(zero_extract:SI
+ (match_operand:QI 2 "memory_operand" "m")
+ (const_int 1)
+ (match_operand 3 "const_int_operand" "n"))
+ (const_int 0)])
+ (match_operand:SI 4 "reg_or_0_operand" "rI")
+ (match_operand:SI 5 "reg_or_int5_operand" "rJ")))]
+ "TARGET_V850E"
+ "tst1 %3,%2 ; cmov %C1,%5,%z4,%0"
+ [(set_attr "length" "8")
+ (set_attr "cc" "clobber")])
+
+;; Matching for sasf requires combining 4 instructions, so we provide a
+;; dummy pattern to match the first 3, which will always be turned into the
+;; second pattern by subsequent combining. As above, we must include the
+;; comparison to avoid input reloads in an insn using cc0.
+
+(define_insn "*sasf_1"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (ior:SI (match_operator 1 "comparison_operator" [(cc0) (const_int 0)])
+ (ashift:SI (match_operand:SI 2 "register_operand" "")
+ (const_int 1))))]
+ "TARGET_V850E"
+ "* abort ();")
+
+(define_insn "*sasf_2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI
+ (match_operator 1 "comparison_operator"
+ [(match_operand:SI 3 "register_operand" "r")
+ (match_operand:SI 4 "reg_or_int5_operand" "rJ")])
+ (ashift:SI (match_operand:SI 2 "register_operand" "0")
+ (const_int 1))))]
+ "TARGET_V850E"
+ "cmp %4,%3 ; sasf %c1,%0"
+ [(set_attr "length" "6")
+ (set_attr "cc" "clobber")])
+
+(define_split
+ [(set (match_operand:SI 0 "register_operand" "")
+ (if_then_else:SI
+ (match_operator 1 "comparison_operator"
+ [(match_operand:SI 4 "register_operand" "")
+ (match_operand:SI 5 "reg_or_int5_operand" "")])
+ (match_operand:SI 2 "const_int_operand" "")
+ (match_operand:SI 3 "const_int_operand" "")))]
+ "TARGET_V850E
+ && ((INTVAL (operands[2]) ^ INTVAL (operands[3])) == 1)
+ && ((INTVAL (operands[2]) + INTVAL (operands[3])) != 1)
+ && (GET_CODE (operands[5]) == CONST_INT
+ || REGNO (operands[0]) != REGNO (operands[5]))
+ && REGNO (operands[0]) != REGNO (operands[4])"
+ [(set (match_dup 0) (match_dup 6))
+ (set (match_dup 0)
+ (ior:SI (match_op_dup 7 [(match_dup 4) (match_dup 5)])
+ (ashift:SI (match_dup 0) (const_int 1))))]
+ "
+{
+ operands[6] = GEN_INT (INTVAL (operands[2]) >> 1);
+ if (INTVAL (operands[2]) & 0x1)
+ operands[7] = operands[1];
+ else
+ operands[7] = gen_rtx (reverse_condition (GET_CODE (operands[1])),
+ GET_MODE (operands[1]), XEXP (operands[1], 0),
+ XEXP (operands[1], 1));
+}")
+;; ---------------------------------------------------------------------
+;; BYTE SWAP INSTRUCTIONS
+;; ---------------------------------------------------------------------
+
+(define_expand "rotlhi3"
+ [(set (match_operand:HI 0 "register_operand" "")
+ (rotate:HI (match_operand:HI 1 "register_operand" "")
+ (match_operand:HI 2 "const_int_operand" "")))]
+ "TARGET_V850E"
+ "
+{
+ if (INTVAL (operands[2]) != 8)
+ FAIL;
+}")
+
+(define_insn "*rotlhi3_8"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (rotate:HI (match_operand:HI 1 "register_operand" "r")
+ (const_int 8)))]
+ "TARGET_V850E"
+ "bsh %1,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_expand "rotlsi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (rotate:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "const_int_operand" "")))]
+ "TARGET_V850E"
+ "
+{
+ if (INTVAL (operands[2]) != 16)
+ FAIL;
+}")
+
+(define_insn "*rotlsi3_16"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (rotate:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int 16)))]
+ "TARGET_V850E"
+ "hsw %1,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
;; ----------------------------------------------------------------------
;; JUMP INSTRUCTIONS
@@ -921,6 +1264,20 @@
[(set_attr "length" "2")
(set_attr "cc" "none")])
+(define_insn "switch"
+ [(set (pc)
+ (plus:SI
+ (sign_extend:SI
+ (mem:HI
+ (plus:SI (ashift:SI (match_operand:SI 0 "register_operand" "r")
+ (const_int 1))
+ (label_ref (match_operand 1 "" "")))))
+ (label_ref (match_dup 1))))]
+ "TARGET_V850E"
+ "switch %0"
+ [(set_attr "length" "2")
+ (set_attr "cc" "none")])
+
(define_expand "casesi"
[(match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "register_operand" "")
@@ -940,6 +1297,12 @@
/* Branch to the default label if out of range of the table. */
emit_jump_insn (gen_bgtu (operands[4]));
+ if (! TARGET_BIG_SWITCH && TARGET_V850E)
+ {
+ emit_jump_insn (gen_switch (reg, operands[3]));
+ DONE;
+ }
+
/* Shift index for the table array access. */
emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1)));
/* Load the table address into a pseudo. */
@@ -1084,6 +1447,18 @@
;; EXTEND INSTRUCTIONS
;; ----------------------------------------------------------------------
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
+ (zero_extend:SI
+ (match_operand:HI 1 "nonimmediate_operand" "0,r,T,m")))]
+ "TARGET_V850E"
+ "@
+ zxh %0
+ andi 65535,%1,%0
+ sld.hu %1,%0
+ ld.hu %1,%0"
+ [(set_attr "length" "2,4,2,4")
+ (set_attr "cc" "none_0hit,set_znv,none_0hit,none_0hit")])
(define_insn "zero_extendhisi2"
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -1094,6 +1469,18 @@
[(set_attr "length" "4")
(set_attr "cc" "set_znv")])
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
+ (zero_extend:SI
+ (match_operand:QI 1 "nonimmediate_operand" "0,r,T,m")))]
+ "TARGET_V850E"
+ "@
+ zxb %0
+ andi 255,%1,%0
+ sld.bu %1,%0
+ ld.bu %1,%0"
+ [(set_attr "length" "2,4,2,4")
+ (set_attr "cc" "none_0hit,set_znv,none_0hit,none_0hit")])
(define_insn "zero_extendqisi2"
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -1106,6 +1493,18 @@
;;- sign extension instructions
+;; ??? The extendhisi2 pattern should not emit shifts for v850e?
+
+(define_insn "*extendhisi_insn"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,Q,m")))]
+ "TARGET_V850E"
+ "@
+ sxh %0
+ sld.h %1,%0
+ ld.h %1,%0"
+ [(set_attr "length" "2,2,4")
+ (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
;; ??? This is missing a sign extend from memory pattern to match the ld.h
;; instruction.
@@ -1124,6 +1523,18 @@
operands[2] = gen_reg_rtx (SImode);
}")
+;; ??? The extendqisi2 pattern should not emit shifts for v850e?
+
+(define_insn "*extendqisi_insn"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,Q,m")))]
+ "TARGET_V850E"
+ "@
+ sxb %0
+ sld.b %1,%0
+ ld.b %1,%0"
+ [(set_attr "length" "2,2,4")
+ (set_attr "cc" "none_0hit,none_0hit,none_0hit")])
;; ??? This is missing a sign extend from memory pattern to match the ld.b
;; instruction.
@@ -1229,6 +1640,21 @@
;; RTXs. These RTXs will then be turned into a suitable call to a worker
;; function.
+;;
+;; Actually, convert the RTXs into a PREPARE instruction.
+;;
+(define_insn ""
+ [(match_parallel 0 "pattern_is_ok_for_prepare"
+ [(set (reg:SI 3)
+ (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
+ (set (mem:SI (plus:SI (reg:SI 3)
+ (match_operand:SI 2 "immediate_operand" "i")))
+ (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
+ "TARGET_PROLOG_FUNCTION && TARGET_V850E"
+ "* return construct_prepare_instruction (operands[0]);
+ "
+ [(set_attr "length" "4")
+ (set_attr "cc" "none")])
(define_insn ""
[(match_parallel 0 "pattern_is_ok_for_prologue"
@@ -1245,6 +1671,23 @@
(const_string "4")))
(set_attr "cc" "clobber")])
+;;
+;; Actually, turn the RTXs into a DISPOSE instruction.
+;;
+(define_insn ""
+ [(match_parallel 0 "pattern_is_ok_for_dispose"
+ [(return)
+ (set (reg:SI 3)
+ (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
+ (set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")
+ (mem:SI (plus:SI (reg:SI 3)
+ (match_operand:SI 3 "immediate_operand" "i"))))])]
+ "TARGET_PROLOG_FUNCTION && TARGET_V850E"
+ "* return construct_dispose_instruction (operands[0]);
+ "
+ [(set_attr "length" "4")
+ (set_attr "cc" "none")])
+
;; This pattern will match a return RTX followed by any number of pop RTXs
;; and possible a stack adjustment as well. These RTXs will be turned into
;; a suitable call to a worker function.
@@ -1266,31 +1709,95 @@
(set_attr "cc" "clobber")])
;; Initialize an interrupt function. Do not depend on TARGET_PROLOG_FUNCTION.
+(define_insn "callt_save_interrupt"
+ [(unspec_volatile [(const_int 0)] 2)]
+ "TARGET_V850E && !TARGET_DISABLE_CALLT"
+ ;; The CALLT instruction stores the next address of CALLT to CTPC register
+ ;; without saving its previous value. So if the interrupt handler
+ ;; or its caller could possibily execute the CALLT insn, save_interrupt
+ ;; MUST NOT be called via CALLT.
+ "*
+{
+ output_asm_insn (\"addi -24, sp, sp\", operands);
+ output_asm_insn (\"st.w r10, 12[sp]\", operands);
+ output_asm_insn (\"stsr ctpc, r10\", operands);
+ output_asm_insn (\"st.w r10, 16[sp]\", operands);
+ output_asm_insn (\"stsr ctpsw, r10\", operands);
+ output_asm_insn (\"st.w r10, 20[sp]\", operands);
+ output_asm_insn (\"callt ctoff(__callt_save_interrupt)\", operands);
+ return \"\";
+}"
+ [(set_attr "length" "26")
+ (set_attr "cc" "none")])
+
+(define_insn "callt_return_interrupt"
+ [(unspec_volatile [(const_int 0)] 3)]
+ "TARGET_V850E && !TARGET_DISABLE_CALLT"
+ "callt ctoff(__callt_return_interrupt)"
+ [(set_attr "length" "2")
+ (set_attr "cc" "clobber")])
+
(define_insn "save_interrupt"
[(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -16)))
- (set (mem:SI (reg:SI 3)) (reg:SI 30))
- (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 10))
- (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 4))
- (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))]
- "TARGET_V850 && ! TARGET_LONG_CALLS"
- "add -16, sp ; st.w r10, 12[sp] ; jarl __save_interrupt, r10"
- [(set_attr "length" "12")
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 30))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 4))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 1))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 10))]
+ ""
+ "*
+{
+ if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
+ return \"add -16,sp\;st.w r10,12[sp]\;jarl __save_interrupt,r10\";
+ else
+ {
+ output_asm_insn (\"add -16, sp\", operands);
+ output_asm_insn (\"st.w r10, 12[sp]\", operands);
+ output_asm_insn (\"st.w ep, 0[sp]\", operands);
+ output_asm_insn (\"st.w gp, 4[sp]\", operands);
+ output_asm_insn (\"st.w r1, 8[sp]\", operands);
+ output_asm_insn (\"movhi hi(__ep), r0, ep\", operands);
+ output_asm_insn (\"movea lo(__ep), ep, ep\", operands);
+ output_asm_insn (\"movhi hi(__gp), r0, gp\", operands);
+ output_asm_insn (\"movea lo(__gp), gp, gp\", operands);
+ return \"\";
+ }
+}"
+ [(set (attr "length")
+ (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
+ (const_int 10)
+ (const_int 34)))
(set_attr "cc" "clobber")])
-
+
;; Restore r1, r4, r10, and return from the interrupt
-(define_insn "restore_interrupt"
+(define_insn "return_interrupt"
[(return)
- (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 16)))
- (set (reg:SI 30) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
- (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
- (set (reg:SI 4) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))
- (set (reg:SI 1) (mem:SI (reg:SI 3)))]
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 16)))
+ (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
+ (set (reg:SI 1) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
+ (set (reg:SI 4) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))
+ (set (reg:SI 30) (mem:SI (reg:SI 3)))]
""
- "jr __return_interrupt"
- [(set_attr "length" "4")
+ "*
+{
+ if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
+ return \"jr __return_interrupt\";
+ else
+ {
+ output_asm_insn (\"ld.w 0[sp], ep\", operands);
+ output_asm_insn (\"ld.w 4[sp], gp\", operands);
+ output_asm_insn (\"ld.w 8[sp], r1\", operands);
+ output_asm_insn (\"ld.w 12[sp], r10\", operands);
+ output_asm_insn (\"addi 16, sp, sp\", operands);
+ output_asm_insn (\"reti\", operands);
+ return \"\";
+ }
+}"
+ [(set (attr "length")
+ (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
+ (const_int 4)
+ (const_int 24)))
(set_attr "cc" "clobber")])
-
;; Save all registers except for the registers saved in save_interrupt when
;; an interrupt function makes a call.
;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
@@ -1298,28 +1805,148 @@
;; This is needed because the rest of the compiler is not ready to handle
;; insns this complicated.
+(define_insn "callt_save_all_interrupt"
+ [(unspec_volatile [(const_int 0)] 0)]
+ "TARGET_V850E && !TARGET_DISABLE_CALLT"
+ "callt ctoff(__callt_save_all_interrupt)"
+ [(set_attr "length" "2")
+ (set_attr "cc" "none")])
+
(define_insn "save_all_interrupt"
[(unspec_volatile [(const_int 0)] 0)]
+ ""
+ "*
+{
+ if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
+ return \"jarl __save_all_interrupt,r10\";
+
+ output_asm_insn (\"addi -120, sp, sp\", operands);
+ output_asm_insn (\"mov ep, r1\", operands);
+ output_asm_insn (\"mov sp, ep\", operands);
+ output_asm_insn (\"sst.w r31, 116[ep]\", operands);
+ output_asm_insn (\"sst.w r2, 112[ep]\", operands);
+ output_asm_insn (\"sst.w gp, 108[ep]\", operands);
+ output_asm_insn (\"sst.w r6, 104[ep]\", operands);
+ output_asm_insn (\"sst.w r7, 100[ep]\", operands);
+ output_asm_insn (\"sst.w r8, 96[ep]\", operands);
+ output_asm_insn (\"sst.w r9, 92[ep]\", operands);
+ output_asm_insn (\"sst.w r11, 88[ep]\", operands);
+ output_asm_insn (\"sst.w r12, 84[ep]\", operands);
+ output_asm_insn (\"sst.w r13, 80[ep]\", operands);
+ output_asm_insn (\"sst.w r14, 76[ep]\", operands);
+ output_asm_insn (\"sst.w r15, 72[ep]\", operands);
+ output_asm_insn (\"sst.w r16, 68[ep]\", operands);
+ output_asm_insn (\"sst.w r17, 64[ep]\", operands);
+ output_asm_insn (\"sst.w r18, 60[ep]\", operands);
+ output_asm_insn (\"sst.w r19, 56[ep]\", operands);
+ output_asm_insn (\"sst.w r20, 52[ep]\", operands);
+ output_asm_insn (\"sst.w r21, 48[ep]\", operands);
+ output_asm_insn (\"sst.w r22, 44[ep]\", operands);
+ output_asm_insn (\"sst.w r23, 40[ep]\", operands);
+ output_asm_insn (\"sst.w r24, 36[ep]\", operands);
+ output_asm_insn (\"sst.w r25, 32[ep]\", operands);
+ output_asm_insn (\"sst.w r26, 28[ep]\", operands);
+ output_asm_insn (\"sst.w r27, 24[ep]\", operands);
+ output_asm_insn (\"sst.w r28, 20[ep]\", operands);
+ output_asm_insn (\"sst.w r29, 16[ep]\", operands);
+ output_asm_insn (\"mov r1, ep\", operands);
+ return \"\";
+}"
+ [(set (attr "length")
+ (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
+ (const_int 4)
+ (const_int 62)
+ ))
+ (set_attr "cc" "clobber")])
+
+(define_insn "_save_all_interrupt"
+ [(unspec_volatile [(const_int 0)] 0)]
"TARGET_V850 && ! TARGET_LONG_CALLS"
"jarl __save_all_interrupt,r10"
[(set_attr "length" "4")
(set_attr "cc" "clobber")])
-
;; Restore all registers saved when an interrupt function makes a call.
;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
;; all of memory. This blocks insns from being moved across this point.
;; This is needed because the rest of the compiler is not ready to handle
;; insns this complicated.
+(define_insn "callt_restore_all_interrupt"
+ [(unspec_volatile [(const_int 0)] 1)]
+ "TARGET_V850E && !TARGET_DISABLE_CALLT"
+ "callt ctoff(__callt_restore_all_interrupt)"
+ [(set_attr "length" "2")
+ (set_attr "cc" "none")])
+
(define_insn "restore_all_interrupt"
[(unspec_volatile [(const_int 0)] 1)]
+ ""
+ "*
+{
+ if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)
+ return \"jarl __restore_all_interrupt,r10\";
+ else
+ {
+ output_asm_insn (\"mov ep, r1\", operands);
+ output_asm_insn (\"mov sp, ep\", operands);
+ output_asm_insn (\"sld.w 116[ep], r31\", operands);
+ output_asm_insn (\"sld.w 112[ep], r2\", operands);
+ output_asm_insn (\"sld.w 108[ep], gp\", operands);
+ output_asm_insn (\"sld.w 104[ep], r6\", operands);
+ output_asm_insn (\"sld.w 100[ep], r7\", operands);
+ output_asm_insn (\"sld.w 96[ep], r8\", operands);
+ output_asm_insn (\"sld.w 92[ep], r9\", operands);
+ output_asm_insn (\"sld.w 88[ep], r11\", operands);
+ output_asm_insn (\"sld.w 84[ep], r12\", operands);
+ output_asm_insn (\"sld.w 80[ep], r13\", operands);
+ output_asm_insn (\"sld.w 76[ep], r14\", operands);
+ output_asm_insn (\"sld.w 72[ep], r15\", operands);
+ output_asm_insn (\"sld.w 68[ep], r16\", operands);
+ output_asm_insn (\"sld.w 64[ep], r17\", operands);
+ output_asm_insn (\"sld.w 60[ep], r18\", operands);
+ output_asm_insn (\"sld.w 56[ep], r19\", operands);
+ output_asm_insn (\"sld.w 52[ep], r20\", operands);
+ output_asm_insn (\"sld.w 48[ep], r21\", operands);
+ output_asm_insn (\"sld.w 44[ep], r22\", operands);
+ output_asm_insn (\"sld.w 40[ep], r23\", operands);
+ output_asm_insn (\"sld.w 36[ep], r24\", operands);
+ output_asm_insn (\"sld.w 32[ep], r25\", operands);
+ output_asm_insn (\"sld.w 28[ep], r26\", operands);
+ output_asm_insn (\"sld.w 24[ep], r27\", operands);
+ output_asm_insn (\"sld.w 20[ep], r28\", operands);
+ output_asm_insn (\"sld.w 16[ep], r29\", operands);
+ output_asm_insn (\"mov r1, ep\", operands);
+ output_asm_insn (\"addi 120, sp, sp\", operands);
+ return \"\";
+ }
+}"
+ [(set (attr "length")
+ (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0))
+ (const_int 4)
+ (const_int 62)
+ ))
+ (set_attr "cc" "clobber")])
+
+(define_insn "_restore_all_interrupt"
+ [(unspec_volatile [(const_int 0)] 1)]
"TARGET_V850 && ! TARGET_LONG_CALLS"
"jarl __restore_all_interrupt,r10"
[(set_attr "length" "4")
(set_attr "cc" "clobber")])
;; Save r6-r9 for a variable argument function
+(define_insn "save_r6_r9_v850e"
+ [(set (mem:SI (reg:SI 3)) (reg:SI 6))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9))
+ ]
+ "TARGET_PROLOG_FUNCTION && TARGET_V850E && !TARGET_DISABLE_CALLT"
+ "callt ctoff(__callt_save_r6_r9)"
+ [(set_attr "length" "2")
+ (set_attr "cc" "none")])
+
(define_insn "save_r6_r9"
[(set (mem:SI (reg:SI 3)) (reg:SI 6))
(set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7))
diff --git a/gcc/config/vax/vax.h b/gcc/config/vax/vax.h
index 80fbd4770a8..702125da6a0 100644
--- a/gcc/config/vax/vax.h
+++ b/gcc/config/vax/vax.h
@@ -1028,7 +1028,7 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
/* This is BSD, so it wants DBX format. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
/* Do not break .stabs pseudos into continuations. */
diff --git a/gcc/config/vax/vaxv.h b/gcc/config/vax/vaxv.h
index 7b8e7fff5ff..7b322307ba0 100644
--- a/gcc/config/vax/vaxv.h
+++ b/gcc/config/vax/vaxv.h
@@ -35,7 +35,7 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_IDENT(FILE, NAME) fprintf (FILE, "\t.ident \"%s\"\n", NAME);
#undef DBX_DEBUGGING_INFO
-#define SDB_DEBUGGING_INFO
+#define SDB_DEBUGGING_INFO 1
#undef LIB_SPEC