Commit 2dbc83d9 by Francois-Xavier Coudert Committed by François-Xavier Coudert

* trans-intrinsic.c: Revert Lee's 2007-06-04 patch.

From-SVN: r125565
parent 4aa97413
2007-06-08 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
* trans-intrinsic.c: Revert Lee's 2007-06-04 patch.
2007-06-07 Steven G. Kargl <kargl@gcc.gnu.org>
Jerry DeLisle <jvdelisle@gcc.gnu.org>
......
......@@ -163,29 +163,25 @@ real_compnt_info;
enum rounding_mode { RND_ROUND, RND_TRUNC, RND_CEIL, RND_FLOOR };
/* Evaluate the arguments to an intrinsic function. The value
of NARGS may be less than the actual number of arguments in EXPR
to allow optional "KIND" arguments that are not included in the
generated code to be ignored. */
/* Evaluate the arguments to an intrinsic function. */
/* FIXME: This function and its callers should be rewritten so that it's
not necessary to cons up a list to hold the arguments. */
static void
gfc_conv_intrinsic_function_args (gfc_se *se, gfc_expr *expr,
tree *argarray, int nargs)
static tree
gfc_conv_intrinsic_function_args (gfc_se * se, gfc_expr * expr)
{
gfc_actual_arglist *actual;
gfc_expr *e;
gfc_intrinsic_arg *formal;
gfc_se argse;
int curr_arg;
tree args;
args = NULL_TREE;
formal = expr->value.function.isym->formal;
actual = expr->value.function.actual;
for (curr_arg = 0; curr_arg < nargs; curr_arg++,
actual = actual->next,
formal = formal ? formal->next : NULL)
for (actual = expr->value.function.actual; actual; actual = actual->next,
formal = formal ? formal->next : NULL)
{
gcc_assert (actual);
e = actual->expr;
/* Skip omitted optional arguments. */
if (!e)
......@@ -199,8 +195,7 @@ gfc_conv_intrinsic_function_args (gfc_se *se, gfc_expr *expr,
{
gfc_conv_expr (&argse, e);
gfc_conv_string_parameter (&argse);
argarray[curr_arg++] = argse.string_length;
gcc_assert (curr_arg < nargs);
args = gfc_chainon_list (args, argse.string_length);
}
else
gfc_conv_expr_val (&argse, e);
......@@ -215,31 +210,9 @@ gfc_conv_intrinsic_function_args (gfc_se *se, gfc_expr *expr,
gfc_add_block_to_block (&se->pre, &argse.pre);
gfc_add_block_to_block (&se->post, &argse.post);
argarray[curr_arg] = argse.expr;
}
}
/* Count the number of actual arguments to the intrinsic function EXPR
including any "hidden" string length arguments. */
static unsigned int
gfc_intrinsic_argument_list_length (gfc_expr *expr)
{
int n = 0;
gfc_actual_arglist *actual;
for (actual = expr->value.function.actual; actual; actual = actual->next)
{
if (!actual->expr)
continue;
if (actual->expr->ts.type == BT_CHARACTER)
n += 2;
else
n++;
args = gfc_chainon_list (args, argse.expr);
}
return n;
return args;
}
......@@ -255,7 +228,8 @@ gfc_conv_intrinsic_conversion (gfc_se * se, gfc_expr * expr)
/* Evaluate the argument. */
type = gfc_typenode_for_spec (&expr->ts);
gcc_assert (expr->value.function.actual->expr);
gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
arg = gfc_conv_intrinsic_function_args (se, expr);
arg = TREE_VALUE (arg);
/* Conversion from complex to non-complex involves taking the real
component of the value. */
......@@ -428,19 +402,20 @@ gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
/* Evaluate the argument. */
gcc_assert (expr->value.function.actual->expr);
gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
arg = gfc_conv_intrinsic_function_args (se, expr);
/* Use a builtin function if one exists. */
if (n != END_BUILTINS)
{
tmp = built_in_decls[n];
se->expr = build_call_expr (tmp, 1, arg);
se->expr = build_function_call_expr (tmp, arg);
return;
}
/* This code is probably redundant, but we'll keep it lying around just
in case. */
type = gfc_typenode_for_spec (&expr->ts);
arg = TREE_VALUE (arg);
arg = gfc_evaluate_now (arg, &se->pre);
/* Test if the value is too large to handle sensibly. */
......@@ -475,7 +450,8 @@ gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
/* Evaluate the argument. */
type = gfc_typenode_for_spec (&expr->ts);
gcc_assert (expr->value.function.actual->expr);
gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
arg = gfc_conv_intrinsic_function_args (se, expr);
arg = TREE_VALUE (arg);
if (TREE_CODE (TREE_TYPE (arg)) == INTEGER_TYPE)
{
......@@ -507,7 +483,8 @@ gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
{
tree arg;
gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
arg = gfc_conv_intrinsic_function_args (se, expr);
arg = TREE_VALUE (arg);
se->expr = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
}
......@@ -519,7 +496,8 @@ gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
{
tree arg;
gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
arg = gfc_conv_intrinsic_function_args (se, expr);
arg = TREE_VALUE (arg);
se->expr = build1 (CONJ_EXPR, TREE_TYPE (arg), arg);
}
......@@ -669,10 +647,8 @@ static void
gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
{
gfc_intrinsic_map_t *m;
tree args;
tree fndecl;
tree rettype;
tree *args;
unsigned int num_args;
gfc_isym_id id;
id = expr->value.function.isym->id;
......@@ -690,15 +666,9 @@ gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
}
/* Get the decl and generate the call. */
num_args = gfc_intrinsic_argument_list_length (expr);
args = alloca (sizeof (tree) * num_args);
gfc_conv_intrinsic_function_args (se, expr, args, num_args);
args = gfc_conv_intrinsic_function_args (se, expr);
fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
rettype = TREE_TYPE (TREE_TYPE (fndecl));
fndecl = build_addr (fndecl, current_function_decl);
se->expr = build_call_array (rettype, fndecl, num_args, args);
se->expr = build_function_call_expr (fndecl, args);
}
/* Generate code for EXPONENT(X) intrinsic function. */
......@@ -706,10 +676,10 @@ gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
static void
gfc_conv_intrinsic_exponent (gfc_se * se, gfc_expr * expr)
{
tree arg, fndecl;
tree args, fndecl;
gfc_expr *a1;
gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
args = gfc_conv_intrinsic_function_args (se, expr);
a1 = expr->value.function.actual->expr;
switch (a1->ts.kind)
......@@ -730,7 +700,7 @@ gfc_conv_intrinsic_exponent (gfc_se * se, gfc_expr * expr)
gcc_unreachable ();
}
se->expr = build_call_expr (fndecl, 1, arg);
se->expr = build_function_call_expr (fndecl, args);
}
/* Evaluate a single upper or lower bound. */
......@@ -934,16 +904,19 @@ gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
static void
gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
{
tree arg;
tree args;
tree val;
int n;
gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
args = gfc_conv_intrinsic_function_args (se, expr);
gcc_assert (args && TREE_CHAIN (args) == NULL_TREE);
val = TREE_VALUE (args);
switch (expr->value.function.actual->expr->ts.type)
{
case BT_INTEGER:
case BT_REAL:
se->expr = build1 (ABS_EXPR, TREE_TYPE (arg), arg);
se->expr = build1 (ABS_EXPR, TREE_TYPE (val), val);
break;
case BT_COMPLEX:
......@@ -962,7 +935,7 @@ gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
default:
gcc_unreachable ();
}
se->expr = build_call_expr (built_in_decls[n], 1, arg);
se->expr = build_function_call_expr (built_in_decls[n], args);
break;
default:
......@@ -976,23 +949,20 @@ gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
static void
gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
{
tree arg;
tree real;
tree imag;
tree type;
tree *args;
unsigned int num_args;
num_args = gfc_intrinsic_argument_list_length (expr);
args = alloca (sizeof (tree) * num_args);
type = gfc_typenode_for_spec (&expr->ts);
gfc_conv_intrinsic_function_args (se, expr, args, num_args);
real = convert (TREE_TYPE (type), args[0]);
arg = gfc_conv_intrinsic_function_args (se, expr);
real = convert (TREE_TYPE (type), TREE_VALUE (arg));
if (both)
imag = convert (TREE_TYPE (type), args[1]);
else if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE)
imag = convert (TREE_TYPE (type), TREE_VALUE (TREE_CHAIN (arg)));
else if (TREE_CODE (TREE_TYPE (TREE_VALUE (arg))) == COMPLEX_TYPE)
{
imag = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (args[0])), args[0]);
arg = TREE_VALUE (arg);
imag = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
imag = convert (TREE_TYPE (type), imag);
}
else
......@@ -1008,6 +978,8 @@ gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
static void
gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
{
tree arg;
tree arg2;
tree type;
tree itype;
tree tmp;
......@@ -1015,20 +987,21 @@ gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
tree test2;
mpfr_t huge;
int n, ikind;
tree args[2];
gfc_conv_intrinsic_function_args (se, expr, args, 2);
arg = gfc_conv_intrinsic_function_args (se, expr);
switch (expr->ts.type)
{
case BT_INTEGER:
/* Integer case is easy, we've got a builtin op. */
type = TREE_TYPE (args[0]);
arg2 = TREE_VALUE (TREE_CHAIN (arg));
arg = TREE_VALUE (arg);
type = TREE_TYPE (arg);
if (modulo)
se->expr = build2 (FLOOR_MOD_EXPR, type, args[0], args[1]);
se->expr = build2 (FLOOR_MOD_EXPR, type, arg, arg2);
else
se->expr = build2 (TRUNC_MOD_EXPR, type, args[0], args[1]);
se->expr = build2 (TRUNC_MOD_EXPR, type, arg, arg2);
break;
case BT_REAL:
......@@ -1056,17 +1029,18 @@ gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
/* Use it if it exists. */
if (n != END_BUILTINS)
{
tmp = build_addr (built_in_decls[n], current_function_decl);
se->expr = build_call_array (TREE_TYPE (TREE_TYPE (built_in_decls[n])),
tmp, 2, args);
tmp = built_in_decls[n];
se->expr = build_function_call_expr (tmp, arg);
if (modulo == 0)
return;
}
type = TREE_TYPE (args[0]);
arg2 = TREE_VALUE (TREE_CHAIN (arg));
arg = TREE_VALUE (arg);
type = TREE_TYPE (arg);
args[0] = gfc_evaluate_now (args[0], &se->pre);
args[1] = gfc_evaluate_now (args[1], &se->pre);
arg = gfc_evaluate_now (arg, &se->pre);
arg2 = gfc_evaluate_now (arg2, &se->pre);
/* Definition:
modulo = arg - floor (arg/arg2) * arg2, so
......@@ -1079,20 +1053,20 @@ gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
{
tree zero = gfc_build_const (type, integer_zero_node);
tmp = gfc_evaluate_now (se->expr, &se->pre);
test = build2 (LT_EXPR, boolean_type_node, args[0], zero);
test2 = build2 (LT_EXPR, boolean_type_node, args[1], zero);
test = build2 (LT_EXPR, boolean_type_node, arg, zero);
test2 = build2 (LT_EXPR, boolean_type_node, arg2, zero);
test2 = build2 (TRUTH_XOR_EXPR, boolean_type_node, test, test2);
test = build2 (NE_EXPR, boolean_type_node, tmp, zero);
test = build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
test = gfc_evaluate_now (test, &se->pre);
se->expr = build3 (COND_EXPR, type, test,
build2 (PLUS_EXPR, type, tmp, args[1]), tmp);
build2 (PLUS_EXPR, type, tmp, arg2), tmp);
return;
}
/* If we do not have a built_in fmod, the calculation is going to
have to be done longhand. */
tmp = build2 (RDIV_EXPR, type, args[0], args[1]);
tmp = build2 (RDIV_EXPR, type, arg, arg2);
/* Test if the value is too large to handle sensibly. */
gfc_set_model_kind (expr->ts.kind);
......@@ -1119,9 +1093,9 @@ gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
else
tmp = build_fix_expr (&se->pre, tmp, itype, RND_TRUNC);
tmp = convert (type, tmp);
tmp = build3 (COND_EXPR, type, test2, tmp, args[0]);
tmp = build2 (MULT_EXPR, type, tmp, args[1]);
se->expr = build2 (MINUS_EXPR, type, args[0], tmp);
tmp = build3 (COND_EXPR, type, test2, tmp, arg);
tmp = build2 (MULT_EXPR, type, tmp, arg2);
se->expr = build2 (MINUS_EXPR, type, arg, tmp);
mpfr_clear (huge);
break;
......@@ -1135,16 +1109,19 @@ gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
static void
gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
{
tree arg;
tree arg2;
tree val;
tree tmp;
tree type;
tree zero;
tree args[2];
gfc_conv_intrinsic_function_args (se, expr, args, 2);
type = TREE_TYPE (args[0]);
arg = gfc_conv_intrinsic_function_args (se, expr);
arg2 = TREE_VALUE (TREE_CHAIN (arg));
arg = TREE_VALUE (arg);
type = TREE_TYPE (arg);
val = build2 (MINUS_EXPR, type, args[0], args[1]);
val = build2 (MINUS_EXPR, type, arg, arg2);
val = gfc_evaluate_now (val, &se->pre);
zero = gfc_build_const (type, integer_zero_node);
......@@ -1163,10 +1140,11 @@ static void
gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
{
tree tmp;
tree arg;
tree arg2;
tree type;
tree args[2];
gfc_conv_intrinsic_function_args (se, expr, args, 2);
arg = gfc_conv_intrinsic_function_args (se, expr);
if (expr->ts.type == BT_REAL)
{
switch (expr->ts.kind)
......@@ -1184,20 +1162,22 @@ gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
default:
gcc_unreachable ();
}
se->expr = build_call_expr (tmp, 2, args[0], args[1]);
se->expr = build_function_call_expr (tmp, arg);
return;
}
/* Having excluded floating point types, we know we are now dealing
with signed integer types. */
type = TREE_TYPE (args[0]);
arg2 = TREE_VALUE (TREE_CHAIN (arg));
arg = TREE_VALUE (arg);
type = TREE_TYPE (arg);
/* Args[0] is used multiple times below. */
args[0] = gfc_evaluate_now (args[0], &se->pre);
/* Arg is used multiple times below. */
arg = gfc_evaluate_now (arg, &se->pre);
/* Construct (A ^ B) >> 31, which generates a bit mask of all zeros if
the signs of A and B are the same, and of all ones if they differ. */
tmp = fold_build2 (BIT_XOR_EXPR, type, args[0], args[1]);
tmp = fold_build2 (BIT_XOR_EXPR, type, arg, arg2);
tmp = fold_build2 (RSHIFT_EXPR, type, tmp,
build_int_cst (type, TYPE_PRECISION (type) - 1));
tmp = gfc_evaluate_now (tmp, &se->pre);
......@@ -1205,7 +1185,7 @@ gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
/* Construct (A + tmp) ^ tmp, which is A if tmp is zero, and -A if tmp]
is all ones (i.e. -1). */
se->expr = fold_build2 (BIT_XOR_EXPR, type,
fold_build2 (PLUS_EXPR, type, args[0], tmp),
fold_build2 (PLUS_EXPR, type, arg, tmp),
tmp);
}
......@@ -1229,16 +1209,19 @@ gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
static void
gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
{
tree arg;
tree arg2;
tree type;
tree args[2];
gfc_conv_intrinsic_function_args (se, expr, args, 2);
arg = gfc_conv_intrinsic_function_args (se, expr);
arg2 = TREE_VALUE (TREE_CHAIN (arg));
arg = TREE_VALUE (arg);
/* Convert the args to double precision before multiplying. */
type = gfc_typenode_for_spec (&expr->ts);
args[0] = convert (type, args[0]);
args[1] = convert (type, args[1]);
se->expr = build2 (MULT_EXPR, type, args[0], args[1]);
arg = convert (type, arg);
arg2 = convert (type, arg2);
se->expr = build2 (MULT_EXPR, type, arg, arg2);
}
......@@ -1251,7 +1234,8 @@ gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
tree var;
tree type;
gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
arg = gfc_conv_intrinsic_function_args (se, expr);
arg = TREE_VALUE (arg);
/* We currently don't support character types != 1. */
gcc_assert (expr->ts.kind == 1);
......@@ -1271,27 +1255,21 @@ gfc_conv_intrinsic_ctime (gfc_se * se, gfc_expr * expr)
tree var;
tree len;
tree tmp;
tree arglist;
tree type;
tree cond;
tree gfc_int8_type_node = gfc_get_int_type (8);
tree fndecl;
tree *args;
unsigned int num_args;
num_args = gfc_intrinsic_argument_list_length (expr) + 2;
args = alloca (sizeof (tree) * num_args);
type = build_pointer_type (gfc_character1_type_node);
var = gfc_create_var (type, "pstr");
len = gfc_create_var (gfc_int8_type_node, "len");
gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
args[0] = build_fold_addr_expr (var);
args[1] = build_fold_addr_expr (len);
tmp = gfc_conv_intrinsic_function_args (se, expr);
arglist = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (var));
arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
arglist = chainon (arglist, tmp);
fndecl = build_addr (gfor_fndecl_ctime, current_function_decl);
tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_ctime)),
fndecl, num_args, args);
tmp = build_function_call_expr (gfor_fndecl_ctime, arglist);
gfc_add_expr_to_block (&se->pre, tmp);
/* Free the temporary afterwards, if necessary. */
......@@ -1312,27 +1290,21 @@ gfc_conv_intrinsic_fdate (gfc_se * se, gfc_expr * expr)
tree var;
tree len;
tree tmp;
tree arglist;
tree type;
tree cond;
tree gfc_int4_type_node = gfc_get_int_type (4);
tree fndecl;
tree *args;
unsigned int num_args;
num_args = gfc_intrinsic_argument_list_length (expr) + 2;
args = alloca (sizeof (tree) * num_args);
type = build_pointer_type (gfc_character1_type_node);
var = gfc_create_var (type, "pstr");
len = gfc_create_var (gfc_int4_type_node, "len");
gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
args[0] = build_fold_addr_expr (var);
args[1] = build_fold_addr_expr (len);
tmp = gfc_conv_intrinsic_function_args (se, expr);
arglist = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (var));
arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
arglist = chainon (arglist, tmp);
fndecl = build_addr (gfor_fndecl_fdate, current_function_decl);
tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_fdate)),
fndecl, num_args, args);
tmp = build_function_call_expr (gfor_fndecl_fdate, arglist);
gfc_add_expr_to_block (&se->pre, tmp);
/* Free the temporary afterwards, if necessary. */
......@@ -1355,27 +1327,21 @@ gfc_conv_intrinsic_ttynam (gfc_se * se, gfc_expr * expr)
tree var;
tree len;
tree tmp;
tree arglist;
tree type;
tree cond;
tree fndecl;
tree gfc_int4_type_node = gfc_get_int_type (4);
tree *args;
unsigned int num_args;
num_args = gfc_intrinsic_argument_list_length (expr) + 2;
args = alloca (sizeof (tree) * num_args);
type = build_pointer_type (gfc_character1_type_node);
var = gfc_create_var (type, "pstr");
len = gfc_create_var (gfc_int4_type_node, "len");
gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
args[0] = build_fold_addr_expr (var);
args[1] = build_fold_addr_expr (len);
tmp = gfc_conv_intrinsic_function_args (se, expr);
arglist = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (var));
arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
arglist = chainon (arglist, tmp);
fndecl = build_addr (gfor_fndecl_ttynam, current_function_decl);
tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_ttynam)),
fndecl, num_args, args);
tmp = build_function_call_expr (gfor_fndecl_ttynam, arglist);
gfc_add_expr_to_block (&se->pre, tmp);
/* Free the temporary afterwards, if necessary. */
......@@ -1415,18 +1381,13 @@ gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, int op)
tree val;
tree thencase;
tree elsecase;
tree arg;
tree type;
tree *args;
unsigned int num_args;
unsigned int i;
num_args = gfc_intrinsic_argument_list_length (expr);
args = alloca (sizeof (tree) * num_args);
gfc_conv_intrinsic_function_args (se, expr, args, num_args);
arg = gfc_conv_intrinsic_function_args (se, expr);
type = gfc_typenode_for_spec (&expr->ts);
limit = args[0];
limit = TREE_VALUE (arg);
if (TREE_TYPE (limit) != type)
limit = convert (type, limit);
/* Only evaluate the argument once. */
......@@ -1435,9 +1396,9 @@ gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, int op)
mvar = gfc_create_var (type, "M");
elsecase = build2_v (MODIFY_EXPR, mvar, limit);
for (i = 1; i < num_args; i++)
for (arg = TREE_CHAIN (arg); arg != NULL_TREE; arg = TREE_CHAIN (arg))
{
val = args[i];
val = TREE_VALUE (arg);
if (TREE_TYPE (val) != type)
val = convert (type, val);
......@@ -2301,15 +2262,18 @@ gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, int op)
static void
gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
{
tree args[2];
tree arg;
tree arg2;
tree type;
tree tmp;
gfc_conv_intrinsic_function_args (se, expr, args, 2);
type = TREE_TYPE (args[0]);
arg = gfc_conv_intrinsic_function_args (se, expr);
arg2 = TREE_VALUE (TREE_CHAIN (arg));
arg = TREE_VALUE (arg);
type = TREE_TYPE (arg);
tmp = build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
tmp = build2 (BIT_AND_EXPR, type, args[0], tmp);
tmp = build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), arg2);
tmp = build2 (BIT_AND_EXPR, type, arg, tmp);
tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp,
build_int_cst (type, 0));
type = gfc_typenode_for_spec (&expr->ts);
......@@ -2320,10 +2284,16 @@ gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
static void
gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, int op)
{
tree args[2];
tree arg;
tree arg2;
tree type;
arg = gfc_conv_intrinsic_function_args (se, expr);
arg2 = TREE_VALUE (TREE_CHAIN (arg));
arg = TREE_VALUE (arg);
type = TREE_TYPE (arg);
gfc_conv_intrinsic_function_args (se, expr, args, 2);
se->expr = fold_build2 (op, TREE_TYPE (args[0]), args[0], args[1]);
se->expr = fold_build2 (op, type, arg, arg2);
}
/* Bitwise not. */
......@@ -2332,7 +2302,9 @@ gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
{
tree arg;
gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
arg = gfc_conv_intrinsic_function_args (se, expr);
arg = TREE_VALUE (arg);
se->expr = build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
}
......@@ -2340,15 +2312,18 @@ gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
static void
gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
{
tree args[2];
tree arg;
tree arg2;
tree type;
tree tmp;
int op;
gfc_conv_intrinsic_function_args (se, expr, args, 2);
type = TREE_TYPE (args[0]);
arg = gfc_conv_intrinsic_function_args (se, expr);
arg2 = TREE_VALUE (TREE_CHAIN (arg));
arg = TREE_VALUE (arg);
type = TREE_TYPE (arg);
tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), arg2);
if (set)
op = BIT_IOR_EXPR;
else
......@@ -2356,7 +2331,7 @@ gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
op = BIT_AND_EXPR;
tmp = fold_build1 (BIT_NOT_EXPR, type, tmp);
}
se->expr = fold_build2 (op, type, args[0], tmp);
se->expr = fold_build2 (op, type, arg, tmp);
}
/* Extract a sequence of bits.
......@@ -2364,19 +2339,25 @@ gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
static void
gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
{
tree args[3];
tree arg;
tree arg2;
tree arg3;
tree type;
tree tmp;
tree mask;
gfc_conv_intrinsic_function_args (se, expr, args, 3);
type = TREE_TYPE (args[0]);
arg = gfc_conv_intrinsic_function_args (se, expr);
arg2 = TREE_CHAIN (arg);
arg3 = TREE_VALUE (TREE_CHAIN (arg2));
arg = TREE_VALUE (arg);
arg2 = TREE_VALUE (arg2);
type = TREE_TYPE (arg);
mask = build_int_cst (type, -1);
mask = build2 (LSHIFT_EXPR, type, mask, args[2]);
mask = build2 (LSHIFT_EXPR, type, mask, arg3);
mask = build1 (BIT_NOT_EXPR, type, mask);
tmp = build2 (RSHIFT_EXPR, type, args[0], args[1]);
tmp = build2 (RSHIFT_EXPR, type, arg, arg2);
se->expr = fold_build2 (BIT_AND_EXPR, type, tmp, mask);
}
......@@ -2386,12 +2367,15 @@ gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
static void
gfc_conv_intrinsic_rlshift (gfc_se * se, gfc_expr * expr, int right_shift)
{
tree args[2];
tree arg;
tree arg2;
gfc_conv_intrinsic_function_args (se, expr, args, 2);
arg = gfc_conv_intrinsic_function_args (se, expr);
arg2 = TREE_VALUE (TREE_CHAIN (arg));
arg = TREE_VALUE (arg);
se->expr = fold_build2 (right_shift ? RSHIFT_EXPR : LSHIFT_EXPR,
TREE_TYPE (args[0]), args[0], args[1]);
TREE_TYPE (arg), arg, arg2);
}
/* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
......@@ -2401,7 +2385,8 @@ gfc_conv_intrinsic_rlshift (gfc_se * se, gfc_expr * expr, int right_shift)
static void
gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
{
tree args[2];
tree arg;
tree arg2;
tree type;
tree utype;
tree tmp;
......@@ -2411,14 +2396,16 @@ gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
tree lshift;
tree rshift;
gfc_conv_intrinsic_function_args (se, expr, args, 2);
type = TREE_TYPE (args[0]);
arg = gfc_conv_intrinsic_function_args (se, expr);
arg2 = TREE_VALUE (TREE_CHAIN (arg));
arg = TREE_VALUE (arg);
type = TREE_TYPE (arg);
utype = unsigned_type_for (type);
width = fold_build1 (ABS_EXPR, TREE_TYPE (args[1]), args[1]);
width = fold_build1 (ABS_EXPR, TREE_TYPE (arg2), arg2);
/* Left shift if positive. */
lshift = fold_build2 (LSHIFT_EXPR, type, args[0], width);
lshift = fold_build2 (LSHIFT_EXPR, type, arg, width);
/* Right shift if negative.
We convert to an unsigned type because we want a logical shift.
......@@ -2426,16 +2413,16 @@ gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
numbers, and we try to be compatible with other compilers, most
notably g77, here. */
rshift = fold_convert (type, build2 (RSHIFT_EXPR, utype,
convert (utype, args[0]), width));
convert (utype, arg), width));
tmp = fold_build2 (GE_EXPR, boolean_type_node, args[1],
build_int_cst (TREE_TYPE (args[1]), 0));
tmp = fold_build2 (GE_EXPR, boolean_type_node, arg2,
build_int_cst (TREE_TYPE (arg2), 0));
tmp = fold_build3 (COND_EXPR, type, tmp, lshift, rshift);
/* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
gcc requires a shift width < BIT_SIZE(I), so we have to catch this
special case. */
num_bits = build_int_cst (TREE_TYPE (args[0]), TYPE_PRECISION (type));
num_bits = build_int_cst (TREE_TYPE (arg2), TYPE_PRECISION (type));
cond = fold_build2 (GE_EXPR, boolean_type_node, width, num_bits);
se->expr = fold_build3 (COND_EXPR, type, cond,
......@@ -2446,37 +2433,38 @@ gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
static void
gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
{
tree *args;
tree arg;
tree arg2;
tree arg3;
tree type;
tree tmp;
tree lrot;
tree rrot;
tree zero;
unsigned int num_args;
num_args = gfc_intrinsic_argument_list_length (expr);
args = alloca (sizeof (tree) * num_args);
gfc_conv_intrinsic_function_args (se, expr, args, num_args);
if (num_args == 3)
arg = gfc_conv_intrinsic_function_args (se, expr);
arg2 = TREE_CHAIN (arg);
arg3 = TREE_CHAIN (arg2);
if (arg3)
{
/* Use a library function for the 3 parameter version. */
tree int4type = gfc_get_int_type (4);
type = TREE_TYPE (args[0]);
type = TREE_TYPE (TREE_VALUE (arg));
/* We convert the first argument to at least 4 bytes, and
convert back afterwards. This removes the need for library
functions for all argument sizes, and function will be
aligned to at least 32 bits, so there's no loss. */
if (expr->ts.kind < 4)
args[0] = convert (int4type, args[0]);
{
tmp = convert (int4type, TREE_VALUE (arg));
TREE_VALUE (arg) = tmp;
}
/* Convert the SHIFT and SIZE args to INTEGER*4 otherwise we would
need loads of library functions. They cannot have values >
BIT_SIZE (I) so the conversion is safe. */
args[1] = convert (int4type, args[1]);
args[2] = convert (int4type, args[2]);
TREE_VALUE (arg2) = convert (int4type, TREE_VALUE (arg2));
TREE_VALUE (arg3) = convert (int4type, TREE_VALUE (arg3));
switch (expr->ts.kind)
{
......@@ -2494,7 +2482,7 @@ gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
default:
gcc_unreachable ();
}
se->expr = build_call_expr (tmp, 3, args[0], args[1], args[2]);
se->expr = build_function_call_expr (tmp, arg);
/* Convert the result back to the original type, if we extended
the first argument's width above. */
if (expr->ts.kind < 4)
......@@ -2502,22 +2490,24 @@ gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
return;
}
type = TREE_TYPE (args[0]);
arg = TREE_VALUE (arg);
arg2 = TREE_VALUE (arg2);
type = TREE_TYPE (arg);
/* Rotate left if positive. */
lrot = fold_build2 (LROTATE_EXPR, type, args[0], args[1]);
lrot = fold_build2 (LROTATE_EXPR, type, arg, arg2);
/* Rotate right if negative. */
tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (args[1]), args[1]);
rrot = fold_build2 (RROTATE_EXPR, type, args[0], tmp);
tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (arg2), arg2);
rrot = fold_build2 (RROTATE_EXPR, type, arg, tmp);
zero = build_int_cst (TREE_TYPE (args[1]), 0);
tmp = fold_build2 (GT_EXPR, boolean_type_node, args[1], zero);
zero = build_int_cst (TREE_TYPE (arg2), 0);
tmp = fold_build2 (GT_EXPR, boolean_type_node, arg2, zero);
rrot = fold_build3 (COND_EXPR, type, tmp, lrot, rrot);
/* Do nothing if shift == 0. */
tmp = fold_build2 (EQ_EXPR, boolean_type_node, args[1], zero);
se->expr = fold_build3 (COND_EXPR, type, tmp, args[0], rrot);
tmp = fold_build2 (EQ_EXPR, boolean_type_node, arg2, zero);
se->expr = fold_build3 (COND_EXPR, type, tmp, arg, rrot);
}
/* The length of a character string. */
......@@ -2590,12 +2580,12 @@ gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
static void
gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
{
tree args[2];
tree args;
tree type;
gfc_conv_intrinsic_function_args (se, expr, args, 2);
args = gfc_conv_intrinsic_function_args (se, expr);
type = gfc_typenode_for_spec (&expr->ts);
se->expr = build_call_expr (gfor_fndecl_string_len_trim, 2, args[0], args[1]);
se->expr = build_function_call_expr (gfor_fndecl_string_len_trim, args);
se->expr = convert (type, se->expr);
}
......@@ -2606,45 +2596,44 @@ static void
gfc_conv_intrinsic_index (gfc_se * se, gfc_expr * expr)
{
tree logical4_type_node = gfc_get_logical_type (4);
tree args;
tree back;
tree type;
tree fndecl;
tree *args;
unsigned int num_args;
num_args = gfc_intrinsic_argument_list_length (expr);
args = alloca (sizeof (tree) * 5);
tree tmp;
gfc_conv_intrinsic_function_args (se, expr, args, num_args);
args = gfc_conv_intrinsic_function_args (se, expr);
type = gfc_typenode_for_spec (&expr->ts);
if (num_args == 4)
args[4] = build_int_cst (logical4_type_node, 0);
tmp = gfc_advance_chain (args, 3);
if (TREE_CHAIN (tmp) == NULL_TREE)
{
back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
NULL_TREE);
TREE_CHAIN (tmp) = back;
}
else
{
gcc_assert (num_args == 5);
args[4] = convert (logical4_type_node, args[4]);
back = TREE_CHAIN (tmp);
TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
}
fndecl = build_addr (gfor_fndecl_string_index, current_function_decl);
se->expr = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_string_index)),
fndecl, 5, args);
se->expr = build_function_call_expr (gfor_fndecl_string_index, args);
se->expr = convert (type, se->expr);
}
/* The ascii value for a single character. */
static void
gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
{
tree args[2];
tree arg;
tree type;
gfc_conv_intrinsic_function_args (se, expr, args, 2);
gcc_assert (POINTER_TYPE_P (TREE_TYPE (args[1])));
args[1] = build1 (NOP_EXPR, pchar_type_node, args[1]);
arg = gfc_conv_intrinsic_function_args (se, expr);
arg = TREE_VALUE (TREE_CHAIN (arg));
gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
arg = build1 (NOP_EXPR, pchar_type_node, arg);
type = gfc_typenode_for_spec (&expr->ts);
se->expr = build_fold_indirect_ref (args[1]);
se->expr = build_fold_indirect_ref (arg);
se->expr = convert (type, se->expr);
}
......@@ -2654,33 +2643,32 @@ gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
static void
gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
{
tree arg;
tree tsource;
tree fsource;
tree mask;
tree type;
tree len;
tree *args;
unsigned int num_args;
num_args = gfc_intrinsic_argument_list_length (expr);
args = alloca (sizeof (tree) * num_args);
gfc_conv_intrinsic_function_args (se, expr, args, num_args);
arg = gfc_conv_intrinsic_function_args (se, expr);
if (expr->ts.type != BT_CHARACTER)
{
tsource = args[0];
fsource = args[1];
mask = args[2];
tsource = TREE_VALUE (arg);
arg = TREE_CHAIN (arg);
fsource = TREE_VALUE (arg);
mask = TREE_VALUE (TREE_CHAIN (arg));
}
else
{
/* We do the same as in the non-character case, but the argument
list is different because of the string length arguments. We
also have to set the string length for the result. */
len = args[0];
tsource = args[1];
fsource = args[3];
mask = args[4];
len = TREE_VALUE (arg);
arg = TREE_CHAIN (arg);
tsource = TREE_VALUE (arg);
arg = TREE_CHAIN (TREE_CHAIN (arg));
fsource = TREE_VALUE (arg);
mask = TREE_VALUE (TREE_CHAIN (arg));
se->string_length = len;
}
......@@ -2837,11 +2825,16 @@ static void
gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, int op)
{
tree type;
tree args[4];
tree args;
tree arg2;
args = gfc_conv_intrinsic_function_args (se, expr);
arg2 = TREE_CHAIN (TREE_CHAIN (args));
gfc_conv_intrinsic_function_args (se, expr, args, 4);
se->expr = gfc_build_compare_string (TREE_VALUE (args),
TREE_VALUE (TREE_CHAIN (args)), TREE_VALUE (arg2),
TREE_VALUE (TREE_CHAIN (arg2)));
se->expr = gfc_build_compare_string (args[0], args[1], args[2], args[3]);
type = gfc_typenode_for_spec (&expr->ts);
se->expr = fold_build2 (op, type, se->expr,
build_int_cst (TREE_TYPE (se->expr), 0));
......@@ -2851,20 +2844,20 @@ gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, int op)
static void
gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
{
tree args[3];
tree args;
tree len;
tree type;
tree var;
tree tmp;
gfc_conv_intrinsic_function_args (se, expr, &args[1], 2);
len = args[1];
args = gfc_conv_intrinsic_function_args (se, expr);
len = TREE_VALUE (args);
type = TREE_TYPE (args[2]);
type = TREE_TYPE (TREE_VALUE (TREE_CHAIN (args)));
var = gfc_conv_string_tmp (se, type, len);
args[0] = var;
args = tree_cons (NULL_TREE, var, args);
tmp = build_call_expr (fndecl, 3, args[0], args[1], args[2]);
tmp = build_function_call_expr (fndecl, args);
gfc_add_expr_to_block (&se->pre, tmp);
se->expr = var;
se->string_length = len;
......@@ -3313,28 +3306,27 @@ static void
gfc_conv_intrinsic_scan (gfc_se * se, gfc_expr * expr)
{
tree logical4_type_node = gfc_get_logical_type (4);
tree args;
tree back;
tree type;
tree fndecl;
tree *args;
unsigned int num_args;
num_args = gfc_intrinsic_argument_list_length (expr);
args = alloca (sizeof (tree) * 5);
tree tmp;
gfc_conv_intrinsic_function_args (se, expr, args, num_args);
args = gfc_conv_intrinsic_function_args (se, expr);
type = gfc_typenode_for_spec (&expr->ts);
if (num_args == 4)
args[4] = build_int_cst (logical4_type_node, 0);
tmp = gfc_advance_chain (args, 3);
if (TREE_CHAIN (tmp) == NULL_TREE)
{
back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
NULL_TREE);
TREE_CHAIN (tmp) = back;
}
else
{
gcc_assert (num_args == 5);
args[4] = convert (logical4_type_node, args[4]);
back = TREE_CHAIN (tmp);
TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
}
fndecl = build_addr (gfor_fndecl_string_scan, current_function_decl);
se->expr = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_string_scan)),
fndecl, 5, args);
se->expr = build_function_call_expr (gfor_fndecl_string_scan, args);
se->expr = convert (type, se->expr);
}
......@@ -3347,29 +3339,27 @@ static void
gfc_conv_intrinsic_verify (gfc_se * se, gfc_expr * expr)
{
tree logical4_type_node = gfc_get_logical_type (4);
tree args;
tree back;
tree type;
tree fndecl;
tree *args;
unsigned int num_args;
num_args = gfc_intrinsic_argument_list_length (expr);
args = alloca (sizeof (tree) * 5);
tree tmp;
gfc_conv_intrinsic_function_args (se, expr, args, num_args);
args = gfc_conv_intrinsic_function_args (se, expr);
type = gfc_typenode_for_spec (&expr->ts);
if (num_args == 4)
args[4] = build_int_cst (logical4_type_node, 0);
tmp = gfc_advance_chain (args, 3);
if (TREE_CHAIN (tmp) == NULL_TREE)
{
back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
NULL_TREE);
TREE_CHAIN (tmp) = back;
}
else
{
gcc_assert (num_args == 5);
args[4] = convert (logical4_type_node, args[4]);
back = TREE_CHAIN (tmp);
TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
}
fndecl = build_addr (gfor_fndecl_string_verify, current_function_decl);
se->expr = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_string_verify)),
fndecl, 5, args);
se->expr = build_function_call_expr (gfor_fndecl_string_verify, args);
se->expr = convert (type, se->expr);
}
......@@ -3379,11 +3369,12 @@ gfc_conv_intrinsic_verify (gfc_se * se, gfc_expr * expr)
static void
gfc_conv_intrinsic_si_kind (gfc_se * se, gfc_expr * expr)
{
tree arg;
tree args;
gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
arg = build_fold_addr_expr (arg);
se->expr = build_call_expr (gfor_fndecl_si_kind, 1, arg);
args = gfc_conv_intrinsic_function_args (se, expr);
args = TREE_VALUE (args);
args = build_fold_addr_expr (args);
se->expr = build_call_expr (gfor_fndecl_si_kind, 1, args);
}
/* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
......@@ -3424,27 +3415,23 @@ gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
tree len;
tree addr;
tree tmp;
tree arglist;
tree type;
tree cond;
tree fndecl;
tree *args;
unsigned int num_args;
num_args = gfc_intrinsic_argument_list_length (expr) + 2;
args = alloca (sizeof (tree) * num_args);
arglist = NULL_TREE;
type = build_pointer_type (gfc_character1_type_node);
var = gfc_create_var (type, "pstr");
addr = gfc_build_addr_expr (ppvoid_type_node, var);
len = gfc_create_var (gfc_int4_type_node, "len");
gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
args[0] = build_fold_addr_expr (len);
args[1] = addr;
tmp = gfc_conv_intrinsic_function_args (se, expr);
arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
arglist = gfc_chainon_list (arglist, addr);
arglist = chainon (arglist, tmp);
fndecl = build_addr (gfor_fndecl_string_trim, current_function_decl);
tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_string_trim)),
fndecl, num_args, args);
tmp = build_function_call_expr (gfor_fndecl_string_trim, arglist);
gfc_add_expr_to_block (&se->pre, tmp);
/* Free the temporary afterwards, if necessary. */
......@@ -3464,16 +3451,18 @@ gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
static void
gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
{
tree args[3], ncopies, dest, dlen, src, slen, ncopies_type;
tree args, ncopies, dest, dlen, src, slen, ncopies_type;
tree type, cond, tmp, count, exit_label, n, max, largest;
stmtblock_t block, body;
int i;
/* Get the arguments. */
gfc_conv_intrinsic_function_args (se, expr, args, 3);
slen = fold_convert (size_type_node, gfc_evaluate_now (args[0], &se->pre));
src = args[1];
ncopies = gfc_evaluate_now (args[2], &se->pre);
args = gfc_conv_intrinsic_function_args (se, expr);
slen = fold_convert (size_type_node, gfc_evaluate_now (TREE_VALUE (args),
&se->pre));
src = TREE_VALUE (TREE_CHAIN (args));
ncopies = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)));
ncopies = gfc_evaluate_now (ncopies, &se->pre);
ncopies_type = TREE_TYPE (ncopies);
/* Check that NCOPIES is not negative. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment