summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/config/rs6000/rs6000.c14
-rw-r--r--gcc/config/rs6000/rs6000.h58
-rw-r--r--gcc/config/rs6000/rs6000.md11
-rw-r--r--gcc/config/rs6000/sysv4.h49
-rw-r--r--gcc/config/rs6000/t-ppc31
-rw-r--r--gcc/config/rs6000/t-ppcgas33
-rw-r--r--gcc/genmultilib10
7 files changed, 194 insertions, 12 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index ce2463d5f26..1f06bb6edd2 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -186,6 +186,20 @@ rs6000_override_options ()
target_flags = (target_flags & ~MASK_MULTIPLE) | multiple;
}
+/* Create a CONST_DOUBLE like immed_double_const, except reverse the
+ two parts of the constant if the target is little endian. */
+
+struct rtx_def *rs6000_immed_double_const (i0, i1, mode)
+ HOST_WIDE_INT i0, i1;
+ enum machine_mode mode;
+{
+ if (! WORDS_BIG_ENDIAN)
+ return immed_double_const (i1, i0, mode);
+
+ return immed_double_const (i0, i1, mode);
+}
+
+
/* Return non-zero if this function is known to have a null epilogue. */
int
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index c13a6b43ca0..96b7951c7a7 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -2345,3 +2345,61 @@ toc_section () \
GT, LEU, LTU, GEU, GTU}}, \
{"scc_comparison_operator", {EQ, NE, LE, LT, GE, \
GT, LEU, LTU, GEU, GTU}},
+
+/* Declare functions in rs6000.c */
+extern void rs6000_override_options ();
+extern struct rtx_def *rs6000_immed_double_const ();
+extern int direct_return ();
+extern int any_operand ();
+extern int short_cint_operand ();
+extern int u_short_cint_operand ();
+extern int non_short_cint_operand ();
+extern int gpc_reg_operand ();
+extern int cc_reg_operand ();
+extern int reg_or_short_operand ();
+extern int reg_or_neg_short_operand ();
+extern int reg_or_u_short_operand ();
+extern int reg_or_cint_operand ();
+extern int easy_fp_constant ();
+extern int low_32_bit_operand ();
+extern int fp_reg_or_mem_operand ();
+extern int mem_or_easy_const_operand ();
+extern int add_operand ();
+extern int non_add_cint_operand ();
+extern int logical_operand ();
+extern int non_logical_operand ();
+extern int mask_constant ();
+extern int mask_operand ();
+extern int and_operand ();
+extern int non_and_cint_operand ();
+extern int reg_or_mem_operand ();
+extern int lwa_operand ();
+extern int call_operand ();
+extern int current_file_function_operand ();
+extern int input_operand ();
+extern int load_multiple_operation ();
+extern int store_multiple_operation ();
+extern int branch_comparison_operator ();
+extern int scc_comparison_operator ();
+extern int includes_lshift_p ();
+extern int includes_rshift_p ();
+extern int registers_ok_for_quad_peep ();
+extern int addrs_ok_for_quad_peep ();
+extern enum reg_class secondary_reload_class ();
+extern int ccr_bit ();
+extern void print_operand ();
+extern void print_operand_address ();
+extern int first_reg_to_save ();
+extern int first_fp_reg_to_save ();
+extern int must_save_cr ();
+extern int rs6000_sa_size ();
+extern int rs6000_makes_calls ();
+extern int rs6000_pushes_stack ();
+extern void svr4_traceback ();
+extern void output_prolog ();
+extern void output_epilog ();
+extern void output_toc ();
+extern void output_ascii ();
+extern void rs6000_gen_section_name ();
+extern void output_function_profiler ();
+extern int rs6000_adjust_cost ();
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 629eeeca575..ecbbc3695f4 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -3297,9 +3297,10 @@
{
operands[2] = gen_reg_rtx (DImode);
operands[3] = gen_rtx (CONST_INT, VOIDmode, 0x80000000);
- operands[4] = immed_double_const (0, 0x43300000, DImode);
- operands[5] = force_reg (DFmode, immed_double_const (0x43300000,
- 0x80000000, DFmode));
+ operands[4] = rs6000_immed_double_const (0, 0x43300000, DImode);
+ operands[5] = force_reg (DFmode, rs6000_immed_double_const (0x43300000,
+ 0x80000000,
+ DFmode));
}")
(define_expand "floatunssidf2"
@@ -3313,8 +3314,8 @@
"
{
operands[2] = gen_reg_rtx (DImode);
- operands[3] = immed_double_const (0, 0x43300000, DImode);
- operands[4] = force_reg (DFmode, immed_double_const (0x43300000, 0, DFmode));
+ operands[3] = rs6000_immed_double_const (0, 0x43300000, DImode);
+ operands[4] = force_reg (DFmode, rs6000_immed_double_const (0x43300000, 0, DFmode));
}")
;; For the above two cases, we always split.
diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
index f42b359386e..b309fa34a9d 100644
--- a/gcc/config/rs6000/sysv4.h
+++ b/gcc/config/rs6000/sysv4.h
@@ -25,6 +25,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define MASK_STRICT_ALIGN 0x20000000 /* Set STRICT_ALIGNMENT to 1. */
#define MASK_RELOCATABLE 0x10000000 /* GOT pointers are PC relative */
#define MASK_NO_TRACEBACK 0x08000000 /* eliminate traceback words */
+#define MASK_LITTLE_ENDIAN 0x04000000 /* target is little endian */
#define TARGET_NO_BITFIELD_TYPE (target_flags & MASK_NO_BITFIELD_TYPE)
#define TARGET_BITFIELD_TYPE (! TARGET_NO_BITFIELD_TYPE)
@@ -32,6 +33,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define TARGET_RELOCATABLE (target_flags & MASK_RELOCATABLE)
#define TARGET_NO_TRACEBACK (target_flags & MASK_NO_TRACEBACK)
#define TARGET_TRACEBACK (! TARGET_NO_TRACEBACK)
+#define TARGET_LITTLE_ENDIAN (target_flags & MASK_LITTLE_ENDIAN)
+#define TARGET_BIG_ENDIAN (! TARGET_LITTLE_ENDIAN)
#undef SUBTARGET_SWITCHES
#define SUBTARGET_SWITCHES \
@@ -42,10 +45,31 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
{ "relocatable", MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC }, \
{ "no-relocatable", -MASK_RELOCATABLE }, \
{ "traceback", -MASK_NO_TRACEBACK }, \
- { "no-traceback", MASK_NO_TRACEBACK },
+ { "no-traceback", MASK_NO_TRACEBACK }, \
+ { "little-endian", MASK_LITTLE_ENDIAN }, \
+ { "little", MASK_LITTLE_ENDIAN }, \
+ { "big-endian", -MASK_LITTLE_ENDIAN }, \
+ { "big", -MASK_LITTLE_ENDIAN },
+
+/* If the user wants little endian support, don't allow -mmultiple */
+#define SUBTARGET_OVERRIDE_OPTIONS \
+{ \
+ if (TARGET_LITTLE_ENDIAN && TARGET_MULTIPLE) \
+ { \
+ target_flags &= ~MASK_MULTIPLE; \
+ if (TARGET_MULTIPLE_SET) \
+ warning ("-mmultiple is not supported on little endian PowerPC systems"); \
+ } \
+}
#include "rs6000/powerpc.h"
+/* Override default big endianism */
+#undef BYTES_BIG_ENDIAN
+#undef WORDS_BIG_ENDIAN
+#define BYTES_BIG_ENDIAN (TARGET_BIG_ENDIAN)
+#define WORDS_BIG_ENDIAN (TARGET_BIG_ENDIAN)
+
/* Don't generate XCOFF debugging information. */
#undef XCOFF_DEBUGGING_INFO
@@ -239,7 +263,13 @@ extern int rs6000_pic_labelno;
implies. */
#undef ASM_SPEC
#define ASM_SPEC \
- "-u -mppc %{V} %{v:%{!V:-V}} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} %{mrelocatable}"
+ "-u \
+%{mcpu=601: -m601} %{mcpu=ppc601: -m601} %{mcpu=mpc601: -m601} \
+%{!mcpu=601: %{!mcpu=ppc601: %{!mcpu=mpc601: -mppc }}} \
+%{V} %{v:%{!V:-V}} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} \
+%{mrelocatable} \
+%{mlittle} %{mlittle-endian} %{mbig} %{mbig-endian}"
+
/* This is the end of what might become sysv4.h. */
/* Allow stabs and dwarf, prefer dwarf. */
@@ -272,6 +302,21 @@ extern int rs6000_pic_labelno;
#define CPP_PREDEFINES \
"-DPPC -Dunix -D__svr4__ -Asystem(unix) -Asystem(svr4) -Acpu(powerpc) -Amachine(powerpc)"
+#undef LINK_SPEC
+#define LINK_SPEC "\
+%{h*} %{V} %{v:%{!V:-V}} \
+%{b} %{Wl,*:%*} \
+%{static:-dn -Bstatic} \
+%{shared:-G -dy -z text %{!h*:%{o*:-h %*}}} \
+%{symbolic:-Bsymbolic -G -dy -z text %{!h*:%{o*:-h %*}}} \
+%{G:-G} \
+%{YP,*} \
+%{!YP,*:%{p:-Y P,/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \
+%{!p:-Y P,/usr/ccs/lib:/usr/lib}} \
+%{Qy:} %{!Qn:-Qy} \
+%{mlittle: -m elf32-powerpcle } %{mlittle-endian: -m elf32-powerpcle } \
+%{mbig: -m elf32-powerpc } %{mbig-endian: -m elf32-powerpc }"
+
#undef CPP_SPEC
#define CPP_SPEC "\
%{posix: -D_POSIX_SOURCE} \
diff --git a/gcc/config/rs6000/t-ppc b/gcc/config/rs6000/t-ppc
new file mode 100644
index 00000000000..fbb26ef7414
--- /dev/null
+++ b/gcc/config/rs6000/t-ppc
@@ -0,0 +1,31 @@
+# Do not build libgcc1.
+LIBGCC1 =
+CROSS_LIBGCC1 =
+
+# These are really part of libgcc1, but this will cause them to be
+# built correctly, so... [taken from t-sparclite]
+LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c
+
+dp-bit.c: $(srcdir)/config/fp-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
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+# Build libgcc.a with different options. If no gas support, don't build
+# explicit little endian or big endian libraries, since it depends on the
+# -mbig/-mlittle switches passed to gas.
+
+MULTILIB_OPTIONS = msoft-float \
+ mmultiple/mno-multiple
+
+MULTILIB_DIRNAMES = soft-float \
+ multiple no-multiple
+
+MULTILIB_MATCHES = msoft-float=mcpu?403 \
+ msoft-float=mcpu?mpc403 \
+ msoft-float=mcpu?ppc403
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
diff --git a/gcc/config/rs6000/t-ppcgas b/gcc/config/rs6000/t-ppcgas
new file mode 100644
index 00000000000..b9da6c73fcf
--- /dev/null
+++ b/gcc/config/rs6000/t-ppcgas
@@ -0,0 +1,33 @@
+# Do not build libgcc1.
+LIBGCC1 =
+CROSS_LIBGCC1 =
+
+# These are really part of libgcc1, but this will cause them to be
+# built correctly, so... [taken from t-sparclite]
+LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c
+
+dp-bit.c: $(srcdir)/config/fp-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
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+# Build libgcc.a with different options.
+
+MULTILIB_OPTIONS = msoft-float \
+ mlittle/mbig \
+ mmultiple/mno-multiple
+
+MULTILIB_DIRNAMES = soft-float \
+ little-endian big-endian \
+ multiple no-multiple
+
+MULTILIB_MATCHES = mlittle=mlittle-endian \
+ mbig=mbig-endian \
+ msoft-float=mcpu?403 \
+ msoft-float=mcpu?mpc403 \
+ msoft-float=mcpu?ppc403
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
diff --git a/gcc/genmultilib b/gcc/genmultilib
index 9118ad07b1a..66dc0d477d9 100644
--- a/gcc/genmultilib
+++ b/gcc/genmultilib
@@ -39,7 +39,7 @@
# identical. The elements in the list are separated by spaces. Each
# element must be of the form OPTION=OPTION. The first OPTION should
# appear in the first argument, and the second should be a synonym for
-# it.
+# it. Question marks are replaced with equal signs in both options.
# The output looks like
# #define MULTILIB_MATCHES "\
@@ -132,8 +132,8 @@ fi
# quoted spaces when expanding a variable.
matchnegations=
for i in ${matches}; do
- l=`echo $i | sed -e 's/=.*$//'`
- r=`echo $i | sed -e 's/^.*=//'`
+ l=`echo $i | sed -e 's/=.*$//' -e 's/?/=/g'`
+ r=`echo $i | sed -e 's/^.*=//' -e 's/?/=/g'`
matchnegations="${matchnegations} -e s/;!${l};/;!${l};!${r};/"
done
@@ -158,8 +158,8 @@ else
first=$1
shift
dirout="${dirout}" optout="${optout}" ./tmpmultilib2 $@
- l=`echo ${first} | sed -e 's/=.*$//'`
- r=`echo ${first} | sed -e 's/^.*=//'`
+ l=`echo ${first} | sed -e 's/=.*$//' -e 's/?/=/g'`
+ r=`echo ${first} | sed -e 's/^.*=//' -e 's/?/=/g'`
case " ${optout} " in
*" ${l} "*)
newopt=`echo " ${optout} " | sed -e "s/ ${l} / ${r} /" -e 's/^ //' -e 's/ $//'`