1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-18 15:30:21 +00:00

Updated the sources to gcc 2.6.3 with FreeBSD changes already applied.

Note: This isn't the most correct way, but it works and it's fast.
This commit is contained in:
Nate Williams 1995-03-11 03:51:44 +00:00
parent fc20488fba
commit b18f8c1dda
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=6996
28 changed files with 7552 additions and 3640 deletions

View File

@ -1,5 +1,5 @@
#
# $Id: Makefile.inc,v 1.11 1995/03/05 20:34:30 phk Exp $
# $Id: Makefile.inc,v 1.12 1995/03/10 19:39:32 davidg Exp $
#
CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../include
@ -7,7 +7,7 @@ CFLAGS+= -Dbsd4_4
CFLAGS+= -DGCC_INCLUDE_DIR=\"FOO\"
CFLAGS+= -DTOOL_INCLUDE_DIR=\"FOO\"
CFLAGS+= -DGPLUSPLUS_INCLUDE_DIR=\"FOO\"
CFLAGS+= -DDEFAULT_TARGET_VERSION=\"2.6.2\"
CFLAGS+= -DDEFAULT_TARGET_VERSION=\"2.6.3\"
CFLAGS+= -DDEFAULT_TARGET_MACHINE=\"i386--freebsd\"
CFLAGS+= -DSTANDARD_EXEC_PREFIX=\"/usr/libexec/\"
CFLAGS+= -DSTANDARD_STARTFILE_PREFIX=\"/usr/lib/\"
@ -24,7 +24,7 @@ LIBDESTDIR= ${.CURDIR}/../cc_int
# XXX LDDESTDIR isn't a directory and there is no standard name for the dir
LDDESTDIR= -L${LIBDESTDIR}
.if defined(SHARED_LIBCC_INT)
LIBCC_INT= ${LIBDESTDIR}/libcc_int.so.262.0
LIBCC_INT= ${LIBDESTDIR}/libcc_int.so.263.0
.else
LIBCC_INT= ${LIBDESTDIR}/libcc_int.a
.endif

View File

@ -525,13 +525,6 @@ convert_harshness (type, parmtype, parm)
else
penalty = 2;
if (TREE_UNSIGNED (ttl) ^ TREE_UNSIGNED (intype))
{
ttl = unsigned_type (ttl);
intype = unsigned_type (intype);
penalty += 2;
}
ttr = intype;
/* If the initializer is not an lvalue, then it does not
@ -551,6 +544,13 @@ convert_harshness (type, parmtype, parm)
return h;
}
if (TREE_UNSIGNED (ttl) ^ TREE_UNSIGNED (intype))
{
ttl = unsigned_type (ttl);
ttr = intype = unsigned_type (intype);
penalty += 2;
}
if (ttl == ttr)
{
if (penalty > 2)

View File

@ -663,10 +663,12 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
if (form == REFERENCE_TYPE)
{
rval = copy_node (expr);
TREE_TYPE (rval) = build_pointer_type (TREE_TYPE (TREE_TYPE (expr)));
rval = cp_convert (build_pointer_type (TREE_TYPE (reftype)), rval,
tree type = TREE_TYPE (expr);
tree tmp = copy_node (expr);
TREE_TYPE (tmp) = build_pointer_type (TREE_TYPE (TREE_TYPE (expr)));
rval = cp_convert (build_pointer_type (TREE_TYPE (reftype)), tmp,
convtype, flags);
TREE_TYPE (tmp) = type;
TREE_TYPE (rval) = reftype;
return rval;
}
@ -1283,12 +1285,9 @@ cp_convert (type, expr, convtype, flags)
if (IS_AGGR_TYPE_CODE (code))
{
tree dtype = TREE_TYPE (e);
tree ctor = NULL_TREE;
tree conversion = NULL_TREE;
if (TREE_CODE (dtype) == REFERENCE_TYPE)
{
e = convert_from_reference (e);
dtype = TREE_TYPE (e);
}
dtype = TYPE_MAIN_VARIANT (dtype);
/* Conversion of object pointers or signature pointers/references
@ -1321,87 +1320,77 @@ cp_convert (type, expr, convtype, flags)
There may be some ambiguity between using a constructor
vs. using a type conversion operator when both apply. */
else if (IS_AGGR_TYPE (dtype))
if (IS_AGGR_TYPE (dtype) && ! DERIVED_FROM_P (type, dtype)
&& TYPE_HAS_CONVERSION (dtype))
conversion = build_type_conversion (CONVERT_EXPR, type, e, 1);
if (conversion == error_mark_node)
{
tree binfo;
error ("ambiguous pointer conversion");
return conversion;
}
tree conversion;
if (TYPE_HAS_CONSTRUCTOR (type))
ctor = build_method_call (NULL_TREE, constructor_name_full (type),
build_tree_list (NULL_TREE, e),
TYPE_BINFO (type),
LOOKUP_NORMAL | LOOKUP_SPECULATIVELY
| (conversion ? LOOKUP_NO_CONVERSION : 0));
if (! DERIVED_FROM_P (type, dtype) && TYPE_HAS_CONVERSION (dtype))
conversion = build_type_conversion (CONVERT_EXPR, type, e, 1);
else
conversion = NULL_TREE;
if (TYPE_HAS_CONSTRUCTOR (type))
{
tree rval = build_method_call (NULL_TREE, constructor_name_full (type),
build_tree_list (NULL_TREE, e),
TYPE_BINFO (type),
conversion ? LOOKUP_NO_CONVERSION : 0);
if (rval != error_mark_node)
{
if (conversion)
{
error ("both constructor and type conversion operator apply");
return error_mark_node;
}
/* call to constructor successful. */
rval = build_cplus_new (type, rval, 1);
return rval;
}
}
/* Type conversion successful/applies. */
if (conversion)
{
if (conversion == error_mark_node)
error ("ambiguous pointer conversion");
return conversion;
}
/* now try normal C++ assignment semantics. */
binfo = TYPE_BINFO (dtype);
if (BINFO_TYPE (binfo) == type
|| (binfo = get_binfo (type, dtype, 1)))
{
if (binfo == error_mark_node)
return error_mark_node;
}
if (binfo != NULL_TREE)
{
if (lvalue_p (e))
{
e = build_unary_op (ADDR_EXPR, e, 0);
if (! BINFO_OFFSET_ZEROP (binfo))
e = build (PLUS_EXPR, TYPE_POINTER_TO (type),
e, BINFO_OFFSET (binfo));
return build1 (INDIRECT_REF, type, e);
}
sorry ("addressable aggregates");
return error_mark_node;
}
error ("conversion between incompatible aggregate types requested");
if (ctor == error_mark_node)
{
cp_error ("in conversion to type `%T'", type);
return error_mark_node;
}
/* conversion from non-aggregate to aggregate type requires
constructor. */
else if (TYPE_HAS_CONSTRUCTOR (type))
if (conversion && ctor)
{
tree rval;
tree init = build_method_call (NULL_TREE, constructor_name_full (type),
build_tree_list (NULL_TREE, e),
TYPE_BINFO (type), LOOKUP_NORMAL);
if (init == error_mark_node)
error ("both constructor and type conversion operator apply");
return error_mark_node;
}
else if (conversion)
return conversion;
else if (ctor)
{
if (current_function_decl)
/* We can't pass 1 to the with_cleanup_p arg here, because that
screws up passing classes by value. */
ctor = build_cplus_new (type, ctor, 0);
else
{
cp_error ("in conversion to type `%T'", type);
return error_mark_node;
register tree parm = TREE_OPERAND (ctor, 1);
/* Initializers for static variables and parameters
have to handle doing the initialization and
cleanup themselves. */
my_friendly_assert (TREE_CODE (ctor) == CALL_EXPR, 322);
#if 0
/* The following assertion fails in cases where we
are initializing a static member variable of a
particular instance of a template class with a
call to a constructor of the given instance, as
in:
TMPL<int> object = TMPL<int>();
Curiously, the assertion does not fail if we do
the same thing for a static member of a
non-template class, as in:
T object = T();
I can't see why we should care here whether or not
the initializer expression involves a call to
`new', so for the time being, it seems best to
just avoid doing this assertion. */
my_friendly_assert (TREE_CALLS_NEW (TREE_VALUE (parm)),
323);
#endif
TREE_VALUE (parm) = NULL_TREE;
ctor = build_indirect_ref (ctor, NULL_PTR);
TREE_HAS_CONSTRUCTOR (ctor) = 1;
}
/* We can't pass 1 to the with_cleanup_p arg here, because that
screws up passing classes by value. */
rval = build_cplus_new (type, init, 0);
return rval;
return ctor;
}
}

View File

@ -11072,7 +11072,7 @@ finish_function (lineno, call_poplevel)
store_parm_decls ();
}
if (write_symbols != NO_DEBUG && TREE_CODE (fntype) != METHOD_TYPE)
if (write_symbols != NO_DEBUG /*&& TREE_CODE (fntype) != METHOD_TYPE*/)
{
tree ttype = target_type (fntype);
tree parmdecl;

View File

@ -514,6 +514,7 @@ build_overload_name (parmtypes, begin, end)
tree parmtype;
if (begin) OB_INIT ();
numeric_outputed_need_bar = 0;
if ((just_one = (TREE_CODE (parmtypes) != TREE_LIST)))
{
@ -920,7 +921,6 @@ build_decl_overload (dname, parms, for_method)
{
ALLOCATE_TYPEVEC (parms);
nofold = 0;
numeric_outputed_need_bar = 0;
if (for_method)
{
build_overload_name (TREE_VALUE (parms), 0, 0);

File diff suppressed because it is too large Load Diff

View File

@ -1116,15 +1116,11 @@ lookup_nested_type_by_name (ctype, name)
{
tree t;
t = TREE_VALUE(CLASSTYPE_TAGS(ctype));
while (t)
{
if (strcmp(IDENTIFIER_POINTER(name), IDENTIFIER_POINTER(TYPE_IDENTIFIER(t)))
== 0)
return t;
else
t = TREE_CHAIN(t);
}
for (t = CLASSTYPE_TAGS (ctype); t; t = TREE_CHAIN (t))
{
if (name == TREE_PURPOSE (t))
return TREE_VALUE (t);
}
return NULL_TREE;
}
@ -1198,9 +1194,12 @@ tsubst (t, args, nargs, in_decl)
tsubst (TYPE_MAX_VALUE (t), args, nargs, in_decl));
case TEMPLATE_TYPE_PARM:
return cp_build_type_variant (args[TEMPLATE_TYPE_IDX (t)],
TYPE_READONLY (t),
TYPE_VOLATILE (t));
{
tree arg = args[TEMPLATE_TYPE_IDX (t)];
return cp_build_type_variant
(arg, TYPE_READONLY (arg) || TYPE_READONLY (t),
TYPE_VOLATILE (arg) || TYPE_VOLATILE (t));
}
case TEMPLATE_CONST_PARM:
return args[TEMPLATE_CONST_IDX (t)];
@ -2008,6 +2007,9 @@ type_unification (tparms, targs, parms, args, nsubsts, subr)
arg = TREE_TYPE (arg);
}
#endif
if (TREE_CODE (arg) == REFERENCE_TYPE)
arg = TREE_TYPE (arg);
if (TREE_CODE (parm) != REFERENCE_TYPE)
{
if (TREE_CODE (arg) == FUNCTION_TYPE
@ -2068,9 +2070,6 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
if (arg == parm)
return 0;
if (TREE_CODE (arg) == REFERENCE_TYPE)
arg = TREE_TYPE (arg);
switch (TREE_CODE (parm))
{
case TEMPLATE_TYPE_PARM:
@ -2082,6 +2081,7 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
return 1;
}
idx = TEMPLATE_TYPE_IDX (parm);
#if 0
/* Template type parameters cannot contain cv-quals; i.e.
template <class T> void f (T& a, T& b) will not generate
void f (const int& a, const int& b). */
@ -2089,6 +2089,13 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
|| TYPE_VOLATILE (arg) > TYPE_VOLATILE (parm))
return 1;
arg = TYPE_MAIN_VARIANT (arg);
#else
{
int constp = TYPE_READONLY (arg) > TYPE_READONLY (parm);
int volatilep = TYPE_VOLATILE (arg) > TYPE_VOLATILE (parm);
arg = cp_build_type_variant (arg, constp, volatilep);
}
#endif
/* Simple cases: Value already set, does match or doesn't. */
if (targs[idx] == arg)
return 0;
@ -2495,12 +2502,19 @@ do_type_instantiation (name, storage)
rest_of_type_compilation (t, 1);
}
}
instantiate_member_templates (TYPE_IDENTIFIER (t));
/* this should really be done by instantiate_member_templates */
{
tree tmp = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0);
tree tmp;
/* Classes nested in template classes currently don't have an
IDENTIFIER_TEMPLATE--their out-of-line members are handled
by the enclosing template class. Note that there are name
conflict bugs with this approach. */
tmp = TYPE_IDENTIFIER (t);
if (IDENTIFIER_TEMPLATE (tmp))
instantiate_member_templates (tmp);
/* this should really be done by instantiate_member_templates */
tmp = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0);
for (; tmp; tmp = TREE_CHAIN (tmp))
{
if (DECL_TEMPLATE_SPECIALIZATION (tmp)

View File

@ -6742,6 +6742,8 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
}
/* Handle the case of default parameter initialization and
initialization of static variables. */
else if (TREE_CODE (rhs) == TARGET_EXPR)
return rhs;
else if (TREE_CODE (rhs) == INDIRECT_REF && TREE_HAS_CONSTRUCTOR (rhs))
{
my_friendly_assert (TREE_CODE (TREE_OPERAND (rhs, 0)) == CALL_EXPR, 318);

View File

@ -1342,6 +1342,7 @@ build_m_component_ref (datum, component)
if (TREE_CODE (objtype) == REFERENCE_TYPE)
objtype = TREE_TYPE (objtype);
objtype = TYPE_MAIN_VARIANT (objtype);
if (! IS_AGGR_TYPE (objtype))
{

View File

@ -532,7 +532,7 @@ typedef struct {
static format_char_info print_char_table[] = {
{ "di", 0, T_I, T_I, T_L, T_LL, T_LL, "-wp0 +" },
{ "oxX", 0, T_UI, T_UI, T_UL, T_ULL, T_ULL, "-wp0#" },
{ "u", 0, T_UI, T_UI, T_UL, T_ULL, NULL, "-wp0" },
{ "u", 0, T_UI, T_UI, T_UL, T_ULL, T_ULL, "-wp0" },
/* Two GNU extensions. */
{ "Z", 0, T_ST, NULL, NULL, NULL, NULL, "-wp0" },
{ "m", 0, T_UI, T_UI, T_UL, NULL, NULL, "-wp" },

View File

@ -1624,10 +1624,11 @@ expand_call (exp, target, ignore)
&& args[i].mode != BLKmode
&& rtx_cost (args[i].value, SET) > 2
#ifdef SMALL_REGISTER_CLASSES
&& (reg_parm_seen || preserve_subexpressions_p ()))
&& (reg_parm_seen || preserve_subexpressions_p ())
#else
&& preserve_subexpressions_p ())
&& preserve_subexpressions_p ()
#endif
)
args[i].value = copy_to_mode_reg (args[i].mode, args[i].value);
}
@ -1909,6 +1910,14 @@ expand_call (exp, target, ignore)
valreg = temp;
}
else if (is_const)
{
/* Otherwise, just write out the sequence without a note. */
rtx insns = get_insns ();
end_sequence ();
emit_insns (insns);
}
/* For calls to `setjmp', etc., inform flow.c it should complain
if nonvolatile values are live. */

View File

@ -9665,6 +9665,9 @@ static void
record_dead_and_set_regs_1 (dest, setter)
rtx dest, setter;
{
if (GET_CODE (dest) == SUBREG)
dest = SUBREG_REG (dest);
if (GET_CODE (dest) == REG)
{
/* If we are setting the whole register, we know its value. Otherwise

View File

@ -650,7 +650,7 @@ gen_lowpart_common (mode, x)
either a reasonable negative value or a reasonable unsigned value
for this mode. */
if (GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT)
if (GET_MODE_BITSIZE (mode) >= 2 * HOST_BITS_PER_WIDE_INT)
return x;
else if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT)
return 0;

View File

@ -1684,8 +1684,7 @@ expand_shift (code, mode, shifted, amount, target, unsignedp)
continue;
else if (methods == OPTAB_LIB_WIDEN)
{
/* If we are rotating by a constant that is valid and
we have been unable to open-code this by a rotation,
/* If we have been unable to open-code this by a rotation,
do it as the IOR of two shifts. I.e., to rotate A
by N bits, compute (A << N) | ((unsigned) A >> (C - N))
where C is the bitsize of A.
@ -1697,25 +1696,25 @@ expand_shift (code, mode, shifted, amount, target, unsignedp)
this extremely unlikely lossage to avoid complicating the
code below. */
if (GET_CODE (op1) == CONST_INT && INTVAL (op1) > 0
&& INTVAL (op1) < GET_MODE_BITSIZE (mode))
{
rtx subtarget = target == shifted ? 0 : target;
rtx temp1;
tree other_amount
= build_int_2 (GET_MODE_BITSIZE (mode) - INTVAL (op1), 0);
rtx subtarget = target == shifted ? 0 : target;
rtx temp1;
tree type = TREE_TYPE (amount);
tree new_amount = make_tree (type, op1);
tree other_amount
= fold (build (MINUS_EXPR, type,
convert (type,
build_int_2 (GET_MODE_BITSIZE (mode),
0)),
amount));
shifted = force_reg (mode, shifted);
shifted = force_reg (mode, shifted);
temp = expand_shift (left ? LSHIFT_EXPR : RSHIFT_EXPR,
mode, shifted, amount, subtarget, 1);
temp1 = expand_shift (left ? RSHIFT_EXPR : LSHIFT_EXPR,
mode, shifted, other_amount, 0, 1);
return expand_binop (mode, ior_optab, temp, temp1, target,
unsignedp, methods);
}
else
methods = OPTAB_LIB;
temp = expand_shift (left ? LSHIFT_EXPR : RSHIFT_EXPR,
mode, shifted, new_amount, subtarget, 1);
temp1 = expand_shift (left ? RSHIFT_EXPR : LSHIFT_EXPR,
mode, shifted, other_amount, 0, 1);
return expand_binop (mode, ior_optab, temp, temp1, target,
unsignedp, methods);
}
temp = expand_binop (mode,
@ -2608,13 +2607,13 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
Second comes a switch statement with code specific for each rounding mode.
For some special operands this code emits all RTL for the desired
operation, for other cases, it generates a quotient and stores it in
operation, for other cases, it generates only a quotient and stores it in
QUOTIENT. The case for trunc division/remainder might leave quotient = 0,
to indicate that it has not done anything.
Last comes code that finishes the operation. If QUOTIENT is set an
REM_FLAG, the remainder is computed as OP0 - QUOTIENT * OP1. If QUOTIENT
is not set, it is computed using trunc rounding.
Last comes code that finishes the operation. If QUOTIENT is set and
REM_FLAG is set, the remainder is computed as OP0 - QUOTIENT * OP1. If
QUOTIENT is not set, it is computed using trunc rounding.
We try to generate special code for division and remainder when OP1 is a
constant. If |OP1| = 2**n we can use shifts and some other fast
@ -3408,10 +3407,70 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
case ROUND_DIV_EXPR:
case ROUND_MOD_EXPR:
/* The code that used to be here was wrong, and nothing really
depends on it. */
abort ();
break;
if (unsignedp)
{
rtx tem;
rtx label;
label = gen_label_rtx ();
quotient = gen_reg_rtx (compute_mode);
remainder = gen_reg_rtx (compute_mode);
if (expand_twoval_binop (udivmod_optab, op0, op1, quotient, remainder, 1) == 0)
{
rtx tem;
quotient = expand_binop (compute_mode, udiv_optab, op0, op1,
quotient, 1, OPTAB_LIB_WIDEN);
tem = expand_mult (compute_mode, quotient, op1, NULL_RTX, 1);
remainder = expand_binop (compute_mode, sub_optab, op0, tem,
remainder, 1, OPTAB_LIB_WIDEN);
}
tem = plus_constant (op1, -1);
tem = expand_shift (RSHIFT_EXPR, compute_mode, tem,
build_int_2 (1, 0), NULL_RTX, 1);
emit_cmp_insn (remainder, tem, LEU, NULL_RTX, compute_mode, 0, 0);
emit_jump_insn (gen_bleu (label));
expand_inc (quotient, const1_rtx);
expand_dec (remainder, op1);
emit_label (label);
}
else
{
rtx abs_rem, abs_op1, tem, mask;
rtx label;
label = gen_label_rtx ();
quotient = gen_reg_rtx (compute_mode);
remainder = gen_reg_rtx (compute_mode);
if (expand_twoval_binop (sdivmod_optab, op0, op1, quotient, remainder, 0) == 0)
{
rtx tem;
quotient = expand_binop (compute_mode, sdiv_optab, op0, op1,
quotient, 0, OPTAB_LIB_WIDEN);
tem = expand_mult (compute_mode, quotient, op1, NULL_RTX, 0);
remainder = expand_binop (compute_mode, sub_optab, op0, tem,
remainder, 0, OPTAB_LIB_WIDEN);
}
abs_rem = expand_abs (compute_mode, remainder, NULL_RTX, 0, 0);
abs_op1 = expand_abs (compute_mode, op1, NULL_RTX, 0, 0);
tem = expand_shift (LSHIFT_EXPR, compute_mode, abs_rem,
build_int_2 (1, 0), NULL_RTX, 1);
emit_cmp_insn (tem, abs_op1, LTU, NULL_RTX, compute_mode, 0, 0);
emit_jump_insn (gen_bltu (label));
tem = expand_binop (compute_mode, xor_optab, op0, op1,
NULL_RTX, 0, OPTAB_WIDEN);
mask = expand_shift (RSHIFT_EXPR, compute_mode, tem,
build_int_2 (size - 1, 0), NULL_RTX, 0);
tem = expand_binop (compute_mode, xor_optab, mask, const1_rtx,
NULL_RTX, 0, OPTAB_WIDEN);
tem = expand_binop (compute_mode, sub_optab, tem, mask,
NULL_RTX, 0, OPTAB_WIDEN);
expand_inc (quotient, tem);
tem = expand_binop (compute_mode, xor_optab, mask, op1,
NULL_RTX, 0, OPTAB_WIDEN);
tem = expand_binop (compute_mode, sub_optab, tem, mask,
NULL_RTX, 0, OPTAB_WIDEN);
expand_dec (remainder, tem);
emit_label (label);
}
return gen_lowpart (mode, rem_flag ? remainder : quotient);
}
if (quotient == 0)

View File

@ -180,7 +180,7 @@ void bc_load_localaddr PROTO((rtx));
void bc_load_parmaddr PROTO((rtx));
static void preexpand_calls PROTO((tree));
static void do_jump_by_parts_greater PROTO((tree, int, rtx, rtx));
static void do_jump_by_parts_greater_rtx PROTO((enum machine_mode, int, rtx, rtx, rtx, rtx));
void do_jump_by_parts_greater_rtx PROTO((enum machine_mode, int, rtx, rtx, rtx, rtx));
static void do_jump_by_parts_equality PROTO((tree, rtx, rtx));
static void do_jump_by_parts_equality_rtx PROTO((rtx, rtx, rtx));
static void do_jump_for_compare PROTO((rtx, rtx, rtx));
@ -916,6 +916,12 @@ convert_move (to, from, unsignedp)
/* No special multiword conversion insn; do it by hand. */
start_sequence ();
/* Since we will turn this into a no conflict block, we must ensure
that the source does not overlap the target. */
if (reg_overlap_mentioned_p (to, from))
from = force_reg (from_mode, from);
/* Get a copy of FROM widened to a word, if necessary. */
if (GET_MODE_BITSIZE (from_mode) < BITS_PER_WORD)
lowpart_mode = word_mode;
@ -1630,7 +1636,10 @@ emit_block_move (x, y, size, align)
here because if SIZE is less than the mode mask, as it is
returned by the macro, it will definitely be less than the
actual mode mask. */
&& (unsigned HOST_WIDE_INT) INTVAL (size) <= GET_MODE_MASK (mode)
&& ((GET_CODE (size) == CONST_INT
&& ((unsigned HOST_WIDE_INT) INTVAL (size)
<= GET_MODE_MASK (mode)))
|| GET_MODE_BITSIZE (mode) >= BITS_PER_WORD)
&& (insn_operand_predicate[(int) code][0] == 0
|| (*insn_operand_predicate[(int) code][0]) (x, BLKmode))
&& (insn_operand_predicate[(int) code][1] == 0
@ -1957,6 +1966,17 @@ emit_move_insn_1 (x, y)
rtx last_insn = 0;
rtx insns;
#ifdef PUSH_ROUNDING
/* If X is a push on the stack, do the push now and replace
X with a reference to the stack pointer. */
if (push_operand (x, GET_MODE (x)))
{
anti_adjust_stack (GEN_INT (GET_MODE_SIZE (GET_MODE (x))));
x = change_address (x, VOIDmode, stack_pointer_rtx);
}
#endif
for (i = 0;
i < (GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
i++)
@ -5216,70 +5236,8 @@ expand_expr (exp, target, tmode, modifier)
if (TREE_UNSIGNED (type))
return op0;
/* First try to do it with a special abs instruction. */
temp = expand_unop (mode, abs_optab, op0, target, 0);
if (temp != 0)
return temp;
/* If this machine has expensive jumps, we can do integer absolute
value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
where W is the width of MODE. */
if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
{
rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
size_int (GET_MODE_BITSIZE (mode) - 1),
NULL_RTX, 0);
temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
OPTAB_LIB_WIDEN);
if (temp != 0)
temp = expand_binop (mode, sub_optab, temp, extended, target, 0,
OPTAB_LIB_WIDEN);
if (temp != 0)
return temp;
}
/* If that does not win, use conditional jump and negate. */
target = original_target;
op1 = gen_label_rtx ();
if (target == 0 || ! safe_from_p (target, TREE_OPERAND (exp, 0))
|| GET_MODE (target) != mode
|| (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
|| (GET_CODE (target) == REG
&& REGNO (target) < FIRST_PSEUDO_REGISTER))
target = gen_reg_rtx (mode);
emit_move_insn (target, op0);
NO_DEFER_POP;
/* If this mode is an integer too wide to compare properly,
compare word by word. Rely on CSE to optimize constant cases. */
if (GET_MODE_CLASS (mode) == MODE_INT && ! can_compare_p (mode))
do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
NULL_RTX, op1);
else
{
temp = compare_from_rtx (target, CONST0_RTX (mode), GE, 0, mode,
NULL_RTX, 0);
if (temp == const1_rtx)
return target;
else if (temp != const0_rtx)
{
if (bcc_gen_fctn[(int) GET_CODE (temp)] != 0)
emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (temp)]) (op1));
else
abort ();
}
}
op0 = expand_unop (mode, neg_optab, target, target, 0);
if (op0 != target)
emit_move_insn (target, op0);
emit_label (op1);
OK_DEFER_POP;
return target;
return expand_abs (mode, op0, target, unsignedp,
safe_from_p (target, TREE_OPERAND (exp, 0)));
case MAX_EXPR:
case MIN_EXPR:
@ -9026,7 +8984,7 @@ do_jump_by_parts_greater (exp, swap, if_false_label, if_true_label)
UNSIGNEDP says to do unsigned comparison.
Jump to IF_TRUE_LABEL if OP0 is greater, IF_FALSE_LABEL otherwise. */
static void
void
do_jump_by_parts_greater_rtx (mode, unsignedp, op0, op1, if_false_label, if_true_label)
enum machine_mode mode;
int unsignedp;

View File

@ -2192,6 +2192,8 @@ find_auto_inc (needed, x, insn)
if (GET_CODE (temp) == CALL_INSN)
reg_n_calls_crossed[regno]++;
}
else
return;
/* If we haven't returned, it means we were able to make the
auto-inc, so update the status. First, record that this insn

View File

@ -1404,6 +1404,11 @@ fold_convert (t, arg1)
{
if (TREE_CODE (arg1) == INTEGER_CST)
{
/* If we would build a constant wider than GCC supports,
leave the conversion unfolded. */
if (TYPE_PRECISION (type) > 2 * HOST_BITS_PER_WIDE_INT)
return t;
/* Given an integer constant, make new constant with new type,
appropriately sign-extended or truncated. */
t = build_int_2 (TREE_INT_CST_LOW (arg1),
@ -2836,14 +2841,12 @@ fold_truthop (code, truth_type, lhs, rhs)
l_const = convert (unsigned_type (TREE_TYPE (l_const)), l_const);
l_const = const_binop (LSHIFT_EXPR, convert (type, l_const),
size_int (xll_bitpos), 0);
l_const = const_binop (BIT_AND_EXPR, l_const, ll_mask, 0);
}
if (r_const)
{
r_const = convert (unsigned_type (TREE_TYPE (r_const)), r_const);
r_const = const_binop (LSHIFT_EXPR, convert (type, r_const),
size_int (xrl_bitpos), 0);
r_const = const_binop (BIT_AND_EXPR, r_const, rl_mask, 0);
}
/* If the right sides are not constant, do the same for it. Also,

View File

@ -1685,6 +1685,8 @@ move_movables (movables, threshold, insn_count, loop_start, end, nregs)
}
p = delete_insn (p);
while (p && GET_CODE (p) == NOTE)
p = NEXT_INSN (p);
}
start_sequence ();

View File

@ -2051,6 +2051,90 @@ expand_unop (mode, unoptab, op0, target, unsignedp)
MODE is the mode of the operand; the mode of the result is
different but can be deduced from MODE.
UNSIGNEDP is relevant if extension is needed. */
rtx
expand_abs (mode, op0, target, unsignedp, safe)
enum machine_mode mode;
rtx op0;
rtx target;
int unsignedp;
int safe;
{
rtx temp, op1;
/* First try to do it with a special abs instruction. */
temp = expand_unop (mode, abs_optab, op0, target, 0);
if (temp != 0)
return temp;
/* If this machine has expensive jumps, we can do integer absolute
value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
where W is the width of MODE. */
if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
{
rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
size_int (GET_MODE_BITSIZE (mode) - 1),
NULL_RTX, 0);
temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
OPTAB_LIB_WIDEN);
if (temp != 0)
temp = expand_binop (mode, sub_optab, temp, extended, target, 0,
OPTAB_LIB_WIDEN);
if (temp != 0)
return temp;
}
/* If that does not win, use conditional jump and negate. */
op1 = gen_label_rtx ();
if (target == 0 || ! safe
|| GET_MODE (target) != mode
|| (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
|| (GET_CODE (target) == REG
&& REGNO (target) < FIRST_PSEUDO_REGISTER))
target = gen_reg_rtx (mode);
emit_move_insn (target, op0);
NO_DEFER_POP;
/* If this mode is an integer too wide to compare properly,
compare word by word. Rely on CSE to optimize constant cases. */
if (GET_MODE_CLASS (mode) == MODE_INT && ! can_compare_p (mode))
do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
NULL_RTX, op1);
else
{
temp = compare_from_rtx (target, CONST0_RTX (mode), GE, 0, mode,
NULL_RTX, 0);
if (temp == const1_rtx)
return target;
else if (temp != const0_rtx)
{
if (bcc_gen_fctn[(int) GET_CODE (temp)] != 0)
emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (temp)]) (op1));
else
abort ();
}
}
op0 = expand_unop (mode, neg_optab, target, target, 0);
if (op0 != target)
emit_move_insn (target, op0);
emit_label (op1);
OK_DEFER_POP;
return target;
}
/* Emit code to compute the absolute value of OP0, with result to
TARGET if convenient. (TARGET may be 0.) The return value says
where the result actually is to be found.
MODE is the mode of the operand; the mode of the result is
different but can be deduced from MODE.
UNSIGNEDP is relevant for complex integer modes. */
rtx
@ -2300,9 +2384,7 @@ emit_unop_insn (icode, target, op0, code)
INSNS is a block of code generated to perform the operation, not including
the CLOBBER and final copy. All insns that compute intermediate values
are first emitted, followed by the block as described above. Only
INSNs are allowed in the block; no library calls or jumps may be
present.
are first emitted, followed by the block as described above.
TARGET, OP0, and OP1 are the output and inputs of the operations,
respectively. OP1 may be zero for a unary operation.
@ -2311,7 +2393,8 @@ emit_unop_insn (icode, target, op0, code)
on the last insn.
If TARGET is not a register, INSNS is simply emitted with no special
processing.
processing. Likewise if anything in INSNS is not an INSN or if
there is a libcall block inside INSNS.
The final insn emitted is returned. */
@ -2326,6 +2409,11 @@ emit_no_conflict_block (insns, target, op0, op1, equiv)
if (GET_CODE (target) != REG || reload_in_progress)
return emit_insns (insns);
else
for (insn = insns; insn; insn = NEXT_INSN (insn))
if (GET_CODE (insn) != INSN
|| find_reg_note (insn, REG_LIBCALL, NULL_RTX))
return emit_insns (insns);
/* First emit all insns that do not store into words of the output and remove
these from the list. */
@ -2336,9 +2424,6 @@ emit_no_conflict_block (insns, target, op0, op1, equiv)
next = NEXT_INSN (insn);
if (GET_CODE (insn) != INSN)
abort ();
if (GET_CODE (PATTERN (insn)) == SET)
set = PATTERN (insn);
else if (GET_CODE (PATTERN (insn)) == PARALLEL)
@ -3861,8 +3946,6 @@ init_optabs ()
init_integral_libfuncs (ashl_optab, "ashl", '3');
init_integral_libfuncs (ashr_optab, "ashr", '3');
init_integral_libfuncs (lshr_optab, "lshr", '3');
init_integral_libfuncs (rotl_optab, "rotl", '3');
init_integral_libfuncs (rotr_optab, "rotr", '3');
init_integral_libfuncs (smin_optab, "min", '3');
init_floating_libfuncs (smin_optab, "min", '3');
init_integral_libfuncs (smax_optab, "max", '3');

View File

@ -244,12 +244,13 @@ static rtx steal_delay_list_from_fallthrough PROTO((rtx, rtx, rtx, rtx,
struct resources *,
int, int *, int *));
static void try_merge_delay_insns PROTO((rtx, rtx));
static int redundant_insn_p PROTO((rtx, rtx, rtx));
static rtx redundant_insn_p PROTO((rtx, rtx, rtx));
static int own_thread_p PROTO((rtx, rtx, int));
static int find_basic_block PROTO((rtx));
static void update_block PROTO((rtx, rtx));
static int reorg_redirect_jump PROTO((rtx, rtx));
static void update_reg_dead_notes PROTO((rtx, rtx));
static void update_reg_unused_notes PROTO((rtx, rtx));
static void update_live_status PROTO((rtx, rtx));
static rtx next_insn_no_annul PROTO((rtx));
static void mark_target_live_regs PROTO((rtx, struct resources *));
@ -1922,7 +1923,7 @@ try_merge_delay_insns (insn, thread)
redundant insn, but the cost of splitting seems greater than the possible
gain in rare cases. */
static int
static rtx
redundant_insn_p (insn, target, delay_list)
rtx insn;
rtx target;
@ -2079,7 +2080,7 @@ redundant_insn_p (insn, target, delay_list)
{
/* Show that this insn will be used in the sequel. */
INSN_FROM_TARGET_P (candidate) = 0;
return 1;
return candidate;
}
/* Unless this is an annulled insn from the target of a branch,
@ -2101,7 +2102,7 @@ redundant_insn_p (insn, target, delay_list)
/* See if TRIAL is the same as INSN. */
pat = PATTERN (trial);
if (rtx_equal_p (pat, ipat))
return 1;
return trial;
/* Can't go any further if TRIAL conflicts with INSN. */
if (insn_sets_resource_p (trial, &needed, 1))
@ -2276,6 +2277,33 @@ update_reg_dead_notes (insn, delayed_insn)
}
}
}
/* Delete any REG_UNUSED notes that exist on INSN but not on REDUNDANT_INSN.
This handles the case of udivmodXi4 instructions which optimize their
output depending on whether any REG_UNUSED notes are present.
we must make sure that INSN calculates as many results as REDUNDANT_INSN
does. */
static void
update_reg_unused_notes (insn, redundant_insn)
rtx insn, redundant_insn;
{
rtx p, link, next;
for (link = REG_NOTES (insn); link; link = next)
{
next = XEXP (link, 1);
if (REG_NOTE_KIND (link) != REG_UNUSED
|| GET_CODE (XEXP (link, 0)) != REG)
continue;
if (! find_regno_note (redundant_insn, REG_UNUSED,
REGNO (XEXP (link, 0))))
remove_note (insn, link);
}
}
/* Marks registers possibly live at the current place being scanned by
mark_target_live_regs. Used only by next two function. */
@ -3279,10 +3307,12 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely,
#endif
)
{
rtx prior_insn;
/* If TRIAL is redundant with some insn before INSN, we don't
actually need to add it to the delay list; we can merely pretend
we did. */
if (redundant_insn_p (trial, insn, delay_list))
if (prior_insn = redundant_insn_p (trial, insn, delay_list))
{
if (own_thread)
{
@ -3297,7 +3327,10 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely,
delete_insn (trial);
}
else
new_thread = next_active_insn (trial);
{
update_reg_unused_notes (prior_insn, trial);
new_thread = next_active_insn (trial);
}
continue;
}
@ -3940,6 +3973,17 @@ relax_delay_slots (first)
if (invert_jump (delay_insn, label))
{
int i;
/* Must update the INSN_FROM_TARGET_P bits now that
the branch is reversed, so that mark_target_live_regs
will handle the delay slot insn correctly. */
for (i = 1; i < XVECLEN (PATTERN (insn), 0); i++)
{
rtx slot = XVECEXP (PATTERN (insn), 0, i);
INSN_FROM_TARGET_P (slot) = ! INSN_FROM_TARGET_P (slot);
}
delete_insn (next);
next = insn;
}

View File

@ -1915,11 +1915,9 @@ staticp (arg)
switch (TREE_CODE (arg))
{
case FUNCTION_DECL:
/* Nested functions aren't static. Since taking their address
/* Nested functions aren't static, since taking their address
involves a trampoline. */
if (decl_function_context (arg) != 0)
return 0;
/* ... fall through ... */
return decl_function_context (arg) == 0;
case VAR_DECL:
return TREE_STATIC (arg) || DECL_EXTERNAL (arg);

View File

@ -3381,10 +3381,11 @@ output_constant (exp, size)
return;
/* Eliminate the NON_LVALUE_EXPR_EXPR that makes a cast not be an lvalue.
That way we get the constant (we hope) inside it. Also, strip
off any NOP_EXPR that converts between two record or union types. */
That way we get the constant (we hope) inside it. Also, strip off any
NOP_EXPR that converts between two record, union, or array types. */
while ((TREE_CODE (exp) == NOP_EXPR
&& (TREE_TYPE (exp) == TREE_TYPE (TREE_OPERAND (exp, 0))
|| TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE
|| TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
|| TREE_CODE (TREE_TYPE (exp)) == UNION_TYPE
|| TREE_CODE (TREE_TYPE (exp)) == QUAL_UNION_TYPE))

View File

@ -1 +1 @@
char *version_string = "2.6.2";
char *version_string = "2.6.3";

View File

@ -5432,9 +5432,9 @@ create_definition (buf, limit, op)
{
switch (*bp)
{
case '\t': case ' ':
case '\t': case ' ': case '\r':
/* Skip spaces and tabs. */
while (++bp < limit && (*bp == ' ' || *bp == '\t'))
while (++bp < limit && (*bp == ' ' || *bp == '\t' || *bp == '\r'))
continue;
break;

View File

@ -536,8 +536,8 @@ Here are the possible CPU types:
@c gmicro, alliant, spur and tahoe omitted since they don't work.
1750a, a29k, alpha, arm, c@var{n}, clipper, dsp16xx, elxsi, h8300,
hppa1.0, hppa1.1, i370, i386, i486, i860, i960, m68000, m68k, m88k,
mips, ns32k, pyramid, romp, rs6000, sh, sparc, sparclite, sparc64, vax,
we32k.
mips, ns32k, powerpc, pyramid, romp, rs6000, sh, sparc, sparclite,
sparc64, vax, we32k.
@end quotation
Here are the recognized company names. As you can see, customary
@ -1228,18 +1228,21 @@ These errors are minor differences in some floating-point constants and
can be safely ignored; the stage 3 compiler is correct.
@item rs6000-*-aix
If you are running AIX version 3.2.5 and have XLC version 1.3.0.0, you
must obtain XLC 1.3.0.1 by requesting PTF 421749 from IBM. Likewise,
XLC-1.3.0.19 cannot correctly compile GNU CC; you must obtain
XLC-1.3.0.24 by requesting PTF 432238 from IBM. If you are using an
older version of AIX you may have an old version of the IBM assembler,
which cannot correctly handle debugging directives. See the file
@file{README.RS6000} for more details on both of these problems.
@itemx powerpc-*-aix
Various early versions of each release of the IBM XLC compiler will not
bootstrap GNU CC. Symptoms include differences between the stage2 and
stage3 object files, and errors when compiling @file{libgcc.a} or
@file{enquire}. Known problematic releases include: xlc-1.2.1.8,
xlc-1.3.0.0 (distributed with AIX 3.2.5), and xlc-1.3.0.19. Both
xlc-1.2.1.28 and xlc-1.3.0.24 (PTF 432238) are known to produce working
versions of GNU CC, but most other recent releases correctly bootstrap
GNU CC. Also, releases of AIX prior to AIX 3.2.4 include a version of
the IBM assembler which does not accept debugging directives: assembler
updates are available as PTFs. See the file @file{README.RS6000} for
more details on both of these problems.
The PowerPC and POWER2 architectures are now supported, but have not
been very extensively tested due to lack of appropriate systems. Only
AIX is supported on the PowerPC. GNU CC does not yet support the 64-bit
PowerPC instructions.
Only AIX is supported on the PowerPC. GNU CC does not yet support the
64-bit PowerPC instructions.
Objective C does not work on this architecture.

View File

@ -487,6 +487,9 @@ extern int expand_twoval_binop PROTO((optab, rtx, rtx, rtx, rtx, int));
/* Expand a unary arithmetic operation given optab rtx operand. */
extern rtx expand_unop PROTO((enum machine_mode, optab, rtx, rtx, int));
/* Expand the absolute value operation. */
extern rtx expand_abs PROTO((enum machine_mode, rtx, rtx, int, int));
/* Expand the complex absolute value operation. */
extern rtx expand_complex_abs PROTO((enum machine_mode, rtx, rtx, int));

View File

@ -22,6 +22,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* This is tested by i386gas.h. */
#define YES_UNDERSCORES
/* Don't assume anything about the header files. */
#define NO_IMPLICIT_EXTERN_C
#include "i386/gstabs.h"
/* Get perform_* macros to build libgcc.a. */
@ -65,12 +68,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define HAVE_ATEXIT
/* Tell final.c that we don't need a label passed to mcount. */
#define NO_PROFILE_DATA
/* Redefine this to not pass an unused label in %edx. */
/* Redefine this to use %eax instead of %edx. */
#undef FUNCTION_PROFILER
#define FUNCTION_PROFILER(FILE, LABELNO) \
{ \
@ -233,22 +231,3 @@ do { \
putc ('\n', FILE); \
} \
} while (0)
/* This is defined when gcc is compiled in the BSD-directory-tree, and must
* make up for the gap to all the stuff done in the GNU-makefiles.
*/
#ifdef FREEBSD_NATIVE
#undef MD_EXEC_PREFIX
#define MD_EXEC_PREFIX "/usr/libexec/"
#undef STANDARD_STARTFILE_PREFIX
#define STANDARD_STARTFILE_PREFIX "/usr/lib"
#define DEFAULT_TARGET_MACHINE "i386-unknown-freebsd_1.0"
#define GPLUSPLUS_INCLUDE_DIR "/usr/local/lib/gcc-lib/i386-unknown-freebsd_1.0/2.5.8/include"
#define TOOL_INCLUDE_DIR "/usr/local/i386-unknown-freebsd_1.0/include"
#define GCC_INCLUDE_DIR "/usr/local/lib/gcc-lib/i386-unknown-freebsd_1.0/2.5.8/include"
#endif /* FREEBSD_NATIVE */

3813
gnu/usr.bin/cc/legal/parse.y Normal file

File diff suppressed because it is too large Load Diff