aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/alpha
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2004-03-11 23:14:56 -0800
committerRichard Henderson <rth@gcc.gnu.org>2004-03-11 23:14:56 -0800
commit75959f0a1d2debc18aedd1a846700184e1f90632 (patch)
tree7b4d16c5775f4cee44df8500bbabeffc2cca126c /gcc/config/alpha
parent009368dba64b7288dc9d9a92618de62d2e36dc3a (diff)
downloadgcc-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.c137
-rw-r--r--gcc/config/alpha/alpha.md7
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;")