Gcc 3.2.1-prerelease from the FSF anoncvs repo gcc-3_2-branch on 1-Sep-2002 00:00:01 EDT.

This commit is contained in:
Alexander Kabaev 2002-09-01 20:38:57 +00:00
parent 00db7afddd
commit bb3c979bf5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/gcc/dist/; revision=102780
144 changed files with 5745 additions and 2194 deletions

File diff suppressed because it is too large Load Diff

View File

@ -541,6 +541,7 @@ CONFIG_H = $(GCONFIG_H) insn-constants.h insn-flags.h
TCONFIG_H = tconfig.h $(xm_file_list)
TARGET_H = target.h
HOOKS_H = hooks.h
LANGHOOKS_DEF_H = langhooks.h $(HOOKS_H)
TARGET_DEF_H = target-def.h $(HOOKS_H)
TM_P_H = tm_p.h $(tm_p_file_list) tm-preds.h
@ -1212,7 +1213,7 @@ s-under: $(GCC_PASSES)
c-common.o : c-common.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(OBSTACK_H) \
$(C_COMMON_H) flags.h toplev.h output.h c-pragma.h $(RTL_H) $(GGC_H) \
$(EXPR_H) $(TM_P_H) builtin-types.def builtin-attrs.def $(TARGET_H) \
diagnostic.h tree-inline.h
diagnostic.h tree-inline.h $(LANGHOOKS_DEF_H)
# A file used by all variants of C and some other languages.
@ -1327,7 +1328,7 @@ convert.o: convert.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h convert.h toplev.
langhooks.o : langhooks.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) toplev.h \
tree-inline.h $(RTL_H) insn-config.h integrate.h langhooks.h \
langhooks-def.h flags.h
$(LANGHOOKS_DEF_H) flags.h
tree.o : tree.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h function.h toplev.h \
$(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H) langhooks.h
tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \

View File

@ -564,6 +564,14 @@ get_alias_set (t)
and references to functions, but that's different.) */
else if (TREE_CODE (t) == FUNCTION_TYPE)
set = 0;
/* Unless the language specifies otherwise, let vector types alias
their components. This avoids some nasty type punning issues in
normal usage. And indeed lets vectors be treated more like an
array slice. */
else if (TREE_CODE (t) == VECTOR_TYPE)
set = get_alias_set (TREE_TYPE (t));
else
/* Otherwise make a new alias set for this type. */
set = new_alias_set ();

View File

@ -1050,7 +1050,6 @@ handle_alias_attribute (node, name, args, flags, no_add_attrs)
DECL_INITIAL (decl) = error_mark_node;
else
DECL_EXTERNAL (decl) = 0;
assemble_alias (decl, id);
}
else
{

View File

@ -211,17 +211,21 @@ make_reorder_chain_1 (bb, prev)
/* In the absence of a prediction, disturb things as little as possible
by selecting the old "next" block from the list of successors. If
there had been a fallthru edge, that will be the one. */
/* Note that the fallthru block may not be next any time we eliminate
forwarder blocks. */
if (! next)
{
for (e = bb->succ; e ; e = e->succ_next)
if (e->dest->index == bb->index + 1)
if (e->flags & EDGE_FALLTHRU)
{
if ((e->flags & EDGE_FALLTHRU)
|| (e->dest->succ
&& ! (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH))))
next = e->dest;
next = e->dest;
break;
}
else if (e->dest->index == bb->index + 1)
{
if (! (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH)))
next = e->dest;
}
}
/* Make sure we didn't select a silly next block. */

View File

@ -300,8 +300,9 @@ bitmap_find_bit (head, bit)
bitmap_element *element;
unsigned HOST_WIDE_INT indx = bit / BITMAP_ELEMENT_ALL_BITS;
if (head->current == 0)
return 0;
if (head->current == 0
|| head->indx == indx)
return head->current;
if (head->indx > indx)
for (element = head->current;

View File

@ -2326,10 +2326,6 @@ c_common_get_alias_set (t)
{
tree u;
/* We know nothing about vector types */
if (TREE_CODE (t) == VECTOR_TYPE)
return 0;
/* Permit type-punning when accessing a union, provided the access
is directly through the union. For example, this code does not
permit taking the address of a union member and then storing
@ -2343,17 +2339,17 @@ c_common_get_alias_set (t)
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE)
return 0;
/* If this is a char *, the ANSI C standard says it can alias
anything. Note that all references need do this. */
if (TREE_CODE_CLASS (TREE_CODE (t)) == 'r'
&& TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
&& TYPE_PRECISION (TREE_TYPE (t)) == TYPE_PRECISION (char_type_node))
return 0;
/* That's all the expressions we handle specially. */
if (! TYPE_P (t))
return -1;
/* The C standard guarantess that any object may be accessed via an
lvalue that has character type. */
if (t == char_type_node
|| t == signed_char_type_node
|| t == unsigned_char_type_node)
return 0;
/* The C standard specifically allows aliasing between signed and
unsigned variants of the same type. We treat the signed
variant as canonical. */
@ -3568,6 +3564,7 @@ c_expand_expr (exp, target, tmode, modifier)
tree rtl_expr;
rtx result;
bool preserve_result = false;
bool return_target = false;
/* Since expand_expr_stmt calls free_temp_slots after every
expression statement, we must call push_temp_slots here.
@ -3595,8 +3592,20 @@ c_expand_expr (exp, target, tmode, modifier)
if (TREE_CODE (last) == SCOPE_STMT
&& TREE_CODE (expr) == EXPR_STMT)
{
TREE_ADDRESSABLE (expr) = 1;
preserve_result = true;
if (target && TREE_CODE (EXPR_STMT_EXPR (expr)) == VAR_DECL
&& DECL_RTL_IF_SET (EXPR_STMT_EXPR (expr)) == target)
/* If the last expression is a variable whose RTL is the
same as our target, just return the target; if it
isn't valid expanding the decl would produce different
RTL, and store_expr would try to do a copy. */
return_target = true;
else
{
/* Otherwise, note that we want the value from the last
expression. */
TREE_ADDRESSABLE (expr) = 1;
preserve_result = true;
}
}
}
@ -3604,7 +3613,9 @@ c_expand_expr (exp, target, tmode, modifier)
expand_end_stmt_expr (rtl_expr);
result = expand_expr (rtl_expr, target, tmode, modifier);
if (preserve_result && GET_CODE (result) == MEM)
if (return_target)
result = target;
else if (preserve_result && GET_CODE (result) == MEM)
{
if (GET_MODE (result) != BLKmode)
result = copy_to_reg (result);
@ -4161,6 +4172,10 @@ c_common_post_options ()
warning ("-Wformat-security ignored without -Wformat");
if (warn_missing_format_attribute && !warn_format)
warning ("-Wmissing-format-attribute ignored without -Wformat");
/* If an error has occurred in cpplib, note it so we fail
immediately. */
errorcount += cpp_errors (parse_in);
}
/* Front end initialization common to C, ObjC and C++. */

View File

@ -3911,6 +3911,7 @@ build_compound_literal (type, init)
DECL_CONTEXT (decl) = current_function_decl;
TREE_USED (decl) = 1;
TREE_TYPE (decl) = type;
TREE_READONLY (decl) = TREE_READONLY (type);
store_init_value (decl, init);
if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
@ -3933,12 +3934,18 @@ build_compound_literal (type, init)
if (TREE_STATIC (decl))
{
/* This decl needs a name for the assembler output. We also need
a unique suffix to be added to the name, for which DECL_CONTEXT
must be set. */
DECL_NAME (decl) = get_identifier ("__compound_literal");
DECL_CONTEXT (decl) = complit;
a unique suffix to be added to the name. */
char *name;
extern int var_labelno;
ASM_FORMAT_PRIVATE_NAME (name, "__compound_literal", var_labelno);
var_labelno++;
DECL_NAME (decl) = get_identifier (name);
DECL_DEFER_OUTPUT (decl) = 1;
DECL_COMDAT (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
pushdecl (decl);
rest_of_decl_compilation (decl, NULL, 1, 0);
DECL_CONTEXT (decl) = NULL_TREE;
}
return complit;
@ -4617,7 +4624,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
even if it is (eg) a const variable with known value. */
size_varies = 1;
if (pedantic)
if (!flag_isoc99 && pedantic)
{
if (TREE_CONSTANT (size))
pedwarn ("ISO C89 forbids array `%s' whose size can't be evaluated",
@ -5591,8 +5598,11 @@ grokfield (filename, line, declarator, declspecs, width)
{
/* This is an unnamed decl. We only support unnamed
structs/unions, so check for other things and refuse them. */
if (TREE_CODE (TREE_VALUE (declspecs)) != RECORD_TYPE
&& TREE_CODE (TREE_VALUE (declspecs)) != UNION_TYPE)
tree type = TREE_VALUE (declspecs);
if (TREE_CODE (type) == TYPE_DECL)
type = TREE_TYPE (type);
if (TREE_CODE (type) != RECORD_TYPE && TREE_CODE (type) != UNION_TYPE)
{
error ("unnamed fields of type other than struct or union are not allowed");
return NULL_TREE;

View File

@ -29,7 +29,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
static const char *c_init PARAMS ((const char *));
static void c_init_options PARAMS ((void));
static void c_post_options PARAMS ((void));
/* ### When changing hooks, consider if ObjC needs changing too!! ### */
@ -44,7 +43,7 @@ static void c_post_options PARAMS ((void));
#undef LANG_HOOKS_DECODE_OPTION
#define LANG_HOOKS_DECODE_OPTION c_decode_option
#undef LANG_HOOKS_POST_OPTIONS
#define LANG_HOOKS_POST_OPTIONS c_post_options
#define LANG_HOOKS_POST_OPTIONS c_common_post_options
#undef LANG_HOOKS_GET_ALIAS_SET
#define LANG_HOOKS_GET_ALIAS_SET c_common_get_alias_set
#undef LANG_HOOKS_SAFE_FROM_P
@ -74,13 +73,6 @@ static void c_post_options PARAMS ((void));
/* Each front end provides its own. */
const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
/* Post-switch processing. */
static void
c_post_options ()
{
c_common_post_options ();
}
static void
c_init_options ()
{

View File

@ -334,20 +334,21 @@ cb_def_pragma (pfile, line)
-Wunknown-pragmas has been given. */
if (warn_unknown_pragmas > in_system_header)
{
const unsigned char *space, *name = 0;
const unsigned char *space, *name;
const cpp_token *s;
space = name = (const unsigned char *) "";
s = cpp_get_token (pfile);
space = cpp_token_as_text (pfile, s);
s = cpp_get_token (pfile);
if (s->type == CPP_NAME)
name = cpp_token_as_text (pfile, s);
if (s->type != CPP_EOF)
{
space = cpp_token_as_text (pfile, s);
s = cpp_get_token (pfile);
if (s->type == CPP_NAME)
name = cpp_token_as_text (pfile, s);
}
lineno = SOURCE_LINE (map, line);
if (name)
warning ("ignoring #pragma %s %s", space, name);
else
warning ("ignoring #pragma %s", space);
warning ("ignoring #pragma %s %s", space, name);
}
}

View File

@ -284,9 +284,14 @@ apply_pragma_weak (decl, value)
tree decl, value;
{
if (value)
decl_attributes (&decl, build_tree_list (get_identifier ("alias"),
build_tree_list (NULL, value)),
0);
{
value = build_string (IDENTIFIER_LENGTH (value),
IDENTIFIER_POINTER (value));
decl_attributes (&decl, build_tree_list (get_identifier ("alias"),
build_tree_list (NULL, value)),
0);
}
if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl)
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
warning_with_decl (decl, "applying #pragma weak `%s' after first use results in unspecified behavior");
@ -343,7 +348,11 @@ handle_pragma_weak (dummy)
decl = identifier_global_value (name);
if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
apply_pragma_weak (decl, value);
{
apply_pragma_weak (decl, value);
if (value)
assemble_alias (decl, value);
}
else
pending_weaks = tree_cons (name, value, pending_weaks);
}

View File

@ -1634,6 +1634,7 @@ try_optimize_cfg (mode)
&& !(s->flags & EDGE_COMPLEX)
&& (c = s->dest) != EXIT_BLOCK_PTR
&& c->pred->pred_next == NULL
&& b != c
/* If the jump insn has side effects,
we can't kill the edge. */
&& (GET_CODE (b->end) != JUMP_INSN

View File

@ -953,9 +953,21 @@ force_nonfallthru_and_redirect (e, target)
if (e->src->succ->succ_next)
{
/* Create the new structures. */
/* Position the new block correctly relative to loop notes. */
note = last_loop_beg_note (e->src->end);
jump_block
= create_basic_block (e->src->index + 1, NEXT_INSN (note), NULL);
note = NEXT_INSN (note);
/* ... and ADDR_VECs. */
if (note != NULL
&& GET_CODE (note) == CODE_LABEL
&& NEXT_INSN (note)
&& GET_CODE (NEXT_INSN (note)) == JUMP_INSN
&& (GET_CODE (PATTERN (NEXT_INSN (note))) == ADDR_DIFF_VEC
|| GET_CODE (PATTERN (NEXT_INSN (note))) == ADDR_VEC))
note = NEXT_INSN (NEXT_INSN (note));
jump_block = create_basic_block (e->src->index + 1, note, NULL);
jump_block->count = e->count;
jump_block->frequency = EDGE_FREQUENCY (e);
jump_block->loop_depth = target->loop_depth;
@ -1954,17 +1966,26 @@ purge_dead_edges (bb)
e->flags &= ~EDGE_ABNORMAL;
/* Check purposes we can have edge. */
if ((e->flags & EDGE_FALLTHRU)
&& any_condjump_p (insn))
/* See if this edge is one we should keep. */
if ((e->flags & EDGE_FALLTHRU) && any_condjump_p (insn))
/* A conditional jump can fall through into the next
block, so we should keep the edge. */
continue;
else if (e->dest != EXIT_BLOCK_PTR
&& e->dest->head == JUMP_LABEL (insn))
/* If the destination block is the target of the jump,
keep the edge. */
continue;
else if (e->dest == EXIT_BLOCK_PTR
&& returnjump_p (insn))
else if (e->dest == EXIT_BLOCK_PTR && returnjump_p (insn))
/* If the destination block is the exit block, and this
instruction is a return, then keep the edge. */
continue;
else if ((e->flags & EDGE_EH) && can_throw_internal (insn))
/* Keep the edges that correspond to exceptions thrown by
this instruction. */
continue;
/* We do not need this edge. */
purged = true;
remove_edge (e);
}

View File

@ -577,6 +577,15 @@ is_ctor_dtor (s)
const char *orig_s = s;
static const struct names special[] = {
#ifndef NO_DOLLAR_IN_LABEL
{ "GLOBAL__I$", sizeof ("GLOBAL__I$")-1, 1, 0 },
{ "GLOBAL__D$", sizeof ("GLOBAL__D$")-1, 2, 0 },
#else
#ifndef NO_DOT_IN_LABEL
{ "GLOBAL__I.", sizeof ("GLOBAL__I.")-1, 1, 0 },
{ "GLOBAL__D.", sizeof ("GLOBAL__D.")-1, 2, 0 },
#endif /* NO_DOT_IN_LABEL */
#endif /* NO_DOLLAR_IN_LABEL */
{ "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
{ "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
{ "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },

View File

@ -3539,11 +3539,12 @@ subst (x, from, to, in_dest, unique_copy)
if (GET_CODE (new) == CONST_INT && GET_CODE (x) == SUBREG)
{
x = simplify_subreg (GET_MODE (x), new,
enum machine_mode mode = GET_MODE (x);
x = simplify_subreg (mode, new,
GET_MODE (SUBREG_REG (x)),
SUBREG_BYTE (x));
if (! x)
abort ();
x = gen_rtx_CLOBBER (mode, const0_rtx);
}
else if (GET_CODE (new) == CONST_INT
&& GET_CODE (x) == ZERO_EXTEND)
@ -6697,18 +6698,7 @@ force_to_mode (x, mode, mask, reg, just_select)
/* If X is a CONST_INT, return a new one. Do this here since the
test below will fail. */
if (GET_CODE (x) == CONST_INT)
{
HOST_WIDE_INT cval = INTVAL (x) & mask;
int width = GET_MODE_BITSIZE (mode);
/* If MODE is narrower that HOST_WIDE_INT and CVAL is a negative
number, sign extend it. */
if (width > 0 && width < HOST_BITS_PER_WIDE_INT
&& (cval & ((HOST_WIDE_INT) 1 << (width - 1))) != 0)
cval |= (HOST_WIDE_INT) -1 << width;
return GEN_INT (cval);
}
return gen_int_mode (INTVAL (x) & mask, mode);
/* If X is narrower than MODE and we want all the bits in X's mode, just
get X in the proper mode. */
@ -6914,14 +6904,6 @@ force_to_mode (x, mode, mask, reg, just_select)
force_to_mode (XEXP (x, 1), mode, mask,
reg, next_select));
/* If OP1 is a CONST_INT and X is an IOR or XOR, clear bits outside
MASK since OP1 might have been sign-extended but we never want
to turn on extra bits, since combine might have previously relied
on them being off. */
if (GET_CODE (op1) == CONST_INT && (code == IOR || code == XOR)
&& (INTVAL (op1) & mask) != 0)
op1 = GEN_INT (INTVAL (op1) & mask);
if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
x = gen_binary (code, op_mode, op0, op1);
break;
@ -9865,6 +9847,12 @@ gen_lowpart_for_combine (mode, x)
int offset = 0;
rtx res;
/* We can't handle VOIDmodes. We can get here when generating vector
modes since these, unlike integral and floating point modes are not
handled earlier. */
if (GET_MODE (x) == VOIDmode)
return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
offset = subreg_lowpart_offset (mode, GET_MODE (x));
res = simplify_gen_subreg (mode, x, GET_MODE (x), offset);
if (res)

View File

@ -365,6 +365,16 @@ esac
case $machine in
*-*-linux*)
xm_defines=POSIX
case $machine in
*-*-linux*ecoff* | *-*-linux*libc1* | *-*-linux*oldld* | *-*-linux*aout*)
;;
*)
case x${enable_threads} in
x | xyes | xposix) thread_file='posix'
;;
esac
;;
esac
;;
*-*-gnu*)
# On the Hurd, the setup is just about the same on
@ -558,9 +568,6 @@ alpha*-*-linux*)
tmake_file="t-slibgcc-elf-ver t-linux alpha/t-crtfm alpha/t-alpha alpha/t-ieee"
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
gas=yes gnu_ld=yes
if test x$enable_threads = xyes; then
thread_file='posix'
fi
;;
alpha*-*-freebsd*)
tm_file="${tm_file} ${fbsd_tm_file} alpha/elf.h alpha/freebsd.h"
@ -572,7 +579,6 @@ alpha*-*-netbsd*)
tm_file="${tm_file} netbsd.h alpha/elf.h netbsd-elf.h alpha/netbsd.h"
target_cpu_default="MASK_GAS"
tmake_file="${tmake_file} alpha/t-alpha alpha/t-ieee"
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
;;
alpha*-*-openbsd*)
@ -872,9 +878,6 @@ hppa*-*-linux* | parisc*-*-linux*)
tmake_file="t-slibgcc-elf-ver t-linux pa/t-linux"
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
gas=yes gnu_ld=yes
if test x$enable_threads = xyes; then
thread_file='posix'
fi
;;
hppa*-*-openbsd*)
target_cpu_default="MASK_PA_11"
@ -1118,9 +1121,6 @@ i370-*-linux*)
gnu_ld=yes
gas=yes
elf=yes
if test x$enable_threads = xyes; then
thread_file='posix'
fi
;;
i[34567]86-*-chorusos*)
xm_defines=POSIX
@ -1317,9 +1317,6 @@ i[34567]86-*-linux*) # Intel 80386's running GNU/Linux
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
gnu_ld=yes
float_format=i386
if test x$enable_threads = xyes; then
thread_file='posix'
fi
;;
x86_64-*-linux*)
tm_file="${tm_file} i386/att.h dbxelf.h elfos.h svr4.h linux.h \
@ -1328,9 +1325,6 @@ x86_64-*-linux*)
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
gnu_ld=yes
float_format=i386
if test x$enable_threads = xyes; then
thread_file='posix'
fi
;;
i[34567]86-*-gnu*)
float_format=i386
@ -1706,9 +1700,6 @@ ia64*-*-linux*)
tm_file="${tm_file} dbxelf.h elfos.h svr4.h linux.h ia64/sysv4.h ia64/linux.h"
tmake_file="t-slibgcc-elf-ver t-linux ia64/t-ia64 ia64/t-glibc"
target_cpu_default="MASK_GNU_AS|MASK_GNU_LD"
if test x$enable_threads = xyes; then
thread_file='posix'
fi
float_format=i386
;;
ia64*-*-hpux*)
@ -2099,9 +2090,6 @@ m68k-*-linux*) # Motorola m68k's running GNU/Linux
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
float_format=m68k
gnu_ld=yes
if test x$enable_threads = xyes; then
thread_file='posix'
fi
;;
m68k-*-psos*)
tmake_file=m68k/t-m68kbare
@ -2379,6 +2367,7 @@ mips*-*-netbsd*) # NetBSD/mips, either endian.
tm_file="mips/little.h $tm_file"
;;
esac
tmake_file="${tmake_file} mips/t-netbsd"
;;
mips*-*-linux*) # Linux MIPS, either endian.
tm_file="dbxelf.h elfos.h svr4.h linux.h mips/linux.h"
@ -2397,9 +2386,6 @@ mips*-*-linux*) # Linux MIPS, either endian.
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
gnu_ld=yes
gas=yes
if test x$enable_threads = xyes; then
thread_file='posix'
fi
;;
mips*el-*-openbsd*) # mips little endian
target_cpu_default="MASK_GAS|MASK_ABICALLS"
@ -2867,17 +2853,11 @@ powerpc-*-linux-gnualtivec*)
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/linux.h rs6000/linuxaltivec.h"
out_file=rs6000/rs6000.c
tmake_file="rs6000/t-ppcos t-slibgcc-elf-ver t-linux rs6000/t-ppccomm"
if test x$enable_threads = xyes; then
thread_file='posix'
fi
;;
powerpc-*-linux*)
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/linux.h"
out_file=rs6000/rs6000.c
tmake_file="rs6000/t-ppcos t-slibgcc-elf-ver t-linux rs6000/t-ppccomm"
if test x$enable_threads = xyes; then
thread_file='posix'
fi
;;
powerpc-*-gnu-gnualtivec*)
tm_file="${cpu_type}/${cpu_type}.h elfos.h svr4.h freebsd-spec.h gnu.h rs6000/sysv4.h rs6000/linux.h rs6000/linuxaltivec.h rs6000/gnu.h"
@ -2993,9 +2973,6 @@ s390-*-linux*)
tm_file="s390/s390.h dbxelf.h elfos.h svr4.h linux.h s390/linux.h"
tmake_file="t-slibgcc-elf-ver t-linux s390/t-linux"
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
if test x$enable_threads = xyes; then
thread_file='posix'
fi
;;
s390x-*-linux*)
tm_file="s390/s390x.h s390/s390.h dbxelf.h elfos.h svr4.h linux.h s390/linux.h"
@ -3004,9 +2981,6 @@ s390x-*-linux*)
out_file=s390/s390.c
tmake_file="t-slibgcc-elf-ver t-linux s390/t-linux s390/t-linux64"
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
if test x$enable_threads = xyes; then
thread_file='posix'
fi
;;
sh-*-elf*)
tmake_file="sh/t-sh sh/t-elf"
@ -3045,9 +3019,6 @@ sh-*-linux*)
tm_file="${tm_file} sh/elf.h sh/linux.h"
tmake_file="sh/t-sh sh/t-elf sh/t-linux"
gas=yes gnu_ld=yes
if test x$enable_threads = xyes; then
thread_file='posix'
fi
float_format=sh
;;
sh-*-*)
@ -3087,6 +3058,13 @@ sparc-*-openbsd*)
# we need collect2 until our bug is fixed...
use_collect2=yes
;;
sparc64-*-openbsd*)
tm_file="sparc/openbsd1-64.h sparc/sparc.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h sparc/sp64-elf.h openbsd.h sparc/openbsd64.h"
xm_file=sparc/xm-sp64.h
gas=yes gnu_ld=yes
with_cpu=ultrasparc
float_format=i128
;;
sparc-*-bsd*)
tm_file="${tm_file} sparc/bsd.h"
;;
@ -3124,9 +3102,6 @@ sparc-*-linux*) # Sparc's running GNU/Linux, libc6
tmake_file="t-slibgcc-elf-ver t-linux sparc/t-crtfm"
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
gnu_ld=yes
if test x$enable_threads = xyes; then
thread_file='posix'
fi
float_format=sparc
;;
sparc-*-lynxos*)
@ -3325,9 +3300,6 @@ sparc64-*-linux*) # 64-bit Sparc's running GNU/Linux
tm_file="sparc/biarch64.h ${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/linux64.h"
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
gnu_ld=yes
if test x$enable_threads = xyes; then
thread_file='posix'
fi
float_format=sparc
;;
sparc64-*-netbsd*)
@ -3457,9 +3429,6 @@ xtensa-*-linux*)
tmake_file="t-linux xtensa/t-xtensa"
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
gas=yes gnu_ld=yes
if test x$enable_threads = xyes; then
thread_file='posix'
fi
;;
*)
echo "Configuration $machine not supported" 1>&2

View File

@ -296,6 +296,12 @@
every opportunity. This is extremely expensive. */
#undef ENABLE_GC_ALWAYS_COLLECT
/* Define if you want to use __cxa_atexit, rather than atexit, to
register C++ destructors for local statics and global objects.
This is essential for fully standards-compliant handling of
destructors, but requires __cxa_atexit in libc. */
#undef DEFAULT_USE_CXA_ATEXIT
/* Define if you want the C and C++ compilers to support multibyte
character sets for source code. */
#undef MULTIBYTE_CHARS

View File

@ -1664,7 +1664,11 @@ alpha_encode_section_info (decl)
XSTR (XEXP (DECL_RTL (decl), 0), 0) = string;
}
else if (symbol_str[0] == '@')
abort ();
{
/* We're hosed. This can happen when the user adds a weak
attribute after rtl generation. They should have gotten
a warning about unspecified behaviour from varasm.c. */
}
}
/* legitimate_address_p recognizes an RTL expression that is a valid

View File

@ -1224,42 +1224,6 @@ extern struct alpha_compare alpha_compare;
#define FUNCTION_PROFILER(FILE, LABELNO)
/* Output assembler code to FILE to initialize this source file's
basic block profiling info, if that has not already been done.
This assumes that __bb_init_func doesn't garble a1-a5. */
#define FUNCTION_BLOCK_PROFILER(FILE, LABELNO) \
do { \
ASM_OUTPUT_REG_PUSH (FILE, 16); \
fputs ("\tlda $16,$PBX32\n", (FILE)); \
fputs ("\tldq $26,0($16)\n", (FILE)); \
fputs ("\tbne $26,1f\n", (FILE)); \
fputs ("\tlda $27,__bb_init_func\n", (FILE)); \
fputs ("\tjsr $26,($27),__bb_init_func\n", (FILE)); \
fputs ("\tldgp $29,0($26)\n", (FILE)); \
fputs ("1:\n", (FILE)); \
ASM_OUTPUT_REG_POP (FILE, 16); \
} while (0);
/* Output assembler code to FILE to increment the entry-count for
the BLOCKNO'th basic block in this source file. */
#define BLOCK_PROFILER(FILE, BLOCKNO) \
do { \
int blockn = (BLOCKNO); \
fputs ("\tsubq $30,16,$30\n", (FILE)); \
fputs ("\tstq $26,0($30)\n", (FILE)); \
fputs ("\tstq $27,8($30)\n", (FILE)); \
fputs ("\tlda $26,$PBX34\n", (FILE)); \
fprintf ((FILE), "\tldq $27,%d($26)\n", 8*blockn); \
fputs ("\taddq $27,1,$27\n", (FILE)); \
fprintf ((FILE), "\tstq $27,%d($26)\n", 8*blockn); \
fputs ("\tldq $26,0($30)\n", (FILE)); \
fputs ("\tldq $27,8($30)\n", (FILE)); \
fputs ("\taddq $30,16,$30\n", (FILE)); \
} while (0)
/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
the stack pointer does not matter. The value is tested only in
functions that have frame pointers.

View File

@ -165,7 +165,7 @@ do { \
} \
ASM_OUTPUT_ALIGN ((FILE), exact_log2((ALIGN) / BITS_PER_UNIT)); \
ASM_OUTPUT_LABEL(FILE, NAME); \
ASM_OUTPUT_SKIP((FILE), (SIZE)); \
ASM_OUTPUT_SKIP((FILE), (SIZE) ? (SIZE) : 1); \
} while (0)
/* This says how to output assembler code to declare an

View File

@ -24,7 +24,7 @@ Boston, MA 02111-1307, USA. */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES \
"-D__NetBSD__ -D__ELF__ -Asystem=unix -Asystem=NetBSD"
"-D__NetBSD__ -D__ELF__ -D_LP64 -Asystem=unix -Asystem=NetBSD"
/* Show that we need a GP when profiling. */

View File

@ -574,6 +574,30 @@ ssib_section () \
#ifndef REAL_ARITHMETIC
#define REAL_VALUE_ATOF(x,s) atof(x)
#define REAL_VALUE_HTOF(x,s) atof(x)
#define REAL_VALUE_TO_TARGET_SINGLE(IN, OUT) \
do { \
union { \
float f; \
HOST_WIDE_INT l; \
} u; \
\
u.f = (IN); \
(OUT) = (u.l >> 32) & 0xFFFFFFFF; \
} while (0)
#define REAL_VALUE_TO_TARGET_DOUBLE(IN, OUT) \
do { \
union { \
REAL_VALUE_TYPE f; \
HOST_WIDE_INT l; \
} u; \
\
u.f = (IN); \
(OUT)[0] = (u.l >> 32) & 0xFFFFFFFF; \
(OUT)[1] = (u.l & 0xFFFFFFFF); \
} while (0)
#endif
#undef NM_FLAGS

View File

@ -4544,8 +4544,8 @@ arm_gen_movstrqi (operands)
RTX_UNCHANGING_P (mem) = dst_unchanging_p;
MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
MEM_SCALAR_P (mem) = dst_scalar_p;
emit_move_insn (mem, gen_rtx_SUBREG (QImode, part_bytes_reg, 0));
emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg));
if (--last_bytes)
{
tmp = gen_reg_rtx (SImode);
@ -4563,7 +4563,7 @@ arm_gen_movstrqi (operands)
RTX_UNCHANGING_P (mem) = dst_unchanging_p;
MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
MEM_SCALAR_P (mem) = dst_scalar_p;
emit_move_insn (mem, gen_rtx_SUBREG (HImode, part_bytes_reg, 0));
emit_move_insn (mem, gen_lowpart (HImode, part_bytes_reg));
last_bytes -= 2;
if (last_bytes)
{
@ -4581,7 +4581,7 @@ arm_gen_movstrqi (operands)
RTX_UNCHANGING_P (mem) = dst_unchanging_p;
MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
MEM_SCALAR_P (mem) = dst_scalar_p;
emit_move_insn (mem, gen_rtx_SUBREG (QImode, part_bytes_reg, 0));
emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg));
}
}
@ -5119,23 +5119,23 @@ arm_reload_out_hi (operands)
{
emit_insn (gen_movqi (gen_rtx_MEM (QImode,
plus_constant (base, offset + 1)),
gen_rtx_SUBREG (QImode, outval, 0)));
gen_lowpart (QImode, outval)));
emit_insn (gen_lshrsi3 (scratch,
gen_rtx_SUBREG (SImode, outval, 0),
GEN_INT (8)));
emit_insn (gen_movqi (gen_rtx_MEM (QImode, plus_constant (base, offset)),
gen_rtx_SUBREG (QImode, scratch, 0)));
gen_lowpart (QImode, scratch)));
}
else
{
emit_insn (gen_movqi (gen_rtx_MEM (QImode, plus_constant (base, offset)),
gen_rtx_SUBREG (QImode, outval, 0)));
gen_lowpart (QImode, outval)));
emit_insn (gen_lshrsi3 (scratch,
gen_rtx_SUBREG (SImode, outval, 0),
GEN_INT (8)));
emit_insn (gen_movqi (gen_rtx_MEM (QImode,
plus_constant (base, offset + 1)),
gen_rtx_SUBREG (QImode, scratch, 0)));
gen_lowpart (QImode, scratch)));
}
}

View File

@ -3390,7 +3390,7 @@
[(set (match_operand:SI 0 "s_register_operand" "")
(zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
(clobber (match_operand:SI 2 "s_register_operand" ""))]
"TARGET_ARM && (GET_CODE (operands[1]) != MEM)"
"TARGET_ARM && (GET_CODE (operands[1]) != MEM) && ! BYTES_BIG_ENDIAN"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
""
@ -4288,7 +4288,7 @@
[(set (match_dup 4) (match_dup 3))
(set (match_dup 2)
(ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
(set (match_operand 1 "" "") (subreg:QI (match_dup 2) 0))]
(set (match_operand 1 "" "") (subreg:QI (match_dup 2) 3))]
"TARGET_ARM"
"
{
@ -4312,7 +4312,7 @@
(define_expand "storeinthi"
[(set (match_operand 0 "" "")
(subreg:QI (match_operand 1 "" "") 0))
(set (match_dup 3) (subreg:QI (match_dup 2) 0))]
(set (match_dup 3) (match_dup 2))]
"TARGET_ARM"
"
{
@ -4351,6 +4351,7 @@
operands[3] = adjust_address (op0, QImode, 1);
operands[0] = adjust_address (operands[0], QImode, 0);
operands[2] = gen_lowpart (QImode, operands[2]);
}"
)
@ -4413,7 +4414,7 @@
}
emit_insn (gen_movsi (reg, GEN_INT (val)));
operands[1] = gen_rtx_SUBREG (HImode, reg, 0);
operands[1] = gen_lowpart (HImode, reg);
}
else if (!arm_arch4)
{
@ -4810,7 +4811,7 @@
rtx reg = gen_reg_rtx (SImode);
emit_insn (gen_movsi (reg, operands[1]));
operands[1] = gen_rtx_SUBREG (QImode, reg, 0);
operands[1] = gen_lowpart (QImode, reg);
}
if (GET_CODE (operands[0]) == MEM)
operands[1] = force_reg (QImode, operands[1]);
@ -4853,7 +4854,7 @@
if (GET_CODE (operands[0]) != REG)
abort ();
operands[0] = gen_rtx (SUBREG, SImode, operands[0], 0);
operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
emit_insn (gen_movsi (operands[0], operands[1]));
DONE;
}

View File

@ -33,9 +33,6 @@ extern HOST_WIDE_INT ix86_initial_elimination_offset PARAMS((int, int));
extern void ix86_expand_prologue PARAMS ((void));
extern void ix86_expand_epilogue PARAMS ((int));
extern void ix86_output_function_block_profiler PARAMS ((FILE *, int));
extern void ix86_output_block_profiler PARAMS ((FILE *, int));
extern void ix86_output_addr_vec_elt PARAMS ((FILE *, int));
extern void ix86_output_addr_diff_elt PARAMS ((FILE *, int, int));
@ -197,4 +194,6 @@ extern tree ix86_handle_shared_attribute PARAMS ((tree *, tree, tree, int, bool
extern unsigned int i386_pe_section_type_flags PARAMS ((tree, const char *,
int));
extern void i386_pe_asm_named_section PARAMS ((const char *, unsigned int));
extern void x86_output_mi_thunk PARAMS ((FILE *, int, tree));
extern int x86_field_alignment PARAMS ((tree, int));
#endif

View File

@ -457,7 +457,7 @@ static int const x86_64_int_return_registers[4] = {0 /*RAX*/, 1 /*RDI*/, 5, 4};
int const dbx64_register_map[FIRST_PSEUDO_REGISTER] =
{
0, 1, 2, 3, 4, 5, 6, 7, /* general regs */
33, 34, 35, 36, 37, 38, 39, 40 /* fp regs */
33, 34, 35, 36, 37, 38, 39, 40, /* fp regs */
-1, -1, -1, -1, -1, /* arg, flags, fpsr, dir, frame */
17, 18, 19, 20, 21, 22, 23, 24, /* SSE */
41, 42, 43, 44, 45, 46, 47, 48, /* MMX */
@ -1675,6 +1675,34 @@ classify_argument (mode, type, classes, bit_offset)
/* Classify each field of record and merge classes. */
if (TREE_CODE (type) == RECORD_TYPE)
{
/* For classes first merge in the field of the subclasses. */
if (TYPE_BINFO (type) != NULL && TYPE_BINFO_BASETYPES (type) != NULL)
{
tree bases = TYPE_BINFO_BASETYPES (type);
int n_bases = TREE_VEC_LENGTH (bases);
int i;
for (i = 0; i < n_bases; ++i)
{
tree binfo = TREE_VEC_ELT (bases, i);
int num;
int offset = tree_low_cst (BINFO_OFFSET (binfo), 0) * 8;
tree type = BINFO_TYPE (binfo);
num = classify_argument (TYPE_MODE (type),
type, subclasses,
(offset + bit_offset) % 256);
if (!num)
return 0;
for (i = 0; i < num; i++)
{
int pos = (offset + bit_offset) / 8 / 8;
classes[i + pos] =
merge_classes (subclasses[i], classes[i + pos]);
}
}
}
/* And now merge the fields of structure. */
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
{
if (TREE_CODE (field) == FIELD_DECL)
@ -1735,6 +1763,33 @@ classify_argument (mode, type, classes, bit_offset)
else if (TREE_CODE (type) == UNION_TYPE
|| TREE_CODE (type) == QUAL_UNION_TYPE)
{
/* For classes first merge in the field of the subclasses. */
if (TYPE_BINFO (type) != NULL && TYPE_BINFO_BASETYPES (type) != NULL)
{
tree bases = TYPE_BINFO_BASETYPES (type);
int n_bases = TREE_VEC_LENGTH (bases);
int i;
for (i = 0; i < n_bases; ++i)
{
tree binfo = TREE_VEC_ELT (bases, i);
int num;
int offset = tree_low_cst (BINFO_OFFSET (binfo), 0) * 8;
tree type = BINFO_TYPE (binfo);
num = classify_argument (TYPE_MODE (type),
type, subclasses,
(offset + bit_offset) % 256);
if (!num)
return 0;
for (i = 0; i < num; i++)
{
int pos = (offset + bit_offset) / 8 / 8;
classes[i + pos] =
merge_classes (subclasses[i], classes[i + pos]);
}
}
}
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
{
if (TREE_CODE (field) == FIELD_DECL)
@ -2841,6 +2896,18 @@ const_int_1_operand (op, mode)
return (GET_CODE (op) == CONST_INT && INTVAL (op) == 1);
}
/* Return nonzero if OP is CONST_INT >= 1 and <= 31 (a valid operand
for shift & compare patterns, as shifting by 0 does not change flags),
else return zero. */
int
const_int_1_31_operand (op, mode)
rtx op;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
return (GET_CODE (op) == CONST_INT && INTVAL (op) >= 1 && INTVAL (op) <= 31);
}
/* Returns 1 if OP is either a symbol reference or a sum of a symbol
reference and a constant. */
@ -3863,9 +3930,6 @@ load_pic_register ()
emit_insn (gen_prologue_get_pc (pic_offset_table_rtx, pclab));
if (! TARGET_DEEP_BRANCH_PREDICTION)
emit_insn (gen_popsi1 (pic_offset_table_rtx));
emit_insn (gen_prologue_set_got (pic_offset_table_rtx, gotsym, pclab));
}
@ -4015,8 +4079,9 @@ ix86_compute_frame_layout (frame)
offset += size;
/* Add outgoing arguments area. */
if (ACCUMULATE_OUTGOING_ARGS)
/* Add outgoing arguments area. Can be skipped if we eliminated
all the function calls as dead code. */
if (ACCUMULATE_OUTGOING_ARGS && !current_function_is_leaf)
{
offset += current_function_outgoing_args_size;
frame->outgoing_arguments_size = current_function_outgoing_args_size;
@ -4024,9 +4089,13 @@ ix86_compute_frame_layout (frame)
else
frame->outgoing_arguments_size = 0;
/* Align stack boundary. */
frame->padding2 = ((offset + preferred_alignment - 1)
& -preferred_alignment) - offset;
/* Align stack boundary. Only needed if we're calling another function
or using alloca. */
if (!current_function_is_leaf || current_function_calls_alloca)
frame->padding2 = ((offset + preferred_alignment - 1)
& -preferred_alignment) - offset;
else
frame->padding2 = 0;
offset += frame->padding2;
@ -7958,7 +8027,12 @@ ix86_expand_int_movcc (operands)
if ((code == LEU || code == GTU)
&& GET_CODE (ix86_compare_op1) == CONST_INT
&& mode != HImode
&& (unsigned int) INTVAL (ix86_compare_op1) != 0xffffffff
&& INTVAL (ix86_compare_op1) != -1
/* For x86-64, the immediate field in the instruction is 32-bit
signed, so we can't increment a DImode value above 0x7fffffff. */
&& (!TARGET_64BIT
|| GET_MODE (ix86_compare_op0) != DImode
|| INTVAL (ix86_compare_op1) != 0x7fffffff)
&& GET_CODE (operands[2]) == CONST_INT
&& GET_CODE (operands[3]) == CONST_INT)
{
@ -7966,7 +8040,8 @@ ix86_expand_int_movcc (operands)
code = LTU;
else
code = GEU;
ix86_compare_op1 = GEN_INT (INTVAL (ix86_compare_op1) + 1);
ix86_compare_op1 = gen_int_mode (INTVAL (ix86_compare_op1) + 1,
GET_MODE (ix86_compare_op0));
}
start_sequence ();
@ -9130,6 +9205,9 @@ ix86_expand_movstr (dst, src, count_exp, align_exp)
{
rtx countreg2;
rtx label = NULL;
int desired_alignment = (TARGET_PENTIUMPRO
&& (count == 0 || count >= (unsigned int) 260)
? 8 : UNITS_PER_WORD);
/* In case we don't know anything about the alignment, default to
library version, since it is usually equally fast and result in
@ -9159,13 +9237,10 @@ ix86_expand_movstr (dst, src, count_exp, align_exp)
This is quite costy. Maybe we can revisit this decision later or
add some customizability to this code. */
if (count == 0
&& align < (TARGET_PENTIUMPRO && (count == 0
|| count >= (unsigned int) 260)
? 8 : UNITS_PER_WORD))
if (count == 0 && align < desired_alignment)
{
label = gen_label_rtx ();
emit_cmp_and_jump_insns (countreg, GEN_INT (UNITS_PER_WORD - 1),
emit_cmp_and_jump_insns (countreg, GEN_INT (desired_alignment - 1),
LEU, 0, counter_mode, 1, label);
}
if (align <= 1)
@ -9184,10 +9259,7 @@ ix86_expand_movstr (dst, src, count_exp, align_exp)
emit_label (label);
LABEL_NUSES (label) = 1;
}
if (align <= 4
&& ((TARGET_PENTIUMPRO && (count == 0
|| count >= (unsigned int) 260))
|| TARGET_64BIT))
if (align <= 4 && desired_alignment > 4)
{
rtx label = ix86_expand_aligntest (destreg, 4);
emit_insn (gen_strmovsi (destreg, srcreg));
@ -9196,6 +9268,12 @@ ix86_expand_movstr (dst, src, count_exp, align_exp)
LABEL_NUSES (label) = 1;
}
if (label && desired_alignment > 4 && !TARGET_64BIT)
{
emit_label (label);
LABEL_NUSES (label) = 1;
label = NULL_RTX;
}
if (!TARGET_SINGLE_STRINGOP)
emit_insn (gen_cld ());
if (TARGET_64BIT)
@ -9341,6 +9419,10 @@ ix86_expand_clrstr (src, count_exp, align_exp)
{
rtx countreg2;
rtx label = NULL;
/* Compute desired alignment of the string operation. */
int desired_alignment = (TARGET_PENTIUMPRO
&& (count == 0 || count >= (unsigned int) 260)
? 8 : UNITS_PER_WORD);
/* In case we don't know anything about the alignment, default to
library version, since it is usually equally fast and result in
@ -9355,13 +9437,10 @@ ix86_expand_clrstr (src, count_exp, align_exp)
countreg = copy_to_mode_reg (counter_mode, count_exp);
zeroreg = copy_to_mode_reg (Pmode, const0_rtx);
if (count == 0
&& align < (TARGET_PENTIUMPRO && (count == 0
|| count >= (unsigned int) 260)
? 8 : UNITS_PER_WORD))
if (count == 0 && align < desired_alignment)
{
label = gen_label_rtx ();
emit_cmp_and_jump_insns (countreg, GEN_INT (UNITS_PER_WORD - 1),
emit_cmp_and_jump_insns (countreg, GEN_INT (desired_alignment - 1),
LEU, 0, counter_mode, 1, label);
}
if (align <= 1)
@ -9382,8 +9461,7 @@ ix86_expand_clrstr (src, count_exp, align_exp)
emit_label (label);
LABEL_NUSES (label) = 1;
}
if (align <= 4 && TARGET_PENTIUMPRO && (count == 0
|| count >= (unsigned int) 260))
if (align <= 4 && desired_alignment > 4)
{
rtx label = ix86_expand_aligntest (destreg, 4);
emit_insn (gen_strsetsi (destreg, (TARGET_64BIT
@ -9394,6 +9472,13 @@ ix86_expand_clrstr (src, count_exp, align_exp)
LABEL_NUSES (label) = 1;
}
if (label && desired_alignment > 4 && !TARGET_64BIT)
{
emit_label (label);
LABEL_NUSES (label) = 1;
label = NULL_RTX;
}
if (!TARGET_SINGLE_STRINGOP)
emit_insn (gen_cld ());
if (TARGET_64BIT)
@ -9409,18 +9494,18 @@ ix86_expand_clrstr (src, count_exp, align_exp)
emit_insn (gen_rep_stossi (destreg, countreg2, zeroreg,
destreg, countreg2));
}
if (label)
{
emit_label (label);
LABEL_NUSES (label) = 1;
}
if (TARGET_64BIT && align > 4 && count != 0 && (count & 4))
emit_insn (gen_strsetsi (destreg,
gen_rtx_SUBREG (SImode, zeroreg, 0)));
if (TARGET_64BIT && (align <= 4 || count == 0))
{
rtx label = ix86_expand_aligntest (destreg, 2);
rtx label = ix86_expand_aligntest (countreg, 4);
emit_insn (gen_strsetsi (destreg,
gen_rtx_SUBREG (SImode, zeroreg, 0)));
emit_label (label);
@ -9431,7 +9516,7 @@ ix86_expand_clrstr (src, count_exp, align_exp)
gen_rtx_SUBREG (HImode, zeroreg, 0)));
if (align <= 2 || count == 0)
{
rtx label = ix86_expand_aligntest (destreg, 2);
rtx label = ix86_expand_aligntest (countreg, 2);
emit_insn (gen_strsethi (destreg,
gen_rtx_SUBREG (HImode, zeroreg, 0)));
emit_label (label);
@ -9442,7 +9527,7 @@ ix86_expand_clrstr (src, count_exp, align_exp)
gen_rtx_SUBREG (QImode, zeroreg, 0)));
if (align <= 1 || count == 0)
{
rtx label = ix86_expand_aligntest (destreg, 1);
rtx label = ix86_expand_aligntest (countreg, 1);
emit_insn (gen_strsetqi (destreg,
gen_rtx_SUBREG (QImode, zeroreg, 0)));
emit_label (label);
@ -12473,3 +12558,97 @@ x86_order_regs_for_local_alloc ()
while (pos < FIRST_PSEUDO_REGISTER)
reg_alloc_order [pos++] = 0;
}
void
x86_output_mi_thunk (file, delta, function)
FILE *file;
int delta;
tree function;
{
tree parm;
rtx xops[3];
if (ix86_regparm > 0)
parm = TYPE_ARG_TYPES (TREE_TYPE (function));
else
parm = NULL_TREE;
for (; parm; parm = TREE_CHAIN (parm))
if (TREE_VALUE (parm) == void_type_node)
break;
xops[0] = GEN_INT (delta);
if (TARGET_64BIT)
{
int n = aggregate_value_p (TREE_TYPE (TREE_TYPE (function))) != 0;
xops[1] = gen_rtx_REG (DImode, x86_64_int_parameter_registers[n]);
output_asm_insn ("add{q} {%0, %1|%1, %0}", xops);
if (flag_pic)
{
fprintf (file, "\tjmp *");
assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
fprintf (file, "@GOTPCREL(%%rip)\n");
}
else
{
fprintf (file, "\tjmp ");
assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
fprintf (file, "\n");
}
}
else
{
if (parm)
xops[1] = gen_rtx_REG (SImode, 0);
else if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function))))
xops[1] = gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 8));
else
xops[1] = gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 4));
output_asm_insn ("add{l} {%0, %1|%1, %0}", xops);
if (flag_pic)
{
xops[0] = pic_offset_table_rtx;
xops[1] = gen_label_rtx ();
xops[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
if (ix86_regparm > 2)
abort ();
output_asm_insn ("push{l}\t%0", xops);
output_asm_insn ("call\t%P1", xops);
ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (xops[1]));
output_asm_insn ("pop{l}\t%0", xops);
output_asm_insn
("add{l}\t{%2+[.-%P1], %0|%0, OFFSET FLAT: %2+[.-%P1]}", xops);
xops[0] = gen_rtx_MEM (SImode, XEXP (DECL_RTL (function), 0));
output_asm_insn
("mov{l}\t{%0@GOT(%%ebx), %%ecx|%%ecx, %0@GOT[%%ebx]}", xops);
asm_fprintf (file, "\tpop{l\t%%ebx|\t%%ebx}\n");
asm_fprintf (file, "\tjmp\t{*%%ecx|%%ecx}\n");
}
else
{
fprintf (file, "\tjmp ");
assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
fprintf (file, "\n");
}
}
}
int
x86_field_alignment (field, computed)
tree field;
int computed;
{
enum machine_mode mode;
tree type = TREE_TYPE (field);
if (TARGET_64BIT || TARGET_ALIGN_DOUBLE)
return computed;
mode = TYPE_MODE (TREE_CODE (type) == ARRAY_TYPE
? get_inner_array_type (type) : type);
if (mode == DFmode || mode == DCmode
|| GET_MODE_CLASS (mode) == MODE_INT
|| GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
return MIN (32, computed);
return computed;
}

View File

@ -609,7 +609,7 @@ extern int ix86_arch;
%{mcpu=athlon-4|mcpu=athlon-xp|mcpu=athlon-mp:\
-D__tune_athlon_sse__ }\
%{mcpu=pentium4:-D__tune_pentium4__ }\
%{march=athlon-tbird|march=athlon-xp|march=athlon-mp|march=pentium3|march=pentium4:\
%{march=athlon-xp|march=athlon-mp|march=pentium3|march=pentium4:\
-D__SSE__ }\
%{march=pentium-mmx|march=k6|march=k6-2|march=k6-3\
|march=athlon|march=athlon-tbird|march=athlon-4|march=athlon-xp\
@ -781,12 +781,15 @@ extern int ix86_arch;
/* The published ABIs say that doubles should be aligned on word
boundaries, so lower the aligment for structure fields unless
-malign-double is set. */
/* BIGGEST_FIELD_ALIGNMENT is also used in libobjc, where it must be
constant. Use the smaller value in that context. */
#ifndef IN_TARGET_LIBS
#define BIGGEST_FIELD_ALIGNMENT (TARGET_64BIT ? 128 : (TARGET_ALIGN_DOUBLE ? 64 : 32))
#else
/* ??? Blah -- this macro is used directly by libobjc. Since it
supports no vector modes, cut out the complexity and fall back
on BIGGEST_FIELD_ALIGNMENT. */
#ifdef IN_TARGET_LIBS
#define BIGGEST_FIELD_ALIGNMENT 32
#else
#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
x86_field_alignment (FIELD, COMPUTED)
#endif
/* If defined, a C expression to compute the alignment given to a
@ -3026,6 +3029,7 @@ extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER];
SYMBOL_REF, LABEL_REF}}, \
{"shiftdi_operand", {SUBREG, REG, MEM}}, \
{"const_int_1_operand", {CONST_INT}}, \
{"const_int_1_31_operand", {CONST_INT}}, \
{"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST}}, \
{"aligned_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, \
LABEL_REF, SUBREG, REG, MEM}}, \

View File

@ -2014,7 +2014,7 @@
;; For 64BIT abi we always round up to 8 bytes.
(define_insn "*pushqi2_rex64"
[(set (match_operand:QI 0 "push_operand" "=X")
(match_operand:QI 1 "nonmemory_no_elim_operand" "ri"))]
(match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
"TARGET_64BIT"
"push{q}\t%q1"
[(set_attr "type" "push")
@ -2555,17 +2555,16 @@
;; We fake an second form of instruction to force reload to load address
;; into register when rax is not available
(define_insn "*movabsdi_1_rex64"
[(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
(match_operand:DI 1 "nonmemory_operand" "a,er,i"))]
[(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
(match_operand:DI 1 "nonmemory_operand" "a,er"))]
"TARGET_64BIT"
"@
movabs{q}\t{%1, %P0|%P0, %1}
mov{q}\t{%1, %a0|%a0, %1}
movabs{q}\t{%1, %a0|%a0, %1}"
mov{q}\t{%1, %a0|%a0, %1}"
[(set_attr "type" "imov")
(set_attr "modrm" "0,*,*")
(set_attr "length_address" "8,0,0")
(set_attr "length_immediate" "0,*,*")
(set_attr "modrm" "0,*")
(set_attr "length_address" "8,0")
(set_attr "length_immediate" "0,*")
(set_attr "memory" "store")
(set_attr "mode" "DI")])
@ -10951,7 +10950,7 @@
[(set (reg 17)
(compare
(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "immediate_operand" "I"))
(match_operand:QI 2 "const_int_1_31_operand" "I"))
(const_int 0)))
(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(ashift:SI (match_dup 1) (match_dup 2)))]
@ -10990,7 +10989,7 @@
[(set (reg 17)
(compare
(ashift:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:QI 2 "immediate_operand" "I"))
(match_operand:QI 2 "const_int_1_31_operand" "I"))
(const_int 0)))
(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
@ -11115,7 +11114,7 @@
[(set (reg 17)
(compare
(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "immediate_operand" "I"))
(match_operand:QI 2 "const_int_1_31_operand" "I"))
(const_int 0)))
(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(ashift:HI (match_dup 1) (match_dup 2)))]
@ -11279,7 +11278,7 @@
[(set (reg 17)
(compare
(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "immediate_operand" "I"))
(match_operand:QI 2 "const_int_1_31_operand" "I"))
(const_int 0)))
(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(ashift:QI (match_dup 1) (match_dup 2)))]
@ -11629,7 +11628,7 @@
[(set (reg 17)
(compare
(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "immediate_operand" "I"))
(match_operand:QI 2 "const_int_1_31_operand" "I"))
(const_int 0)))
(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(ashiftrt:SI (match_dup 1) (match_dup 2)))]
@ -11643,7 +11642,7 @@
[(set (reg 17)
(compare
(ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:QI 2 "immediate_operand" "I"))
(match_operand:QI 2 "const_int_1_31_operand" "I"))
(const_int 0)))
(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
@ -11715,7 +11714,7 @@
[(set (reg 17)
(compare
(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "immediate_operand" "I"))
(match_operand:QI 2 "const_int_1_31_operand" "I"))
(const_int 0)))
(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(ashiftrt:HI (match_dup 1) (match_dup 2)))]
@ -11768,7 +11767,7 @@
(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "const_int_1_operand" "I"))
(const_int 0)))
(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(ashiftrt:QI (match_dup 1) (match_dup 2)))]
"ix86_match_ccmode (insn, CCGOCmode)
&& (TARGET_PENTIUM || TARGET_PENTIUMPRO)
@ -11787,9 +11786,9 @@
[(set (reg 17)
(compare
(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "immediate_operand" "I"))
(match_operand:QI 2 "const_int_1_31_operand" "I"))
(const_int 0)))
(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(ashiftrt:QI (match_dup 1) (match_dup 2)))]
"ix86_match_ccmode (insn, CCGOCmode)
&& ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
@ -12020,7 +12019,7 @@
[(set (reg 17)
(compare
(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "immediate_operand" "I"))
(match_operand:QI 2 "const_int_1_31_operand" "I"))
(const_int 0)))
(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(lshiftrt:SI (match_dup 1) (match_dup 2)))]
@ -12034,7 +12033,7 @@
[(set (reg 17)
(compare
(lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:QI 2 "immediate_operand" "I"))
(match_operand:QI 2 "const_int_1_31_operand" "I"))
(const_int 0)))
(set (match_operand:DI 0 "register_operand" "=r")
(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
@ -12106,7 +12105,7 @@
[(set (reg 17)
(compare
(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "immediate_operand" "I"))
(match_operand:QI 2 "const_int_1_31_operand" "I"))
(const_int 0)))
(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(lshiftrt:HI (match_dup 1) (match_dup 2)))]
@ -12178,7 +12177,7 @@
[(set (reg 17)
(compare
(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "immediate_operand" "I"))
(match_operand:QI 2 "const_int_1_31_operand" "I"))
(const_int 0)))
(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(lshiftrt:QI (match_dup 1) (match_dup 2)))]
@ -13816,6 +13815,7 @@
{
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
CODE_LABEL_NUMBER (operands[1]));
return "pop{l}\t%0";
}
RET;
}
@ -16576,12 +16576,12 @@
"#")
(define_insn "sse_movdfcc"
[(set (match_operand:DF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
[(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?f#Yr,?f#Yr,?r#Yf,?r#Yf,?r#Yf,?r#Yf")
(if_then_else:DF (match_operator 1 "sse_comparison_operator"
[(match_operand:DF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
(match_operand:DF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
(match_operand:DF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
(match_operand:DF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
[(match_operand:DF 4 "nonimmediate_operand" "0#fY,Y#fY,f#Y,f#Y,Ym#f,Ym#f,f#Y,f#Y,Ym#f,Ym#f")
(match_operand:DF 5 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,f#Y,Y#f,Y#f,f#Y,f#Y,Y#f,Y#f")])
(match_operand:DF 2 "nonimmediate_operand" "Y#fr,0#fr,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY,0#rY")
(match_operand:DF 3 "nonimmediate_operand" "Y#fr,Y#fr,0#fY,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY")))
(clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
(clobber (reg:CC 17))]
"TARGET_SSE2
@ -16591,11 +16591,11 @@
"#")
(define_insn "sse_movdfcc_eq"
[(set (match_operand:DF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
(if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
(match_operand:DF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
(match_operand:DF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
(match_operand:DF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
[(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
(if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
(match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
(match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
(match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
(clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
(clobber (reg:CC 17))]
"TARGET_SSE
@ -16647,6 +16647,10 @@
(set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
(subreg:TI (match_dup 7) 0)))]
{
/* If op2 == op3, op3 will be clobbered before it is used.
This should be optimized out though. */
if (operands_match_p (operands[2], operands[3]))
abort ();
PUT_MODE (operands[1], GET_MODE (operands[0]));
if (operands_match_p (operands[0], operands[4]))
operands[6] = operands[4], operands[7] = operands[2];
@ -16658,7 +16662,7 @@
;; Do not brother with the integer/floating point case, since these are
;; bot considerably slower, unlike in the generic case.
(define_insn "*sse_movsfcc_const0_1"
[(set (match_operand:SF 0 "register_operand" "=x")
[(set (match_operand:SF 0 "register_operand" "=&x")
(if_then_else:SF (match_operator 1 "sse_comparison_operator"
[(match_operand:SF 4 "register_operand" "0")
(match_operand:SF 5 "nonimmediate_operand" "xm")])
@ -16668,7 +16672,7 @@
"#")
(define_insn "*sse_movsfcc_const0_2"
[(set (match_operand:SF 0 "register_operand" "=x")
[(set (match_operand:SF 0 "register_operand" "=&x")
(if_then_else:SF (match_operator 1 "sse_comparison_operator"
[(match_operand:SF 4 "register_operand" "0")
(match_operand:SF 5 "nonimmediate_operand" "xm")])
@ -16678,7 +16682,7 @@
"#")
(define_insn "*sse_movsfcc_const0_3"
[(set (match_operand:SF 0 "register_operand" "=x")
[(set (match_operand:SF 0 "register_operand" "=&x")
(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
[(match_operand:SF 4 "nonimmediate_operand" "xm")
(match_operand:SF 5 "register_operand" "0")])
@ -16688,7 +16692,7 @@
"#")
(define_insn "*sse_movsfcc_const0_4"
[(set (match_operand:SF 0 "register_operand" "=x")
[(set (match_operand:SF 0 "register_operand" "=&x")
(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
[(match_operand:SF 4 "nonimmediate_operand" "xm")
(match_operand:SF 5 "register_operand" "0")])
@ -16698,42 +16702,42 @@
"#")
(define_insn "*sse_movdfcc_const0_1"
[(set (match_operand:SF 0 "register_operand" "=x")
(if_then_else:SF (match_operator 1 "sse_comparison_operator"
[(match_operand:SF 4 "register_operand" "0")
(match_operand:SF 5 "nonimmediate_operand" "xm")])
(match_operand:SF 2 "register_operand" "x")
(match_operand:SF 3 "const0_operand" "X")))]
[(set (match_operand:DF 0 "register_operand" "=&Y")
(if_then_else:DF (match_operator 1 "sse_comparison_operator"
[(match_operand:DF 4 "register_operand" "0")
(match_operand:DF 5 "nonimmediate_operand" "Ym")])
(match_operand:DF 2 "register_operand" "Y")
(match_operand:DF 3 "const0_operand" "X")))]
"TARGET_SSE2"
"#")
(define_insn "*sse_movdfcc_const0_2"
[(set (match_operand:SF 0 "register_operand" "=x")
(if_then_else:SF (match_operator 1 "sse_comparison_operator"
[(match_operand:SF 4 "register_operand" "0")
(match_operand:SF 5 "nonimmediate_operand" "xm")])
(match_operand:SF 2 "const0_operand" "X")
(match_operand:SF 3 "register_operand" "x")))]
[(set (match_operand:DF 0 "register_operand" "=&Y")
(if_then_else:DF (match_operator 1 "sse_comparison_operator"
[(match_operand:DF 4 "register_operand" "0")
(match_operand:DF 5 "nonimmediate_operand" "Ym")])
(match_operand:DF 2 "const0_operand" "X")
(match_operand:DF 3 "register_operand" "Y")))]
"TARGET_SSE2"
"#")
(define_insn "*sse_movdfcc_const0_3"
[(set (match_operand:SF 0 "register_operand" "=x")
(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
[(match_operand:SF 4 "nonimmediate_operand" "xm")
(match_operand:SF 5 "register_operand" "0")])
(match_operand:SF 2 "register_operand" "x")
(match_operand:SF 3 "const0_operand" "X")))]
[(set (match_operand:DF 0 "register_operand" "=&Y")
(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
[(match_operand:DF 4 "nonimmediate_operand" "Ym")
(match_operand:DF 5 "register_operand" "0")])
(match_operand:DF 2 "register_operand" "Y")
(match_operand:DF 3 "const0_operand" "X")))]
"TARGET_SSE2"
"#")
(define_insn "*sse_movdfcc_const0_4"
[(set (match_operand:SF 0 "register_operand" "=x")
(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
[(match_operand:SF 4 "nonimmediate_operand" "xm")
(match_operand:SF 5 "register_operand" "0")])
(match_operand:SF 2 "const0_operand" "X")
(match_operand:SF 3 "register_operand" "x")))]
[(set (match_operand:DF 0 "register_operand" "=&Y")
(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
[(match_operand:DF 4 "nonimmediate_operand" "Ym")
(match_operand:DF 5 "register_operand" "0")])
(match_operand:DF 2 "const0_operand" "X")
(match_operand:DF 3 "register_operand" "Y")))]
"TARGET_SSE2"
"#")
@ -19779,7 +19783,7 @@
[(set_attr "type" "mmx")])
(define_expand "prefetch"
[(prefetch (match_operand:SI 0 "address_operand" "")
[(prefetch (match_operand 0 "address_operand" "")
(match_operand:SI 1 "const_int_operand" "")
(match_operand:SI 2 "const_int_operand" ""))]
"TARGET_PREFETCH_SSE || TARGET_3DNOW"
@ -19791,6 +19795,8 @@
abort ();
if (locality < 0 || locality > 3)
abort ();
if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
abort ();
/* Use 3dNOW prefetch in case we are asking for write prefetch not
suported by SSE counterpart or the SSE prefetch is not available
@ -19806,7 +19812,26 @@
[(prefetch (match_operand:SI 0 "address_operand" "p")
(const_int 0)
(match_operand:SI 1 "const_int_operand" ""))]
"TARGET_PREFETCH_SSE"
"TARGET_PREFETCH_SSE && !TARGET_64BIT"
{
static const char * const patterns[4] = {
"prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
};
int locality = INTVAL (operands[1]);
if (locality < 0 || locality > 3)
abort ();
return patterns[locality];
}
[(set_attr "type" "sse")
(set_attr "memory" "none")])
(define_insn "*prefetch_sse_rex"
[(prefetch (match_operand:DI 0 "address_operand" "p")
(const_int 0)
(match_operand:SI 1 "const_int_operand" ""))]
"TARGET_PREFETCH_SSE && TARGET_64BIT"
{
static const char * const patterns[4] = {
"prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
@ -19824,7 +19849,21 @@
[(prefetch (match_operand:SI 0 "address_operand" "p")
(match_operand:SI 1 "const_int_operand" "n")
(const_int 3))]
"TARGET_3DNOW"
"TARGET_3DNOW && !TARGET_64BIT"
{
if (INTVAL (operands[1]) == 0)
return "prefetch\t%a0";
else
return "prefetchw\t%a0";
}
[(set_attr "type" "mmx")
(set_attr "memory" "none")])
(define_insn "*prefetch_3dnow_rex"
[(prefetch (match_operand:DI 0 "address_operand" "p")
(match_operand:SI 1 "const_int_operand" "n")
(const_int 3))]
"TARGET_3DNOW && TARGET_64BIT"
{
if (INTVAL (operands[1]) == 0)
return "prefetch\t%a0";

View File

@ -69,13 +69,16 @@ Boston, MA 02111-1307, USA. */
#define MULTILIB_DEFAULTS { "m64" }
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
state data appropriately. See unwind-dw2.c for the structs.
Don't use this at all if inhibit_libc is used. */
#ifndef inhibit_libc
#ifdef IN_LIBGCC2
#include <signal.h>
#include <sys/ucontext.h>
#endif
#ifdef __x86_64__
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
do { \
unsigned char *pc_ = (CONTEXT)->ra; \
@ -132,3 +135,59 @@ Boston, MA 02111-1307, USA. */
(FS)->retaddr_column = 16; \
goto SUCCESS; \
} while (0)
#else /* ifdef __x86_64__ */
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
do { \
unsigned char *pc_ = (CONTEXT)->ra; \
struct sigcontext *sc_; \
long new_cfa_; \
\
/* popl %eax ; movl $__NR_sigreturn,%eax ; int $0x80 */ \
if (*(unsigned short *)(pc_+0) == 0xb858 \
&& *(unsigned int *)(pc_+2) == 119 \
&& *(unsigned short *)(pc_+6) == 0x80cd) \
sc_ = (CONTEXT)->cfa + 4; \
/* movl $__NR_rt_sigreturn,%eax ; int $0x80 */ \
else if (*(unsigned char *)(pc_+0) == 0xb8 \
&& *(unsigned int *)(pc_+1) == 173 \
&& *(unsigned short *)(pc_+5) == 0x80cd) \
{ \
struct rt_sigframe { \
int sig; \
struct siginfo *pinfo; \
void *puc; \
struct siginfo info; \
struct ucontext uc; \
} *rt_ = (CONTEXT)->cfa; \
sc_ = (struct sigcontext *) &rt_->uc.uc_mcontext; \
} \
else \
break; \
\
new_cfa_ = sc_->esp; \
(FS)->cfa_how = CFA_REG_OFFSET; \
(FS)->cfa_reg = 4; \
(FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
\
/* The SVR4 register numbering macros aren't usable in libgcc. */ \
(FS)->regs.reg[0].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[0].loc.offset = (long)&sc_->eax - new_cfa_; \
(FS)->regs.reg[3].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[3].loc.offset = (long)&sc_->ebx - new_cfa_; \
(FS)->regs.reg[1].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[1].loc.offset = (long)&sc_->ecx - new_cfa_; \
(FS)->regs.reg[2].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[2].loc.offset = (long)&sc_->edx - new_cfa_; \
(FS)->regs.reg[6].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[6].loc.offset = (long)&sc_->esi - new_cfa_; \
(FS)->regs.reg[7].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[7].loc.offset = (long)&sc_->edi - new_cfa_; \
(FS)->regs.reg[5].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[5].loc.offset = (long)&sc_->ebp - new_cfa_; \
(FS)->regs.reg[8].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[8].loc.offset = (long)&sc_->eip - new_cfa_; \
(FS)->retaddr_column = 8; \
goto SUCCESS; \
} while (0)
#endif /* ifdef __x86_64__ */
#endif /* ifdef inhibit_libc */

View File

@ -31,7 +31,7 @@
#define _MMINTRIN_H_INCLUDED
/* The data type intended for user use. */
typedef unsigned long long __m64;
typedef unsigned long long __m64 __attribute__ ((__aligned__ (8)));
/* Internal data types for implementing the intrinsics. */
typedef int __v2si __attribute__ ((__mode__ (__V2SI__)));

View File

@ -48,6 +48,24 @@ Boston, MA 02111-1307, USA. */
"-D__NetBSD__ -D__ELF__ -Asystem=unix -Asystem=NetBSD"
/* Provide some extra CPP specs needed by NetBSD/x86_64. */
#define CPP_LP64_SPEC "%{!m32:-D_LP64}"
#define CPP_SUBTARGET_SPEC "%(cpp_lp64)"
#undef SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS \
{ "cpp_lp64", CPP_LP64_SPEC }, \
{ "cpp_subtarget", CPP_SUBTARGET_SPEC },
/* Provide a CPP_SPEC appropriate for NetBSD. Currently we deal with
our subtarget specs and the GCC option `-posix'. */
#undef CPP_SPEC
#define CPP_SPEC "%(cpp_cpu) %(cpp_subtarget) %{posix:-D_POSIX_SOURCE}"
/* Output assembler code to FILE to call the profiler. */
#undef FUNCTION_PROFILER

View File

@ -95,26 +95,11 @@ Boston, MA 02111-1307, USA. */
#undef ASM_PREFERRED_EH_DATA_FORMAT
/* Assembler format: alignment output. */
/* A C statement to output to the stdio stream FILE an assembler
command to advance the location counter to a multiple of 1<<LOG
bytes if it is within MAX_SKIP bytes.
This will be used to align code labels according to Intel
recommendations, in prevision of binutils upgrade. */
#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
do { \
if ((LOG) != 0) { \
if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
} \
} while (0)
#endif
/* Note that we pick up ASM_OUTPUT_MI_THUNK from unix.h. */
#undef ASM_COMMENT_START
#define ASM_COMMENT_START ";#"
/* OpenBSD gas currently does not support quad, so do not use it. */
#undef ASM_QUAD

View File

@ -79,57 +79,5 @@ Boston, MA 02111-1307, USA. */
/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
Used for C++ multiple inheritance. */
#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
do { \
tree parm; \
rtx xops[3]; \
\
if (ix86_regparm > 0) \
parm = TYPE_ARG_TYPES (TREE_TYPE (function)); \
else \
parm = NULL_TREE; \
for (; parm; parm = TREE_CHAIN (parm)) \
if (TREE_VALUE (parm) == void_type_node) \
break; \
\
xops[0] = GEN_INT (DELTA); \
if (parm) \
xops[1] = gen_rtx_REG (SImode, 0); \
else if (aggregate_value_p (TREE_TYPE (TREE_TYPE (FUNCTION)))) \
xops[1] = gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 8)); \
else \
xops[1] = gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 4)); \
output_asm_insn ("add{l} {%0, %1|%1, %0}", xops); \
\
if (flag_pic && !TARGET_64BIT) \
{ \
xops[0] = pic_offset_table_rtx; \
xops[1] = gen_label_rtx (); \
xops[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); \
\
if (ix86_regparm > 2) \
abort (); \
output_asm_insn ("push{l}\t%0", xops); \
output_asm_insn ("call\t%P1", xops); \
ASM_OUTPUT_INTERNAL_LABEL (FILE, "L", CODE_LABEL_NUMBER (xops[1])); \
output_asm_insn ("pop{l}\t%0", xops); \
output_asm_insn ("add{l}\t{%2+[.-%P1], %0|%0, OFFSET FLAT: %2+[.-%P1]}", xops); \
xops[0] = gen_rtx_MEM (SImode, XEXP (DECL_RTL (FUNCTION), 0)); \
output_asm_insn ("mov{l}\t{%0@GOT(%%ebx), %%ecx|%%ecx, %0@GOT[%%ebx]}",\
xops); \
asm_fprintf (FILE, "\tpop{l\t%%ebx|\t%%ebx}\n"); \
asm_fprintf (FILE, "\tjmp\t{*%%ecx|%%ecx}\n"); \
} \
else if (flag_pic && TARGET_64BIT) \
{ \
fprintf (FILE, "\tjmp *"); \
assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \
fprintf (FILE, "@GOTPCREL(%%rip)\n"); \
} \
else \
{ \
fprintf (FILE, "\tjmp "); \
assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \
fprintf (FILE, "\n"); \
} \
} while (0)
#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
x86_output_mi_thunk (FILE, DELTA, FUNCTION);

View File

@ -58,7 +58,7 @@
#include <sys/ucontext.h>
#define IA64_GATE_AREA_START 0xa000000000000100LL
#define IA64_GATE_AREA_END 0xa000000000010000LL
#define IA64_GATE_AREA_END 0xa000000000020000LL
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
if ((CONTEXT)->rp >= IA64_GATE_AREA_START \

View File

@ -140,45 +140,136 @@ do { \
emit_safe_across_calls (STREAM); \
} while (0)
/* A C statement or statements to switch to the appropriate
section for output of DECL. DECL is either a `VAR_DECL' node
or a constant of some sort. RELOC indicates whether forming
the initial value of DECL requires link-time relocations.
Set SECNUM to:
0 .text
1 .rodata
2 .data
3 .sdata
4 .bss
5 .sbss
*/
#define DO_SELECT_SECTION(SECNUM, DECL, RELOC) \
do \
{ \
if (TREE_CODE (DECL) == FUNCTION_DECL) \
SECNUM = 0; \
else if (TREE_CODE (DECL) == STRING_CST) \
{ \
if (! flag_writable_strings) \
SECNUM = 0x101; \
else \
SECNUM = 2; \
} \
else if (TREE_CODE (DECL) == VAR_DECL) \
{ \
if (XSTR (XEXP (DECL_RTL (DECL), 0), 0)[0] \
== SDATA_NAME_FLAG_CHAR) \
SECNUM = 3; \
/* ??? We need the extra RELOC check, because the default \
is to only check RELOC if flag_pic is set, and we don't \
set flag_pic (yet?). */ \
else if (!DECL_READONLY_SECTION (DECL, RELOC) || (RELOC)) \
SECNUM = 2; \
else if (flag_merge_constants < 2) \
/* C and C++ don't allow different variables to share \
the same location. -fmerge-all-constants allows \
even that (at the expense of not conforming). */ \
SECNUM = 1; \
else if (TREE_CODE (DECL_INITIAL (DECL)) == STRING_CST) \
SECNUM = 0x201; \
else \
SECNUM = 0x301; \
} \
/* This could be a CONSTRUCTOR containing ADDR_EXPR of a VAR_DECL, \
in which case we can't put it in a shared library rodata. */ \
else if (flag_pic && (RELOC)) \
SECNUM = 3; \
else \
SECNUM = 2; \
} \
while (0)
/* We override svr4.h so that we can support the sdata section. */
#undef SELECT_SECTION
#define SELECT_SECTION(DECL,RELOC,ALIGN) \
{ \
if (TREE_CODE (DECL) == STRING_CST) \
do \
{ \
if (! flag_writable_strings) \
mergeable_string_section ((DECL), (ALIGN), 0); \
else \
data_section (); \
typedef void (*sec_fn) PARAMS ((void)); \
static sec_fn const sec_functions[6] = \
{ \
text_section, \
const_section, \
data_section, \
sdata_section, \
bss_section, \
sbss_section \
}; \
\
int sec; \
\
DO_SELECT_SECTION (sec, DECL, RELOC); \
\
switch (sec) \
{ \
case 0x101: \
mergeable_string_section (DECL, ALIGN, 0); \
break; \
case 0x201: \
mergeable_string_section (DECL_INITIAL (DECL), \
ALIGN, 0); \
break; \
case 0x301: \
mergeable_constant_section (DECL_MODE (DECL), \
ALIGN, 0); \
break; \
default: \
(*sec_functions[sec]) (); \
break; \
} \
} \
else if (TREE_CODE (DECL) == VAR_DECL) \
while (0)
#undef UNIQUE_SECTION
#define UNIQUE_SECTION(DECL, RELOC) \
do \
{ \
if (XSTR (XEXP (DECL_RTL (DECL), 0), 0)[0] \
== SDATA_NAME_FLAG_CHAR) \
sdata_section (); \
/* ??? We need the extra RELOC check, because the default is to \
only check RELOC if flag_pic is set, and we don't set flag_pic \
(yet?). */ \
else if (!DECL_READONLY_SECTION (DECL, RELOC) || (RELOC)) \
data_section (); \
else if (flag_merge_constants < 2) \
/* C and C++ don't allow different variables to share \
the same location. -fmerge-all-constants allows \
even that (at the expense of not conforming). */ \
const_section (); \
else if (TREE_CODE (DECL_INITIAL (DECL)) == STRING_CST) \
mergeable_string_section (DECL_INITIAL (DECL), (ALIGN), 0); \
else \
mergeable_constant_section (DECL_MODE (DECL), (ALIGN), 0); \
static const char * const prefixes[6][2] = \
{ \
{ ".text.", ".gnu.linkonce.t." }, \
{ ".rodata.", ".gnu.linkonce.r." }, \
{ ".data.", ".gnu.linkonce.d." }, \
{ ".sdata.", ".gnu.linkonce.s." }, \
{ ".bss.", ".gnu.linkonce.b." }, \
{ ".sbss.", ".gnu.linkonce.sb." } \
}; \
\
int nlen, plen, sec; \
const char *name, *prefix; \
char *string; \
\
DO_SELECT_SECTION (sec, DECL, RELOC); \
\
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \
STRIP_NAME_ENCODING (name, name); \
nlen = strlen (name); \
\
prefix = prefixes[sec & 0xff][DECL_ONE_ONLY(DECL)]; \
plen = strlen (prefix); \
\
string = alloca (nlen + plen + 1); \
\
memcpy (string, prefix, plen); \
memcpy (string + plen, name, nlen + 1); \
\
DECL_SECTION_NAME (DECL) = build_string (nlen + plen, string); \
} \
/* This could be a CONSTRUCTOR containing ADDR_EXPR of a VAR_DECL, \
in which case we can't put it in a shared library rodata. */ \
else if (flag_pic && (RELOC)) \
data_section (); \
else \
const_section (); \
}
while (0)
/* Similarly for constant pool data. */

View File

@ -186,18 +186,15 @@ do { \
#undef LINK_SPEC
#define LINK_SPEC "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro} -bnodelcsect\
%{static:-bnso %(link_syscalls) } %{shared:-bM:SRE %{!e:-bnoentry}}\
%{!maix64:%{!shared:%{g*: %(link_libg) }}} %{maix64:-b64}"
%{!maix64:%{!shared:%{g*: %(link_libg) }}} %{maix64:-b64}\
%{mpe:-binitfini:poe_remote_main}"
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "%{!shared:\
%{mpe:%{pg:/usr/lpp/ppe.poe/lib/gcrt0.o}\
%{!pg:%{p:/usr/lpp/ppe.poe/lib/mcrt0.o}\
%{!p:/usr/lpp/ppe.poe/lib/crt0.o}}}\
%{!mpe:\
%{maix64:%{pg:gcrt0_64%O%s}%{!pg:%{p:mcrt0_64%O%s}%{!p:crt0_64%O%s}}}\
%{!maix64:\
%{pthread:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\
%{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}}"
%{maix64:%{pg:gcrt0_64%O%s}%{!pg:%{p:mcrt0_64%O%s}%{!p:crt0_64%O%s}}}\
%{!maix64:\
%{pthread:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\
%{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}"
/* AIX 4.3 typedefs ptrdiff_t as "long" while earlier releases used "int". */

View File

@ -189,18 +189,15 @@ do { \
#undef LINK_SPEC
#define LINK_SPEC "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro} -bnodelcsect\
%{static:-bnso %(link_syscalls) } %{shared:-bM:SRE %{!e:-bnoentry}}\
%{!maix64:%{!shared:%{g*: %(link_libg) }}} %{maix64:-b64}"
%{!maix64:%{!shared:%{g*: %(link_libg) }}} %{maix64:-b64}\
%{mpe:-binitfini:poe_remote_main}"
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "%{!shared:\
%{mpe:%{pg:/usr/lpp/ppe.poe/lib/gcrt0.o}\
%{!pg:%{p:/usr/lpp/ppe.poe/lib/mcrt0.o}\
%{!p:/usr/lpp/ppe.poe/lib/crt0.o}}}\
%{!mpe:\
%{maix64:%{pg:gcrt0_64%O%s}%{!pg:%{p:mcrt0_64%O%s}%{!p:crt0_64%O%s}}}\
%{!maix64:\
%{pthread:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\
%{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}}"
%{maix64:%{pg:gcrt0_64%O%s}%{!pg:%{p:mcrt0_64%O%s}%{!p:crt0_64%O%s}}}\
%{!maix64:\
%{pthread:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\
%{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}"
/* AIX V5 typedefs ptrdiff_t as "long" while earlier releases used "int". */

File diff suppressed because it is too large Load Diff

View File

@ -308,3 +308,22 @@ do { \
|| (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
&& ! TARGET_NO_FP_IN_TOC)))))
/* This is the same as the dbxelf.h version, except that we need to
use the function code label, not the function descriptor. */
#undef ASM_OUTPUT_SOURCE_LINE
#define ASM_OUTPUT_SOURCE_LINE(FILE, LINE) \
do \
{ \
static int sym_lineno = 1; \
char temp[256]; \
ASM_GENERATE_INTERNAL_LABEL (temp, "LM", sym_lineno); \
fprintf (FILE, "\t.stabn 68,0,%d,", LINE); \
assemble_name (FILE, temp); \
fputs ("-.", FILE); \
assemble_name (FILE, \
XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));\
putc ('\n', FILE); \
ASM_OUTPUT_INTERNAL_LABEL (FILE, "LM", sym_lineno); \
sym_lineno += 1; \
} \
while (0)

View File

@ -60,11 +60,6 @@ Boston, MA 02111-1307, USA. */
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC NetBSD/ELF)");
/* For backward compatibility, we must continue to use the AIX
structure return convention. */
#undef DRAFT_V4_STRUCT_RET
#define DRAFT_V4_STRUCT_RET 1
/* Use STABS debugging information by default. DWARF2 makes a mess of
the 1.5.2 linker. */
#undef PREFERRED_DEBUGGING_TYPE

View File

@ -9735,23 +9735,22 @@ output_mi_thunk (file, thunk_fndecl, delta, function)
fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta);
}
/* 64-bit constants. If "int" is 32 bits, we'll never hit this abort. */
else if (TARGET_64BIT && (delta < -2147483647 - 1 || delta > 2147483647))
abort ();
/* Large constants that can be done by one addis instruction. */
else if ((delta & 0xffff) == 0 && num_insns_constant_wide (delta) == 1)
else if ((delta & 0xffff) == 0)
asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
delta >> 16);
/* 32-bit constants that can be done by an add and addis instruction. */
else if (TARGET_32BIT || num_insns_constant_wide (delta) == 1)
else
{
/* Break into two pieces, propagating the sign bit from the low
word to the upper word. */
int delta_high = delta >> 16;
int delta_low = delta & 0xffff;
if ((delta_low & 0x8000) != 0)
{
delta_high++;
delta_low = (delta_low ^ 0x8000) - 0x8000; /* sign extend */
}
int delta_low = ((delta & 0xffff) ^ 0x8000) - 0x8000;
int delta_high = (delta - delta_low) >> 16;
asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
delta_high);
@ -9762,10 +9761,6 @@ output_mi_thunk (file, thunk_fndecl, delta, function)
fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta_low);
}
/* 64-bit constants, fixme */
else
abort ();
/* Get the prefix in front of the names. */
switch (DEFAULT_ABI)
{
@ -9821,7 +9816,10 @@ output_mi_thunk (file, thunk_fndecl, delta, function)
}
assemble_name (file, fname);
putc ('\n', file);
text_section ();
if (TARGET_ELF)
function_section (current_function_decl);
else
text_section ();
if (TARGET_MINIMAL_TOC)
asm_fprintf (file, (TARGET_32BIT)
? "\t{l|lwz} %s,%s(%s)\n" : "\tld %s,%s(%s)\n", r12,
@ -10157,8 +10155,10 @@ output_toc (file, x, labelno, mode)
if (TARGET_MINIMAL_TOC)
fputs (DOUBLE_INT_ASM_OP, file);
else
fprintf (file, "\t.tc FD_%lx_%lx[TC],", k[0], k[1]);
fprintf (file, "0x%lx%08lx\n", k[0], k[1]);
fprintf (file, "\t.tc FD_%lx_%lx[TC],",
k[0] & 0xffffffff, k[1] & 0xffffffff);
fprintf (file, "0x%lx%08lx\n",
k[0] & 0xffffffff, k[1] & 0xffffffff);
return;
}
else
@ -10166,8 +10166,10 @@ output_toc (file, x, labelno, mode)
if (TARGET_MINIMAL_TOC)
fputs ("\t.long ", file);
else
fprintf (file, "\t.tc FD_%lx_%lx[TC],", k[0], k[1]);
fprintf (file, "0x%lx,0x%lx\n", k[0], k[1]);
fprintf (file, "\t.tc FD_%lx_%lx[TC],",
k[0] & 0xffffffff, k[1] & 0xffffffff);
fprintf (file, "0x%lx,0x%lx\n",
k[0] & 0xffffffff, k[1] & 0xffffffff);
return;
}
}
@ -10184,8 +10186,8 @@ output_toc (file, x, labelno, mode)
if (TARGET_MINIMAL_TOC)
fputs (DOUBLE_INT_ASM_OP, file);
else
fprintf (file, "\t.tc FS_%lx[TC],", l);
fprintf (file, "0x%lx00000000\n", l);
fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
return;
}
else
@ -10193,8 +10195,8 @@ output_toc (file, x, labelno, mode)
if (TARGET_MINIMAL_TOC)
fputs ("\t.long ", file);
else
fprintf (file, "\t.tc FS_%lx[TC],", l);
fprintf (file, "0x%lx\n", l);
fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
fprintf (file, "0x%lx\n", l & 0xffffffff);
return;
}
}
@ -10244,8 +10246,10 @@ output_toc (file, x, labelno, mode)
if (TARGET_MINIMAL_TOC)
fputs (DOUBLE_INT_ASM_OP, file);
else
fprintf (file, "\t.tc ID_%lx_%lx[TC],", (long) high, (long) low);
fprintf (file, "0x%lx%08lx\n", (long) high, (long) low);
fprintf (file, "\t.tc ID_%lx_%lx[TC],",
(long) high & 0xffffffff, (long) low & 0xffffffff);
fprintf (file, "0x%lx%08lx\n",
(long) high & 0xffffffff, (long) low & 0xffffffff);
return;
}
else
@ -10256,16 +10260,17 @@ output_toc (file, x, labelno, mode)
fputs ("\t.long ", file);
else
fprintf (file, "\t.tc ID_%lx_%lx[TC],",
(long) high, (long) low);
fprintf (file, "0x%lx,0x%lx\n", (long) high, (long) low);
(long) high & 0xffffffff, (long) low & 0xffffffff);
fprintf (file, "0x%lx,0x%lx\n",
(long) high & 0xffffffff, (long) low & 0xffffffff);
}
else
{
if (TARGET_MINIMAL_TOC)
fputs ("\t.long ", file);
else
fprintf (file, "\t.tc IS_%lx[TC],", (long) low);
fprintf (file, "0x%lx\n", (long) low);
fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
}
return;
}
@ -10879,18 +10884,19 @@ rs6000_select_section (decl, reloc)
if (TREE_CODE (decl) == STRING_CST)
readonly = ! flag_writable_strings;
else if (TREE_CODE (decl) == VAR_DECL)
readonly = (! (flag_pic && reloc)
readonly = (! ((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc)
&& TREE_READONLY (decl)
&& ! TREE_SIDE_EFFECTS (decl)
&& DECL_INITIAL (decl)
&& DECL_INITIAL (decl) != error_mark_node
&& TREE_CONSTANT (DECL_INITIAL (decl)));
else if (TREE_CODE (decl) == CONSTRUCTOR)
readonly = (! (flag_pic && reloc)
readonly = (! ((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc)
&& ! TREE_SIDE_EFFECTS (decl)
&& TREE_CONSTANT (decl));
else
readonly = 1;
readonly = ! ((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc);
if (needs_sdata && rs6000_sdata != SDATA_EABI)
readonly = 0;
@ -10935,14 +10941,15 @@ rs6000_unique_section (decl, reloc)
int needs_sdata;
int size;
readonly = 1;
if (TREE_CODE (decl) == STRING_CST)
readonly = ! flag_writable_strings;
else if (TREE_CODE (decl) == VAR_DECL)
readonly = (! (flag_pic && reloc)
readonly = (! ((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc)
&& TREE_READONLY (decl)
&& ! TREE_SIDE_EFFECTS (decl)
&& TREE_CONSTANT (DECL_INITIAL (decl)));
else
readonly = ! ((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc);
size = int_size_in_bytes (TREE_TYPE (decl));
needs_sdata = (size > 0

View File

@ -105,8 +105,8 @@ Boston, MA 02111-1307, USA. */
%{mcpu=rsc: -mpwr} \
%{mcpu=rsc1: -mpwr} \
%{mcpu=401: -mppc} \
%{mcpu=403: -mppc} \
%{mcpu=405: -mppc} \
%{mcpu=403: -m403} \
%{mcpu=405: -m405} \
%{mcpu=505: -mppc} \
%{mcpu=601: -m601} \
%{mcpu=602: -mppc} \
@ -2439,12 +2439,14 @@ extern int toc_initialized;
do \
{ \
fputs ("\t.weak\t", (FILE)); \
assemble_name ((FILE), (NAME)); \
RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL \
&& DEFAULT_ABI == ABI_AIX) \
{ \
if (TARGET_XCOFF) \
fputs ("[DS]", (FILE)); \
fputs ("\n\t.weak\t.", (FILE)); \
assemble_name ((FILE), (NAME)); \
RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
} \
fputc ('\n', (FILE)); \
if (VAL) \
@ -2454,9 +2456,9 @@ extern int toc_initialized;
&& DEFAULT_ABI == ABI_AIX) \
{ \
fputs ("\t.set\t.", (FILE)); \
assemble_name ((FILE), (NAME)); \
RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
fputs (",.", (FILE)); \
assemble_name ((FILE), (VAL)); \
RS6000_OUTPUT_BASENAME ((FILE), (VAL)); \
fputc ('\n', (FILE)); \
} \
} \
@ -2479,20 +2481,20 @@ extern int toc_initialized;
if (!RS6000_WEAK || !DECL_WEAK (DECL)) \
{ \
fputs ("\t.globl\t.", FILE); \
assemble_name (FILE, alias); \
RS6000_OUTPUT_BASENAME (FILE, alias); \
putc ('\n', FILE); \
} \
} \
else if (TARGET_XCOFF) \
{ \
fputs ("\t.lglobl\t.", FILE); \
assemble_name (FILE, alias); \
RS6000_OUTPUT_BASENAME (FILE, alias); \
putc ('\n', FILE); \
} \
fputs ("\t.set\t.", FILE); \
assemble_name (FILE, alias); \
RS6000_OUTPUT_BASENAME (FILE, alias); \
fputs (",.", FILE); \
assemble_name (FILE, name); \
RS6000_OUTPUT_BASENAME (FILE, name); \
fputc ('\n', FILE); \
} \
ASM_OUTPUT_DEF (FILE, alias, name); \

View File

@ -5271,9 +5271,18 @@
(clobber (match_dup 4))
(clobber (match_dup 5))
(clobber (match_dup 6))])]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
"TARGET_HARD_FLOAT"
"
{
if (TARGET_POWERPC64)
{
rtx mem = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0);
rtx t1 = gen_reg_rtx (DImode);
rtx t2 = gen_reg_rtx (DImode);
emit_insn (gen_floatsidf_ppc64 (operands[0], operands[1], mem, t1, t2));
DONE;
}
operands[2] = force_reg (SImode, GEN_INT (0x43300000));
operands[3] = force_reg (DFmode, rs6000_float_const (\"4503601774854144\", DFmode));
operands[4] = assign_stack_temp (DFmode, GET_MODE_SIZE (DFmode), 0);
@ -5338,9 +5347,19 @@
(use (match_dup 3))
(clobber (match_dup 4))
(clobber (match_dup 5))])]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
"TARGET_HARD_FLOAT"
"
{
if (TARGET_POWERPC64)
{
rtx mem = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0);
rtx t1 = gen_reg_rtx (DImode);
rtx t2 = gen_reg_rtx (DImode);
emit_insn (gen_floatunssidf_ppc64 (operands[0], operands[1], mem,
t1, t2));
DONE;
}
operands[2] = force_reg (SImode, GEN_INT (0x43300000));
operands[3] = force_reg (DFmode, rs6000_float_const (\"4503599627370496\", DFmode));
operands[4] = assign_stack_temp (DFmode, GET_MODE_SIZE (DFmode), 0);
@ -5407,7 +5426,7 @@
(define_insn "*fix_truncdfsi2_internal"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
(clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
(clobber (match_operand:DI 2 "gpc_reg_operand" "=*f"))
(clobber (match_operand:DI 3 "memory_operand" "=o"))]
"(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
"#"
@ -5443,7 +5462,7 @@
; because the first makes it clear that operand 0 is not live
; before the instruction.
(define_insn "fctiwz"
[(set (match_operand:DI 0 "gpc_reg_operand" "=f")
[(set (match_operand:DI 0 "gpc_reg_operand" "=*f")
(unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))] 10))]
"(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
"{fcirz|fctiwz} %0,%1"
@ -5451,13 +5470,43 @@
(define_insn "floatdidf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(float:DF (match_operand:DI 1 "gpc_reg_operand" "f")))]
(float:DF (match_operand:DI 1 "gpc_reg_operand" "*f")))]
"TARGET_POWERPC64 && TARGET_HARD_FLOAT"
"fcfid %0,%1"
[(set_attr "type" "fp")])
(define_insn_and_split "floatsidf_ppc64"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
(clobber (match_operand:DI 2 "memory_operand" "=o"))
(clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))
(clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))]
"TARGET_POWERPC64 && TARGET_HARD_FLOAT"
"#"
""
[(set (match_dup 3) (sign_extend:DI (match_dup 1)))
(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (match_dup 2))
(set (match_dup 0) (float:DF (match_dup 4)))]
"")
(define_insn_and_split "floatunssidf_ppc64"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
(clobber (match_operand:DI 2 "memory_operand" "=o"))
(clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))
(clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))]
"TARGET_POWERPC64 && TARGET_HARD_FLOAT"
"#"
""
[(set (match_dup 3) (zero_extend:DI (match_dup 1)))
(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (match_dup 2))
(set (match_dup 0) (float:DF (match_dup 4)))]
"")
(define_insn "fix_truncdfdi2"
[(set (match_operand:DI 0 "gpc_reg_operand" "=f")
[(set (match_operand:DI 0 "gpc_reg_operand" "=*f")
(fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))]
"TARGET_POWERPC64 && TARGET_HARD_FLOAT"
"fctidz %0,%1"
@ -13255,15 +13304,15 @@
(define_insn "*ctrdi_internal1"
[(set (pc)
(if_then_else (ne (match_operand:DI 1 "register_operand" "c,*r,*r,!*f")
(if_then_else (ne (match_operand:DI 1 "register_operand" "c,*r,*r")
(const_int 1))
(label_ref (match_operand 0 "" ""))
(pc)))
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l,!*f")
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
(plus:DI (match_dup 1)
(const_int -1)))
(clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
(clobber (match_scratch:DI 4 "=X,X,r,r"))]
(clobber (match_scratch:CC 3 "=X,&x,&x"))
(clobber (match_scratch:DI 4 "=X,X,r"))]
"TARGET_POWERPC64"
"*
{
@ -13275,19 +13324,19 @@
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
(set_attr "length" "*,12,16,24")])
(set_attr "length" "*,12,16")])
(define_insn "*ctrdi_internal2"
[(set (pc)
(if_then_else (ne (match_operand:DI 1 "register_operand" "c,*r,*r,!*f")
(if_then_else (ne (match_operand:DI 1 "register_operand" "c,*r,*r")
(const_int 1))
(pc)
(label_ref (match_operand 0 "" ""))))
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l,!*f")
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
(plus:DI (match_dup 1)
(const_int -1)))
(clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
(clobber (match_scratch:DI 4 "=X,X,r,r"))]
(clobber (match_scratch:CC 3 "=X,&x,&x"))
(clobber (match_scratch:DI 4 "=X,X,r"))]
"TARGET_POWERPC64"
"*
{
@ -13299,7 +13348,7 @@
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
(set_attr "length" "*,12,16,24")])
(set_attr "length" "*,12,16")])
;; Similar, but we can use GE since we have a REG_NONNEG.
@ -13353,15 +13402,15 @@
(define_insn "*ctrdi_internal3"
[(set (pc)
(if_then_else (ge (match_operand:DI 1 "register_operand" "c,*r,*r,!*f")
(if_then_else (ge (match_operand:DI 1 "register_operand" "c,*r,*r")
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l,!*f")
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
(plus:DI (match_dup 1)
(const_int -1)))
(clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
(clobber (match_scratch:DI 4 "=X,X,r,r"))]
(clobber (match_scratch:CC 3 "=X,&x,&x"))
(clobber (match_scratch:DI 4 "=X,X,r"))]
"TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)"
"*
{
@ -13373,19 +13422,19 @@
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
(set_attr "length" "*,12,16,24")])
(set_attr "length" "*,12,16")])
(define_insn "*ctrdi_internal4"
[(set (pc)
(if_then_else (ge (match_operand:DI 1 "register_operand" "c,*r,*r,!*f")
(if_then_else (ge (match_operand:DI 1 "register_operand" "c,*r,*r")
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l,!*f")
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
(plus:DI (match_dup 1)
(const_int -1)))
(clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
(clobber (match_scratch:DI 4 "=X,X,r,r"))]
(clobber (match_scratch:CC 3 "=X,&x,&x"))
(clobber (match_scratch:DI 4 "=X,X,r"))]
"TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)"
"*
{
@ -13397,7 +13446,7 @@
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
(set_attr "length" "*,12,16,24")])
(set_attr "length" "*,12,16")])
;; Similar but use EQ
@ -13451,15 +13500,15 @@
(define_insn "*ctrdi_internal5"
[(set (pc)
(if_then_else (eq (match_operand:DI 1 "register_operand" "c,*r,*r,!*f")
(if_then_else (eq (match_operand:DI 1 "register_operand" "c,*r,*r")
(const_int 1))
(label_ref (match_operand 0 "" ""))
(pc)))
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l,!*f")
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
(plus:DI (match_dup 1)
(const_int -1)))
(clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
(clobber (match_scratch:DI 4 "=X,X,r,r"))]
(clobber (match_scratch:CC 3 "=X,&x,&x"))
(clobber (match_scratch:DI 4 "=X,X,r"))]
"TARGET_POWERPC64"
"*
{
@ -13471,19 +13520,19 @@
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
(set_attr "length" "*,12,16,24")])
(set_attr "length" "*,12,16")])
(define_insn "*ctrdi_internal6"
[(set (pc)
(if_then_else (eq (match_operand:DI 1 "register_operand" "c,*r,*r,!*f")
(if_then_else (eq (match_operand:DI 1 "register_operand" "c,*r,*r")
(const_int 1))
(pc)
(label_ref (match_operand 0 "" ""))))
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l,!*f")
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
(plus:DI (match_dup 1)
(const_int -1)))
(clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
(clobber (match_scratch:DI 4 "=X,X,r,r"))]
(clobber (match_scratch:CC 3 "=X,&x,&x"))
(clobber (match_scratch:DI 4 "=X,X,r"))]
"TARGET_POWERPC64"
"*
{
@ -13495,7 +13544,7 @@
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
(set_attr "length" "*,12,16,24")])
(set_attr "length" "*,12,16")])
;; Now the splitters if we could not allocate the CTR register
@ -13566,7 +13615,7 @@
(const_int -1)))
(clobber (match_scratch:CC 3 ""))
(clobber (match_scratch:DI 4 ""))]
"TARGET_POWERPC64 && reload_completed && INT_REGNO_P (REGNO (operands[0]))"
"TARGET_POWERPC64 && reload_completed"
[(parallel [(set (match_dup 3)
(compare:CC (plus:DI (match_dup 1)
(const_int -1))
@ -13610,44 +13659,6 @@
{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
const0_rtx); }")
(define_split
[(set (pc)
(if_then_else (match_operator 2 "comparison_operator"
[(match_operand:DI 1 "gpc_reg_operand" "")
(const_int 1)])
(match_operand 5 "" "")
(match_operand 6 "" "")))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(plus:DI (match_dup 1)
(const_int -1)))
(clobber (match_scratch:CC 3 ""))
(clobber (match_scratch:DI 4 ""))]
"TARGET_POWERPC64 && reload_completed && FP_REGNO_P (REGNO (operands[0]))"
[(set (match_dup 8)
(match_dup 1))
(set (match_dup 4)
(match_dup 8))
(parallel [(set (match_dup 3)
(compare:CC (plus:DI (match_dup 4)
(const_int -1))
(const_int 0)))
(set (match_dup 4)
(plus:DI (match_dup 4)
(const_int -1)))])
(set (match_dup 8)
(match_dup 4))
(set (match_dup 0)
(match_dup 8))
(set (pc) (if_then_else (match_dup 7)
(match_dup 5)
(match_dup 6)))]
"
{
operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
const0_rtx);
operands[8] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0);
}")
(define_insn "trap"
[(trap_if (const_int 1) (const_int 0))]

View File

@ -403,7 +403,6 @@ do { \
: MAX (COMPUTED, SPECIFIED))
#undef BIGGEST_FIELD_ALIGNMENT
#undef ADJUST_FIELD_ALIGN
/* Use ELF style section commands. */

View File

@ -457,6 +457,15 @@ toc_section () \
/* This is how we tell the assembler that two symbols have the same value. */
#define SET_ASM_OP "\t.set "
/* This is how we tell the assembler to equate two values. */
#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \
do { fprintf ((FILE), "%s", SET_ASM_OP); \
RS6000_OUTPUT_BASENAME (FILE, LABEL1); \
fprintf (FILE, ","); \
RS6000_OUTPUT_BASENAME (FILE, LABEL2); \
fprintf (FILE, "\n"); \
} while (0)
/* Used by rs6000_assemble_integer, among others. */
#define DOUBLE_INT_ASM_OP "\t.llong\t"

View File

@ -31,12 +31,28 @@ Boston, MA 02111-1307, USA. */
/* CPP defines used for 64 bit code. */
#undef CPP_SUBTARGET_SPEC64
#define CPP_SUBTARGET_SPEC64 \
"-D__sparc64__ -D__arch64__ -D__sparc_v9__ %{posix:-D_POSIX_SOURCE}"
"-D__sparc64__ -D__sparc_v9__ -D_LP64 %{posix:-D_POSIX_SOURCE}"
/* CPP defines used for 32 bit code. */
#undef CPP_SUBTARGET_SPEC32
#define CPP_SUBTARGET_SPEC32 "-D__sparc %{posix:-D_POSIX_SOURCE}"
/* CPP_ARCH32_SPEC and CPP_ARCH64_SPEC are wrong from sparc/sparc.h; we
always want the non-SPARC_BI_ARCH versions, since the SPARC_BI_ARCH
versions define __SIZE_TYPE__ and __PTRDIFF_TYPE__ incorrectly for
NetBSD. */
#undef CPP_ARCH32_SPEC
#define CPP_ARCH32_SPEC "-D__GCC_NEW_VARARGS__ -Acpu=sparc -Amachine=sparc"
#undef CPP_ARCH64_SPEC
#define CPP_ARCH64_SPEC "-D__arch64__ -Acpu=sparc64 -Amachine=sparc64"
/* sparc/sparc.h defines NO_BUILTIN_SIZE_TYPE and NO_BUILTIN_PTRDIFF_TYPE
if SPARC_BI_ARCH is defined. This is wrong for NetBSD; size_t and
ptrdiff_t do not change for 32-bit vs. 64-bit. */
#undef NO_BUILTIN_PTRDIFF_TYPE
#undef NO_BUILTIN_SIZE_TYPE
/* SIZE_TYPE and PTRDIFF_TYPE are wrong from sparc/sparc.h. */
#undef SIZE_TYPE
#define SIZE_TYPE "long unsigned int"
@ -99,9 +115,6 @@ Boston, MA 02111-1307, USA. */
* Clean up afterwards generic SPARC ELF configuration.
*/
#undef TRANSFER_FROM_TRAMPOLINE
#define TRANSFER_FROM_TRAMPOLINE
/* FIXME: Aren't these supposed to be available for SPARC ELF? */
#undef MULDI3_LIBCALL
#undef DIVDI3_LIBCALL

View File

@ -0,0 +1,24 @@
/* Configuration file for sparc64 OpenBSD target.
Copyright (C) 1999 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#define OBSD_HAS_DECLARE_FUNCTION_NAME
#define OBSD_HAS_DECLARE_FUNCTION_SIZE
#define OBSD_HAS_DECLARE_OBJECT

View File

@ -0,0 +1,75 @@
/* Configuration file for sparc64 OpenBSD target.
Copyright (C) 1999 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (sparc64 OpenBSD ELF)")
/* XXX - do we really want HARD_QUAD? */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT \
(MASK_V9 + MASK_PTR64 + MASK_64BIT + MASK_HARD_QUAD \
+ MASK_APP_REGS + MASK_FPU + MASK_STACK_BIAS + MASK_LONG_DOUBLE_128)
#undef SPARC_DEFAULT_CMODEL
#define SPARC_DEFAULT_CMODEL CM_MEDMID
/* Run-time target specifications. */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-D__unix__ -D__sparc__ -D__sparc64__ -D__sparcv9__ -D__sparc_v9__ -D__arch64__ -D__ELF__ -D__OpenBSD__ -Asystem(unix) -Asystem(OpenBSD) -Acpu(sparc) -Amachine(sparc)"
#undef CPP_SUBTARGET_SPEC
#define CPP_SUBTARGET_SPEC ""
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
#undef ASM_SPEC
#define ASM_SPEC "\
%{v:-V} -s %{fpic:-K PIC} %{fPIC:-K PIC} \
%{mlittle-endian:-EL} \
%(asm_cpu) %(asm_arch) \
"
/* Layout of source language data types. */
#undef WCHAR_TYPE
#define WCHAR_TYPE "int"
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 32
#undef LONG_DOUBLE_TYPE_SIZE
#define LONG_DOUBLE_TYPE_SIZE 128
#undef LINK_SPEC
#define LINK_SPEC \
"%{!shared:%{!nostdlib:%{!r*:%{!e*:-e __start}}}} \
%{shared:-shared} %{R*} \
%{static:-Bstatic} \
%{!static:-Bdynamic} \
%{assert*} \
%{!dynamic-linker:-dynamic-linker /usr/libexec/ld.so}"
/* As an elf system, we need crtbegin/crtend stuff. */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "\
%{!shared: %{pg:gcrt0%O%s} %{!pg:%{p:gcrt0%O%s} %{!p:crt0%O%s}} \
crtbegin%O%s} %{shared:crtbeginS%O%s}"
#undef ENDFILE_SPEC
#define ENDFILE_SPEC "%{!shared:crtend%O%s} %{shared:crtendS%O%s}"

View File

@ -71,17 +71,21 @@ Boston, MA 02111-1307, USA. */
/* This is here rather than in sparc.h because it's not known what
other assemblers will accept. */
#if TARGET_CPU_DEFAULT == TARGET_CPU_v9
#undef ASM_CPU_DEFAULT_SPEC
#define ASM_CPU_DEFAULT_SPEC "-xarch=v8plus"
#endif
#if TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc
#undef ASM_CPU_DEFAULT_SPEC
#define ASM_CPU_DEFAULT_SPEC "-xarch=v8plusa"
#endif
#undef ASM_CPU_SPEC
#define ASM_CPU_SPEC "\
%{mcpu=v8plus:-xarch=v8plus} \
%{mcpu=v9:-xarch=v8plus} \
%{mcpu=ultrasparc:-xarch=v8plusa} \
%{!mcpu*:%(asm_cpu_default)} \
"
@ -227,6 +231,12 @@ Boston, MA 02111-1307, USA. */
#define MODDI3_LIBCALL "__rem64"
#define UMODDI3_LIBCALL "__urem64"
/* Solaris's _Qp_* library routine implementation clobbers the output
memory before the inputs are fully consumed. */
#undef TARGET_BUGGY_QP_LIB
#define TARGET_BUGGY_QP_LIB 1
#undef INIT_SUBTARGET_OPTABS
#define INIT_SUBTARGET_OPTABS \
fixsfdi_libfunc \

View File

@ -123,4 +123,6 @@ extern rtx gen_df_reg PARAMS ((rtx, int));
extern int sparc_extra_constraint_check PARAMS ((rtx, int, int));
#endif /* RTX_CODE */
extern void sparc_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT, tree));
#endif /* __SPARC_PROTOS_H__ */

View File

@ -2489,9 +2489,17 @@ emit_soft_tfmode_libcall (func_name, nargs, operands)
/* TFmode arguments and return values are passed by reference. */
if (GET_MODE (this_arg) == TFmode)
{
if (GET_CODE (this_arg) == MEM)
int force_stack_temp;
force_stack_temp = 0;
if (TARGET_BUGGY_QP_LIB && i == 0)
force_stack_temp = 1;
if (GET_CODE (this_arg) == MEM
&& ! force_stack_temp)
this_arg = XEXP (this_arg, 0);
else if (CONSTANT_P (this_arg))
else if (CONSTANT_P (this_arg)
&& ! force_stack_temp)
{
this_slot = force_const_mem (TFmode, this_arg);
this_arg = XEXP (this_slot, 0);
@ -8993,3 +9001,70 @@ sparc_extra_constraint_check (op, c, strict)
return reload_ok_mem;
}
/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
Used for C++ multiple inheritance. */
void
sparc_output_mi_thunk (file, thunk_fndecl, delta, function)
FILE *file;
tree thunk_fndecl ATTRIBUTE_UNUSED;
HOST_WIDE_INT delta;
tree function;
{
rtx this, insn, funexp, delta_rtx, tmp;
reload_completed = 1;
no_new_pseudos = 1;
current_function_uses_only_leaf_regs = 1;
emit_note (NULL, NOTE_INSN_PROLOGUE_END);
/* Find the "this" pointer. Normally in %o0, but in ARCH64 if the function
returns a structure, the structure return pointer is there instead. */
if (TARGET_ARCH64 && aggregate_value_p (TREE_TYPE (TREE_TYPE (function))))
this = gen_rtx_REG (Pmode, SPARC_INCOMING_INT_ARG_FIRST + 1);
else
this = gen_rtx_REG (Pmode, SPARC_INCOMING_INT_ARG_FIRST);
/* Add DELTA. When possible use a plain add, otherwise load it into
a register first. */
delta_rtx = GEN_INT (delta);
if (!SPARC_SIMM13_P (delta))
{
rtx scratch = gen_rtx_REG (Pmode, 1);
if (TARGET_ARCH64)
sparc_emit_set_const64 (scratch, delta_rtx);
else
sparc_emit_set_const32 (scratch, delta_rtx);
delta_rtx = scratch;
}
tmp = gen_rtx_PLUS (Pmode, this, delta_rtx);
emit_insn (gen_rtx_SET (VOIDmode, this, tmp));
/* Generate a tail call to the target function. */
if (! TREE_USED (function))
{
assemble_external (function);
TREE_USED (function) = 1;
}
funexp = XEXP (DECL_RTL (function), 0);
funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
insn = emit_call_insn (gen_sibcall (funexp));
SIBLING_CALL_P (insn) = 1;
emit_barrier ();
/* Run just enough of rest_of_compilation to get the insns emitted.
There's not really enough bulk here to make other passes such as
instruction scheduling worth while. Note that use_thunk calls
assemble_start_function and assemble_end_function. */
insn = get_insns ();
shorten_branches (insn);
final_start_function (insn, file, 1);
final (insn, file, 1, 0);
final_end_function ();
reload_completed = 0;
no_new_pseudos = 0;
}

View File

@ -1414,6 +1414,8 @@ extern char leaf_reg_remap[];
#define PREFERRED_RELOAD_CLASS(X,CLASS) \
(CONSTANT_P (X) \
? ((FP_REG_CLASS_P (CLASS) \
|| (CLASS) == GENERAL_OR_FP_REGS \
|| (CLASS) == GENERAL_OR_EXTRA_FP_REGS \
|| (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
&& ! TARGET_FPU) \
|| (GET_MODE (X) == TFmode \
@ -1958,7 +1960,8 @@ do { \
return an rtx for the address of the word in the frame
that holds the dynamic chain--the previous frame's address.
??? -mflat support? */
#define DYNAMIC_CHAIN_ADDRESS(frame) plus_constant (frame, 14 * UNITS_PER_WORD)
#define DYNAMIC_CHAIN_ADDRESS(frame) \
plus_constant (frame, 14 * UNITS_PER_WORD + SPARC_STACK_BIAS)
/* The return address isn't on the stack, it is in a register, so we can't
access it from the current frame pointer. We can access it from the
@ -2568,6 +2571,11 @@ do { \
#define LTTF2_LIBCALL "_Q_flt"
#define LETF2_LIBCALL "_Q_fle"
/* Assume by default that the _Qp_* 64-bit libcalls are implemented such
that the inputs are fully consumed before the output memory is clobbered. */
#define TARGET_BUGGY_QP_LIB 0
/* We can define the TFmode sqrt optab only if TARGET_FPU. This is because
with soft-float, the SFmode and DFmode sqrt instructions will be absent,
and the compiler will notice and try to use the TFmode sqrt instruction
@ -2604,6 +2612,17 @@ do { \
sqrt_optab->handlers[(int) TFmode].libfunc \
= init_one_libfunc ("_Q_sqrt"); \
} \
if (TARGET_ARCH64) \
{ \
/* In the SPARC 64bit ABI, these libfuncs do not exist in the \
library. Make sure the compiler does not emit calls to them \
by accident. */ \
sdiv_optab->handlers[(int) SImode].libfunc = NULL; \
udiv_optab->handlers[(int) SImode].libfunc = NULL; \
smod_optab->handlers[(int) SImode].libfunc = NULL; \
umod_optab->handlers[(int) SImode].libfunc = NULL; \
smul_optab->handlers[(int) SImode].libfunc = NULL; \
} \
INIT_SUBTARGET_OPTABS; \
} while (0)
@ -2903,24 +2922,8 @@ do { \
/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
Used for C++ multiple inheritance. */
#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
do { \
int reg = 0; \
\
if (TARGET_ARCH64 \
&& aggregate_value_p (TREE_TYPE (TREE_TYPE (FUNCTION)))) \
reg = 1; \
if ((DELTA) >= 4096 || (DELTA) < -4096) \
fprintf (FILE, "\tset\t%d, %%g1\n\tadd\t%%o%d, %%g1, %%o%d\n", \
(int)(DELTA), reg, reg); \
else \
fprintf (FILE, "\tadd\t%%o%d, %d, %%o%d\n", reg, (int)(DELTA), reg);\
fprintf (FILE, "\tor\t%%o7, %%g0, %%g1\n"); \
fprintf (FILE, "\tcall\t"); \
assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \
fprintf (FILE, ", 0\n"); \
fprintf (FILE, "\t or\t%%g1, %%g0, %%o7\n"); \
} while (0)
#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
sparc_output_mi_thunk (FILE, THUNK_FNDECL, DELTA, FUNCTION)
#define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^' || (CHAR) == '(' || (CHAR) == '_')

View File

@ -1,4 +1,4 @@
EXTRA_PARTS += crtfastmath.o
crtfastmath.o: $(srcdir)/config/sparc/crtfastmath.c $(GCC_PASSES)
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -c -o crtfastmath.o $(srcdir)/config/sparc/crtfastmath.c
$(T)crtfastmath.o: $(srcdir)/config/sparc/crtfastmath.c $(GCC_PASSES)
$(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) $(LIBGCC2_CFLAGS) -c -o $(T)crtfastmath.o $(srcdir)/config/sparc/crtfastmath.c

View File

@ -7,7 +7,8 @@ MULTILIB_EXCLUSIONS = m32/!m64/mno-app-regs m32/!m64/mcmodel=medany
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o
EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o \
crtfastmath.o
SHLIB_SLIBDIR_SUFFIXES = 64:64 32:

View File

@ -5,6 +5,7 @@ MULTILIB_MATCHES =
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o gmon.o crt1.o crti.o crtn.o gcrt1.o
EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o gmon.o crt1.o crti.o crtn.o gcrt1.o \
crtfastmath.o
SHLIB_SLIBDIR_SUFFIXES = sparcv9:/sparcv9 sparcv7:

679
contrib/gcc/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -167,7 +167,7 @@ esac])
if test x${gcc_gxx_include_dir} = x; then
if test x${enable_version_specific_runtime_libs} = xyes; then
gcc_gxx_include_dir='${libsubdir}/include/g++'
gcc_gxx_include_dir='${libsubdir}/include/c++'
else
topsrcdir=${srcdir}/.. . ${srcdir}/../config.if
changequote(<<, >>)dnl
@ -259,6 +259,18 @@ elif test x$withval != xno; then
cpp_install_dir=$withval
fi])
# Enable __cxa_atexit for C++.
AC_ARG_ENABLE(__cxa_atexit,
[ --enable-__cxa_atexit enable __cxa_atexit for C++],
[], [])
if test x$enable___cxa_atexit = xyes; then
AC_DEFINE(DEFAULT_USE_CXA_ATEXIT, 1,
[Define if you want to use __cxa_atexit, rather than atexit, to
register C++ destructors for local statics and global objects.
This is essential for fully standards-compliant handling of
destructors, but requires __cxa_atexit in libc.])
fi
# Enable Multibyte Characters for C/C++
AC_ARG_ENABLE(c-mbchar,
[ --enable-c-mbchar enable multibyte characters for C and C++],
@ -1525,11 +1537,31 @@ elif test x$gcc_cv_as != x; then
ld_ver=`$gcc_cv_ld --version 2>/dev/null | head -1`
if echo "$ld_ver" | grep GNU > /dev/null; then
changequote(,)dnl
ld_vers=`echo $ld_ver | sed -n 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*\(\|\.[0-9][0-9]*\)\)\([ ].*\|\)$,\1,p'`
ld_date=`echo $ld_ver | sed -n 's,^.*\([2-9][0-9][0-9][0-9]\)[-]*\([01][0-9]\)[-]*\([0-3][0-9]\).*$,\1\2\3,p'`
changequote([,])dnl
if test 0"$ld_date" -lt 20020404; then
gcc_cv_as_hidden="no"
if test -n "$ld_date"; then
# If there was date string, but was earlier than 2002-04-04, fail
gcc_cv_as_hidden="no"
elif test -z "$ld_vers"; then
# If there was no date string nor ld version number, something is wrong
gcc_cv_as_hidden="no"
else
ld_vers_major=`expr "$ld_vers" : '\([0-9]*\)'`
ld_vers_minor=`expr "$ld_vers" : '[0-9]*\.\([0-9]*\)'`
ld_vers_patch=`expr "$ld_vers" : '[0-9]*\.[0-9]*\.\([0-9]*\)'`
test -z "$ld_vers_patch" && ld_vers_patch=0
if test "$ld_vers_major" -lt 2; then
gcc_cv_as_hidden="no"
elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -lt 12; then
gcc_cv_as_hidden="no"
elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -eq 12 \
-a "$ld_vers_patch" -eq 0; then
gcc_cv_as_hidden="no"
fi
fi
fi
changequote([,])dnl
fi
fi

View File

@ -227,9 +227,11 @@ convert_to_integer (type, expr)
case LSHIFT_EXPR:
/* We can pass truncation down through left shifting
when the shift count is a nonnegative constant. */
when the shift count is a nonnegative constant and
the target type is unsigned. */
if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
&& tree_int_cst_sgn (TREE_OPERAND (expr, 1)) >= 0
&& TREE_UNSIGNED (type)
&& TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
{
/* If shift count is less than the width of the truncated type,
@ -311,12 +313,15 @@ convert_to_integer (type, expr)
/* Don't do unsigned arithmetic where signed was wanted,
or vice versa.
Exception: if both of the original operands were
unsigned then can safely do the work as unsigned.
unsigned then we can safely do the work as unsigned;
if we are distributing through a LSHIFT_EXPR, we must
do the work as unsigned to avoid a signed overflow.
And we may need to do it as unsigned
if we truncate to the original size. */
typex = ((TREE_UNSIGNED (TREE_TYPE (expr))
|| (TREE_UNSIGNED (TREE_TYPE (arg0))
&& TREE_UNSIGNED (TREE_TYPE (arg1))))
&& TREE_UNSIGNED (TREE_TYPE (arg1)))
|| ex_form == LSHIFT_EXPR)
? unsigned_type (typex) : signed_type (typex));
return convert (type,
fold (build (ex_form, typex,

View File

@ -1,5 +1,5 @@
/* Demangler for IA64 / g++ V3 ABI.
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
Written by Alex Samuel <samuel@codesourcery.com>.
This file is part of GNU CC.
@ -898,7 +898,7 @@ static status_t demangle_number_literally
static status_t demangle_identifier
PARAMS ((demangling_t, int, dyn_string_t));
static status_t demangle_operator_name
PARAMS ((demangling_t, int, int *));
PARAMS ((demangling_t, int, int *, int *));
static status_t demangle_nv_offset
PARAMS ((demangling_t));
static status_t demangle_v_offset
@ -1325,7 +1325,7 @@ demangle_unqualified_name (dm, suppress_return_type)
if (peek == 'c' && peek_char_next (dm) == 'v')
*suppress_return_type = 1;
RETURN_IF_ERROR (demangle_operator_name (dm, 0, &num_args));
RETURN_IF_ERROR (demangle_operator_name (dm, 0, &num_args, NULL));
}
else if (peek == 'C' || peek == 'D')
{
@ -1501,7 +1501,9 @@ demangle_identifier (dm, length, identifier)
/* Demangles and emits an <operator-name>. If SHORT_NAME is non-zero,
the short form is emitted; otherwise the full source form
(`operator +' etc.) is emitted. *NUM_ARGS is set to the number of
operands that the operator takes.
operands that the operator takes. If TYPE_ARG is non-NULL,
*TYPE_ARG is set to 1 if the first argument is a type and 0
otherwise.
<operator-name>
::= nw # new
@ -1551,15 +1553,17 @@ demangle_identifier (dm, length, identifier)
::= cl # ()
::= ix # []
::= qu # ?
::= sz # sizeof
::= st # sizeof (a type)
::= sz # sizeof (an expression)
::= cv <type> # cast
::= v [0-9] <source-name> # vendor extended operator */
static status_t
demangle_operator_name (dm, short_name, num_args)
demangle_operator_name (dm, short_name, num_args, type_arg)
demangling_t dm;
int short_name;
int *num_args;
int *type_arg;
{
struct operator_code
{
@ -1633,6 +1637,10 @@ demangle_operator_name (dm, short_name, num_args)
DEMANGLE_TRACE ("operator-name", dm);
/* Assume the first argument is not a type. */
if (type_arg)
*type_arg = 0;
/* Is this a vendor-extended operator? */
if (c0 == 'v' && IS_DIGIT (c1))
{
@ -1652,6 +1660,16 @@ demangle_operator_name (dm, short_name, num_args)
return STATUS_OK;
}
/* Is it the sizeof variant that takes a type? */
if (c0 == 's' && c1 == 't')
{
RETURN_IF_ERROR (result_add (dm, " sizeof"));
*num_args = 1;
if (type_arg)
*type_arg = 1;
return STATUS_OK;
}
/* Perform a binary search for the operator code. */
while (1)
{
@ -3154,6 +3172,7 @@ demangle_expression (dm)
/* An operator expression. */
{
int num_args;
int type_arg;
status_t status = STATUS_OK;
dyn_string_t operator_name;
@ -3161,7 +3180,8 @@ demangle_expression (dm)
operations in infix notation, capture the operator name
first. */
RETURN_IF_ERROR (result_push (dm));
RETURN_IF_ERROR (demangle_operator_name (dm, 1, &num_args));
RETURN_IF_ERROR (demangle_operator_name (dm, 1, &num_args,
&type_arg));
operator_name = (dyn_string_t) result_pop (dm);
/* If it's binary, do an operand first. */
@ -3182,7 +3202,10 @@ demangle_expression (dm)
/* Emit its second (if binary) or only (if unary) operand. */
RETURN_IF_ERROR (result_add_char (dm, '('));
RETURN_IF_ERROR (demangle_expression (dm));
if (type_arg)
RETURN_IF_ERROR (demangle_type (dm));
else
RETURN_IF_ERROR (demangle_expression (dm));
RETURN_IF_ERROR (result_add_char (dm, ')'));
/* The ternary operator takes a third operand. */

View File

@ -1,3 +1,269 @@
2002-08-27 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (warn_abi): Declare it.
* decl.c (warn_abi): Define it.
(cxx_decode_option): Set it.
* class.c (layout_virtual_bases): Warn about bugs in G++ that
result in incorrect object layouts.
(layout_class_type): Likewise.
2002-08-22 Jason Merrill <jason@redhat.com>
PR c++/5607
* search.c (check_final_overrider): No longer static.
* class.c (update_vtable_entry_for_fn): Call it.
* cp-tree.h: Adjust.
* cp-lang.c (LANG_HOOKS_EXPR_SIZE): Define.
(cp_expr_size): New fn.
* call.c (convert_arg_to_ellipsis): Promote non-POD warning to error.
* typeck.c (build_modify_expr): Don't use save_expr on an lvalue.
2002-08-14 Release Manager
* GCC 3.2 Released.
2002-08-03 Nathan Sidwell <nathan@codesourcery.com>
PR 7470.
C++ ABI change - vfunc ordering.
* class.c (add_virtual_function): Remove.
(dfs_modify_all_vtables): Take list of all declared
virtuals. Assign all that are not in primary base.
(check_for_override): Adjust comments.
(create_vtable_ptr): Take single list of virtuals. Build chain
of declared virtuals here.
(layout_class_type): Take single list of virtuals. Adjust.
(finish_struct_1): Keep virtuals on single list. Adjust.
2002-07-30 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
* lang-specs.h: Remove __GXX_ABI_VERSION, moved to gcc.c.
2002-07-17 Scott Snyder <snyder@fnal.gov>
PR c++/7320
* rtti.c (get_tinfo_decl): Set DECL_COMDAT.
2002-07-05 Nathan Sidwell <nathan@codesourcery.com>
Repair damage on weak-impared targets caused by my previous patch.
* cp-tree.h (import_export_tinfo): Add parameter.
* decl2.c (import_export_tinfo): Add parameter, post adjust
DECL_COMDAT.
* rtti.c (emit_tinfo_decl): DECL_COMDAT is (nearly) always setup by
import_export_tinfo.
2002-06-30 Nathan Sidwell <nathan@codesourcery.com>
* cp-tree.h (CPTI_TINFO_DECL_TYPE): Replace with ...
(CPTI_TYPE_INFO_PTR_TYPE): ... this.
(tinfo_decl_type): Replace with ...
(type_info_ptr_type): ... this.
(import_export_tinfo): Declare.
(tinfo_decl_p): Rename to ...
(unemitted_tinfo_decl_p): ... this.
* decl2.c (import_export_decl): Break out tinfo handling into ...
(import_export_tinfo): ... here. New function.
(finish_file): Adjust.
* rtti.c (TINFO_REAL_NAME): New macro.
(init_rtti_processing): Create the tinfo types.
(get_tinfo_decl_dynamic): Use type_info_ptr_type, get_tinfo_ptr.
(get_tinfo_decl): Adjust.
(get_tinfo_ptr): New function.
(get_type_id): Use it.
(tinfo_base_init): Create vtable decl here, if it doesn't exist.
(ptr_initializer): Use get_tinfo_ptr.
(ptm_initializer): Likewise.
(synthesize_tinfo_var): Break into ...
(get_pseudo_ti_init): ... this. Just create the initializer.
(get_pseudo_ti_desc): .. and this.
(create_real_tinfo_var): Remove.
(create_pseudo_type_info): Don't create the vtable decl here.
(get_vmi_pseudo_type_info): Remove.
(create_tinfo_types): Adjust.
(tinfo_decl_p): Rename to ...
(unemitted_tinfo_decl_p): ... here. Adjust.
(emit_tinfo_decl): Adjust. Create the initializer.
2002-06-14 Jason Merrill <jason@redhat.com>
C++ ABI changes.
* class.c (build_base_field): Set DECL_PACKED.
(layout_class_type): Don't use tail padding of PODs.
* mangle.c (write_unqualified_name): Fix template conversion op
mangling.
2002-05-18 Jason Merrill <jason@redhat.com>
PR c++/6611
* decl2.c (import_export_decl): If we clear
DECL_NOT_REALLY_EXTERN, make sure DECL_EXTERNAL is set.
2002-05-14 Jason Merrill <jason@redhat.com>
* rtti.c (get_tinfo_decl): Don't call comdat_linkage.
Do set DECL_COMDAT.
(synthesize_tinfo_var): Take the public decl.
(create_real_tinfo_var): Likewise. Check DECL_COMDAT.
(emit_tinfo_decl): Adjust. Call import_export_decl.
* decl2.c (import_export_decl): Simplify tinfo decl handling.
2002-07-25 Release Manager
* GCC 3.1.1 Released.
2002-07-12 Mark Mitchell <mark@codesourcery.com>
* class.c (add_method): Correct handling of conversion operators.
2002-07-11 Mark Mitchell <mark@codesourcery.com>
PR c++/7224
* class.c (add_method): Simplify.
2002-07-11 Jason Merrill <jason@redhat.com>
PR c++/7279
* tree.c (cp_copy_res_decl_for_inlining): Also copy
TREE_ADDRESSABLE.
2002-07-10 Jason Merrill <jason@redhat.com>
PR c++/6255
* decl.c (lookup_name_real): Build a new TYPENAME_TYPE rather than
modifying the old one.
2002-07-08 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
* pt.c (can_complete_type_without_circularity): Add static to
function definition.
2002-07-05 Jim Wilson <wilson@redhat.com>
* decl.c (mark_named_label_lists): Add missing & in call to
mark_binding_level.
2002-07-05 Jason Merrill <jason@redhat.com>
* cvt.c (cp_convert_to_pointer): Call force_fit_type for null
pointers.
PR optimization/7145
* tree.c (cp_copy_res_decl_for_inlining): Also copy DECL_INITIAL.
2002-05-18 Jason Merrill <jason@redhat.com>
PR c++/6611
* decl2.c (import_export_decl): If we clear
DECL_NOT_REALLY_EXTERN, make sure DECL_EXTERNAL is set.
2002-07-03 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/6944
* init.c (build_aggr_init): Remove qualifiers of init before calling
build_vec_init.
(build_vec_init): Flatten multi-dimensional array during cleanup.
(build_vec_delete_1): Abort if the type of each element is array.
2002-07-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/6716
* pt.c (can_complete_type_without_circularity): New function.
(instantiate_class_template): Use it.
* typeck2.c (incomplete_type_error): Improve error message
due to incomplete fields.
2002-07-01 Mark Mitchell <mark@codesourcery.com>
PR c++/7112
* mangle.c (write_expression): Add mangling for sizeof when
applied to a type.
* operators.def: Remove stale comment.
2002-06-27 Mark Mitchell <mark@codesourcery.com>
PR c++/6695
* pt.c (tsubst_friend_class): Substitute into the context of the
friend before using it.
2002-06-23 Matt Thomas <matt@3am-software.com>
* decl.c (finish_function): Change "#ifdef VMS_TARGET" to
"#if VMS_TARGET".
2002-06-20 Richard Henderson <rth@redhat.com>
PR c++/6747
* typeck.c (mark_addressable): Don't test TREE_ADDRESSABLE early.
Call put_var_into_stack.
2002-06-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/6892
* pt.c (tsubst_expr): Handle FILE_STMT.
2002-06-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/6723
* pt.c (lookup_template_class): Don't build complete argument of
BOUND_TEMPLATE_TEMPLATE_PARM if appeared as a default template
argument.
2002-06-16 Richard Henderson <rth@redhat.com>
PR opt/6793
* tree.c (cp_cannot_inline_tree_fn): Don't short-circuit test
after template instantiation.
2002-06-07 H.J. Lu (hjl@gnu.org)
* decl2.c (flag_use_cxa_atexit): Set to DEFAULT_USE_CXA_ATEXIT.
2002-05-23 Neil Booth <neil@daikokuya.demon.co.uk>
* cp-lang.c (LANG_HOOKS_POST_OPTIONS): Use c_common_post_options.
* cp-tree.h (cxx_post_options): Kill.
* cp-lex.c (cxx_post_options): Kill.
2002-05-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
* error.c (dump_type) [TYPEOF_TYPE]: Fix parenthesis printing.
2002-05-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/186, DR 259
* pt.c (do_decl_instantiation): Don't complain explicit
instantiation after explicit specialization.
(do_type_instantiation): Likewise.
2002-05-09 Jason Merrill <jason@redhat.com>
* pt.c (tsubst_expr) [ASM_STMT]: Copy ASM_INPUT_P.
2002-05-15 Alexandre Oliva <aoliva@redhat.com>
* cp-tree.h (struct lang_type): Added non_zero_init.
(CLASSTYPE_NON_ZERO_INIT_P): New macro.
(zero_init_p, force_store_init_value, build_forced_zero_init): Declare.
* class.c (check_field_decls): Test non_zero_init.
* cvt.c (convert_to_pointer_force): Use cp_convert_to_pointer for
zero-to-NULL conversions.
* decl.c (obscure_complex_init): Don't reset DECL_INITIAL of a
type that needs zero-initialization without zeros.
(check_initializer_decl): Compute zero-initializer for types
that require a non-trivial one.
* init.c (build_forced_zero_init): New function.
(build_default_init): Use it.
* tree.c (zero_init_p): New function.
* typeck2.c (force_store_init_value): New function.
(process_init_constructor): Create non-trivial zero-initializers
for array members and class fields.
2002-05-14 Release Manager
* GCC 3.1 Released.
2002-05-03 Jason Merrill <jason@redhat.com>
* decl.c (BOOL_TYPE_SIZE): Move default to defaults.h.
@ -26,6 +292,7 @@
2002-04-30 Jason Merrill <jason@redhat.com>
PR debug/6436
* decl.c (grokdeclarator): Don't override TYPE_NAME of an
anonymous class with a typedef if there are attributes.
@ -163,12 +430,12 @@
2002-04-11 Andrew Haley <aph@redhat.com>
* typeck.c (type_after_usual_arithmetic_conversions):
If two types have the same variant, return immediately.
When two floating-point operands are the same precision:
convert to float if one of the operands is float;
if neither operand is one of the standard types, return the type
of the first operand.
* typeck.c (type_after_usual_arithmetic_conversions):
If two types have the same variant, return immediately.
When two floating-point operands are the same precision:
convert to float if one of the operands is float;
if neither operand is one of the standard types, return the type
of the first operand.
2002-04-12 Richard Sandiford <rsandifo@redhat.com>

View File

@ -251,7 +251,7 @@ cp/spew.o: cp/spew.c $(CXX_TREE_H) cp/parse.h flags.h cp/lex.h toplev.h
cp/lex.o: cp/lex.c $(CXX_TREE_H) cp/parse.h flags.h cp/lex.h c-pragma.h \
toplev.h output.h mbchar.h $(GGC_H) input.h diagnostic.h cp/operators.def \
$(TM_P_H)
cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) toplev.h langhooks.h langhooks-def.h \
cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) toplev.h langhooks.h $(LANGHOOKS_DEF_H) \
c-common.h
cp/decl.o: cp/decl.c $(CXX_TREE_H) flags.h cp/lex.h cp/decl.h stack.h \
output.h $(EXPR_H) except.h toplev.h hash.h $(GGC_H) $(RTL_H) \

View File

@ -4022,9 +4022,12 @@ convert_arg_to_ellipsis (arg)
if (arg != error_mark_node && ! pod_type_p (TREE_TYPE (arg)))
{
/* Undefined behaviour [expr.call] 5.2.2/7. */
warning ("cannot pass objects of non-POD type `%#T' through `...'",
TREE_TYPE (arg));
/* Undefined behaviour [expr.call] 5.2.2/7. We used to just warn
here and do a bitwise copy, but now cp_expr_size will abort if we
try to do that. */
error ("cannot pass objects of non-POD type `%#T' through `...'",
TREE_TYPE (arg));
arg = error_mark_node;
}
return arg;

View File

@ -114,7 +114,6 @@ static int build_primary_vtable PARAMS ((tree, tree));
static int build_secondary_vtable PARAMS ((tree, tree));
static void finish_vtbls PARAMS ((tree));
static void modify_vtable_entry PARAMS ((tree, tree, tree, tree, tree *));
static void add_virtual_function PARAMS ((tree *, tree *, int *, tree, tree));
static tree delete_duplicate_fields_1 PARAMS ((tree, tree));
static void delete_duplicate_fields PARAMS ((tree));
static void finish_struct_bits PARAMS ((tree));
@ -150,8 +149,8 @@ static void check_methods PARAMS ((tree));
static void remove_zero_width_bit_fields PARAMS ((tree));
static void check_bases PARAMS ((tree, int *, int *, int *));
static void check_bases_and_members PARAMS ((tree, int *));
static tree create_vtable_ptr PARAMS ((tree, int *, int *, tree *, tree *));
static void layout_class_type PARAMS ((tree, int *, int *, tree *, tree *));
static tree create_vtable_ptr PARAMS ((tree, int *, int *, tree *));
static void layout_class_type PARAMS ((tree, int *, int *, tree *));
static void fixup_pending_inline PARAMS ((tree));
static void fixup_inline_methods PARAMS ((tree));
static void set_primary_base PARAMS ((tree, tree, int *));
@ -792,61 +791,6 @@ set_vindex (decl, vfuns_p)
? TARGET_VTABLE_USES_DESCRIPTORS : 1);
DECL_VINDEX (decl) = build_shared_int_cst (vindex);
}
/* Add a virtual function to all the appropriate vtables for the class
T. DECL_VINDEX(X) should be error_mark_node, if we want to
allocate a new slot in our table. If it is error_mark_node, we
know that no other function from another vtable is overridden by X.
VFUNS_P keeps track of how many virtuals there are in our
main vtable for the type, and we build upon the NEW_VIRTUALS list
and return it. */
static void
add_virtual_function (new_virtuals_p, overridden_virtuals_p,
vfuns_p, fndecl, t)
tree *new_virtuals_p;
tree *overridden_virtuals_p;
int *vfuns_p;
tree fndecl;
tree t; /* Structure type. */
{
tree new_virtual;
/* If this function doesn't override anything from a base class, we
can just assign it a new DECL_VINDEX now. Otherwise, if it does
override something, we keep it around and assign its DECL_VINDEX
later, in modify_all_vtables. */
if (TREE_CODE (DECL_VINDEX (fndecl)) == INTEGER_CST)
/* We've already dealt with this function. */
return;
new_virtual = make_node (TREE_LIST);
BV_FN (new_virtual) = fndecl;
BV_DELTA (new_virtual) = integer_zero_node;
if (DECL_VINDEX (fndecl) == error_mark_node)
{
/* FNDECL is a new virtual function; it doesn't override any
virtual function in a base class. */
/* We remember that this was the base sub-object for rtti. */
CLASSTYPE_RTTI (t) = t;
/* Now assign virtual dispatch information. */
set_vindex (fndecl, vfuns_p);
DECL_VIRTUAL_CONTEXT (fndecl) = t;
/* Save the state we've computed on the NEW_VIRTUALS list. */
TREE_CHAIN (new_virtual) = *new_virtuals_p;
*new_virtuals_p = new_virtual;
}
else
{
/* FNDECL overrides a function from a base class. */
TREE_CHAIN (new_virtual) = *overridden_virtuals_p;
*overridden_virtuals_p = new_virtual;
}
}
/* Add method METHOD to class TYPE. If ERROR_P is true, we are adding
the method after the class has already been defined because a
@ -973,69 +917,60 @@ add_method (type, method, error_p)
fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
tree parms1;
tree parms2;
bool same = 1;
if (TREE_CODE (fn) != TREE_CODE (method))
continue;
if (TREE_CODE (method) != TEMPLATE_DECL)
/* [over.load] Member function declarations with the
same name and the same parameter types cannot be
overloaded if any of them is a static member
function declaration.
[namespace.udecl] When a using-declaration brings names
from a base class into a derived class scope, member
functions in the derived class override and/or hide member
functions with the same name and parameter types in a base
class (rather than conflicting). */
parms1 = TYPE_ARG_TYPES (TREE_TYPE (fn));
parms2 = TYPE_ARG_TYPES (TREE_TYPE (method));
/* Compare the quals on the 'this' parm. Don't compare
the whole types, as used functions are treated as
coming from the using class in overload resolution. */
if (! DECL_STATIC_FUNCTION_P (fn)
&& ! DECL_STATIC_FUNCTION_P (method)
&& (TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms1)))
!= TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms2)))))
same = 0;
if (! DECL_STATIC_FUNCTION_P (fn))
parms1 = TREE_CHAIN (parms1);
if (! DECL_STATIC_FUNCTION_P (method))
parms2 = TREE_CHAIN (parms2);
if (same && compparms (parms1, parms2)
&& (!DECL_CONV_FN_P (fn)
|| same_type_p (TREE_TYPE (TREE_TYPE (fn)),
TREE_TYPE (TREE_TYPE (method)))))
{
/* [over.load] Member function declarations with the
same name and the same parameter types cannot be
overloaded if any of them is a static member
function declaration.
[namespace.udecl] When a using-declaration brings names
from a base class into a derived class scope, member
functions in the derived class override and/or hide member
functions with the same name and parameter types in a base
class (rather than conflicting). */
if ((DECL_STATIC_FUNCTION_P (fn)
!= DECL_STATIC_FUNCTION_P (method))
|| using)
if (using && DECL_CONTEXT (fn) == type)
/* Defer to the local function. */
return;
else
{
tree parms1 = TYPE_ARG_TYPES (TREE_TYPE (fn));
tree parms2 = TYPE_ARG_TYPES (TREE_TYPE (method));
int same = 1;
cp_error_at ("`%#D' and `%#D' cannot be overloaded",
method, fn, method);
/* Compare the quals on the 'this' parm. Don't compare
the whole types, as used functions are treated as
coming from the using class in overload resolution. */
if (using
&& ! DECL_STATIC_FUNCTION_P (fn)
&& ! DECL_STATIC_FUNCTION_P (method)
&& (TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms1)))
!= TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms2)))))
same = 0;
if (! DECL_STATIC_FUNCTION_P (fn))
parms1 = TREE_CHAIN (parms1);
if (! DECL_STATIC_FUNCTION_P (method))
parms2 = TREE_CHAIN (parms2);
if (same && compparms (parms1, parms2))
{
if (using && DECL_CONTEXT (fn) == type)
/* Defer to the local function. */
return;
else
error ("`%#D' and `%#D' cannot be overloaded",
fn, method);
}
/* We don't call duplicate_decls here to merge
the declarations because that will confuse
things if the methods have inline
definitions. In particular, we will crash
while processing the definitions. */
return;
}
}
if (!decls_match (fn, method))
continue;
/* There has already been a declaration of this method
or member template. */
cp_error_at ("`%D' has already been declared in `%T'",
method, type);
/* We don't call duplicate_decls here to merge the
declarations because that will confuse things if the
methods have inline definitions. In particular, we
will crash while processing the definitions. */
return;
}
}
@ -2519,6 +2454,10 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals)
if (overrider == error_mark_node)
return;
/* Check for unsupported covariant returns again now that we've
calculated the base offsets. */
check_final_overrider (TREE_PURPOSE (overrider), fn);
/* Assume that we will produce a thunk that convert all the way to
the final overrider, and not to an intermediate virtual base. */
virtual_base = NULL_TREE;
@ -2641,18 +2580,18 @@ dfs_modify_vtables (binfo, data)
/* Update all of the primary and secondary vtables for T. Create new
vtables as required, and initialize their RTTI information. Each
of the functions in OVERRIDDEN_VIRTUALS overrides a virtual
function from a base class; find and modify the appropriate entries
to point to the overriding functions. Returns a list, in
declaration order, of the functions that are overridden in this
class, but do not appear in the primary base class vtable, and
which should therefore be appended to the end of the vtable for T. */
of the functions in VIRTUALS is declared in T and may override a
virtual function from a base class; find and modify the appropriate
entries to point to the overriding functions. Returns a list, in
declaration order, of the virtual functions that are declared in T,
but do not appear in the primary base class vtable, and which
should therefore be appended to the end of the vtable for T. */
static tree
modify_all_vtables (t, vfuns_p, overridden_virtuals)
modify_all_vtables (t, vfuns_p, virtuals)
tree t;
int *vfuns_p;
tree overridden_virtuals;
tree virtuals;
{
tree binfo = TYPE_BINFO (t);
tree *fnsp;
@ -2664,14 +2603,16 @@ modify_all_vtables (t, vfuns_p, overridden_virtuals)
t);
dfs_walk (binfo, dfs_unmark, dfs_marked_real_bases_queue_p, t);
/* Include overriding functions for secondary vtables in our primary
vtable. */
for (fnsp = &overridden_virtuals; *fnsp; )
/* Add virtual functions not already in our primary vtable. These
will be both those introduced by this class, and those overridden
from secondary bases. It does not include virtuals merely
inherited from secondary bases. */
for (fnsp = &virtuals; *fnsp; )
{
tree fn = TREE_VALUE (*fnsp);
if (!BINFO_VIRTUALS (binfo)
|| !value_member (fn, BINFO_VIRTUALS (binfo)))
if (!value_member (fn, BINFO_VIRTUALS (binfo))
|| DECL_VINDEX (fn) == error_mark_node)
{
/* Set the vtable index. */
set_vindex (fn, vfuns_p);
@ -2684,8 +2625,7 @@ modify_all_vtables (t, vfuns_p, overridden_virtuals)
BV_DELTA (*fnsp) = integer_zero_node;
BV_VCALL_INDEX (*fnsp) = NULL_TREE;
/* This is an overridden function not already in our
vtable. Keep it. */
/* This is a function not already in our vtable. Keep it. */
fnsp = &TREE_CHAIN (*fnsp);
}
else
@ -2693,7 +2633,7 @@ modify_all_vtables (t, vfuns_p, overridden_virtuals)
*fnsp = TREE_CHAIN (*fnsp);
}
return overridden_virtuals;
return virtuals;
}
/* Here, we already know that they match in every respect.
@ -2763,16 +2703,14 @@ check_for_override (decl, ctype)
|| IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)))
&& look_for_overrides (ctype, decl)
&& !DECL_STATIC_FUNCTION_P (decl))
{
/* Set DECL_VINDEX to a value that is neither an
INTEGER_CST nor the error_mark_node so that
add_virtual_function will realize this is an
overriding function. */
DECL_VINDEX (decl) = decl;
}
/* Set DECL_VINDEX to a value that is neither an INTEGER_CST nor
the error_mark_node so that we know it is an overriding
function. */
DECL_VINDEX (decl) = decl;
if (DECL_VIRTUAL_P (decl))
{
if (DECL_VINDEX (decl) == NULL_TREE)
if (!DECL_VINDEX (decl))
DECL_VINDEX (decl) = error_mark_node;
IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1;
}
@ -3410,6 +3348,9 @@ check_field_decls (t, access_decls, empty_p,
to be allowed in POD structs. */
CLASSTYPE_NON_POD_P (t) = 1;
if (! zero_init_p (type))
CLASSTYPE_NON_ZERO_INIT_P (t) = 1;
/* If any field is const, the structure type is pseudo-const. */
if (CP_TYPE_CONST_P (type))
{
@ -3836,6 +3777,8 @@ build_base_field (rli, binfo, empty_p, offsets, t)
DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype);
DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype);
DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype);
/* Tell the backend not to round up to TYPE_ALIGN. */
DECL_PACKED (decl) = 1;
if (!integer_zerop (DECL_SIZE (decl)))
{
@ -4389,31 +4332,37 @@ check_bases_and_members (t, empty_p)
accordingly. If a new vfield was created (because T doesn't have a
primary base class), then the newly created field is returned. It
is not added to the TYPE_FIELDS list; it is the caller's
responsibility to do that. */
responsibility to do that. Accumulate declared virtual functions
on VIRTUALS_P. */
static tree
create_vtable_ptr (t, empty_p, vfuns_p,
new_virtuals_p, overridden_virtuals_p)
create_vtable_ptr (t, empty_p, vfuns_p, virtuals_p)
tree t;
int *empty_p;
int *vfuns_p;
tree *new_virtuals_p;
tree *overridden_virtuals_p;
tree *virtuals_p;
{
tree fn;
/* Loop over the virtual functions, adding them to our various
vtables. */
/* Collect the virtual functions declared in T. */
for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))
if (DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
add_virtual_function (new_virtuals_p, overridden_virtuals_p,
vfuns_p, fn, t);
if (DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)
&& TREE_CODE (DECL_VINDEX (fn)) != INTEGER_CST)
{
tree new_virtual = make_node (TREE_LIST);
BV_FN (new_virtual) = fn;
BV_DELTA (new_virtual) = integer_zero_node;
TREE_CHAIN (new_virtual) = *virtuals_p;
*virtuals_p = new_virtual;
}
/* If we couldn't find an appropriate base class, create a new field
here. Even if there weren't any new virtual functions, we might need a
new virtual function table if we're supposed to include vptrs in
all classes that need them. */
if (!TYPE_VFIELD (t) && (*vfuns_p || TYPE_CONTAINS_VPTR_P (t)))
if (!TYPE_VFIELD (t) && (*virtuals_p || TYPE_CONTAINS_VPTR_P (t)))
{
/* We build this decl with vtbl_ptr_type_node, which is a
`vtable_entry_type*'. It might seem more precise to use
@ -4608,6 +4557,7 @@ layout_virtual_bases (t, offsets)
{
tree vbases, dsize;
unsigned HOST_WIDE_INT eoc;
bool first_vbase = true;
if (CLASSTYPE_N_BASECLASSES (t) == 0)
return;
@ -4635,6 +4585,7 @@ layout_virtual_bases (t, offsets)
if (!TREE_VIA_VIRTUAL (vbases))
continue;
vbase = binfo_for_vbase (BINFO_TYPE (vbases), t);
if (!BINFO_PRIMARY_P (vbase))
@ -4652,7 +4603,6 @@ layout_virtual_bases (t, offsets)
/* Add padding so that we can put the virtual base class at an
appropriately aligned offset. */
dsize = round_up (dsize, desired_align);
usize = size_binop (CEIL_DIV_EXPR, dsize, bitsize_unit_node);
/* We try to squish empty virtual bases in just like
@ -4680,11 +4630,30 @@ layout_virtual_bases (t, offsets)
CLASSTYPE_SIZE (basetype)));
}
/* If the first virtual base might have been placed at a
lower address, had we started from CLASSTYPE_SIZE, rather
than TYPE_SIZE, issue a warning. There can be both false
positives and false negatives from this warning in rare
cases; to deal with all the possibilities would probably
require performing both layout algorithms and comparing
the results which is not particularly tractable. */
if (warn_abi
&& first_vbase
&& tree_int_cst_lt (size_binop (CEIL_DIV_EXPR,
round_up (CLASSTYPE_SIZE (t),
desired_align),
bitsize_unit_node),
BINFO_OFFSET (vbase)))
warning ("offset of virtual base `%T' is not ABI-compliant and may change in a future version of GCC",
basetype);
/* Keep track of the offsets assigned to this virtual base. */
record_subobject_offsets (BINFO_TYPE (vbase),
BINFO_OFFSET (vbase),
offsets,
/*vbases_p=*/0);
first_vbase = false;
}
}
@ -4805,16 +4774,14 @@ splay_tree_compare_integer_csts (k1, k2)
/* Calculate the TYPE_SIZE, TYPE_ALIGN, etc for T. Calculate
BINFO_OFFSETs for all of the base-classes. Position the vtable
pointer. */
pointer. Accumulate declared virtual functions on VIRTUALS_P. */
static void
layout_class_type (t, empty_p, vfuns_p,
new_virtuals_p, overridden_virtuals_p)
layout_class_type (t, empty_p, vfuns_p, virtuals_p)
tree t;
int *empty_p;
int *vfuns_p;
tree *new_virtuals_p;
tree *overridden_virtuals_p;
tree *virtuals_p;
{
tree non_static_data_members;
tree field;
@ -4824,6 +4791,8 @@ layout_class_type (t, empty_p, vfuns_p,
/* Maps offsets (represented as INTEGER_CSTs) to a TREE_LIST of
types that appear at that offset. */
splay_tree empty_base_offsets;
/* True if the last field layed out was a bit-field. */
bool last_field_was_bitfield = false;
/* Keep track of the first non-static data member. */
non_static_data_members = TYPE_FIELDS (t);
@ -4836,8 +4805,7 @@ layout_class_type (t, empty_p, vfuns_p,
determine_primary_base (t, vfuns_p);
/* Create a pointer to our virtual function table. */
vptr = create_vtable_ptr (t, empty_p, vfuns_p,
new_virtuals_p, overridden_virtuals_p);
vptr = create_vtable_ptr (t, empty_p, vfuns_p, virtuals_p);
/* The vptr is always the first thing in the class. */
if (vptr)
@ -4914,6 +4882,18 @@ layout_class_type (t, empty_p, vfuns_p,
layout_nonempty_base_or_field (rli, field, NULL_TREE,
empty_base_offsets, t);
/* If a bit-field does not immediately follow another bit-field,
and yet it starts in the middle of a byte, we have failed to
comply with the ABI. */
if (warn_abi
&& DECL_C_BIT_FIELD (field)
&& !last_field_was_bitfield
&& !integer_zerop (size_binop (TRUNC_MOD_EXPR,
DECL_FIELD_BIT_OFFSET (field),
bitsize_unit_node)))
cp_warning_at ("offset of `%D' is not ABI-compliant and may change in a future version of GCC",
field);
/* If we needed additional padding after this field, add it
now. */
if (padding)
@ -4931,6 +4911,8 @@ layout_class_type (t, empty_p, vfuns_p,
NULL_TREE,
empty_base_offsets, t);
}
last_field_was_bitfield = DECL_C_BIT_FIELD (field);
}
/* It might be the case that we grew the class to allocate a
@ -4977,6 +4959,12 @@ layout_class_type (t, empty_p, vfuns_p,
CLASSTYPE_SIZE (t) = bitsize_zero_node;
CLASSTYPE_SIZE_UNIT (t) = size_zero_node;
}
/* If this is a POD, we can't reuse its tail padding. */
else if (!CLASSTYPE_NON_POD_P (t))
{
CLASSTYPE_SIZE (t) = TYPE_SIZE (t);
CLASSTYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (t);
}
else
{
CLASSTYPE_SIZE (t) = TYPE_BINFO_SIZE (t);
@ -5038,15 +5026,8 @@ finish_struct_1 (t)
{
tree x;
int vfuns;
/* The NEW_VIRTUALS is a TREE_LIST. The TREE_VALUE of each node is
a FUNCTION_DECL. Each of these functions is a virtual function
declared in T that does not override any virtual function from a
base class. */
tree new_virtuals = NULL_TREE;
/* The OVERRIDDEN_VIRTUALS list is like the NEW_VIRTUALS list,
except that each declaration here overrides the declaration from
a base class. */
tree overridden_virtuals = NULL_TREE;
/* A TREE_LIST. The TREE_VALUE of each node is a FUNCTION_DECL. */
tree virtuals = NULL_TREE;
int n_fields = 0;
tree vfield;
int empty = 1;
@ -5076,8 +5057,7 @@ finish_struct_1 (t)
check_bases_and_members (t, &empty);
/* Layout the class itself. */
layout_class_type (t, &empty, &vfuns,
&new_virtuals, &overridden_virtuals);
layout_class_type (t, &empty, &vfuns, &virtuals);
/* Make sure that we get our own copy of the vfield FIELD_DECL. */
vfield = TYPE_VFIELD (t);
@ -5101,8 +5081,7 @@ finish_struct_1 (t)
else
my_friendly_assert (!vfield || DECL_FIELD_CONTEXT (vfield) == t, 20010726);
overridden_virtuals
= modify_all_vtables (t, &vfuns, nreverse (overridden_virtuals));
virtuals = modify_all_vtables (t, &vfuns, nreverse (virtuals));
/* If we created a new vtbl pointer for this class, add it to the
list. */
@ -5111,9 +5090,8 @@ finish_struct_1 (t)
= chainon (CLASSTYPE_VFIELDS (t), build_tree_list (NULL_TREE, t));
/* If necessary, create the primary vtable for this class. */
if (new_virtuals || overridden_virtuals || TYPE_CONTAINS_VPTR_P (t))
if (virtuals || TYPE_CONTAINS_VPTR_P (t))
{
new_virtuals = nreverse (new_virtuals);
/* We must enter these virtuals into the table. */
if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
build_primary_vtable (NULL_TREE, t);
@ -5126,7 +5104,6 @@ finish_struct_1 (t)
constructors might clobber the virtual function table. But
they don't if the derived class shares the exact vtable of the base
class. */
CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1;
}
/* If we didn't need a new vtable, see if we should copy one from
@ -5152,14 +5129,8 @@ finish_struct_1 (t)
20000116);
CLASSTYPE_VSIZE (t) = vfuns;
/* Entries for virtual functions defined in the primary base are
followed by entries for new functions unique to this class. */
TYPE_BINFO_VIRTUALS (t)
= chainon (TYPE_BINFO_VIRTUALS (t), new_virtuals);
/* Finally, add entries for functions that override virtuals
from non-primary bases. */
TYPE_BINFO_VIRTUALS (t)
= chainon (TYPE_BINFO_VIRTUALS (t), overridden_virtuals);
/* Add entries for virtual functions introduced by this class. */
TYPE_BINFO_VIRTUALS (t) = chainon (TYPE_BINFO_VIRTUALS (t), virtuals);
}
finish_struct_bits (t);

View File

@ -1,5 +1,5 @@
/* Language-dependent hooks for C++.
Copyright 2001 Free Software Foundation, Inc.
Copyright 2001, 2002 Free Software Foundation, Inc.
Contributed by Alexandre Oliva <aoliva@redhat.com>
This file is part of GNU CC.
@ -28,7 +28,8 @@ Boston, MA 02111-1307, USA. */
#include "langhooks.h"
#include "langhooks-def.h"
static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree));
static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree));
static tree cp_expr_size PARAMS ((tree));
#undef LANG_HOOKS_NAME
#define LANG_HOOKS_NAME "GNU C++"
@ -43,7 +44,7 @@ static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree));
#undef LANG_HOOKS_DECODE_OPTION
#define LANG_HOOKS_DECODE_OPTION cxx_decode_option
#undef LANG_HOOKS_POST_OPTIONS
#define LANG_HOOKS_POST_OPTIONS cxx_post_options
#define LANG_HOOKS_POST_OPTIONS c_common_post_options
#undef LANG_HOOKS_GET_ALIAS_SET
#define LANG_HOOKS_GET_ALIAS_SET cxx_get_alias_set
#undef LANG_HOOKS_EXPAND_CONSTANT
@ -91,6 +92,8 @@ static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree));
#define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN cp_dump_tree
#undef LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN
#define LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN cp_type_quals
#undef LANG_HOOKS_EXPR_SIZE
#define LANG_HOOKS_EXPR_SIZE cp_expr_size
/* Each front end provides its own hooks, for toplev.c. */
const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
@ -108,3 +111,28 @@ cxx_get_alias_set (t)
return c_common_get_alias_set (t);
}
/* Langhook for expr_size: Tell the backend that the value of an expression
of non-POD class type does not include any tail padding; a derived class
might have allocated something there. */
static tree
cp_expr_size (exp)
tree exp;
{
if (CLASS_TYPE_P (TREE_TYPE (exp)))
{
/* The backend should not be interested in the size of an expression
of a type with both of these set; all copies of such types must go
through a constructor or assignment op. */
if (TYPE_HAS_COMPLEX_INIT_REF (TREE_TYPE (exp))
&& TYPE_HAS_COMPLEX_ASSIGN_REF (TREE_TYPE (exp)))
abort ();
/* This would be wrong for a type with virtual bases, but they are
caught by the abort above. */
return CLASSTYPE_SIZE_UNIT (TREE_TYPE (exp));
}
else
/* Use the default code. */
return lhd_expr_size (exp);
}

View File

@ -539,7 +539,7 @@ enum cp_tree_index
CPTI_STD,
CPTI_ABI,
CPTI_TYPE_INFO_TYPE,
CPTI_TINFO_DECL_TYPE,
CPTI_TYPE_INFO_PTR_TYPE,
CPTI_ABORT_FNDECL,
CPTI_GLOBAL_DELETE_FNDECL,
CPTI_AGGR_TAG,
@ -626,7 +626,7 @@ extern tree cp_global_trees[CPTI_MAX];
#define std_node cp_global_trees[CPTI_STD]
#define abi_node cp_global_trees[CPTI_ABI]
#define type_info_type_node cp_global_trees[CPTI_TYPE_INFO_TYPE]
#define tinfo_decl_type cp_global_trees[CPTI_TINFO_DECL_TYPE]
#define type_info_ptr_type cp_global_trees[CPTI_TYPE_INFO_PTR_TYPE]
#define abort_fndecl cp_global_trees[CPTI_ABORT_FNDECL]
#define global_delete_fndecl cp_global_trees[CPTI_GLOBAL_DELETE_FNDECL]
#define current_aggr cp_global_trees[CPTI_AGGR_TAG]
@ -934,6 +934,11 @@ extern int flag_operator_names;
extern int flag_gnu_binutils;
/* Nonzero means warn about things that will change when compiling
with an ABI-compliant compiler. */
extern int warn_abi;
/* Nonzero means warn about implicit declarations. */
extern int warn_implicit;
@ -1245,6 +1250,8 @@ struct lang_type
unsigned is_partial_instantiation : 1;
unsigned java_interface : 1;
unsigned non_zero_init : 1;
/* When adding a flag here, consider whether or not it ought to
apply to a template instance if it applies to the template. If
so, make sure to copy it in instantiate_class_template! */
@ -1252,7 +1259,7 @@ struct lang_type
/* There are some bits left to fill out a 32-bit word. Keep track
of this by updating the size of this bitfield whenever you add or
remove a flag. */
unsigned dummy : 8;
unsigned dummy : 7;
int vsize;
@ -1500,9 +1507,14 @@ struct lang_type
#define CLASSTYPE_HAS_MUTABLE(NODE) (TYPE_LANG_SPECIFIC (NODE)->has_mutable)
#define TYPE_HAS_MUTABLE_P(NODE) (cp_has_mutable_p (NODE))
/* Nonzero means that this class type is a non-POD class. */
/* Nonzero means that this class type is a non-POD class. */
#define CLASSTYPE_NON_POD_P(NODE) (TYPE_LANG_SPECIFIC (NODE)->non_pod_class)
/* Nonzero means that this class contains pod types whose default
initialization is not a zero initialization (namely, pointers to
data members). */
#define CLASSTYPE_NON_ZERO_INIT_P(NODE) (TYPE_LANG_SPECIFIC (NODE)->non_zero_init)
/* Nonzero if this class is "nearly empty", i.e., contains only a
virtual function table pointer. */
#define CLASSTYPE_NEARLY_EMPTY_P(NODE) \
@ -3812,6 +3824,7 @@ extern tree coerce_delete_type PARAMS ((tree));
extern void comdat_linkage PARAMS ((tree));
extern void import_export_vtable PARAMS ((tree, tree, int));
extern void import_export_decl PARAMS ((tree));
extern void import_export_tinfo PARAMS ((tree, tree, int));
extern tree build_cleanup PARAMS ((tree));
extern void finish_file PARAMS ((void));
extern tree reparse_absdcl_as_expr PARAMS ((tree, tree));
@ -3900,6 +3913,7 @@ extern tree build_aggr_init PARAMS ((tree, tree, int));
extern int is_aggr_type PARAMS ((tree, int));
extern tree get_aggr_from_typedef PARAMS ((tree, int));
extern tree get_type_value PARAMS ((tree));
extern tree build_forced_zero_init PARAMS ((tree));
extern tree build_member_call PARAMS ((tree, tree, tree));
extern tree build_offset_ref PARAMS ((tree, tree));
extern tree resolve_offset_ref PARAMS ((tree));
@ -3953,7 +3967,6 @@ extern int cp_type_qual_from_rid PARAMS ((tree));
extern const char *cxx_init PARAMS ((const char *));
extern void cxx_finish PARAMS ((void));
extern void cxx_init_options PARAMS ((void));
extern void cxx_post_options PARAMS ((void));
/* in method.c */
extern void init_method PARAMS ((void));
@ -4044,7 +4057,7 @@ extern tree get_tinfo_decl PARAMS((tree));
extern tree get_typeid PARAMS((tree));
extern tree build_dynamic_cast PARAMS((tree, tree));
extern void emit_support_tinfos PARAMS((void));
extern int tinfo_decl_p PARAMS((tree, void *));
extern int unemitted_tinfo_decl_p PARAMS((tree, void *));
extern int emit_tinfo_decl PARAMS((tree *, void *));
/* in search.c */
@ -4076,6 +4089,7 @@ extern tree lookup_conversions PARAMS ((tree));
extern tree binfo_for_vtable PARAMS ((tree));
extern tree binfo_from_vbase PARAMS ((tree));
extern tree look_for_overrides_here PARAMS ((tree, tree));
extern int check_final_overrider PARAMS ((tree, tree));
extern tree dfs_walk PARAMS ((tree,
tree (*) (tree, void *),
tree (*) (tree, void *),
@ -4212,6 +4226,7 @@ extern void end_input PARAMS ((void));
/* in tree.c */
extern void init_tree PARAMS ((void));
extern int pod_type_p PARAMS ((tree));
extern int zero_init_p PARAMS ((tree));
extern tree canonical_type_variant PARAMS ((tree));
extern void unshare_base_binfos PARAMS ((tree));
extern int member_p PARAMS ((tree));
@ -4357,6 +4372,7 @@ extern int abstract_virtuals_error PARAMS ((tree, tree));
#define my_friendly_assert(EXP, N) (void) \
(((EXP) == 0) ? (fancy_abort (__FILE__, __LINE__, __FUNCTION__), 0) : 0)
extern tree force_store_init_value PARAMS ((tree, tree));
extern tree store_init_value PARAMS ((tree, tree));
extern tree digest_init PARAMS ((tree, tree, tree *));
extern tree build_scoped_ref PARAMS ((tree, tree));

View File

@ -1,6 +1,6 @@
/* Language-level data type conversion for GNU C++.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000 Free Software Foundation, Inc.
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
@ -249,6 +249,8 @@ cp_convert_to_pointer (type, expr, force)
else
expr = build_int_2 (0, 0);
TREE_TYPE (expr) = type;
/* Fix up the representation of -1 if appropriate. */
force_fit_type (expr, 0);
return expr;
}
@ -285,13 +287,6 @@ convert_to_pointer_force (type, expr)
register tree intype = TREE_TYPE (expr);
register enum tree_code form = TREE_CODE (intype);
if (integer_zerop (expr))
{
expr = build_int_2 (0, 0);
TREE_TYPE (expr) = type;
return expr;
}
if (form == POINTER_TYPE)
{
intype = TYPE_MAIN_VARIANT (intype);

View File

@ -1970,7 +1970,7 @@ mark_named_label_lists (labs, uses)
for (; l; l = l->next)
{
ggc_mark (l);
mark_binding_level (l->binding_level);
mark_binding_level (&l->binding_level);
ggc_mark_tree (l->old_value);
ggc_mark_tree (l->label_decl);
ggc_mark_tree (l->bad_decls);
@ -6101,7 +6101,13 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
if (got_scope && got_scope != type
&& val && TREE_CODE (val) == TYPE_DECL
&& TREE_CODE (TREE_TYPE (val)) == TYPENAME_TYPE)
TYPE_CONTEXT (TREE_TYPE (val)) = got_scope;
{
val = TREE_TYPE (val);
val = build_typename_type (got_scope, name,
TYPENAME_TYPE_FULLNAME (val),
TREE_TYPE (val));
val = TYPE_STUB_DECL (val);
}
}
}
else
@ -7605,7 +7611,13 @@ obscure_complex_init (decl, init)
NULL_TREE);
else
#endif
DECL_INITIAL (decl) = error_mark_node;
{
if (zero_init_p (TREE_TYPE (decl)))
DECL_INITIAL (decl) = error_mark_node;
/* Otherwise, force_store_init_value will have already stored a
zero-init initializer in DECL_INITIAL, that should be
retained. */
}
return init;
}
@ -7851,8 +7863,16 @@ check_initializer (decl, init)
if (init)
init = obscure_complex_init (decl, init);
}
else if (!DECL_EXTERNAL (decl) && !zero_init_p (type))
{
force_store_init_value (decl, build_forced_zero_init (type));
if (init)
goto process_init;
}
else if (init)
{
process_init:
if (TYPE_HAS_CONSTRUCTOR (type) || TYPE_NEEDS_CONSTRUCTING (type))
{
if (TREE_CODE (type) == ARRAY_TYPE)
@ -14222,7 +14242,7 @@ finish_function (flags)
if (DECL_MAIN_P (current_function_decl))
{
/* Make it so that `main' always returns 0 by default. */
#ifdef VMS_TARGET
#if VMS_TARGET
finish_return_stmt (integer_one_node);
#else
finish_return_stmt (integer_zero_node);

View File

@ -172,6 +172,11 @@ int flag_implicit_templates = 1;
int flag_implicit_inline_templates = 1;
/* Nonzero means warn about things that will change when compiling
with an ABI-compliant compiler. */
int warn_abi = 0;
/* Nonzero means warn about implicit declarations. */
int warn_implicit = 1;
@ -376,7 +381,7 @@ int flag_weak = 1;
/* Nonzero to use __cxa_atexit, rather than atexit, to register
destructors for local statics and global objects. */
int flag_use_cxa_atexit;
int flag_use_cxa_atexit = DEFAULT_USE_CXA_ATEXIT;
/* Maximum template instantiation depth. This limit is rather
arbitrary, but it exists to limit the time it takes to notice
@ -600,7 +605,9 @@ cxx_decode_option (argc, argv)
if (p[0] == 'n' && p[1] == 'o' && p[2] == '-')
setting = 0, p += 3;
if (!strcmp (p, "implicit"))
if (!strcmp (p, "abi"))
warn_abi = setting;
else if (!strcmp (p, "implicit"))
warn_implicit = setting;
else if (!strcmp (p, "long-long"))
warn_long_long = setting;
@ -2497,7 +2504,10 @@ import_export_decl (decl)
comdat_linkage (decl);
}
else
DECL_NOT_REALLY_EXTERN (decl) = 0;
{
DECL_EXTERNAL (decl) = 1;
DECL_NOT_REALLY_EXTERN (decl) = 0;
}
}
else if (DECL_FUNCTION_MEMBER_P (decl))
{
@ -2513,6 +2523,9 @@ import_export_decl (decl)
&& ! flag_implement_inlines
&& !DECL_VINDEX (decl)));
if (!DECL_NOT_REALLY_EXTERN (decl))
DECL_EXTERNAL (decl) = 1;
/* Always make artificials weak. */
if (DECL_ARTIFICIAL (decl) && flag_weak)
comdat_linkage (decl);
@ -2523,48 +2536,53 @@ import_export_decl (decl)
else
comdat_linkage (decl);
}
else if (tinfo_decl_p (decl, 0))
{
tree ctype = TREE_TYPE (DECL_NAME (decl));
if (IS_AGGR_TYPE (ctype))
import_export_class (ctype);
if (IS_AGGR_TYPE (ctype) && CLASSTYPE_INTERFACE_KNOWN (ctype)
&& TYPE_POLYMORPHIC_P (ctype)
/* If -fno-rtti, we're not necessarily emitting this stuff with
the class, so go ahead and emit it now. This can happen
when a class is used in exception handling. */
&& flag_rtti
/* If the type is a cv-qualified variant of a type, then we
must emit the tinfo function in this translation unit
since it will not be emitted when the vtable for the type
is output (which is when the unqualified version is
generated). */
&& same_type_p (ctype, TYPE_MAIN_VARIANT (ctype)))
{
DECL_NOT_REALLY_EXTERN (decl)
= ! (CLASSTYPE_INTERFACE_ONLY (ctype)
|| (DECL_DECLARED_INLINE_P (decl)
&& ! flag_implement_inlines
&& !DECL_VINDEX (decl)));
/* Always make artificials weak. */
if (flag_weak)
comdat_linkage (decl);
}
else if (TYPE_BUILT_IN (ctype)
&& same_type_p (ctype, TYPE_MAIN_VARIANT (ctype)))
DECL_NOT_REALLY_EXTERN (decl) = 0;
else
comdat_linkage (decl);
}
else
comdat_linkage (decl);
DECL_INTERFACE_KNOWN (decl) = 1;
}
/* Here, we only decide whether or not the tinfo node should be
emitted with the vtable. IS_IN_LIBRARY is non-zero iff the
typeinfo for TYPE should be in the runtime library. */
void
import_export_tinfo (decl, type, is_in_library)
tree decl;
tree type;
int is_in_library;
{
if (DECL_INTERFACE_KNOWN (decl))
return;
if (IS_AGGR_TYPE (type))
import_export_class (type);
if (IS_AGGR_TYPE (type) && CLASSTYPE_INTERFACE_KNOWN (type)
&& TYPE_POLYMORPHIC_P (type)
/* If -fno-rtti, we're not necessarily emitting this stuff with
the class, so go ahead and emit it now. This can happen when
a class is used in exception handling. */
&& flag_rtti)
{
DECL_NOT_REALLY_EXTERN (decl) = !CLASSTYPE_INTERFACE_ONLY (type);
DECL_COMDAT (decl) = 0;
}
else
{
DECL_NOT_REALLY_EXTERN (decl) = 1;
DECL_COMDAT (decl) = 1;
}
/* Now override some cases. */
if (flag_weak)
DECL_COMDAT (decl) = 1;
else if (is_in_library)
DECL_COMDAT (decl) = 0;
DECL_INTERFACE_KNOWN (decl) = 1;
}
tree
build_cleanup (decl)
tree decl;
@ -3358,7 +3376,7 @@ finish_file ()
/* Write out needed type info variables. Writing out one variable
might cause others to be needed. */
if (walk_globals (tinfo_decl_p, emit_tinfo_decl, /*data=*/0))
if (walk_globals (unemitted_tinfo_decl_p, emit_tinfo_decl, /*data=*/0))
reconsider = 1;
/* The list of objects with static storage duration is built up

View File

@ -474,7 +474,7 @@ dump_type (t, flags)
case TYPEOF_TYPE:
output_add_string (scratch_buffer, "__typeof (");
dump_expr (TYPE_FIELDS (t), flags & ~TFF_EXPR_IN_PARENS);
print_left_paren (scratch_buffer);
print_right_paren (scratch_buffer);
break;
default:

View File

@ -1,6 +1,6 @@
/* Handle initialization things in C++.
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001 Free Software Foundation, Inc.
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
@ -176,6 +176,44 @@ initialize_vtbl_ptrs (addr)
dfs_marked_real_bases_queue_p, type);
}
/* Types containing pointers to data members cannot be
zero-initialized with zeros, because the NULL value for such
pointers is -1.
TYPE is a type that requires such zero initialization. The
returned value is the initializer. */
tree
build_forced_zero_init (type)
tree type;
{
tree init = NULL;
if (AGGREGATE_TYPE_P (type) && !TYPE_PTRMEMFUNC_P (type))
{
/* This is a default initialization of an aggregate, but not one of
non-POD class type. We cleverly notice that the initialization
rules in such a case are the same as for initialization with an
empty brace-initialization list. */
init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, NULL_TREE);
}
else if (TREE_CODE (type) == REFERENCE_TYPE)
/* --if T is a reference type, no initialization is performed. */
return NULL_TREE;
else
{
init = integer_zero_node;
if (TREE_CODE (type) == ENUMERAL_TYPE)
/* We must make enumeral types the right type. */
init = fold (build1 (NOP_EXPR, type, init));
}
init = digest_init (type, init, 0);
return init;
}
/* [dcl.init]:
To default-initialize an object of type T means:
@ -202,28 +240,8 @@ build_default_init (type)
anything with a CONSTRUCTOR for arrays here, as that would imply
copy-initialization. */
return NULL_TREE;
else if (AGGREGATE_TYPE_P (type) && !TYPE_PTRMEMFUNC_P (type))
{
/* This is a default initialization of an aggregate, but not one of
non-POD class type. We cleverly notice that the initialization
rules in such a case are the same as for initialization with an
empty brace-initialization list. */
init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, NULL_TREE);
}
else if (TREE_CODE (type) == REFERENCE_TYPE)
/* --if T is a reference type, no initialization is performed. */
return NULL_TREE;
else
{
init = integer_zero_node;
if (TREE_CODE (type) == ENUMERAL_TYPE)
/* We must make enumeral types the right type. */
init = fold (build1 (NOP_EXPR, type, init));
}
init = digest_init (type, init, 0);
return init;
return build_forced_zero_init (type);
}
/* Subroutine of emit_base_init. */
@ -1165,11 +1183,9 @@ build_aggr_init (exp, init, flags)
return error_mark_node;
}
if (cp_type_quals (type) != TYPE_UNQUALIFIED)
{
TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
if (init)
TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype);
}
TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
if (itype && cp_type_quals (itype) != TYPE_UNQUALIFIED)
TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype);
stmt_expr = build_vec_init (exp, init,
init && same_type_p (TREE_TYPE (init),
TREE_TYPE (exp)));
@ -2575,6 +2591,10 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, use_global_delete)
This is also the containing expression returned by this function. */
tree controller = NULL_TREE;
/* We should only have 1-D arrays here. */
if (TREE_CODE (type) == ARRAY_TYPE)
abort ();
if (! IS_AGGR_TYPE (type) || TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
{
loop = integer_zero_node;
@ -2988,12 +3008,20 @@ build_vec_init (base, init, from_array)
&& from_array != 2)
{
tree e;
tree m = cp_build_binary_op (MINUS_EXPR, maxindex, iterator);
/* Flatten multi-dimensional array since build_vec_delete only
expects one-dimensional array. */
if (TREE_CODE (type) == ARRAY_TYPE)
{
m = cp_build_binary_op (MULT_EXPR, m,
array_type_nelts_total (type));
type = strip_array_types (type);
}
finish_compound_stmt (/*has_no_scope=*/1, try_body);
finish_cleanup_try_block (try_block);
e = build_vec_delete_1 (rval,
cp_build_binary_op (MINUS_EXPR, maxindex,
iterator),
e = build_vec_delete_1 (rval, m,
type,
sfk_base_destructor,
/*use_global_delete=*/0);

View File

@ -38,14 +38,12 @@ Boston, MA 02111-1307, USA. */
"%{E|M|MM:cpp0 -lang-c++ %{!no-gcc:-D__GNUG__=%v1}\
%{!Wno-deprecated:-D__DEPRECATED}\
%{!fno-exceptions:-D__EXCEPTIONS}\
-D__GXX_ABI_VERSION=100\
%{ansi:-D__STRICT_ANSI__ -trigraphs -$} %(cpp_options)}\
%{!E:%{!M:%{!MM:\
%{save-temps|no-integrated-cpp:cpp0 -lang-c++ \
%{!no-gcc:-D__GNUG__=%v1}\
%{!Wno-deprecated:-D__DEPRECATED}\
%{!fno-exceptions:-D__EXCEPTIONS}\
-D__GXX_ABI_VERSION=100\
%{ansi:-D__STRICT_ANSI__ -trigraphs -$}\
%(cpp_options) %{save-temps:%b.ii} %{!save-temps:%g.ii} \n}\
cc1plus %{save-temps|no-integrated-cpp:-fpreprocessed %{save-temps:%b.ii} %{!save-temps:%g.ii}}\
@ -53,7 +51,6 @@ Boston, MA 02111-1307, USA. */
%{!no-gcc:-D__GNUG__=%v1} \
%{!Wno-deprecated:-D__DEPRECATED}\
%{!fno-exceptions:-D__EXCEPTIONS}\
-D__GXX_ABI_VERSION=100\
%{ansi:-D__STRICT_ANSI__}}}\
%{ansi:-trigraphs -$}\
%(cc1_options) %2 %{+e1*}\

View File

@ -1,6 +1,6 @@
/* Separate lexical analyzer for GNU C++.
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001 Free Software Foundation, Inc.
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
@ -237,13 +237,6 @@ static const char *const cplus_tree_code_name[] = {
};
#undef DEFTREECODE
/* Post-switch processing. */
void
cxx_post_options ()
{
c_common_post_options ();
}
/* Initialization before switch parsing. */
void
cxx_init_options ()

View File

@ -982,8 +982,17 @@ write_unqualified_name (decl)
{
/* Conversion operator. Handle it right here.
<operator> ::= cv <type> */
tree type;
if (decl_is_template_id (decl, NULL))
{
tree fn_type = get_mostly_instantiated_function_type (decl, NULL,
NULL);
type = TREE_TYPE (fn_type);
}
else
type = TREE_TYPE (DECL_NAME (decl));
write_string ("cv");
write_type (TREE_TYPE (DECL_NAME (decl)));
write_type (type);
}
else if (DECL_OVERLOADED_OPERATOR_P (decl))
{
@ -1818,6 +1827,12 @@ write_expression (expr)
write_mangled_name (expr);
write_char ('E');
}
else if (TREE_CODE (expr) == SIZEOF_EXPR
&& TYPE_P (TREE_OPERAND (expr, 0)))
{
write_string ("st");
write_type (TREE_OPERAND (expr, 0));
}
else
{
int i;
@ -1856,6 +1871,7 @@ write_expression (expr)
write_expression (TREE_OPERAND (expr, 0));
break;
/* Handle pointers-to-members specially. */
case SCOPE_REF:
write_type (TREE_OPERAND (expr, 0));

View File

@ -5,7 +5,7 @@
non-overloadable operators (like the `?:' ternary operator).
Writtey by Mark Mitchell <mark@codesourcery.com>
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -46,10 +46,6 @@ Boston, MA 02111-1307, USA. */
mangled under the new ABI. For `operator +', for example, this
would be "pl".
OLD_MANGLING
Analogous, but for the old ABI.
ARITY
The arity of the operator, or -1 if any arity is allowed. (As

View File

@ -134,6 +134,7 @@ static tree build_template_decl PARAMS ((tree, tree));
static int mark_template_parm PARAMS ((tree, void *));
static tree tsubst_friend_function PARAMS ((tree, tree));
static tree tsubst_friend_class PARAMS ((tree, tree));
static int can_complete_type_without_circularity PARAMS ((tree));
static tree get_bindings_real PARAMS ((tree, tree, tree, int, int, int));
static int template_decl_level PARAMS ((tree));
static tree maybe_get_template_decl_from_type_decl PARAMS ((tree));
@ -3942,10 +3943,16 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
The template parameter level of T and U are one level larger than
of TT. To proper process the default argument of U, say when an
instantiation `TT<int>' is seen, we need to build the full
arguments containing {int} as the innermost level. Outer levels
can be obtained from `current_template_args ()'. */
arguments containing {int} as the innermost level. Outer levels,
available when not appearing as default template argument, can be
obtained from `current_template_args ()'.
if (processing_template_decl)
Suppose that TT is later substituted with std::vector. The above
instantiation is `TT<int, std::allocator<T> >' with TT at
level 1, and T at level 2, while the template arguments at level 1
becomes {std::vector} and the inner level 2 is {int}. */
if (current_template_parms)
arglist = add_to_template_args (current_template_args (), arglist);
arglist2 = coerce_template_parms (parmlist, arglist, template,
@ -4805,7 +4812,7 @@ tsubst_friend_class (friend_tmpl, args)
if (TREE_CODE (context) == NAMESPACE_DECL)
push_nested_namespace (context);
else
push_nested_class (context, 2);
push_nested_class (tsubst (context, args, tf_none, NULL_TREE), 2);
}
/* First, we look for a class template. */
@ -4877,6 +4884,25 @@ tsubst_friend_class (friend_tmpl, args)
return friend_type;
}
/* Returns zero if TYPE cannot be completed later due to circularity.
Otherwise returns one. */
static int
can_complete_type_without_circularity (type)
tree type;
{
if (type == NULL_TREE || type == error_mark_node)
return 0;
else if (COMPLETE_TYPE_P (type))
return 1;
else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
return can_complete_type_without_circularity (TREE_TYPE (type));
else if (CLASS_TYPE_P (type) && TYPE_BEING_DEFINED (TYPE_MAIN_VARIANT (type)))
return 0;
else
return 1;
}
tree
instantiate_class_template (type)
tree type;
@ -5197,7 +5223,20 @@ instantiate_class_template (type)
if (DECL_INITIALIZED_IN_CLASS_P (r))
check_static_variable_definition (r, TREE_TYPE (r));
}
else if (TREE_CODE (r) == FIELD_DECL)
{
/* Determine whether R has a valid type and can be
completed later. If R is invalid, then it is replaced
by error_mark_node so that it will not be added to
TYPE_FIELDS. */
tree rtype = TREE_TYPE (r);
if (!can_complete_type_without_circularity (rtype))
{
incomplete_type_error (r, rtype);
r = error_mark_node;
}
}
/* R will have a TREE_CHAIN if and only if it has already been
processed by finish_member_declaration. This can happen
if, for example, it is a TYPE_DECL for a class-scoped
@ -5278,6 +5317,8 @@ instantiate_class_template (type)
--processing_template_decl;
}
/* Now that TYPE_FIELDS and TYPE_METHODS are set up. We can
instantiate templates used by this class. */
for (t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t))
if (TREE_CODE (t) == FIELD_DECL)
{
@ -7487,6 +7528,11 @@ tsubst_expr (t, args, complain, in_decl)
finish_label_stmt (DECL_NAME (LABEL_STMT_LABEL (t)));
break;
case FILE_STMT:
input_filename = FILE_STMT_FILENAME (t);
add_stmt (build_nt (FILE_STMT, FILE_STMT_FILENAME_NODE (t)));
break;
case GOTO_STMT:
prep_stmt (t);
tmp = GOTO_DESTINATION (t);
@ -7502,12 +7548,13 @@ tsubst_expr (t, args, complain, in_decl)
case ASM_STMT:
prep_stmt (t);
finish_asm_stmt (ASM_CV_QUAL (t),
tsubst_expr (ASM_STRING (t), args, complain, in_decl),
tsubst_expr (ASM_OUTPUTS (t), args, complain, in_decl),
tsubst_expr (ASM_INPUTS (t), args, complain, in_decl),
tsubst_expr (ASM_CLOBBERS (t), args, complain,
in_decl));
tmp = finish_asm_stmt
(ASM_CV_QUAL (t),
tsubst_expr (ASM_STRING (t), args, complain, in_decl),
tsubst_expr (ASM_OUTPUTS (t), args, complain, in_decl),
tsubst_expr (ASM_INPUTS (t), args, complain, in_decl),
tsubst_expr (ASM_CLOBBERS (t), args, complain, in_decl));
ASM_INPUT_P (tmp) = ASM_INPUT_P (t);
break;
case TRY_BLOCK:
@ -9501,12 +9548,16 @@ do_decl_instantiation (declspecs, declarator, storage)
if (DECL_TEMPLATE_SPECIALIZATION (result))
{
/* [temp.spec]
/* DR 259 [temp.spec].
No program shall both explicitly instantiate and explicitly
specialize a template. */
pedwarn ("explicit instantiation of `%#D' after", result);
cp_pedwarn_at ("explicit specialization here", result);
Both an explicit instantiation and a declaration of an explicit
specialization shall not appear in a program unless the explicit
instantiation follows a declaration of the explicit specialization.
For a given set of template parameters, if an explicit
instantiation of a template appears after a declaration of an
explicit specialization for that template, the explicit
instantiation has no effect. */
return;
}
else if (DECL_EXPLICIT_INSTANTIATION (result))
@ -9636,15 +9687,16 @@ do_type_instantiation (t, storage, complain)
if (CLASSTYPE_TEMPLATE_SPECIALIZATION (t))
{
/* [temp.spec]
/* DR 259 [temp.spec].
No program shall both explicitly instantiate and explicitly
specialize a template. */
if (complain & tf_error)
{
error ("explicit instantiation of `%#T' after", t);
cp_error_at ("explicit specialization here", t);
}
Both an explicit instantiation and a declaration of an explicit
specialization shall not appear in a program unless the explicit
instantiation follows a declaration of the explicit specialization.
For a given set of template parameters, if an explicit
instantiation of a template appears after a declaration of an
explicit specialization for that template, the explicit
instantiation has no effect. */
return;
}
else if (CLASSTYPE_EXPLICIT_INSTANTIATION (t))

View File

@ -1,5 +1,5 @@
/* RunTime Type Identification
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
Mostly written by Jason Merrill (jason@cygnus.com).
@ -30,16 +30,46 @@ Boston, MA 02111-1307, USA. */
#include "assert.h"
#include "toplev.h"
/* C++ returns type information to the user in struct type_info
objects. We also use type information to implement dynamic_cast and
exception handlers. Type information for a particular type is
indicated with an ABI defined structure derived from type_info.
This would all be very straight forward, but for the fact that the
runtime library provides the definitions of the type_info structure
and the ABI defined derived classes. We cannot build declarations
of them directly in the compiler, but we need to layout objects of
their type. Somewhere we have to lie.
We define layout compatible POD-structs with compiler-defined names
and generate the appropriate initializations for them (complete
with explicit mention of their vtable). When we have to provide a
type_info to the user we reinterpret_cast the internal compiler
type to type_info. A well formed program can only explicitly refer
to the type_infos of complete types (& cv void). However, we chain
pointer type_infos to the pointed-to-type, and that can be
incomplete. We only need the addresses of such incomplete
type_info objects for static initialization.
The type information VAR_DECL of a type is held on the
IDENTIFIER_GLOBAL_VALUE of the type's mangled name. That VAR_DECL
will be the internal type. It will usually have the correct
internal type reflecting the kind of type it represents (pointer,
array, function, class, inherited class, etc). When the type it
represents is incomplete, it will have the internal type
corresponding to type_info. That will only happen at the end of
translation, when we are emitting the type info objects. */
/* Accessors for the type_info objects. We need to remember several things
about each of the type_info types. The global tree nodes such as
bltn_desc_type_node are TREE_LISTs, and these macros are used to access
the required information. */
/* The RECORD_TYPE of a type_info derived class. */
#define TINFO_PSEUDO_TYPE(NODE) TREE_TYPE (NODE)
/* The VAR_DECL of the vtable for the type_info derived class. */
/* The VAR_DECL of the vtable for the type_info derived class.
This is only filled in at the end of the translation. */
#define TINFO_VTABLE_DECL(NODE) TREE_VALUE (NODE)
extern struct obstack permanent_obstack;
/* The IDENTIFIER_NODE naming the real class. */
#define TINFO_REAL_NAME(NODE) TREE_PURPOSE (NODE)
static tree build_headof PARAMS((tree));
static tree ifnonnull PARAMS((tree, tree));
@ -48,7 +78,8 @@ static tree build_dynamic_cast_1 PARAMS((tree, tree));
static tree throw_bad_cast PARAMS((void));
static tree throw_bad_typeid PARAMS((void));
static tree get_tinfo_decl_dynamic PARAMS((tree));
static bool typeid_ok_p PARAMS ((void));
static tree get_tinfo_ptr PARAMS((tree));
static bool typeid_ok_p PARAMS((void));
static int qualifier_flags PARAMS((tree));
static int target_incomplete_p PARAMS((tree));
static tree tinfo_base_init PARAMS((tree, tree));
@ -59,15 +90,21 @@ static tree dfs_class_hint_mark PARAMS ((tree, void *));
static tree dfs_class_hint_unmark PARAMS ((tree, void *));
static int class_hint_flags PARAMS((tree));
static tree class_initializer PARAMS((tree, tree, tree));
static tree synthesize_tinfo_var PARAMS((tree, tree));
static tree create_real_tinfo_var PARAMS((tree, tree, tree, tree, int));
static tree create_pseudo_type_info PARAMS((const char *, int, ...));
static tree get_vmi_pseudo_type_info PARAMS((int));
static tree get_pseudo_ti_init PARAMS ((tree, tree, int *));
static tree get_pseudo_ti_desc PARAMS((tree));
static void create_tinfo_types PARAMS((void));
static int typeinfo_in_lib_p PARAMS((tree));
static int doing_runtime = 0;
/* Declare language defined type_info type and a pointer to const
type_info. This is incomplete here, and will be completed when
the user #includes <typeinfo>. There are language defined
restrictions on what can be done until that is included. Create
the internal versions of the ABI types. */
void
init_rtti_processing ()
{
@ -75,8 +112,11 @@ init_rtti_processing ()
type_info_type_node = xref_tag
(class_type_node, get_identifier ("type_info"), 1);
pop_namespace ();
tinfo_decl_type =
build_qualified_type (type_info_type_node, TYPE_QUAL_CONST);
type_info_ptr_type =
build_pointer_type
(build_qualified_type (type_info_type_node, TYPE_QUAL_CONST));
create_tinfo_types ();
}
/* Given the expression EXP of type `class *', return the head of the
@ -183,13 +223,12 @@ get_tinfo_decl_dynamic (exp)
/* The RTTI information is at index -1. */
index = integer_minus_one_node;
t = build_vtbl_ref (exp, index);
TREE_TYPE (t) = build_pointer_type (tinfo_decl_type);
TREE_TYPE (t) = type_info_ptr_type;
return t;
}
/* otherwise return the type_info for the static type of the expr. */
exp = get_tinfo_decl (TYPE_MAIN_VARIANT (type));
return build_unary_op (ADDR_EXPR, exp, 0);
/* Otherwise return the type_info for the static type of the expr. */
return get_tinfo_ptr (TYPE_MAIN_VARIANT (type));
}
static bool
@ -263,9 +302,9 @@ tinfo_name (type)
return name_string;
}
/* Returns a decl for the type_info variable for TYPE. You must
arrange that the decl is mark_used, if actually use it --- decls in
vtables are only used if the vtable is output. */
/* Return a VAR_DECL for the internal ABI defined type_info object for
TYPE. You must arrange that the decl is mark_used, if actually use
it --- decls in vtables are only used if the vtable is output. */
tree
get_tinfo_decl (type)
@ -278,7 +317,7 @@ get_tinfo_decl (type)
&& TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
{
error ("cannot create type information for type `%T' because its size is variable",
type);
type);
return error_mark_node;
}
@ -291,37 +330,45 @@ get_tinfo_decl (type)
name = mangle_typeinfo_for_type (type);
d = IDENTIFIER_GLOBAL_VALUE (name);
if (d)
/* OK */;
else
if (!d)
{
/* The tinfo decl is the type_info object itself. We make all
tinfo objects look as type_info, even though they will end up
being a subclass of that when emitted. This means that we'll
erroneously think we know the dynamic type -- be careful in the
runtime. */
d = build_lang_decl (VAR_DECL, name, tinfo_decl_type);
tree var_desc = get_pseudo_ti_desc (type);
d = build_lang_decl (VAR_DECL, name, TINFO_PSEUDO_TYPE (var_desc));
DECL_ARTIFICIAL (d) = 1;
DECL_ALIGN (d) = TYPE_ALIGN (ptr_type_node);
DECL_USER_ALIGN (d) = 0;
TREE_READONLY (d) = 1;
TREE_STATIC (d) = 1;
DECL_EXTERNAL (d) = 1;
TREE_PUBLIC (d) = 1;
if (flag_weak || !typeinfo_in_lib_p (type))
comdat_linkage (d);
SET_DECL_ASSEMBLER_NAME (d, name);
DECL_COMDAT (d) = 1;
cp_finish_decl (d, NULL_TREE, NULL_TREE, 0);
pushdecl_top_level (d);
/* Remember the type it is for. */
TREE_TYPE (name) = type;
TREE_USED (name) = 1;
}
return d;
}
/* Return a pointer to a type_info object describing TYPE, suitably
cast to the language defined type. */
static tree
get_tinfo_ptr (type)
tree type;
{
tree exp = get_tinfo_decl (type);
/* Convert to type_info type. */
exp = build_unary_op (ADDR_EXPR, exp, 0);
exp = ocp_convert (type_info_ptr_type, exp, CONV_REINTERPRET, 0);
return exp;
}
/* Return the type_info object for TYPE. */
tree
@ -350,7 +397,7 @@ get_typeid (type)
if (!type)
return error_mark_node;
return get_tinfo_decl (type);
return build_indirect_ref (get_tinfo_ptr (type), NULL);
}
/* Check whether TEST is null before returning RESULT. If TEST is used in
@ -683,6 +730,7 @@ tinfo_base_init (desc, target)
{
tree init = NULL_TREE;
tree name_decl;
tree vtable_ptr;
{
tree name_name;
@ -710,12 +758,40 @@ tinfo_base_init (desc, target)
cp_finish_decl (name_decl, name_string, NULL_TREE, 0);
pushdecl_top_level (name_decl);
}
if (TINFO_VTABLE_DECL (desc))
vtable_ptr = TINFO_VTABLE_DECL (desc);
if (!vtable_ptr)
{
tree vtbl_ptr = TINFO_VTABLE_DECL (desc);
init = tree_cons (NULL_TREE, vtbl_ptr, init);
tree real_type;
push_nested_namespace (abi_node);
real_type = xref_tag (class_type_node, TINFO_REAL_NAME (desc), 1);
pop_nested_namespace (abi_node);
if (!COMPLETE_TYPE_P (real_type))
{
/* We never saw a definition of this type, so we need to
tell the compiler that this is an exported class, as
indeed all of the __*_type_info classes are. */
SET_CLASSTYPE_INTERFACE_KNOWN (real_type);
CLASSTYPE_INTERFACE_ONLY (real_type) = 1;
}
vtable_ptr = get_vtable_decl (real_type, /*complete=*/1);
vtable_ptr = build_unary_op (ADDR_EXPR, vtable_ptr, 0);
/* We need to point into the middle of the vtable. */
vtable_ptr = build
(PLUS_EXPR, TREE_TYPE (vtable_ptr), vtable_ptr,
size_binop (MULT_EXPR,
size_int (2),
TYPE_SIZE_UNIT (vtable_entry_type)));
TREE_CONSTANT (vtable_ptr) = 1;
TINFO_VTABLE_DECL (desc) = vtable_ptr;
}
init = tree_cons (NULL_TREE, vtable_ptr, init);
init = tree_cons (NULL_TREE, decay_conversion (name_decl), init);
@ -764,8 +840,7 @@ ptr_initializer (desc, target, non_public_ptr)
}
init = tree_cons (NULL_TREE, build_int_2 (flags, 0), init);
init = tree_cons (NULL_TREE,
build_unary_op (ADDR_EXPR,
get_tinfo_decl (TYPE_MAIN_VARIANT (to)), 0),
get_tinfo_ptr (TYPE_MAIN_VARIANT (to)),
init);
init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init));
@ -802,12 +877,11 @@ ptm_initializer (desc, target, non_public_ptr)
}
init = tree_cons (NULL_TREE, build_int_2 (flags, 0), init);
init = tree_cons (NULL_TREE,
build_unary_op (ADDR_EXPR,
get_tinfo_decl (TYPE_MAIN_VARIANT (to)), 0),
get_tinfo_ptr (TYPE_MAIN_VARIANT (to)),
init);
init = tree_cons (NULL_TREE,
build_unary_op (ADDR_EXPR, get_tinfo_decl (klass), 0),
init);
get_tinfo_ptr (klass),
init);
init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init));
TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
@ -928,77 +1002,63 @@ typeinfo_in_lib_p (type)
}
}
/* Generate a pseudo_type_info VAR_DECL suitable for the supplied
TARGET_TYPE and given the REAL_NAME. This is the structure expected by
the runtime, and therefore has additional fields. If we need not emit a
definition (because the runtime must contain it), return NULL_TREE,
otherwise return the VAR_DECL. */
/* Generate the initializer for the type info describing
TYPE. VAR_DESC is a . NON_PUBLIC_P is set non-zero, if the VAR_DECL
should not be exported from this object file. This should only be
called at the end of translation, when we know that no further
types will be completed. */
static tree
synthesize_tinfo_var (target_type, real_name)
tree target_type;
tree real_name;
get_pseudo_ti_init (type, var_desc, non_public_p)
tree type;
tree var_desc;
int *non_public_p;
{
tree var_init = NULL_TREE;
tree var_type = NULL_TREE;
int non_public = 0;
switch (TREE_CODE (target_type))
my_friendly_assert (at_eof, 20021120);
switch (TREE_CODE (type))
{
case POINTER_TYPE:
if (TYPE_PTRMEM_P (target_type))
{
var_type = ptm_desc_type_node;
var_init = ptm_initializer (var_type, target_type, &non_public);
}
if (TYPE_PTRMEM_P (type))
return ptm_initializer (var_desc, type, non_public_p);
else
{
if (typeinfo_in_lib_p (target_type) && !doing_runtime)
/* These are in the runtime. */
return NULL_TREE;
var_type = ptr_desc_type_node;
var_init = ptr_initializer (var_type, target_type, &non_public);
}
return ptr_initializer (var_desc, type, non_public_p);
break;
case ENUMERAL_TYPE:
var_type = enum_desc_type_node;
var_init = generic_initializer (var_type, target_type);
return generic_initializer (var_desc, type);
break;
case FUNCTION_TYPE:
var_type = func_desc_type_node;
var_init = generic_initializer (var_type, target_type);
return generic_initializer (var_desc, type);
break;
case ARRAY_TYPE:
var_type = ary_desc_type_node;
var_init = generic_initializer (var_type, target_type);
return generic_initializer (var_desc, type);
break;
case UNION_TYPE:
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (target_type))
if (TYPE_PTRMEMFUNC_P (type))
return ptm_initializer (var_desc, type, non_public_p);
else if (var_desc == class_desc_type_node)
{
var_type = ptm_desc_type_node;
var_init = ptm_initializer (var_type, target_type, &non_public);
}
else if (!COMPLETE_TYPE_P (target_type))
{
/* Emit a non-public class_type_info. */
non_public = 1;
var_type = class_desc_type_node;
var_init = class_initializer (var_type, target_type, NULL_TREE);
}
else if (!CLASSTYPE_N_BASECLASSES (target_type))
{
var_type = class_desc_type_node;
var_init = class_initializer (var_type, target_type, NULL_TREE);
if (!COMPLETE_TYPE_P (type))
/* Emit a non-public class_type_info. */
*non_public_p = 1;
return class_initializer (var_desc, type, NULL_TREE);
}
else if (var_desc == si_class_desc_type_node)
{
tree base_binfos = BINFO_BASETYPES (TYPE_BINFO (type));
tree base_binfo = TREE_VEC_ELT (base_binfos, 0);
tree tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo));
tree base_inits = tree_cons (NULL_TREE, tinfo, NULL_TREE);
return class_initializer (var_desc, type, base_inits);
}
else
{
/* if this has a single public non-virtual base, it's easier */
tree binfo = TYPE_BINFO (target_type);
int hint = class_hint_flags (type);
tree binfo = TYPE_BINFO (type);
int nbases = BINFO_N_BASETYPES (binfo);
tree base_binfos = BINFO_BASETYPES (binfo);
tree base_inits = NULL_TREE;
int is_simple = nbases == 1;
int ix;
/* Generate the base information initializer. */
@ -1012,28 +1072,19 @@ synthesize_tinfo_var (target_type, real_name)
if (TREE_PUBLIC (base_binfo))
flags |= 2;
tinfo = get_tinfo_decl (BINFO_TYPE (base_binfo));
tinfo = build_unary_op (ADDR_EXPR, tinfo, 0);
tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo));
if (TREE_VIA_VIRTUAL (base_binfo))
{
/* We store the vtable offset at which the virtual
base offset can be found. */
offset = BINFO_VPTR_FIELD (binfo_for_vbase (BINFO_TYPE (base_binfo),
target_type));
offset = BINFO_VPTR_FIELD
(binfo_for_vbase (BINFO_TYPE (base_binfo), type));
offset = convert (sizetype, offset);
flags |= 1;
}
else
offset = BINFO_OFFSET (base_binfo);
/* is it a single public inheritance? */
if (is_simple && flags == 2 && integer_zerop (offset))
{
base_inits = tree_cons (NULL_TREE, tinfo, NULL_TREE);
break;
}
is_simple = 0;
/* combine offset and flags into one field */
offset = cp_build_binary_op (LSHIFT_EXPR, offset,
build_int_2 (8, 0));
@ -1044,86 +1095,23 @@ synthesize_tinfo_var (target_type, real_name)
base_init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_init);
base_inits = tree_cons (NULL_TREE, base_init, base_inits);
}
if (is_simple)
var_type = si_class_desc_type_node;
else
{
int hint = class_hint_flags (target_type);
base_inits = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_inits);
base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
/* Prepend the number of bases. */
base_inits = tree_cons (NULL_TREE,
build_int_2 (nbases, 0), base_inits);
/* Prepend the hint flags. */
base_inits = tree_cons (NULL_TREE,
build_int_2 (hint, 0), base_inits);
var_type = get_vmi_pseudo_type_info (nbases);
}
var_init = class_initializer (var_type, target_type, base_inits);
base_inits = build (CONSTRUCTOR,
NULL_TREE, NULL_TREE, base_inits);
base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
/* Prepend the number of bases. */
base_inits = tree_cons (NULL_TREE,
build_int_2 (nbases, 0), base_inits);
/* Prepend the hint flags. */
base_inits = tree_cons (NULL_TREE,
build_int_2 (hint, 0), base_inits);
return class_initializer (var_desc, type, base_inits);
}
break;
default:
if (typeinfo_in_lib_p (target_type))
{
if (!doing_runtime)
/* These are guaranteed to be in the runtime. */
return NULL_TREE;
var_type = bltn_desc_type_node;
var_init = generic_initializer (var_type, target_type);
break;
}
abort ();
return generic_initializer (var_desc, type);
}
return create_real_tinfo_var (target_type,
real_name, TINFO_PSEUDO_TYPE (var_type),
var_init, non_public);
}
/* Create the real typeinfo variable. NON_PUBLIC indicates that we cannot
make this variable public (comdat). */
static tree
create_real_tinfo_var (target_type, name, type, init, non_public)
tree target_type;
tree name;
tree type;
tree init;
int non_public;
{
static int count = 0;
tree decl;
tree hidden_name;
char hidden[30];
/* We cannot give this the name NAME, as that already is globally
bound to the tinfo_decl we originally created for this type in
get_tinfo_decl. */
sprintf (hidden, "__ti_%d", count++);
hidden_name = get_identifier (hidden);
decl = build_lang_decl (VAR_DECL, hidden_name,
build_qualified_type (type, TYPE_QUAL_CONST));
DECL_ARTIFICIAL (decl) = 1;
TREE_READONLY (decl) = 1;
TREE_STATIC (decl) = 1;
DECL_EXTERNAL (decl) = 0;
if (!non_public)
{
TREE_PUBLIC (decl) = 1;
if (flag_weak || !typeinfo_in_lib_p (target_type))
comdat_linkage (decl);
}
SET_DECL_ASSEMBLER_NAME (decl, name);
DECL_INITIAL (decl) = init;
cp_finish_decl (decl, init, NULL_TREE, 0);
pushdecl_top_level (decl);
TREE_USED (decl) = 1;
return decl;
}
/* Generate the RECORD_TYPE containing the data layout of a type_info
@ -1132,7 +1120,10 @@ create_real_tinfo_var (target_type, name, type, init, non_public)
type's vtable. We explicitly manage the vtable member, and name it for
real type as used in the runtime. The RECORD type has a different name,
to avoid collisions. Return a TREE_LIST who's TINFO_PSEUDO_TYPE
is the generated type and TINFO_VTABLE_DECL is the vtable decl.
is the generated type and TINFO_VTABLE_NAME is the name of the
vtable. We have to delay generating the VAR_DECL of the vtable
until the end of the translation, when we'll have seen the library
definition, if there was one.
REAL_NAME is the runtime's name of the type. Trailing arguments are
additional FIELD_DECL's for the structure. The final argument must be
@ -1141,9 +1132,8 @@ create_real_tinfo_var (target_type, name, type, init, non_public)
static tree
create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
{
tree real_type, pseudo_type;
tree pseudo_type;
char *pseudo_name;
tree vtable_decl;
int ix;
tree fields[10];
tree field_decl;
@ -1160,29 +1150,6 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
if (ident)
sprintf (pseudo_name + strlen (pseudo_name), "%d", ident);
/* Get the vtable decl. */
real_type = xref_tag (class_type_node, get_identifier (real_name), 1);
if (! TYPE_SIZE (real_type))
{
/* We never saw a definition of this type, so we need to tell the
compiler that this is an exported class, as indeed all of the
__*_type_info classes are. */
SET_CLASSTYPE_INTERFACE_KNOWN (real_type);
CLASSTYPE_INTERFACE_ONLY (real_type) = 1;
}
vtable_decl = get_vtable_decl (real_type, /*complete=*/1);
vtable_decl = build_unary_op (ADDR_EXPR, vtable_decl, 0);
/* We need to point into the middle of the vtable. */
vtable_decl = build (PLUS_EXPR,
TREE_TYPE (vtable_decl),
vtable_decl,
size_binop (MULT_EXPR,
size_int (2),
TYPE_SIZE_UNIT (vtable_entry_type)));
TREE_CONSTANT (vtable_decl) = 1;
/* First field is the pseudo type_info base class. */
fields[0] = build_decl (FIELD_DECL, NULL_TREE, ti_desc_type_node);
@ -1196,53 +1163,96 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
TYPE_HAS_CONSTRUCTOR (pseudo_type) = 1;
result = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE);
TINFO_VTABLE_DECL (result) = vtable_decl;
TINFO_PSEUDO_TYPE (result) = pseudo_type;
TINFO_REAL_NAME (result) = get_identifier (real_name);
TINFO_PSEUDO_TYPE (result) =
cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST);
VA_CLOSE (ap);
return result;
}
/* Return a descriptor for a vmi type with NUM_BASES bases. */
/* Return a pseudo type info type node used to describe TYPE. TYPE
must be a complete type (or cv void), except at the end of the
translation unit. */
static tree
get_vmi_pseudo_type_info (num_bases)
int num_bases;
get_pseudo_ti_desc (type)
tree type;
{
tree desc;
tree array_domain, base_array;
if (TREE_VEC_LENGTH (vmi_class_desc_type_node) <= num_bases)
switch (TREE_CODE (type))
{
int ix;
tree extend = make_tree_vec (num_bases + 5);
for (ix = TREE_VEC_LENGTH (vmi_class_desc_type_node); ix--;)
TREE_VEC_ELT (extend, ix) = TREE_VEC_ELT (vmi_class_desc_type_node, ix);
vmi_class_desc_type_node = extend;
case POINTER_TYPE:
return TYPE_PTRMEM_P (type) ? ptm_desc_type_node : ptr_desc_type_node;
case ENUMERAL_TYPE:
return enum_desc_type_node;
case FUNCTION_TYPE:
return func_desc_type_node;
case ARRAY_TYPE:
return ary_desc_type_node;
case UNION_TYPE:
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (type))
return ptm_desc_type_node;
else if (!COMPLETE_TYPE_P (type))
{
my_friendly_assert (at_eof, 20020609);
return class_desc_type_node;
}
else if (!CLASSTYPE_N_BASECLASSES (type))
return class_desc_type_node;
else
{
tree base_binfo =
TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)), 0);
int num_bases = BINFO_N_BASETYPES (TYPE_BINFO (type));
if (num_bases == 1
&& TREE_PUBLIC (base_binfo)
&& !TREE_VIA_VIRTUAL (base_binfo)
&& integer_zerop (BINFO_OFFSET (base_binfo)))
/* single non-virtual public. */
return si_class_desc_type_node;
else
{
tree var_desc;
tree array_domain, base_array;
if (TREE_VEC_LENGTH (vmi_class_desc_type_node) <= num_bases)
{
int ix;
tree extend = make_tree_vec (num_bases + 5);
for (ix = TREE_VEC_LENGTH (vmi_class_desc_type_node); ix--;)
TREE_VEC_ELT (extend, ix)
= TREE_VEC_ELT (vmi_class_desc_type_node, ix);
vmi_class_desc_type_node = extend;
}
var_desc = TREE_VEC_ELT (vmi_class_desc_type_node, num_bases);
if (var_desc)
return var_desc;
/* Add number of bases and trailing array of
base_class_type_info. */
array_domain = build_index_type (size_int (num_bases));
base_array =
build_array_type (base_desc_type_node, array_domain);
push_nested_namespace (abi_node);
var_desc = create_pseudo_type_info
("__vmi_class_type_info", num_bases,
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
build_decl (FIELD_DECL, NULL_TREE, base_array),
NULL);
pop_nested_namespace (abi_node);
TREE_VEC_ELT (vmi_class_desc_type_node, num_bases) = var_desc;
return var_desc;
}
}
default:
return bltn_desc_type_node;
}
desc = TREE_VEC_ELT (vmi_class_desc_type_node, num_bases);
if (desc)
return desc;
/* Add number of bases and trailing array of base_class_type_info. */
array_domain = build_index_type (size_int (num_bases));
base_array = build_array_type (base_desc_type_node, array_domain);
push_nested_namespace (abi_node);
desc = create_pseudo_type_info
("__vmi_class_type_info", num_bases,
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
build_decl (FIELD_DECL, NULL_TREE, base_array),
NULL);
pop_nested_namespace (abi_node);
TREE_VEC_ELT (vmi_class_desc_type_node, num_bases) = desc;
return desc;
}
/* Make sure the required builtin types exist for generating the type_info
@ -1251,15 +1261,9 @@ get_vmi_pseudo_type_info (num_bases)
static void
create_tinfo_types ()
{
tree ptr_type_info;
if (bltn_desc_type_node)
return;
push_nested_namespace (abi_node);
my_friendly_assert (!ti_desc_type_node, 20020609);
ptr_type_info = build_pointer_type
(build_qualified_type
(type_info_type_node, TYPE_QUAL_CONST));
push_nested_namespace (abi_node);
/* Create the internal type_info structure. This is used as a base for
the other structures. */
@ -1299,7 +1303,7 @@ create_tinfo_types ()
This is really a descendant of __class_type_info. */
si_class_desc_type_node = create_pseudo_type_info
("__si_class_type_info", 0,
build_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
NULL);
/* Base class internal helper. Pointer to base type, offset to base,
@ -1307,7 +1311,7 @@ create_tinfo_types ()
{
tree fields[2];
fields[0] = build_decl (FIELD_DECL, NULL_TREE, ptr_type_info);
fields[0] = build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type);
fields[1] = build_decl (FIELD_DECL, NULL_TREE, integer_types[itk_long]);
base_desc_type_node = make_aggr_type (RECORD_TYPE);
finish_builtin_type (base_desc_type_node, "__base_class_type_info_pseudo",
@ -1324,7 +1328,7 @@ create_tinfo_types ()
ptr_desc_type_node = create_pseudo_type_info
("__pointer_type_info", 0,
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
build_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
NULL);
/* Pointer to member data type_info. Add qualifications flags,
@ -1333,8 +1337,8 @@ create_tinfo_types ()
ptm_desc_type_node = create_pseudo_type_info
("__pointer_to_member_type_info", 0,
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
build_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
build_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
NULL);
pop_nested_namespace (abi_node);
@ -1401,75 +1405,61 @@ emit_support_tinfos ()
definition emitted for it. */
int
tinfo_decl_p (t, data)
unemitted_tinfo_decl_p (t, data)
tree t;
void *data ATTRIBUTE_UNUSED;
{
return TREE_CODE (t) == VAR_DECL
&& IDENTIFIER_GLOBAL_VALUE (DECL_NAME (t)) == (t)
&& TREE_TYPE (t) == tinfo_decl_type
&& TREE_TYPE (DECL_NAME (t));
if (/* It's a var decl */
TREE_CODE (t) == VAR_DECL
/* whos name points back to itself */
&& IDENTIFIER_GLOBAL_VALUE (DECL_NAME (t)) == t
/* whos name's type is non-null */
&& TREE_TYPE (DECL_NAME (t))
/* and whos type is a struct */
&& TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE
/* with a first field of our pseudo type info */
&& TREE_TYPE (TYPE_FIELDS (TREE_TYPE (t))) == ti_desc_type_node)
return 1;
return 0;
}
/* Emit a suitable type_info definition for the type_info decl pointed to by
DECL_PTR. We emit a completely new variable, of the correct type for the
actual type this is describing. The DECL_ASSEMBLER_NAME of the generated
definition is set to that of the supplied decl, so that they can be tied
up. Mark the supplied decl as having been dealt with. Emitting one
definition might cause other definitions to be required.
We need to do things this way, because we're trying to do something like
struct B : A {
...
};
extern const A tinfo_var;
const B tinfo_var = {...};
which is not permitted. Also, we've not necessarily seen the definition of B.
So we do something like the following,
extern const A tinfo_var;
struct pseudo_A {
const void *vtable_ptr;
const char *name;
};
struct pseudo_B {
pseudo_A base;
...
};
const pseudo_B proxy_tinfo_var attribute((assembler_name="tinfo_var")) =
{
{&B::vtable, "..."},
...
};
pseudo_A and pseudo_B must be layout equivalent to the real definitions in
the runtime. */
/* Finish a type info decl. DECL_PTR is a pointer to an unemitted
tinfo decl. Determine whether it needs emitting, and if so
generate the initializer. */
int
emit_tinfo_decl (decl_ptr, data)
tree *decl_ptr;
void *data ATTRIBUTE_UNUSED;
{
tree tinfo_decl = *decl_ptr;
tree tinfo_type, decl;
tree decl = *decl_ptr;
tree type = TREE_TYPE (DECL_NAME (decl));
int non_public;
int in_library = typeinfo_in_lib_p (type);
tree var_desc, var_init;
my_friendly_assert (TREE_TYPE (tinfo_decl) == tinfo_decl_type, 20000121);
tinfo_type = TREE_TYPE (DECL_NAME (tinfo_decl));
my_friendly_assert (tinfo_type != NULL_TREE, 20000120);
if (!DECL_NEEDED_P (tinfo_decl))
import_export_tinfo (decl, type, in_library);
if (DECL_REALLY_EXTERN (decl) || !DECL_NEEDED_P (decl))
return 0;
if (!doing_runtime && in_library)
return 0;
non_public = 0;
var_desc = get_pseudo_ti_desc (type);
var_init = get_pseudo_ti_init (type, var_desc, &non_public);
DECL_EXTERNAL (decl) = 0;
TREE_PUBLIC (decl) = !non_public;
if (non_public)
DECL_COMDAT (decl) = 0;
DECL_INITIAL (decl) = var_init;
cp_finish_decl (decl, var_init, NULL_TREE, 0);
/* cp_finish_decl will have dealt with linkage. */
/* Say we've dealt with it. */
TREE_TYPE (DECL_NAME (tinfo_decl)) = NULL_TREE;
create_tinfo_types ();
decl = synthesize_tinfo_var (tinfo_type, DECL_ASSEMBLER_NAME (tinfo_decl));
return decl != 0;
TREE_TYPE (DECL_NAME (decl)) = NULL_TREE;
return 1;
}

View File

@ -100,7 +100,6 @@ static tree dfs_push_decls PARAMS ((tree, void *));
static tree dfs_unuse_fields PARAMS ((tree, void *));
static tree add_conversions PARAMS ((tree, void *));
static int covariant_return_p PARAMS ((tree, tree));
static int check_final_overrider PARAMS ((tree, tree));
static int look_for_overrides_r PARAMS ((tree, tree));
static struct search_level *push_search_level
PARAMS ((struct stack_level *, struct obstack *));
@ -1800,7 +1799,7 @@ covariant_return_p (brettype, drettype)
/* Check that virtual overrider OVERRIDER is acceptable for base function
BASEFN. Issue diagnostic, and return zero, if unacceptable. */
static int
int
check_final_overrider (overrider, basefn)
tree overrider, basefn;
{

View File

@ -1,6 +1,6 @@
/* Language-dependent node constructors for parse phase of GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001 Free Software Foundation, Inc.
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
@ -1898,6 +1898,27 @@ pod_type_p (t)
return 1;
}
/* Returns 1 iff zero initialization of type T means actually storing
zeros in it. */
int
zero_init_p (t)
tree t;
{
t = strip_array_types (t);
/* NULL pointers to data members are initialized with -1. */
if (TYPE_PTRMEM_P (t))
return 0;
/* Classes that contain types that can't be zero-initialized, cannot
be zero-initialized themselves. */
if (CLASS_TYPE_P (t) && CLASSTYPE_NON_ZERO_INIT_P (t))
return 0;
return 1;
}
/* Table of valid C++ attributes. */
const struct attribute_spec cp_attribute_table[] =
{
@ -2147,7 +2168,8 @@ cp_cannot_inline_tree_fn (fnp)
&& TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn)))
{
fn = *fnp = instantiate_decl (fn, /*defer_ok=*/0);
return TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn));
if (TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn)))
return 1;
}
if (varargs_function_p (fn))
@ -2262,6 +2284,11 @@ cp_copy_res_decl_for_inlining (result, fn, caller, decl_map_,
DECL_SOURCE_FILE (var) = DECL_SOURCE_FILE (nrv);
DECL_SOURCE_LINE (var) = DECL_SOURCE_LINE (nrv);
DECL_ABSTRACT_ORIGIN (var) = DECL_ORIGIN (nrv);
/* Don't lose initialization info. */
DECL_INITIAL (var) = DECL_INITIAL (nrv);
/* Don't forget that it needs to go in the stack. */
TREE_ADDRESSABLE (var) = TREE_ADDRESSABLE (nrv);
splay_tree_insert (decl_map,
(splay_tree_key) nrv,
(splay_tree_value) var);

View File

@ -4806,9 +4806,6 @@ mark_addressable (exp)
{
register tree x = exp;
if (TREE_ADDRESSABLE (x) == 1)
return 1;
while (1)
switch (TREE_CODE (x))
{
@ -4827,6 +4824,8 @@ mark_addressable (exp)
TREE_ADDRESSABLE (x) = 1; /* so compiler doesn't die later */
return 1;
}
/* FALLTHRU */
case VAR_DECL:
/* Caller should not be trying to mark initialized
constant fields addressable. */
@ -4834,6 +4833,7 @@ mark_addressable (exp)
|| DECL_IN_AGGR_P (x) == 0
|| TREE_STATIC (x)
|| DECL_EXTERNAL (x), 314);
/* FALLTHRU */
case CONST_DECL:
case RESULT_DECL:
@ -4842,6 +4842,7 @@ mark_addressable (exp)
warning ("address requested for `%D', which is declared `register'",
x);
TREE_ADDRESSABLE (x) = 1;
put_var_into_stack (x);
return 1;
case FUNCTION_DECL:
@ -5449,7 +5450,10 @@ build_modify_expr (lhs, modifycode, rhs)
so the code to compute it is only emitted once. */
tree cond;
rhs = save_expr (rhs);
if (lvalue_p (rhs))
rhs = stabilize_reference (rhs);
else
rhs = save_expr (rhs);
/* Check this here to avoid odd errors when trying to convert
a throw to the type of the COND_EXPR. */

View File

@ -1,7 +1,7 @@
/* Report error messages, build initializers, and perform
some front-end optimizations for C++ compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000 Free Software Foundation, Inc.
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
@ -196,7 +196,8 @@ incomplete_type_error (value, type)
return;
if (value != 0 && (TREE_CODE (value) == VAR_DECL
|| TREE_CODE (value) == PARM_DECL))
|| TREE_CODE (value) == PARM_DECL
|| TREE_CODE (value) == FIELD_DECL))
{
cp_error_at ("`%D' has incomplete type", value);
decl = 1;
@ -211,7 +212,10 @@ incomplete_type_error (value, type)
case ENUMERAL_TYPE:
if (!decl)
error ("invalid use of undefined type `%#T'", type);
cp_error_at ("forward declaration of `%#T'", type);
if (!TYPE_TEMPLATE_INFO (type))
cp_error_at ("forward declaration of `%#T'", type);
else
cp_error_at ("declaration of `%#T'", type);
break;
case VOID_TYPE:
@ -420,6 +424,28 @@ store_init_value (decl, init)
DECL_INITIAL (decl) = value;
return NULL_TREE;
}
/* Same as store_init_value, but used for known-to-be-valid static
initializers. Used to introduce a static initializer even in data
structures that may require dynamic initialization. */
tree
force_store_init_value (decl, init)
tree decl, init;
{
tree type = TREE_TYPE (decl);
int needs_constructing = TYPE_NEEDS_CONSTRUCTING (type);
TYPE_NEEDS_CONSTRUCTING (type) = 0;
init = store_init_value (decl, init);
if (init)
abort ();
TYPE_NEEDS_CONSTRUCTING (type) = needs_constructing;
return init;
}
/* Digest the parser output INIT as an initializer for type TYPE.
Return a C expression of type TYPE to represent the initial value.
@ -732,6 +758,8 @@ process_init_constructor (type, init, elts)
next1 = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, NULL_TREE);
next1 = digest_init (TREE_TYPE (type), next1, 0);
}
else if (! zero_init_p (TREE_TYPE (type)))
next1 = build_forced_zero_init (TREE_TYPE (type));
else
/* The default zero-initialization is fine for us; don't
add anything to the CONSTRUCTOR. */
@ -848,9 +876,12 @@ process_init_constructor (type, init, elts)
&& (!init || TREE_HAS_CONSTRUCTOR (init)))
warning ("missing initializer for member `%D'", field);
/* The default zero-initialization is fine for us; don't
add anything to the CONSTRUCTOR. */
continue;
if (! zero_init_p (TREE_TYPE (field)))
next1 = build_forced_zero_init (TREE_TYPE (field));
else
/* The default zero-initialization is fine for us; don't
add anything to the CONSTRUCTOR. */
continue;
}
if (next1 == error_mark_node)

View File

@ -310,9 +310,12 @@ stack_include_file (pfile, inc)
sysp = MAX ((pfile->map ? pfile->map->sysp : 0),
(inc->foundhere ? inc->foundhere->sysp : 0));
/* For -M, add the file to the dependencies on its first inclusion. */
if (CPP_OPTION (pfile, print_deps) > sysp && !inc->include_count)
deps_add_dep (pfile->deps, inc->name);
/* Add the file to the dependencies on its first inclusion. */
if (CPP_OPTION (pfile, print_deps) > !!sysp && !inc->include_count)
{
if (pfile->buffer || CPP_OPTION (pfile, deps_ignore_main_file) == 0)
deps_add_dep (pfile->deps, inc->name);
}
/* Not in cache? */
if (! inc->buffer)

View File

@ -99,6 +99,7 @@ static void path_include PARAMS ((cpp_reader *,
char *, int));
static void init_library PARAMS ((void));
static void init_builtins PARAMS ((cpp_reader *));
static void mark_named_operators PARAMS ((cpp_reader *));
static void append_include_chain PARAMS ((cpp_reader *,
char *, int, int));
static struct search_path * remove_dup_dir PARAMS ((cpp_reader *,
@ -188,7 +189,7 @@ path_include (pfile, list, path)
name[q - p] = 0;
}
append_include_chain (pfile, name, path, 0);
append_include_chain (pfile, name, path, path == SYSTEM);
/* Advance past this name. */
if (*q == 0)
@ -395,7 +396,7 @@ struct lang_flags
char objc;
char cplusplus;
char extended_numbers;
char trigraphs;
char std;
char dollars_in_ident;
char cplusplus_comments;
char digraphs;
@ -403,7 +404,7 @@ struct lang_flags
/* ??? Enable $ in identifiers in assembly? */
static const struct lang_flags lang_defaults[] =
{ /* c99 objc c++ xnum trig dollar c++comm digr */
{ /* c99 objc c++ xnum std dollar c++comm digr */
/* GNUC89 */ { 0, 0, 0, 1, 0, 1, 1, 1 },
/* GNUC99 */ { 1, 0, 0, 1, 0, 1, 1, 1 },
/* STDC89 */ { 0, 0, 0, 0, 1, 0, 0, 0 },
@ -430,7 +431,8 @@ set_lang (pfile, lang)
CPP_OPTION (pfile, objc) = l->objc;
CPP_OPTION (pfile, cplusplus) = l->cplusplus;
CPP_OPTION (pfile, extended_numbers) = l->extended_numbers;
CPP_OPTION (pfile, trigraphs) = l->trigraphs;
CPP_OPTION (pfile, std) = l->std;
CPP_OPTION (pfile, trigraphs) = l->std;
CPP_OPTION (pfile, dollars_in_ident) = l->dollars_in_ident;
CPP_OPTION (pfile, cplusplus_comments) = l->cplusplus_comments;
CPP_OPTION (pfile, digraphs) = l->digraphs;
@ -612,28 +614,22 @@ cpp_destroy (pfile)
Two values are not compile time constants, so we tag
them in the FLAGS field instead:
VERS value is the global version_string, quoted
ULP value is the global user_label_prefix
Also, macros with CPLUS set in the flags field are entered only for C++. */
ULP value is the global user_label_prefix */
struct builtin
{
const U_CHAR *name;
const char *value;
unsigned char builtin;
unsigned char operator;
unsigned short flags;
unsigned short len;
};
#define VERS 0x01
#define ULP 0x02
#define CPLUS 0x04
#define BUILTIN 0x08
#define OPERATOR 0x10
#define B(n, t) { U n, 0, t, 0, BUILTIN, sizeof n - 1 }
#define C(n, v) { U n, v, 0, 0, 0, sizeof n - 1 }
#define X(n, f) { U n, 0, 0, 0, f, sizeof n - 1 }
#define O(n, c, f) { U n, 0, 0, c, OPERATOR | f, sizeof n - 1 }
#define B(n, t) { U n, 0, t, BUILTIN, sizeof n - 1 }
#define C(n, v) { U n, v, 0, 0, sizeof n - 1 }
#define X(n, f) { U n, 0, 0, f, sizeof n - 1 }
static const struct builtin builtin_array[] =
{
B("__TIME__", BT_TIME),
@ -669,30 +665,55 @@ static const struct builtin builtin_array[] =
#else
C("__STDC__", "1"),
#endif
/* Named operators known to the preprocessor. These cannot be #defined
and always have their stated meaning. They are treated like normal
identifiers except for the type code and the meaning. Most of them
are only for C++ (but see iso646.h). */
O("and", CPP_AND_AND, CPLUS),
O("and_eq", CPP_AND_EQ, CPLUS),
O("bitand", CPP_AND, CPLUS),
O("bitor", CPP_OR, CPLUS),
O("compl", CPP_COMPL, CPLUS),
O("not", CPP_NOT, CPLUS),
O("not_eq", CPP_NOT_EQ, CPLUS),
O("or", CPP_OR_OR, CPLUS),
O("or_eq", CPP_OR_EQ, CPLUS),
O("xor", CPP_XOR, CPLUS),
O("xor_eq", CPP_XOR_EQ, CPLUS)
};
#undef B
#undef C
#undef X
#undef O
#define builtin_array_end \
builtin_array + sizeof(builtin_array)/sizeof(struct builtin)
/* Named operators known to the preprocessor. These cannot be
#defined and always have their stated meaning. They are treated
like normal identifiers except for the type code and the meaning.
Most of them are only for C++ (but see iso646.h). */
#define B(n, t) { DSC(n), t }
static const struct named_op
{
const U_CHAR *name;
unsigned int len;
enum cpp_ttype value;
} operator_array[] = {
B("and", CPP_AND_AND),
B("and_eq", CPP_AND_EQ),
B("bitand", CPP_AND),
B("bitor", CPP_OR),
B("compl", CPP_COMPL),
B("not", CPP_NOT),
B("not_eq", CPP_NOT_EQ),
B("or", CPP_OR_OR),
B("or_eq", CPP_OR_EQ),
B("xor", CPP_XOR),
B("xor_eq", CPP_XOR_EQ)
};
#undef B
/* Mark the C++ named operators in the hash table. */
static void
mark_named_operators (pfile)
cpp_reader *pfile;
{
const struct named_op *b;
for (b = operator_array;
b < (operator_array + ARRAY_SIZE (operator_array));
b++)
{
cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len);
hp->flags |= NODE_OPERATOR;
hp->value.operator = b->value;
}
}
/* Subroutine of cpp_read_main_file; reads the builtins table above and
enters them, and language-specific macros, into the hash table. */
static void
@ -703,26 +724,12 @@ init_builtins (pfile)
for(b = builtin_array; b < builtin_array_end; b++)
{
if ((b->flags & CPLUS) && ! CPP_OPTION (pfile, cplusplus))
continue;
if ((b->flags & OPERATOR) && ! CPP_OPTION (pfile, operator_names))
continue;
if (b->flags & (OPERATOR | BUILTIN))
if (b->flags & BUILTIN)
{
cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len);
if (b->flags & OPERATOR)
{
hp->flags |= NODE_OPERATOR;
hp->value.operator = b->operator;
}
else
{
hp->type = NT_MACRO;
hp->flags |= NODE_BUILTIN | NODE_WARN;
hp->value.builtin = b->builtin;
}
hp->type = NT_MACRO;
hp->flags |= NODE_BUILTIN | NODE_WARN;
hp->value.builtin = b->builtin;
}
else /* A standard macro of some kind. */
{
@ -781,7 +788,6 @@ init_builtins (pfile)
#undef OPERATOR
#undef VERS
#undef ULP
#undef CPLUS
#undef builtin_array_end
/* And another subroutine. This one sets up the standard include path. */
@ -1001,6 +1007,10 @@ void
cpp_finish_options (pfile)
cpp_reader *pfile;
{
/* Mark named operators before handling command line macros. */
if (CPP_OPTION (pfile, cplusplus) && CPP_OPTION (pfile, operator_names))
mark_named_operators (pfile);
/* Install builtins and process command line macros etc. in the order
they appeared, but only if not already preprocessed. */
if (! CPP_OPTION (pfile, preprocessed))
@ -1871,7 +1881,10 @@ init_dependency_output (pfile)
{
spec = getenv ("SUNPRO_DEPENDENCIES");
if (spec)
CPP_OPTION (pfile, print_deps) = 2;
{
CPP_OPTION (pfile, print_deps) = 2;
CPP_OPTION (pfile, deps_ignore_main_file) = 1;
}
else
return;
}

View File

@ -406,12 +406,17 @@ run_directive (pfile, dir_no, buf, count)
{
cpp_push_buffer (pfile, (const U_CHAR *) buf, count,
/* from_stage3 */ true, 1);
/* Disgusting hack. */
if (dir_no == T_PRAGMA)
pfile->buffer->inc = pfile->buffer->prev->inc;
start_directive (pfile);
/* We don't want a leading # to be interpreted as a directive. */
pfile->buffer->saved_flags = 0;
pfile->directive = &dtable[dir_no];
(void) (*pfile->directive->handler) (pfile);
end_directive (pfile, 1);
if (dir_no == T_PRAGMA)
pfile->buffer->inc = NULL;
_cpp_pop_buffer (pfile);
}

View File

@ -279,6 +279,9 @@ struct cpp_options
/* If true, fopen (deps_file, "a") else fopen (deps_file, "w"). */
unsigned char print_deps_append;
/* If true, no dependency is generated on the main file. */
unsigned char deps_ignore_main_file;
/* Nonzero means print names of header files (-H). */
unsigned char print_include_names;
@ -335,6 +338,9 @@ struct cpp_options
/* Nonzero for the 1999 C Standard, including corrigenda and amendments. */
unsigned char c99;
/* Nonzero if conforming to some particular standard. */
unsigned char std;
/* Nonzero means give all the error messages the ANSI standard requires. */
unsigned char pedantic;

View File

@ -613,7 +613,20 @@ collect_args (pfile, node)
}
if (!error)
return base_buff;
{
/* GCC has special semantics for , ## b where b is a varargs
parameter: we remove the comma if b was omitted entirely.
If b was merely an empty argument, the comma is retained.
If the macro takes just one (varargs) parameter, then we
retain the comma only if we are standards conforming.
If FIRST is NULL replace_args () swallows the comma. */
if (macro->variadic && (argc < macro->paramc
|| (argc == 1 && args[0].count == 0
&& !CPP_OPTION (pfile, std))))
args[macro->paramc - 1].first = NULL;
return base_buff;
}
_cpp_release_buff (pfile, base_buff);
return NULL;
@ -673,6 +686,8 @@ enter_macro_context (pfile, node)
/* The presence of a macro invalidates a file's controlling macro. */
pfile->mi_valid = false;
pfile->state.angled_headers = false;
/* Handle standard macros. */
if (! (node->flags & NODE_BUILTIN))
{
@ -797,15 +812,13 @@ replace_args (pfile, node, args)
count = arg->count, from = arg->first;
if (dest != first)
{
/* GCC has special semantics for , ## b where b is a
varargs parameter: the comma disappears if b was
given no actual arguments (not merely if b is an
empty argument); otherwise the paste flag is removed. */
if (dest[-1]->type == CPP_COMMA
&& macro->variadic
&& src->val.arg_no == macro->paramc)
{
if (count == 0)
/* Swallow a pasted comma if from == NULL, otherwise
drop the paste flag. */
if (from == NULL)
dest--;
else
paste_flag = dest - 1;
@ -1529,7 +1542,7 @@ cpp_macro_definition (pfile, node)
}
/* Calculate length. */
len = NODE_LEN (node) + 1; /* ' ' */
len = NODE_LEN (node) + 2; /* ' ' and NUL. */
if (macro->fun_like)
{
len += 4; /* "()" plus possible final ".." of named

View File

@ -2254,10 +2254,11 @@ canon_hash (x, mode)
case REG:
{
unsigned int regno = REGNO (x);
bool record;
/* On some machines, we can't record any non-fixed hard register,
because extending its life will cause reload problems. We
consider ap, fp, and sp to be fixed for this purpose.
consider ap, fp, sp, gp to be fixed for this purpose.
We also consider CCmode registers to be fixed for this purpose;
failure to do so leads to failure to simplify 0<100 type of
@ -2267,16 +2268,28 @@ canon_hash (x, mode)
Nor should we record any register that is in a small
class, as defined by CLASS_LIKELY_SPILLED_P. */
if (regno < FIRST_PSEUDO_REGISTER
&& (global_regs[regno]
|| CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (regno))
|| (SMALL_REGISTER_CLASSES
&& ! fixed_regs[regno]
&& x != frame_pointer_rtx
&& x != hard_frame_pointer_rtx
&& x != arg_pointer_rtx
&& x != stack_pointer_rtx
&& GET_MODE_CLASS (GET_MODE (x)) != MODE_CC)))
if (regno >= FIRST_PSEUDO_REGISTER)
record = true;
else if (x == frame_pointer_rtx
|| x == hard_frame_pointer_rtx
|| x == arg_pointer_rtx
|| x == stack_pointer_rtx
|| x == pic_offset_table_rtx)
record = true;
else if (global_regs[regno])
record = false;
else if (fixed_regs[regno])
record = true;
else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_CC)
record = true;
else if (SMALL_REGISTER_CLASSES)
record = false;
else if (CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (regno)))
record = false;
else
record = true;
if (!record)
{
do_not_record = 1;
return 0;
@ -3464,7 +3477,9 @@ fold_rtx (x, insn)
&& GET_CODE (elt->exp) != SIGN_EXTEND
&& GET_CODE (elt->exp) != ZERO_EXTEND
&& GET_CODE (XEXP (elt->exp, 0)) == SUBREG
&& GET_MODE (SUBREG_REG (XEXP (elt->exp, 0))) == mode)
&& GET_MODE (SUBREG_REG (XEXP (elt->exp, 0))) == mode
&& (GET_MODE_CLASS (mode)
== GET_MODE_CLASS (GET_MODE (XEXP (elt->exp, 0)))))
{
rtx op0 = SUBREG_REG (XEXP (elt->exp, 0));
@ -4906,7 +4921,10 @@ cse_insn (insn, libcall_insn)
&& (tem = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0
&& (! rtx_equal_p (XEXP (tem, 0), SET_SRC (sets[0].rtl))
|| GET_CODE (SET_DEST (sets[0].rtl)) == STRICT_LOW_PART))
src_eqv = canon_reg (XEXP (tem, 0), NULL_RTX);
{
src_eqv = fold_rtx (canon_reg (XEXP (tem, 0), NULL_RTX), insn);
XEXP (tem, 0) = src_eqv;
}
/* Canonicalize sources and addresses of destinations.
We do this in a separate pass to avoid problems when a MATCH_DUP is
@ -5010,7 +5028,6 @@ cse_insn (insn, libcall_insn)
eqvmode = GET_MODE (SUBREG_REG (XEXP (dest, 0)));
do_not_record = 0;
hash_arg_in_memory = 0;
src_eqv = fold_rtx (src_eqv, insn);
src_eqv_hash = HASH (src_eqv, eqvmode);
/* Find the equivalence class for the equivalent expression. */

View File

@ -104,6 +104,10 @@ static int n_useless_values;
static varray_type reg_values;
#define REG_VALUES(I) VARRAY_ELT_LIST (reg_values, (I))
/* The largest number of hard regs used by any entry added to the
REG_VALUES table. Cleared on each clear_table() invocation. */
static unsigned int max_value_regs;
/* Here the set of indices I with REG_VALUES(I) != 0 is saved. This is used
in clear_table() for fast emptying. */
static varray_type used_regs;
@ -227,6 +231,8 @@ clear_table (clear_all)
for (i = 0; i < VARRAY_ACTIVE_SIZE (used_regs); i++)
REG_VALUES (VARRAY_UINT (used_regs, i)) = 0;
max_value_regs = 0;
VARRAY_POP_ALL (used_regs);
htab_empty (hash_table);
@ -897,6 +903,14 @@ cselib_lookup (x, mode, create)
if (! create)
return 0;
if (i < FIRST_PSEUDO_REGISTER)
{
unsigned int n = HARD_REGNO_NREGS (i, mode);
if (n > max_value_regs)
max_value_regs = n;
}
e = new_cselib_val (++next_unknown_value, GET_MODE (x));
e->locs = new_elt_loc_list (e->locs, x);
if (REG_VALUES (i) == 0)
@ -957,11 +971,22 @@ cselib_invalidate_regno (regno, mode)
pseudos, only REGNO is affected. For hard regs, we must take MODE
into account, and we must also invalidate lower register numbers
if they contain values that overlap REGNO. */
endregno = regno + 1;
if (regno < FIRST_PSEUDO_REGISTER && mode != VOIDmode)
endregno = regno + HARD_REGNO_NREGS (regno, mode);
{
if (regno < max_value_regs)
i = 0;
else
i = regno - max_value_regs;
for (i = 0; i < endregno; i++)
endregno = regno + HARD_REGNO_NREGS (regno, mode);
}
else
{
i = regno;
endregno = regno + 1;
}
for (; i < endregno; i++)
{
struct elt_list **l = &REG_VALUES (i);
@ -1171,6 +1196,14 @@ cselib_record_set (dest, src_elt, dest_addr_elt)
if (REG_VALUES (dreg) == 0)
VARRAY_PUSH_UINT (used_regs, dreg);
if (dreg < FIRST_PSEUDO_REGISTER)
{
unsigned int n = HARD_REGNO_NREGS (dreg, GET_MODE (dest));
if (n > max_value_regs)
max_value_regs = n;
}
REG_VALUES (dreg) = new_elt_list (REG_VALUES (dreg), src_elt);
if (src_elt->locs == 0)
n_useless_values--;

View File

@ -462,4 +462,10 @@ You Lose! You must define PREFERRED_DEBUGGING_TYPE!
#define MODE_BASE_REG_CLASS(MODE) BASE_REG_CLASS
#endif
/* Determine whether __cxa_atexit, rather than atexit, is used to
register C++ destructors for local statics and global objects. */
#ifndef DEFAULT_USE_CXA_ATEXIT
#define DEFAULT_USE_CXA_ATEXIT 0
#endif
#endif /* ! GCC_DEFAULTS_H */

View File

@ -38,7 +38,8 @@ Alasdair Baird for various bugfixes.
Gerald Baumgartner added the signature extension to the C++ front end.
@item
Neil Booth for various work on cpplib.
Neil Booth for work on cpplib, lang hooks, debug hooks and other
miscellaneous clean-ups.
@item
Per Bothner for his direction via the steering committee and various

View File

@ -1676,6 +1676,15 @@ eprintf ("success!\n")
@expansion{} fprintf(stderr, "success!\n");
@end example
@noindent
The above explanation is ambiguous about the case where the only macro
parameter is a variable arguments parameter, as it is meaningless to
try to distinguish whether no argument at all is an empty argument or
a missing argument. In this case the C99 standard is clear that the
comma must remain, however the existing GCC extension used to swallow
the comma. So CPP retains the comma when conforming to a specific C
standard, and drops it otherwise.
C99 mandates that the only place the identifier @code{@w{__VA_ARGS__}}
can appear is in the replacement list of a variadic macro. It may not
be used as a macro name, macro argument name, or within a different type

View File

@ -66,7 +66,8 @@ with an optional @option{-MT} switch too.
This variable is the same as the environment variable
@env{DEPENDENCIES_OUTPUT} (@pxref{DEPENDENCIES_OUTPUT}), except that
system header files are not ignored, so it implies @option{-M} rather
than @option{-MM}.
than @option{-MM}. However, the dependence on the main input file is
omitted.
@ifset cppmanual
@xref{Invocation}.
@end ifset

View File

@ -4,7 +4,7 @@
@c Common values used in the GCC manuals:
@set version-GCC 3.1
@set version-GCC 3.2
@c Common macros to support generating man pages:

View File

@ -187,7 +187,7 @@ in the following sections.
-fno-optional-diags -fpermissive @gol
-frepo -fno-rtti -fstats -ftemplate-depth-@var{n} @gol
-fuse-cxa-atexit -fvtable-gc -fno-weak -nostdinc++ @gol
-fno-default-inline -Wctor-dtor-privacy @gol
-fno-default-inline -Wabi -Wctor-dtor-privacy @gol
-Wnon-virtual-dtor -Wreorder @gol
-Weffc++ -Wno-deprecated @gol
-Wno-non-template-friend -Wold-style-cast @gol
@ -211,7 +211,7 @@ in the following sections.
@xref{Warning Options,,Options to Request or Suppress Warnings}.
@gccoptlist{
-fsyntax-only -pedantic -pedantic-errors @gol
-w -W -Wall -Waggregate-return @gol
-w -W -Wall -Waggregate-return @gol
-Wcast-align -Wcast-qual -Wchar-subscripts -Wcomment @gol
-Wconversion -Wno-deprecated-declarations @gol
-Wdisabled-optimization -Wdiv-by-zero -Werror @gol
@ -486,6 +486,7 @@ in the following sections.
-mpush-args -maccumulate-outgoing-args -m128bit-long-double @gol
-m96bit-long-double -mregparm=@var{num} -momit-leaf-frame-pointer @gol
-mno-red-zone@gol
-mcmodel=@var{code-model} @gol
-m32 -m64}
@emph{HPPA Options}
@ -1550,6 +1551,58 @@ Do not assume @samp{inline} for functions defined inside a class scope.
functions will have linkage like inline functions; they just won't be
inlined by default.
@item -Wabi @r{(C++ only)}
@opindex Wabi
Warn when G++ generates code that is probably not compatible with the
vendor-neutral C++ ABI. Although an effort has been made to warn about
all such cases, there are probably some cases that are not warned about,
even though G++ is generating incompatible code. There may also be
cases where warnings are emitted even though the code that is generated
will be compatible.
You should rewrite your code to avoid these warnings if you are
concerned about the fact that code generated by G++ may not be binary
compatible with code generated by other compilers.
The known incompatibilites at this point include:
@itemize @bullet
@item
Incorrect handling of tail-padding for bit-fields. G++ may attempt to
pack data into the same byte as a base class. For example:
@smallexample
struct A @{ virtual void f(); int f1 : 1; @};
struct B : public A @{ int f2 : 1; @};
@end smallexample
@noindent
In this case, G++ will place @code{B::f2} into the same byte
as@code{A::f1}; other compilers will not. You can avoid this problem
by explicitly padding @code{A} so that its size is a multiple of the
byte size on your platform; that will cause G++ and other compilers to
layout @code{B} identically.
@item
Incorrect handling of tail-padding for virtual bases. G++ does not use
tail padding when laying out virtual bases. For example:
@smallexample
struct A @{ virtual void f(); char c1; @};
struct B @{ B(); char c2; @};
struct C : public A, public virtual B @{@};
@end smallexample
@noindent
In this case, G++ will not place @code{B} into the tail-padding for
@code{A}; other compilers will. You can avoid this problem by
explicitly padding @code{A} so that its size is a multiple of its
alignment (ignoring virtual base classes); that will cause G++ and other
compilers to layout @code{C} identically.
@end itemize
@item -Wctor-dtor-privacy @r{(C++ only)}
@opindex Wctor-dtor-privacy
Warn when a class seems unusable, because all the constructors or
@ -7415,6 +7468,10 @@ boundary. Aligning @code{double} variables on a two word boundary will
produce code that runs somewhat faster on a @samp{Pentium} at the
expense of more memory.
@strong{Warning:} if you use the @samp{-malign-double} switch,
structures containing the above types will be aligned differently than
the published application binary interface specifications for the 386.
@item -m128bit-long-double
@opindex m128bit-long-double
Control the size of @code{long double} type. i386 application binary interface
@ -7594,6 +7651,32 @@ by the x86-64 ABI, it is a 128-byte area beyond the location of the
stack pointer that will not be modified by signal or interrupt handlers
and therefore can be used for temporary data without adjusting the stack
pointer. The flag @option{-mno-red-zone} disables this red zone.
@item -mcmodel=small
@opindex mcmodel=small
Generate code for the small code model: the program and its symbols must
be linked in the lower 2 GB of the address space. Pointers are 64 bits.
Programs can be statically or dynamically linked. This is the default
code model.
@item -mcmodel=kernel
@opindex mcmodel=kernel
Generate code for the kernel code model. The kernel runs in the
negative 2 GB of the address space.
This model has to be used for Linux kernel code.
@item -mcmodel=medium
@opindex mcmodel=medium
Generate code for the medium model: The program is linked in the lower 2
GB of the address space but symbols can be located anywhere in the
address space. Programs can be statically or dynamically linked, but
building of shared libraries are not supported with the medium model.
@item -mcmodel=large
@opindex mcmodel=large
Generate code for the large model: This model makes no assumptions
about addresses and sizes of sections. Currently GCC does not implement
this model.
@end table
@node HPPA Options

View File

@ -158,7 +158,9 @@ available in a particular run.
For nameless patterns, the condition is applied only when matching an
individual insn, and only after the insn has matched the pattern's
recognition template. The insn's operands may be found in the vector
@code{operands}.
@code{operands}. For an insn where the condition has once matched, it
can't be used to control register allocation, for example by excluding
certain hard registers or hard register combinations.
@item
The @dfn{output template}: a string that says how to output matching
@ -1867,7 +1869,7 @@ A constant in the range supported by @code{movrcc} instructions
@item N
Same as @samp{K}, except that it verifies that bits that are not in the
lower 32-bits range are all zero. Must be used instead of @samp{K} for
lower 32-bit range are all zero. Must be used instead of @samp{K} for
modes wider than @code{SImode}
@item G

View File

@ -1072,9 +1072,11 @@ by the @code{__attribute__ ((aligned (@var{n})))} construct.
@findex ADJUST_FIELD_ALIGN
@item ADJUST_FIELD_ALIGN (@var{field}, @var{computed})
An expression for the alignment of a structure field @var{field} if the
alignment computed in the usual way is @var{computed}. GCC uses
this value instead of the value in @code{BIGGEST_ALIGNMENT} or
@code{BIGGEST_FIELD_ALIGNMENT}, if defined.
alignment computed in the usual way (including applying of
@code{BIGGEST_ALIGNMENT} and @code{BIGGEST_FIELD_ALIGNMENT} to the
alignment) is @var{computed}. It overrides alignment only if the
field alignment has not been set by the
@code{__attribute__ ((aligned (@var{n})))} construct.
@findex MAX_OFILE_ALIGNMENT
@item MAX_OFILE_ALIGNMENT
@ -2454,14 +2456,14 @@ A C expression that is true if, for a register in
@code{CLASS_CANNOT_CHANGE_MODE}, the requested mode punning is invalid.
For the example, loading 32-bit integer or floating-point objects into
floating-point registers on the Alpha extends them to 64-bits.
floating-point registers on the Alpha extends them to 64 bits.
Therefore loading a 64-bit object and then storing it as a 32-bit object
does not store the low-order 32-bits, as would be the case for a normal
does not store the low-order 32 bits, as would be the case for a normal
register. Therefore, @file{alpha.h} defines @code{CLASS_CANNOT_CHANGE_MODE}
as @code{FLOAT_REGS} and @code{CLASS_CANNOT_CHANGE_MODE_P} restricts
mode changes to same-size modes.
Compare this to IA-64, which extends floating-point values to 82-bits,
Compare this to IA-64, which extends floating-point values to 82 bits,
and stores 64-bit integers in a different format than 64-bit doubles.
Therefore @code{CLASS_CANNOT_CHANGE_MODE_P} is always true.
@end table

View File

@ -417,16 +417,17 @@ expand_builtin_init_dwarf_reg_sizes (address)
rtx addr = expand_expr (address, NULL_RTX, VOIDmode, 0);
rtx mem = gen_rtx_MEM (BLKmode, addr);
for (i = 0; i < DWARF_FRAME_REGISTERS; i++)
{
HOST_WIDE_INT offset = DWARF_FRAME_REGNUM (i) * GET_MODE_SIZE (mode);
HOST_WIDE_INT size = GET_MODE_SIZE (reg_raw_mode[i]);
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (DWARF_FRAME_REGNUM (i) < DWARF_FRAME_REGISTERS)
{
HOST_WIDE_INT offset = DWARF_FRAME_REGNUM (i) * GET_MODE_SIZE (mode);
HOST_WIDE_INT size = GET_MODE_SIZE (reg_raw_mode[i]);
if (offset < 0)
continue;
if (offset < 0)
continue;
emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size));
}
emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size));
}
}
/* Convert a DWARF call frame info. operation to its string name */
@ -1943,7 +1944,8 @@ output_call_frame_info (for_eh)
fde = &fde_table[i];
/* Don't emit EH unwind info for leaf functions that don't need it. */
if (for_eh && fde->nothrow && ! fde->uses_eh_lsda)
if (!flag_asynchronous_unwind_tables && for_eh && fde->nothrow
&& ! fde->uses_eh_lsda)
continue;
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, FDE_LABEL, for_eh + i * 2);
@ -7571,11 +7573,11 @@ modified_type_die (type, is_const_type, is_volatile_type, context_die)
}
/* We want to equate the qualified type to the die below. */
if (qualified_type)
type = qualified_type;
type = qualified_type;
}
equate_type_number_to_die (type, mod_type_die);
if (type)
equate_type_number_to_die (type, mod_type_die);
if (item_type)
/* We must do this after the equate_type_number_to_die call, in case
this is a recursive type. This ensures that the modified_type_die
@ -8941,21 +8943,18 @@ rtl_for_decl_location (decl)
== strlen (TREE_STRING_POINTER (init)) + 1))
rtl = gen_rtx_CONST_STRING (VOIDmode, TREE_STRING_POINTER (init));
}
#if 0
/* We mustn't actually emit anything here, as we might not get a
chance to emit any symbols we refer to. For the release, don't
try to get this right. */
if (rtl == NULL)
/* If the initializer is something that we know will expand into an
immediate RTL constant, expand it now. Expanding anything else
tends to produce unresolved symbols; see debug/5770 and c++/6381. */
else if (TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST
|| TREE_CODE (DECL_INITIAL (decl)) == REAL_CST)
{
rtl = expand_expr (DECL_INITIAL (decl), NULL_RTX, VOIDmode,
EXPAND_INITIALIZER);
/* If expand_expr returned a MEM, we cannot use it, since
it won't be output, leading to unresolved symbol. */
/* If expand_expr returns a MEM, it wasn't immediate. */
if (rtl && GET_CODE (rtl) == MEM)
rtl = NULL;
abort ();
}
#endif
}
#ifdef ASM_SIMPLIFY_DWARF_ADDR

View File

@ -2086,7 +2086,8 @@ output_reg_number (rtl)
if (regno >= DWARF_FRAME_REGISTERS)
{
warning_with_decl (dwarf_last_decl, "internal regno botch: regno = %d\n",
warning_with_decl (dwarf_last_decl,
"internal regno botch: `%s' has regno = %d\n",
regno);
regno = 0;
}
@ -2303,7 +2304,8 @@ output_bound_representation (bound, dim_num, u_or_l)
|| TREE_CODE (bound) == CONVERT_EXPR)
bound = TREE_OPERAND (bound, 0);
if (TREE_CODE (bound) == SAVE_EXPR)
if (TREE_CODE (bound) == SAVE_EXPR
&& SAVE_EXPR_RTL (bound))
output_loc_descriptor
(eliminate_regs (SAVE_EXPR_RTL (bound), 0, NULL_RTX));
}

View File

@ -355,6 +355,14 @@ gen_rtx_CONST_INT (mode, arg)
return (rtx) *slot;
}
rtx
gen_int_mode (c, mode)
HOST_WIDE_INT c;
enum machine_mode mode;
{
return GEN_INT (trunc_int_for_mode (c, mode));
}
/* CONST_DOUBLEs needs special handling because their length is known
only at run-time. */
@ -831,6 +839,11 @@ gen_lowpart_common (mode, x)
> ((xsize + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))
return 0;
/* Don't allow generating paradoxical FLOAT_MODE subregs. */
if (GET_MODE_CLASS (mode) == MODE_FLOAT
&& GET_MODE (x) != VOIDmode && msize > xsize)
return 0;
offset = subreg_lowpart_offset (mode, GET_MODE (x));
if ((GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND)
@ -2161,6 +2174,7 @@ widen_memory_access (memref, mode, offset)
/* Similarly for the decl. */
else if (DECL_P (expr)
&& DECL_SIZE_UNIT (expr)
&& TREE_CODE (DECL_SIZE_UNIT (expr)) == INTEGER_CST
&& compare_tree_int (DECL_SIZE_UNIT (expr), size) >= 0
&& (! memoffset || INTVAL (memoffset) >= 0))
break;
@ -5023,7 +5037,7 @@ init_emit_once (line_numbers)
tries to use these variables. */
for (i = - MAX_SAVED_CONST_INT; i <= MAX_SAVED_CONST_INT; i++)
const_int_rtx[i + MAX_SAVED_CONST_INT] =
gen_rtx_raw_CONST_INT (VOIDmode, i);
gen_rtx_raw_CONST_INT (VOIDmode, (HOST_WIDE_INT) i);
ggc_add_rtx_root (const_int_rtx, 2 * MAX_SAVED_CONST_INT + 1);
if (STORE_FLAG_VALUE >= - MAX_SAVED_CONST_INT

View File

@ -34,6 +34,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "insn-config.h"
#include "ggc.h"
#include "recog.h"
#include "langhooks.h"
static rtx break_out_memory_refs PARAMS ((rtx));
static void emit_stack_probe PARAMS ((rtx));
@ -285,20 +286,33 @@ rtx
expr_size (exp)
tree exp;
{
tree size;
if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'd'
&& DECL_SIZE_UNIT (exp) != 0)
size = DECL_SIZE_UNIT (exp);
else
size = size_in_bytes (TREE_TYPE (exp));
tree size = (*lang_hooks.expr_size) (exp);
if (TREE_CODE (size) != INTEGER_CST
&& contains_placeholder_p (size))
size = build (WITH_RECORD_EXPR, sizetype, size, exp);
return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), 0);
}
/* Return a wide integer for the size in bytes of the value of EXP, or -1
if the size can vary or is larger than an integer. */
HOST_WIDE_INT
int_expr_size (exp)
tree exp;
{
tree t = (*lang_hooks.expr_size) (exp);
if (t == 0
|| TREE_CODE (t) != INTEGER_CST
|| TREE_OVERFLOW (t)
|| TREE_INT_CST_HIGH (t) != 0
/* If the result would appear negative, it's too big to represent. */
|| (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0)
return -1;
return TREE_INT_CST_LOW (t);
}
/* Return a copy of X in which all memory references

View File

@ -3049,9 +3049,12 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
not straightforward to generalize this. Maybe we should make an array
of possible modes in init_expmed? Save this for GCC 2.7. */
optab1 = (op1_is_pow2 ? (unsignedp ? lshr_optab : ashr_optab)
optab1 = ((op1_is_pow2 && op1 != const0_rtx)
? (unsignedp ? lshr_optab : ashr_optab)
: (unsignedp ? udiv_optab : sdiv_optab));
optab2 = (op1_is_pow2 ? optab1 : (unsignedp ? udivmod_optab : sdivmod_optab));
optab2 = ((op1_is_pow2 && op1 != const0_rtx)
? optab1
: (unsignedp ? udivmod_optab : sdivmod_optab));
for (compute_mode = mode; compute_mode != VOIDmode;
compute_mode = GET_MODE_WIDER_MODE (compute_mode))
@ -4136,6 +4139,12 @@ make_tree (type, x)
build (TRUNC_DIV_EXPR, t,
make_tree (t, XEXP (x, 0)),
make_tree (t, XEXP (x, 1)))));
case SIGN_EXTEND:
case ZERO_EXTEND:
t = type_for_mode (GET_MODE (XEXP (x, 0)), GET_CODE (x) == ZERO_EXTEND);
return fold (convert (type, make_tree (t, XEXP (x, 0))));
default:
t = make_node (RTL_EXPR);
TREE_TYPE (t) = type;

Some files were not shown because too many files have changed in this diff Show More