Support -msoft-float; support eabi -mrelocatable
authorMichael Meissner <meissner@gcc.gnu.org>
Thu, 23 Feb 1995 20:30:26 +0000 (20:30 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Thu, 23 Feb 1995 20:30:26 +0000 (20:30 +0000)
From-SVN: r9053

gcc/config/rs6000/eabi.asm [new file with mode: 0644]
gcc/config/rs6000/eabi.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/rs6000.md
gcc/config/rs6000/sysv4.h
gcc/config/rs6000/t-rs6000

diff --git a/gcc/config/rs6000/eabi.asm b/gcc/config/rs6000/eabi.asm
new file mode 100644 (file)
index 0000000..65b7518
--- /dev/null
@@ -0,0 +1,57 @@
+# File to either setup register 2 to point to the GOT, or to adjust the
+# pointers in the .got2 section to point to their new addresses.
+
+       .file   "eabi.asm"
+       .section ".text"
+       .globl   __eabi
+
+       .long   0x4000                          # traceback table
+__eabi:        mflr    0
+       bl      .Laddr                          # get current address
+
+# Table of addresses
+.Ltable:
+       .long   .Ltable                         # address we are really at
+       .long   _GLOBAL_OFFSET_TABLE_           # normal GOT address
+       .long   _GOT2_START_                    # -mrelocatable GOT pointers start
+       .long   _GOT2_END_                      # -mrelocatable GOT pointers end
+
+.Laddr:        mflr    11                              # real address of .Ltable
+       lwz     12,0(11)                        # linker generated address of .Ltable
+       subf.   12,12,11                        # calculate difference
+       bc      4,2,.Lreloc                     # skip if we need to relocate
+
+# Normal program, load up register 2
+
+       mtlr    0                               # restore link register
+       lwz     2,4(11)                         # normal GOT address
+       blr
+
+# We need to relocate the .got2 pointers.  Don't load register 2
+
+.Lreloc:
+       stwu    30,-4(1)
+       stwu    31,-4(1)
+       lwz     30,8(11)                        # GOT pointers start
+       lwz     31,12(11)                       # GOT pointers end
+       add     30,12,30                        # adjust pointers
+       add     31,12,31
+
+       cmpw    1,30,31                         # any pointers to adjust
+       bc      12,6,.Ldone
+
+.Lloop:        lwz     11,0(30)                        # next pointer
+       add     11,11,12                        # adjust
+       stw     11,0(30)
+       addi    30,30,4                         # bump to next word
+       cmpw    1,30,31                         # more pointers to adjust?
+       bc      4,6,.Lloop
+
+# Done adjusting pointers, return
+
+.Ldone:
+       mtlr    0                               # restore link register
+       lwz     31,0(1)
+       lwz     30,-4(1)                        # restore regs
+       addic   1,1,8                           # pop stack
+       blr
index 0d04790..2a9ae8d 100644 (file)
@@ -19,22 +19,6 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
-/* eABI local switches */
-/* Set PCC_BITFIELD_TYPE_MATTERS to 0 to ignore the type of bitfields
-   when calculating alignment.  */
-#define        MASK_NO_BITFIELD_TYPE   0x40000000
-#define        MASK_STRICT_ALIGN       0x20000000
-
-#define        TARGET_NO_BITFIELD_TYPE (target_flags & MASK_NO_BITFIELD_TYPE)
-#define        TARGET_BITFIELD_TYPE    (! TARGET_NO_BITFIELD_TYPE)
-#define TARGET_STRICT_ALIGN    (target_flags & MASK_STRICT_ALIGN)
-
-#define SUBTARGET_SWITCHES                                             \
-  { "bit-align",       -MASK_NO_BITFIELD_TYPE },                       \
-  { "no-bit-align",     MASK_NO_BITFIELD_TYPE },                       \
-  { "strict-align",     MASK_STRICT_ALIGN },                           \
-  { "no-strict-align", -MASK_STRICT_ALIGN },
-
 #include "rs6000/sysv4.h"
 
 /* For now, make stabs the default debugging type, not dwarf. */
@@ -60,6 +44,15 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #undef BIGGEST_ALIGNMENT
 #define BIGGEST_ALIGNMENT 64
 
+/* Put PC relative got entries in .got2 */
+#undef MINIMAL_TOC_SECTION_ASM_OP
+#define MINIMAL_TOC_SECTION_ASM_OP \
+  ((TARGET_RELOCATABLE) ? "\t.section\t\".got2\",\"aw\"" : "\t.section\t\".got1\",\"aw\"")
+
+/* Invoke an initializer function to set up the GOT */
+#define INVOKE__main 1
+#define NAME__MAIN "__eabi"
+
 #undef TARGET_VERSION
 #define TARGET_VERSION fprintf (stderr, " (PowerPC Embedded)");
 
index bd79804..4890134 100644 (file)
@@ -75,7 +75,7 @@ rs6000_override_options ()
   /* Simplify the entries below by making a mask for any POWER
      variant and any PowerPC variant.  */
 
-#define POWER_MASKS (MASK_POWER | MASK_POWER2)
+#define POWER_MASKS (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE)
 #define POWERPC_MASKS (MASK_POWERPC | MASK_PPC_GPOPT \
                       | MASK_PPC_GFXOPT | MASK_POWERPC64)
 #define POWERPC_OPT_MASKS (MASK_PPC_GPOPT | MASK_PPC_GFXOPT)
@@ -89,34 +89,34 @@ rs6000_override_options ()
     } processor_target_table[]
       = {{"common", PROCESSOR_COMMON, 0, POWER_MASKS | POWERPC_MASKS},
         {"power", PROCESSOR_POWER,
-           MASK_POWER,
+           MASK_POWER | MASK_MULTIPLE,
            MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
         {"powerpc", PROCESSOR_POWERPC,
            MASK_POWERPC | MASK_NEW_MNEMONICS,
            POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
         {"rios", PROCESSOR_RIOS1,
-           MASK_POWER,
+           MASK_POWER | MASK_MULTIPLE,
            MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
         {"rios1", PROCESSOR_RIOS1,
-           MASK_POWER,
+           MASK_POWER | MASK_MULTIPLE,
            MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
         {"rsc", PROCESSOR_PPC601,
-           MASK_POWER,
+           MASK_POWER | MASK_MULTIPLE,
            MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
         {"rsc1", PROCESSOR_PPC601,
-           MASK_POWER,
+           MASK_POWER | MASK_MULTIPLE,
            MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
         {"rios2", PROCESSOR_RIOS2,
-           MASK_POWER | MASK_POWER2,
+           MASK_POWER | MASK_MULTIPLE | MASK_POWER2,
            POWERPC_MASKS | MASK_NEW_MNEMONICS},
         {"601", PROCESSOR_PPC601,
-           MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS,
+           MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_MULTIPLE,
            MASK_POWER2 | POWERPC_OPT_MASKS | MASK_POWERPC64},
         {"mpc601", PROCESSOR_PPC601,
-           MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS,
+           MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_MULTIPLE,
            MASK_POWER2 | POWERPC_OPT_MASKS | MASK_POWERPC64},
         {"ppc601", PROCESSOR_PPC601,
-           MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS,
+           MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_MULTIPLE,
            MASK_POWER2 | POWERPC_OPT_MASKS | MASK_POWERPC64},
         {"603", PROCESSOR_PPC603,
            MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
@@ -1601,6 +1601,12 @@ output_prolog (file, size)
       common_mode_defined = 1;
     }
 
+#ifdef USING_SVR4_H
+  /* If we have a relocatable GOT section, we need to save the LR. */
+  if (TARGET_RELOCATABLE && get_pool_size () != 0)
+    regs_ever_live[65] = 1;
+#endif
+
   /* If we have to call a function to save fpr's, or if we are doing profiling,
      then we will be using LR.  */
   if (first_fp_reg < 62 || profile_flag)
@@ -1673,12 +1679,38 @@ output_prolog (file, size)
      TOC_TABLE address into register 30.  */
   if (TARGET_MINIMAL_TOC && get_pool_size () != 0)
     {
-      char buf[100];
+      char buf[256];
 
-      ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 0);
-      asm_fprintf (file, "\t{l|lwz} 30,");
-      assemble_name (file, buf);
-      asm_fprintf (file, "(2)\n");
+#ifdef USING_SVR4_H
+      if (TARGET_RELOCATABLE)
+       {
+         static int labelno = 0;
+
+         ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", labelno);
+         fprintf (file, "\tbl ");
+         assemble_name (file, buf);
+         fprintf (file, "\n");
+
+         ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
+         fprintf (file, (TARGET_POWERPC64) ? "\t.quad " : "\t.long ");
+         assemble_name (file, buf);
+         fprintf (file, "-.\n");
+
+         ASM_OUTPUT_INTERNAL_LABEL (file, "LCF", labelno);
+         fprintf (file, "\tmflr 30\n");
+
+         asm_fprintf (file, (TARGET_POWERPC64) ? "\tld 0,0(30)\n" : "\t{l|lwz} 0,0(30)\n");
+         asm_fprintf (file, "\t{cax|add} 30,0,30\n");
+         labelno++;
+       }
+      else
+#endif /* USING_SVR4_H */
+       {
+         ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 0);
+         asm_fprintf (file, "\t{l|lwz} 30,");
+         assemble_name (file, buf);
+         asm_fprintf (file, "(2)\n");
+       }
     }
 }
 
@@ -1973,7 +2005,17 @@ output_toc (file, x, labelno)
   rtx base = x;
   int offset = 0;
 
-  ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno);
+#ifdef USING_SVR4_H
+  if (TARGET_MINIMAL_TOC)
+    {
+      ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
+      fprintf (file, "%d = .-", labelno);
+      ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LCTOC");
+      fprintf (file, "1\n");
+    }
+  else
+#endif /* USING_SVR4_H */
+    ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno);
 
   /* Handle FP constants specially.  Note that if we have a minimal
      TOC, things we put here aren't actually in the TOC, so we can allow
index 0339f49..55f52cb 100644 (file)
@@ -148,7 +148,7 @@ extern int target_flags;
 #define MASK_64BIT             0x400
 
 /* Disable use of FPRs.  */
-#define MASK_NO_FPR            0x800
+#define MASK_SOFT_FLOAT                0x800
 
 /* Enable load/store multiple, even on powerpc */
 #define        MASK_MULTIPLE           0x1000
@@ -164,9 +164,11 @@ extern int target_flags;
 #define TARGET_NO_SUM_IN_TOC           (target_flags & MASK_NO_SUM_IN_TOC)
 #define TARGET_MINIMAL_TOC             (target_flags & MASK_MINIMAL_TOC)
 #define TARGET_64BIT                   (target_flags & MASK_64BIT)
-#define TARGET_NO_FPR                  (target_flags & MASK_NO_FPR)
+#define TARGET_SOFT_FLOAT              (target_flags & MASK_SOFT_FLOAT)
 #define        TARGET_MULTIPLE                 (target_flags & MASK_MULTIPLE)
 
+#define TARGET_HARD_FLOAT              (! TARGET_SOFT_FLOAT)
+
 /* Run-time compilation parameters selecting different hardware subsets.
 
    Macro to define tables used to set the flags.
@@ -181,10 +183,10 @@ extern int target_flags;
 #endif
 
 #define TARGET_SWITCHES                                                \
- {{"power",            MASK_POWER},                            \
-  {"power2",           MASK_POWER | MASK_POWER2},              \
+ {{"power",            MASK_POWER  | MASK_MULTIPLE},           \
+  {"power2",           MASK_POWER | MASK_MULTIPLE | MASK_POWER2}, \
   {"no-power2",                - MASK_POWER2},                         \
-  {"no-power",         - (MASK_POWER | MASK_POWER2)},          \
+  {"no-power",         - (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE)}, \
   {"powerpc",          MASK_POWERPC},                          \
   {"no-powerpc",       - (MASK_POWERPC | MASK_PPC_GPOPT        \
                           | MASK_PPC_GFXOPT | MASK_POWERPC64)}, \
@@ -203,8 +205,8 @@ extern int target_flags;
   {"minimal-toc",      MASK_MINIMAL_TOC},                      \
   {"minimal-toc",      - (MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC)}, \
   {"no-minimal-toc",   - MASK_MINIMAL_TOC},                    \
-  {"fp-regs",          - MASK_NO_FPR},                         \
-  {"no-fp-regs",       MASK_NO_FPR},                           \
+  {"hard-float",       - MASK_SOFT_FLOAT},                     \
+  {"soft-float",       MASK_SOFT_FLOAT},                       \
   {"multiple",         MASK_MULTIPLE},                         \
   {"no-multiple",      - MASK_MULTIPLE},                       \
   SUBTARGET_SWITCHES                                           \
@@ -615,8 +617,8 @@ do {                                \
 {                                      \
   if (! TARGET_POWER)                  \
     fixed_regs[64] = 1;                        \
-  if (TARGET_NO_FPR)                   \
-    for (i = 32; i < 64; i++)                  \
+  if (TARGET_SOFT_FLOAT)               \
+    for (i = 32; i < 64; i++)          \
       fixed_regs[i] = call_used_regs[i] = 1; \
 }
 
@@ -896,17 +898,17 @@ enum reg_class { NO_REGS, BASE_REGS, GENERAL_REGS, FLOAT_REGS,
    otherwise, FUNC is 0.
 
    On RS/6000 an integer value is in r3 and a floating-point value is in 
-   fp1.  */
+   fp1, unless -msoft-float.  */
 
 #define FUNCTION_VALUE(VALTYPE, FUNC)  \
   gen_rtx (REG, TYPE_MODE (VALTYPE),   \
-          TREE_CODE (VALTYPE) == REAL_TYPE ? 33 : 3)
+          TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT ? 33 : 3)
 
 /* Define how to find the value returned by a library function
    assuming the value has mode MODE.  */
 
 #define LIBCALL_VALUE(MODE)            \
-  gen_rtx (REG, MODE, GET_MODE_CLASS (MODE) == MODE_FLOAT ? 33 : 3)
+  gen_rtx (REG, MODE, GET_MODE_CLASS (MODE) == MODE_FLOAT && TARGET_HARD_FLOAT ? 33 : 3)
 
 /* The definition of this macro implies that there are cases where
    a scalar value cannot be returned in registers.
@@ -989,7 +991,7 @@ struct rs6000_args {int words, fregno, nargs_prototype; };
 
 /* Non-zero if we can use a floating-point register to pass this arg.  */
 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE)        \
-  (GET_MODE_CLASS (MODE) == MODE_FLOAT && (CUM).fregno < 46)
+  (GET_MODE_CLASS (MODE) == MODE_FLOAT && (CUM).fregno < 46 && TARGET_HARD_FLOAT)
 
 /* Determine where to put an argument to a function.
    Value is zero to push the argument on the stack,
@@ -1361,6 +1363,7 @@ struct rs6000_args {int words, fregno, nargs_prototype; };
   if (LEGITIMATE_OFFSET_ADDRESS_P (MODE, X))           \
     goto ADDR;                                         \
   if ((MODE) != DImode && (MODE) != TImode             \
+      && (TARGET_HARD_FLOAT || (MODE) != DFmode)       \
       && LEGITIMATE_INDEXED_ADDRESS_P (X))             \
     goto ADDR;                                         \
 }
@@ -1465,7 +1468,7 @@ struct rs6000_args {int words, fregno, nargs_prototype; };
 
 /* Max number of bytes we can move from memory to memory
    in one reasonably fast instruction.  */
-#define MOVE_MAX (TARGET_POWER ? 16 : (TARGET_POWERPC64 ? 8 : 4))
+#define MOVE_MAX (TARGET_MULTIPLE ? 16 : (TARGET_POWERPC64 ? 8 : 4))
 #define MAX_MOVE_MAX 16
 
 /* Nonzero if access to memory by bytes is no faster than for words.
index ee1f2c7..13de97b 100644 (file)
 (define_insn "extendsfdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
        (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f")))]
-  ""
+  "TARGET_HARD_FLOAT"
   "*
 {
   if (REGNO (operands[0]) == REGNO (operands[1]))
 (define_insn "truncdfsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  ""
+  "TARGET_HARD_FLOAT"
   "frsp %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "negsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
-  ""
+  "TARGET_HARD_FLOAT"
   "fneg %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "abssf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
-  ""
+  "TARGET_HARD_FLOAT"
   "fabs %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (neg:SF (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f"))))]
-  ""
+  "TARGET_HARD_FLOAT"
   "fnabs %0,%1"
   [(set_attr "type" "fp")])
 
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
        (plus:SF (match_operand:SF 1 "gpc_reg_operand" "")
                 (match_operand:SF 2 "gpc_reg_operand" "")))]
-  ""
+  "TARGET_HARD_FLOAT"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
                 (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT"
   "fadds %0,%1,%2"
   [(set_attr "type" "fp")])
 
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
                 (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT"
   "{fa|fadd} %0,%1,%2"
   [(set_attr "type" "fp")])
 
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
        (minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
                  (match_operand:SF 2 "gpc_reg_operand" "")))]
-  ""
+  "TARGET_HARD_FLOAT"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
                  (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT"
   "fsubs %0,%1,%2"
   [(set_attr "type" "fp")])
 
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
                  (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT"
   "{fs|fsub} %0,%1,%2"
   [(set_attr "type" "fp")])
 
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
        (mult:SF (match_operand:SF 1 "gpc_reg_operand" "")
                 (match_operand:SF 2 "gpc_reg_operand" "")))]
-  ""
+  "TARGET_HARD_FLOAT"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
                 (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT"
   "fmuls %0,%1,%2"
   [(set_attr "type" "fp")])
 
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
                 (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT"
   "{fm|fmul} %0,%1,%2"
   [(set_attr "type" "fp")])
 
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
        (div:SF (match_operand:SF 1 "gpc_reg_operand" "")
                (match_operand:SF 2 "gpc_reg_operand" "")))]
-  ""
+  "TARGET_HARD_FLOAT"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
                (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT"
   "fdivs %0,%1,%2"
   [(set_attr "type" "sdiv")])
 
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
                (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT"
   "{fd|fdiv} %0,%1,%2"
   [(set_attr "type" "sdiv")])
 
        (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
                          (match_operand:SF 2 "gpc_reg_operand" "f"))
                 (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT"
   "fmadds %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
        (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
                          (match_operand:SF 2 "gpc_reg_operand" "f"))
                 (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT"
   "{fma|fmadd} %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
        (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
                           (match_operand:SF 2 "gpc_reg_operand" "f"))
                  (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT"
   "fmsubs %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
        (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
                           (match_operand:SF 2 "gpc_reg_operand" "f"))
                  (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "! TARGET_POWERPC"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT"
   "{fms|fmsub} %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
        (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
                                  (match_operand:SF 2 "gpc_reg_operand" "f"))
                         (match_operand:SF 3 "gpc_reg_operand" "f"))))]
-  "TARGET_POWERPC"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT"
   "fnmadds %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
        (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
                                  (match_operand:SF 2 "gpc_reg_operand" "f"))
                         (match_operand:SF 3 "gpc_reg_operand" "f"))))]
-  "! TARGET_POWERPC"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT"
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
        (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
                                   (match_operand:SF 2 "gpc_reg_operand" "f"))
                          (match_operand:SF 3 "gpc_reg_operand" "f"))))]
-  "TARGET_POWERPC"
+  "TARGET_POWERPC && TARGET_HARD_FLOAT"
   "fnmsubs %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
        (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
                                   (match_operand:SF 2 "gpc_reg_operand" "f"))
                          (match_operand:SF 3 "gpc_reg_operand" "f"))))]
-  "! TARGET_POWERPC"
+  "! TARGET_POWERPC && TARGET_HARD_FLOAT"
   "{fnms|fnmsub} %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
 (define_expand "sqrtsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
        (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
-  "TARGET_PPC_GPOPT || TARGET_POWER2"
+  "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT"
   "")
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
-  "TARGET_PPC_GPOPT"
+  "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT"
   "fsqrts %0,%1"
   [(set_attr "type" "ssqrt")])
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
-  "TARGET_POWER2"
+  "TARGET_POWER2 && TARGET_HARD_FLOAT"
   "fsqrt %0,%1"
   [(set_attr "type" "dsqrt")])
 
                             (const_int 0))
                         (match_dup 1)
                         (match_dup 2)))]
-  "TARGET_PPC_GFXOPT"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
   "
 { operands[3] = gen_reg_rtx (SFmode); }")
 
        (smax:SF (match_operand:SF 1 "gpc_reg_operand" "")
                 (match_operand:SF 2 "gpc_reg_operand" "")))
    (clobber (match_operand:SF 3 "gpc_reg_operand" ""))]
-  "TARGET_PPC_GFXOPT"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
   [(set (match_dup 3)
        (minus:SF (match_dup 1) (match_dup 2)))
    (set (match_dup 0)
                             (const_int 0))
                         (match_dup 1)
                         (match_dup 2)))]
-  "TARGET_PPC_GFXOPT"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
   "
 { operands[3] = gen_reg_rtx (SFmode); }")
 
        (smin:SF (match_operand:SF 1 "gpc_reg_operand" "")
                 (match_operand:SF 2 "gpc_reg_operand" "")))
    (clobber (match_operand:SF 3 "gpc_reg_operand" ""))]
-  "TARGET_PPC_GFXOPT"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
   [(set (match_dup 3)
        (minus:SF (match_dup 2) (match_dup 1)))
    (set (match_dup 0)
         (if_then_else:SF (match_operand 1 "comparison_operator" "")
                          (match_operand:SF 2 "gpc_reg_operand" "f")
                          (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_PPC_GFXOPT"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
   "
 {
   rtx temp, op0, op1;
                             (const_int 0))
                         (match_operand:SF 2 "gpc_reg_operand" "f")
                         (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_PPC_GFXOPT"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
   "fsel %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 
                             (const_int 0))
                         (match_operand:SF 2 "gpc_reg_operand" "f")
                         (match_operand:SF 3 "gpc_reg_operand" "f")))]
-  "TARGET_PPC_GFXOPT"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
   "fsel %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 (define_insn "negdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
        (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  ""
+  "TARGET_HARD_FLOAT"
   "fneg %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "absdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
        (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  ""
+  "TARGET_HARD_FLOAT"
   "fabs %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn ""
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
        (neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f"))))]
-  ""
+  "TARGET_HARD_FLOAT"
   "fnabs %0,%1"
   [(set_attr "type" "fp")])
 
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
        (plus:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
                 (match_operand:DF 2 "gpc_reg_operand" "f")))]
-  ""
+  "TARGET_HARD_FLOAT"
   "{fa|fadd} %0,%1,%2"
   [(set_attr "type" "fp")])
 
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
        (minus:DF (match_operand:DF 1 "gpc_reg_operand" "f")
                  (match_operand:DF 2 "gpc_reg_operand" "f")))]
-  ""
+  "TARGET_HARD_FLOAT"
   "{fs|fsub} %0,%1,%2"
   [(set_attr "type" "fp")])
 
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
        (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
                 (match_operand:DF 2 "gpc_reg_operand" "f")))]
-  ""
+  "TARGET_HARD_FLOAT"
   "{fm|fmul} %0,%1,%2"
   [(set_attr "type" "dmul")])
 
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
        (div:DF (match_operand:DF 1 "gpc_reg_operand" "f")
                (match_operand:DF 2 "gpc_reg_operand" "f")))]
-  ""
+  "TARGET_HARD_FLOAT"
   "{fd|fdiv} %0,%1,%2"
   [(set_attr "type" "ddiv")])
 
        (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
                          (match_operand:DF 2 "gpc_reg_operand" "f"))
                 (match_operand:DF 3 "gpc_reg_operand" "f")))]
-  ""
+  "TARGET_HARD_FLOAT"
   "{fma|fmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
        (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
                           (match_operand:DF 2 "gpc_reg_operand" "f"))
                  (match_operand:DF 3 "gpc_reg_operand" "f")))]
-  ""
+  "TARGET_HARD_FLOAT"
   "{fms|fmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
        (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
                                  (match_operand:DF 2 "gpc_reg_operand" "f"))
                         (match_operand:DF 3 "gpc_reg_operand" "f"))))]
-  ""
+  "TARGET_HARD_FLOAT"
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
        (neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
                                   (match_operand:DF 2 "gpc_reg_operand" "f"))
                          (match_operand:DF 3 "gpc_reg_operand" "f"))))]
-  ""
+  "TARGET_HARD_FLOAT"
   "{fnms|fnmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
 (define_insn "sqrtdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
        (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  "TARGET_PPC_GPOPT || TARGET_POWER2"
+  "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT"
   "fsqrt %0,%1"
   [(set_attr "type" "dsqrt")])
 
                             (const_int 0))
                         (match_dup 1)
                         (match_dup 2)))]
-  "TARGET_PPC_GFXOPT"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
   "
 { operands[3] = gen_reg_rtx (DFmode); }")
 
        (smax:DF (match_operand:DF 1 "gpc_reg_operand" "")
                 (match_operand:DF 2 "gpc_reg_operand" "")))
    (clobber (match_operand:DF 3 "gpc_reg_operand" ""))]
-  "TARGET_PPC_GFXOPT"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
   [(set (match_dup 3)
        (minus:DF (match_dup 1) (match_dup 2)))
    (set (match_dup 0)
                             (const_int 0))
                         (match_dup 1)
                         (match_dup 2)))]
-  "TARGET_PPC_GFXOPT"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
   "
 { operands[3] = gen_reg_rtx (DFmode); }")
 
        (smin:DF (match_operand:DF 1 "gpc_reg_operand" "")
                 (match_operand:DF 2 "gpc_reg_operand" "")))
    (clobber (match_operand:DF 3 "gpc_reg_operand" ""))]
-  "TARGET_PPC_GFXOPT"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
   [(set (match_dup 3)
        (minus:DF (match_dup 2) (match_dup 1)))
    (set (match_dup 0)
         (if_then_else:DF (match_operand 1 "comparison_operator" "")
                          (match_operand:DF 2 "gpc_reg_operand" "f")
                          (match_operand:DF 3 "gpc_reg_operand" "f")))]
-  "TARGET_PPC_GFXOPT"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
   "
 {
   rtx temp, op0, op1;
                             (const_int 0))
                         (match_operand:DF 2 "gpc_reg_operand" "f")
                         (match_operand:DF 3 "gpc_reg_operand" "f")))]
-  "TARGET_PPC_GFXOPT"
+  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
   "fsel %0,%1,%2,%3"
   [(set_attr "type" "fp")])
 (define_insn "fselsfdf4"
    (set (match_operand:DF 0 "gpc_reg_operand" "")
        (minus:DF (subreg:DF (match_dup 2) 0)
                  (match_dup 5)))]
-  "! TARGET_POWERPC64 && HOST_BITS_PER_INT == BITS_PER_WORD"
+  "! TARGET_POWERPC64 && (HOST_BITS_PER_INT == BITS_PER_WORD) && TARGET_HARD_FLOAT"
   "
 {
   operands[2] = gen_reg_rtx (DImode);
    (set (match_operand:DF 0 "gpc_reg_operand" "")
        (minus:DF (subreg:DF (match_dup 2) 0)
                  (match_dup 4)))]
-  "! TARGET_POWERPC64 && HOST_BITS_PER_INT == BITS_PER_WORD"
+  "! TARGET_POWERPC64 && (HOST_BITS_PER_INT == BITS_PER_WORD) && TARGET_HARD_FLOAT"
   "
 {
   operands[2] = gen_reg_rtx (DImode);
 (define_expand "fix_truncdfsi2"
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
        (fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
-  ""
+  "TARGET_HARD_FLOAT"
   "
 {
   if (TARGET_POWER2 || TARGET_POWERPC)
   [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
        (sign_extend:DI
         (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))))]
-  "TARGET_POWER2 || TARGET_POWERPC"
+  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
   "{fcirz|fctiwz} %0,%1"
   [(set_attr "type" "fp")])
 
 (define_expand "fixuns_truncdfsi2"
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
        (unsigned_fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
-  "! TARGET_POWER2 && ! TARGET_POWERPC"
+  "! TARGET_POWER2 && ! TARGET_POWERPC && TARGET_HARD_FLOAT"
   "
 {
   emit_insn (gen_trunc_call (operands[0], operands[1],
   [(parallel [(set (match_operand:SI 0 "" "")
                   (fix:SI (match_operand:DF 1 "" "")))
              (use (match_operand:SI 2 "" ""))])]
-  ""
+  "TARGET_HARD_FLOAT"
   "
 {
   rtx insns = gen_trunc_call_rtl (operands[0], operands[1], operands[2]);
              (clobber (scratch:SI))])
    (set (match_operand:SI 0 "gpc_reg_operand" "")
        (reg:SI 3))]
-  ""
+  "TARGET_HARD_FLOAT"
   "
 { 
   rs6000_trunc_used = 1;
 (define_insn "floatdidf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
        (float:DF (match_operand:DI 1 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC64"
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT"
   "fcfid %0,%1"
   [(set_attr "type" "fp")])
 
 (define_insn "fix_truncdfdi2"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
        (fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))]
-  "TARGET_POWERPC64"
+  "TARGET_POWERPC64 && TARGET_HARD_FLOAT"
   "fctidz %0,%1"
   [(set_attr "type" "fp")])
 \f
 (define_insn ""
   [(set (match_operand:SF 0 "fp_reg_or_mem_operand" "=f,f,m")
        (match_operand:SF 1 "input_operand" "f,m,f"))]
-  "gpc_reg_operand (operands[0], SFmode)
-   || gpc_reg_operand (operands[1], SFmode)"
+  "(gpc_reg_operand (operands[0], SFmode)
+   || gpc_reg_operand (operands[1], SFmode)) && TARGET_HARD_FLOAT"
   "@
    fmr %0,%1
    lfs%U1%X1 %0,%1
    stfs%U0%X0 %1,%0"
   [(set_attr "type" "fp,fpload,*")])
+
+(define_insn ""
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,r,r,r")
+       (match_operand:SF 1 "input_operand" "r,m,r,I,J,R"))]
+  "(gpc_reg_operand (operands[0], SFmode)
+   || gpc_reg_operand (operands[1], SFmode)) && TARGET_SOFT_FLOAT"
+  "@
+   mr %0,%1
+   {l%U1%X1|lwz%U1%X1} %0,%1
+   {st%U0%X0|stw%U0%X0} %1,%0
+   {lil|li} %0,%1
+   {liu|lis} %0,%u1
+   {cal|la} %0,%1(%*)"
+  [(set_attr "type" "*,load,*,*,*,*")])
+
 \f
 (define_expand "movdf"
   [(set (match_operand:DF 0 "nonimmediate_operand" "")
   [(parallel [(set (match_operand:TI 0 "general_operand" "")
                   (match_operand:TI 1 "general_operand" ""))
              (clobber (scratch:SI))])]
-  "TARGET_POWER || TARGET_POWERPC64"
+  "TARGET_MULTIPLE || TARGET_POWERPC64"
   "
 {
   if (GET_CODE (operands[0]) == MEM)
   [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r")
        (match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))
    (clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))]
-  "TARGET_POWER && ! TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
+  "TARGET_MULTIPLE && ! TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
    || gpc_reg_operand (operands[1], TImode))"
   "*
 {
                   [(set (match_operand:SI 1 "indirect_operand" "=Q")
                         (match_operand:SI 2 "gpc_reg_operand" "r"))
                    (clobber (match_scratch:SI 3 "=q"))])]
-  "TARGET_POWER"
+  "TARGET_MULTIPLE && !TARGET_POWERPC"
+  "{stsi|stswi} %2,%P1,%O0")
+
+(define_insn ""
+  [(match_parallel 0 "store_multiple_operation"
+                  [(set (match_operand:SI 1 "indirect_operand" "=Q")
+                        (match_operand:SI 2 "gpc_reg_operand" "r"))
+                   (clobber (match_scratch:SI 3 "X"))])]
+  "TARGET_MULTIPLE && TARGET_POWERPC"
   "{stsi|stswi} %2,%P1,%O0")
 \f
 ;; Define insns that do load or store with update.  Some of these we can 
                         (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
        (plus:SI (match_dup 1) (match_dup 2)))]
-  ""
+  "TARGET_HARD_FLOAT"
   "@
    lfsux %3,%0,%2
    lfsu %3,%2(%0)"
        (match_operand:SF 3 "gpc_reg_operand" "f,f"))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
        (plus:SI (match_dup 1) (match_dup 2)))]
-  ""
+  "TARGET_HARD_FLOAT"
   "@
    stfsux %3,%0,%2
    stfsu %3,%2(%0)")
                         (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
        (plus:SI (match_dup 1) (match_dup 2)))]
-  ""
+  "TARGET_HARD_FLOAT"
   "@
    lfdux %3,%0,%2
    lfdu %3,%2(%0)"
        (match_operand:DF 3 "gpc_reg_operand" "f,f"))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
        (plus:SI (match_dup 1) (match_dup 2)))]
-  ""
+  "TARGET_HARD_FLOAT"
   "@
    stfdux %3,%0,%2
    stfdu %3,%2(%0)")
    (set (match_operand:DF 2 "gpc_reg_operand" "=f")
        (match_operand:DF 3 "memory_operand" ""))]
   "TARGET_POWER2
+   && TARGET_HARD_FLOAT
    && registers_ok_for_quad_peep (operands[0], operands[2])
    && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
    && addrs_ok_for_quad_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
    (set (match_operand:DF 2 "memory_operand" "")
        (match_operand:DF 3 "gpc_reg_operand" "f"))]
   "TARGET_POWER2
+   && TARGET_HARD_FLOAT
    && registers_ok_for_quad_peep (operands[1], operands[3])
    && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
    && addrs_ok_for_quad_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
 (define_expand "cmpsf"
   [(set (cc0) (compare (match_operand:SF 0 "gpc_reg_operand" "")
                       (match_operand:SF 1 "gpc_reg_operand" "")))]
-  ""
+  "TARGET_HARD_FLOAT"
   "
 {
   rs6000_compare_op0 = operands[0];
 (define_expand "cmpdf"
   [(set (cc0) (compare (match_operand:DF 0 "gpc_reg_operand" "")
                       (match_operand:DF 1 "gpc_reg_operand" "")))]
-  ""
+  "TARGET_HARD_FLOAT"
   "
 {
   rs6000_compare_op0 = operands[0];
   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
        (compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "f")
                      (match_operand:SF 2 "gpc_reg_operand" "f")))]
-  ""
+  "TARGET_HARD_FLOAT"
   "fcmpu %0,%1,%2"
   [(set_attr "type" "fpcompare")])
 
   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
        (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "f")
                      (match_operand:DF 2 "gpc_reg_operand" "f")))]
-  ""
+  "TARGET_HARD_FLOAT"
   "fcmpu %0,%1,%2"
   [(set_attr "type" "fpcompare")])
 \f
index f0c1363..e2ff344 100644 (file)
@@ -18,6 +18,27 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
+/* eABI local switches -- put here rather than eabi.h, so the switches
+   can be tested in macros.  */
+
+#define        MASK_NO_BITFIELD_TYPE   0x40000000      /* Set PCC_BITFIELD_TYPE_MATTERS to 0 */
+#define        MASK_STRICT_ALIGN       0x20000000      /* Set STRICT_ALIGNMENT to 1.  */
+#define MASK_RELOCATABLE       0x10000000      /* GOT pointers are PC relative */
+
+#define        TARGET_NO_BITFIELD_TYPE (target_flags & MASK_NO_BITFIELD_TYPE)
+#define        TARGET_BITFIELD_TYPE    (! TARGET_NO_BITFIELD_TYPE)
+#define TARGET_STRICT_ALIGN    (target_flags & MASK_STRICT_ALIGN)
+#define TARGET_RELOCATABLE     (target_flags & MASK_RELOCATABLE)
+
+#undef SUBTARGET_SWITCHES
+#define SUBTARGET_SWITCHES                                             \
+  { "bit-align",       -MASK_NO_BITFIELD_TYPE },                       \
+  { "no-bit-align",     MASK_NO_BITFIELD_TYPE },                       \
+  { "strict-align",     MASK_STRICT_ALIGN },                           \
+  { "no-strict-align", -MASK_STRICT_ALIGN },                           \
+  { "relocatable",      MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC }, \
+  { "no-relocatable",  -MASK_RELOCATABLE },
+
 #include "rs6000/powerpc.h"
 
 /* Don't generate XCOFF debugging information.  */
@@ -106,33 +127,46 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 void                                                                   \
 toc_section ()                                                         \
 {                                                                      \
-  if (TARGET_MINIMAL_TOC)                                              \
-    {                                                                  \
-      static int toc_initialized = 0;                                  \
+  static int toc_initialized = 0;                                      \
                                                                        \
+  if (in_section != in_toc)                                            \
+    {                                                                  \
       if (! toc_initialized)                                           \
        {                                                               \
-         fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);           \
-         fprintf (asm_out_file, ".LCTOC0:\n");                         \
-         fprintf (asm_out_file, "\t.tc .LCTOC1\n");                    \
-         fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);   \
-         fprintf (asm_out_file, ".LCTOC1:\n");                         \
+         if (!TARGET_RELOCATABLE)                                      \
+           fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);         \
+                                                                       \
+         if (TARGET_MINIMAL_TOC)                                       \
+           {                                                           \
+             if (!TARGET_RELOCATABLE)                                  \
+               {                                                       \
+                 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LCTOC", 0); \
+                 fprintf (asm_out_file, "\t.tc ");                     \
+                 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],"); \
+                 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1"); \
+                 fprintf (asm_out_file, "\n");                         \
+               }                                                       \
+                                                                       \
+             fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); \
+             ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1"); \
+             fprintf (asm_out_file, " = .+32768\n");                   \
+           }                                                           \
+                                                                       \
          toc_initialized = 1;                                          \
        }                                                               \
-    }                                                                  \
                                                                        \
-  if (in_section != in_toc)                                            \
-    {                                                                  \
-      fprintf (asm_out_file, "%s\n",                                   \
-              (TARGET_MINIMAL_TOC                                      \
-               ? MINIMAL_TOC_SECTION_ASM_OP                            \
-               : TOC_SECTION_ASM_OP));                                 \
+      else                                                             \
+       fprintf (asm_out_file, "%s\n",                                  \
+                (TARGET_MINIMAL_TOC                                    \
+                 ? MINIMAL_TOC_SECTION_ASM_OP                          \
+                 : TOC_SECTION_ASM_OP));                               \
+                                                                       \
       in_section = in_toc;                                             \
     }                                                                  \
 }
 
-#define TOC_SECTION_ASM_OP "\t.section\t.got,\"aw\""
-#define MINIMAL_TOC_SECTION_ASM_OP "\t.section\t.got1,\"aw\""
+#define TOC_SECTION_ASM_OP "\t.section\t\".got\",\"aw\""
+#define MINIMAL_TOC_SECTION_ASM_OP "\t.section\t\".got1\",\"aw\""
 
 /* Use the TOC section for TOC entries.  */
 
index 1490b39..4c659a6 100644 (file)
@@ -1,3 +1,22 @@
 # 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 the libraries for both hard and soft floating point
+
+MULTILIB_OPTIONS = msoft-float
+MULTILIB_DIRNAMES = soft-float
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib