diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 981185e8449..174a7ee18fd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2002-04-30 Richard Henderson + + * config/sparc/sparc.c (emit_soft_tfmode_libcall, + emit_soft_tfmode_binop, emit_soft_tfmode_unop, emit_soft_tfmode_cvt, + emit_hard_tfmode_operation, emit_tfmode_binop, emit_tfmode_unop, + emit_tfmode_cvt): New. + * config/sparc/sparc.md (extendsftf2, extenddftf2, trunctfsf2, + trunctfdf2, floatsitf2, floatunssitf2, floatditf2, floatunsditf2, + fix_trunctfsi2, fixuns_trunctfsi2, fix_trunctfdi2, fixuns_trunctfdi2, + addtf3, subtf3, multf3, divtf3, sqrttf2): Use them. + * config/sparc/sparc-protos.h: Update. + 2002-04-30 Janis Johnson * install.texi (Final install): Add to the list of info to include diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index fef6ecb6db0..5f6343bf9ac 100644 --- a/gcc/config/sparc/sparc-protos.h +++ b/gcc/config/sparc/sparc-protos.h @@ -74,6 +74,9 @@ extern enum machine_mode select_cc_mode PARAMS ((enum rtx_code, rtx, rtx)); extern rtx gen_compare_reg PARAMS ((enum rtx_code code, rtx, rtx)); extern void sparc_emit_float_lib_cmp PARAMS ((rtx, rtx, enum rtx_code)); extern void sparc_emit_floatunsdi PARAMS ((rtx [2])); +extern void emit_tfmode_binop PARAMS ((enum rtx_code, rtx *)); +extern void emit_tfmode_unop PARAMS ((enum rtx_code, rtx *)); +extern void emit_tfmode_cvt PARAMS ((enum rtx_code, rtx *)); /* This function handles all v9 scc insns */ extern int gen_v9_scc PARAMS ((enum rtx_code, rtx *)); extern void sparc_initialize_trampoline PARAMS ((rtx, rtx, rtx)); diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index e564e4649bd..0bac7c9afc9 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -168,6 +168,12 @@ static void sparc_sched_init PARAMS ((FILE *, int, int)); static int sparc_use_dfa_pipeline_interface PARAMS ((void)); static int sparc_use_sched_lookahead PARAMS ((void)); static rtx sparc_cycle_display PARAMS ((int, rtx)); + +static void emit_soft_tfmode_libcall PARAMS ((const char *, int, rtx *)); +static void emit_soft_tfmode_binop PARAMS ((enum rtx_code, rtx *)); +static void emit_soft_tfmode_unop PARAMS ((enum rtx_code, rtx *)); +static void emit_soft_tfmode_cvt PARAMS ((enum rtx_code, rtx *)); +static void emit_hard_tfmode_operation PARAMS ((enum rtx_code, rtx *)); /* Option handling. */ @@ -2456,6 +2462,304 @@ gen_df_reg (reg, low) return gen_rtx_REG (DFmode, regno); } +/* Generate a call to FUNC with OPERANDS. Operand 0 is the return value. + Unlike normal calls, TFmode operands are passed by reference. It is + assumed that no more than 3 operands are required. */ + +static void +emit_soft_tfmode_libcall (func_name, nargs, operands) + const char *func_name; + int nargs; + rtx *operands; +{ + rtx ret_slot = NULL, arg[3], func_sym; + int i; + + /* We only expect to be called for conversions, unary, and binary ops. */ + if (nargs < 2 || nargs > 3) + abort (); + + for (i = 0; i < nargs; ++i) + { + rtx this_arg = operands[i]; + rtx this_slot; + + /* TFmode arguments and return values are passed by reference. */ + if (GET_MODE (this_arg) == TFmode) + { + if (GET_CODE (this_arg) == MEM) + this_arg = XEXP (this_arg, 0); + else if (CONSTANT_P (this_arg)) + { + this_slot = force_const_mem (TFmode, this_arg); + this_arg = XEXP (this_slot, 0); + } + else + { + this_slot = assign_stack_temp (TFmode, GET_MODE_SIZE (TFmode), 0); + + /* Operand 0 is the return value. We'll copy it out later. */ + if (i > 0) + emit_move_insn (this_slot, this_arg); + else + ret_slot = this_slot; + + this_arg = XEXP (this_slot, 0); + } + } + + arg[i] = this_arg; + } + + func_sym = gen_rtx_SYMBOL_REF (Pmode, func_name); + + if (GET_MODE (operands[0]) == TFmode) + { + if (nargs == 2) + emit_library_call (func_sym, LCT_NORMAL, VOIDmode, 2, + arg[0], GET_MODE (arg[0]), + arg[1], GET_MODE (arg[1])); + else + emit_library_call (func_sym, LCT_NORMAL, VOIDmode, 3, + arg[0], GET_MODE (arg[0]), + arg[1], GET_MODE (arg[1]), + arg[2], GET_MODE (arg[2])); + + if (ret_slot) + emit_move_insn (operands[0], ret_slot); + } + else + { + rtx ret; + + if (nargs != 2) + abort (); + + ret = emit_library_call_value (func_sym, operands[0], LCT_NORMAL, + GET_MODE (operands[0]), 1, + arg[1], GET_MODE (arg[1])); + + if (ret != operands[0]) + emit_move_insn (operands[0], ret); + } +} + +/* Expand soft-float TFmode calls to sparc abi routines. */ + +static void +emit_soft_tfmode_binop (code, operands) + enum rtx_code code; + rtx *operands; +{ + const char *func; + + switch (code) + { + case PLUS: + func = "_Qp_add"; + break; + case MINUS: + func = "_Qp_sub"; + break; + case MULT: + func = "_Qp_mul"; + break; + case DIV: + func = "_Qp_div"; + break; + default: + abort (); + } + + emit_soft_tfmode_libcall (func, 3, operands); +} + +static void +emit_soft_tfmode_unop (code, operands) + enum rtx_code code; + rtx *operands; +{ + const char *func; + + switch (code) + { + case SQRT: + func = "_Qp_sqrt"; + break; + default: + abort (); + } + + emit_soft_tfmode_libcall (func, 2, operands); +} + +static void +emit_soft_tfmode_cvt (code, operands) + enum rtx_code code; + rtx *operands; +{ + const char *func; + + switch (code) + { + case FLOAT_EXTEND: + switch (GET_MODE (operands[1])) + { + case SFmode: + func = "_Qp_stoq"; + break; + case DFmode: + func = "_Qp_dtoq"; + break; + default: + abort (); + } + break; + + case FLOAT_TRUNCATE: + switch (GET_MODE (operands[0])) + { + case SFmode: + func = "_Qp_qtos"; + break; + case DFmode: + func = "_Qp_qtod"; + break; + default: + abort (); + } + break; + + case FLOAT: + switch (GET_MODE (operands[1])) + { + case SImode: + func = "_Qp_itoq"; + break; + case DImode: + func = "_Qp_xtoq"; + break; + default: + abort (); + } + break; + + case UNSIGNED_FLOAT: + switch (GET_MODE (operands[1])) + { + case SImode: + func = "_Qp_uitoq"; + break; + case DImode: + func = "_Qp_uxtoq"; + break; + default: + abort (); + } + break; + + case FIX: + switch (GET_MODE (operands[0])) + { + case SImode: + func = "_Qp_qtoi"; + break; + case DImode: + func = "_Qp_qtox"; + break; + default: + abort (); + } + break; + + case UNSIGNED_FIX: + switch (GET_MODE (operands[0])) + { + case SImode: + func = "_Qp_qtoui"; + break; + case DImode: + func = "_Qp_qtoux"; + break; + default: + abort (); + } + break; + + default: + abort (); + } + + emit_soft_tfmode_libcall (func, 2, operands); +} + +/* Expand a hard-float tfmode operation. All arguments must be in + registers. */ + +static void +emit_hard_tfmode_operation (code, operands) + enum rtx_code code; + rtx *operands; +{ + rtx op, dest; + + if (GET_RTX_CLASS (code) == '1') + { + operands[1] = force_reg (GET_MODE (operands[1]), operands[1]); + op = gen_rtx_fmt_e (code, GET_MODE (operands[0]), operands[1]); + } + else + { + operands[1] = force_reg (GET_MODE (operands[1]), operands[1]); + operands[2] = force_reg (GET_MODE (operands[2]), operands[2]); + op = gen_rtx_fmt_ee (code, GET_MODE (operands[0]), + operands[1], operands[2]); + } + + if (register_operand (operands[0], VOIDmode)) + dest = operands[0]; + else + dest = gen_reg_rtx (GET_MODE (operands[0])); + + emit_insn (gen_rtx_SET (VOIDmode, dest, op)); + + if (dest != operands[0]) + emit_move_insn (operands[0], dest); +} + +void +emit_tfmode_binop (code, operands) + enum rtx_code code; + rtx *operands; +{ + if (TARGET_HARD_QUAD) + emit_hard_tfmode_operation (code, operands); + else + emit_soft_tfmode_binop (code, operands); +} + +void +emit_tfmode_unop (code, operands) + enum rtx_code code; + rtx *operands; +{ + if (TARGET_HARD_QUAD) + emit_hard_tfmode_operation (code, operands); + else + emit_soft_tfmode_unop (code, operands); +} + +void +emit_tfmode_cvt (code, operands) + enum rtx_code code; + rtx *operands; +{ + if (TARGET_HARD_QUAD) + emit_hard_tfmode_operation (code, operands); + else + emit_soft_tfmode_cvt (code, operands); +} + /* Return nonzero if a return peephole merging return with setting of output register is ok. */ int diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 0932c84966a..db12cfe479b 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -5220,31 +5220,11 @@ (set_attr "fptype" "double")]) (define_expand "extendsftf2" - [(set (match_operand:TF 0 "register_operand" "=e") + [(set (match_operand:TF 0 "nonimmediate_operand" "") (float_extend:TF - (match_operand:SF 1 "register_operand" "f")))] + (match_operand:SF 1 "register_operand" "")))] "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" - " -{ - if (! TARGET_HARD_QUAD) - { - rtx slot0; - - if (GET_CODE (operands[0]) != MEM) - slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - else - slot0 = operands[0]; - - emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), LCT_NORMAL, - VOIDmode, 2, - XEXP (slot0, 0), Pmode, - operands[1], SFmode); - - if (GET_CODE (operands[0]) != MEM) - emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0)); - DONE; - } -}") + "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;") (define_insn "*extendsftf2_hq" [(set (match_operand:TF 0 "register_operand" "=e") @@ -5255,31 +5235,11 @@ [(set_attr "type" "fp")]) (define_expand "extenddftf2" - [(set (match_operand:TF 0 "register_operand" "=e") + [(set (match_operand:TF 0 "nonimmediate_operand" "") (float_extend:TF - (match_operand:DF 1 "register_operand" "e")))] + (match_operand:DF 1 "register_operand" "")))] "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" - " -{ - if (! TARGET_HARD_QUAD) - { - rtx slot0; - - if (GET_CODE (operands[0]) != MEM) - slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - else - slot0 = operands[0]; - - emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), LCT_NORMAL, - VOIDmode, 2, - XEXP (slot0, 0), Pmode, - operands[1], DFmode); - - if (GET_CODE (operands[0]) != MEM) - emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0)); - DONE; - } -}") + "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;") (define_insn "*extenddftf2_hq" [(set (match_operand:TF 0 "register_operand" "=e") @@ -5299,30 +5259,11 @@ (set_attr "fptype" "double")]) (define_expand "trunctfsf2" - [(set (match_operand:SF 0 "register_operand" "=f") + [(set (match_operand:SF 0 "register_operand" "") (float_truncate:SF - (match_operand:TF 1 "register_operand" "e")))] + (match_operand:TF 1 "general_operand" "")))] "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" - " -{ - if (! TARGET_HARD_QUAD) - { - rtx slot0; - - if (GET_CODE (operands[1]) != MEM) - { - slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1])); - } - else - slot0 = operands[1]; - - emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"), - operands[0], LCT_NORMAL, SFmode, 1, - XEXP (slot0, 0), Pmode); - DONE; - } -}") + "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;") (define_insn "*trunctfsf2_hq" [(set (match_operand:SF 0 "register_operand" "=f") @@ -5333,30 +5274,11 @@ [(set_attr "type" "fp")]) (define_expand "trunctfdf2" - [(set (match_operand:DF 0 "register_operand" "=f") + [(set (match_operand:DF 0 "register_operand" "") (float_truncate:DF - (match_operand:TF 1 "register_operand" "e")))] + (match_operand:TF 1 "general_operand" "")))] "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" - " -{ - if (! TARGET_HARD_QUAD) - { - rtx slot0; - - if (GET_CODE (operands[1]) != MEM) - { - slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1])); - } - else - slot0 = operands[1]; - - emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"), - operands[0], LCT_NORMAL, DFmode, 1, - XEXP (slot0, 0), Pmode); - DONE; - } -}") + "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;") (define_insn "*trunctfdf2_hq" [(set (match_operand:DF 0 "register_operand" "=e") @@ -5385,30 +5307,10 @@ (set_attr "fptype" "double")]) (define_expand "floatsitf2" - [(set (match_operand:TF 0 "register_operand" "=e") - (float:TF (match_operand:SI 1 "register_operand" "f")))] + [(set (match_operand:TF 0 "nonimmediate_operand" "") + (float:TF (match_operand:SI 1 "register_operand" "")))] "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" - " -{ - if (! TARGET_HARD_QUAD) - { - rtx slot0; - - if (GET_CODE (operands[1]) != MEM) - slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - else - slot0 = operands[1]; - - emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0, - VOIDmode, 2, - XEXP (slot0, 0), Pmode, - operands[1], SImode); - - if (GET_CODE (operands[0]) != MEM) - emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0)); - DONE; - } -}") + "emit_tfmode_cvt (FLOAT, operands); DONE;") (define_insn "*floatsitf2_hq" [(set (match_operand:TF 0 "register_operand" "=e") @@ -5418,27 +5320,10 @@ [(set_attr "type" "fp")]) (define_expand "floatunssitf2" - [(set (match_operand:TF 0 "register_operand" "=e") - (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))] + [(set (match_operand:TF 0 "nonimmediate_operand" "") + (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))] "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD" - " -{ - rtx slot0; - - if (GET_CODE (operands[1]) != MEM) - slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - else - slot0 = operands[1]; - - emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0, - VOIDmode, 2, - XEXP (slot0, 0), Pmode, - operands[1], SImode); - - if (GET_CODE (operands[0]) != MEM) - emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0)); - DONE; -}") + "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;") ;; Now the same for 64 bit sources. @@ -5471,30 +5356,10 @@ "sparc_emit_floatunsdi (operands); DONE;") (define_expand "floatditf2" - [(set (match_operand:TF 0 "register_operand" "=e") - (float:TF (match_operand:DI 1 "register_operand" "e")))] + [(set (match_operand:TF 0 "nonimmediate_operand" "") + (float:TF (match_operand:DI 1 "register_operand" "")))] "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)" - " -{ - if (! TARGET_HARD_QUAD) - { - rtx slot0; - - if (GET_CODE (operands[1]) != MEM) - slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - else - slot0 = operands[1]; - - emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0, - VOIDmode, 2, - XEXP (slot0, 0), Pmode, - operands[1], DImode); - - if (GET_CODE (operands[0]) != MEM) - emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0)); - DONE; - } -}") + "emit_tfmode_cvt (FLOAT, operands); DONE;") (define_insn "*floatditf2_hq" [(set (match_operand:TF 0 "register_operand" "=e") @@ -5504,27 +5369,10 @@ [(set_attr "type" "fp")]) (define_expand "floatunsditf2" - [(set (match_operand:TF 0 "register_operand" "=e") - (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))] + [(set (match_operand:TF 0 "nonimmediate_operand" "") + (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))] "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD" - " -{ - rtx slot0; - - if (GET_CODE (operands[1]) != MEM) - slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - else - slot0 = operands[1]; - - emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0, - VOIDmode, 2, - XEXP (slot0, 0), Pmode, - operands[1], DImode); - - if (GET_CODE (operands[0]) != MEM) - emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0)); - DONE; -}") + "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;") ;; Convert a float to an actual integer. ;; Truncation is performed as part of the conversion. @@ -5546,58 +5394,23 @@ (set_attr "fptype" "double")]) (define_expand "fix_trunctfsi2" - [(set (match_operand:SI 0 "register_operand" "=f") - (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))] + [(set (match_operand:SI 0 "register_operand" "") + (fix:SI (match_operand:TF 1 "general_operand" "")))] "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" - " -{ - if (! TARGET_HARD_QUAD) - { - rtx slot0; - - if (GET_CODE (operands[1]) != MEM) - { - slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1])); - } - else - slot0 = operands[1]; - - emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"), - operands[0], LCT_NORMAL, SImode, 1, - XEXP (slot0, 0), Pmode); - DONE; - } -}") + "emit_tfmode_cvt (FIX, operands); DONE;") (define_insn "*fix_trunctfsi2_hq" [(set (match_operand:SI 0 "register_operand" "=f") - (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))] + (fix:SI (match_operand:TF 1 "register_operand" "e")))] "TARGET_FPU && TARGET_HARD_QUAD" "fqtoi\\t%1, %0" [(set_attr "type" "fp")]) (define_expand "fixuns_trunctfsi2" - [(set (match_operand:SI 0 "register_operand" "=f") - (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))] + [(set (match_operand:SI 0 "register_operand" "") + (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))] "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD" - " -{ - rtx slot0; - - if (GET_CODE (operands[1]) != MEM) - { - slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1])); - } - else - slot0 = operands[1]; - - emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"), - operands[0], LCT_NORMAL, SImode, 1, - XEXP (slot0, 0), Pmode); - DONE; -}") + "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;") ;; Now the same, for V9 targets @@ -5618,59 +5431,23 @@ (set_attr "fptype" "double")]) (define_expand "fix_trunctfdi2" - [(set (match_operand:DI 0 "register_operand" "=e") - (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))] + [(set (match_operand:DI 0 "register_operand" "") + (fix:DI (match_operand:TF 1 "general_operand" "")))] "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" - " -{ - if (! TARGET_HARD_QUAD) - { - rtx slot0; - - if (GET_CODE (operands[1]) != MEM) - { - slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1])); - } - else - slot0 = operands[1]; - - emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"), - operands[0], LCT_NORMAL, DImode, 1, - XEXP (slot0, 0), Pmode); - DONE; - } -}") + "emit_tfmode_cvt (FIX, operands); DONE;") (define_insn "*fix_trunctfdi2_hq" [(set (match_operand:DI 0 "register_operand" "=e") - (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))] + (fix:DI (match_operand:TF 1 "register_operand" "e")))] "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" "fqtox\\t%1, %0" [(set_attr "type" "fp")]) (define_expand "fixuns_trunctfdi2" - [(set (match_operand:DI 0 "register_operand" "=f") - (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))] + [(set (match_operand:DI 0 "register_operand" "") + (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))] "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD" - " -{ - rtx slot0; - - if (GET_CODE (operands[1]) != MEM) - { - slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1])); - } - else - slot0 = operands[1]; - - emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"), - operands[0], LCT_NORMAL, DImode, 1, - XEXP (slot0, 0), Pmode); - DONE; -}") - + "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;") ;;- arithmetic instructions @@ -7570,42 +7347,7 @@ (plus:TF (match_operand:TF 1 "general_operand" "") (match_operand:TF 2 "general_operand" "")))] "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" - " -{ - if (! TARGET_HARD_QUAD) - { - rtx slot0, slot1, slot2; - - if (GET_CODE (operands[0]) != MEM) - slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - else - slot0 = operands[0]; - if (GET_CODE (operands[1]) != MEM) - { - slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1])); - } - else - slot1 = operands[1]; - if (GET_CODE (operands[2]) != MEM) - { - slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2])); - } - else - slot2 = operands[2]; - - emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0, - VOIDmode, 3, - XEXP (slot0, 0), Pmode, - XEXP (slot1, 0), Pmode, - XEXP (slot2, 0), Pmode); - - if (GET_CODE (operands[0]) != MEM) - emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0)); - DONE; - } -}") + "emit_tfmode_binop (PLUS, operands); DONE;") (define_insn "*addtf3_hq" [(set (match_operand:TF 0 "register_operand" "=e") @@ -7637,42 +7379,7 @@ (minus:TF (match_operand:TF 1 "general_operand" "") (match_operand:TF 2 "general_operand" "")))] "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" - " -{ - if (! TARGET_HARD_QUAD) - { - rtx slot0, slot1, slot2; - - if (GET_CODE (operands[0]) != MEM) - slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - else - slot0 = operands[0]; - if (GET_CODE (operands[1]) != MEM) - { - slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1])); - } - else - slot1 = operands[1]; - if (GET_CODE (operands[2]) != MEM) - { - slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2])); - } - else - slot2 = operands[2]; - - emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0, - VOIDmode, 3, - XEXP (slot0, 0), Pmode, - XEXP (slot1, 0), Pmode, - XEXP (slot2, 0), Pmode); - - if (GET_CODE (operands[0]) != MEM) - emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0)); - DONE; - } -}") + "emit_tfmode_binop (MINUS, operands); DONE;") (define_insn "*subtf3_hq" [(set (match_operand:TF 0 "register_operand" "=e") @@ -7704,42 +7411,7 @@ (mult:TF (match_operand:TF 1 "general_operand" "") (match_operand:TF 2 "general_operand" "")))] "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" - " -{ - if (! TARGET_HARD_QUAD) - { - rtx slot0, slot1, slot2; - - if (GET_CODE (operands[0]) != MEM) - slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - else - slot0 = operands[0]; - if (GET_CODE (operands[1]) != MEM) - { - slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1])); - } - else - slot1 = operands[1]; - if (GET_CODE (operands[2]) != MEM) - { - slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2])); - } - else - slot2 = operands[2]; - - emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0, - VOIDmode, 3, - XEXP (slot0, 0), Pmode, - XEXP (slot1, 0), Pmode, - XEXP (slot2, 0), Pmode); - - if (GET_CODE (operands[0]) != MEM) - emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0)); - DONE; - } -}") + "emit_tfmode_binop (MULT, operands); DONE;") (define_insn "*multf3_hq" [(set (match_operand:TF 0 "register_operand" "=e") @@ -7788,42 +7460,7 @@ (div:TF (match_operand:TF 1 "general_operand" "") (match_operand:TF 2 "general_operand" "")))] "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" - " -{ - if (! TARGET_HARD_QUAD) - { - rtx slot0, slot1, slot2; - - if (GET_CODE (operands[0]) != MEM) - slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - else - slot0 = operands[0]; - if (GET_CODE (operands[1]) != MEM) - { - slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1])); - } - else - slot1 = operands[1]; - if (GET_CODE (operands[2]) != MEM) - { - slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2])); - } - else - slot2 = operands[2]; - - emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0, - VOIDmode, 3, - XEXP (slot0, 0), Pmode, - XEXP (slot1, 0), Pmode, - XEXP (slot2, 0), Pmode); - - if (GET_CODE (operands[0]) != MEM) - emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0)); - DONE; - } -}") + "emit_tfmode_binop (DIV, operands); DONE;") ;; don't have timing for quad-prec. divide. (define_insn "*divtf3_hq" @@ -8072,37 +7709,10 @@ [(set_attr "type" "fpmove")]) (define_expand "sqrttf2" - [(set (match_operand:TF 0 "register_operand" "=e") - (sqrt:TF (match_operand:TF 1 "register_operand" "e")))] + [(set (match_operand:TF 0 "nonimmediate_operand" "") + (sqrt:TF (match_operand:TF 1 "general_operand" "")))] "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" - " -{ - if (! TARGET_HARD_QUAD) - { - rtx slot0, slot1; - - if (GET_CODE (operands[0]) != MEM) - slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - else - slot0 = operands[0]; - if (GET_CODE (operands[1]) != MEM) - { - slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); - emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1])); - } - else - slot1 = operands[1]; - - emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0, - VOIDmode, 2, - XEXP (slot0, 0), Pmode, - XEXP (slot1, 0), Pmode); - - if (GET_CODE (operands[0]) != MEM) - emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0)); - DONE; - } -}") + "emit_tfmode_unop (SQRT, operands); DONE;") (define_insn "*sqrttf2_hq" [(set (match_operand:TF 0 "register_operand" "=e")