aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Edelsohn <edelsohn@gnu.org>2001-11-20 16:13:07 +0000
committerDavid Edelsohn <dje@gcc.gnu.org>2001-11-20 11:13:07 -0500
commit06f4e019e245e05883b43893b9c15d75ab72a303 (patch)
treeee2cc1d937887e46e2754ea726b21c7af59ce925
parentca34930415ad53674071f3d0280d775ea6d57ef0 (diff)
downloadgcc-06f4e019e245e05883b43893b9c15d75ab72a303.zip
gcc-06f4e019e245e05883b43893b9c15d75ab72a303.tar.gz
gcc-06f4e019e245e05883b43893b9c15d75ab72a303.tar.bz2
rs6000.c (rs6000_emit_eh_toc_restore): Remove ALIGN parm.
* rs6000.c (rs6000_emit_eh_toc_restore): Remove ALIGN parm. * rs6000.c (rs6000_emit_move): Add TFmode case. * sysv4.h (MASK_LONG_DOUBLE_128, TARGET_LONG_DOUBLE_128, LONG_DOUBLE_TYPE_SIZE, MAX_LONG_DOUBLE_TYPE_SIZE, LIBGCC2_LONG_DOUBLE_TYPE_SIZE): Move from here... * rs6000.h: ... to here. * rs6000.md (movtf, extenddftf2, extendsftf2, trunctfdf2, trunctfsf2, floatditf2, floatsitf2, fix_trunctfdi2, fix_trunctfsi2, negtf2, abstf2, nabstf2): New patterns. From-SVN: r47218
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/config/rs6000/rs6000.c5
-rw-r--r--gcc/config/rs6000/rs6000.h21
-rw-r--r--gcc/config/rs6000/rs6000.md177
-rw-r--r--gcc/config/rs6000/sysv4.h24
5 files changed, 214 insertions, 26 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f5325dc..96e0126 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2001-11-20 David Edelsohn <edelsohn@gnu.org>
+
+ * rs6000.c (rs6000_emit_eh_toc_restore): Remove ALIGN parm.
+
+ * rs6000.c (rs6000_emit_move): Add TFmode case.
+ * sysv4.h (MASK_LONG_DOUBLE_128, TARGET_LONG_DOUBLE_128,
+ LONG_DOUBLE_TYPE_SIZE, MAX_LONG_DOUBLE_TYPE_SIZE,
+ LIBGCC2_LONG_DOUBLE_TYPE_SIZE): Move from here...
+ * rs6000.h: ... to here.
+ * rs6000.md (movtf, extenddftf2, extendsftf2, trunctfdf2,
+ trunctfsf2, floatditf2, floatsitf2, fix_trunctfdi2,
+ fix_trunctfsi2, negtf2, abstf2, nabstf2): New patterns.
+
Tue Nov 20 06:41:38 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* emit-rtl.c (get_mem_attrs): Fix typo.
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 186692d..d9b3e09 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1935,6 +1935,7 @@ rs6000_emit_move (dest, source, mode)
operands[1] = force_const_mem (mode, operands[1]);
break;
+ case TFmode:
case DFmode:
case SFmode:
if (CONSTANT_P (operands[1])
@@ -6594,7 +6595,7 @@ rs6000_emit_eh_toc_restore (stacksize)
emit_label (loop_start);
do_compare_rtx_and_jump (opcode, tocompare, NE, 1,
- SImode, NULL_RTX, 0, NULL_RTX,
+ SImode, NULL_RTX, NULL_RTX,
no_toc_restore_needed);
mem = gen_rtx_MEM (Pmode,
@@ -6604,7 +6605,7 @@ rs6000_emit_eh_toc_restore (stacksize)
emit_label (no_toc_restore_needed);
do_compare_rtx_and_jump (top_of_stack, bottom_of_stack, EQ, 1,
- Pmode, NULL_RTX, 0, NULL_RTX,
+ Pmode, NULL_RTX, NULL_RTX,
loop_exit);
mem = gen_rtx_MEM (Pmode, bottom_of_stack);
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 238cedc..94aa09e 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -217,6 +217,9 @@ extern int target_flags;
/* Enhance the current ABI with AltiVec extensions. */
#define MASK_ALTIVEC_ABI 0x00100000
+/* Use 128-bit long double. */
+#define MASK_LONG_DOUBLE_128 0x00200000
+
#define TARGET_POWER (target_flags & MASK_POWER)
#define TARGET_POWER2 (target_flags & MASK_POWER2)
#define TARGET_POWERPC (target_flags & MASK_POWERPC)
@@ -237,6 +240,7 @@ extern int target_flags;
#define TARGET_SCHED_PROLOG (target_flags & MASK_SCHED_PROLOG)
#define TARGET_ALTIVEC (target_flags & MASK_ALTIVEC)
#define TARGET_ALTIVEC_ABI (target_flags & MASK_ALTIVEC_ABI)
+#define TARGET_LONG_DOUBLE_128 (target_flags & MASK_LONG_DOUBLE_128)
#define TARGET_32BIT (! TARGET_64BIT)
#define TARGET_HARD_FLOAT (! TARGET_SOFT_FLOAT)
@@ -341,6 +345,10 @@ extern int target_flags;
N_("Generate fused multiply/add instructions")},\
{"no-fused-madd", MASK_NO_FUSED_MADD, \
N_("Don't generate fused multiply/add instructions")},\
+ {"long-double-64", -MASK_LONG_DOUBLE_128, \
+ N_("Use 64 bit long doubles") }, \
+ {"long-double-128", MASK_LONG_DOUBLE_128, \
+ N_("Use 128 bit long doubles") }, \
{"sched-prolog", MASK_SCHED_PROLOG, \
""}, \
{"no-sched-prolog", -MASK_SCHED_PROLOG, \
@@ -576,7 +584,18 @@ extern int rs6000_debug_arg; /* debug argument handling */
/* A C expression for the size in bits of the type `long double' on
the target machine. If you don't define this, the default is two
words. */
-#define LONG_DOUBLE_TYPE_SIZE 64
+#define LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_128 ? 128 : 64)
+
+/* Constant which presents upper bound of the above value. */
+#define MAX_LONG_DOUBLE_TYPE_SIZE 128
+
+/* Define this to set long double type size to use in libgcc2.c, which can
+ not depend on target_flags. */
+#ifdef __LONG_DOUBLE_128__
+#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 128
+#else
+#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
+#endif
/* Width in bits of a pointer.
See also the macro `Pmode' defined below. */
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 6b8dda7..0292c57 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -7906,6 +7906,183 @@
[(set_attr "type" "*,load,store,*,*,*")
(set_attr "length" "*,*,*,8,12,16")])
+(define_expand "movtf"
+ [(set (match_operand:TF 0 "general_operand" "")
+ (match_operand:TF 1 "any_operand" ""))]
+ "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+ "{ rs6000_emit_move (operands[0], operands[1], TFmode); DONE; }")
+
+(define_insn "*movtf_internal"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=f,f,m,!r,!r,!r")
+ (match_operand:TF 1 "input_operand" "f,m,f,G,H,F"))]
+ "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128
+ && (gpc_reg_operand (operands[0], TFmode)
+ || gpc_reg_operand (operands[1], TFmode))"
+ "*
+{
+ switch (which_alternative)
+ {
+ default:
+ abort ();
+ case 0:
+ /* We normally copy the low-numbered register first. However, if
+ the first register operand 0 is the same as the second register of
+ operand 1, we must copy in the opposite order. */
+ if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
+ return \"fmr %L0,%L1\;fmr %0,%1\";
+ else
+ return \"fmr %0,%1\;fmr %L0,%L1\";
+ case 1:
+ return \"lfd %0,%1\;lfd %L0,%L1\";
+ case 2:
+ return \"stfd %1,%0\;stfd %L1,%L0\";
+ case 3:
+ case 4:
+ case 5:
+ return \"#\";
+ }
+}"
+ [(set_attr "type" "fp,fpload,fpstore,*,*,*")
+ (set_attr "length" "8,8,8,12,16,20")])
+
+(define_split
+ [(set (match_operand:TF 0 "gpc_reg_operand" "")
+ (match_operand:TF 1 "const_double_operand" ""))]
+ "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+ [(set (match_dup 3) (match_dup 1))
+ (set (match_dup 0)
+ (float_extend:TF (match_dup 3)))]
+ "
+{
+ operands[2] = operand_subword (operands[1], 0, 0, DFmode);
+ operands[3] = gen_reg_rtx (DFmode);
+}")
+
+(define_insn_and_split "extenddftf2"
+ [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
+ (float_extend:TF (match_operand:DF 1 "gpc_reg_operand" "f")))]
+ "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+ "#"
+ ""
+ [(set (match_dup 2) (match_dup 3))]
+ "
+{
+ operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0] + 1));
+ operands[3] = CONST0_RTX (DFmode);
+}")
+
+(define_insn_and_split "extendsftf2"
+ [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
+ (float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "f")))]
+ "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+ "#"
+ ""
+ [(set (match_dup 2) (match_dup 3))]
+ "
+{
+ operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0] + 1));
+ operands[3] = CONST0_RTX (SFmode);
+}")
+
+(define_insn "trunctfdf2"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
+ (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "f")))]
+ "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+ "fadd %0,%1,%L1"
+ [(set_attr "type" "fp")
+ (set_attr "length" "8")])
+
+(define_insn_and_split "trunctfsf2"
+ [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+ (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "f")))]
+ "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+ "#"
+ ""
+ [(set (match_dup 2)
+ (float_truncate:DF (match_dup 1)))
+ (set (match_dup 0)
+ (float_truncate:SF (match_dup 2)))]
+ "
+{
+ operands[2] = gen_reg_rtx (DFmode);
+}")
+
+(define_expand "floatditf2"
+ [(set (match_dup 2)
+ (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))
+ (set (match_operand:TF 0 "gpc_reg_operand" "")
+ (float_extend:TF (match_dup 2)))]
+ "DEFAULT_ABI == ABI_AIX && TARGET_POWERPC64
+ && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+ "{ operands[2] = gen_reg_rtx (DFmode); }")
+
+(define_expand "floatsitf2"
+ [(set (match_dup 2)
+ (float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
+ (set (match_operand:TF 0 "gpc_reg_operand" "")
+ (float_extend:TF (match_dup 2)))]
+ "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+ "{ operands[2] = gen_reg_rtx (DFmode); }")
+
+(define_expand "fix_trunctfdi2"
+ [(set (match_dup 2)
+ (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))
+ (set (match_operand:DI 0 "gpc_reg_operand" "")
+ (fix:SI (match_dup 2)))]
+ "DEFAULT_ABI == ABI_AIX && TARGET_POWERPC64
+ && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+ "{ operands[2] = gen_reg_rtx (DFmode); }")
+
+(define_expand "fix_trunctfsi2"
+ [(set (match_dup 2)
+ (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))
+ (set (match_operand:SI 0 "gpc_reg_operand" "")
+ (fix:SI (match_dup 2)))]
+ "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+ "{ operands[2] = gen_reg_rtx (DFmode); }")
+
+(define_insn "negtf2"
+ [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
+ (neg:TF (match_operand:TF 1 "gpc_reg_operand" "f")))]
+ "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+ "*
+{
+ if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
+ return \"fneg %L0,%L1\;fneg %0,%1\";
+ else
+ return \"fneg %0,%1\;fneg %L0,%L1\";
+}"
+ [(set_attr "type" "fp")
+ (set_attr "length" "8")])
+
+(define_insn "abstf2"
+ [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
+ (abs:TF (match_operand:TF 1 "gpc_reg_operand" "f")))]
+ "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+ "*
+{
+ if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
+ return \"fabs %L0,%L1\;fabs %0,%1\";
+ else
+ return \"fabs %0,%1\;fabs %L0,%L1\";
+}"
+ [(set_attr "type" "fp")
+ (set_attr "length" "8")])
+
+(define_insn ""
+ [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
+ (neg:TF (abs:TF (match_operand:TF 1 "gpc_reg_operand" "f"))))]
+ "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+ "*
+{
+ if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
+ return \"fnabs %L0,%L1\;fnabs %0,%1\";
+ else
+ return \"fnabs %0,%1\;fnabs %L0,%L1\";
+}"
+ [(set_attr "type" "fp")
+ (set_attr "length" "8")])
+
;; Next come the multi-word integer load and store and the load and store
;; multiple insns.
(define_expand "movdi"
diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
index fcff961..99e4c27 100644
--- a/gcc/config/rs6000/sysv4.h
+++ b/gcc/config/rs6000/sysv4.h
@@ -56,8 +56,7 @@ extern enum rs6000_sdata_type rs6000_sdata;
#define MASK_LITTLE_ENDIAN 0x04000000 /* Target is little endian. */
#define MASK_REGNAMES 0x02000000 /* Use alternate register names. */
#define MASK_PROTOTYPE 0x01000000 /* Only prototyped fcns pass variable args. */
-#define MASK_LONG_DOUBLE_128 0x00800000 /* Use IEEE quad long double. */
-#define MASK_NO_BITFIELD_WORD 0x00400000 /* Bitfields cannot cross word boundaries */
+#define MASK_NO_BITFIELD_WORD 0x00800000 /* Bitfields cannot cross word boundaries */
#define TARGET_NO_BITFIELD_TYPE (target_flags & MASK_NO_BITFIELD_TYPE)
#define TARGET_STRICT_ALIGN (target_flags & MASK_STRICT_ALIGN)
@@ -66,7 +65,6 @@ extern enum rs6000_sdata_type rs6000_sdata;
#define TARGET_LITTLE_ENDIAN (target_flags & MASK_LITTLE_ENDIAN)
#define TARGET_REGNAMES (target_flags & MASK_REGNAMES)
#define TARGET_PROTOTYPE (target_flags & MASK_PROTOTYPE)
-#define TARGET_LONG_DOUBLE_128 (target_flags & MASK_LONG_DOUBLE_128)
#define TARGET_NO_BITFIELD_WORD (target_flags & MASK_NO_BITFIELD_WORD)
#define TARGET_TOC ((target_flags & MASK_64BIT) \
|| ((target_flags & (MASK_RELOCATABLE \
@@ -126,10 +124,6 @@ extern int g_switch_set; /* Whether -G xx was passed. */
N_("Produce big endian code.") }, \
{ "big", -MASK_LITTLE_ENDIAN, \
N_("Produce big endian code.") }, \
- { "long-double-64", -MASK_LONG_DOUBLE_128, \
- N_("Use 64 bit long doubles") }, \
- { "long-double-128", MASK_LONG_DOUBLE_128, \
- N_("Use 128 bit long doubles") }, \
{ "no-toc", 0, N_("no description yet") }, \
{ "toc", MASK_MINIMAL_TOC, N_("no description yet") }, \
{ "full-toc", MASK_MINIMAL_TOC, N_("no description yet") }, \
@@ -366,22 +360,6 @@ do { \
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 32
-/* Define for support of TFmode long double and REAL_ARITHMETIC.
- PowerPC SVR4 ABI says that long double is 4 words. */
-#undef LONG_DOUBLE_TYPE_SIZE
-#define LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_128 ? 128 : 64)
-
-/* Constant which presents upper bound of the above value. */
-#define MAX_LONG_DOUBLE_TYPE_SIZE 128
-
-/* Define this to set long double type size to use in libgcc2.c, which can
- not depend on target_flags. */
-#ifdef __LONG_DOUBLE_128__
-#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 128
-#else
-#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
-#endif
-
/* Make int foo : 8 not cause structures to be aligned to an int boundary. */
/* Override elfos.h definition. */
#undef PCC_BITFIELD_TYPE_MATTERS