+2002-10-07 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_override_options): Set
+ real_format_for_mode for IBM extended format, if enabled.
+ (easy_fp_constant): Add TFmode.
+ (rs6000_legitimize_address): Add TFmode.
+ (rs6000_legitimate_address): Same.
+ (function_arg_advance): TFmode uses two FPRs.
+ (rs6000_emit_prologue): Fix warning.
+ (rs6000_output_function_epilogue): Add TFmode.
+ (output_toc): Add TFmode.
+ * rs6000.h (SLOW_UNALIGNED_ACCESS): Add TFmode.
+ (LEGITIMATE_OFFSET_ADDRESS_P): Add TFmode.
+ * rs6000.md (movtf splitter): Load TFmode constant.
+
2002-10-07 Dale Johannesen <dalej@apple.com>
+
* rtl.h: Add NOTE_PRECONDITIONED.
* unroll.c: Set it.
* loop.c: Set loop_info->preconditioned from it.
target_flags |= MASK_AIX_STRUCT_RET;
}
+ if (TARGET_LONG_DOUBLE_128
+ && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN))
+ real_format_for_mode[TFmode - QFmode] = &ibm_extended_format;
+
/* Register global variables with the garbage collector. */
rs6000_add_gc_roots ();
return 0;
#endif
- if (mode == DFmode)
+ if (mode == TFmode)
+ {
+ long k[4];
+ REAL_VALUE_TYPE rv;
+
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
+ REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
+
+ return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1
+ && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1
+ && num_insns_constant_wide ((HOST_WIDE_INT) k[2]) == 1
+ && num_insns_constant_wide ((HOST_WIDE_INT) k[3]) == 1);
+ }
+
+ else if (mode == DFmode)
{
long k[2];
REAL_VALUE_TYPE rv;
&& GET_MODE_NUNITS (mode) == 1
&& ((TARGET_HARD_FLOAT && TARGET_FPRS)
|| TARGET_POWERPC64
- || mode != DFmode)
+ || (mode != DFmode && mode != TFmode))
&& (TARGET_POWERPC64 || mode != DImode)
&& mode != TImode)
{
if (mode != TImode
&& ((TARGET_HARD_FLOAT && TARGET_FPRS)
|| TARGET_POWERPC64
- || mode != DFmode)
+ || (mode != DFmode && mode != TFmode))
&& (TARGET_POWERPC64 || mode != DImode)
&& LEGITIMATE_INDEXED_ADDRESS_P (x, reg_ok_strict))
return 1;
if (GET_MODE_CLASS (mode) == MODE_FLOAT
&& TARGET_HARD_FLOAT && TARGET_FPRS)
- cum->fregno++;
+ cum->fregno += (mode == TFmode ? 2 : 1);
if (TARGET_DEBUG_ARG)
{
gen_rtx_REG (Pmode, 11));
}
+#if TARGET_MACHO
if (DEFAULT_ABI == ABI_DARWIN
&& flag_pic && current_function_uses_pic_offset_table)
{
rtx dest = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
-#if TARGET_MACHO
char *picbase = machopic_function_base_name ();
rtx src = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (picbase, -1));
rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (dest, src)));
-#endif
rs6000_maybe_dead (
emit_move_insn (gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM),
gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)));
}
+#endif
}
/* Write function prologue. */
if (mode == SFmode)
bits = 0x2;
- else if (mode == DFmode)
+ else if (mode == DFmode || mode == TFmode)
bits = 0x3;
else
abort ();
/* 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
FP constants. */
- if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
+ if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == TFmode)
+ {
+ REAL_VALUE_TYPE rv;
+ long k[4];
+
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
+ REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
+
+ if (TARGET_64BIT)
+ {
+ if (TARGET_MINIMAL_TOC)
+ fputs (DOUBLE_INT_ASM_OP, file);
+ else
+ fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
+ k[0] & 0xffffffff, k[1] & 0xffffffff,
+ k[2] & 0xffffffff, k[3] & 0xffffffff);
+ fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
+ k[0] & 0xffffffff, k[1] & 0xffffffff,
+ k[2] & 0xffffffff, k[3] & 0xffffffff);
+ return;
+ }
+ else
+ {
+ if (TARGET_MINIMAL_TOC)
+ fputs ("\t.long ", file);
+ else
+ fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
+ k[0] & 0xffffffff, k[1] & 0xffffffff,
+ k[2] & 0xffffffff, k[3] & 0xffffffff);
+ fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
+ k[0] & 0xffffffff, k[1] & 0xffffffff,
+ k[2] & 0xffffffff, k[3] & 0xffffffff);
+ return;
+ }
+ }
+ else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
{
REAL_VALUE_TYPE rv;
long k[2];
emulated in a trap handler. */
#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) \
(STRICT_ALIGNMENT \
- || (((MODE) == SFmode || (MODE) == DFmode || (MODE) == DImode) \
+ || (((MODE) == SFmode || (MODE) == DFmode || (MODE) == TFmode \
+ || (MODE) == DImode) \
&& (ALIGN) < 32))
\f
/* Standard register usage. */
|| (TARGET_32BIT \
? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) \
: ! (INTVAL (XEXP (X, 1)) & 3))) \
- && ((MODE) != TImode \
+ && (((MODE) != TFmode && (MODE) != TImode) \
|| (TARGET_32BIT \
? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 12) \
: (LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 8) \
#"
[(set_attr "type" "compare")
(set_attr "length" "4,8")])
-\f
+
(define_split
[(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
(compare:CC
(compare:CC (match_dup 0)
(const_int 0)))]
"")
-
+\f
;; Rotate and shift insns, in all their variants. These support shifts,
;; field inserts and extracts, and various combinations thereof.
(define_expand "insv"
(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_FPRS
- && TARGET_LONG_DOUBLE_128"
- [(set (match_dup 3) (match_dup 1))
- (set (match_dup 0)
- (float_extend:TF (match_dup 3)))]
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_POWERPC64
+ && TARGET_LONG_DOUBLE_128 && reload_completed
+ && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
+ || (GET_CODE (operands[0]) == SUBREG
+ && GET_CODE (SUBREG_REG (operands[0])) == REG
+ && REGNO (SUBREG_REG (operands[0])) <= 31))"
+ [(set (match_dup 2) (match_dup 6))
+ (set (match_dup 3) (match_dup 7))
+ (set (match_dup 4) (match_dup 8))
+ (set (match_dup 5) (match_dup 9))]
+ "
+{
+ long l[4];
+ REAL_VALUE_TYPE rv;
+
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
+ REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, l);
+
+ operands[2] = operand_subword (operands[0], 0, 0, TFmode);
+ operands[3] = operand_subword (operands[0], 1, 0, TFmode);
+ operands[4] = operand_subword (operands[0], 2, 0, TFmode);
+ operands[5] = operand_subword (operands[0], 3, 0, TFmode);
+ operands[6] = gen_int_mode (l[0], SImode);
+ operands[7] = gen_int_mode (l[1], SImode);
+ operands[8] = gen_int_mode (l[2], SImode);
+ operands[9] = gen_int_mode (l[3], SImode);
+}")
+
+(define_split
+ [(set (match_operand:TF 0 "gpc_reg_operand" "")
+ (match_operand:TF 1 "easy_fp_constant" ""))]
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
+ && TARGET_LONG_DOUBLE_128 && reload_completed
+ && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
+ || (GET_CODE (operands[0]) == SUBREG
+ && GET_CODE (SUBREG_REG (operands[0])) == REG
+ && REGNO (SUBREG_REG (operands[0])) <= 31))"
+ [(set (match_dup 2) (match_dup 4))
+ (set (match_dup 3) (match_dup 5))]
"
{
- operands[2] = operand_subword (operands[1], 0, 0, DFmode);
- operands[3] = gen_reg_rtx (DFmode);
+ long l[4];
+ REAL_VALUE_TYPE rv;
+
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
+ REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, l);
+
+ operands[2] = operand_subword (operands[0], 0, 0, TFmode);
+ operands[3] = operand_subword (operands[0], 1, 0, TFmode);
+ operands[4] = gen_int_mode (l[0], DImode);
+ operands[5] = gen_int_mode (l[1], DImode);
}")
(define_insn_and_split "extenddftf2"