diff options
author | Richard Henderson <rth@redhat.com> | 2004-03-11 23:14:56 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2004-03-11 23:14:56 -0800 |
commit | 75959f0a1d2debc18aedd1a846700184e1f90632 (patch) | |
tree | 7b4d16c5775f4cee44df8500bbabeffc2cca126c /gcc/config/alpha | |
parent | 009368dba64b7288dc9d9a92618de62d2e36dc3a (diff) | |
download | gcc-75959f0a1d2debc18aedd1a846700184e1f90632.zip gcc-75959f0a1d2debc18aedd1a846700184e1f90632.tar.gz gcc-75959f0a1d2debc18aedd1a846700184e1f90632.tar.bz2 |
alpha.c (xfloating_ops, [...]): New.
* config/alpha/alpha.c (xfloating_ops, vax_cvt_ops): New.
(alpha_lookup_xfloating_lib_func): Use them, return rtx.
(alpha_emit_xfloating_arith): Update to match.
(alpha_emit_xfloating_compare): Likewise.
(alpha_emit_xfloating_cvt): Likewise.
(alpha_emit_xfloating_libcall): Take already built symbol,
mark call const.
* config/alpha/alpha.md (extendsftf2, extenddftf2): Take
op1 in a register.
From-SVN: r79371
Diffstat (limited to 'gcc/config/alpha')
-rw-r--r-- | gcc/config/alpha/alpha.c | 137 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.md | 7 |
2 files changed, 64 insertions, 80 deletions
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 061113c..37920ad 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -3564,85 +3564,65 @@ alpha_split_conditional_move (enum rtx_code code, rtx dest, rtx cond, /* Look up the function X_floating library function name for the given operation. */ -static const char * +struct xfloating_op GTY(()) +{ + const enum rtx_code code; + const char *const GTY((skip(""))) osf_func; + const char *const GTY((skip(""))) vms_func; + rtx libcall; +}; + +static GTY(()) struct xfloating_op xfloating_ops[] = +{ + { PLUS, "_OtsAddX", "OTS$ADD_X", 0 }, + { MINUS, "_OtsSubX", "OTS$SUB_X", 0 }, + { MULT, "_OtsMulX", "OTS$MUL_X", 0 }, + { DIV, "_OtsDivX", "OTS$DIV_X", 0 }, + { EQ, "_OtsEqlX", "OTS$EQL_X", 0 }, + { NE, "_OtsNeqX", "OTS$NEQ_X", 0 }, + { LT, "_OtsLssX", "OTS$LSS_X", 0 }, + { LE, "_OtsLeqX", "OTS$LEQ_X", 0 }, + { GT, "_OtsGtrX", "OTS$GTR_X", 0 }, + { GE, "_OtsGeqX", "OTS$GEQ_X", 0 }, + { FIX, "_OtsCvtXQ", "OTS$CVTXQ", 0 }, + { FLOAT, "_OtsCvtQX", "OTS$CVTQX", 0 }, + { UNSIGNED_FLOAT, "_OtsCvtQUX", "OTS$CVTQUX", 0 }, + { FLOAT_EXTEND, "_OtsConvertFloatTX", "OTS$CVT_FLOAT_T_X", 0 }, + { FLOAT_TRUNCATE, "_OtsConvertFloatXT", "OTS$CVT_FLOAT_X_T", 0 } +}; + +static GTY(()) struct xfloating_op vax_cvt_ops[] = +{ + { FLOAT_EXTEND, "_OtsConvertFloatGX", "OTS$CVT_FLOAT_G_X", 0 }, + { FLOAT_TRUNCATE, "_OtsConvertFloatXG", "OTS$CVT_FLOAT_X_G", 0 } +}; + +static rtx alpha_lookup_xfloating_lib_func (enum rtx_code code) { - struct xfloating_op - { - const enum rtx_code code; - const char *const func; - }; - - static const struct xfloating_op vms_xfloating_ops[] = - { - { PLUS, "OTS$ADD_X" }, - { MINUS, "OTS$SUB_X" }, - { MULT, "OTS$MUL_X" }, - { DIV, "OTS$DIV_X" }, - { EQ, "OTS$EQL_X" }, - { NE, "OTS$NEQ_X" }, - { LT, "OTS$LSS_X" }, - { LE, "OTS$LEQ_X" }, - { GT, "OTS$GTR_X" }, - { GE, "OTS$GEQ_X" }, - { FIX, "OTS$CVTXQ" }, - { FLOAT, "OTS$CVTQX" }, - { UNSIGNED_FLOAT, "OTS$CVTQUX" }, - { FLOAT_EXTEND, "OTS$CVT_FLOAT_T_X" }, - { FLOAT_TRUNCATE, "OTS$CVT_FLOAT_X_T" }, - }; - - static const struct xfloating_op osf_xfloating_ops[] = - { - { PLUS, "_OtsAddX" }, - { MINUS, "_OtsSubX" }, - { MULT, "_OtsMulX" }, - { DIV, "_OtsDivX" }, - { EQ, "_OtsEqlX" }, - { NE, "_OtsNeqX" }, - { LT, "_OtsLssX" }, - { LE, "_OtsLeqX" }, - { GT, "_OtsGtrX" }, - { GE, "_OtsGeqX" }, - { FIX, "_OtsCvtXQ" }, - { FLOAT, "_OtsCvtQX" }, - { UNSIGNED_FLOAT, "_OtsCvtQUX" }, - { FLOAT_EXTEND, "_OtsConvertFloatTX" }, - { FLOAT_TRUNCATE, "_OtsConvertFloatXT" }, - }; - - const struct xfloating_op *ops; - const long n = ARRAY_SIZE (osf_xfloating_ops); + struct xfloating_op *ops = xfloating_ops; + long n = ARRAY_SIZE (xfloating_ops); long i; - /* How irritating. Nothing to key off for the table. Hardcode - knowledge of the G_floating routines. */ - if (TARGET_FLOAT_VAX) + /* How irritating. Nothing to key off for the main table. */ + if (TARGET_FLOAT_VAX && (code == FLOAT_EXTEND || code == FLOAT_TRUNCATE)) { - if (TARGET_ABI_OPEN_VMS) - { - if (code == FLOAT_EXTEND) - return "OTS$CVT_FLOAT_G_X"; - if (code == FLOAT_TRUNCATE) - return "OTS$CVT_FLOAT_X_G"; - } - else - { - if (code == FLOAT_EXTEND) - return "_OtsConvertFloatGX"; - if (code == FLOAT_TRUNCATE) - return "_OtsConvertFloatXG"; - } + ops = vax_cvt_ops; + n = ARRAY_SIZE (vax_cvt_ops); } - if (TARGET_ABI_OPEN_VMS) - ops = vms_xfloating_ops; - else - ops = osf_xfloating_ops; - - for (i = 0; i < n; ++i) - if (ops[i].code == code) - return ops[i].func; + for (i = 0; i < n; ++i, ++ops) + if (ops->code == code) + { + rtx func = ops->libcall; + if (!func) + { + func = init_one_libfunc (TARGET_ABI_OPEN_VMS + ? ops->vms_func : ops->osf_func); + ops->libcall = func; + } + return func; + } abort(); } @@ -3688,7 +3668,7 @@ alpha_compute_xfloating_mode_arg (enum rtx_code code, TFmode arguments are passed in two integer registers (as opposed to indirect); TFmode return values appear in R16+R17. - FUNC is the function name to call. + FUNC is the function to call. TARGET is where the output belongs. OPERANDS are the inputs. NOPERANDS is the count of inputs. @@ -3696,7 +3676,7 @@ alpha_compute_xfloating_mode_arg (enum rtx_code code, */ static void -alpha_emit_xfloating_libcall (const char *func, rtx target, rtx operands[], +alpha_emit_xfloating_libcall (rtx func, rtx target, rtx operands[], int noperands, rtx equiv) { rtx usage = NULL_RTX, tmp, reg; @@ -3750,10 +3730,11 @@ alpha_emit_xfloating_libcall (const char *func, rtx target, rtx operands[], abort (); } - tmp = gen_rtx_MEM (QImode, init_one_libfunc (func)); + tmp = gen_rtx_MEM (QImode, func); tmp = emit_call_insn (GEN_CALL_VALUE (reg, tmp, const0_rtx, const0_rtx, const0_rtx)); CALL_INSN_FUNCTION_USAGE (tmp) = usage; + CONST_OR_PURE_CALL_P (tmp) = 1; tmp = get_insns (); end_sequence (); @@ -3766,7 +3747,7 @@ alpha_emit_xfloating_libcall (const char *func, rtx target, rtx operands[], void alpha_emit_xfloating_arith (enum rtx_code code, rtx operands[]) { - const char *func; + rtx func; int mode; rtx out_operands[3]; @@ -3786,7 +3767,7 @@ alpha_emit_xfloating_arith (enum rtx_code code, rtx operands[]) static rtx alpha_emit_xfloating_compare (enum rtx_code code, rtx op0, rtx op1) { - const char *func; + rtx func; rtx out, operands[2]; func = alpha_lookup_xfloating_lib_func (code); @@ -3810,7 +3791,7 @@ alpha_emit_xfloating_cvt (enum rtx_code orig_code, rtx operands[]) { int noperands = 1, mode; rtx out_operands[2]; - const char *func; + rtx func; enum rtx_code code = orig_code; if (code == UNSIGNED_FIX) diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md index 79ae422..64c88e3 100644 --- a/gcc/config/alpha/alpha.md +++ b/gcc/config/alpha/alpha.md @@ -2630,9 +2630,12 @@ st%- %1,%0" [(set_attr "type" "fcpys,fld,fst")]) +;; Use register_operand for operand 1 to prevent compress_float_constant +;; from doing something silly. When optimizing we'll put things back +;; together anyway. (define_expand "extendsftf2" [(use (match_operand:TF 0 "register_operand" "")) - (use (match_operand:SF 1 "general_operand" ""))] + (use (match_operand:SF 1 "register_operand" ""))] "TARGET_HAS_XFLOATING_LIBS" { rtx tmp = gen_reg_rtx (DFmode); @@ -2643,7 +2646,7 @@ (define_expand "extenddftf2" [(use (match_operand:TF 0 "register_operand" "")) - (use (match_operand:DF 1 "general_operand" ""))] + (use (match_operand:DF 1 "register_operand" ""))] "TARGET_HAS_XFLOATING_LIBS" "alpha_emit_xfloating_cvt (FLOAT_EXTEND, operands); DONE;") |