diff options
author | dnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-09-04 01:37:44 +0000 |
---|---|---|
committer | dnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-09-04 01:37:44 +0000 |
commit | c5cc674a6c755c0fce26956c01ed5f0d3c8af53a (patch) | |
tree | 4e5bb3c9ea566fec6a9b8765feea6eebb0b413b0 /gcc/config | |
parent | 9e20f2157d6f65ba22c9a53712fa4f170de1a738 (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')
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 |