From fcce224d2a322481095f1b3ecf259b7acae50b6b Mon Sep 17 00:00:00 2001 From: David Edelsohn Date: Mon, 7 Oct 2002 19:12:04 +0000 Subject: [PATCH] rs6000.c (rs6000_override_options): Set real_format_for_mode for IBM extended format, if enabled. * 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. From-SVN: r57904 --- gcc/ChangeLog | 16 +++++++++ gcc/config/rs6000/rs6000.c | 69 ++++++++++++++++++++++++++++++++----- gcc/config/rs6000/rs6000.h | 5 +-- gcc/config/rs6000/rs6000.md | 62 ++++++++++++++++++++++++++++----- 4 files changed, 133 insertions(+), 19 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index adffbeb11cc..558eaa7506c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,20 @@ +2002-10-07 David Edelsohn + + * 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 + * rtl.h: Add NOTE_PRECONDITIONED. * unroll.c: Set it. * loop.c: Set loop_info->preconditioned from it. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index b293cc28ccb..53b7a9b5e3c 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -683,6 +683,10 @@ rs6000_override_options (default_cpu) 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 (); @@ -1306,7 +1310,21 @@ easy_fp_constant (op, mode) 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; @@ -2095,7 +2113,7 @@ rs6000_legitimize_address (x, oldx, mode) && GET_MODE_NUNITS (mode) == 1 && ((TARGET_HARD_FLOAT && TARGET_FPRS) || TARGET_POWERPC64 - || mode != DFmode) + || (mode != DFmode && mode != TFmode)) && (TARGET_POWERPC64 || mode != DImode) && mode != TImode) { @@ -2348,7 +2366,7 @@ rs6000_legitimate_address (mode, x, reg_ok_strict) 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; @@ -3026,7 +3044,7 @@ function_arg_advance (cum, mode, type, named) if (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_HARD_FLOAT && TARGET_FPRS) - cum->fregno++; + cum->fregno += (mode == TFmode ? 2 : 1); if (TARGET_DEBUG_ARG) { @@ -10453,21 +10471,21 @@ rs6000_emit_prologue () 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. */ @@ -11085,7 +11103,7 @@ rs6000_output_function_epilogue (file, size) if (mode == SFmode) bits = 0x2; - else if (mode == DFmode) + else if (mode == DFmode || mode == TFmode) bits = 0x3; else abort (); @@ -11639,7 +11657,42 @@ output_toc (file, x, labelno, mode) /* 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]; diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index d1d84ef24db..7f4139be88d 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -660,7 +660,8 @@ extern int rs6000_default_long_calls; 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)) /* Standard register usage. */ @@ -2073,7 +2074,7 @@ typedef struct rs6000_args || (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) \ diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 91fa56c7637..13adeca14b0 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -3615,7 +3615,7 @@ #" [(set_attr "type" "compare") (set_attr "length" "4,8")]) - + (define_split [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") (compare:CC @@ -3635,7 +3635,7 @@ (compare:CC (match_dup 0) (const_int 0)))] "") - + ;; Rotate and shift insns, in all their variants. These support shifts, ;; field inserts and extracts, and various combinations thereof. (define_expand "insv" @@ -8744,15 +8744,59 @@ (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" -- 2.30.2