Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff -burN orig.gcc-3.2.3/config.sub gcc-3.2.3/config.sub
- --- orig.gcc-3.2.3/config.sub 2003-01-30 18:32:36.000000000 -0400
- +++ gcc-3.2.3/config.sub 2007-07-26 13:04:40.000000000 -0300
- @@ -236,6 +236,7 @@
- | i370 | i860 | i960 | ia64 \
- | ip2k \
- | m32r | m68000 | m68k | m88k | mcore \
- + | mips64r5900 | mips64r5900el \
- | mips | mipsbe | mipseb | mipsel | mipsle \
- | mips16 \
- | mips64 | mips64el \
- @@ -308,6 +309,7 @@
- | m32r-* \
- | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | mcore-* \
- + | mips64r5900-* | mips64r5900el-* \
- | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
- | mips16-* \
- | mips64-* | mips64el-* \
- @@ -594,6 +596,10 @@
- basic_machine=i386-unknown
- os=-vsta
- ;;
- + iop)
- + basic_machine=mipsel-scei
- + os=-irx
- + ;;
- iris | iris4d)
- basic_machine=mips-sgi
- case $os in
- @@ -630,6 +636,16 @@
- basic_machine=m68k-atari
- os=-mint
- ;;
- + mipsEE* | ee | ps2)
- + basic_machine=mips64r5900el-scei
- + case $os in
- + -linux*)
- + ;;
- + *)
- + os=-elf
- + ;;
- + esac
- + ;;
- mips3*-*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
- ;;
- @@ -1118,7 +1134,8 @@
- | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
- | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
- | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
- - | -powermax* | -dnix* | -microbsd*)
- + | -powermax* | -dnix* | -microbsd* \
- + | -irx* )
- # Remember, each alternative MUST END IN *, to match a version number.
- ;;
- -qnx*)
- diff -burN orig.gcc-3.2.3/configure gcc-3.2.3/configure
- --- orig.gcc-3.2.3/configure 2002-06-24 13:14:28.000000000 -0300
- +++ gcc-3.2.3/configure 2007-07-26 13:04:40.000000000 -0300
- @@ -89,7 +89,7 @@
- target_alias=NOTARGET
- target_makefile_frag=
- undefs=NOUNDEFS
- -version="$Revision: 1.40.6.3 $"
- +version="$Revision: 1.8 $"
- x11=default
- bindir='${exec_prefix}/bin'
- sbindir='${exec_prefix}/sbin'
- @@ -697,7 +697,7 @@
- if test -f skip-this-dir; then
- # Perform the same cleanup as the trap handler, minus the "exit 1" of course,
- # and reset the trap handler.
- - trap 0
- + trap - 0
- rm -rf Makefile* ${tmpdir}
- # Execute the final clean-up actions
- ${config_shell} skip-this-dir
- @@ -1615,7 +1615,7 @@
- # Perform the same cleanup as the trap handler, minus the "exit 1" of course,
- # and reset the trap handler.
- rm -rf ${tmpdir}
- -trap 0
- +trap - 0
- exit 0
- diff -burN orig.gcc-3.2.3/configure.in gcc-3.2.3/configure.in
- --- orig.gcc-3.2.3/configure.in 2002-07-08 07:00:57.000000000 -0300
- +++ gcc-3.2.3/configure.in 2007-07-26 13:04:40.000000000 -0300
- @@ -980,6 +980,9 @@
- mips*-*-linux*)
- noconfigdirs="$noconfigdirs target-libffi"
- ;;
- + mipsel-*-irx*)
- + noconfigdirs="$noconfigdirs target-libiberty target-newlib target-libgloss target-libstdc++-v3 ${libgcj}"
- + ;;
- mips*-*-*)
- noconfigdirs="$noconfigdirs gprof ${libgcj}"
- ;;
- diff -burN orig.gcc-3.2.3/gcc/caller-save.c gcc-3.2.3/gcc/caller-save.c
- --- orig.gcc-3.2.3/gcc/caller-save.c 2002-01-01 18:22:25.000000000 -0400
- +++ gcc-3.2.3/gcc/caller-save.c 2007-07-26 13:04:40.000000000 -0300
- @@ -50,13 +50,21 @@
- If that is not possible the save is done one register at a time. */
- static enum machine_mode
- +#if TARGET_MIPS5900
- + regno_save_mode[FIRST_PSEUDO_REGISTER][16 / MIN_UNITS_PER_WORD + 1];
- +#else
- regno_save_mode[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1];
- +#endif
- /* For each hard register, a place on the stack where it can be saved,
- if needed. */
- static rtx
- +#if TARGET_MIPS5900
- + regno_save_mem[FIRST_PSEUDO_REGISTER][16 / MIN_UNITS_PER_WORD + 1];
- +#else
- regno_save_mem[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1];
- +#endif
- /* We will only make a register eligible for caller-save if it can be
- saved in its widest mode with a simple SET insn as long as the memory
- diff -burN orig.gcc-3.2.3/gcc/c-common.c gcc-3.2.3/gcc/c-common.c
- --- orig.gcc-3.2.3/gcc/c-common.c 2002-12-01 14:19:08.000000000 -0400
- +++ gcc-3.2.3/gcc/c-common.c 2007-07-26 13:04:40.000000000 -0300
- @@ -1336,6 +1336,9 @@
- if (bits <= TYPE_PRECISION (intDI_type_node))
- return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
- + if (bits <= TYPE_PRECISION (intTI_type_node))
- + return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
- +
- return 0;
- }
- @@ -1379,10 +1382,8 @@
- if (mode == DImode)
- return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
- -#if HOST_BITS_PER_WIDE_INT >= 64
- if (mode == TYPE_MODE (intTI_type_node))
- return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
- -#endif
- if (mode == TYPE_MODE (float_type_node))
- return float_type_node;
- @@ -1449,10 +1450,8 @@
- return long_long_unsigned_type_node;
- if (type1 == widest_integer_literal_type_node)
- return widest_unsigned_literal_type_node;
- -#if HOST_BITS_PER_WIDE_INT >= 64
- if (type1 == intTI_type_node)
- return unsigned_intTI_type_node;
- -#endif
- if (type1 == intDI_type_node)
- return unsigned_intDI_type_node;
- if (type1 == intSI_type_node)
- @@ -1484,10 +1483,8 @@
- return long_long_integer_type_node;
- if (type1 == widest_unsigned_literal_type_node)
- return widest_integer_literal_type_node;
- -#if HOST_BITS_PER_WIDE_INT >= 64
- if (type1 == unsigned_intTI_type_node)
- return intTI_type_node;
- -#endif
- if (type1 == unsigned_intDI_type_node)
- return intDI_type_node;
- if (type1 == unsigned_intSI_type_node)
- @@ -1527,10 +1524,8 @@
- return (unsignedp ? widest_unsigned_literal_type_node
- : widest_integer_literal_type_node);
- -#if HOST_BITS_PER_WIDE_INT >= 64
- if (TYPE_PRECISION (type) == TYPE_PRECISION (intTI_type_node))
- return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
- -#endif
- if (TYPE_PRECISION (type) == TYPE_PRECISION (intDI_type_node))
- return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
- if (TYPE_PRECISION (type) == TYPE_PRECISION (intSI_type_node))
- @@ -2576,16 +2571,12 @@
- pushdecl (build_decl (TYPE_DECL, NULL_TREE, intHI_type_node));
- pushdecl (build_decl (TYPE_DECL, NULL_TREE, intSI_type_node));
- pushdecl (build_decl (TYPE_DECL, NULL_TREE, intDI_type_node));
- -#if HOST_BITS_PER_WIDE_INT >= 64
- pushdecl (build_decl (TYPE_DECL, get_identifier ("__int128_t"), intTI_type_node));
- -#endif
- pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intQI_type_node));
- pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intHI_type_node));
- pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intSI_type_node));
- pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intDI_type_node));
- -#if HOST_BITS_PER_WIDE_INT >= 64
- pushdecl (build_decl (TYPE_DECL, get_identifier ("__uint128_t"), unsigned_intTI_type_node));
- -#endif
- /* Create the widest literal types. */
- widest_integer_literal_type_node
- diff -burN orig.gcc-3.2.3/gcc/config/i386/xm-mingw32.h gcc-3.2.3/gcc/config/i386/xm-mingw32.h
- --- orig.gcc-3.2.3/gcc/config/i386/xm-mingw32.h 2002-01-10 18:21:39.000000000 -0400
- +++ gcc-3.2.3/gcc/config/i386/xm-mingw32.h 2007-07-26 13:04:51.000000000 -0300
- @@ -31,3 +31,143 @@
- #undef PATH_SEPARATOR
- #define PATH_SEPARATOR ';'
- +
- +/* This describes the machine the compiler is hosted on. */
- +#define HOST_BITS_PER_CHAR CHAR_BIT
- +#define HOST_BITS_PER_SHORT (CHAR_BIT * SIZEOF_SHORT)
- +#define HOST_BITS_PER_INT (CHAR_BIT * SIZEOF_INT)
- +#define HOST_BITS_PER_LONG (CHAR_BIT * SIZEOF_LONG)
- +
- +#ifdef HAVE_LONG_LONG
- +# define HOST_BITS_PER_LONGLONG (CHAR_BIT * SIZEOF_LONG_LONG)
- +#else
- +#ifdef HAVE___INT64
- +# define HOST_BITS_PER_LONGLONG (CHAR_BIT * SIZEOF___INT64)
- +#else
- +/* If we're here and we're GCC, assume this is stage 2+ of a bootstrap
- + and 'long long' has the width of the *target*'s long long. */
- +# if GCC_VERSION > 3000
- +# define HOST_BITS_PER_LONGLONG LONG_LONG_TYPE_SIZE
- +# endif /* gcc */
- +#endif
- +#endif /* no long long */
- +
- +/* Find the largest host integer type and set its size and type. */
- +
- +/* Use long long on the host if the target has a wider long type than
- + the host. */
- +
- +#if ! defined HOST_BITS_PER_WIDE_INT \
- + && defined HOST_BITS_PER_LONGLONG \
- + && (HOST_BITS_PER_LONGLONG > HOST_BITS_PER_LONG) \
- + && (defined (LONG_LONG_MAX) || defined (LONGLONG_MAX) \
- + || defined (LLONG_MAX) || defined (__GNUC__))
- +
- +# ifdef MAX_LONG_TYPE_SIZE
- +# if MAX_LONG_TYPE_SIZE > HOST_BITS_PER_LONG
- +# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONGLONG
- +# define HOST_WIDE_INT long long
- +# endif
- +# else
- +# if LONG_TYPE_SIZE > HOST_BITS_PER_LONG
- +# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONGLONG
- +# define HOST_WIDE_INT long long
- +# endif
- +# endif
- +
- +#endif
- +
- +#ifndef HOST_BITS_PER_WIDE_INT
- +
- +# if HOST_BITS_PER_LONG > HOST_BITS_PER_INT
- +# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG
- +# define HOST_WIDE_INT long
- +# else
- +# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_INT
- +# define HOST_WIDE_INT int
- +# endif
- +
- +#endif /* ! HOST_BITS_PER_WIDE_INT */
- +
- +/* Provide defaults for the way to print a HOST_WIDE_INT
- + in various manners. */
- +
- +#ifndef HOST_WIDE_INT_PRINT_DEC
- +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
- +# define HOST_WIDE_INT_PRINT_DEC "%d"
- +# else
- +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
- +# define HOST_WIDE_INT_PRINT_DEC "%ld"
- +# else
- +# define HOST_WIDE_INT_PRINT_DEC "%I64d"
- +# endif
- +# endif
- +#endif /* ! HOST_WIDE_INT_PRINT_DEC */
- +
- +#ifndef HOST_WIDE_INT_PRINT_UNSIGNED
- +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
- +# define HOST_WIDE_INT_PRINT_UNSIGNED "%u"
- +# else
- +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
- +# define HOST_WIDE_INT_PRINT_UNSIGNED "%lu"
- +# else
- +# define HOST_WIDE_INT_PRINT_UNSIGNED "%I64u"
- +# endif
- +# endif
- +#endif /* ! HOST_WIDE_INT_PRINT_UNSIGNED */
- +
- +#ifndef HOST_WIDE_INT_PRINT_HEX
- +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
- +# define HOST_WIDE_INT_PRINT_HEX "0x%x"
- +# else
- +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
- +# define HOST_WIDE_INT_PRINT_HEX "0x%lx"
- +# else
- +# define HOST_WIDE_INT_PRINT_HEX "0x%I64x"
- +# endif
- +# endif
- +#endif /* ! HOST_WIDE_INT_PRINT_HEX */
- +
- +#ifndef HOST_WIDE_INT_PRINT_DOUBLE_HEX
- +# if HOST_BITS_PER_WIDE_INT == 64
- +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
- +# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%x%016x"
- +# else
- +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
- +# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%lx%016lx"
- +# else
- +# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%llx%016llx"
- +# endif
- +# endif
- +# else
- +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
- +# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%x%08x"
- +# else
- +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
- +# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%lx%08lx"
- +# else
- +# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%llx%08llx"
- +# endif
- +# endif
- +# endif
- +#endif /* ! HOST_WIDE_INT_PRINT_DOUBLE_HEX */
- +
- +/* Find HOST_WIDEST_INT and set its bit size, type and print macros.
- + It will be the largest integer mode supported by the host which may
- + (or may not) be larger than HOST_WIDE_INT. */
- +
- +#ifndef HOST_WIDEST_INT
- +#if defined HOST_BITS_PER_LONGLONG && HOST_BITS_PER_LONGLONG > HOST_BITS_PER_LONG
- +# define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER_LONGLONG
- +# define HOST_WIDEST_INT __int64
- +# define HOST_WIDEST_INT_PRINT_DEC "%I64d"
- +# define HOST_WIDEST_INT_PRINT_UNSIGNED "%I64u"
- +# define HOST_WIDEST_INT_PRINT_HEX "0x%I64x"
- +# else
- +# define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER_LONG
- +# define HOST_WIDEST_INT long
- +# define HOST_WIDEST_INT_PRINT_DEC "%ld"
- +# define HOST_WIDEST_INT_PRINT_UNSIGNED "%lu"
- +# define HOST_WIDEST_INT_PRINT_HEX "0x%lx"
- +# endif /* long long wider than long */
- +#endif /* ! HOST_WIDEST_INT */
- diff -burN orig.gcc-3.2.3/gcc/config/mips/core-mmi.h gcc-3.2.3/gcc/config/mips/core-mmi.h
- --- orig.gcc-3.2.3/gcc/config/mips/core-mmi.h 1969-12-31 20:00:00.000000000 -0400
- +++ gcc-3.2.3/gcc/config/mips/core-mmi.h 2007-07-26 13:04:40.000000000 -0300
- @@ -0,0 +1,104 @@
- +/*
- + * mmi-intrinsics.h - R5900 MMI compiler intrinsics.
- + *
- + * Copyright (c) 2003 M. R. Brown <mrbrown@0xd6.org>
- + *
- + * This file is licensed under the GNU GPL version 2.
- + *
- + * As a special exception, if you include this header file into source
- + * files compiled by GCC, this header file does not by itself cause
- + * the resulting executable to be covered by the GNU General Public
- + * License. This exception does not however invalidate any other
- + * reasons why the executable file might be covered by the GNU General
- + * Public License.
- + *
- + */
- +
- +/* Based off of the mmintrin.h file in GCC 3.2.1 */
- +
- +#ifndef __mmi_intrinsics_h
- +#define __mmi_intrinsics_h
- +
- +/* This for user programs. */
- +typedef int __m128 __attribute__ ((mode(TI)));
- +
- +#define __vector __attribute__((vector_size(16)))
- +
- +/* These are internal. */
- +typedef int __v16qi __attribute__ ((mode(V16QI)));
- +typedef int __v8hi __attribute__ ((mode(V8HI)));
- +typedef int __v4si __attribute__ ((mode(V4SI)));
- +
- +#if !defined(__u128)
- +typedef unsigned int __u128 __attribute__((mode(TI)));
- +#endif
- +#if !defined(__s128)
- +typedef __signed__ int __s128 __attribute__((mode(TI)));
- +#endif
- +
- +/* Convert i to a __m128 object. The integer is zero-extended to 128-bits. */
- +/* XXX: No, not really. Figure out why. */
- +static __inline __m128 _mmi_cvtsi32_si128(int i)
- +{
- + __u128 tmp = (unsigned int)i;
- + return (__m128)tmp;
- +}
- +
- +/* Add the 8-bit values in m1 to the 8-bit values in m2. */
- +
- +static inline __m128
- +_mmi_paddb(__m128 m1, __m128 m2)
- +{
- + return (__m128) __builtin_mmi_paddb((__v16qi)m1, (__v16qi)m2);
- +}
- +
- +/* Creates a vector of two 64-bit values; d0 is least significant. */
- +static inline __m128
- +_mmi_create_vec64(long d1, long d0)
- +{
- + union {
- + __m128 q;
- + struct {
- + unsigned long d0;
- + unsigned long d1;
- + } s;
- + } u;
- +
- + u.s.d0 = d0;
- + u.s.d1 = d1;
- + return u.q;
- +}
- +
- +/* Convienence routines for creating vectors. */
- +
- +/* Creates a vector of 4 32-bit values; w0 is least significant. */
- +static inline __m128
- +_mmi_create_vec32(int w3, int w2, int w1, int w0)
- +{
- + unsigned long d1 = (unsigned int)w3 << 32 | (unsigned int)w2;
- + unsigned long d0 = (unsigned int)w1 << 32 | (unsigned int)w0;
- + return _mmi_create_vec64(d1, d0);
- +}
- +
- +/* Creates a vector of 8 16-bit values; h0 is least significant. */
- +static inline __m128
- +_mmi_create_vec16(short h7, short h6, short h5, short h4,
- + short h3, short h2, short h1, short h0)
- +{
- + unsigned long d1, d0;
- +
- + d1 = (unsigned short)h7;
- + d1 = d1 << 16 | (unsigned short)h6;
- + d1 = d1 << 16 | (unsigned short)h5;
- + d1 = d1 << 16 | (unsigned short)h4;
- +
- + d0 = (unsigned short)h3;
- + d0 = d0 << 16 | (unsigned short)h2;
- + d0 = d0 << 16 | (unsigned short)h1;
- + d0 = d0 << 16 | (unsigned short)h0;
- +
- + return _mmi_create_vec64(d1, d0);
- +}
- +
- +#endif /* __mmi_intrinsics_h */
- +
- diff -burN orig.gcc-3.2.3/gcc/config/mips/core-vumm.h gcc-3.2.3/gcc/config/mips/core-vumm.h
- --- orig.gcc-3.2.3/gcc/config/mips/core-vumm.h 1969-12-31 20:00:00.000000000 -0400
- +++ gcc-3.2.3/gcc/config/mips/core-vumm.h 2007-07-26 13:04:40.000000000 -0300
- @@ -0,0 +1 @@
- +#define __THIS__IS__A__BLANK__FILE__
- diff -burN orig.gcc-3.2.3/gcc/config/mips/crti5900.asm gcc-3.2.3/gcc/config/mips/crti5900.asm
- --- orig.gcc-3.2.3/gcc/config/mips/crti5900.asm 1969-12-31 20:00:00.000000000 -0400
- +++ gcc-3.2.3/gcc/config/mips/crti5900.asm 2007-07-26 13:04:40.000000000 -0300
- @@ -0,0 +1,16 @@
- +/* 4 slots for argument spill area. 1 for cpreturn, 1 for stack.
- + Return spill offset of 80. */
- +
- + .section .init,"ax",@progbits
- + .globl _init
- + .type _init,@function
- +_init:
- + addu $sp,$sp,-96
- + sq $31,80($sp)
- +
- + .section .fini,"ax",@progbits
- + .globl _fini
- + .type _fini,@function
- +_fini:
- + addu $sp,$sp,-96
- + sq $31,80($sp)
- diff -burN orig.gcc-3.2.3/gcc/config/mips/crtn5900.asm gcc-3.2.3/gcc/config/mips/crtn5900.asm
- --- orig.gcc-3.2.3/gcc/config/mips/crtn5900.asm 1969-12-31 20:00:00.000000000 -0400
- +++ gcc-3.2.3/gcc/config/mips/crtn5900.asm 2007-07-26 13:04:40.000000000 -0300
- @@ -0,0 +1,12 @@
- +/* 4 slots for argument spill area. 1 for cpreturn, 1 for stack.
- + Return spill offset of 80. */
- +
- + .section .init,"ax",@progbits
- + lq $31,80($sp)
- + addu $sp,$sp,96
- + j $31
- +
- + .section .fini,"ax",@progbits
- + lq $31,80($sp)
- + addu $sp,$sp,96
- + j $31
- diff -burN orig.gcc-3.2.3/gcc/config/mips/mips.c gcc-3.2.3/gcc/config/mips/mips.c
- --- orig.gcc-3.2.3/gcc/config/mips/mips.c 2002-07-26 20:23:02.000000000 -0300
- +++ gcc-3.2.3/gcc/config/mips/mips.c 2015-08-10 16:10:25 +0300
- @@ -51,6 +51,7 @@
- #include "gstab.h"
- #include "hashtab.h"
- #include "debug.h"
- +#include "optabs.h"
- #include "target.h"
- #include "target-def.h"
- @@ -102,6 +103,7 @@
- int, int));
- static void mips_emit_frame_related_store PARAMS ((rtx, rtx,
- HOST_WIDE_INT));
- +static void mips_check_reg_mode PARAMS ((rtx, rtx, void *));
- static void save_restore_insns PARAMS ((int, rtx,
- long, FILE *));
- static void mips16_output_gp_offset PARAMS ((FILE *, rtx));
- @@ -135,6 +137,23 @@
- #endif
- static int mips_adjust_cost PARAMS ((rtx, rtx, rtx, int));
- +/* R5900 (Emotion Engine) support. */
- +static enum sequence_type r5900_detect_sequence_type PARAMS ((rtx, int *, rtx *,
- + int *, int));
- +static void r5900_lengthen_loops PARAMS ((rtx, int));
- +static void r5900_sched_init PARAMS ((void));
- +static void mips_sched_init PARAMS ((FILE *, int, int));
- +static void r5900_sched_reorder PARAMS ((FILE *, int, rtx *, int));
- +static int mips_sched_reorder PARAMS ((FILE *, int, rtx *,
- + int *, int));
- +static void r5900_init_builtins PARAMS ((void));
- +static rtx r5900_expand_binop_builtin PARAMS ((enum insn_code, tree,
- + rtx));
- +static rtx r5900_expand_builtin PARAMS ((tree, rtx));
- +static rtx mips_expand_builtin PARAMS ((tree, rtx, rtx,
- + enum machine_mode, int));
- +static void mips_init_builtins PARAMS ((void));
- +
- /* Global variables for machine-dependent things. */
- /* Threshold for data being put into the small data/bss area, instead
- @@ -232,6 +251,8 @@
- /* which abi to use. */
- int mips_abi;
- +int mips_alignment;
- +
- /* Strings to hold which cpu and instruction set architecture to use. */
- const char *mips_cpu_string; /* for -mcpu=<xxx> */
- const char *mips_arch_string; /* for -march=<xxx> */
- @@ -253,6 +274,18 @@
- set this option if such an option is used. */
- const char *mips_explicit_type_size_string;
- +#ifdef DEFAULT_MIPS_ALIGNMENT
- +int mips_alignment=DEFAULT_MIPS_ALIGNMENT; /* biggest alignment bits */
- +#else
- +int mips_alignment=BIGGEST_ALIGNMENT; /* biggest alignment bits */
- +#endif
- +const char * mips_no_align128_string;
- +const char * mips_align128_string;
- +const char * mips_use_128_string;
- +const char * mips_align_all_string;
- +int mips_align_all = 1;
- +int mips_use_128 = 0;
- +
- /* Whether we are generating mips16 hard float code. In mips16 mode
- we always set TARGET_SOFT_FLOAT; this variable is nonzero if
- -msoft-float was not specified by the user, which means that we
- @@ -280,8 +313,11 @@
- initialized in override_options. */
- REAL_VALUE_TYPE dfhigh, dflow, sfhigh, sflow;
- -/* Mode used for saving/restoring general purpose registers. */
- -static enum machine_mode gpr_mode;
- +/* The mode that will be used to save a given gpr on the stack. Note
- + the entry for $0 is special; it indicates the generic size of a gpr
- + save/restore by the prologue/epilogue and must be the maximum mode
- + ever used to save a GPR. This is typically WORD_MODE. */
- +enum machine_mode mips_reg_mode[GP_REG_NUM];
- /* Array giving truth value on whether or not a given hard register
- can support a given mode. */
- @@ -343,7 +379,8 @@
- "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
- "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
- "hi", "lo", "accum","$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
- - "$fcc5","$fcc6","$fcc7","$rap"
- + "$fcc5","$fcc6","$fcc7","$rap",
- + "hi1", "lo1", "accum1"
- };
- /* Mips software names for the registers, used to overwrite the
- @@ -360,7 +397,8 @@
- "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
- "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
- "hi", "lo", "accum","$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
- - "$fcc5","$fcc6","$fcc7","$rap"
- + "$fcc5","$fcc6","$fcc7","$rap",
- + "hi1", "lo1", "accum1"
- };
- /* Map hard register number to register class */
- @@ -384,7 +422,8 @@
- FP_REGS, FP_REGS, FP_REGS, FP_REGS,
- HI_REG, LO_REG, HILO_REG, ST_REGS,
- ST_REGS, ST_REGS, ST_REGS, ST_REGS,
- - ST_REGS, ST_REGS, ST_REGS, GR_REGS
- + ST_REGS, ST_REGS, ST_REGS, GR_REGS,
- + HI1_REG, LO1_REG, HILO1_REG
- };
- /* Map register constraint character to register class. */
- @@ -479,6 +518,18 @@
- #undef TARGET_SCHED_ADJUST_COST
- #define TARGET_SCHED_ADJUST_COST mips_adjust_cost
- +#undef TARGET_SCHED_INIT
- +#define TARGET_SCHED_INIT mips_sched_init
- +
- +#undef TARGET_SCHED_REORDER
- +#define TARGET_SCHED_REORDER mips_sched_reorder
- +
- +#undef TARGET_INIT_BUILTINS
- +#define TARGET_INIT_BUILTINS mips_init_builtins
- +
- +#undef TARGET_EXPAND_BUILTIN
- +#define TARGET_EXPAND_BUILTIN mips_expand_builtin
- +
- struct gcc_target targetm = TARGET_INITIALIZER;
- /* Return truth value of whether OP can be used as an operands
- @@ -1111,6 +1162,38 @@
- && ! mips16_constant (op, mode, 1, 0)));
- }
- +/* Return truth value of whether OP is a register, a memory operand,
- + or a constant. This is used by the r5900 lq/sq support. */
- +
- +int
- +movti_operand (op, mode)
- + rtx op;
- + enum machine_mode mode;
- +{
- + switch (GET_CODE (op))
- + {
- + case CONST_INT:
- + if (TARGET_MIPS16)
- + return FALSE;
- + return TRUE;
- +
- + case CONST_DOUBLE:
- + if (TARGET_MIPS16 || GET_MODE (op) != VOIDmode)
- + return FALSE;
- + return TRUE;
- +
- + case REG:
- + case SUBREG:
- + return register_operand (op, mode);
- +
- + case MEM:
- + return memory_operand (op, mode);
- +
- + default:
- + return FALSE;
- + }
- +}
- +
- /* Like register_operand, but when in 64 bit mode also accept a sign
- extend of a 32 bit register, since the value is known to be already
- sign extended. */
- @@ -1315,6 +1398,7 @@
- accept (subreg (const_int)) which will fail to reload. */
- if (CONSTANT_ADDRESS_P (xinsn)
- && ! (mips_split_addresses && mips_check_split (xinsn, mode))
- + && ! (TARGET_MIPS5900 && mode == TImode)
- && (! TARGET_MIPS16 || mips16_constant (xinsn, mode, 1, 0)))
- return 1;
- @@ -1651,7 +1735,7 @@
- if (type == DELAY_LOAD || type == DELAY_FCMP)
- num_nops = 1;
- - else if (type == DELAY_HILO)
- + else if (type == DELAY_HILO || type == DELAY_HILO1)
- num_nops = 2;
- else
- @@ -1663,6 +1747,7 @@
- next_insn = NEXT_INSN (next_insn);
- dslots_load_total += num_nops;
- +
- if (TARGET_DEBUG_F_MODE
- || !optimize
- || type == DELAY_NONE
- @@ -1701,6 +1786,11 @@
- mips_load_reg3 = gen_rtx_REG (SImode, MD_REG_FIRST);
- mips_load_reg4 = gen_rtx_REG (SImode, MD_REG_FIRST+1);
- }
- + else if (type == DELAY_HILO1)
- + {
- + mips_load_reg3 = gen_rtx_REG (SImode, MD1_REG_FIRST);
- + mips_load_reg4 = gen_rtx_REG (SImode, MD1_REG_FIRST+1);
- + }
- else
- {
- mips_load_reg3 = 0;
- @@ -1935,6 +2025,15 @@
- ret = "mflo\t%0";
- }
- + else if (MD1_REG_P (regno1))
- + {
- + delay = DELAY_HILO1;
- + if (regno1 != HILO1_REGNUM)
- + ret = "mf%1\t%0";
- + else
- + ret = "mflo1\t%0";
- + }
- +
- else if (ST_REG_P (regno1) && ISA_HAS_8CC)
- ret = "li\t%0,1\n\tmovf\t%0,%.,%1";
- @@ -1971,6 +2070,16 @@
- }
- }
- + else if (MD1_REG_P (regno0))
- + {
- + if (GP_REG_P (regno1))
- + {
- + delay = DELAY_HILO1;
- + if (regno0 != HILO1_REGNUM && ! TARGET_MIPS16)
- + ret = "mt%0\t%1";
- + }
- + }
- +
- else if (regno0 == FPSW_REGNUM && ! ISA_HAS_8CC)
- {
- if (GP_REG_P (regno1))
- @@ -2056,6 +2165,12 @@
- delay = DELAY_HILO;
- ret = "mt%0\t%.";
- }
- +
- + else if (MD1_REG_P (regno0))
- + {
- + delay = DELAY_HILO1;
- + ret = "mt%0\t%.";
- + }
- }
- else if (GP_REG_P (regno0))
- @@ -2390,6 +2505,20 @@
- ret = "mthi\t%M1\n\tmtlo\t%L1";
- }
- + else if (MD1_REG_P (regno0) && GP_REG_P (regno1) && !TARGET_MIPS16)
- + {
- + delay = DELAY_HILO1;
- + if (TARGET_64BIT)
- + {
- + if (regno0 != HILO1_REGNUM)
- + ret = "mt%0\t%1";
- + else if (regno1 == 0)
- + ret = "mtlo%H0\t%.\n\tmthi%H0\t%.";
- + }
- + else
- + ret = "mthi%H0\t%M1\n\tmtlo%H0\t%L1";
- + }
- +
- else if (GP_REG_P (regno0) && MD_REG_P (regno1))
- {
- delay = DELAY_HILO;
- @@ -2402,6 +2531,18 @@
- ret = "mfhi\t%M0\n\tmflo\t%L0";
- }
- + else if (GP_REG_P (regno0) && MD1_REG_P (regno1))
- + {
- + delay = DELAY_HILO1;
- + if (TARGET_64BIT)
- + {
- + if (regno1 != HILO1_REGNUM)
- + ret = "mf%1\t%0";
- + }
- + else
- + ret = "mfhi%H1\t%M0\n\tmflo%H1\t%L0";
- + }
- +
- else if (TARGET_64BIT)
- ret = "move\t%0,%1";
- @@ -2507,6 +2648,14 @@
- ? "mtlo\t%.\n\tmthi\t%."
- : "mt%0\t%.\n");
- }
- +
- + else if (MD1_REG_P (regno0))
- + {
- + delay = DELAY_HILO1;
- + ret = (regno0 == HILO1_REGNUM
- + ? "mtlo%H0\t%.\n\tmthi%H0\t%."
- + : "mt%0\t%.\n");
- + }
- }
- else if (code1 == CONST_INT && GET_MODE (op0) == DImode
- @@ -4015,6 +4164,14 @@
- cum->gp_reg_found = 1;
- cum->arg_words++;
- break;
- +
- + case V16QImode:
- + case V8HImode:
- + case V4SImode:
- + if (! TARGET_MMI)
- + abort ();
- + cum->gp_reg_found = 1;
- + cum->arg_words++;
- }
- }
- @@ -4135,6 +4292,15 @@
- if (! TARGET_64BIT)
- cum->arg_words += (cum->arg_words & 1);
- regbase = GP_ARG_FIRST;
- + break;
- +
- + case V4SImode:
- + case V8HImode:
- + case V16QImode:
- + if (! TARGET_MMI)
- + abort ();
- + regbase = GP_ARG_FIRST;
- +
- }
- if (*arg_words >= (unsigned) MAX_ARGS_IN_REGISTERS)
- @@ -4311,6 +4477,7 @@
- int named ATTRIBUTE_UNUSED;/* != 0 for normal args, == 0 for ... args */
- {
- if ((mode == BLKmode
- + || (mode == TImode && TARGET_MIPS5900)
- || GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
- || GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
- && cum->arg_words < (unsigned) MAX_ARGS_IN_REGISTERS
- @@ -4851,6 +5018,14 @@
- target_flags &= ~((TARGET_DEFAULT) & (MASK_SOFT_FLOAT | MASK_SINGLE_FLOAT));
- #endif
- + if (mips_align_all_string == 0)
- + mips_align_all = 1;
- +
- + else if (ISDIGIT (*mips_align_all_string))
- + {
- + mips_align_all = atoi (mips_align_all_string);
- + }
- +
- /* Get the architectural level. */
- if (mips_isa_string == 0)
- mips_isa = MIPS_ISA_DEFAULT;
- @@ -5081,6 +5256,10 @@
- }
- }
- + /* Humf... */
- + if (mips_arch == PROCESSOR_R3000)
- + mips_isa = 1;
- +
- /* make sure sizes of ints/longs/etc. are ok */
- if (! ISA_HAS_64BIT_REGS)
- {
- @@ -5234,6 +5413,10 @@
- mips_char_to_class['l'] = LO_REG;
- mips_char_to_class['a'] = HILO_REG;
- mips_char_to_class['x'] = MD_REGS;
- + mips_char_to_class['u'] = HI1_REG;
- + mips_char_to_class['v'] = LO1_REG;
- + mips_char_to_class['q'] = HILO1_REG;
- + mips_char_to_class['w'] = MD1_REGS;
- mips_char_to_class['b'] = ALL_REGS;
- mips_char_to_class['y'] = GR_REGS;
- mips_char_to_class['z'] = ST_REGS;
- @@ -5279,6 +5462,10 @@
- || FP_REG_P (regno));
- }
- + /* General registers can hold TImode values on the r5900. */
- + else if (GP_REG_P (regno) && mode == TImode && TARGET_MIPS5900)
- + temp = 1;
- +
- else if (GP_REG_P (regno))
- temp = ((regno & 1) == 0 || size <= UNITS_PER_WORD);
- @@ -5302,6 +5489,12 @@
- || (regno == MD_REG_FIRST
- && size == 2 * UNITS_PER_WORD)));
- + else if (MD1_REG_P (regno))
- + temp = (class == MODE_INT
- + && (size <= UNITS_PER_WORD
- + || (regno == MD1_REG_FIRST
- + && size == 2 * UNITS_PER_WORD)));
- +
- else
- temp = 0;
- @@ -5311,9 +5504,18 @@
- /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
- initialized yet, so we can't use that here. */
- - gpr_mode = TARGET_64BIT ? DImode : SImode;
- + for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
- + {
- + mips_reg_mode[regno] = TARGET_64BIT ? DImode : SImode;
- + }
- +
- + /* Saves/restores of general purpose registers on the r5900 use
- + a mode wider than word_mode. */
- + if (TARGET_MIPS5900)
- + mips_reg_mode[0] = TImode;
- /* Provide default values for align_* for 64-bit targets. */
- + /* XXX: fix this up for the r5900. */
- if (TARGET_64BIT && !TARGET_MIPS16)
- {
- if (align_loops == 0)
- @@ -5324,6 +5526,21 @@
- align_functions = 8;
- }
- +#ifdef DEFAULT_MIPS_ALIGNMENT
- + if (mips_align128_string != NULL) {
- + /* -malign128 */
- + mips_alignment=128;
- + }
- + if (mips_no_align128_string != NULL) {
- + /* -mno-align128 */
- + mips_alignment=64;
- + }
- +#endif
- +
- + if (mips_use_128_string != NULL) {
- + mips_use_128=1;
- + }
- +
- /* Register global variables with the garbage collector. */
- mips_add_gc_roots ();
- }
- @@ -5425,6 +5642,7 @@
- 'M' print high-order register of double-word register operand.
- 'C' print part of opcode for a branch condition.
- 'F' print part of opcode for a floating-point branch condition.
- + 'H' print the appropiate Integer pipe # for r5900 mult/div instructions.
- 'N' print part of opcode for a branch condition, inverted.
- 'W' print part of opcode for a floating-point branch condition, inverted.
- 'S' X is CODE_LABEL, print with prefix of "LS" (for embedded switch).
- @@ -5649,7 +5867,17 @@
- default:
- abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%W");
- }
- + else if (letter == 'H')
- + {
- + if (true_regnum (op) >= MD_REG_FIRST
- + && true_regnum (op) <= MD_REG_LAST)
- + ;
- +
- + else if (true_regnum (op) >= MD1_REG_FIRST
- + && true_regnum (op) <= MD1_REG_LAST)
- + fputs ("1", file);
- + }
- else if (letter == 'S')
- {
- char buffer[100];
- @@ -5673,6 +5901,16 @@
- fprintf (file, "%s,", reg_names[regnum]);
- }
- + else if ((letter == 'L' || letter == 'M')
- + && code == CONST_DOUBLE
- + && GET_MODE (op) == VOIDmode)
- + {
- + if (letter == 'L')
- + fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (op));
- + else
- + fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_HIGH (op));
- + }
- +
- else if (code == REG || code == SUBREG)
- {
- register int regnum;
- @@ -6144,8 +6382,7 @@
- || (mips_load_reg != 0 && reg_mentioned_p (mips_load_reg, pattern))
- || (mips_load_reg2 != 0 && reg_mentioned_p (mips_load_reg2, pattern))
- || (mips_load_reg3 != 0 && reg_mentioned_p (mips_load_reg3, pattern))
- - || (mips_load_reg4 != 0
- - && reg_mentioned_p (mips_load_reg4, pattern)))
- + || (mips_load_reg4 != 0 && reg_mentioned_p (mips_load_reg4, pattern)))
- fputs ("\t#nop\n", asm_out_file);
- else
- @@ -6343,6 +6580,27 @@
- }
- }
- +void
- +mips_declare_object_align (stream, name, init_string, final_string, size, align)
- + FILE *stream;
- + const char *name;
- + const char *init_string;
- + const char *final_string;
- + int size;
- + int align;
- +{
- + fputs (init_string, stream); /* "", "\t.comm\t", or "\t.lcomm\t" */
- + assemble_name (stream, name);
- + fprintf (stream, final_string, size, align); /* ":\n", ",%u\n", ",%u\n" */
- +
- + if (TARGET_GP_OPT)
- + {
- + tree name_tree = get_identifier (name);
- + TREE_ASM_WRITTEN (name_tree) = 1;
- + }
- +}
- +
- +
- /* Return the bytes needed to compute the frame pointer from the current
- stack pointer.
- @@ -6455,7 +6713,7 @@
- || (GET_MODE_SIZE (DECL_MODE (DECL_RESULT (current_function_decl)))
- <= 4))))
- {
- - gp_reg_size += GET_MODE_SIZE (gpr_mode);
- + gp_reg_size += GET_MODE_SIZE (mips_reg_mode[0]);
- mask |= 1L << (regno - GP_REG_FIRST);
- /* The entry and exit pseudo instructions can not save $17
- @@ -6479,7 +6737,7 @@
- regno = EH_RETURN_DATA_REGNO (i);
- if (regno == INVALID_REGNUM)
- break;
- - gp_reg_size += GET_MODE_SIZE (gpr_mode);
- + gp_reg_size += GET_MODE_SIZE (mips_reg_mode[0]);
- mask |= 1L << (regno - GP_REG_FIRST);
- }
- }
- @@ -6561,9 +6819,9 @@
- top of the stack. */
- if (! mips_entry)
- offset = (args_size + extra_size + var_size
- - + gp_reg_size - GET_MODE_SIZE (gpr_mode));
- + + gp_reg_size - GET_MODE_SIZE (mips_reg_mode[0]));
- else
- - offset = total_size - GET_MODE_SIZE (gpr_mode);
- + offset = total_size - GET_MODE_SIZE (mips_reg_mode[0]);
- current_frame_info.gp_sp_offset = offset;
- current_frame_info.gp_save_offset = offset - total_size;
- @@ -6699,6 +6957,24 @@
- mips_annotate_frame_insn (emit_move_insn (mem, reg), dwarf_expr);
- }
- +/* If modifying X uses a larger mode than in mips_reg_mode,
- + indicate that fact by setting mips_reg_mode. */
- +
- +static void
- +mips_check_reg_mode (x, set, data)
- + rtx x;
- + rtx set ATTRIBUTE_UNUSED;
- + void *data ATTRIBUTE_UNUSED;
- +{
- + if (GET_CODE (x) == REG
- + && REGNO (x) <= GP_REG_LAST
- + && (GET_MODE_SIZE (GET_MODE (x))
- + > GET_MODE_SIZE (mips_reg_mode[REGNO (x)])))
- + {
- + mips_reg_mode[REGNO (x)] = GET_MODE (x);
- + }
- +}
- +
- static void
- save_restore_insns (store_p, large_reg, large_offset, file)
- int store_p; /* true if this is prologue */
- @@ -6735,6 +7011,47 @@
- need a nop in the epilog if at least one register is reloaded in
- addition to return address. */
- + if (TARGET_MIPS5900 && store_p)
- + {
- + rtx insn;
- + tree attr;
- +
- + for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn))
- + {
- + if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
- + note_stores (PATTERN (insn), mips_check_reg_mode, NULL);
- + }
- +
- + if ((attr = lookup_attribute
- + ("register_precision", DECL_ATTRIBUTES (current_function_decl)))
- + != 0)
- + for (; attr; attr = TREE_CHAIN (attr))
- + {
- + const char *reg_expr = IDENTIFIER_POINTER (TREE_VALUE (TREE_VALUE (attr)));
- + tree reg_length = TREE_VALUE (TREE_CHAIN (TREE_VALUE (attr)));
- + enum machine_mode mode = VOIDmode;
- + int j;
- + switch (TREE_INT_CST_LOW (reg_length))
- + {
- + case 32:
- + mode= SImode;
- + break;
- + case 64:
- + mode= DImode;
- + break;
- + case 128:
- + mode= TImode;
- + break;
- + }
- +
- + if ((j = decode_reg_name (reg_expr)) >= 0)
- + {
- + if (j != 0)
- + mips_reg_mode[j] = mode;
- + }
- + }
- + }
- +
- /* Save GP registers if needed. */
- if (mask)
- {
- @@ -6747,7 +7064,7 @@
- gp_offset = current_frame_info.gp_sp_offset;
- end_offset
- = gp_offset - (current_frame_info.gp_reg_size
- - - GET_MODE_SIZE (gpr_mode));
- + - GET_MODE_SIZE (mips_reg_mode[0]));
- if (gp_offset < 0 || end_offset < 0)
- internal_error
- @@ -6810,7 +7127,8 @@
- {
- rtx reg_rtx;
- rtx mem_rtx
- - = gen_rtx (MEM, gpr_mode,
- + = gen_rtx (MEM,
- + mips_reg_mode[regno],
- gen_rtx (PLUS, Pmode, base_reg_rtx,
- GEN_INT (gp_offset - base_offset)));
- @@ -6821,23 +7139,24 @@
- $31, so we load $7 instead, and work things out
- in mips_expand_epilogue. */
- if (TARGET_MIPS16 && ! store_p && regno == GP_REG_FIRST + 31)
- - reg_rtx = gen_rtx (REG, gpr_mode, GP_REG_FIRST + 7);
- + reg_rtx = gen_rtx (REG, mips_reg_mode[7], GP_REG_FIRST + 7);
- /* The mips16 sometimes needs to save $18. */
- else if (TARGET_MIPS16
- && regno != GP_REG_FIRST + 31
- && ! M16_REG_P (regno))
- {
- if (! store_p)
- - reg_rtx = gen_rtx (REG, gpr_mode, 6);
- + reg_rtx = gen_rtx (REG, mips_reg_mode[6], 6);
- else
- {
- - reg_rtx = gen_rtx (REG, gpr_mode, 3);
- + reg_rtx = gen_rtx (REG, mips_reg_mode[3], 3);
- emit_move_insn (reg_rtx,
- - gen_rtx (REG, gpr_mode, regno));
- + gen_rtx (REG, mips_reg_mode[regno],
- + regno));
- }
- }
- else
- - reg_rtx = gen_rtx (REG, gpr_mode, regno);
- + reg_rtx = gen_rtx (REG, mips_reg_mode[regno], regno);
- if (store_p)
- mips_emit_frame_related_store (mem_rtx, reg_rtx, gp_offset);
- @@ -6847,7 +7166,7 @@
- if (TARGET_MIPS16
- && regno != GP_REG_FIRST + 31
- && ! M16_REG_P (regno))
- - emit_move_insn (gen_rtx (REG, gpr_mode, regno),
- + emit_move_insn (gen_rtx (REG, mips_reg_mode[regno], regno),
- reg_rtx);
- }
- }
- @@ -6889,13 +7208,13 @@
- fprintf (file, "\tmove\t%s,%s\n",
- reg_names[regno], reg_names[r]);
- }
- - gp_offset -= GET_MODE_SIZE (gpr_mode);
- + gp_offset -= GET_MODE_SIZE (mips_reg_mode[0]);
- }
- /* If the restore is being supressed, still take into account
- the offset at which it is stored. */
- else if (BITSET_P (real_mask, regno - GP_REG_FIRST))
- {
- - gp_offset -= GET_MODE_SIZE (gpr_mode);
- + gp_offset -= GET_MODE_SIZE (mips_reg_mode[0]);
- }
- }
- else
- @@ -6920,13 +7239,13 @@
- base_reg_rtx = stack_pointer_rtx, base_offset = 0;
- else if (base_reg_rtx != 0
- - && (unsigned HOST_WIDE_INT) (base_offset - fp_offset) < 32768
- - && (unsigned HOST_WIDE_INT) (base_offset - end_offset) < 32768)
- + && (((unsigned HOST_WIDE_INT) (base_offset - fp_offset)) < 32768)
- + && (((unsigned HOST_WIDE_INT) (base_offset - end_offset)) < 32768))
- ; /* already set up for gp registers above */
- else if (large_reg != 0
- - && (unsigned HOST_WIDE_INT) (large_offset - fp_offset) < 32768
- - && (unsigned HOST_WIDE_INT) (large_offset - end_offset) < 32768)
- + && (((unsigned HOST_WIDE_INT) (large_offset - fp_offset)) < 32768)
- + && (((unsigned HOST_WIDE_INT) (large_offset - end_offset)) < 32768))
- {
- base_reg_rtx = gen_rtx_REG (Pmode, MIPS_TEMP2_REGNUM);
- base_offset = large_offset;
- @@ -7358,10 +7677,10 @@
- {
- if (offset != 0)
- ptr = gen_rtx (PLUS, Pmode, stack_pointer_rtx, GEN_INT (offset));
- - emit_move_insn (gen_rtx (MEM, gpr_mode, ptr),
- - gen_rtx (REG, gpr_mode, regno));
- + emit_move_insn (gen_rtx (MEM, mips_reg_mode[regno], ptr),
- + gen_rtx (REG, mips_reg_mode[regno], regno));
- - offset += GET_MODE_SIZE (gpr_mode);
- + offset += GET_MODE_SIZE (mips_reg_mode[0]);
- }
- }
- @@ -7406,7 +7725,8 @@
- moment. */
- if (TARGET_MIPS16 && BITSET_P (current_frame_info.mask, 18))
- {
- - rtx reg_rtx = gen_rtx (REG, gpr_mode, GP_REG_FIRST + 3);
- + rtx reg_rtx = gen_rtx (REG, mips_reg_mode[GP_REG_FIRST + 3],
- + GP_REG_FIRST + 3);
- long gp_offset, base_offset;
- gp_offset = current_frame_info.gp_sp_offset;
- @@ -7422,8 +7742,9 @@
- base_offset = 0;
- start_sequence ();
- emit_move_insn (reg_rtx,
- - gen_rtx (REG, gpr_mode, GP_REG_FIRST + 18));
- - emit_move_insn (gen_rtx (MEM, gpr_mode,
- + gen_rtx (REG, mips_reg_mode[GP_REG_FIRST + 18],
- + GP_REG_FIRST + 18));
- + emit_move_insn (gen_rtx (MEM, mips_reg_mode[GP_REG_FIRST + 18],
- gen_rtx (PLUS, Pmode, stack_pointer_rtx,
- GEN_INT (gp_offset
- - base_offset))),
- @@ -8153,6 +8474,11 @@
- if (type == NULL_TREE || mode == DImode || mode == DFmode)
- return 0;
- + /* The r5900 can pass TImode values in a single register, so
- + there is no need to pass it by reference. */
- + if (mode == TImode && TARGET_MIPS5900)
- + return 0;
- +
- size = int_size_in_bytes (type);
- return size == -1 || size > UNITS_PER_WORD;
- }
- @@ -8213,15 +8539,30 @@
- && gp_reg_p
- && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (SImode))
- ? NO_REGS : gr_regs);
- +
- + else if (class == HILO1_REG && regno != GP_REG_FIRST + 0)
- + return ((! in_p
- + && gp_reg_p
- + && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (SImode))
- + ? NO_REGS : gr_regs);
- +
- else if (regno == HILO_REGNUM)
- return ((in_p
- && class == gr_regs
- && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (SImode))
- ? NO_REGS : gr_regs);
- + else if (regno == HILO1_REGNUM)
- + return ((in_p
- + && class == gr_regs
- + && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (SImode))
- + ? NO_REGS : gr_regs);
- +
- /* Copying from HI or LO to anywhere other than a general register
- requires a general register. */
- - if (class == HI_REG || class == LO_REG || class == MD_REGS)
- +
- + if (class == HI_REG || class == LO_REG || class == MD_REGS
- + || class == HI1_REG || class == LO1_REG || class == MD1_REGS)
- {
- if (TARGET_MIPS16 && in_p)
- {
- @@ -8230,7 +8571,8 @@
- }
- return gp_reg_p ? NO_REGS : gr_regs;
- }
- - if (MD_REG_P (regno))
- +
- + if (MD_REG_P (regno) || MD1_REG_P (regno))
- {
- if (TARGET_MIPS16 && ! in_p)
- {
- @@ -9389,6 +9731,11 @@
- if (! TARGET_MIPS16)
- return;
- +#ifdef FILL_BDSLOT_WITH_NOP
- + if (TARGET_MIPS5900 && !TARGET_NO_LENGTHEN_LOOP)
- + r5900_lengthen_loops (first,0);
- +#endif
- +
- /* If $gp is used, try to remove stores, and replace loads with
- copies from $gp. */
- if (optimize)
- @@ -9578,6 +9925,205 @@
- constant table, but we have no way to prevent that. */
- }
- +
- +/* On the R5900, we must ensure that the compiler never generates loops
- + that satisfy all of the following conditions:
- +
- + * a loop consists of less than equal to six instructions (including the
- + branch delay slot).
- +
- + * a loop contains only one conditional branch instruction at the
- + end of the loop.
- +
- + * a loop does not contain any other branch or jump instructions.
- +
- + * a branch delay slot of the loop is not nop. ( EE#2.9 or later )
- +
- + We need to do this because of a bug in the chip.
- +
- + */
- +
- +#define NOP_INSN_P(INSN) (rtx_equal_p (INSN, gen_nop ()))
- +
- +enum sequence_type {Jump, Reset, Other};
- +
- +/* Detect if possible loop jump presents in the sequence */
- +
- +static enum sequence_type
- +r5900_detect_sequence_type (insn, count_p, jump_insn_p, seen_before,
- + after_delayed_branch_sched)
- + rtx insn;
- + int *count_p;
- + rtx *jump_insn_p;
- + int *seen_before;
- + int after_delayed_branch_sched;
- +{
- + int i;
- + int detect_later = 0;
- +
- + for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
- + {
- + rtx v_insn;
- + v_insn = XVECEXP (PATTERN (insn), 0, i);
- +
- + switch (GET_CODE (v_insn))
- + {
- + case CODE_LABEL:
- + seen_before [INSN_UID (v_insn)] = *count_p;
- + break;
- + case INSN:
- + /* The attr_length may be bigger than acctual insn length.
- + So don't use it in the after_delayed_branch_sched phase. */
- + *count_p += ( get_attr_length (insn) > 0
- + && !after_delayed_branch_sched )
- + ? get_attr_length (insn) : 4 ;
- + if (detect_later)
- + {
- + /* inspect BD slot */
- + if (NOP_INSN_P (PATTERN (v_insn)))
- + return Reset;
- + return Jump;
- + }
- + break;
- + case JUMP_INSN:
- + *jump_insn_p = v_insn;
- + detect_later = 1;
- + break;
- + case CALL_INSN:
- + return Reset;
- + break;
- + default:
- + break;
- + }
- + }
- +
- + if (detect_later)
- + /* Since there's no instruction in the delay slot, the assembler will
- + insert a "nop" later. */
- + return Reset;
- +
- + return Other;
- +}
- +
- +/* XXX: Fix this. */
- +
- +static void
- +r5900_lengthen_loops (first, after_delayed_branch_sched)
- + rtx first;
- + int after_delayed_branch_sched;
- +{
- + rtx insn;
- + rtx this_jump_insn;
- + const int hazardous_distance = 6;
- + int n = 4;
- + int max_uid = get_max_uid ();
- + int *seen_before = alloca (sizeof seen_before[0] * max_uid);
- + int in_sequence = 0;
- + enum sequence_type result;
- +
- + /*bzero ((char *) seen_before, sizeof seen_before[0] * max_uid);*/
- + memset((char *) seen_before, 0, sizeof seen_before[0] * max_uid);
- +
- + for (insn = first; insn; insn = NEXT_INSN (insn))
- + {
- + in_sequence = 0;
- + switch (GET_CODE (insn))
- + {
- + case CODE_LABEL:
- + seen_before [INSN_UID (insn)] = n;
- + break;
- +
- + case INSN:
- + if (GET_CODE (PATTERN (insn)) != SEQUENCE )
- + {
- + /* The attr_length may be bigger than acctual insn length.
- + So don't use it in the after_delayed_branch_sched phase. */
- + n += ( get_attr_length (insn) > 0
- + && !after_delayed_branch_sched )
- + ? get_attr_length (insn) : 4 ;
- + break;
- + }
- + result = r5900_detect_sequence_type(insn, &n, &this_jump_insn,
- + seen_before, after_delayed_branch_sched);
- + switch(result)
- + {
- + case Reset:
- + goto reset;
- + case Jump:
- + in_sequence=1;
- + goto jump_insn;
- + case Other:
- + default:
- + break;
- + }
- + break;
- +
- + case JUMP_INSN:
- + this_jump_insn = insn;
- + in_sequence=0;
- + jump_insn:
- + if (condjump_p (this_jump_insn))
- + {
- + rtx target = condjump_label (this_jump_insn);
- +
- + if (seen_before [INSN_UID (XEXP (target, 0))])
- + {
- + int distance
- + = (n - seen_before [INSN_UID (XEXP (target, 0))]) >> 2;
- +
- + if (!in_sequence)
- + {
- + /* try to insert one nop before jump
- + * if distance is in hazardous_distance */
- +
- + if ( distance <= hazardous_distance )
- + {
- + rtx prev_insn = PREV_INSN (this_jump_insn);
- + while ( prev_insn && ( GET_CODE (prev_insn) != INSN ))
- + prev_insn = PREV_INSN (prev_insn);
- + if (prev_insn && ! NOP_INSN_P (PATTERN (prev_insn)))
- + emit_insn_before (gen_nop (), this_jump_insn);
- +
- + }
- + }
- + else
- + {
- + if ( distance <= hazardous_distance )
- + {
- + for (; distance <= hazardous_distance; distance++)
- + emit_insn_before (gen_nop(), insn);
- + }
- + }
- + }
- + }
- +
- + /* Falls through */
- +
- + case CALL_INSN:
- + reset:
- + /*bzero ((char *) seen_before, sizeof seen_before[0] * max_uid);*/
- + memset((char *) seen_before, 0, sizeof seen_before[0] * max_uid);
- + break;
- +
- + default:
- + break;
- + }
- + }
- +}
- +
- +/* Exported to toplev.c.
- +
- + Do a final pass over the function, just before rtl to asm conversion
- + (after "delayed branch scheduling" and "shorten jump"). */
- +
- +void
- +machine_dependent_reorg_final (first)
- + rtx first;
- +{
- + if (TARGET_MIPS5900 && ! TARGET_NO_LENGTHEN_LOOP)
- + r5900_lengthen_loops (first, 1);
- +}
- +
- /* Return nonzero if X is a SIGN or ZERO extend operator. */
- int
- extend_operator (x, mode)
- @@ -9978,6 +10524,8 @@
- case '5':
- if (!strcmp (p, "5000") || !strcmp (p, "5k") || !strcmp (p, "5K"))
- cpu = PROCESSOR_R5000;
- + else if (!strcmp (p, "5900"))
- + cpu = PROCESSOR_R5900;
- else if (!strcmp (p, "5kc") || !strcmp (p, "5Kc") )
- cpu = PROCESSOR_R5KC;
- break;
- @@ -10102,7 +10650,10 @@
- int regno;
- enum machine_mode mode;
- {
- - if (! FP_REG_P (regno))
- + /* TODO: Add r5900 dual mode register support. */
- + if (TARGET_MIPS5900 && GP_REG_P (regno) && mode == TImode)
- + return 1;
- + else if (! FP_REG_P (regno))
- return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
- else
- return ((GET_MODE_SIZE (mode) + UNITS_PER_FPREG - 1) / UNITS_PER_FPREG);
- @@ -10268,3 +10819,345 @@
- mips_asm_file_end (stream);
- }
- #endif /* TARGET_IRIX6 */
- +
- +static void
- +r5900_sched_init ()
- +{
- +}
- +
- +static void
- +mips_sched_init (dump, sched_verbose, veclen)
- + FILE *dump ATTRIBUTE_UNUSED;
- + int sched_verbose ATTRIBUTE_UNUSED;
- + int veclen ATTRIBUTE_UNUSED;
- +{
- + if (TARGET_MIPS5900)
- + r5900_sched_init ();
- +}
- +
- +static void
- +r5900_sched_reorder (dump, sched_verbose, ready, n_ready)
- + FILE *dump;
- + int sched_verbose;
- + rtx *ready;
- + int n_ready;
- +{
- + static int imuldivunit = -1;
- +
- + return;
- + /* There is also no point in trying these tweaks after reload has
- + completed. */
- + if (reload_completed)
- + return;
- +
- + /* If there are less than three insns on the queue, then there's nothing
- + to do. */
- + if (n_ready < 3)
- + return;
- +
- + /* We need to know what value will be returned by function_units_used for
- + the r5900's multiply/divide units. If we have not computed it yet,
- + do so now. */
- + if (imuldivunit == -1)
- + {
- + int i;
- +
- + for (i = 0; i < FUNCTION_UNITS_SIZE; i++)
- + {
- + if (!strcmp ("r5900imuldiv", function_units[i].name))
- + {
- + imuldivunit = i;
- + break;
- + }
- + }
- + if (imuldivunit == -1)
- + return;
- + }
- +
- + {
- + int i;
- +
- + /* Loop through the instructions and try to pair up two instructions
- + which use the imuldiv pipelines.
- +
- + We want such instructions to appear back to back in the RTL chain
- + so that the register allocator will allocate a different HILO
- + register for the two imuldiv instructions.
- +
- + Note the ready list is ordered backwards.
- +
- + If we do not find an idivmul insn which could issue this cycle, quit
- + to save time. */
- + for (i = n_ready - 1; i >= n_ready - 2; i--)
- + {
- + rtx insn = ready[i];
- + enum rtx_code code;
- +
- + /* Ignore anything we do not understand. */
- + if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
- + || (code = GET_CODE (PATTERN (insn))) == USE
- + || code == CLOBBER || code == ADDR_VEC)
- + continue;
- + else
- + {
- + /* We are looking for instructions that issue to the imuldiv
- + pipelines. */
- + if (function_units_used (insn) == imuldivunit)
- + {
- + int j;
- +
- + /* We have found one insn that uses the imuldiv pipeline, so
- + now look for another imuldiv instruction. */
- + for (j = i - 1; j >= 0; j--)
- + {
- + rtx temp = ready[j];
- +
- + /* Ignore anything we do not understand. */
- + if (GET_RTX_CLASS (GET_CODE (temp)) != 'i'
- + || (code = GET_CODE (PATTERN (temp))) == USE
- + || code == CLOBBER || code == ADDR_VEC)
- + continue;
- +
- + /* Again, we are looking for an imuldiv insn. */
- + if (function_units_used (temp) == imuldivunit)
- + {
- +
- + /* Make the idivmul insns consecutive if they were
- + not already consecutive. */
- + if (i - j != 1)
- + {
- + rtx temp = ready[j];
- + /*bcopy (&ready[j+1], &ready[j],
- + (i - j - 1) * sizeof (rtx *));*/
- + memcpy(&ready[j], &ready[j+1], (i - j - 1) * sizeof (rtx *));
- + ready[i - 1] = temp;
- + }
- +
- + /* Now the imuldiv insns are consecutive. We can
- + still lose if they issue at different clocks, so
- + move them as a pair to the head of ready list.
- +
- + Note I must either be the head of the queue or
- + the second insn in the queue. */
- + if (i != n_ready - 1)
- + {
- + rtx temp1, temp2;
- +
- + /* Rotate the first three elements in the
- + ready queue. */
- + temp1 = ready[n_ready - 1];
- + temp2 = ready[n_ready - 2];
- + ready[n_ready - 2] = ready[n_ready - 3];
- + ready[n_ready - 3] = temp1;
- + ready[n_ready - 1] = temp2;
- + }
- + return;
- + }
- + }
- + }
- + }
- + }
- + }
- +}
- +
- +/* Reorder the ready list as needed to improve performance. */
- +
- +static int
- +mips_sched_reorder (dump, sched_verbose, ready, n_readyp, clock_var)
- + FILE *dump ATTRIBUTE_UNUSED;
- + int sched_verbose ATTRIBUTE_UNUSED;
- + rtx *ready;
- + int *n_readyp;
- + int clock_var ATTRIBUTE_UNUSED;
- +{
- + if (TARGET_MIPS5900)
- + r5900_sched_reorder (dump, sched_verbose, ready, *n_readyp);
- + return ISSUE_RATE;
- +}
- +
- +/* R5900 built-ins support. This is largely based off of the ix86 SSE/MMX
- + and rs6000 Altivec implementations. */
- +
- +#define def_builtin(MASK, NAME, TYPE, CODE) \
- +do { \
- + if ((MASK) & target_flags) \
- + builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL); \
- +} while (0)
- +
- +struct builtin_description
- +{
- + const unsigned int mask;
- + const enum insn_code icode;
- + const char *const name;
- + const enum r5900_builtins code;
- +};
- +
- +/* Builtins that take 2 arguments. */
- +static struct builtin_description bdesc_2arg[] =
- +{
- + { MASK_MMI, CODE_FOR_addv16qi3, "__builtin_mmi_paddb", MMI_BUILTIN_PADDB },
- + { MASK_MMI, CODE_FOR_addv8hi3, "__builtin_mmi_paddh", MMI_BUILTIN_PADDH },
- + { MASK_MMI, CODE_FOR_addv4si3, "__builtin_mmi_paddw", MMI_BUILTIN_PADDW },
- + { MASK_MMI, CODE_FOR_ssaddv16qi3, "__builtin_mmi_paddsb", MMI_BUILTIN_PADDSB },
- + { MASK_MMI, CODE_FOR_ssaddv8hi3, "__builtin_mmi_paddsh", MMI_BUILTIN_PADDSW },
- + { MASK_MMI, CODE_FOR_ssaddv4si3, "__builtin_mmi_paddsw", MMI_BUILTIN_PADDSH },
- + { MASK_MMI, CODE_FOR_usaddv16qi3, "__builtin_mmi_paddub", MMI_BUILTIN_PADDUB },
- + { MASK_MMI, CODE_FOR_usaddv8hi3, "__builtin_mmi_padduh", MMI_BUILTIN_PADDUW },
- + { MASK_MMI, CODE_FOR_usaddv4si3, "__builtin_mmi_padduw", MMI_BUILTIN_PADDUH },
- +
- + { MASK_MMI, CODE_FOR_subv16qi3, "__builtin_mmi_psubb", MMI_BUILTIN_PSUBB },
- + { MASK_MMI, CODE_FOR_subv8hi3, "__builtin_mmi_psubh", MMI_BUILTIN_PSUBH },
- + { MASK_MMI, CODE_FOR_subv4si3, "__builtin_mmi_psubw", MMI_BUILTIN_PSUBW },
- + { MASK_MMI, CODE_FOR_sssubv16qi3, "__builtin_mmi_psubsb", MMI_BUILTIN_PSUBSB },
- + { MASK_MMI, CODE_FOR_sssubv8hi3, "__builtin_mmi_psubsh", MMI_BUILTIN_PSUBSW },
- + { MASK_MMI, CODE_FOR_sssubv4si3, "__builtin_mmi_psubsw", MMI_BUILTIN_PSUBSH },
- + { MASK_MMI, CODE_FOR_ussubv16qi3, "__builtin_mmi_psubub", MMI_BUILTIN_PSUBUB },
- + { MASK_MMI, CODE_FOR_ussubv8hi3, "__builtin_mmi_psubuh", MMI_BUILTIN_PSUBUW },
- + { MASK_MMI, CODE_FOR_ussubv4si3, "__builtin_mmi_psubuw", MMI_BUILTIN_PSUBUH },
- +
- +};
- +
- +/* Expand all r5900-specific builtins. This is only called if TARGET_MMI or
- + TARGET_VUMM are true. */
- +static void
- +r5900_init_builtins()
- +{
- + struct builtin_description *d;
- + size_t i;
- + tree endlink = void_list_node;
- +
- + /* Normal vector binops. */
- + tree v16qi_ftype_v16qi_v16qi
- + = build_function_type (V16QI_type_node,
- + tree_cons (NULL_TREE, V16QI_type_node,
- + tree_cons (NULL_TREE, V16QI_type_node,
- + endlink)));
- +
- + tree v8hi_ftype_v8hi_v8hi
- + = build_function_type (V8HI_type_node,
- + tree_cons (NULL_TREE, V8HI_type_node,
- + tree_cons (NULL_TREE, V8HI_type_node,
- + endlink)));
- +
- + tree v4si_ftype_v4si_v4si
- + = build_function_type (V4SI_type_node,
- + tree_cons (NULL_TREE, V4SI_type_node,
- + tree_cons (NULL_TREE, V4SI_type_node,
- + endlink)));
- +
- + tree ti_ftype_ti_ti
- + = build_function_type (intTI_type_node,
- + tree_cons (NULL_TREE, intTI_type_node,
- + tree_cons (NULL_TREE, intTI_type_node,
- + endlink)));
- +
- + /* Add all builtins that are simple binary operations. */
- + for (i = 0, d = bdesc_2arg; i < sizeof (bdesc_2arg) / sizeof *d; i++, d++)
- + {
- + enum machine_mode mode;
- + tree type;
- +
- + if (d->name == 0)
- + continue;
- + mode = insn_data[d->icode].operand[1].mode;
- +
- + switch (mode)
- + {
- + case V16QImode:
- + type = v16qi_ftype_v16qi_v16qi;
- + break;
- + case V8HImode:
- + type = v8hi_ftype_v8hi_v8hi;
- + case V4SImode:
- + type = v4si_ftype_v4si_v4si;
- + case TImode:
- + type = ti_ftype_ti_ti;
- + break;
- +
- + default:
- + abort ();
- + }
- +
- + def_builtin (d->mask, d->name, type, d->code);
- + }
- +}
- +
- +static rtx
- +r5900_expand_binop_builtin (icode, arglist, target)
- + enum insn_code icode;
- + tree arglist;
- + rtx target;
- +{
- + rtx pat;
- + tree arg0 = TREE_VALUE (arglist);
- + tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
- + rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
- + rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
- + enum machine_mode tmode = insn_data[icode].operand[0].mode;
- + enum machine_mode mode0 = insn_data[icode].operand[1].mode;
- + enum machine_mode mode1 = insn_data[icode].operand[2].mode;
- +
- + if (! target
- + || GET_MODE (target) != tmode
- + || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
- + target = gen_reg_rtx (tmode);
- +
- + /* In case the insn wants input operands in modes different fro
- + the result, abort. */
- + if (GET_MODE (op0) != mode0 || GET_MODE (op1) != mode1)
- + abort ();
- +
- + if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
- + op0 = copy_to_mode_reg (mode0, op0);
- + if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
- + op1 = copy_to_mode_reg (mode1, op1);
- +
- + pat = GEN_FCN (icode) (target, op0, op1);
- + if (! pat)
- + return 0;
- + emit_insn (pat);
- + return target;
- +}
- +
- +static rtx
- +r5900_expand_builtin (exp, target)
- + tree exp;
- + rtx target;
- +{
- + struct builtin_description *d;
- + size_t i;
- + enum insn_code icode;
- + tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
- + tree arglist = TREE_OPERAND (exp, 1);
- + tree arg0, arg1, arg2, arg3;
- + rtx op0, op1, op2, pat;
- + enum machine_mode tmode, mode0, mode1, mode2;
- + unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
- +
- + for (i = 0, d = bdesc_2arg; i < sizeof (bdesc_2arg) / sizeof *d; i++, d++)
- + if (d->code == fcode)
- + return r5900_expand_binop_builtin (d->icode, arglist, target);
- +
- + return 0;
- +}
- +
- +static rtx
- +mips_expand_builtin (exp, target, subtarget, mode, ignore)
- + tree exp;
- + rtx target;
- + rtx subtarget ATTRIBUTE_UNUSED;
- + enum machine_mode mode ATTRIBUTE_UNUSED;
- + int ignore ATTRIBUTE_UNUSED;
- +{
- + if (TARGET_MIPS5900)
- + return r5900_expand_builtin (exp, target);
- +
- + abort ();
- +}
- +
- +static void
- +mips_init_builtins ()
- +{
- + if (TARGET_MIPS5900)
- + r5900_init_builtins ();
- +}
- diff -burN orig.gcc-3.2.3/gcc/config/mips/mips.h gcc-3.2.3/gcc/config/mips/mips.h
- --- orig.gcc-3.2.3/gcc/config/mips/mips.h 2002-04-26 18:32:14.000000000 -0300
- +++ gcc-3.2.3/gcc/config/mips/mips.h 2015-08-10 16:11:20 +0300
- @@ -48,6 +48,7 @@
- DELAY_NONE, /* no delay slot */
- DELAY_LOAD, /* load from memory delay */
- DELAY_HILO, /* move from/to hi/lo registers */
- + DELAY_HILO1, /* move from/to hi1/lo1 registers */
- DELAY_FCMP /* delay after doing c.<xx>.{d,s} */
- };
- @@ -67,6 +68,7 @@
- PROCESSOR_R4600,
- PROCESSOR_R4650,
- PROCESSOR_R5000,
- + PROCESSOR_R5900,
- PROCESSOR_R8000,
- PROCESSOR_R4KC,
- PROCESSOR_R5KC,
- @@ -146,6 +148,7 @@
- extern int mips16; /* whether generating mips16 code */
- extern int mips16_hard_float; /* mips16 without -msoft-float */
- extern int mips_entry; /* generate entry/exit for mips16 */
- +extern int mips_alignment; /* max alignment bits */
- extern const char *mips_cpu_string; /* for -mcpu=<xxx> */
- extern const char *mips_arch_string; /* for -march=<xxx> */
- extern const char *mips_tune_string; /* for -mtune=<xxx> */
- @@ -155,6 +158,11 @@
- extern const char *mips_no_mips16_string;/* for -mno-mips16 */
- extern const char *mips_explicit_type_size_string;/* for -mexplicit-type-size */
- extern const char *mips_cache_flush_func;/* for -mflush-func= and -mno-flush-func */
- +extern const char *mips_align_all_string;/* for -malign-all= */
- +extern const char * mips_align128_string;/* for -malign128 */
- +extern const char * mips_no_align128_string;/* for -mno-align128 */
- +extern const char * mips_use_128_string; /* for -muse-128 */
- +extern int mips_use_128; /* the boolean for -muse-128 */
- extern int mips_split_addresses; /* perform high/lo_sum support */
- extern int dslots_load_total; /* total # load related delay slots */
- extern int dslots_load_filled; /* # filled load delay slots */
- @@ -175,6 +183,8 @@
- extern void sdata_section PARAMS ((void));
- extern void sbss_section PARAMS ((void));
- +extern int mips_align_all;
- +
- /* Stubs for half-pic support if not OSF/1 reference platform. */
- #ifndef HALF_PIC_P
- @@ -232,6 +242,10 @@
- consts in rodata */
- #define MASK_NO_FUSED_MADD 0x01000000 /* Don't generate floating point
- multiply-add operations. */
- +#define MASK_MMI 0x02000000 /* r5900 MultiMedia Instructions (MMI) */
- +#define MASK_VUMM 0x04000000 /* r5900 VU0 macro mode (COP2) */
- +#define MASK_NO_LENGTHEN_LOOP \
- + 0x08000000 /* Disable r5900 loop bug workaround */
- /* Debug switches, not documented */
- #define MASK_DEBUG 0 /* unused */
- @@ -327,6 +341,16 @@
- #define TARGET_NO_CHECK_ZERO_DIV (target_flags & MASK_NO_CHECK_ZERO_DIV)
- #define TARGET_CHECK_RANGE_DIV (target_flags & MASK_CHECK_RANGE_DIV)
- + /* enable r5900 multimedia
- + instructions. */
- +#define TARGET_MMI (target_flags & MASK_MMI)
- +
- + /* enable r5900 macro mode for VU0 */
- +#define TARGET_VUMM (target_flags & MASK_VUMM)
- +
- + /* disable r5900 loop bug workaround */
- +#define TARGET_NO_LENGTHEN_LOOP (target_flags & MASK_NO_LENGTHEN_LOOP)
- +
- /* This is true if we must enable the assembly language file switching
- code. */
- @@ -346,6 +370,7 @@
- #define TARGET_MIPS4000 (mips_arch == PROCESSOR_R4000)
- #define TARGET_MIPS4100 (mips_arch == PROCESSOR_R4100)
- #define TARGET_MIPS4300 (mips_arch == PROCESSOR_R4300)
- +#define TARGET_MIPS5900 (mips_arch == PROCESSOR_R5900)
- #define TARGET_MIPS4KC (mips_arch == PROCESSOR_R4KC)
- #define TARGET_MIPS5KC (mips_arch == PROCESSOR_R5KC)
- @@ -354,6 +379,7 @@
- #define TUNE_MIPS3900 (mips_tune == PROCESSOR_R3900)
- #define TUNE_MIPS4000 (mips_tune == PROCESSOR_R4000)
- #define TUNE_MIPS5000 (mips_tune == PROCESSOR_R5000)
- +#define TUNE_MIPS5900 (mips_tune == PROCESSOR_R5900)
- #define TUNE_MIPS6000 (mips_tune == PROCESSOR_R6000)
- /* Macro to define tables used to set the flags.
- @@ -464,6 +490,18 @@
- N_("Optimize for 3900")}, \
- {"4650", 0, \
- N_("Optimize for 4650")}, \
- + {"5900", 0, \
- + N_("Optimize for 5900")}, \
- + {"mmi", MASK_MMI, \
- + N_("Use r5900 multimedia instructions")}, \
- + {"no-mmi", -MASK_MMI, \
- + N_("Don't use r5900 multimedia instructions")}, \
- + {"vumm", MASK_VUMM, \
- + N_("Use r5900 VU0 macro mode instructions")}, \
- + {"no-vumm", -MASK_VUMM, \
- + N_("Don't use r5900 VU0 macro mode instructions")}, \
- + {"no-lengthen-loop", MASK_NO_LENGTHEN_LOOP, \
- + N_("Don't workaround r5900 short loop bug")}, \
- {"check-zero-division",-MASK_NO_CHECK_ZERO_DIV, \
- N_("Trap on integer divide by zero")}, \
- {"no-check-zero-division", MASK_NO_CHECK_ZERO_DIV, \
- @@ -472,6 +510,8 @@
- N_("Trap on integer divide overflow")}, \
- {"no-check-range-division",-MASK_CHECK_RANGE_DIV, \
- N_("Don't trap on integer divide overflow")}, \
- + {"iop", 0, \
- + N_("Output IOP's IRX file")}, \
- {"debug", MASK_DEBUG, \
- NULL}, \
- {"debuga", MASK_DEBUG_A, \
- @@ -604,6 +644,8 @@
- N_("Don't call any cache flush functions")}, \
- { "flush-func=", &mips_cache_flush_func, \
- N_("Specify cache flush function")}, \
- + { "align-all=", &mips_align_all_string, \
- + N_("Force lower alignment")}, \
- }
- /* This is meant to be redefined in the host dependent files. */
- @@ -613,6 +655,7 @@
- /* Generate three-operand multiply instructions for SImode. */
- #define GENERATE_MULT3_SI ((TARGET_MIPS3900 \
- + || TARGET_MIPS5900 \
- || mips_isa == 32 \
- || mips_isa == 64) \
- && !TARGET_MIPS16)
- @@ -644,7 +687,7 @@
- || mips_isa == 64)
- /* ISA has just the integer condition move instructions (movn,movz) */
- -#define ISA_HAS_INT_CONDMOVE 0
- +#define ISA_HAS_INT_CONDMOVE (TARGET_MIPS5900)
- @@ -847,7 +890,7 @@
- /* GAS_ASM_SPEC is passed when using gas, rather than the MIPS
- assembler. */
- -#define GAS_ASM_SPEC "%{march=*} %{mtune=*} %{mcpu=*} %{m4650} %{mmad:-m4650} %{m3900} %{v} %{mgp32} %{mgp64} %(abi_gas_asm_spec) %{mabi=32:%{!mips*:-mips1}}"
- +#define GAS_ASM_SPEC "%{march=*} %{mtune=*} %{mcpu=*} %{m4650} %{mmad:-m4650} %{m3900} %{m5900} %{v} %{mgp32} %{mgp64} %(abi_gas_asm_spec) %{mabi=32:%{!mips*:-mips1}}"
- extern int mips_abi;
- @@ -964,7 +1007,7 @@
- #ifndef LINK_SPEC
- #define LINK_SPEC "\
- %(endian_spec) \
- -%{G*} %{mips1} %{mips2} %{mips3} %{mips4} %{mips32} %{mips64} \
- +%{G*} %{mips1} %{mips2} %{mips3} %{mips4} %{mips32} %{mips64} %{miop:-mmipsirx} \
- %{bestGnum} %{shared} %{non_shared}"
- #endif /* LINK_SPEC defined */
- @@ -984,7 +1027,9 @@
- %{m3900:-march=r3900 -mips1 -mfp32 -mgp32 \
- %n`-m3900' is deprecated. Use `-march=r3900' instead.\n} \
- %{m4650:-march=r4650 -mmad -msingle-float \
- -%n`-m4650' is deprecated. Use `-march=r4650' instead.\n}}"
- +%n`-m4650' is deprecated. Use `-march=r4650' instead.\n} \
- +%{m5900:-march=r5900 -mips3 -mgp64 -mfp32 -mlong64 -mmmi -msingle-float \
- +%n`-m5900' is deprecated. Use `-march=r5900' instead.\n}}"
- #endif
- /* CC1_SPEC is the set of arguments to pass to the compiler proper. */
- @@ -1003,6 +1048,7 @@
- %{mfp64:%{msingle-float:%emay not use both -mfp64 and -msingle-float}} \
- %{mfp64:%{m4650:%emay not use both -mfp64 and -m4650}} \
- %{mint64|mlong64|mlong32:-mexplicit-type-size }\
- +%{miop:-march=r3000 -mfp32 -mgp32 -fno-builtin} \
- %{mgp32: %{mfp64:%emay not use both -mgp32 and -mfp64} %{!mfp32: -mfp32}} \
- %{G*} %{EB:-meb} %{EL:-mel} %{EB:%{EL:%emay not use both -EB and -EL}} \
- %{pic-none: -mno-half-pic} \
- @@ -1661,7 +1707,7 @@
- #define STRUCTURE_SIZE_BOUNDARY 8
- /* There is no point aligning anything to a rounder boundary than this. */
- -#define BIGGEST_ALIGNMENT 64
- +#define BIGGEST_ALIGNMENT 128
- /* Set this nonzero if move instructions will actually fail to work
- when given unaligned data. */
- @@ -1796,20 +1842,20 @@
- address reg ($31) was stored. This is needed for C++ exception
- handling. */
- -#define FIRST_PSEUDO_REGISTER 76
- +#define FIRST_PSEUDO_REGISTER 79
- /* 1 for registers that have pervasive standard uses
- and are not available for the register allocator.
- On the MIPS, see conventions, page D-2 */
- -
- #define FIXED_REGISTERS \
- { \
- 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, \
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 \
- + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, \
- + 0, 0, 0 \
- }
- @@ -1826,7 +1872,8 @@
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, \
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
- 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 \
- + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
- + 1, 1, 1 \
- }
- /* Like `CALL_USED_REGISTERS' but used to overcome a historical
- @@ -1846,7 +1893,8 @@
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
- 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- /* Others. */ \
- - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 \
- + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
- + 1, 1, 1 \
- }
- /* Internal macros to classify a register number as to whether it's a
- @@ -1867,6 +1915,10 @@
- #define MD_REG_LAST 66
- #define MD_REG_NUM (MD_REG_LAST - MD_REG_FIRST + 1)
- +#define MD1_REG_FIRST 76
- +#define MD1_REG_LAST 78
- +#define MD1_REG_NUM (MD1_REG_LAST - MD1_REG_FIRST + 1)
- +
- #define ST_REG_FIRST 67
- #define ST_REG_LAST 74
- #define ST_REG_NUM (ST_REG_LAST - ST_REG_FIRST + 1)
- @@ -1877,6 +1929,9 @@
- #define HI_REGNUM (MD_REG_FIRST + 0)
- #define LO_REGNUM (MD_REG_FIRST + 1)
- #define HILO_REGNUM (MD_REG_FIRST + 2)
- +#define HI1_REGNUM (MD1_REG_FIRST + 0)
- +#define LO1_REGNUM (MD1_REG_FIRST + 1)
- +#define HILO1_REGNUM (MD1_REG_FIRST + 2)
- /* FPSW_REGNUM is the single condition code used if mips_isa < 4. If
- mips_isa >= 4, it should not be used, and an arbitrary ST_REG
- @@ -1891,6 +1946,8 @@
- ((unsigned int) ((int) (REGNO) - FP_REG_FIRST) < FP_REG_NUM)
- #define MD_REG_P(REGNO) \
- ((unsigned int) ((int) (REGNO) - MD_REG_FIRST) < MD_REG_NUM)
- +#define MD1_REG_P(REGNO) \
- + ((unsigned int) ((int) (REGNO) - MD1_REG_FIRST) < MD1_REG_NUM)
- #define ST_REG_P(REGNO) \
- ((unsigned int) ((int) (REGNO) - ST_REG_FIRST) < ST_REG_NUM)
- @@ -2057,6 +2114,20 @@
- LO_AND_GR_REGS,
- HILO_AND_GR_REGS,
- HI_AND_FP_REGS,
- + HI1_REG, /* hi1 register */
- + LO1_REG, /* lo1 register */
- + HILO1_REG, /* hilo1 register pair for 64 bit mode mult */
- + MD1_REGS, /* multiply/divide registers (hi/lo) */
- + HI1_AND_GR_REGS, /* union classes */
- + LO1_AND_GR_REGS,
- + HILO1_AND_GR_REGS,
- + HI01_REG, /* hi01 register */
- + LO01_REG, /* lo01 register */
- + HILO01_REG, /* hilo1 register pair for 64 bit mode mult */
- + MD01_REGS, /* multiply/divide registers (hi1/lo1) */
- + HI01_AND_GR_REGS, /* union classes */
- + LO01_AND_GR_REGS,
- + HILO01_AND_GR_REGS,
- ST_REGS, /* status registers (fp status) */
- ALL_REGS, /* all registers */
- LIM_REG_CLASSES /* max value + 1 */
- @@ -2087,6 +2158,20 @@
- "LO_AND_GR_REGS", \
- "HILO_AND_GR_REGS", \
- "HI_AND_FP_REGS", \
- + "HI1_REG", \
- + "LO1_REG", \
- + "HILO1_REG", \
- + "MD1_REGS", \
- + "HI1_AND_GR_REGS", \
- + "LO1_AND_GR_REGS", \
- + "HILO1_AND_GR_REGS", \
- + "HI01_REG", \
- + "LO01_REG", \
- + "HILO01_REG", \
- + "MD01_REGS", \
- + "HI01_AND_GR_REGS", \
- + "LO01_AND_GR_REGS", \
- + "HILO01_AND_GR_REGS", \
- "ST_REGS", \
- "ALL_REGS" \
- }
- @@ -2105,7 +2190,7 @@
- #define REG_CLASS_CONTENTS \
- { \
- { 0x00000000, 0x00000000, 0x00000000 }, /* no registers */ \
- - { 0x0003000c, 0x00000000, 0x00000000 }, /* mips16 nonarg regs */\
- + { 0x0003000c, 0x00000000, 0x00000000 }, /* mips16 nonarg regs */ \
- { 0x000300fc, 0x00000000, 0x00000000 }, /* mips16 registers */ \
- { 0x01000000, 0x00000000, 0x00000000 }, /* mips16 T register */ \
- { 0x010300fc, 0x00000000, 0x00000000 }, /* mips16 and T regs */ \
- @@ -2119,8 +2204,24 @@
- { 0xffffffff, 0x00000000, 0x00000002 }, \
- { 0xffffffff, 0x00000000, 0x00000004 }, \
- { 0x00000000, 0xffffffff, 0x00000001 }, \
- + /* Start of r5900 extra registers. */ \
- + { 0x00000000, 0x00000000, 0x00001000 }, /* hi1 register */ \
- + { 0x00000000, 0x00000000, 0x00002000 }, /* lo1 register */ \
- + { 0x00000000, 0x00000000, 0x00004000 }, /* hilo1 register */ \
- + { 0x00000000, 0x00000000, 0x00003000 }, /* mul1/div1 registers */ \
- + { 0xffffffff, 0x00000000, 0x00001000 }, /* union classes */ \
- + { 0xffffffff, 0x00000000, 0x00002000 }, \
- + { 0xffffffff, 0x00000000, 0x00004000 }, \
- + { 0x00000000, 0x00000000, 0x00001001 }, /* hi01 registers */ \
- + { 0x00000000, 0x00000000, 0x00002002 }, /* lo01 registers */ \
- + { 0x00000000, 0x00000000, 0x00004004 }, /* hilo01 registers */ \
- + { 0x00000000, 0x00000000, 0x00003003 }, /* mul01/div01 registers */ \
- + { 0xffffffff, 0x00000000, 0x00001001 }, /* union classes */ \
- + { 0xffffffff, 0x00000000, 0x00002002 }, \
- + { 0xffffffff, 0x00000000, 0x00004004 }, \
- + /* End of r5900 extra registers. */ \
- { 0x00000000, 0x00000000, 0x000007f8 }, /* status registers */ \
- - { 0xffffffff, 0xffffffff, 0x000007ff } /* all registers */ \
- + { 0xffffffff, 0xffffffff, 0x000078ff } /* all registers */ \
- }
- @@ -2169,7 +2270,8 @@
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, \
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, \
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, \
- - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75 \
- + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, \
- + 76, 77, 78 \
- }
- /* ORDER_REGS_FOR_LOCAL_ALLOC is a macro which permits reg_alloc_order
- @@ -2197,7 +2299,11 @@
- 'x' Multiply/divide registers
- 'a' HILO_REG
- 'z' FP Status register
- - 'b' All registers */
- + 'b' All registers
- + 'u' Hi1 register
- + 'v' Lo1 register
- + 'w' Multiply/divide1 registers
- + 'q' HILO1_REG */
- extern enum reg_class mips_char_to_class[256];
- @@ -2357,7 +2463,7 @@
- #define CLASS_CANNOT_CHANGE_MODE \
- (TARGET_BIG_ENDIAN \
- ? (TARGET_FLOAT64 && ! TARGET_64BIT ? FP_REGS : NO_REGS) \
- - : (TARGET_FLOAT64 && ! TARGET_64BIT ? HI_AND_FP_REGS : HI_REG))
- + : (TARGET_FLOAT64 && ! TARGET_64BIT ? HI_AND_FP_REGS : HI01_REG))
- /* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
- @@ -3470,8 +3576,9 @@
- /* Max number of bytes we can move from memory to memory
- in one reasonably fast instruction. */
- -#define MOVE_MAX (TARGET_64BIT ? 8 : 4)
- -#define MAX_MOVE_MAX 8
- +/* We can do 16 bytes using the r5900's MMI */
- +#define MOVE_MAX (TARGET_MIPS5900 ? (mips_use_128 ? 16 : 8) : (TARGET_64BIT ? 8 : 4))
- +#define MAX_MOVE_MAX (mips_use_128 ? 16 : 8)
- /* Define this macro as a C expression which is nonzero if
- accessing less than a word of memory (i.e. a `char' or a
- @@ -3764,6 +3871,8 @@
- return COSTS_N_INSNS (17); \
- else if (TUNE_MIPS5000) \
- return COSTS_N_INSNS (5); \
- + else if (TUNE_MIPS5900) \
- + return (xmode == SImode ? COSTS_N_INSNS (3) : COSTS_N_INSNS (30));\
- else \
- return COSTS_N_INSNS (10); \
- } \
- @@ -3805,6 +3914,8 @@
- return COSTS_N_INSNS (38); \
- else if (TUNE_MIPS5000) \
- return COSTS_N_INSNS (36); \
- + else if (TUNE_MIPS5900) \
- + return COSTS_N_INSNS (30); \
- else \
- return COSTS_N_INSNS (69); \
- \
- @@ -3910,10 +4021,14 @@
- : GR_REG_CLASS_P (FROM) && (TO) == FP_REGS ? 4 \
- : (FROM) == FP_REGS && GR_REG_CLASS_P (TO) ? 4 \
- : (((FROM) == HI_REG || (FROM) == LO_REG \
- - || (FROM) == MD_REGS || (FROM) == HILO_REG) \
- + || (FROM) == MD_REGS || (FROM) == HILO_REG \
- + || (FROM) == HI1_REG || (FROM) == LO1_REG \
- + || (FROM) == MD1_REGS || (FROM) == HILO1_REG) \
- && GR_REG_CLASS_P (TO)) ? (TARGET_MIPS16 ? 12 : 6) \
- : (((TO) == HI_REG || (TO) == LO_REG \
- - || (TO) == MD_REGS || (TO) == HILO_REG) \
- + || (TO) == MD_REGS || (TO) == HILO_REG \
- + || (TO) == HI1_REG || (TO) == LO1_REG \
- + || (TO) == MD1_REGS || (TO) == HILO1_REG) \
- && GR_REG_CLASS_P (FROM)) ? (TARGET_MIPS16 ? 12 : 6) \
- : (FROM) == ST_REGS && GR_REG_CLASS_P (TO) ? 4 \
- : (FROM) == FP_REGS && (TO) == ST_REGS ? 8 \
- @@ -3947,6 +4062,10 @@
- #define ADJUST_INSN_LENGTH(INSN, LENGTH) \
- ((LENGTH) = mips_adjust_insn_length ((INSN), (LENGTH)))
- +/* The r5900 is a dual issue processor. */
- +#undef ISSUE_RATE
- +#define ISSUE_RATE ((TARGET_MIPS5900) ? 2 : 1)
- +
- /* Optionally define this if you have added predicates to
- `MACHINE.c'. This macro is called within an initializer of an
- @@ -3992,6 +4111,8 @@
- {"movdi_operand", { CONST_INT, CONST_DOUBLE, CONST, \
- SYMBOL_REF, LABEL_REF, SUBREG, REG, \
- MEM, SIGN_EXTEND }}, \
- + {"movti_operand", { REG, MEM, CONST_INT, CONST_DOUBLE, \
- + SUBREG }}, \
- {"se_register_operand", { SUBREG, REG, SIGN_EXTEND }}, \
- {"se_reg_or_0_operand", { REG, CONST_INT, CONST_DOUBLE, SUBREG, \
- SIGN_EXTEND }}, \
- @@ -4147,6 +4268,9 @@
- &mips_reg_names[73][0], \
- &mips_reg_names[74][0], \
- &mips_reg_names[75][0], \
- + &mips_reg_names[76][0], \
- + &mips_reg_names[77][0], \
- + &mips_reg_names[78][0], \
- }
- /* print-rtl.c can't use REGISTER_NAMES, since it depends on mips.c.
- @@ -4162,7 +4286,8 @@
- "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", \
- "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", \
- "hi", "lo", "accum","$fcc0","$fcc1","$fcc2","$fcc3","$fcc4", \
- - "$fcc5","$fcc6","$fcc7","$rap" \
- + "$fcc5","$fcc6","$fcc7","$rap", \
- + "hi1", "lo1", "accum1" \
- }
- /* If defined, a C initializer for an array of structures
- @@ -4415,6 +4540,7 @@
- } while (0)
- /* This says how to define a global common symbol. */
- +/* ASM_OUTPUT_ALIGN (STREAM, floor_log2 (ALIGN / BITS_PER_UNIT)); */
- #define ASM_OUTPUT_ALIGNED_DECL_COMMON(STREAM, DECL, NAME, SIZE, ALIGN) \
- do { \
- @@ -4433,9 +4559,10 @@
- mips_declare_object (STREAM, NAME, "", ":\n\t.space\t%u\n", \
- (SIZE)); \
- } \
- - else \
- - mips_declare_object (STREAM, NAME, "\n\t.comm\t", ",%u\n", \
- - (SIZE)); \
- + else { \
- + mips_declare_object_align (STREAM, NAME, "\n\t.comm\t", ",%u,%u\n", \
- + (SIZE),(ALIGN / BITS_PER_UNIT)); \
- + } \
- } while (0)
- @@ -4547,7 +4674,7 @@
- to a multiple of 2**LOG bytes. */
- #define ASM_OUTPUT_ALIGN(STREAM,LOG) \
- - fprintf (STREAM, "\t.align\t%d\n", (LOG))
- + fprintf (STREAM, "\t.align\t%d\n", (LOG) > mips_align_all ? (LOG) : mips_align_all)
- /* This is how to output an assembler line to advance the location
- counter by SIZE bytes. */
- @@ -4721,6 +4848,15 @@
- PC relative loads that are out of range. */
- #define MACHINE_DEPENDENT_REORG(X) machine_dependent_reorg (X)
- +/* This is used to lengthen short loops on the r5900. */
- +#define MACHINE_DEPENDENT_REORG_FINAL(X) \
- +do \
- + { \
- + if (TARGET_MIPS5900 && ! TARGET_NO_LENGTHEN_LOOP) \
- + machine_dependent_reorg_final (X); \
- + } \
- +while (0)
- +
- /* We need to use a special set of functions to handle hard floating
- point code in mips16 mode. */
- @@ -4793,3 +4929,44 @@
- } \
- } \
- while (0)
- +
- +/* r5900 vector mode & built-in support. */
- +
- +#define VALID_MMI_REG_MODE(MODE) \
- + ((MODE) == TImode || (MODE) == V16QImode || (MODE) == V8HImode \
- + || (MODE) == V4SImode || (MODE) == V4SFmode || (MODE) == V2DImode)
- +
- +#define VALID_VUMM_REG_MODE(MODE) \
- + ((MODE) == TImode || (MODE) == V4SFmode)
- +
- +#define VECTOR_MODE_SUPPORTED_P(MODE) \
- + ((VALID_MMI_REG_MODE (MODE) && TARGET_MMI) \
- + || (VALID_VUMM_REG_MODE (MODE) && TARGET_VUMM) ? 1 : 0)
- +
- +enum r5900_builtins
- +{
- + /* MMI built-ins */
- + MMI_BUILTIN_PADDB,
- + MMI_BUILTIN_PADDH,
- + MMI_BUILTIN_PADDW,
- + MMI_BUILTIN_PADDSB,
- + MMI_BUILTIN_PADDSH,
- + MMI_BUILTIN_PADDSW,
- + MMI_BUILTIN_PADDUB,
- + MMI_BUILTIN_PADDUH,
- + MMI_BUILTIN_PADDUW,
- +
- + MMI_BUILTIN_PSUBB,
- + MMI_BUILTIN_PSUBH,
- + MMI_BUILTIN_PSUBW,
- + MMI_BUILTIN_PSUBSB,
- + MMI_BUILTIN_PSUBSH,
- + MMI_BUILTIN_PSUBSW,
- + MMI_BUILTIN_PSUBUB,
- + MMI_BUILTIN_PSUBUH,
- + MMI_BUILTIN_PSUBUW,
- +
- + /* VU macro mode built-ins */
- +
- + R5900_BUILTIN_MAX
- +};
- diff -burN orig.gcc-3.2.3/gcc/config/mips/mips.md gcc-3.2.3/gcc/config/mips/mips.md
- --- orig.gcc-3.2.3/gcc/config/mips/mips.md 2002-11-11 01:57:14.000000000 -0400
- +++ gcc-3.2.3/gcc/config/mips/mips.md 2015-08-10 16:15:12 +0300
- @@ -84,11 +84,11 @@
- ;; nop no operation
- (define_attr "type"
- - "unknown,branch,jump,call,load,store,move,xfer,hilo,arith,darith,imul,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,multi,nop"
- + "unknown,branch,jump,call,load,store,move,xfer,hilo,arith,darith,imul,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop,mmi,mmi_mul,mmi_div,vmm_mul,vmm_div"
- (const_string "unknown"))
- ;; Main data type used by the insn
- -(define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown"))
- +(define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,FPSW" (const_string "unknown"))
- ;; Length (in # of bytes). A conditional branch is allowed only to a
- ;; location within a signed 18-bit offset of the delay slot. If that
- @@ -121,7 +121,7 @@
- ;; ??? Fix everything that tests this attribute.
- (define_attr "cpu"
- - "default,r3000,r3900,r6000,r4000,r4100,r4300,r4600,r4650,r5000,r8000,r4kc,r5kc,r20kc"
- + "default,r3000,r3900,r6000,r4000,r4100,r4300,r4600,r4650,r5000,r5900,r8000,r4kc,r5kc,r20kc"
- (const (symbol_ref "mips_cpu_attr")))
- ;; Does the instruction have a mandatory delay slot?
- @@ -206,7 +206,7 @@
- (define_function_unit "memory" 1 0
- (and (eq_attr "type" "load")
- - (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
- + (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4300,r5000,r5900"))
- 3 0)
- (define_function_unit "memory" 1 0
- @@ -214,17 +214,20 @@
- (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
- 2 0)
- -(define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
- +(define_function_unit "memory" 1 0
- + (and (eq_attr "type" "store") (eq_attr "cpu" "!r5900")) 1 0)
- -(define_function_unit "memory" 1 0 (eq_attr "type" "xfer") 2 0)
- +(define_function_unit "memory" 1 0
- + (and (eq_attr "type" "xfer") (eq_attr "cpu" "!r5900")) 2 0)
- (define_function_unit "imuldiv" 1 0
- - (eq_attr "type" "hilo")
- + (and (eq_attr "type" "hilo")
- + (eq_attr "cpu" "!r5900"))
- 1 3)
- (define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul")
- - (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
- + (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000,r5900"))
- 17 17)
- ;; On them mips16, we want to stronly discourage a mult from appearing
- @@ -276,7 +279,7 @@
- (define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- - (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
- + (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000,r5900"))
- 38 38)
- (define_function_unit "imuldiv" 1 0
- @@ -333,7 +336,7 @@
- ;; instructions to be processed in the "imuldiv" unit.
- (define_function_unit "adder" 1 1
- - (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
- + (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000,r5900"))
- 3 0)
- (define_function_unit "adder" 1 1
- @@ -345,7 +348,7 @@
- 1 0)
- (define_function_unit "adder" 1 1
- - (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
- + (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5900"))
- 4 0)
- (define_function_unit "adder" 1 1
- @@ -358,7 +361,7 @@
- (define_function_unit "adder" 1 1
- (and (eq_attr "type" "fabs,fneg")
- - (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000"))
- + (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000,r5900"))
- 2 0)
- (define_function_unit "adder" 1 1
- @@ -368,7 +371,7 @@
- (define_function_unit "mult" 1 1
- (and (eq_attr "type" "fmul")
- (and (eq_attr "mode" "SF")
- - (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
- + (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000,r5900")))
- 7 0)
- (define_function_unit "mult" 1 1
- @@ -388,7 +391,7 @@
- (define_function_unit "mult" 1 1
- (and (eq_attr "type" "fmul")
- - (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")))
- + (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000,r5900")))
- 8 0)
- (define_function_unit "mult" 1 1
- @@ -404,7 +407,7 @@
- (define_function_unit "divide" 1 1
- (and (eq_attr "type" "fdiv")
- (and (eq_attr "mode" "SF")
- - (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
- + (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000,r5900")))
- 23 0)
- (define_function_unit "divide" 1 1
- @@ -430,7 +433,7 @@
- (define_function_unit "divide" 1 1
- (and (eq_attr "type" "fdiv")
- (and (eq_attr "mode" "DF")
- - (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300")))
- + (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5900")))
- 36 0)
- (define_function_unit "divide" 1 1
- @@ -451,7 +454,7 @@
- ;;; ??? Is this number right?
- (define_function_unit "divide" 1 1
- (and (eq_attr "type" "fsqrt")
- - (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
- + (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000,r5900")))
- 54 0)
- (define_function_unit "divide" 1 1
- @@ -467,7 +470,7 @@
- ;;; ??? Is this number right?
- (define_function_unit "divide" 1 1
- (and (eq_attr "type" "fsqrt")
- - (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
- + (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000,r5900")))
- 112 0)
- (define_function_unit "divide" 1 1
- @@ -507,6 +510,63 @@
- (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
- 58 58)
- +;; Using a value immediately after a load causes a one cycle delay.
- +(define_function_unit "memory" 1 0
- + (and (eq_attr "type" "load") (eq_attr "cpu" "r5900")) 2 0)
- +
- +;; The r5900 has a store buffer which can cause an interlock for
- +;; consecutive stores in some cases. So try to separate stores.
- +(define_function_unit "memory" 1 0
- + (and (eq_attr "type" "store") (eq_attr "cpu" "r5900")) 2 1)
- +
- +;; Transfer to/from coprocessor. This is just a guess. There may or
- +;; may not be an interlock for such transfers.
- +(define_function_unit "memory" 1 0
- + (and (eq_attr "type" "xfer") (eq_attr "cpu" "r5900")) 2 0)
- +
- +;; The r5900 has two independent ALUs.
- +;; XXX: MM instructions take up both ALUs, work that out properly here
- +(define_function_unit "alu" 2 0
- + (and (eq_attr "type" "move,arith,darith,icmp,nop,mmi,mmi_mul,mmi_div")
- + (eq_attr "cpu" "r5900")) 1 0)
- +
- +;; It also has a seperate branch unit.
- +(define_function_unit "branch" 1 0
- + (and (eq_attr "type" "branch,jump,call")
- + (eq_attr "cpu" "r5900")) 1 0)
- +
- +;; XXX There is differing data between the architecture manual
- +;; about what these values should be.
- +(define_function_unit "r5900imuldiv" 2 0
- + (and (eq_attr "type" "hilo") (eq_attr "cpu" "r5900")) 1 3)
- +
- +(define_function_unit "r5900imuldiv" 2 0
- + (and (eq_attr "type" "imul") (eq_attr "cpu" "r5900")) 4 2)
- +
- +(define_function_unit "r5900imuldiv" 2 0
- + (and (eq_attr "type" "idiv") (eq_attr "cpu" "r5900")) 37 37)
- +
- +;; The r5900 FP unit has three independent units.
- +;; fmac -- all computational instructions except fdiv, fsqrt, rsqrt
- +;; fdiv -- fdiv, fsqrt, rsqrt
- +;; load/store -- load store and transfer unit
- +;;
- +;; It appears that fmac/fdiv can dual issue with load/store.
- +(define_function_unit "fmac" 1 0
- + (and (eq_attr "type" "fadd,fmul,fmadd,fabs,fneg,fcmp,fcvt")
- + (eq_attr "cpu" "r5900")) 3 0)
- +
- +(define_function_unit "fdiv" 1 1
- + (and (eq_attr "type" "fdiv,fsqrt,frsqrt") (eq_attr "cpu" "r5900")) 6 0)
- +
- +;; And now a few fake units to encourage dual issue.
- +;; We can only issue one operation to the FPU per cycle.
- +(define_function_unit "flop" 1 0
- + (and (eq_attr "type"
- + "fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,xfer")
- + (eq_attr "cpu" "r5900")) 1 0)
- +
- +
- ;; The following functional units do not use the cpu type, and use
- ;; much less memory in genattrtab.c.
- @@ -1727,7 +1787,22 @@
- ""
- "
- {
- - if (GENERATE_MULT3_SI || TARGET_MAD)
- + /* mulsi3_mult3_r5900 is just like the other mulsi3_mult3 pattern, except
- + that it has additional alternatives, slightly different output
- + templates and clobbers pseudos instead of scratches.
- +
- + We generate a different pattern merely to keep the sanitize issues from
- + driving us crazy. Long term we may want the other multiply patterns to
- + clobber pseudos instead of scratches. */
- + if (TARGET_MIPS5900)
- + {
- + emit_insn (gen_mulsi3_mult3_r5900 (operands[0], operands[1], operands[2],
- + gen_reg_rtx (SImode),
- + gen_reg_rtx (SImode),
- + gen_reg_rtx (SImode)));
- + DONE;
- + }
- + else if (GENERATE_MULT3_SI || TARGET_MAD)
- emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
- else if (!TARGET_MIPS4000 || TARGET_MIPS16)
- emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
- @@ -1736,6 +1811,23 @@
- DONE;
- }")
- +(define_insn "mulsi3_mult3_r5900"
- + [(set (match_operand:SI 0 "register_operand" "=d,l,d,v")
- + (mult:SI (match_operand:SI 1 "register_operand" "d,d,d,d")
- + (match_operand:SI 2 "register_operand" "d,d,d,d")))
- + (clobber (match_operand:SI 3 "register_operand" "=h,h,u,u"))
- + (clobber (match_operand:SI 4 "register_operand" "=l,X,v,X"))
- + (clobber (match_operand:SI 5 "register_operand" "=a,a,q,q"))]
- + "TARGET_MIPS5900"
- + "*
- +{
- + if (which_alternative == 1 || which_alternative == 3)
- + return \"mult%H5\\t%1,%2\";
- + return \"mult%H5\\t%0,%1,%2\";
- +}"
- + [(set_attr "type" "imul")
- + (set_attr "mode" "SI")])
- +
- (define_insn "mulsi3_mult3"
- [(set (match_operand:SI 0 "register_operand" "=d,l")
- (mult:SI (match_operand:SI 1 "register_operand" "d,d")
- @@ -1743,8 +1835,8 @@
- (clobber (match_scratch:SI 3 "=h,h"))
- (clobber (match_scratch:SI 4 "=l,X"))
- (clobber (match_scratch:SI 5 "=a,a"))]
- - "GENERATE_MULT3_SI
- - || TARGET_MAD"
- + "(GENERATE_MULT3_SI
- + || TARGET_MAD) && !TARGET_MIPS5900"
- "*
- {
- if (which_alternative == 1)
- @@ -1804,6 +1896,31 @@
- ;; "?" to the constraint is too strong, and causes values to be loaded into
- ;; LO even when that's more costly. For now, using "*d" mostly does the
- ;; trick.
- +
- +;; Like the standard multiply-accumulate, except with more alternatives and
- +;; works with both pipelines.
- +;; XXX: Broken for now.
- +(define_insn "*mul_acc_si_r5900"
- + [(set (match_operand:SI 0 "register_operand" "=l,*d,*d,v,*d,*d")
- + (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d,d,d,d")
- + (match_operand:SI 2 "register_operand" "d,d,d,d,d,d"))
- + (match_operand:SI 3 "register_operand" "0,l,*d,0,v,*d")))
- + (clobber (match_scratch:SI 4 "=h,h,h,u,u,u"))
- + (clobber (match_scratch:SI 5 "=X,3,l,X,3,v"))
- + (clobber (match_scratch:SI 6 "=a,a,a,q,q,q"))
- + (clobber (match_scratch:SI 7 "=X,X,d,X,X,d"))]
- + "TARGET_MIPS5900 && !TARGET_MIPS16"
- + "*
- +{
- + static char *const madd[] = { \"madd%H6\\t%1,%2\",
- + \"madd%H6\\t%0,%1,%2\",
- + \"#\" };
- + return madd[which_alternative % 3];
- +}"
- + [(set_attr "type" "imul")
- + (set_attr "mode" "SI")
- + (set_attr "length" "4,4,8,4,4,8")])
- +
- (define_insn "*mul_acc_si"
- [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
- (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
- @@ -1964,7 +2081,7 @@
- (match_operand:DI 2 "register_operand" "d")))
- (clobber (match_scratch:DI 3 "=h"))
- (clobber (match_scratch:DI 4 "=a"))]
- - "TARGET_64BIT"
- + "TARGET_64BIT && !TARGET_MIPS5900"
- "
- {
- @@ -1986,7 +2103,7 @@
- (match_operand:DI 2 "register_operand" "d")))
- (clobber (match_scratch:DI 3 "=h"))
- (clobber (match_scratch:DI 4 "=a"))]
- - "TARGET_64BIT && !TARGET_MIPS4000 && !TARGET_MIPS16"
- + "TARGET_64BIT && !TARGET_MIPS4000 && !TARGET_MIPS16 && !TARGET_MIPS5900"
- "dmult\\t%1,%2"
- [(set_attr "type" "imul")
- (set_attr "mode" "DI")])
- @@ -2032,6 +2149,15 @@
- "
- {
- rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx);
- + if (TARGET_64BIT && TARGET_MIPS5900)
- + {
- + emit_insn (gen_mulsidi3_64bit_r5900 (operands[0], operands[1],
- + operands[2],
- + dummy, dummy,
- + gen_reg_rtx (DImode),
- + gen_reg_rtx (DImode)));
- + DONE;
- + }
- if (TARGET_64BIT)
- emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
- dummy, dummy));
- @@ -2049,6 +2175,15 @@
- "
- {
- rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx);
- + if (TARGET_64BIT && TARGET_MIPS5900)
- + {
- + emit_insn (gen_mulsidi3_64bit_r5900 (operands[0], operands[1],
- + operands[2],
- + dummy, dummy,
- + gen_reg_rtx (DImode),
- + gen_reg_rtx (DImode)));
- + DONE;
- + }
- if (TARGET_64BIT)
- emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
- dummy, dummy));
- @@ -2075,6 +2210,25 @@
- [(set_attr "type" "imul")
- (set_attr "mode" "SI")])
- +(define_insn "mulsidi3_64bit_r5900"
- + [(set (match_operand:DI 0 "register_operand" "=a,q")
- + (mult:DI (match_operator:DI 3 "extend_operator"
- + [(match_operand:SI 1 "register_operand" "d,d")])
- + (match_operator:DI 4 "extend_operator"
- + [(match_operand:SI 2 "register_operand" "d,d")])))
- + (clobber (match_operand:DI 5 "register_operand" "=l,v"))
- + (clobber (match_operand:DI 6 "register_operand" "=h,u"))]
- + "TARGET_64BIT && TARGET_MIPS5900
- + && GET_CODE (operands[3]) == GET_CODE (operands[4])"
- + "*
- +{
- + if (GET_CODE (operands[3]) == SIGN_EXTEND)
- + return \"mult%H0\\t%1,%2\";
- + return \"multu%H0\\t%1,%2\";
- +}"
- + [(set_attr "type" "imul")
- + (set_attr "mode" "SI")])
- +
- (define_insn "mulsidi3_64bit"
- [(set (match_operand:DI 0 "register_operand" "=a")
- (mult:DI (match_operator:DI 3 "extend_operator"
- @@ -2111,6 +2265,8 @@
- rtx (*genfn) ();
- #endif
- genfn = gen_xmulsi3_highpart_internal;
- + if (TARGET_MIPS5900)
- + genfn = gen_xmulsi3_highpart_r5900;
- emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
- dummy, dummy2));
- DONE;
- @@ -2132,12 +2288,36 @@
- #else
- rtx (*genfn) ();
- #endif
- + if (TARGET_MIPS5900)
- + genfn = gen_xmulsi3_highpart_r5900;
- genfn = gen_xmulsi3_highpart_internal;
- emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
- dummy, dummy2));
- DONE;
- }")
- +(define_insn "xmulsi3_highpart_r5900"
- + [(set (match_operand:SI 0 "register_operand" "=h,u")
- + (truncate:SI
- + (match_operator:DI 5 "highpart_shift_operator"
- + [(mult:DI (match_operator:DI 3 "extend_operator"
- + [(match_operand:SI 1 "register_operand" "d,d")])
- + (match_operator:DI 4 "extend_operator"
- + [(match_operand:SI 2 "register_operand" "d,d")]))
- + (const_int 32)])))
- + (clobber (match_scratch:SI 6 "=l,v"))
- + (clobber (match_scratch:SI 7 "=a,q"))]
- + "TARGET_MIPS5900 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
- + "*
- +{
- + if (GET_CODE (operands[3]) == SIGN_EXTEND)
- + return \"mult%H0\\t%1,%2\";
- + else
- + return \"multu%H0\\t%1,%2\";
- +}"
- + [(set_attr "type" "imul")
- + (set_attr "mode" "SI")])
- +
- (define_insn "xmulsi3_highpart_internal"
- [(set (match_operand:SI 0 "register_operand" "=h")
- (truncate:SI
- @@ -2168,7 +2348,7 @@
- (const_int 64))))
- (clobber (match_scratch:DI 3 "=l"))
- (clobber (match_scratch:DI 4 "=a"))]
- - "TARGET_64BIT"
- + "TARGET_64BIT && !TARGET_MIPS5900"
- "dmult\\t%1,%2"
- [(set_attr "type" "imul")
- (set_attr "mode" "DI")])
- @@ -2181,7 +2361,7 @@
- (const_int 64))))
- (clobber (match_scratch:DI 3 "=l"))
- (clobber (match_scratch:DI 4 "=a"))]
- - "TARGET_64BIT"
- + "TARGET_64BIT && !TARGET_MIPS5900"
- "dmultu\\t%1,%2"
- [(set_attr "type" "imul")
- (set_attr "mode" "DI")])
- @@ -2397,8 +2577,15 @@
- "optimize"
- "
- {
- + if (TARGET_MIPS5900)
- + {
- + emit_insn (gen_divmodsi4_internal_r5900 (operands[0], operands[1],
- + operands[2], operands[3]));
- + goto zero_div_check;
- + }
- emit_insn (gen_divmodsi4_internal (operands[0], operands[1], operands[2],
- operands[3]));
- +zero_div_check:
- if (!TARGET_NO_CHECK_ZERO_DIV)
- {
- emit_insn (gen_div_trap (operands[2],
- @@ -2421,6 +2608,19 @@
- DONE;
- }")
- +(define_insn "divmodsi4_internal_r5900"
- + [(set (match_operand:SI 0 "register_operand" "=l,v")
- + (div:SI (match_operand:SI 1 "register_operand" "d,d")
- + (match_operand:SI 2 "register_operand" "d,d")))
- + (set (match_operand:SI 3 "register_operand" "=h,u")
- + (mod:SI (match_dup 1)
- + (match_dup 2)))
- + (clobber (match_scratch:SI 4 "=a,q"))]
- + "optimize && TARGET_MIPS5900"
- + "div%H0\\t$0,%1,%2"
- + [(set_attr "type" "idiv")
- + (set_attr "mode" "SI")])
- +
- (define_insn "divmodsi4_internal"
- [(set (match_operand:SI 0 "register_operand" "=l")
- (div:SI (match_operand:SI 1 "register_operand" "d")
- @@ -2429,7 +2629,7 @@
- (mod:SI (match_dup 1)
- (match_dup 2)))
- (clobber (match_scratch:SI 4 "=a"))]
- - "optimize"
- + "optimize && !TARGET_MIPS5900"
- "div\\t$0,%1,%2"
- [(set_attr "type" "idiv")
- (set_attr "mode" "SI")])
- @@ -2444,7 +2644,7 @@
- (clobber (match_scratch:DI 4 "=l"))
- (clobber (match_scratch:DI 5 "=h"))
- (clobber (match_scratch:DI 6 "=a"))]
- - "TARGET_64BIT && optimize"
- + "TARGET_64BIT && optimize && !TARGET_MIPS5900"
- "
- {
- emit_insn (gen_divmoddi4_internal (operands[0], operands[1], operands[2],
- @@ -2477,7 +2677,7 @@
- (mod:DI (match_dup 1)
- (match_dup 2)))
- (clobber (match_scratch:DI 4 "=a"))]
- - "TARGET_64BIT && optimize"
- + "TARGET_64BIT && optimize && !TARGET_MIPS5900"
- "ddiv\\t$0,%1,%2"
- [(set_attr "type" "idiv")
- (set_attr "mode" "SI")])
- @@ -2495,8 +2695,15 @@
- "optimize"
- "
- {
- + if (TARGET_MIPS5900)
- + {
- + emit_insn (gen_udivmodsi4_internal_r5900 (operands[0], operands[1],
- + operands[2], operands[3]));
- + goto zero_div_check;
- + }
- emit_insn (gen_udivmodsi4_internal (operands[0], operands[1], operands[2],
- operands[3]));
- +zero_div_check:
- if (!TARGET_NO_CHECK_ZERO_DIV)
- {
- emit_insn (gen_div_trap (operands[2],
- @@ -2507,6 +2714,19 @@
- DONE;
- }")
- +(define_insn "udivmodsi4_internal_r5900"
- + [(set (match_operand:SI 0 "register_operand" "=l,v")
- + (udiv:SI (match_operand:SI 1 "register_operand" "d,d")
- + (match_operand:SI 2 "register_operand" "d,d")))
- + (set (match_operand:SI 3 "register_operand" "=h,u")
- + (umod:SI (match_dup 1)
- + (match_dup 2)))
- + (clobber (match_scratch:SI 4 "=a,q"))]
- + "optimize && TARGET_MIPS5900"
- + "divu%H0\\t$0,%1,%2"
- + [(set_attr "type" "idiv")
- + (set_attr "mode" "SI")])
- +
- (define_insn "udivmodsi4_internal"
- [(set (match_operand:SI 0 "register_operand" "=l")
- (udiv:SI (match_operand:SI 1 "register_operand" "d")
- @@ -2515,7 +2735,7 @@
- (umod:SI (match_dup 1)
- (match_dup 2)))
- (clobber (match_scratch:SI 4 "=a"))]
- - "optimize"
- + "optimize && !TARGET_MIPS5900"
- "divu\\t$0,%1,%2"
- [(set_attr "type" "idiv")
- (set_attr "mode" "SI")])
- @@ -2530,7 +2750,7 @@
- (clobber (match_scratch:DI 4 "=l"))
- (clobber (match_scratch:DI 5 "=h"))
- (clobber (match_scratch:DI 6 "=a"))]
- - "TARGET_64BIT && optimize"
- + "TARGET_64BIT && optimize && !TARGET_MIPS5900"
- "
- {
- emit_insn (gen_udivmoddi4_internal (operands[0], operands[1], operands[2],
- @@ -2553,7 +2773,7 @@
- (umod:DI (match_dup 1)
- (match_dup 2)))
- (clobber (match_scratch:DI 4 "=a"))]
- - "TARGET_64BIT && optimize"
- + "TARGET_64BIT && optimize && !TARGET_MIPS5900"
- "ddivu\\t$0,%1,%2"
- [(set_attr "type" "idiv")
- (set_attr "mode" "SI")])
- @@ -2651,6 +2871,7 @@
- [(set_attr "type" "unknown")
- (set_attr "length" "12")])
- +;; Add r5900-specific div here.
- (define_expand "divsi3"
- [(set (match_operand:SI 0 "register_operand" "=l")
- (div:SI (match_operand:SI 1 "register_operand" "d")
- @@ -2700,7 +2921,7 @@
- (match_operand:DI 2 "se_register_operand" "d")))
- (clobber (match_scratch:DI 3 "=h"))
- (clobber (match_scratch:DI 4 "=a"))]
- - "TARGET_64BIT && !optimize"
- + "TARGET_64BIT && !optimize && !TARGET_MIPS5900"
- "
- {
- emit_insn (gen_divdi3_internal (operands[0], operands[1], operands[2]));
- @@ -2730,11 +2951,12 @@
- (match_operand:DI 2 "se_nonmemory_operand" "di")))
- (clobber (match_scratch:SI 3 "=h"))
- (clobber (match_scratch:SI 4 "=a"))]
- - "TARGET_64BIT && !optimize"
- + "TARGET_64BIT && !optimize && !TARGET_MIPS5900"
- "ddiv\\t$0,%1,%2"
- [(set_attr "type" "idiv")
- (set_attr "mode" "DI")])
- +;; XXX: add r5900-specific support here
- (define_expand "modsi3"
- [(set (match_operand:SI 0 "register_operand" "=h")
- (mod:SI (match_operand:SI 1 "register_operand" "d")
- @@ -2784,7 +3006,7 @@
- (match_operand:DI 2 "se_register_operand" "d")))
- (clobber (match_scratch:DI 3 "=l"))
- (clobber (match_scratch:DI 4 "=a"))]
- - "TARGET_64BIT && !optimize"
- + "TARGET_64BIT && !optimize && !TARGET_MIPS5900"
- "
- {
- emit_insn (gen_moddi3_internal (operands[0], operands[1], operands[2]));
- @@ -2814,11 +3036,12 @@
- (match_operand:DI 2 "se_nonmemory_operand" "di")))
- (clobber (match_scratch:SI 3 "=l"))
- (clobber (match_scratch:SI 4 "=a"))]
- - "TARGET_64BIT && !optimize"
- + "TARGET_64BIT && !optimize && !TARGET_MIPS5900"
- "ddiv\\t$0,%1,%2"
- [(set_attr "type" "idiv")
- (set_attr "mode" "DI")])
- +;; XXX: Add r5900-specific support here
- (define_expand "udivsi3"
- [(set (match_operand:SI 0 "register_operand" "=l")
- (udiv:SI (match_operand:SI 1 "register_operand" "d")
- @@ -2856,7 +3079,7 @@
- (match_operand:DI 2 "se_register_operand" "di")))
- (clobber (match_scratch:DI 3 "=h"))
- (clobber (match_scratch:DI 4 "=a"))]
- - "TARGET_64BIT && !optimize"
- + "TARGET_64BIT && !optimize && !TARGET_MIPS5900"
- "
- {
- emit_insn (gen_udivdi3_internal (operands[0], operands[1], operands[2]));
- @@ -2876,11 +3099,12 @@
- (match_operand:DI 2 "se_nonmemory_operand" "di")))
- (clobber (match_scratch:SI 3 "=h"))
- (clobber (match_scratch:SI 4 "=a"))]
- - "TARGET_64BIT && !optimize"
- + "TARGET_64BIT && !optimize && !TARGET_MIPS5900"
- "ddivu\\t$0,%1,%2"
- [(set_attr "type" "idiv")
- (set_attr "mode" "DI")])
- +;; XXX: add r5900-specific support here
- (define_expand "umodsi3"
- [(set (match_operand:SI 0 "register_operand" "=h")
- (umod:SI (match_operand:SI 1 "register_operand" "d")
- @@ -2918,7 +3142,7 @@
- (match_operand:DI 2 "se_register_operand" "di")))
- (clobber (match_scratch:DI 3 "=l"))
- (clobber (match_scratch:DI 4 "=a"))]
- - "TARGET_64BIT && !optimize"
- + "TARGET_64BIT && !optimize && !TARGET_MIPS5900"
- "
- {
- emit_insn (gen_umoddi3_internal (operands[0], operands[1], operands[2]));
- @@ -2938,7 +3162,7 @@
- (match_operand:DI 2 "se_nonmemory_operand" "di")))
- (clobber (match_scratch:SI 3 "=l"))
- (clobber (match_scratch:SI 4 "=a"))]
- - "TARGET_64BIT && !optimize"
- + "TARGET_64BIT && !optimize && !TARGET_MIPS5900"
- "ddivu\\t$0,%1,%2"
- [(set_attr "type" "idiv")
- (set_attr "mode" "DI")])
- @@ -2979,7 +3203,7 @@
- [(set (match_operand:SF 0 "register_operand" "=f")
- (div:SF (match_operand:SF 1 "const_float_1_operand" "")
- (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
- - "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
- + "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_MIPS5900 && flag_unsafe_math_optimizations"
- "rsqrt.s\\t%0,%2"
- [(set_attr "type" "fsqrt")
- (set_attr "mode" "SF")])
- @@ -3061,6 +3285,37 @@
- (set_attr "mode" "SF")])
- +;; ....................
- +;;
- +;; MIN, MAX
- +;;
- +;; ....................
- +
- +(define_insn "minsf3"
- + [(set (match_operand:SF 0 "register_operand" "=f")
- + (if_then_else (lt:SF
- + (match_operand:SF 1 "register_operand" "f")
- + (match_operand:SF 2 "register_operand" "f"))
- + (match_dup 1)
- + (match_dup 2)))]
- + "TARGET_HARD_FLOAT && TARGET_MIPS5900"
- + "min.s\\t%0,%1,%2"
- + [(set_attr "type" "fadd")
- + (set_attr "mode" "SF")])
- +
- +(define_insn "maxsf3"
- + [(set (match_operand:SF 0 "register_operand" "=f")
- + (if_then_else (gt:SF
- + (match_operand:SF 1 "register_operand" "f")
- + (match_operand:SF 2 "register_operand" "f"))
- + (match_dup 1)
- + (match_dup 2)))]
- + "TARGET_HARD_FLOAT && TARGET_MIPS5900"
- + "max.s\\t%0,%1,%2"
- + [(set_attr "type" "fadd")
- + (set_attr "mode" "SF")])
- +
- +
- ;;
- ;; ....................
- ;;
- @@ -3081,6 +3336,38 @@
- dslots_jump_filled += 2;
- operands[4] = const0_rtx;
- + if (TARGET_MIPS5900 && !TARGET_NO_LENGTHEN_LOOP ) {
- + if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
- + return \"%(\\
- +move\\t%0,%z4\\n\\
- +\\tbeq\\t%1,%z4,2f\\n\\
- +1:\\tand\\t%2,%1,0x0001\\n\\
- +\\taddu\\t%0,%0,1\\n\\
- +\\tbne\\t%2,%z4,2f\\n\\
- +\\tsrl\\t%1,%1,1\\n\\
- +\\n\\
- +\\tand\\t%2,%1,0x0001\\n\\
- +\\taddu\\t%0,%0,1\\n\\
- +\\tbeq\\t%2,%z4,1b\\n\\
- +\\tsrl\\t%1,%1,1\\n\\
- +2:%)\";
- +
- + return \"%(\\
- +move\\t%0,%z4\\n\\
- +\\tmove\\t%3,%1\\n\\
- +\\tbeq\\t%3,%z4,2f\\n\\
- +1:\\tand\\t%2,%3,0x0001\\n\\
- +\\taddu\\t%0,%0,1\\n\\
- +\\tbne\\t%2,%z4,2f\\n\\
- +\\tsrl\\t%3,%3,1\\n\\
- +\\n\\
- +\\tand\\t%2,%3,0x0001\\n\\
- +\\taddu\\t%0,%0,1\\n\\
- +\\tbeq\\t%2,%z4,1b\\n\\
- +\\tsrl\\t%3,%3,1\\n\\
- +2:%)\";
- + }
- +
- if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
- return \"%(\\
- move\\t%0,%z4\\n\\
- @@ -3103,7 +3390,11 @@
- }"
- [(set_attr "type" "multi")
- (set_attr "mode" "SI")
- - (set_attr "length" "12")])
- + (set (attr "length")
- + (if_then_else (and (ne (const_int 0) (symbol_ref "TARGET_MIPS5900") )
- + (eq (const_int 0) (symbol_ref "TARGET_NO_LENGTHEN_LOOP")))
- + (const_int 44)
- + (const_int 24))) ])
- (define_insn "ffsdi2"
- [(set (match_operand:DI 0 "register_operand" "=&d")
- @@ -3117,6 +3408,38 @@
- dslots_jump_filled += 2;
- operands[4] = const0_rtx;
- + if (TARGET_MIPS5900 && !TARGET_NO_LENGTHEN_LOOP ) {
- + if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
- + return \"%(\\
- +move\\t%0,%z4\\n\\
- +\\tbeq\\t%1,%z4,2f\\n\\
- +1:\\tand\\t%2,%1,0x0001\\n\\
- +\\tdaddu\\t%0,%0,1\\n\\
- +\\tbne\\t%2,%z4,2f\\n\\
- +\\tdsrl\\t%1,%1,1\\n\\
- +\\n\\
- +\\tand\\t%2,%1,0x0001\\n\\
- +\\tdaddu\\t%0,%0,1\\n\\
- +\\tbeq\\t%2,%z4,1b\\n\\
- +\\tdsrl\\t%1,%1,1\\n\\
- +2:%)\";
- +
- + return \"%(\\
- +move\\t%0,%z4\\n\\
- +\\tmove\\t%3,%1\\n\\
- +\\tbeq\\t%3,%z4,2f\\n\\
- +1:\\tand\\t%2,%3,0x0001\\n\\
- +\\tdaddu\\t%0,%0,1\\n\\
- +\\tbne\\t%2,%z4,2f\\n\\
- +\\tdsrl\\t%3,%3,1\\n\\
- +\\n\\
- +\\tand\\t%2,%3,0x0001\\n\\
- +\\tdaddu\\t%0,%0,1\\n\\
- +\\tbeq\\t%2,%z4,1b\\n\\
- +\\tdsrl\\t%3,%3,1\\n\\
- +2:%)\";
- + }
- +
- if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
- return \"%(\\
- move\\t%0,%z4\\n\\
- @@ -3139,7 +3462,11 @@
- }"
- [(set_attr "type" "multi")
- (set_attr "mode" "DI")
- - (set_attr "length" "24")])
- + (set (attr "length")
- + (if_then_else (and (ne (const_int 0) (symbol_ref "TARGET_MIPS5900") )
- + (eq (const_int 0) (symbol_ref "TARGET_NO_LENGTHEN_LOOP")))
- + (const_int 44)
- + (const_int 24))) ])
- ;;
- @@ -3271,6 +3598,18 @@
- (set (subreg:SI (match_dup 0) 4) (not:SI (subreg:SI (match_dup 1) 4)))]
- "")
- +(define_insn "one_cmplti2"
- + [(set (match_operand:TI 0 "register_operand" "=d")
- + (not:TI (match_operand:TI 1 "register_operand" "d")))]
- + "TARGET_MIPS5900"
- + "*
- +{
- + operands[2] = const0_rtx;
- + return \"pnor\\t%0,%z2,%1\";
- +}"
- + [(set_attr "type" "mmi")
- + (set_attr "mode" "TI")])
- +
- ;;
- ;; ....................
- @@ -3386,6 +3725,17 @@
- [(set_attr "type" "arith")
- (set_attr "mode" "DI")])
- +(define_insn "andti3"
- + [(set (match_operand:TI 0 "register_operand" "=d,d")
- + (and:TI (match_operand:TI 1 "register_operand" "%0,d")
- + (match_operand:TI 2 "register_operand" "d,d")))]
- + "TARGET_MIPS5900"
- + "@
- + pand\\t%0,%2
- + pand\\t%0,%1,%2"
- + [(set_attr "type" "mmi")
- + (set_attr "mode" "TI")])
- +
- (define_expand "iorsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
- @@ -3477,6 +3827,17 @@
- (set (subreg:SI (match_dup 0) 4) (ior:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))]
- "")
- +(define_insn "iorti3"
- + [(set (match_operand:TI 0 "register_operand" "=d,d")
- + (ior:TI (match_operand:TI 1 "register_operand" "%0,d")
- + (match_operand:TI 2 "register_operand" "d,d")))]
- + "TARGET_MIPS5900"
- + "@
- + por\\t%0,%2
- + por\\t%0,%1,%2"
- + [(set_attr "type" "mmi")
- + (set_attr "mode" "TI")])
- +
- (define_expand "xorsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
- @@ -3591,6 +3952,17 @@
- [(set_attr "type" "arith")
- (set_attr "mode" "DI")])
- +(define_insn "xorti3"
- + [(set (match_operand:TI 0 "register_operand" "=d,d")
- + (xor:TI (match_operand:TI 1 "register_operand" "%0,d")
- + (match_operand:TI 2 "register_operand" "d,d")))]
- + "TARGET_MIPS5900"
- + "@
- + pxor\\t%0,%2
- + pxor\\t%0,%1,%2"
- + [(set_attr "type" "mmi")
- + (set_attr "mode" "TI")])
- +
- (define_insn "*norsi3"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
- @@ -3632,6 +4004,18 @@
- (set (subreg:SI (match_dup 0) 4) (and:SI (not:SI (subreg:SI (match_dup 1) 4)) (not:SI (subreg:SI (match_dup 2) 4))))]
- "")
- +(define_insn "*norti3"
- + [(set (match_operand:TI 0 "register_operand" "=d,d")
- + (and:TI (not:TI (match_operand:TI 1 "register_operand" "%0,d"))
- + (not:TI (match_operand:TI 2 "register_operand" "d,d"))))]
- + "TARGET_MIPS5900"
- + "@
- + pnor\\t%0,%2
- + pnor\\t%0,%1,%2"
- + [(set_attr "type" "mmi")
- + (set_attr "mode" "TI")])
- +
- +
- ;;
- ;; ....................
- ;;
- @@ -4073,7 +4457,7 @@
- (define_insn "extendsidi2"
- [(set (match_operand:DI 0 "register_operand" "=d,y,d,*d,d,d")
- - (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,d,y,*x,R,m")))]
- + (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,d,y,*x*w,R,m")))]
- "TARGET_64BIT"
- "* return mips_move_1word (operands, insn, FALSE);"
- [(set_attr "type" "move,move,move,hilo,load,load")
- @@ -4299,6 +4683,21 @@
- {
- rtx xoperands[10];
- + /* trunc.w.s isn't implemented on the r5900, but cvt.w.s */
- + /* truncates, so use it here. */
- + if (TARGET_MIPS5900)
- + {
- + if (which_alternative == 1)
- + return \"cvt.w.s %0,%1\";
- +
- + output_asm_insn (\"cvt.w.s %3,%1\", operands);
- +
- + xoperands[0] = operands[0];
- + xoperands[1] = operands[3];
- + output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
- + return \"\";
- + }
- +
- if (which_alternative == 1)
- return \"trunc.w.s %0,%1,%2\";
- @@ -4912,6 +5311,86 @@
- [(set_attr "type" "arith")
- (set_attr "mode" "SI")])
- +;; 128-bit integer moves
- +
- +;; Unlike most other insns, the move insns can't be split with
- +;; different predicates, because register spilling and other parts of
- +;; the compiler, have memoized the insn number already.
- +
- +(define_expand "movti"
- + [(set (match_operand:TI 0 "nonimmediate_operand" "")
- + (match_operand:TI 1 "general_operand" ""))]
- + "TARGET_MIPS5900"
- + "
- +{
- + /* I think this code is unnecessary since we'll never split when
- + the mode is larger than UNITS_PER_WORD. */
- + if (mips_split_addresses && mips_check_split (operands[1], TImode))
- + {
- + enum machine_mode mode = GET_MODE (operands[0]);
- + rtx tem = ((reload_in_progress | reload_completed)
- + ? operands[0] : gen_reg_rtx (mode));
- +
- + emit_insn (gen_rtx (SET, VOIDmode, tem,
- + gen_rtx (HIGH, mode, operands[1])));
- +
- + operands[1] = gen_rtx (LO_SUM, mode, tem, operands[1]);
- + }
- +
- + /* If we are generating embedded PIC code, and we are referring to a
- + symbol in the .text section, we must use an offset from the start
- + of the function.
- +
- + For now we abort this case on the R5900. */
- + if (TARGET_EMBEDDED_PIC
- + && (GET_CODE (operands[1]) == LABEL_REF
- + || (GET_CODE (operands[1]) == SYMBOL_REF
- + && ! SYMBOL_REF_FLAG (operands[1]))))
- + abort ();
- +
- + /* If operands[1] is a constant address illegal for pic, then we need to
- + handle it just like LEGITIMIZE_ADDRESS does.
- + For now we abort this case on the R5900. */
- + if (flag_pic && pic_address_needs_scratch (operands[1]))
- + abort ();
- +
- + /* Make operand1 a register if it isn't already. */
- + if ((reload_in_progress | reload_completed) == 0
- + && !register_operand (operands[0], TImode)
- + && !register_operand (operands[1], TImode)
- + && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
- + && operands[1] != CONST0_RTX (TImode))
- + {
- + rtx temp = force_reg (TImode, operands[1]);
- + emit_move_insn (operands[0], temp);
- + DONE;
- + }
- +}")
- +
- +(define_insn "movti_internal"
- + [(set (match_operand:TI 0 "nonimmediate_operand" "=d,d,d,R,m,d,d,d,d,d")
- + (match_operand:TI 1 "movti_operand" "d,R,m,d,d,J,K,L,M,i"))]
- + "TARGET_MIPS5900
- + && (register_operand (operands[0], TImode)
- + || se_register_operand (operands[1], TImode)
- + || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
- + || operands[1] == CONST0_RTX (TImode))"
- + "@
- + por %0,$0,%1
- + lq %0,%1
- + lq %0,%1
- + sq %1,%0
- + sq %1,%0
- + por %0,%.,%.
- + por\\t%0,%.,%.\;li\\t%0,%1 \\t\\t\\t# ori
- + por\\t%0,%.,%.\;li\\t%0,%1 \\t\\t\\t# lui
- + por\\t%0,%.,%.\;dli\\t%0,%1 \\t\\t\\t# general li macro
- + dli\\t%0,%M1\;pcpyld\\t%0,%0,%.\;dli\\t%0,%L1"
- + [(set_attr "type" "mmi,load,load,store,store,mmi,mmi,mmi,mmi,mmi")
- + (set_attr "mode" "TI")
- +;; The general li macro on a 64 bit machine can be up to 7 instructions long.
- + (set_attr "length" "4,4,4,4,4,4,16,16,32,60")])
- +
- ;; 64-bit integer moves
- ;; Unlike most other insns, the move insns can't be split with
- @@ -5039,7 +5518,7 @@
- (set_attr "length" "4,8")])
- (define_insn "movdi_internal"
- - [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*x,*d,*x")
- + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*x*w,*d,*x*w")
- (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,J,*x,*d"))]
- "!TARGET_64BIT && !TARGET_MIPS16
- && (register_operand (operands[0], DImode)
- @@ -5075,8 +5554,8 @@
- "")
- (define_insn "movdi_internal2"
- - [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*x,*d,*x,*a")
- - (match_operand:DI 1 "movdi_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,J,*x,*d,*J"))]
- + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*x*w,*d,*x*w,*a*q")
- + (match_operand:DI 1 "movdi_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,J,*x*w,*d,*J"))]
- "TARGET_64BIT && !TARGET_MIPS16
- && (register_operand (operands[0], DImode)
- || se_register_operand (operands[1], DImode)
- @@ -5089,7 +5568,7 @@
- (define_insn ""
- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,R,m,*d")
- - (match_operand:DI 1 "movdi_operand" "d,d,y,K,N,s,R,m,d,d,*x"))]
- + (match_operand:DI 1 "movdi_operand" "d,d,y,K,N,s,R,m,d,d,*x*w"))]
- "TARGET_64BIT && TARGET_MIPS16
- && (register_operand (operands[0], DImode)
- || se_register_operand (operands[1], DImode))"
- @@ -5180,7 +5659,7 @@
- ? REGNO (operands[2]) + 1
- : REGNO (operands[2])));
- - if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
- + if (GET_CODE (operands[0]) == REG && ( REGNO (operands[0]) == HILO_REGNUM || REGNO (operands[0]) == HILO1_REGNUM ) )
- {
- if (GET_CODE (operands[1]) == MEM)
- {
- @@ -5203,28 +5682,45 @@
- lo_word = memword;
- }
- emit_move_insn (scratch, hi_word);
- + if( REGNO (operands[0]) == HILO_REGNUM )
- emit_move_insn (gen_rtx_REG (SImode, 64), scratch);
- + else
- + emit_move_insn (gen_rtx_REG (SImode, 76), scratch);
- emit_move_insn (scratch, lo_word);
- + if( REGNO (operands[0]) == HILO_REGNUM )
- emit_move_insn (gen_rtx (REG, SImode, 65), scratch);
- + else
- + emit_move_insn (gen_rtx (REG, SImode, 77), scratch);
- emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[0]), 2));
- }
- else
- {
- emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
- + if( REGNO (operands[0]) == HILO_REGNUM )
- emit_insn (gen_movdi (gen_rtx_REG (DImode, 64), scratch));
- + else
- + emit_insn (gen_movdi (gen_rtx_REG (DImode, 76), scratch));
- emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
- emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
- + if( REGNO (operands[0]) == HILO_REGNUM )
- emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
- - emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[0]), 2));
- + else
- + emit_insn (gen_movdi (gen_rtx (REG, DImode, 77), scratch));
- }
- DONE;
- }
- - if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
- + if (GET_CODE (operands[1]) == REG && ( REGNO (operands[1]) == HILO_REGNUM || REGNO (operands[1]) == HILO1_REGNUM ) )
- {
- + if( REGNO (operands[1]) == HILO_REGNUM )
- emit_insn (gen_movdi (scratch, gen_rtx_REG (DImode, 65)));
- + else
- + emit_insn (gen_movdi (scratch, gen_rtx_REG (DImode, 76)));
- emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
- emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
- + if( REGNO (operands[1]) == HILO_REGNUM )
- emit_insn (gen_movdi (operands[0], gen_rtx_REG (DImode, 64)));
- + else
- + emit_insn (gen_movdi (operands[0], gen_rtx_REG (DImode, 77)));
- emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
- emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
- emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[1]), 2));
- @@ -5242,7 +5738,7 @@
- ;; use a TImode scratch reg.
- (define_expand "reload_outdi"
- - [(set (match_operand:DI 0 "general_operand" "=b")
- + [(set (match_operand:DI 0 "" "=b")
- (match_operand:DI 1 "se_register_operand" "b"))
- (clobber (match_operand:TI 2 "register_operand" "=&d"))]
- "TARGET_64BIT"
- @@ -5250,17 +5746,23 @@
- {
- rtx scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
- - if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
- + if (GET_CODE (operands[0]) == REG && ( REGNO (operands[0]) == HILO_REGNUM || REGNO (operands[0]) == HILO1_REGNUM ) )
- {
- emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
- + if( REGNO (operands[0]) == HILO_REGNUM )
- emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
- + else
- + emit_insn (gen_movdi (gen_rtx (REG, DImode, 76), scratch));
- emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
- emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
- + if( REGNO (operands[0]) == HILO_REGNUM )
- emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
- + else
- + emit_insn (gen_movdi (gen_rtx (REG, DImode, 77), scratch));
- emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[0]), 2));
- DONE;
- }
- - if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
- + if (GET_CODE (operands[1]) == REG && ( REGNO (operands[1]) == HILO_REGNUM || REGNO (operands[1]) == HILO1_REGNUM ) )
- {
- if (GET_CODE (operands[0]) == MEM)
- {
- @@ -5282,9 +5784,15 @@
- hi_word = offword;
- lo_word = memword;
- }
- + if( REGNO (operands[1]) == HILO_REGNUM )
- emit_move_insn (scratch, gen_rtx_REG (SImode, 64));
- + else
- + emit_move_insn (scratch, gen_rtx_REG (SImode, 76));
- emit_move_insn (hi_word, scratch);
- + if( REGNO (operands[1]) == HILO_REGNUM )
- emit_move_insn (scratch, gen_rtx_REG (SImode, 65));
- + else
- + emit_move_insn (scratch, gen_rtx_REG (SImode, 77));
- emit_move_insn (lo_word, scratch);
- emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[1]), 2));
- }
- @@ -5294,10 +5802,16 @@
- and hence we can not directly move from the HILO register
- into it. */
- rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
- + if( REGNO (operands[1]) == HILO_REGNUM )
- emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
- + else
- + emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 77)));
- emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
- emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
- + if( REGNO (operands[1]) == HILO_REGNUM )
- emit_insn (gen_movdi (scratch2, gen_rtx (REG, DImode, 64)));
- + else
- + emit_insn (gen_movdi (scratch2, gen_rtx (REG, DImode, 76)));
- emit_insn (gen_ashldi3 (scratch2, scratch2, GEN_INT (32)));
- emit_insn (gen_iordi3 (scratch, scratch, scratch2));
- emit_insn (gen_movdi (operands[0], scratch));
- @@ -5305,10 +5819,16 @@
- }
- else
- {
- + if( REGNO (operands[1]) == HILO_REGNUM )
- emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
- + else
- + emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 77)));
- emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
- emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
- + if( REGNO (operands[1]) == HILO_REGNUM )
- emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
- + else
- + emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 76)));
- emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
- emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
- emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[1]), 2));
- @@ -5468,8 +5988,8 @@
- ;; in FP registers (off by default, use -mdebugh to enable).
- (define_insn "movsi_internal1"
- - [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*f*z,*f,*f,*f,*R,*m,*x,*x,*d,*d")
- - (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*f*z,*d,*f,*R,*m,*f,*f,J,*d,*x,*a"))]
- + [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*f*z,*f,*f,*f,*R,*m,*x*w,*x*w,*d,*d")
- + (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*f*z,*d,*f,*R,*m,*f,*f,J,*d,*x*w,*a*q"))]
- "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
- && (register_operand (operands[0], SImode)
- || register_operand (operands[1], SImode)
- @@ -5480,8 +6000,8 @@
- (set_attr "length" "4,8,4,8,4,8,4,8,4,4,4,4,8,4,8,4,4,4,4")])
- (define_insn "movsi_internal2"
- - [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*z,*x,*d,*x,*d")
- - (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,J,*x,*d,*a"))]
- + [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d, d, d,d,d, R, m,*d,*z,*x*w,*d,*x*w,*d")
- + (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,J,*x*w,*d,*a*q"))]
- "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
- && (register_operand (operands[0], SImode)
- || register_operand (operands[1], SImode)
- @@ -5764,7 +6284,7 @@
- ;; This insn is for the unspec delay for HILO.
- -(define_insn "*HILO_delay"
- +(define_insn "HILO_delay"
- [(unspec [(match_operand 0 "register_operand" "=b")] 2 )]
- ""
- ""
- @@ -5937,8 +6457,8 @@
- ;; in FP registers (off by default, use -mdebugh to enable).
- (define_insn "movhi_internal1"
- - [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f*z,*x,*d")
- - (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
- + [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f*z,*x*w,*d")
- + (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x*w"))]
- "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
- && (register_operand (operands[0], HImode)
- || register_operand (operands[1], HImode)
- @@ -5949,8 +6469,8 @@
- (set_attr "length" "4,4,4,8,4,8,4,4,4,4,4")])
- (define_insn "movhi_internal2"
- - [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
- - (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
- + [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x*w,*d")
- + (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x*w"))]
- "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
- && (register_operand (operands[0], HImode)
- || register_operand (operands[1], HImode)
- @@ -5962,7 +6482,7 @@
- (define_insn ""
- [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
- - (match_operand:HI 1 "general_operand" "d,d,y,K,N,R,m,d,d,*x"))]
- + (match_operand:HI 1 "general_operand" "d,d,y,K,N,R,m,d,d,*x*w"))]
- "TARGET_MIPS16
- && (register_operand (operands[0], HImode)
- || register_operand (operands[1], HImode))"
- @@ -6059,8 +6579,8 @@
- ;; in FP registers (off by default, use -mdebugh to enable).
- (define_insn "movqi_internal1"
- - [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
- - (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
- + [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x*w,*d")
- + (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x*w"))]
- "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
- && (register_operand (operands[0], QImode)
- || register_operand (operands[1], QImode)
- @@ -6072,7 +6592,7 @@
- (define_insn "movqi_internal2"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
- - (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
- + (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x*w"))]
- "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
- && (register_operand (operands[0], QImode)
- || register_operand (operands[1], QImode)
- @@ -6289,12 +6809,13 @@
- ;; This is volatile to make sure that the scheduler won't move any symbol_ref
- ;; uses in front of it. All symbol_refs implicitly use the gp reg.
- +;; FIXME: what is this for? needed for r5900 PIC?
- (define_insn "loadgp"
- [(set (reg:DI 28)
- (unspec_volatile:DI [(match_operand:DI 0 "address_operand" "")
- (match_operand:DI 1 "register_operand" "")] 2))
- (clobber (reg:DI 1))]
- - ""
- + "!TARGET_MIPS5900"
- "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%a0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%a0)))\\n\\tdaddu\\t$gp,$1,%1%]"
- [(set_attr "type" "move")
- (set_attr "mode" "DI")
- @@ -9568,7 +10089,7 @@
- }")
- ;; Trivial return. Make it look like a normal return insn as that
- -;; allows jump optimizations to work better .
- +;; allows jump optimizations to work better.
- (define_insn "return"
- [(return)]
- "mips_can_use_return_insn ()"
- @@ -9773,6 +10294,37 @@
- (set_attr "mode" "none")
- (set_attr "length" "8")])
- +;;
- +;; use jalr instead of jal
- +;;
- +(define_insn "call_indirect_internal"
- + [ (unspec_volatile [
- + (match_operand 0 "call_insn_operand" "ri")
- + (match_operand 1 "" "i")
- + (match_operand:SI 2 "register_operand" "=d") ] 30 )]
- + ""
- + "*
- +{
- + register rtx target = operands[0];
- +
- + if (GET_CODE (target) == SYMBOL_REF)
- + {
- + if (GET_MODE (target) == SImode)
- + return \"la\\t%^,%0\\n\\tjalr\\t%2,%^\";
- + else
- + return \"dla\\t%^,%0\\n\\tjalr\\t%2,%^\";
- + }
- + else if (GET_CODE (target) == CONST_INT)
- + return \"li\\t%^,%0\\n\\tjalr\\t%2,%^\";
- + else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
- + return \"move\\t%^,%0\\n\\tjalr\\t%2,%^\";
- + else
- + return \"jalr\\t%2,%0\";
- +}"
- + [(set_attr "type" "call")
- + (set_attr "mode" "none")
- + (set_attr "length" "8")])
- +
- (define_insn "call_internal1"
- [(call (mem (match_operand 0 "call_insn_operand" "ri"))
- (match_operand 1 "" "i"))
- @@ -9805,6 +10357,8 @@
- return \"li\\t%^,%0\\n\\tjal\\t%2,%^\";
- else if (CONSTANT_ADDRESS_P (target))
- {
- + if (REGNO (operands[2]) == (31 + GP_REG_FIRST))
- + return \"jal\\t%0\";
- if (GET_MODE (target) == SImode)
- return \"la\\t%^,%0\\n\\tjal\\t%2,%^\";
- else
- @@ -10013,6 +10567,8 @@
- return \"li\\t%^,%1\\n\\tjal\\t%3,%^\";
- else if (CONSTANT_ADDRESS_P (target))
- {
- + if (REGNO (operands[3]) == (31 + GP_REG_FIRST))
- + return \"jal\\t%1\";
- if (GET_MODE (target) == SImode)
- return \"la\\t%^,%1\\n\\tjal\\t%3,%^\";
- else
- @@ -10148,6 +10704,8 @@
- return \"li\\t%^,%1\\n\\tjal\\t%4,%^\";
- else if (CONSTANT_ADDRESS_P (target))
- {
- + if (REGNO (operands[4]) == (31 + GP_REG_FIRST))
- + return \"jal\\t%1\";
- if (GET_MODE (target) == SImode)
- return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
- else
- @@ -10205,6 +10763,15 @@
- [(set_attr "type" "nop")
- (set_attr "mode" "none")])
- +;; Used by the r5900 loop lengthening code.
- +
- +(define_insn "nop_internal"
- + [ (unspec_volatile [(const_int 0)] 31)]
- + "TARGET_MIPS5900"
- + "%(nop%)"
- + [(set_attr "type" "nop")
- + (set_attr "mode" "none")])
- +
- ;; The MIPS chip does not seem to require stack probes.
- ;;
- ;; (define_expand "probe"
- @@ -10419,6 +10986,11 @@
- "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
- "
- {
- + /* XXX: Verify this */
- + if (TARGET_MIPS5900
- + && GET_MODE_CLASS (GET_MODE (branch_cmp[0])) == MODE_FLOAT)
- + FAIL;
- +
- gen_conditional_move (operands);
- DONE;
- }")
- @@ -10720,3 +11292,175 @@
- [(set_attr "type" "arith")
- (set_attr "mode" "DI")
- (set_attr "length" "40")])
- +
- +;; r5900 MultiMedia Instructions (MMI)
- +;; A lot of this code is based on the MMX implementation in i386.md. The main
- +;; differences between MMX and MMI is that MMI supports 128-bit wide vector
- +;; operations and MMI operates directly on the r5900 128-bit GPRs vs. needing
- +;; a special set of MM-dedicated registers. Most of the instructions have the
- +;; same mnemonics and perform similiar operations.
- +
- +;; Supported vector types
- +;; 16 x 8 bits = V16QI
- +;; 8 x 16 bits = V8HI
- +;; 4 x 32 bits = V4SI and V4SF
- +;; 2 x 64 bits = V2DI and V2SF
- +;;
- +
- +;; MMI arithmetic
- +;; TODO: Add the alternative where operand 1 == operand 2
- +
- +(define_insn "addv16qi3"
- + [(set (match_operand:V16QI 0 "register_operand" "=d")
- + (plus:V16QI (match_operand:V16QI 1 "register_operand" "d")
- + (match_operand:V16QI 2 "register_operand" "d")))]
- + "TARGET_MMI"
- + "paddb\\t%0,%1,%2"
- + [(set_attr "type" "mmi")])
- +
- +(define_insn "addv8hi3"
- + [(set (match_operand:V8HI 0 "register_operand" "=d")
- + (plus:V8HI (match_operand:V8HI 1 "register_operand" "d")
- + (match_operand:V8HI 2 "register_operand" "d")))]
- + "TARGET_MMI"
- + "paddh\\t%0,%1,%2"
- + [(set_attr "type" "mmi")])
- +
- +(define_insn "addv4si3"
- + [(set (match_operand:V4SI 0 "register_operand" "=d")
- + (plus:V4SI (match_operand:V4SI 1 "register_operand" "d")
- + (match_operand:V4SI 2 "register_operand" "d")))]
- + "TARGET_MMI"
- + "paddw\\t%0,%1,%2"
- + [(set_attr "type" "mmi")])
- +
- +;; Signed saturation
- +
- +(define_insn "ssaddv16qi3"
- + [(set (match_operand:V16QI 0 "register_operand" "=d")
- + (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "d")
- + (match_operand:V16QI 2 "register_operand" "d")))]
- + "TARGET_MMI"
- + "paddsb\\t%0,%1,%2"
- + [(set_attr "type" "mmi")])
- +
- +(define_insn "ssaddv8hi3"
- + [(set (match_operand:V8HI 0 "register_operand" "=d")
- + (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "d")
- + (match_operand:V8HI 2 "register_operand" "d")))]
- + "TARGET_MMI"
- + "paddsh\\t%0,%1,%2"
- + [(set_attr "type" "mmi")])
- +
- +(define_insn "ssaddv4si3"
- + [(set (match_operand:V4SI 0 "register_operand" "=d")
- + (ss_plus:V4SI (match_operand:V4SI 1 "register_operand" "d")
- + (match_operand:V4SI 2 "register_operand" "d")))]
- + "TARGET_MMI"
- + "paddsw\\t%0,%1,%2"
- + [(set_attr "type" "mmi")])
- +
- +;; Unsigned saturation
- +
- +(define_insn "usaddv16qi3"
- + [(set (match_operand:V16QI 0 "register_operand" "=d")
- + (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "d")
- + (match_operand:V16QI 2 "register_operand" "d")))]
- + "TARGET_MMI"
- + "paddub\\t%0,%1,%2"
- + [(set_attr "type" "mmi")])
- +
- +(define_insn "usaddv8hi3"
- + [(set (match_operand:V8HI 0 "register_operand" "=d")
- + (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "d")
- + (match_operand:V8HI 2 "register_operand" "d")))]
- + "TARGET_MMI"
- + "padduh\\t%0,%1,%2"
- + [(set_attr "type" "mmi")])
- +
- +(define_insn "usaddv4si3"
- + [(set (match_operand:V4SI 0 "register_operand" "=d")
- + (us_plus:V4SI (match_operand:V4SI 1 "register_operand" "d")
- + (match_operand:V4SI 2 "register_operand" "d")))]
- + "TARGET_MMI"
- + "padduw\\t%0,%1,%2"
- + [(set_attr "type" "mmi")])
- +
- +;; Subtraction
- +
- +(define_insn "subv16qi3"
- + [(set (match_operand:V16QI 0 "register_operand" "=d")
- + (minus:V16QI (match_operand:V16QI 1 "register_operand" "d")
- + (match_operand:V16QI 2 "register_operand" "d")))]
- + "TARGET_MMI"
- + "psubb\\t%0,%1,%2"
- + [(set_attr "type" "mmi")])
- +
- +(define_insn "subv8hi3"
- + [(set (match_operand:V8HI 0 "register_operand" "=d")
- + (minus:V8HI (match_operand:V8HI 1 "register_operand" "d")
- + (match_operand:V8HI 2 "register_operand" "d")))]
- + "TARGET_MMI"
- + "psubh\\t%0,%1,%2"
- + [(set_attr "type" "mmi")])
- +
- +(define_insn "subv4si3"
- + [(set (match_operand:V4SI 0 "register_operand" "=d")
- + (minus:V4SI (match_operand:V4SI 1 "register_operand" "d")
- + (match_operand:V4SI 2 "register_operand" "d")))]
- + "TARGET_MMI"
- + "psubw\\t%0,%1,%2"
- + [(set_attr "type" "mmi")])
- +
- +;; Signed saturation
- +
- +(define_insn "sssubv16qi3"
- + [(set (match_operand:V16QI 0 "register_operand" "=d")
- + (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "d")
- + (match_operand:V16QI 2 "register_operand" "d")))]
- + "TARGET_MMI"
- + "psubsb\\t%0,%1,%2"
- + [(set_attr "type" "mmi")])
- +
- +(define_insn "sssubv8hi3"
- + [(set (match_operand:V8HI 0 "register_operand" "=d")
- + (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "d")
- + (match_operand:V8HI 2 "register_operand" "d")))]
- + "TARGET_MMI"
- + "psubsh\\t%0,%1,%2"
- + [(set_attr "type" "mmi")])
- +
- +(define_insn "sssubv4si3"
- + [(set (match_operand:V4SI 0 "register_operand" "=d")
- + (ss_minus:V4SI (match_operand:V4SI 1 "register_operand" "d")
- + (match_operand:V4SI 2 "register_operand" "d")))]
- + "TARGET_MMI"
- + "psubsw\\t%0,%1,%2"
- + [(set_attr "type" "mmi")])
- +
- +;; Unsigned saturation
- +
- +(define_insn "ussubv16qi3"
- + [(set (match_operand:V16QI 0 "register_operand" "=d")
- + (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "d")
- + (match_operand:V16QI 2 "register_operand" "d")))]
- + "TARGET_MMI"
- + "psubub\\t%0,%1,%2"
- + [(set_attr "type" "mmi")])
- +
- +(define_insn "ussubv8hi3"
- + [(set (match_operand:V8HI 0 "register_operand" "=d")
- + (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "d")
- + (match_operand:V8HI 2 "register_operand" "d")))]
- + "TARGET_MMI"
- + "psubuh\\t%0,%1,%2"
- + [(set_attr "type" "mmi")])
- +
- +(define_insn "ussubv4si3"
- + [(set (match_operand:V4SI 0 "register_operand" "=d")
- + (us_minus:V4SI (match_operand:V4SI 1 "register_operand" "d")
- + (match_operand:V4SI 2 "register_operand" "d")))]
- + "TARGET_MMI"
- + "psubuw\\t%0,%1,%2"
- + [(set_attr "type" "mmi")])
- +
- diff -burN orig.gcc-3.2.3/gcc/config/mips/mips-protos.h gcc-3.2.3/gcc/config/mips/mips-protos.h
- --- orig.gcc-3.2.3/gcc/config/mips/mips-protos.h 2002-03-24 04:13:16.000000000 -0400
- +++ gcc-3.2.3/gcc/config/mips/mips-protos.h 2015-08-10 16:09:43 +0300
- @@ -82,6 +82,7 @@
- extern void mips_gen_conditional_trap PARAMS ((rtx *));
- extern void mips_emit_fcc_reload PARAMS ((rtx, rtx, rtx));
- extern void machine_dependent_reorg PARAMS ((rtx));
- +extern void machine_dependent_reorg_final PARAMS ((rtx));
- extern int mips_address_cost PARAMS ((rtx));
- extern void mips_count_memory_refs PARAMS ((rtx, int));
- extern HOST_WIDE_INT mips_debugger_offset PARAMS ((rtx, HOST_WIDE_INT));
- diff -burN orig.gcc-3.2.3/gcc/config/mips/r5900.h gcc-3.2.3/gcc/config/mips/r5900.h
- --- orig.gcc-3.2.3/gcc/config/mips/r5900.h 1969-12-31 20:00:00.000000000 -0400
- +++ gcc-3.2.3/gcc/config/mips/r5900.h 2007-07-26 13:04:40.000000000 -0300
- @@ -0,0 +1,285 @@
- +/*
- + * Target machine definitions for the Toshiba r5900.
- + *
- + * Copyright (c) 2003 M. R. Brown <mrbrown@0xd6.org>
- + *
- + * Based on the file elf5900.h, which originally bore
- + * the copyright banner:
- + *
- + * Definitions of target machine for GNU compiler.
- + * Toshiba r5900 little-endian
- + * Copyright (c) 1995 Cygnus Support Inc.
- + *
- + * Also based on the PS2/Linux GCC port provided by SCEI and SCEA.
- + *
- + * Licensed under the terms of the GNU GPL version 2.
- + */
- +
- +/* TODO: Add Linux support. */
- +
- +#include "mips/elf64.h"
- +#include "mips/abi64.h"
- +
- +#define MIPS_CPU_STRING_DEFAULT "R5900"
- +
- +#undef MIPS_ABI_DEFAULT
- +#define MIPS_ABI_DEFAULT ABI_EABI
- +
- +#undef MIPS_ISA_DEFAULT
- +#define MIPS_ISA_DEFAULT 3
- +
- +#undef MACHINE_TYPE
- +#define MACHINE_TYPE "(MIPSel R5900 ELF)"
- +
- +/*
- + I started doing some macro fixes, but as we plan to use 3.4 soon I'm not risking changing stuff I'm not
- + certain about.
- +*/
- +/*
- +#define USE_MACRO_FIXES
- +*/
- +
- +/*
- + gcc-3.0.3-ps2linux has additional min.s and max.s floating point insns. These should be incorporate into mips.md.
- +*/
- +
- +#define FILL_BDSLOT_WITH_NOP
- +
- +/*
- + * Use Gas, target r5900, -msingle-float, 64-bit CPU and longs, split-addr (avoids la insn emits), -mmmi
- + */
- +#undef TARGET_DEFAULT
- +#define TARGET_DEFAULT ( MASK_GAS | MASK_SINGLE_FLOAT | MASK_64BIT \
- + | MASK_LONG64 | MASK_MMI | MASK_VUMM | MASK_SPLIT_ADDR )
- +
- +/*
- + * Even though we're a 64-bit processor, we only support a 32-bit address
- + * space.
- + */
- +#undef Pmode
- +#define Pmode SImode
- +
- +/* 128-bit alignment options */
- +#define DEFAULT_MIPS_ALIGNMENT 128
- +
- +/* TODO: need to make this variable */
- +#undef BIGGEST_ALIGNMENT
- +#define BIGGEST_ALIGNMENT DEFAULT_MIPS_ALIGNMENT
- +
- +#undef SUBTARGET_TARGET_OPTIONS
- +#define SUBTARGET_TARGET_OPTIONS \
- + { "use-128", &mips_use_128_string, \
- + N_("Use 128-bit operations")}, \
- + { "align128", &mips_align128_string, \
- + N_("Use 128-bit alignment")}, \
- + { "no-align128", &mips_no_align128_string, \
- + N_("Don't use 128-bit alignment")}, \
- + { "abi=", &mips_abi_string, \
- + N_("Speciy ABI to use")},
- +
- +/* Stack alignment */
- +#undef STACK_BOUNDARY
- +#define STACK_BOUNDARY \
- + ((mips_abi == ABI_32 || mips_abi == ABI_O64 || (mips_abi == ABI_EABI \
- + && !TARGET_MIPS5900)) \
- + ? 64 : 128)
- +
- +#undef MIPS_STACK_ALIGN
- +#define MIPS_STACK_ALIGN(LOC) \
- + (((mips_abi == ABI_32 || mips_abi == ABI_O64 || mips_abi == ABI_EABI) \
- + && mips_alignment != 128 ) \
- + ? ((LOC) + 7) & ~7 \
- + : ((LOC) + 15) & ~15)
- +
- +#define PREFERRED_STACK_BOUNDARY \
- +(mips_alignment == 128 ? 128 : \
- + ((mips_abi == ABI_32 || mips_abi == ABI_O64 || mips_abi == ABI_EABI ) \
- + ? 64 : 128))
- +
- +/* TODO: Find a way to specify default alignments for functions, jumps,
- + and loops. These used to be machine dependant, but now live as -f
- + parameters. */
- +
- +/* prefer .p2align rather than .align (gas assumed) */
- +#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
- + if ((LOG)!=0) \
- + if ((MAX_SKIP)==0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
- + else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP))
- +
- +/* How to output a quadword for the r5900. */
- +#define ASM_OUTPUT_QUADRUPLE_INT(STREAM,VALUE) \
- +do { \
- + if (TARGET_64BIT) \
- + { \
- + fprintf (STREAM, "\t.octa\t"); \
- + if (HOST_BITS_PER_WIDE_INT < 64 || GET_CODE (VALUE) != CONST_INT) \
- + /* We can't use 'X' for negative numbers, because then we won't \
- + get the right value for the upper 32 bits. */ \
- + output_addr_const (STREAM, VALUE); \
- + else \
- + /* We must use 'X', because otherwise LONG_MIN will print as \
- + a number that the Irix 6 assembler won't accept. */ \
- + print_operand (STREAM, VALUE, 'X'); \
- + fprintf (STREAM, "\n"); \
- + } \
- + else \
- + { \
- + assemble_integer (operand_subword ((VALUE), 0, 0, TImode), \
- + UNITS_PER_WORD, 1); \
- + assemble_integer (operand_subword ((VALUE), 1, 0, TImode), \
- + UNITS_PER_WORD, 1); \
- + } \
- +} while (0)
- +
- +
- +#undef CPP_PREDEFINES
- +#define CPP_PREDEFINES "\
- +-D__ELF__ \
- +-Dmips -D_mips -D__mips -D__mips__ \
- +%{!miop: -DR5900 -D_R5900 -D__R5900 -D_EE } \
- +%{miop: -DR3000 -D_3000 -D__3000 } \
- +-DMIPSEL -D_MIPSEL -D__MIPSEL -D__MIPSEL__ \
- +-Acpu(mips) -Amachine(mips) \
- +"
- +
- +/* Default to 32-bit ints and 64-bit longs. */
- +#undef SUBTARGET_CPP_SIZE_SPEC
- +#define SUBTARGET_CPP_SIZE_SPEC "\
- +%{mgp64: -D_MIPS_SZPTR=32 } \
- +%{!mgp64: -D_MIPS_SZPTR=32 } \
- +\
- +%{mlong64:-D__SIZE_TYPE__=long\\ unsigned\\ int \
- + -D__SSIZE_TYPE__=long\\ int \
- + -D__PTRDIFF_TYPE__=long\\ int \
- + -D_MIPS_SZLONG=64} \
- +\
- +%{mint64:-D_MIPS_SZINT=64 \
- + %{!mlong64:-D__SIZE_TYPE__=long\\ unsigned\\ int \
- + -D__SSIZE_TYPE__=long\\ int \
- + -D__PTRDIFF_TYPE__=long\\ int \
- + -D_MIPS_SZLONG=64}} \
- +\
- +%{!mint64:-D_MIPS_SZINT=32 \
- + %{!mlong64:-D__SIZE_TYPE__=unsigned\\ int \
- + -D__SSIZE_TYPE__=int \
- + -D__PTRDIFF_TYPE__=int \
- + -D_MIPS_SZLONG=64}} \
- +"
- +
- +#undef SUBTARGET_CPP_SPEC
- +#define SUBTARGET_CPP_SPEC "\
- +%{mfp32: -D_MIPS_FPSET=16}%{!mfp32: -D_MIPS_FPSET=32} \
- +%{mips1: -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS1} \
- +%{mips2: -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS2} \
- +%{mips3: -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS3 -UR3000 -U_R3000} \
- +%{mips4: -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS4 -UR3000 -U_R3000} \
- +%{!mips*: -U__mips -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS3 -D__mips=3 -D__mips64} \
- +%{!mabi=32: %{!mabi=n32: %{!mabi=64: -D__mips_eabi}}} \
- +%{!msoft-float: %{!mdouble-float : -D__mips_single_float}} \
- +%{-D__HAVE_FPU__ } \
- +%{posix: -D_POSIX_SOURCE} \
- +%{.cc: -D__LANGUAGE_C_PLUS_PLUS__ %{!ansi:-DLANGUAGE_C_PLUS_PLUS}} \
- +%{.cxx: -D__LANGUAGE_C_PLUS_PLUS__ %{!ansi:-DLANGUAGE_C_PLUS_PLUS}} \
- +%{.C: -D__LANGUAGE_C_PLUS_PLUS__ %{!ansi:-DLANGUAGE_C_PLUS_PLUS}} \
- +%{.m: -D__LANGUAGE_OBJECTIVE_C__ %{!ansi:-DLANGUAGE_OBJECTIVE_C}} \
- +%{.S: -D__LANGUAGE_ASSEMBLY__ %{!ansi:-DLANGUAGE_ASSEMBLY}} \
- +%{.s: -D__LANGUAGE_ASSEMBLY__ %{!ansi:-DLANGUAGE_ASSEMBLY}} \
- +%{!.S: %{!.s: %{!.cc: %{!.cxx: %{!.C: %{!.m: -D__LANGUAGE_C__ %{!ansi:-DLANGUAGE_C}}}}}} } \
- +%{ansi:-Uunix -Ulinux -Umips -UR3000 -UMIPSEB -UMIPSEL} \
- +%{ffast-math: -D__FAST_MATH__} \
- + "
- +
- +/* The GNU C++ standard library requires that these macros be defined. */
- +#undef CPLUSPLUS_CPP_SPEC
- +#define CPLUSPLUS_CPP_SPEC "\
- +-D__LANGUAGE_C_PLUS_PLUS -D_LANGUAGE_C_PLUS_PLUS \
- +-D_GNU_SOURCE %(cpp) \
- + "
- +
- +#undef SUBTARGET_ASM_SPEC
- +#define SUBTARGET_ASM_SPEC "\
- +%{!march*: %{!miop: -mwarn-short-loop -march=r5900} %{miop: -march=r3000}} \
- +%{!mips*: %{!miop: -mips3 %{!mfp*: -mfp32} %{!mgp*: -mgp64}} %{miop: -mips1 %{!mfp*: -mfp32} %{!mgp*: -mgp32}}} \
- +%{!mabi*: %{!miop: -mabi=eabi}} \
- +%{!mdouble-float: -msingle-float} \
- + "
- +
- +/*
- + * We want to include alignment directives for the r5900 to ensure that
- + * TImode values are properly aligned. It would be best to do this in
- + * mips.h, but it's unclear if all mips assemblers can handle alignments
- + * for local common/bss objects.
- + */
- +#undef ASM_OUTPUT_LOCAL
- +
- +/*
- + * This says how to output an assembler line to define a global common symbol
- + * with size SIZE (in bytes) and alignment ALIGN (in bits).
- + */
- +
- +#undef ASM_OUTPUT_ALIGNED_COMMON
- +#define ASM_OUTPUT_ALIGNED_COMMON(STREAM, NAME, SIZE, ALIGN) \
- +do \
- +{ \
- + mips_declare_object (STREAM, NAME, "\n\t.comm\t", ",%u,", (SIZE)); \
- + fprintf ((STREAM), "%d\n", ((ALIGN) / BITS_PER_UNIT)); \
- +} \
- +while (0)
- +
- +#define POPSECTION_ASM_OP "\t.previous"
- +#define BSS_SECTION_ASM_OP "\t.section\t.bss"
- +#define SBSS_SECTION_ASM_OP "\t.section\t.sbss"
- +#undef ASM_OUTPUT_ALIGNED_LOCAL
- +#define ASM_OUTPUT_ALIGNED_LOCAL(STREAM, NAME, SIZE, ALIGN) \
- +do \
- + { \
- + if ((SIZE) > 0 && (SIZE) <= mips_section_threshold) \
- + fprintf (STREAM, "%s\n", SBSS_SECTION_ASM_OP); \
- + else \
- + fprintf (STREAM, "%s\n", BSS_SECTION_ASM_OP); \
- + mips_declare_object (STREAM, NAME, "", ":\n", 0); \
- + ASM_OUTPUT_ALIGN (STREAM, floor_log2 (ALIGN / BITS_PER_UNIT)); \
- + ASM_OUTPUT_SKIP (STREAM, SIZE); \
- + fprintf (STREAM, "%s\n", POPSECTION_ASM_OP); \
- + } \
- +while (0)
- +
- +/*
- + * Avoid returning unaligned structures > 64bits, but <= 128bits wide
- + * in registers.
- + *
- + * This avoids a bad interaction between the code to return BLKmode
- + * structures in registers and the wider than word_mode registers
- + * found on the r5900.
- + *
- + * This does not effect returning an aligned 128bit value in a register,
- + * which should work.
- + */
- +
- +#undef RETURN_IN_MEMORY
- +#define RETURN_IN_MEMORY(TYPE) \
- + ((mips_abi == ABI_32 || mips_abi == ABI_O64) \
- + ? TYPE_MODE (TYPE) == BLKmode \
- + : (mips_abi == ABI_EABI && TYPE_MODE (TYPE) == BLKmode \
- + ? (int_size_in_bytes (TYPE) > UNITS_PER_WORD) \
- + : (int_size_in_bytes (TYPE) \
- + > (mips_abi == ABI_EABI ? 2 * UNITS_PER_WORD : 16))))
- +
- +#define EH_FRAME_IN_DATA_SECTION 1
- +
- +/*
- + * This patch is ugly. But it hopefully will put an end to that
- + * 128-bits alignment madness.
- + */
- +
- +#undef CONSTANT_ALIGNMENT
- +#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
- + ((TREE_CODE (EXP) == STRING_CST || TREE_CODE (EXP) == CONSTRUCTOR) \
- + && (ALIGN) < (mips_use_128 ? 128 : 64) ? (mips_use_128 ? 128 : 64) : (ALIGN))
- +
- +#undef DATA_ALIGNMENT
- +#define DATA_ALIGNMENT(TYPE, ALIGN) \
- + ((((ALIGN) < (mips_use_128 ? 128 : 64)) \
- + && (TREE_CODE (TYPE) == ARRAY_TYPE \
- + || TREE_CODE (TYPE) == UNION_TYPE \
- + || TREE_CODE (TYPE) == RECORD_TYPE)) ? (mips_use_128 ? 128 : 64) : (ALIGN))
- diff -burN orig.gcc-3.2.3/gcc/config/mips/t-irx gcc-3.2.3/gcc/config/mips/t-irx
- --- orig.gcc-3.2.3/gcc/config/mips/t-irx 1969-12-31 20:00:00.000000000 -0400
- +++ gcc-3.2.3/gcc/config/mips/t-irx 2007-07-26 13:04:40.000000000 -0300
- @@ -0,0 +1,77 @@
- +CONFIG2_H = $(srcdir)/config/mips/ecoff.h
- +
- +# Don't run fixproto
- +STMP_FIXPROTO =
- +
- +# Suppress building libgcc1.a, since the MIPS compiler port is complete
- +# and does not need anything from libgcc1.a.
- +LIBGCC1 =
- +CROSS_LIBGCC1 =
- +
- +# We must build libgcc2.a with -G 0, in case the user wants to link
- +# without the $gp register.
- +TARGET_LIBGCC2_CFLAGS = -G 0
- +
- +# We want fine grained libraries, so use the new code to build the
- +# floating point emulation libraries.
- +FPBIT = fp-bit.c
- +DPBIT = dp-bit.c
- +
- +dp-bit.c: $(srcdir)/config/fp-bit.c
- + echo '#ifdef __MIPSEL__' > dp-bit.c
- + echo '#define FLOAT_BIT_ORDER_MISMATCH' >> dp-bit.c
- + echo '#endif' >> dp-bit.c
- + echo '#define US_SOFTWARE_GOFAST' >> dp-bit.c
- + cat $(srcdir)/config/fp-bit.c >> dp-bit.c
- +
- +fp-bit.c: $(srcdir)/config/fp-bit.c
- + echo '#define FLOAT' > fp-bit.c
- + echo '#ifdef __MIPSEL__' >> fp-bit.c
- + echo '#define FLOAT_BIT_ORDER_MISMATCH' >> fp-bit.c
- + echo '#endif' >> fp-bit.c
- + echo '#define US_SOFTWARE_GOFAST' >> fp-bit.c
- + cat $(srcdir)/config/fp-bit.c >> fp-bit.c
- +
- +# Build the libraries for both hard and soft floating point
- +
- +MULTILIB_OPTIONS =
- +MULTILIB_DIRNAMES =
- +MULTILIB_MATCHES =
- +
- +# Library members defined in libgcc2.c.
- +# LIB2FUNCS = _muldi3 _divdi3 _moddi3 _udivdi3 _umoddi3 _negdi2 \
- +# _lshrdi3 _ashldi3 _ashrdi3 _ffsdi2 \
- +# _udiv_w_sdiv _udivmoddi4 _cmpdi2 _ucmpdi2 \
- +# __gcc_bcmp _varargs __dummy
- +
- +
- +# Add additional dependencies to recompile selected modules whenever the
- +# tm.h file changes. The files compiled are:
- +#
- +# gcc.c (*_SPEC changes)
- +# toplev.c (new switches + assembly output changes)
- +# sdbout.c (debug format changes)
- +# dbxout.c (debug format changes)
- +# dwarfout.c (debug format changes)
- +# final.c (assembly output changes)
- +# varasm.c (assembly output changes)
- +# cse.c (cost functions)
- +# insn-output.c (possible ifdef changes in tm.h)
- +# regclass.c (fixed/call used register changes)
- +# explow.c (GO_IF_LEGITIMATE_ADDRESS)
- +# recog.c (GO_IF_LEGITIMATE_ADDRESS)
- +# reload.c (GO_IF_LEGITIMATE_ADDRESS)
- +
- +gcc.o: $(CONFIG2_H)
- +toplev.o: $(CONFIG2_H)
- +sdbout.o: $(CONFIG2_H)
- +dbxout.o: $(CONFIG2_H)
- +dwarfout.o: $(CONFIG2_H)
- +final.o: $(CONFIG2_H)
- +varasm.o: $(CONFIG2_H)
- +cse.o: $(CONFIG2_H)
- +insn-output.o: $(CONFIG2_H)
- +regclass.o: $(CONFIG2_H)
- +explow.o: $(CONFIG2_H)
- +recog.o: $(CONFIG2_H)
- +reload.o: $(CONFIG2_H)
- diff -burN orig.gcc-3.2.3/gcc/config/mips/t-r5900 gcc-3.2.3/gcc/config/mips/t-r5900
- --- orig.gcc-3.2.3/gcc/config/mips/t-r5900 1969-12-31 20:00:00.000000000 -0400
- +++ gcc-3.2.3/gcc/config/mips/t-r5900 2007-07-26 13:04:40.000000000 -0300
- @@ -0,0 +1,56 @@
- +# Suppress building libgcc1.a, since the MIPS compiler port is complete
- +# and does not need anything from libgcc1.a.
- +LIBGCC1 =
- +CROSS_LIBGCC1 =
- +
- +# We must build libgcc2.a with -G 0, in case the user wants to link
- +# without the $gp register.
- +TARGET_LIBGCC2_CFLAGS = -G 0
- +
- +# We want fine grained libraries, so use the new code to build the
- +# floating point emulation libraries.
- +FPBIT = fp-bit.c
- +
- +fp-bit.c: $(srcdir)/config/fp-bit.c
- + echo '#define FLOAT' > fp-bit.c
- + echo '#ifdef __MIPSEL__' >> fp-bit.c
- + echo '#define FLOAT_BIT_ORDER_MISMATCH' >> fp-bit.c
- + echo '#endif' >> fp-bit.c
- + echo '#define US_SOFTWARE_GOFAST' >> fp-bit.c
- + cat $(srcdir)/config/fp-bit.c >> fp-bit.c
- +
- +# To reenable the double precision emulation code uncomment the next line and
- +# the 6 lines that follow it.
- +DPBIT = dp-bit.c
- +
- +dp-bit.c: $(srcdir)/config/fp-bit.c
- + echo '#ifdef __MIPSEL__' > dp-bit.c
- + echo '#define FLOAT_BIT_ORDER_MISMATCH' >> dp-bit.c
- + echo '#endif' >> dp-bit.c
- + echo '#define US_SOFTWARE_GOFAST' >> dp-bit.c
- + cat $(srcdir)/config/fp-bit.c >> dp-bit.c
- +
- +# Don't let CTOR_LIST end up in sdata section.
- +CRTSTUFF_T_CFLAGS = -G 0
- +
- +# Assemble startup files.
- +$(T)crti.o: $(srcdir)/config/mips/crti5900.asm $(GCC_PASSES)
- + $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
- + -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/mips/crti5900.asm
- +
- +$(T)crtn.o: $(srcdir)/config/mips/crtn5900.asm $(GCC_PASSES)
- + $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
- + -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/mips/crtn5900.asm
- +
- +MULTILIB_OPTIONS =
- +MULTILIB_DIRNAMES =
- +EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o
- +
- +#
- +# TImode runtime support
- +#
- +LIBGCC_TIMODE_SRC = $(srcdir)/config/mips/libgcc2-timode.c
- +TIMODE_FUNCS_LIST = _ashlti3 _ashrti3 _cmpti2 _divti3 _ffsti2 _fixdfti _fixunsdfti \
- + _floattidf _floattisf _lshrti3 _modti3 _multi3 _negti2 _ucmpti2 _udivti3 _umodti3
- +
- +LIB2FUNCS_TI = $(TIMODE_FUNCS_LIST)
- diff -burN orig.gcc-3.2.3/gcc/config.gcc gcc-3.2.3/gcc/config.gcc
- --- orig.gcc-3.2.3/gcc/config.gcc 2003-01-30 10:03:42.000000000 -0400
- +++ gcc-3.2.3/gcc/config.gcc 2007-07-26 13:04:40.000000000 -0300
- @@ -1553,6 +1553,10 @@
- *minwg32msv* | *mingw32*)
- ;;
- esac
- + if test x$pass1done = xyes && test x$pass2done = x
- + then
- + host_to_target_tmake_file=i386/t-mingw32
- + fi
- ;;
- i[34567]86-*-uwin*)
- tm_file=i386/uwin.h
- @@ -2387,6 +2391,13 @@
- esac
- tmake_file="t-slibgcc-elf-ver t-linux mips/t-linux"
- extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
- + case $machine in
- + mips*r5900*-*) # Linux for r5900 (EE)
- + tm_file="$tm_file mips/r5900.h"
- + tmake_file="$tmake_file t-r5900"
- + extra_headers="core-mmi.h core-vumm.h"
- + ;;
- + esac
- gnu_ld=yes
- gas=yes
- ;;
- @@ -2583,6 +2594,24 @@
- use_collect2=yes
- fi
- ;;
- +mips*r5900*-*-elf*) # MIPS r5900 ELF, either endian
- + tm_file="dbxelf.h elfos.h mips/r5900.h"
- + tmake_file=mips/t-r5900
- + case $machine in
- + mips*el-*)
- + tm_file="mips/little.h $tm_file"
- + ;;
- + esac
- + gnu_ld=yes
- + gas=yes
- + extra_headers="core-mmi.h core-vumm.h"
- + ;;
- +mipsel-*-irx)
- + tm_file="mips/elfl.h libgloss.h"
- + tmake_file=mips/t-irx
- + target_cpu_default="MASK_GAS|MASK_SOFT_FLOAT"
- + fixincludes=Makefile.in
- + ;;
- mipsel-*-ecoff*)
- tm_file=mips/ecoffl.h
- if test x$stabs = xyes; then
- @@ -3673,5 +3702,8 @@
- host_extra_objs=$extra_host_objs
- host_exeext=$exeext
- pass2done=yes
- + else
- + tmake_file="$tmake_file $host_to_target_tmake_file"
- fi
- fi
- +
- diff -burN orig.gcc-3.2.3/gcc/cp/decl.c gcc-3.2.3/gcc/cp/decl.c
- --- orig.gcc-3.2.3/gcc/cp/decl.c 2003-01-21 15:00:27.000000000 -0400
- +++ gcc-3.2.3/gcc/cp/decl.c 2015-08-10 16:06:57 +0300
- @@ -458,6 +458,10 @@
- ? cp_function_chain->bindings \
- : scope_chain->bindings)
- +#define set_current_binding_level(x) \
- + if(cfun && cp_function_chain->bindings) { cp_function_chain->bindings = (x); } \
- + else { scope_chain->bindings = (x); }
- +
- /* The binding level of the current class, if any. */
- #define class_binding_level scope_chain->class_bindings
- @@ -507,7 +511,7 @@
- are active. */
- memset ((char*) newlevel, 0, sizeof (struct binding_level));
- newlevel->level_chain = current_binding_level;
- - current_binding_level = newlevel;
- + set_current_binding_level(newlevel);
- newlevel->tag_transparent = tag_transparent;
- newlevel->more_cleanups_ok = 1;
- @@ -563,7 +567,7 @@
- #endif /* defined(DEBUG_CP_BINDING_LEVELS) */
- {
- register struct binding_level *level = current_binding_level;
- - current_binding_level = current_binding_level->level_chain;
- + set_current_binding_level(current_binding_level->level_chain);
- level->level_chain = free_binding_level;
- #if 0 /* defined(DEBUG_CP_BINDING_LEVELS) */
- if (level->binding_depth != binding_depth)
- @@ -578,7 +582,9 @@
- suspend_binding_level ()
- {
- if (class_binding_level)
- - current_binding_level = class_binding_level;
- + {
- + set_current_binding_level(class_binding_level);
- + }
- if (global_binding_level)
- {
- @@ -600,7 +606,7 @@
- }
- is_class_level = 0;
- #endif /* defined(DEBUG_CP_BINDING_LEVELS) */
- - current_binding_level = current_binding_level->level_chain;
- + set_current_binding_level(current_binding_level->level_chain);
- find_class_binding_level ();
- }
- @@ -613,7 +619,7 @@
- my_friendly_assert(!class_binding_level, 386);
- /* Also, resuming a non-directly nested namespace is a no-no. */
- my_friendly_assert(b->level_chain == current_binding_level, 386);
- - current_binding_level = b;
- + set_current_binding_level(b);
- #if defined(DEBUG_CP_BINDING_LEVELS)
- b->binding_depth = binding_depth;
- indent ();
- @@ -4291,9 +4297,9 @@
- else
- {
- b = current_binding_level;
- - current_binding_level = level;
- + set_current_binding_level(level);
- x = pushdecl (x);
- - current_binding_level = b;
- + set_current_binding_level(b);
- }
- current_function_decl = function_decl;
- return x;
- @@ -4540,14 +4546,14 @@
- return NULL_TREE;
- ancestor = namespace_ancestor (current_decl_namespace (), used);
- - ud = current_binding_level->using_directives;
- - ud = tree_cons (used, ancestor, ud);
- - current_binding_level->using_directives = ud;
- /* Recursively add all namespaces used. */
- for (iter = DECL_NAMESPACE_USING (used); iter; iter = TREE_CHAIN (iter))
- push_using_directive (TREE_PURPOSE (iter));
- + ud = current_binding_level->using_directives;
- + ud = tree_cons (used, ancestor, ud);
- + current_binding_level->using_directives = ud;
- return ud;
- }
- @@ -6538,7 +6544,7 @@
- current_lang_name = lang_name_c;
- current_function_decl = NULL_TREE;
- - current_binding_level = NULL_BINDING_LEVEL;
- + set_current_binding_level(NULL_BINDING_LEVEL);
- free_binding_level = NULL_BINDING_LEVEL;
- build_common_tree_nodes (flag_signed_char);
- @@ -10124,10 +10130,10 @@
- if (decl_context == NORMAL && !toplevel_bindings_p ())
- {
- struct binding_level *b = current_binding_level;
- - current_binding_level = b->level_chain;
- + set_current_binding_level(b->level_chain);
- if (current_binding_level != 0 && toplevel_bindings_p ())
- decl_context = PARM;
- - current_binding_level = b;
- + set_current_binding_level(b);
- }
- if (name == NULL)
- @@ -13757,7 +13763,7 @@
- FIXME factor out the non-RTL stuff. */
- bl = current_binding_level;
- init_function_start (decl1, input_filename, lineno);
- - current_binding_level = bl;
- + set_current_binding_level(bl);
- /* Even though we're inside a function body, we still don't want to
- call expand_expr to calculate the size of a variable-sized array.
- @@ -14309,20 +14315,11 @@
- if (current_function_return_value)
- {
- tree r = current_function_return_value;
- - tree outer;
- -
- - if (r != error_mark_node
- /* This is only worth doing for fns that return in memory--and
- simpler, since we don't have to worry about promoted modes. */
- - && aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl)))
- - /* Only allow this for variables declared in the outer scope of
- - the function so we know that their lifetime always ends with a
- - return; see g++.dg/opt/nrv6.C. We could be more flexible if
- - we were to do this optimization in tree-ssa. */
- - && (outer = BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl)),
- - chain_member (r, BLOCK_VARS (outer))))
- + if (r != error_mark_node
- + && aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl))))
- {
- -
- DECL_ALIGN (r) = DECL_ALIGN (DECL_RESULT (fndecl));
- walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
- nullify_returns_r, r);
- diff -burN orig.gcc-3.2.3/gcc/fixinc/gnu-regex.c gcc-3.2.3/gcc/fixinc/gnu-regex.c
- --- orig.gcc-3.2.3/gcc/fixinc/gnu-regex.c 2002-02-26 20:23:56.000000000 -0400
- +++ gcc-3.2.3/gcc/fixinc/gnu-regex.c 2007-07-26 13:04:40.000000000 -0300
- @@ -26,6 +26,9 @@
- # include <config.h>
- #endif
- +/* XXX :: Should find the correct way for other platforms that have mempcpy. this is a cygwin hack! */
- +#undef HAVE_MEMPCPY
- +
- /* GCC LOCAL: we don't need NLS here. */
- #undef ENABLE_NLS
- /* GCC LOCAL: to handle defining alloca. */
- diff -burN orig.gcc-3.2.3/gcc/fixinc/mkfixinc.sh gcc-3.2.3/gcc/fixinc/mkfixinc.sh
- --- orig.gcc-3.2.3/gcc/fixinc/mkfixinc.sh 2002-01-05 00:06:51.000000000 -0400
- +++ gcc-3.2.3/gcc/fixinc/mkfixinc.sh 2007-07-26 13:04:40.000000000 -0300
- @@ -80,6 +80,8 @@
- i?86-*-mingw32* | \
- i?86-*-uwin* | \
- mips-sgi-irix5cross64 | \
- + mips64r5900el-scei-elf | \
- + mipsel-scei-irx | \
- powerpc-*-eabiaix* | \
- powerpc-*-eabisim* | \
- powerpc-*-eabi* | \
- diff -burN orig.gcc-3.2.3/gcc/glimits.h gcc-3.2.3/gcc/glimits.h
- --- orig.gcc-3.2.3/gcc/glimits.h 2001-08-13 21:53:23.000000000 -0300
- +++ gcc-3.2.3/gcc/glimits.h 2007-07-26 13:04:40.000000000 -0300
- @@ -67,11 +67,11 @@
- /* Minimum and maximum values a `signed long int' can hold.
- (Same as `int'). */
- #ifndef __LONG_MAX__
- -#if defined (__alpha__) || (defined (__sparc__) && defined(__arch64__)) || defined (__sparcv9)
- +#if defined (__alpha__) || (defined (__sparc__) && defined(__arch64__)) || defined (__sparcv9) || defined (__R5900)
- #define __LONG_MAX__ 9223372036854775807L
- #else
- #define __LONG_MAX__ 2147483647L
- -#endif /* __alpha__ || sparc64 */
- +#endif /* __alpha__ || sparc64 || R5900 */
- #endif
- #undef LONG_MIN
- #define LONG_MIN (-LONG_MAX-1)
- diff -burN orig.gcc-3.2.3/gcc/integrate.c gcc-3.2.3/gcc/integrate.c
- --- orig.gcc-3.2.3/gcc/integrate.c 2003-02-03 16:56:29.000000000 -0400
- +++ gcc-3.2.3/gcc/integrate.c 2007-07-26 13:04:40.000000000 -0300
- @@ -358,12 +358,18 @@
- /* Copy the declaration. */
- if (TREE_CODE (decl) == PARM_DECL || TREE_CODE (decl) == RESULT_DECL)
- {
- + tree type;
- + type = TREE_TYPE(decl);
- +
- /* For a parameter, we must make an equivalent VAR_DECL, not a
- new PARM_DECL. */
- copy = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
- TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
- TREE_READONLY (copy) = TREE_READONLY (decl);
- TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
- +
- + if (TYPE_RESTRICT(type))
- + DECL_POINTER_ALIAS_SET (copy) = -2;
- }
- else
- {
- diff -burN orig.gcc-3.2.3/gcc/libgcc2-timode.c gcc-3.2.3/gcc/libgcc2-timode.c
- --- orig.gcc-3.2.3/gcc/libgcc2-timode.c 1969-12-31 20:00:00.000000000 -0400
- +++ gcc-3.2.3/gcc/libgcc2-timode.c 2007-07-26 13:04:40.000000000 -0300
- @@ -0,0 +1,792 @@
- +/* GCC rutime support routines for TI mode */
- +
- +/* Copyright (C) 2001 Sony Computer Entertainment Inc.
- + Copyright 2001 Sony Corportaion. */
- +
- +/* This file is derived from libgcc2.c and subject to the original
- + license of libgcc2.c, as follows. */
- +
- +/* Compile this one with gcc. */
- +/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
- +
- +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 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. */
- +
- +/* As a special exception, if you link this library with other files,
- + some of which are compiled with GCC, to produce an executable,
- + this library does not by itself cause the resulting executable
- + to be covered by the GNU General Public License.
- + This exception does not however invalidate any other reasons why
- + the executable file might be covered by the GNU General Public License. */
- +
- +
- +#include "tconfig.h"
- +
- +/* We disable this when inhibit_libc, so that gcc can still be built without
- + needing header files first. */
- +/* ??? This is not a good solution, since prototypes may be required in
- + some cases for correct code. See also frame.c. */
- +
- +#include "machmode.h"
- +#include "defaults.h"
- +
- +#ifndef LIBGCC2_WORDS_BIG_ENDIAN
- +#define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
- +#endif
- +
- +
- +/* In this file, we are interfacing to calls generated by the compiler
- + itself. These calls pass values into these routines which have very
- + specific modes (rather than very specific types), and these
- + compiler-generated calls also expect any return values to have very
- + specific modes (rather than very specific types). Thus, we need to
- + avoid using regular C language type names in this part of the file
- + because the sizes for those types can be configured to be anything.
- + Instead we use the following special type names. */
- +
- +typedef unsigned int UTItype __attribute__((mode(TI)));
- +typedef int TItype __attribute__((mode(TI)));
- +typedef unsigned int UDItype __attribute__((mode(DI)));
- +typedef int DItype __attribute__((mode(DI)));
- +typedef unsigned int UQItype __attribute__((mode(QI)));
- +typedef int QItype __attribute__((mode(QI)));
- +
- +typedef float SFtype __attribute__ ((mode (SF)));
- +typedef float DFtype __attribute__ ((mode (DF)));
- +
- +typedef int word_type __attribute__ ((mode (__word__)));
- +
- +/* Make sure that we don't accidentally use any normal C language
- + built-in type names in the first part of this file. Instead we want
- + to use *only* the type names defined above.
- + The following macro definitions insure that if we *do* accidentally
- + use some normal C language built-in type name, we will get a syntax
- + error. */
- +
- +#define char bogus_type
- +#define short bogus_type
- +#define int bogus_type
- +#define long bogus_type
- +#define unsigned bogus_type
- +#define float bogus_type
- +#define double bogus_type
- +
- +
- +#ifndef BITS_PER_UNIT
- +#define BITS_PER_UNIT 8
- +#endif
- +#ifndef DI_TYPE_SIZE
- +#define DI_TYPE_SIZE 64
- +#endif
- +
- +
- +/* TIstructs are pairs of DItype values in the order determined by
- + LIBGCC2_WORDS_BIG_ENDIAN. */
- +
- +#if LIBGCC2_WORDS_BIG_ENDIAN
- +struct TIstruct {DItype high, low;};
- +#else
- +struct TIstruct {DItype low, high;};
- +#endif
- +
- +/* We need this union to unpack/pack TImode values, since we don't have
- + any arithmetic yet. Incoming TImode parameters are stored into the
- + `ti' field, and the unpacked result is read from the struct `d'. */
- +
- +typedef union
- +{
- + struct TIstruct d;
- + TItype ti;
- +} TIunion;
- +
- +/* for
- + __fixunsdfti
- + __floattidf
- + */
- +#define DI_WORD_SIZE (sizeof (DItype) * BITS_PER_UNIT)
- +#define HIGH_DI_WORD_COEFF (((UTItype) 1) << DI_WORD_SIZE)
- +#define HIGH_DI_HALFWORD_COEFF (((UDItype) 1) << (DI_WORD_SIZE / 2))
- +
- +
- +
- +#if (defined (L_udivti3) || defined (L_divti3) || defined (L_multi3) ||\
- + defined (L_umodti3) || defined (L_modti3))
- +/* ----------------------------------------------------------------- */
- +/* BEGIN: derived from longlog.h */
- +/* for
- + __udivmoddi4
- + __multi3
- + __dviti3
- + __udviti3
- + __modti3
- + __umodti3
- +*/
- +
- +#define __ti_B (((UDItype)1) << (DI_TYPE_SIZE / 2))
- +#define __ti_lowpart(t) ((UDItype) (t) % __ti_B)
- +#define __ti_highpart(t) ((UDItype) (t) / __ti_B)
- +
- +#define umul_ppmm_di(w1, w0, u, v) \
- +do { \
- + UDItype __x0, __x1, __x2, __x3; \
- + UDItype __ul, __vl, __uh, __vh; \
- + \
- + __ul = __ti_lowpart (u); \
- + __uh = __ti_highpart (u); \
- + __vl = __ti_lowpart (v); \
- + __vh = __ti_highpart (v); \
- + \
- + __x0 = (UDItype) __ul * __vl; \
- + __x1 = (UDItype) __ul * __vh; \
- + __x2 = (UDItype) __uh * __vl; \
- + __x3 = (UDItype) __uh * __vh; \
- + \
- + __x1 += __ti_highpart (__x0);/* this can't give carry */ \
- + __x1 += __x2; /* but this indeed can */ \
- + if (__x1 < __x2) /* did we get it? */ \
- + __x3 += __ti_B; /* yes, add it in the proper pos. */ \
- + \
- + (w1) = __x3 + __ti_highpart (__x1); \
- + (w0) = __ti_lowpart (__x1) * __ti_B + __ti_lowpart (__x0); \
- +} while (0)
- +
- +#define __umulditi3(u, v) \
- + ({TIunion __w; \
- + umul_ppmm_di (__w.d.high, __w.d.low, u, v); \
- + __w.ti; })
- +
- +
- +
- +/* Define this unconditionally, so it can be used for debugging. */
- +#define udiv_qrnnd_c_di(q, r, n1, n0, d) \
- + do { \
- + UDItype __d1, __d0, __q1, __q0; \
- + UDItype __r1, __r0, __m; \
- + __d1 = __ti_highpart (d); \
- + __d0 = __ti_lowpart (d); \
- + \
- + __r1 = (n1) % __d1; \
- + __q1 = (n1) / __d1; \
- + __m = (UDItype) __q1 * __d0; \
- + __r1 = __r1 * __ti_B | __ti_highpart (n0); \
- + if (__r1 < __m) \
- + { \
- + __q1--, __r1 += (d); \
- + if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
- + if (__r1 < __m) \
- + __q1--, __r1 += (d); \
- + } \
- + __r1 -= __m; \
- + \
- + __r0 = __r1 % __d1; \
- + __q0 = __r1 / __d1; \
- + __m = (UDItype) __q0 * __d0; \
- + __r0 = __r0 * __ti_B | __ti_lowpart (n0); \
- + if (__r0 < __m) \
- + { \
- + __q0--, __r0 += (d); \
- + if (__r0 >= (d)) \
- + if (__r0 < __m) \
- + __q0--, __r0 += (d); \
- + } \
- + __r0 -= __m; \
- + \
- + (q) = (UDItype) __q1 * __ti_B | __q0; \
- + (r) = __r0; \
- + } while (0)
- +
- +
- +#define sub_ddmmss_di(sh, sl, ah, al, bh, bl) \
- + do { \
- + UDItype __x; \
- + __x = (al) - (bl); \
- + (sh) = (ah) - (bh) - (__x > (al)); \
- + (sl) = __x; \
- + } while (0)
- +
- +#define count_leading_zeros_di(count, x) \
- + do { \
- + UDItype __xr = (x); \
- + UDItype __a; \
- + \
- + { \
- + for (__a = DI_TYPE_SIZE - 8; __a > 0; __a -= 8) \
- + if (((__xr >> __a) & 0xff) != 0) \
- + break; \
- + } \
- + \
- + (count) = DI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
- + } while (0)
- +
- +
- +
- +/* END: derived from longlog.h */
- +/* ----------------------------------------------------------------- */
- +#endif /* (defined (L_udivti3) || defined (L_divti3) || defined (L_multi3) ||
- + defined (L_umodti3) || defined (L_modti3)) */
- +
- +
- +#if defined (L_negti2) || defined (L_divti3) || defined (L_modti3)
- +#if defined (L_divti3) || defined (L_modti3)
- +static inline
- +#endif
- +TItype
- +__negti2 (TItype u)
- +{
- + TIunion w;
- + TIunion uu;
- +
- + uu.ti = u;
- +
- + w.d.low = -uu.d.low;
- + w.d.high = -uu.d.high - ((UDItype) w.d.low > 0);
- +
- + return w.ti;
- +}
- +#endif
- +
- +/* Unless shift functions are defined whith full ANSI prototypes,
- + parameter b will be promoted to int if word_type is smaller than an int. */
- +#ifdef L_lshrti3
- +TItype
- +__lshrti3 (TItype u, word_type b)
- +{
- + TIunion w;
- + word_type bm;
- + TIunion uu;
- +
- + if (b == 0)
- + return u;
- +
- + uu.ti = u;
- +
- + bm = (sizeof (DItype) * BITS_PER_UNIT) - b;
- + if (bm <= 0)
- + {
- + w.d.high = 0;
- + w.d.low = (UDItype)uu.d.high >> -bm;
- + }
- + else
- + {
- + UDItype carries = (UDItype)uu.d.high << bm;
- + w.d.high = (UDItype)uu.d.high >> b;
- + w.d.low = ((UDItype)uu.d.low >> b) | carries;
- + }
- +
- + return w.ti;
- +}
- +#endif
- +
- +#ifdef L_ashlti3
- +TItype
- +__ashlti3 (TItype u, word_type b)
- +{
- + TIunion w;
- + word_type bm;
- + TIunion uu;
- +
- + if (b == 0)
- + return u;
- +
- + uu.ti = u;
- +
- + bm = (sizeof (DItype) * BITS_PER_UNIT) - b;
- + if (bm <= 0)
- + {
- + w.d.low = 0;
- + w.d.high = (UDItype)uu.d.low << -bm;
- + }
- + else
- + {
- + UDItype carries = (UDItype)uu.d.low >> bm;
- + w.d.low = (UDItype)uu.d.low << b;
- + w.d.high = ((UDItype)uu.d.high << b) | carries;
- + }
- +
- + return w.ti;
- +}
- +#endif
- +
- +#ifdef L_ashrti3
- +TItype
- +__ashrti3 (TItype u, word_type b)
- +{
- + TIunion w;
- + word_type bm;
- + TIunion uu;
- +
- + if (b == 0)
- + return u;
- +
- + uu.ti = u;
- +
- + bm = (sizeof (DItype) * BITS_PER_UNIT) - b;
- + if (bm <= 0)
- + {
- + /* w.d.high = 1..1 or 0..0 */
- + w.d.high = uu.d.high >> (sizeof (DItype) * BITS_PER_UNIT - 1);
- + w.d.low = uu.d.high >> -bm;
- + }
- + else
- + {
- + UDItype carries = (UDItype)uu.d.high << bm;
- + w.d.high = uu.d.high >> b;
- + w.d.low = ((UDItype)uu.d.low >> b) | carries;
- + }
- +
- + return w.ti;
- +}
- +#endif
- +
- +#ifdef L_ffsti2
- +TItype
- +__ffsti2 (TItype u)
- +{
- + TIunion uu, w;
- + uu.ti = u;
- + w.d.high = 0;
- + w.d.low = __ffsdi2 (uu.d.low);
- + if (w.d.low != 0)
- + return w.ti;
- + w.d.low = __ffsdi2 (uu.d.high);
- + if (w.d.low != 0)
- + {
- + w.d.low += BITS_PER_UNIT * sizeof (DItype);
- + return w.ti;
- + }
- + return w.ti;
- +}
- +#endif
- +
- +
- +#ifdef L_multi3
- +TItype
- +__multi3 (TItype u, TItype v)
- +{
- + TIunion w;
- + TIunion uu, vv;
- +
- + uu.ti = u,
- + vv.ti= v;
- +
- + w.ti = __umulditi3 (uu.d.low, vv.d.low);
- + w.d.high += ((UDItype) uu.d.low * (UDItype) vv.d.high
- + + (UDItype) uu.d.high * (UDItype) vv.d.low);
- +
- + return w.ti;
- +}
- +#endif
- +
- +#if (defined (L_udivti3) || defined (L_divti3) || \
- + defined (L_umodti3) || defined (L_modti3))
- +#define L_udivmodti4
- +#endif
- +
- +#ifdef L_udivmodti4
- +static const UQItype __clz_tab[] =
- +{
- + 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
- + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
- + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
- + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
- + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
- +};
- +
- +#if (defined (L_udivti3) || defined (L_divti3) || \
- + defined (L_umodti3) || defined (L_modti3))
- +static inline
- +#endif
- +UTItype
- +__udivmodti4 (UTItype n, UTItype d, UTItype *rp)
- +{
- + TIunion ww;
- + TIunion nn, dd;
- + TIunion rr;
- + UDItype d0, d1, n0, n1, n2;
- + UDItype q0, q1;
- + UDItype b, bm;
- +
- + nn.ti = n;
- + dd.ti = d;
- +
- + d0 = dd.d.low;
- + d1 = dd.d.high;
- + n0 = nn.d.low;
- + n1 = nn.d.high;
- +
- +
- + if (d1 == 0)
- + {
- + if (d0 > n1)
- + {
- + /* 0q = nn / 0D */
- +
- + count_leading_zeros_di (bm, d0);
- +
- + if (bm != 0)
- + {
- + /* Normalize, i.e. make the most significant bit of the
- + denominator set. */
- +
- + d0 = d0 << bm;
- + n1 = (n1 << bm) | (n0 >> (DI_TYPE_SIZE - bm));
- + n0 = n0 << bm;
- + }
- +
- + udiv_qrnnd_c_di (q0, n0, n1, n0, d0);
- + q1 = 0;
- +
- + /* Remainder in n0 >> bm. */
- + }
- + else
- + {
- + /* qq = NN / 0d */
- +
- + if (d0 == 0)
- + d0 = 1 / d0; /* Divide intentionally by zero. */
- +
- + count_leading_zeros_di (bm, d0);
- +
- + if (bm == 0)
- + {
- + /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
- + conclude (the most significant bit of n1 is set) /\ (the
- + leading quotient digit q1 = 1).
- +
- + This special case is necessary, not an optimization.
- + (Shifts counts of DI_TYPE_SIZE are undefined.) */
- +
- + n1 -= d0;
- + q1 = 1;
- + }
- + else
- + {
- + /* Normalize. */
- +
- + b = DI_TYPE_SIZE - bm;
- +
- + d0 = d0 << bm;
- + n2 = n1 >> b;
- + n1 = (n1 << bm) | (n0 >> b);
- + n0 = n0 << bm;
- +
- + udiv_qrnnd_c_di (q1, n1, n2, n1, d0);
- + }
- +
- + /* n1 != d0... */
- +
- + udiv_qrnnd_c_di (q0, n0, n1, n0, d0);
- +
- + /* Remainder in n0 >> bm. */
- + }
- +
- + if (rp != 0)
- + {
- + rr.d.low = n0 >> bm;
- + rr.d.high = 0;
- + *rp = rr.ti;
- + }
- + }
- + else
- + {
- + if (d1 > n1)
- + {
- + /* 00 = nn / DD */
- +
- + q0 = 0;
- + q1 = 0;
- +
- + /* Remainder in n1n0. */
- + if (rp != 0)
- + {
- + rr.d.low = n0;
- + rr.d.high = n1;
- + *rp = rr.ti;
- + }
- + }
- + else
- + {
- + /* 0q = NN / dd */
- +
- + count_leading_zeros_di (bm, d1);
- + if (bm == 0)
- + {
- + /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
- + conclude (the most significant bit of n1 is set) /\ (the
- + quotient digit q0 = 0 or 1).
- +
- + This special case is necessary, not an optimization. */
- +
- + /* The condition on the next line takes advantage of that
- + n1 >= d1 (true due to program flow). */
- + if (n1 > d1 || n0 >= d0)
- + {
- + q0 = 1;
- + sub_ddmmss_di (n1, n0, n1, n0, d1, d0);
- + }
- + else
- + q0 = 0;
- +
- + q1 = 0;
- +
- + if (rp != 0)
- + {
- + rr.d.low = n0;
- + rr.d.high = n1;
- + *rp = rr.ti;
- + }
- + }
- + else
- + {
- + UDItype m1, m0;
- + /* Normalize. */
- +
- + b = DI_TYPE_SIZE - bm;
- +
- + d1 = (d1 << bm) | (d0 >> b);
- + d0 = d0 << bm;
- + n2 = n1 >> b;
- + n1 = (n1 << bm) | (n0 >> b);
- + n0 = n0 << bm;
- +
- + udiv_qrnnd_c_di (q0, n1, n2, n1, d1);
- + umul_ppmm_di (m1, m0, q0, d0);
- +
- + if (m1 > n1 || (m1 == n1 && m0 > n0))
- + {
- + q0--;
- + sub_ddmmss_di (m1, m0, m1, m0, d1, d0);
- + }
- +
- + q1 = 0;
- +
- + /* Remainder in (n1n0 - m1m0) >> bm. */
- + if (rp != 0)
- + {
- + sub_ddmmss_di (n1, n0, n1, n0, m1, m0);
- + rr.d.low = (n1 << b) | (n0 >> bm);
- + rr.d.high = n1 >> bm;
- + *rp = rr.ti;
- + }
- + }
- + }
- + }
- +
- + ww.d.low = q0;
- + ww.d.high = q1;
- + return ww.ti;
- +}
- +#endif
- +
- +#ifdef L_divti3
- +UTItype __udivmodti4 ();
- +
- +TItype
- +__divti3 (TItype u, TItype v)
- +{
- + word_type c = 0;
- + TIunion uu, vv;
- + TItype w;
- +
- + uu.ti = u;
- + vv.ti = v;
- +
- + if (uu.d.high < 0)
- + c = ~c,
- + uu.ti = __negti2 (uu.ti);
- + if (vv.d.high < 0)
- + c = ~c,
- + vv.ti = __negti2 (vv.ti);
- +
- + w = __udivmodti4 (uu.ti, vv.ti, (UTItype *) 0);
- + if (c)
- + w = __negti2 (w);
- +
- + return w;
- +}
- +#endif
- +
- +#ifdef L_modti3
- +UTItype __udivmodti4 ();
- +
- +TItype
- +__modti3 (TItype u, TItype v)
- +{
- + word_type c = 0;
- + TIunion uu, vv;
- + TItype w;
- +
- + uu.ti = u;
- + vv.ti = v;
- +
- + if (uu.d.high < 0)
- + c = ~c,
- + uu.ti = __negti2 (uu.ti);
- + if (vv.d.high < 0)
- + vv.ti = __negti2 (vv.ti);
- +
- + (void) __udivmodti4 (uu.ti, vv.ti, (UTItype *)&w);
- + if (c)
- + w = __negti2 (w);
- +
- + return w;
- +}
- +#endif
- +
- +#ifdef L_umodti3
- +UTItype __udivmodti4 ();
- +
- +UTItype
- +__umodti3 (UTItype u, UTItype v)
- +{
- + UTItype w;
- +
- + (void) __udivmodti4 (u, v, &w);
- +
- + return w;
- +}
- +#endif
- +
- +
- +#ifdef L_udivti3
- +UTItype __udivmodti4 ();
- +UTItype
- +__udivti3 (UTItype n, UTItype d)
- +{
- + return __udivmodti4 (n, d, (UTItype *) 0);
- +}
- +#endif
- +
- +#ifdef L_cmpti2
- +word_type
- +__cmpti2 (TItype a, TItype b)
- +{
- + TIunion au, bu;
- +
- + au.ti = a, bu.ti = b;
- +
- + if (au.d.high < bu.d.high)
- + return 0;
- + else if (au.d.high > bu.d.high)
- + return 2;
- + if ((UDItype) au.d.low < (UDItype) bu.d.low)
- + return 0;
- + else if ((UDItype) au.d.low > (UDItype) bu.d.low)
- + return 2;
- + return 1;
- +}
- +#endif
- +
- +#ifdef L_ucmpti2
- +word_type
- +__ucmpti2 (UTItype a, UTItype b)
- +{
- + TIunion au, bu;
- +
- + au.ti = a, bu.ti = b;
- +
- + if ((UDItype) au.d.high < (UDItype) bu.d.high)
- + return 0;
- + else if ((UDItype) au.d.high > (UDItype) bu.d.high)
- + return 2;
- + if ((UDItype) au.d.low < (UDItype) bu.d.low)
- + return 0;
- + else if ((UDItype) au.d.low > (UDItype) bu.d.low)
- + return 2;
- + return 1;
- +}
- +#endif
- +
- +
- +/*
- + Followings are not neeeded, because TF or XF mode is not supported.
- + __fixunstfti(), __fixtfdi()
- + __fixunsxfti(), __fixxfti()
- +*/
- +
- +#ifdef L_fixunsdfti
- +TItype
- +__fixunsdfti (DFtype a)
- +{
- + DFtype b;
- + UTItype v;
- +
- + if (a < 0)
- + return 0;
- +
- + /* Compute high word of result, as a flonum. */
- + b = (a / HIGH_DI_WORD_COEFF);
- + /* Convert that to fixed (but not to DItype!),
- + and shift it into the high word. */
- + v = (UDItype) b;
- + v <<= DI_WORD_SIZE;
- + /* Remove high part from the DFtype, leaving the low part as flonum. */
- + a -= (DFtype)v;
- + /* Convert that to fixed (but not to DItype!) and add it in.
- + Sometimes A comes out negative. This is significant, since
- + A has more bits than a long int does. */
- + if (a < 0)
- + v -= (UDItype) (- a);
- + else
- + v += (UDItype) a;
- + return v;
- +}
- +#endif
- +
- +#ifdef L_fixdfti
- +TItype
- +__fixdfti (DFtype a)
- +{
- + if (a < 0)
- + return - __fixunsdfti (-a);
- + return __fixunsdfti (a);
- +}
- +#endif
- +
- +/*
- + Followings are not neeeded, because TF or XF mode is not supported.
- + __floattixf
- + __floattitf
- +*/
- +
- +#ifdef L_floattidf
- +DFtype
- +__floattidf (TItype u)
- +{
- + DFtype d;
- +
- + d = (DItype) (u >> DI_WORD_SIZE);
- + d *= HIGH_DI_HALFWORD_COEFF;
- + d *= HIGH_DI_HALFWORD_COEFF;
- + d += (UDItype) (u & (HIGH_DI_WORD_COEFF - 1));
- +
- + return d;
- +}
- +#endif
- +
- +#ifdef L_floattisf
- +SFtype
- +__floattisf (TItype u)
- +{
- + DFtype df;
- + df = __floattidf (u);
- + return (SFtype) df;
- +}
- +#endif
- diff -burN orig.gcc-3.2.3/gcc/Makefile.in gcc-3.2.3/gcc/Makefile.in
- --- orig.gcc-3.2.3/gcc/Makefile.in 2003-01-28 17:54:07.000000000 -0400
- +++ gcc-3.2.3/gcc/Makefile.in 2007-07-26 13:04:40.000000000 -0300
- @@ -987,6 +987,7 @@
- LIB2FUNCS_ST='$(LIB2FUNCS_ST)' \
- LIB2ADD='$(LIB2ADD)' \
- LIB2ADD_ST='$(LIB2ADD_ST)' \
- + LIB2FUNCS_TI='$(LIB2FUNCS_TI)' \
- LIB2ADDEH='$(LIB2ADDEH)' \
- LIB2ADDEHDEP='$(LIB2ADDEHDEP)' \
- FPBIT='$(FPBIT)' \
- diff -burN orig.gcc-3.2.3/gcc/collect2.c gcc-3.2.3/gcc/collect2.c
- --- orig.gcc-3.2.3/gcc/collect2.c 2009-08-19 16:36:00.000000000 -0500
- +++ gcc-3.2.3/gcc/collect2.c 2009-08-19 16:36:11.000000000 -0500
- @@ -1587,7 +1587,7 @@
- if (redir)
- {
- /* Open response file. */
- - redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT);
- + redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT, 0666);
- /* Duplicate the stdout and stderr file handles
- so they can be restored later. */
- diff -burN orig.gcc-3.2.3/gcc/mklibgcc.in gcc-3.2.3/gcc/mklibgcc.in
- --- orig.gcc-3.2.3/gcc/mklibgcc.in 2003-01-28 17:57:40.000000000 -0400
- +++ gcc-3.2.3/gcc/mklibgcc.in 2007-07-26 13:04:40.000000000 -0300
- @@ -232,6 +232,21 @@
- libgcc2_st_objs="$libgcc2_st_objs ${oname}${objext}"
- done
- +if [ "$LIB2FUNCS_TI" ]; then
- + for name in $LIB2FUNCS_TI; do
- + for ml in $MULTILIBS; do
- + dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
- + flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
- + out="libgcc/${dir}/${name}${objext}"
- +
- + echo $out: $libgcc2_c_dep
- + echo " $gcc_compile" '$(MAYBE_USE_COLLECT2)' $flags -DL$name \
- + -c '$(srcdir)/libgcc2-timode.c' -o $out
- + done
- + libgcc2_objs="$libgcc2_objs ${name}${objext}"
- + done
- +fi
- +
- # SHLIB_MKMAP
- # SHLIB_MKMAP_OPTS
- # SHLIB_MAPFILES
- diff -burN orig.gcc-3.2.3/gcc/toplev.c gcc-3.2.3/gcc/toplev.c
- --- orig.gcc-3.2.3/gcc/toplev.c 2002-11-01 20:57:23.000000000 -0400
- +++ gcc-3.2.3/gcc/toplev.c 2007-07-26 13:04:40.000000000 -0300
- @@ -3469,6 +3469,18 @@
- convert_to_eh_region_ranges ();
- +#ifdef MACHINE_DEPENDENT_REORG_FINAL
- + timevar_push (TV_MACH_DEP);
- + open_dump_file (DFI_mach, decl);
- +
- + MACHINE_DEPENDENT_REORG_FINAL (insns);
- +
- + close_dump_file (DFI_mach, print_rtl, insns);
- + timevar_pop (TV_MACH_DEP);
- +
- + ggc_collect ();
- +#endif
- +
- /* Shorten branches. */
- timevar_push (TV_SHORTEN_BRANCH);
- shorten_branches (get_insns ());
- diff -burN orig.gcc-3.2.3/include/obstack.h gcc-3.2.3/include/obstack.h
- --- orig.gcc-3.2.3/include/obstack.h 2001-03-14 15:44:38.000000000 -0400
- +++ gcc-3.2.3/include/obstack.h 2007-07-26 13:04:40.000000000 -0300
- @@ -423,7 +423,8 @@
- ({ struct obstack *__o = (OBSTACK); \
- if (__o->next_free + sizeof (void *) > __o->chunk_limit) \
- _obstack_newchunk (__o, sizeof (void *)); \
- - *((void **)__o->next_free)++ = ((void *)datum); \
- + *((void **)__o->next_free) = ((void *)datum); \
- + __o->next_free += sizeof(void *); \
- (void) 0; })
- # define obstack_int_grow(OBSTACK,datum) \
- diff -burN orig.gcc-3.2.3/libstdc++-v3/configure.target gcc-3.2.3/libstdc++-v3/configure.target
- --- orig.gcc-3.2.3/libstdc++-v3/configure.target 2002-09-06 15:32:08.000000000 -0300
- +++ gcc-3.2.3/libstdc++-v3/configure.target 2007-07-26 13:04:40.000000000 -0300
- @@ -55,6 +55,9 @@
- m68k | m680[246]0)
- cpu_include_dir="config/cpu/m68k"
- ;;
- + mips)
- + cpu_include_dir="config/cpu/mips"
- + ;;
- powerpc | rs6000)
- cpu_include_dir="config/cpu/powerpc"
- ;;
- diff -burN orig.gcc-3.2.3/libstdc++-v3/libsupc++/pure.cc gcc-3.2.3/libstdc++-v3/libsupc++/pure.cc
- --- orig.gcc-3.2.3/libstdc++-v3/libsupc++/pure.cc 2002-06-28 05:22:38.000000000 -0300
- +++ gcc-3.2.3/libstdc++-v3/libsupc++/pure.cc 2007-07-26 13:04:40.000000000 -0300
- @@ -46,6 +46,6 @@
- extern "C" void
- __cxa_pure_virtual (void)
- {
- - writestr ("pure virtual method called\n");
- +// writestr ("pure virtual method called\n");
- std::terminate ();
- }
- diff -burN orig.gcc-3.2.3/README.PS2 gcc-3.2.3/README.PS2
- --- orig.gcc-3.2.3/README.PS2 1969-12-31 20:00:00.000000000 -0400
- +++ gcc-3.2.3/README.PS2 2007-07-26 13:04:40.000000000 -0300
- @@ -0,0 +1,80 @@
- +Apologies to mrbrown, who's README.PS2 this was based on.
- +GCC for Sony Playstation 2
- +http://www.ps2dev.org/
- +BETA 3 Release 3.2.3-20040214-1
- +==
- +
- +This patch contains a port of the GNU Compiler Collection (http://gcc.gnu.org)
- +version 3.2.3 (prerelease) to the Sony Playstation 2. It supports a C and C++
- +cross-compiler targeting the Emotion Engine (Toshiba MIPS R5900). It is based
- +off of the port that Cygnus (now Red Hat) created for the original PS2 SDK,
- +and contains a number of changes and updates that mrbrown has incorporated,
- +plus some fixes by me.
- +
- +Unfortunately, there is no ChangeLog in this release.
- +
- +The Playstation 2 Linux kit is NOT supported in this release. There are a
- +number of issues related to the deployment of this version of GCC in that
- +environment. This is left as an exercise for the ps2linux folks.
- +
- +You can grab the source to the GCC 3.2.3 release from
- +ftp://ftp.gnu.org/pub/gnu/gcc/gcc-3.2.3.tar.gz or a mirror site.
- +
- +
- +Features
- +--
- +
- +- Basic support for the R5900 and COP1.
- +- Initial support for 128-bit logical/arith operations (pand, pnor, etc.).
- +- Initial support for MMI built-in functions (__builtin_paddb, etc.) and vector
- + types.
- +- The main "feature" of this release is the port to the 3.2.3 compiler and fixes
- + to the HILO1 code, allowing re-enabling of double precision emulation and also
- + C++ global constructor fixes. This release may fix the 64bit shift bug, but
- + if that's the case then it's a side effect of another fix.
- +- Used in conjunction with my binutils-2.13.2.1 patch, you should be able to use
- + -O0 and -O1 without causing bad code generation.
- +- Alignment in bss sections bug fix.
- +
- +To configure the compiler, you can use one of the following configuration
- +names:
- +
- + ee, mips64r5900[el], mipsEE[el]
- +
- +If you don't specify the OS portion of the name, -elf is assumed. Note that
- +even if you leave off the "el", you cannot build for big-endian R5900 (it's
- +explicitly disabled). I always use "ee".
- +
- +
- +Known Bugs
- +--
- +
- +[ I haven't found any serious codegen bugs yet. Mail to the ps2dev forums if
- + you find any. ]
- +
- + If you wish to disable double precision emulation, comment out the text around
- + DPBIT (and the make target that follows it) in gcc/config/mips/t-r5900. If you
- + comment this section out and use double precision FP in your code, you WILL
- + receive link errors when linking with libgcc. You can use this "feature" as a
- + tool to find all misuses of float constants and type conversions in your code.
- + Personally, I had trouble getting libstdc++-v3 to build without double precision
- + emulation but YMMV. It should be possible to configure the compiler and libs
- + to use single precision doubles in place of doubles, however you'd have to make
- + sure that all your libs are built in this manner.
- +
- +
- +Future Work
- +--
- +
- + Move over to gcc 3.4, once it's released. gcc 3.4 includes a re-write of the
- + entire mips back end and it looks a lot cleaner.
- +
- +
- +Contact
- +--
- +
- + Use the forums at www.ps2dev.org or find me on IRC at #ps2dev on EFnet.
- +
- +--
- +MrHTFord (mrhtford_ps2dev@hotmail.com)
- +Friday 14th February 2004.
Add Comment
Please, Sign In to add comment