i386.md ("mmx_uavgv8qi3"): Use const_vector.

2002-02-19  Aldy Hernandez  <aldyh@redhat.com>

	* config/i386/i386.md ("mmx_uavgv8qi3"): Use const_vector.
	("mmx_uavgv4hi3"): Same.
	("pmulhrwv4hi3"): Same.

	* tree-inline.c (walk_tree): Handle vectors.

	* c-common.c (constant_expression_warning): Handle vectors.
	(overflow_warning): Same.

	* sched-deps.c (sched_analyze_2): Handle vectors.

	* rtlanal.c (rtx_unstable_p): Handle vectors.
	(rtx_varies_p): Same.
	(count_occurrences): Same.
	(regs_set_between_p): Same.
	(modified_between_p): Same.
	(modified_in_p): Same.
	(volatile_insn_p): Same.
	(volatile_refs_p): Same.
	(side_effects_p): Same.
	(may_trap_p): Same.
	(inequality_comparisons_p): Same.
	(replace_regs): Same.
	(computed_jump_p_1): Same.

	* rtl.c (DEF_MACHMODE): Change all definitions to accept 8th
	argument.
	(inner_mode_array): New.
	(copy_rtx): Handle vectors.
	(copy_most_rtx): Same.
	(rtx_equal_p): Same.
	(get_mode_alignment): Adjust for vectors.

	* resource.c (mark_referenced_resources): Handle vectors.
	(mark_set_resources): Same.

	* reload1.c (eliminate_regs): Handle vectors.
	(elimination_effects): Same.
	(scan_paradoxical_subregs): Same.

	* reload.c (subst_reg_equivs): Handle vectors.

	* regrename.c (scan_rtx): Handle vectors.

	* regclass.c (reg_scan_mark_refs): Handle vectors.

	* recog.c (find_single_use_1): Handle vectors.

	* local-alloc.c (equiv_init_varies_p): Handle vectors.
	(contains_replace_regs): Same.
	(memref_referenced_p): Same.

	* integrate.c (copy_rtx_and_substitute): Handle vectors.
	(subst_constants): Same.

	* genattrtab.c (attr_copy_rtx): Handle vectors.
	(encode_units_mask): Same.
	(clear_struct_flag): Same.
	(count_sub_rtxs): Same.

	* gcse.c (want_to_gcse_p): Handle vectors.
	(oprs_unchanged_p): Same.
	(hash_expr_1): Same.
	(oprs_not_set_p): Same.
	(expr_killed_p): Same.
	(compute_transp): Same.
	(store_ops_ok): Same.

	* function.c (purge_addressof_1): Do not allow paradoxical subregs
	of vectors.
	(fixup_var_refs_1): Same.
	(instantiate_virtual_regs_1): Same.

	* fold-const.c (operand_equal_p): Handle vectors.
	(fold): Same.
	(rtl_expr_nonnegative_p): Same.

	* flow.c (mark_used_regs): Handle vectors.

	* df.c (df_uses_record): Handle vectors.

	* cselib.c (cselib_subst_to_values): Handle vectors.
	(cselib_mem_conflict_p): Same.
	(hash_rtx): Same.

	* cse.c (canon_reg): Handle vectors.
	(fold_rt): Same.
	(cse_process_notes): Same.
	(count_reg_usage): Same.
	(canon_hash): Same.

	* alias.c (nonlocal_mentioned_p): Add case for CONST_VECTOR.

	* combine.c (mark_used_regs_combine): Add case for CONST_VECTOR.

	* emit-rtl.c (init_emit_once): Generate const0_rtx for vectors.
	(gen_rtx): Handle CONST_VECTOR.
	(gen_const_vector_0): New.
	(copy_rtx_if_shared): CONST_VECTORs can be shared.
	(reset_used_flags): Same.
	(copy_insn_1): Same.
	(initializer_constant_valid_p): Handle VECTOR_CST.

	* doc/c-tree.texi (Expression trees): Document VECTOR_CST.

	* doc/rtl.texi (Constants): Document const_vector.
	(CONST0_RTX): Update for vectors.
	(RTL sharing): Same.

	* print-tree.c (print_node): Add case for VECTOR_CST.

	* tree.h (TREE_VECTOR_CST_ELTS): New.
	(struct tree_vector): New.
	(union tree_node): Add vector node.
	(build_vector): Add prototype.

	* tree.def (VECTOR_CST): New.

	* tree.c (build_vector): New.

	* expmed.c (make_tree): Handle CONST_VECTOR.

	* rtl.h (CONSTANT_P): CONST_VECTORs are constants too.
	(CONST_VECTOR_ELT): New.
	(CONST_VECTOR_NUNITS): New.

	* machmode.h (GET_MODE_INNER): New.
	(DEF_MACHMODE): Accept 8th arg.

	* machmode.def: Add 8th argument for vector inner mode.
	Add inner vector modes for vectors.

	* rtl.def (VEC_CONST): Remove.
	(CONST_VECTOR): New.

	* expr.c (clear_storage): Allow vectors.
	(is_zeros_p): Handle VECTOR_CST.

	* varasm.c (output_constant_pool): Handle vectors.
	(rtx_const): Add veclo and vechi fields.
	(kind): Add RTX_VECTOR.
	(decode_rtx_const): Add case for vector.

	* config/rs6000/rs6000-protos.h: Add zero_constant.

	* config/rs6000/rs6000.c (rs6000_emit_move): Handle vector
	constants.  Force easy vector constants into memory.
	(easy_vector_constant): New.
	(emit_easy_vector_constant): New.
	(rs6000_legitimize_reload_address): Do not generate bad reloads on
	darwin.

	* config/rs6000/rs6000.md ("altivec_lvx"): Reflect what
	instruction does.
	("altivec_lvxl"): Same.
	(altivec_lvebx): Same.
	(altivec_lvehx): Same.
	(altivec_lvewx): Same.
	("*movv4si_const0"): New.
	("*movv4sf_const0"): New.
	("*movv8hi_const0"): New.
	("*movv16qi_const0"): New.

From-SVN: r49853
This commit is contained in:
Aldy Hernandez 2002-02-19 02:53:41 +00:00
parent 336669e7b0
commit 69ef87e2bc
42 changed files with 646 additions and 131 deletions

View File

@ -2276,6 +2276,7 @@ nonlocal_mentioned_p (x)
case CC0:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case CONST:
case LABEL_REF:
return 0;

View File

@ -702,6 +702,7 @@ constant_expression_warning (value)
tree value;
{
if ((TREE_CODE (value) == INTEGER_CST || TREE_CODE (value) == REAL_CST
|| TREE_CODE (value) == VECTOR_CST
|| TREE_CODE (value) == COMPLEX_CST)
&& TREE_CONSTANT_OVERFLOW (value) && pedantic)
pedwarn ("overflow in constant expression");
@ -736,6 +737,12 @@ overflow_warning (value)
if (skip_evaluation == 0)
warning ("floating point overflow in expression");
}
else if (TREE_CODE (value) == VECTOR_CST && TREE_OVERFLOW (value))
{
TREE_OVERFLOW (value) = 0;
if (skip_evaluation == 0)
warning ("vector overflow in expression");
}
}
/* Print a warning if a large constant is truncated to unsigned,

View File

@ -11603,6 +11603,7 @@ mark_used_regs_combine (x)
case CONST_INT:
case CONST:
case CONST_DOUBLE:
case CONST_VECTOR:
case PC:
case ADDR_VEC:
case ADDR_DIFF_VEC:

View File

@ -18999,14 +18999,14 @@
(plus:V8QI (plus:V8QI
(match_operand:V8QI 1 "register_operand" "0")
(match_operand:V8QI 2 "nonimmediate_operand" "ym"))
(vec_const:V8QI (parallel [(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)])))
(const_vector:V8QI [(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)]))
(const_int 1)))]
"TARGET_SSE || TARGET_3DNOW_A"
"pavgb\t{%2, %0|%0, %2}"
@ -19018,10 +19018,10 @@
(plus:V4HI (plus:V4HI
(match_operand:V4HI 1 "register_operand" "0")
(match_operand:V4HI 2 "nonimmediate_operand" "ym"))
(vec_const:V4HI (parallel [(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)])))
(const_vector:V4HI [(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)]))
(const_int 1)))]
"TARGET_SSE || TARGET_3DNOW_A"
"pavgw\t{%2, %0|%0, %2}"
@ -19735,12 +19735,11 @@
(match_operand:V4HI 1 "register_operand" "0"))
(sign_extend:V4SI
(match_operand:V4HI 2 "nonimmediate_operand" "ym")))
(vec_const:V4SI
(parallel [(const_int 32768)
(const_int 32768)
(const_int 32768)
(const_int 32768)])))
(const_int 16))))]
(const_vector:V4SI [(const_int 32768)
(const_int 32768)
(const_int 32768)
(const_int 32768)]))
(const_int 16))))]
"TARGET_3DNOW"
"pmulhrw\\t{%2, %0|%0, %2}"
[(set_attr "type" "mmx")])

View File

@ -52,6 +52,7 @@ extern int got_no_const_operand PARAMS ((rtx, enum machine_mode));
extern int num_insns_constant PARAMS ((rtx, enum machine_mode));
extern int easy_fp_constant PARAMS ((rtx, enum machine_mode));
extern int zero_fp_constant PARAMS ((rtx, enum machine_mode));
extern int zero_constant PARAMS ((rtx, enum machine_mode));
extern int volatile_mem_operand PARAMS ((rtx, enum machine_mode));
extern int offsettable_mem_operand PARAMS ((rtx, enum machine_mode));
extern int mem_or_easy_const_operand PARAMS ((rtx, enum machine_mode));

View File

@ -174,6 +174,7 @@ static void is_altivec_return_reg PARAMS ((rtx, void *));
int vrsave_operation PARAMS ((rtx, enum machine_mode));
static rtx generate_set_vrsave PARAMS ((rtx, rs6000_stack_t *, int));
static void altivec_frame_fixup PARAMS ((rtx, rtx, HOST_WIDE_INT));
static int easy_vector_constant PARAMS ((rtx));
/* Default register names. */
char rs6000_reg_names[][8] =
@ -1194,6 +1195,54 @@ easy_fp_constant (op, mode)
abort ();
}
/* Return 1 if the operand is a CONST_INT and can be put into a
register with one instruction. */
static int
easy_vector_constant (op)
rtx op;
{
rtx elt;
int units, i;
if (GET_CODE (op) != CONST_VECTOR)
return 0;
units = CONST_VECTOR_NUNITS (op);
/* We can generate 0 easily. Look for that. */
for (i = 0; i < units; ++i)
{
elt = CONST_VECTOR_ELT (op, i);
/* We could probably simplify this by just checking for equality
with CONST0_RTX for the current mode, but let's be safe
instead. */
if (GET_CODE (elt) == CONST_INT && INTVAL (elt) != 0)
return 0;
if (GET_CODE (elt) == CONST_DOUBLE
&& (CONST_DOUBLE_LOW (elt) != 0
|| CONST_DOUBLE_HIGH (elt) != 0))
return 0;
}
/* We could probably generate a few other constants trivially, but
gcc doesn't generate them yet. FIXME later. */
return 0;
}
/* Return 1 if the operand is the constant 0. This works for scalars
as well as vectors. */
int
zero_constant (op, mode)
rtx op;
enum machine_mode mode;
{
return op == CONST0_RTX (mode);
}
/* Return 1 if the operand is 0.0. */
int
zero_fp_constant (op, mode)
@ -1892,6 +1941,7 @@ rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
#if TARGET_MACHO
if (GET_CODE (x) == SYMBOL_REF
&& DEFAULT_ABI == ABI_DARWIN
&& !ALTIVEC_VECTOR_MODE (mode)
&& flag_pic)
{
/* Darwin load of floating point constant. */
@ -2186,9 +2236,10 @@ rs6000_emit_move (dest, source, mode)
/* Handle the case where reload calls us with an invalid address;
and the case of CONSTANT_P_RTX. */
if (! general_operand (operands[1], mode)
|| ! nonimmediate_operand (operands[0], mode)
|| GET_CODE (operands[1]) == CONSTANT_P_RTX)
if (!VECTOR_MODE_P (mode)
&& (! general_operand (operands[1], mode)
|| ! nonimmediate_operand (operands[0], mode)
|| GET_CODE (operands[1]) == CONSTANT_P_RTX))
{
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
return;
@ -2218,8 +2269,8 @@ rs6000_emit_move (dest, source, mode)
case V8HImode:
case V4SFmode:
case V4SImode:
/* fixme: aldyh -- allow vector constants when they are implemented. */
if (CONSTANT_P (operands[1]))
if (CONSTANT_P (operands[1])
&& !easy_vector_constant (operands[1]))
operands[1] = force_const_mem (mode, operands[1]);
break;

View File

@ -638,10 +638,13 @@ extern int rs6000_altivec_abi;
/* A bitfield declared as `int' forces `int' alignment for the struct. */
#define PCC_BITFIELD_TYPE_MATTERS 1
/* Make strings word-aligned so strcpy from constants will be faster. */
#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
(TREE_CODE (EXP) == STRING_CST \
&& (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
/* Make strings word-aligned so strcpy from constants will be faster.
Make vector constants quadword aligned. */
#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
(TREE_CODE (EXP) == STRING_CST \
&& (ALIGN) < BITS_PER_WORD \
? BITS_PER_WORD \
: (ALIGN))
/* Make arrays of chars word-aligned for the same reasons.
Align vectors to 128 bits. */

View File

@ -14017,6 +14017,36 @@
"mtvrsave %1"
[(set_attr "type" "altivec")])
;; Vector clears
(define_insn "*movv4si_const0"
[(set (match_operand:V4SI 0 "altivec_register_operand" "=v")
(match_operand:V4SI 1 "zero_constant" ""))]
"TARGET_ALTIVEC"
"vxor %0,%0,%0"
[(set_attr "type" "vecsimple")])
(define_insn "*movv4sf_const0"
[(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
(match_operand:V4SF 1 "zero_constant" ""))]
"TARGET_ALTIVEC"
"vxor %0,%0,%0"
[(set_attr "type" "vecsimple")])
(define_insn "*movv8hi_const0"
[(set (match_operand:V8HI 0 "altivec_register_operand" "=v")
(match_operand:V8HI 1 "zero_constant" ""))]
"TARGET_ALTIVEC"
"vxor %0,%0,%0"
[(set_attr "type" "vecsimple")])
(define_insn "*movv16qi_const0"
[(set (match_operand:V16QI 0 "altivec_register_operand" "=v")
(match_operand:V16QI 1 "zero_constant" ""))]
"TARGET_ALTIVEC"
"vxor %0,%0,%0"
[(set_attr "type" "vecsimple")])
;; Simple binary operations.
(define_insn "addv16qi3"
@ -15481,49 +15511,61 @@
"lvsr %0,%1,%2"
[(set_attr "type" "vecload")])
;; Parallel some of the LVE* and STV*'s with unspecs because some have
;; identical rtl but different instructions-- and gcc gets confused.
(define_insn "altivec_lvebx"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:SI 1 "register_operand" "b")
(match_operand:SI 2 "register_operand" "r")] 196))]
[(parallel
[(set (match_operand:V16QI 0 "register_operand" "=v")
(mem:V16QI (plus:SI (match_operand:SI 1 "register_operand" "b")
(match_operand:SI 2 "register_operand" "r"))))
(unspec [(const_int 0)] 196)])]
"TARGET_ALTIVEC"
"lvebx %0,%1,%2"
[(set_attr "type" "vecload")])
(define_insn "altivec_lvehx"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:SI 1 "register_operand" "b")
(match_operand:SI 2 "register_operand" "r")] 197))]
[(parallel
[(set (match_operand:V8HI 0 "register_operand" "=v")
(mem:V8HI
(and:SI (plus:SI (match_operand:SI 1 "register_operand" "b")
(match_operand:SI 2 "register_operand" "r"))
(const_int -2))))
(unspec [(const_int 0)] 197)])]
"TARGET_ALTIVEC"
"lvehx %0,%1,%2"
[(set_attr "type" "vecload")])
(define_insn "altivec_lvewx"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:SI 1 "register_operand" "b")
(match_operand:SI 2 "register_operand" "r")] 198))]
[(parallel
[(set (match_operand:V4SI 0 "register_operand" "=v")
(mem:V4SI
(and:SI (plus:SI (match_operand:SI 1 "register_operand" "b")
(match_operand:SI 2 "register_operand" "r"))
(const_int -4))))
(unspec [(const_int 0)] 198)])]
"TARGET_ALTIVEC"
"lvewx %0,%1,%2"
[(set_attr "type" "vecload")])
(define_insn "altivec_lvxl"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:SI 1 "register_operand" "b")
(match_operand:SI 2 "register_operand" "r")] 199))]
[(parallel
[(set (match_operand:V4SI 0 "register_operand" "=v")
(mem:V4SI (plus:SI (match_operand:SI 1 "register_operand" "b")
(match_operand:SI 2 "register_operand" "r"))))
(unspec [(const_int 0)] 213)])]
"TARGET_ALTIVEC"
"lvxl %0,%1,%2"
[(set_attr "type" "vecload")])
(define_insn "altivec_lvx"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:SI 1 "register_operand" "b")
(match_operand:SI 2 "register_operand" "r")] 200))]
(mem:V4SI (plus:SI (match_operand:SI 1 "register_operand" "b")
(match_operand:SI 2 "register_operand" "r"))))]
"TARGET_ALTIVEC"
"lvx %0,%1,%2"
[(set_attr "type" "vecload")])
;; Parallel the STV*'s with unspecs because some of them have
;; identical rtl but are different instructions-- and gcc gets confused.
(define_insn "altivec_stvx"
[(parallel
[(set (mem:V4SI

View File

@ -2323,6 +2323,22 @@ canon_hash (x, mode)
+ (unsigned) CONST_DOUBLE_HIGH (x));
return hash;
case CONST_VECTOR:
{
int units;
rtx elt;
units = CONST_VECTOR_NUNITS (x);
for (i = 0; i < units; ++i)
{
elt = CONST_VECTOR_ELT (x, i);
hash += canon_hash (elt, GET_MODE (elt));
}
return hash;
}
/* Assume there is only one rtx object for any given label. */
case LABEL_REF:
hash += ((unsigned) LABEL_REF << 7) + (unsigned long) XEXP (x, 0);
@ -2776,6 +2792,7 @@ canon_reg (x, insn)
case CONST:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case LABEL_REF:
case ADDR_VEC:
@ -3317,6 +3334,7 @@ fold_rtx (x, insn)
case CONST:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case LABEL_REF:
case REG:
@ -3727,6 +3745,7 @@ fold_rtx (x, insn)
case SYMBOL_REF:
case LABEL_REF:
case CONST_DOUBLE:
case CONST_VECTOR:
const_arg = arg;
break;
@ -6425,6 +6444,7 @@ cse_process_notes (x, object)
case SYMBOL_REF:
case LABEL_REF:
case CONST_DOUBLE:
case CONST_VECTOR:
case PC:
case CC0:
case LO_SUM:
@ -7416,6 +7436,7 @@ count_reg_usage (x, counts, dest, incr)
case CONST:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case LABEL_REF:
return;

View File

@ -593,6 +593,22 @@ hash_rtx (x, mode, create)
+ (unsigned) CONST_DOUBLE_HIGH (x));
return hash ? hash : (unsigned int) CONST_DOUBLE;
case CONST_VECTOR:
{
int units;
rtx elt;
units = CONST_VECTOR_NUNITS (x);
for (i = 0; i < units; ++i)
{
elt = CONST_VECTOR_ELT (x, i);
hash += hash_rtx (elt, GET_MODE (elt), 0);
}
return hash;
}
/* Assume there is only one rtx object for any given label. */
case LABEL_REF:
hash
@ -794,6 +810,7 @@ cselib_subst_to_values (x)
return e->u.val_rtx;
case CONST_DOUBLE:
case CONST_VECTOR:
case CONST_INT:
return x;
@ -1009,6 +1026,7 @@ cselib_mem_conflict_p (mem_base, val)
case CONST:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case LABEL_REF:
return 0;

View File

@ -1032,6 +1032,7 @@ df_uses_record (df, loc, ref_type, bb, insn, flags)
case CONST_INT:
case CONST:
case CONST_DOUBLE:
case CONST_VECTOR:
case PC:
case ADDR_VEC:
case ADDR_DIFF_VEC:

View File

@ -1712,6 +1712,7 @@ This macro returns the attributes on the type @var{type}.
@findex tree_int_cst_equal
@tindex REAL_CST
@tindex COMPLEX_CST
@tindex VECTOR_CST
@tindex STRING_CST
@findex TREE_STRING_LENGTH
@findex TREE_STRING_POINTER
@ -1858,6 +1859,12 @@ These nodes are used to represent complex number constants, that is a
@code{TREE_REALPART} and @code{TREE_IMAGPART} return the real and the
imaginary parts respectively.
@item VECTOR_CST
These nodes are used to represent vector constants, whose parts are
constant nodes. Each individual constant node is either an integer or a
double constant node. The first operand is a @code{TREE_LIST} of the
constant nodes and is accessed through @code{TREE_VECTOR_CST_ELTS}.
@item STRING_CST
These nodes represent string-constants. The @code{TREE_STRING_LENGTH}
returns the length of the string, as an @code{int}. The

View File

@ -1156,6 +1156,20 @@ bits but small enough to fit within twice that number of bits (GCC
does not provide a mechanism to represent even larger constants). In
the latter case, @var{m} will be @code{VOIDmode}.
@findex const_vector
@item (const_vector:@var{m} [@var{x0} @var{x1} @dots{}])
Represents a vector constant. The square brackets stand for the vector
containing the constant elements. @var{x0}, @var{x1} and so on are
the @code{const_int} or @code{const_double} elements.
The number of units in a @code{const_vector} is obtained with the macro
@code{CONST_VECTOR_NUNITS} as in @code{CONST_VECTOR_NUNITS (@var{v})}.
Individual elements in a vector constant are accessed with the macro
@code{CONST_VECTOR_ELT} as in @code{CONST_VECTOR_ELT (@var{v}, @var{n})
where @var{v} is the vector constant and @var{n} is the element
desired.
@findex CONST_DOUBLE_MEM
@findex CONST_DOUBLE_CHAIN
@var{addr} is used to contain the @code{mem} expression that corresponds
@ -1185,10 +1199,14 @@ the precise bit pattern used by the target machine, use the macro
@findex CONST2_RTX
The macro @code{CONST0_RTX (@var{mode})} refers to an expression with
value 0 in mode @var{mode}. If mode @var{mode} is of mode class
@code{MODE_INT}, it returns @code{const0_rtx}. Otherwise, it returns a
@code{CONST_DOUBLE} expression in mode @var{mode}. Similarly, the macro
@code{MODE_INT}, it returns @code{const0_rtx}. If mode @var{mode} is of
mode class @code{MODE_FLOAT}, it returns a @code{CONST_DOUBLE}
expression in mode @var{mode}. Otherwise, it returns a
@code{CONST_VECTOR} expression in mode @var{mode}. Similarly, the macro
@code{CONST1_RTX (@var{mode})} refers to an expression with value 1 in
mode @var{mode} and similarly for @code{CONST2_RTX}.
mode @var{mode} and similarly for @code{CONST2_RTX}. The
@code{CONST1_RTX} and @code{CONST2_RTX} macros are undefined
for vector modes.
@findex const_string
@item (const_string @var{str})
@ -3331,6 +3349,11 @@ There is only one @code{cc0} expression.
There is only one @code{const_double} expression with value 0 for
each floating point mode. Likewise for values 1 and 2.
@cindex @code{const_vector}, RTL sharing
@item
There is only one @code{const_vector} expression with value 0 for
each vector mode, be it an integer or a double constant vector.
@cindex @code{label_ref}, RTL sharing
@cindex @code{scratch}, RTL sharing
@item

View File

@ -196,6 +196,7 @@ static mem_attrs *get_mem_attrs PARAMS ((HOST_WIDE_INT, tree, rtx,
rtx, unsigned int,
enum machine_mode));
static tree component_ref_for_mem_expr PARAMS ((tree));
static rtx gen_const_vector_0 PARAMS ((enum mode_class, enum machine_mode));
/* Probability of the conditional branch currently proceeded by try_split.
Set to -1 otherwise. */
@ -2390,6 +2391,7 @@ copy_rtx_if_shared (orig)
case QUEUED:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case CODE_LABEL:
case PC:
@ -2506,6 +2508,7 @@ reset_used_flags (x)
case QUEUED:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case CODE_LABEL:
case PC:
@ -4541,6 +4544,7 @@ copy_insn_1 (orig)
case QUEUED:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case CODE_LABEL:
case PC:
@ -4779,6 +4783,35 @@ mark_emit_status (es)
ggc_mark_rtx (es->x_first_insn);
}
/* Generate the constant 0. The first argument is MODE_VECTOR_INT for
integers or MODE_VECTOR_FLOAT for floats. */
static rtx
gen_const_vector_0 (type, mode)
enum mode_class type;
enum machine_mode mode;
{
rtx tem;
rtvec v;
int units, i;
enum machine_mode inner;
units = GET_MODE_NUNITS (mode);
inner = GET_MODE_INNER (mode);
v = rtvec_alloc (units);
/* We need to call this function after we to set CONST0_RTX first. */
if (!CONST0_RTX (inner))
abort ();
for (i = 0; i < units; ++i)
RTVEC_ELT (v, i) = CONST0_RTX (inner);
tem = gen_rtx_CONST_VECTOR (mode, v);
return tem;
}
/* Create some permanent unique rtl objects shared between all functions.
LINE_NUMBERS is nonzero if line numbers are to be generated. */
@ -4920,6 +4953,18 @@ init_emit_once (line_numbers)
const_tiny_rtx[i][(int) mode] = GEN_INT (i);
}
for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
const_tiny_rtx[0][(int) mode]
= gen_const_vector_0 (MODE_VECTOR_INT, mode);
for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
const_tiny_rtx[0][(int) mode]
= gen_const_vector_0 (MODE_VECTOR_FLOAT, mode);
for (i = (int) CCmode; i < (int) MAX_MACHINE_MODE; ++i)
if (GET_MODE_CLASS ((enum machine_mode) i) == MODE_CC)
const_tiny_rtx[0][i] = const0_rtx;

View File

@ -4038,7 +4038,25 @@ make_tree (type, x)
}
return t;
case CONST_VECTOR:
{
int i, units;
rtx elt;
tree t = NULL_TREE;
units = CONST_VECTOR_NUNITS (x);
/* Build a tree with vector elements. */
for (i = units - 1; i >= 0; --i)
{
elt = CONST_VECTOR_ELT (x, i);
t = tree_cons (NULL_TREE, make_tree (type, elt), t);
}
return build_vector (type, t);
}
case PLUS:
return fold (build (PLUS_EXPR, type, make_tree (type, XEXP (x, 0)),
make_tree (type, XEXP (x, 1))));

View File

@ -2562,8 +2562,7 @@ clear_storage (object, size)
/* If OBJECT is not BLKmode and SIZE is the same size as its mode,
just move a zero. Otherwise, do this a piece at a time. */
if ((GET_MODE (object) != BLKmode
&& !VECTOR_MODE_P (GET_MODE (object)))
if (GET_MODE (object) != BLKmode
&& GET_CODE (size) == CONST_INT
&& GET_MODE_SIZE (GET_MODE (object)) == (unsigned int) INTVAL (size))
emit_move_insn (object, CONST0_RTX (GET_MODE (object)));
@ -4245,6 +4244,14 @@ is_zeros_p (exp)
case REAL_CST:
return REAL_VALUES_IDENTICAL (TREE_REAL_CST (exp), dconst0);
case VECTOR_CST:
for (elt = TREE_VECTOR_CST_ELTS (exp); elt;
elt = TREE_CHAIN (elt))
if (!is_zeros_p (TREE_VALUE (elt)))
return 0;
return 1;
case CONSTRUCTOR:
if (TREE_TYPE (exp) && TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
return CONSTRUCTOR_ELTS (exp) == NULL_TREE;

View File

@ -3635,6 +3635,7 @@ mark_used_regs (pbi, x, cond, insn)
case CONST_INT:
case CONST:
case CONST_DOUBLE:
case CONST_VECTOR:
case PC:
case ADDR_VEC:
case ADDR_DIFF_VEC:

View File

@ -2427,6 +2427,27 @@ operand_equal_p (arg0, arg1, only_const)
&& REAL_VALUES_IDENTICAL (TREE_REAL_CST (arg0),
TREE_REAL_CST (arg1)));
case VECTOR_CST:
{
tree v1, v2;
if (TREE_CONSTANT_OVERFLOW (arg0)
|| TREE_CONSTANT_OVERFLOW (arg1))
return 0;
v1 = TREE_VECTOR_CST_ELTS (arg0);
v2 = TREE_VECTOR_CST_ELTS (arg1);
while (v1 && v2)
{
if (!operand_equal_p (v1, v2, only_const))
return 0;
v1 = TREE_CHAIN (v1);
v2 = TREE_CHAIN (v2);
}
return 1;
}
case COMPLEX_CST:
return (operand_equal_p (TREE_REALPART (arg0), TREE_REALPART (arg1),
only_const)
@ -5184,6 +5205,7 @@ fold (expr)
{
case INTEGER_CST:
case REAL_CST:
case VECTOR_CST:
case STRING_CST:
case COMPLEX_CST:
case CONSTRUCTOR:
@ -7586,6 +7608,23 @@ rtl_expr_nonnegative_p (r)
return CONST_DOUBLE_HIGH (r) >= 0;
return 0;
case CONST_VECTOR:
{
int units, i;
rtx elt;
units = CONST_VECTOR_NUNITS (r);
for (i = 0; i < units; ++i)
{
elt = CONST_VECTOR_ELT (r, i);
if (!rtl_expr_nonnegative_p (elt))
return 0;
}
return 1;
}
case SYMBOL_REF:
case LABEL_REF:
/* These are always nonnegative. */

View File

@ -1994,6 +1994,7 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
case SYMBOL_REF:
case LABEL_REF:
case CONST_DOUBLE:
case CONST_VECTOR:
return;
case SIGN_EXTRACT:
@ -3722,6 +3723,7 @@ instantiate_virtual_regs_1 (loc, object, extra_insns)
{
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case CONST:
case SYMBOL_REF:
case CODE_LABEL:

View File

@ -1315,6 +1315,7 @@ want_to_gcse_p (x)
case SUBREG:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case CALL:
return 0;
@ -1400,6 +1401,7 @@ oprs_unchanged_p (x, insn, avail_p)
case CONST:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case LABEL_REF:
case ADDR_VEC:
@ -1635,6 +1637,22 @@ hash_expr_1 (x, mode, do_not_record_p)
+ (unsigned int) CONST_DOUBLE_HIGH (x));
return hash;
case CONST_VECTOR:
{
int units;
rtx elt;
units = CONST_VECTOR_NUNITS (x);
for (i = 0; i < units; ++i)
{
elt = CONST_VECTOR_ELT (x, i);
hash += hash_expr_1 (elt, GET_MODE (elt), do_not_record_p);
}
return hash;
}
/* Assume there is only one rtx object for any given label. */
case LABEL_REF:
/* We don't hash on the address of the CODE_LABEL to avoid bootstrap
@ -2756,6 +2774,7 @@ oprs_not_set_p (x, insn)
case CONST:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case LABEL_REF:
case ADDR_VEC:
@ -3089,6 +3108,7 @@ expr_killed_p (x, bb)
case CONST:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case LABEL_REF:
case ADDR_VEC:
@ -3789,6 +3809,7 @@ compute_transp (x, indx, bmap, set_p)
case CONST:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case LABEL_REF:
case ADDR_VEC:
@ -6289,6 +6310,7 @@ store_ops_ok (x, bb)
case CONST:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case LABEL_REF:
case ADDR_VEC:

View File

@ -839,6 +839,7 @@ attr_copy_rtx (orig)
case QUEUED:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case CODE_LABEL:
case PC:
@ -2278,6 +2279,7 @@ encode_units_mask (x)
case QUEUED:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case CODE_LABEL:
case PC:
@ -4112,6 +4114,7 @@ clear_struct_flag (x)
case QUEUED:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case CODE_LABEL:
case PC:
@ -4167,6 +4170,7 @@ count_sub_rtxs (x, max)
case QUEUED:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case CODE_LABEL:
case PC:

View File

@ -2120,6 +2120,7 @@ copy_rtx_and_substitute (orig, map, for_lhs)
case PC:
case CC0:
case CONST_INT:
case CONST_VECTOR:
return orig;
case SYMBOL_REF:
@ -2479,6 +2480,7 @@ subst_constants (loc, insn, map, memonly)
case PC:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case CONST:
case LABEL_REF:

View File

@ -539,6 +539,7 @@ equiv_init_varies_p (x)
case CONST:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case LABEL_REF:
return 0;
@ -658,6 +659,7 @@ contains_replace_regs (x)
case LABEL_REF:
case SYMBOL_REF:
case CONST_DOUBLE:
case CONST_VECTOR:
case PC:
case CC0:
case HIGH:
@ -708,6 +710,7 @@ memref_referenced_p (memref, x)
case LABEL_REF:
case SYMBOL_REF:
case CONST_DOUBLE:
case CONST_VECTOR:
case PC:
case CC0:
case HIGH:

View File

@ -63,50 +63,54 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
there is none. Vector modes use this field to point to the next
vector size, so we can iterate through the different vectors modes.
The ordering is by increasing byte size, with QI coming before HI,
HI before SI, etc. */
HI before SI, etc.
Eigth arg is the mode of the internal elements in a vector.
VOIDmode if not a vector.
*/
/* VOIDmode is used when no mode needs to be specified,
as for example on CONST_INT RTL expressions. */
DEF_MACHMODE (VOIDmode, "VOID", MODE_RANDOM, 0, 0, 0, VOIDmode)
DEF_MACHMODE (VOIDmode, "VOID", MODE_RANDOM, 0, 0, 0, VOIDmode, VOIDmode)
DEF_MACHMODE (BImode, "BI", MODE_INT, 1, 1, 1, QImode)
DEF_MACHMODE (QImode, "QI", MODE_INT, BITS_PER_UNIT, 1, 1, HImode)
DEF_MACHMODE (HImode, "HI", MODE_INT, BITS_PER_UNIT*2, 2, 2, SImode)
DEF_MACHMODE (SImode, "SI", MODE_INT, BITS_PER_UNIT*4, 4, 4, DImode)
DEF_MACHMODE (DImode, "DI", MODE_INT, BITS_PER_UNIT*8, 8, 8, TImode)
DEF_MACHMODE (TImode, "TI", MODE_INT, BITS_PER_UNIT*16, 16, 16, OImode)
DEF_MACHMODE (OImode, "OI", MODE_INT, BITS_PER_UNIT*32, 32, 32, VOIDmode)
DEF_MACHMODE (BImode, "BI", MODE_INT, 1, 1, 1, QImode, VOIDmode)
DEF_MACHMODE (QImode, "QI", MODE_INT, BITS_PER_UNIT, 1, 1, HImode, VOIDmode)
DEF_MACHMODE (HImode, "HI", MODE_INT, BITS_PER_UNIT*2, 2, 2, SImode, VOIDmode)
DEF_MACHMODE (SImode, "SI", MODE_INT, BITS_PER_UNIT*4, 4, 4, DImode, VOIDmode)
DEF_MACHMODE (DImode, "DI", MODE_INT, BITS_PER_UNIT*8, 8, 8, TImode, VOIDmode)
DEF_MACHMODE (TImode, "TI", MODE_INT, BITS_PER_UNIT*16, 16, 16, OImode, VOIDmode)
DEF_MACHMODE (OImode, "OI", MODE_INT, BITS_PER_UNIT*32, 32, 32, VOIDmode, VOIDmode)
/* Pointers on some machines use these types to distinguish them from
ints. Useful if a pointer is 4 bytes but has some bits that are
not significant, so it is really not quite as wide as an integer. */
DEF_MACHMODE (PQImode, "PQI", MODE_PARTIAL_INT, BITS_PER_UNIT, 1, 1, PHImode)
DEF_MACHMODE (PHImode, "PHI", MODE_PARTIAL_INT, BITS_PER_UNIT*2, 2, 2, PSImode)
DEF_MACHMODE (PSImode, "PSI", MODE_PARTIAL_INT, BITS_PER_UNIT*4, 4, 4, PDImode)
DEF_MACHMODE (PDImode, "PDI", MODE_PARTIAL_INT, BITS_PER_UNIT*8, 8, 8, VOIDmode)
DEF_MACHMODE (PQImode, "PQI", MODE_PARTIAL_INT, BITS_PER_UNIT, 1, 1, PHImode, VOIDmode)
DEF_MACHMODE (PHImode, "PHI", MODE_PARTIAL_INT, BITS_PER_UNIT*2, 2, 2, PSImode, VOIDmode)
DEF_MACHMODE (PSImode, "PSI", MODE_PARTIAL_INT, BITS_PER_UNIT*4, 4, 4, PDImode, VOIDmode)
DEF_MACHMODE (PDImode, "PDI", MODE_PARTIAL_INT, BITS_PER_UNIT*8, 8, 8, VOIDmode, VOIDmode)
DEF_MACHMODE (QFmode, "QF", MODE_FLOAT, BITS_PER_UNIT, 1, 1, HFmode)
DEF_MACHMODE (HFmode, "HF", MODE_FLOAT, BITS_PER_UNIT*2, 2, 2, TQFmode)
DEF_MACHMODE (TQFmode, "TQF", MODE_FLOAT, BITS_PER_UNIT*3, 3, 3, SFmode) /* MIL-STD-1750A */
DEF_MACHMODE (SFmode, "SF", MODE_FLOAT, BITS_PER_UNIT*4, 4, 4, DFmode)
DEF_MACHMODE (DFmode, "DF", MODE_FLOAT, BITS_PER_UNIT*8, 8, 8, XFmode)
DEF_MACHMODE (XFmode, "XF", MODE_FLOAT, BITS_PER_UNIT*12, 12, 12, TFmode) /* IEEE extended */
DEF_MACHMODE (TFmode, "TF", MODE_FLOAT, BITS_PER_UNIT*16, 16, 16, VOIDmode)
DEF_MACHMODE (QFmode, "QF", MODE_FLOAT, BITS_PER_UNIT, 1, 1, HFmode, VOIDmode)
DEF_MACHMODE (HFmode, "HF", MODE_FLOAT, BITS_PER_UNIT*2, 2, 2, TQFmode, VOIDmode)
DEF_MACHMODE (TQFmode, "TQF", MODE_FLOAT, BITS_PER_UNIT*3, 3, 3, SFmode, VOIDmode) /* MIL-STD-1750A */
DEF_MACHMODE (SFmode, "SF", MODE_FLOAT, BITS_PER_UNIT*4, 4, 4, DFmode, VOIDmode)
DEF_MACHMODE (DFmode, "DF", MODE_FLOAT, BITS_PER_UNIT*8, 8, 8, XFmode, VOIDmode)
DEF_MACHMODE (XFmode, "XF", MODE_FLOAT, BITS_PER_UNIT*12, 12, 12, TFmode, VOIDmode) /* IEEE extended */
DEF_MACHMODE (TFmode, "TF", MODE_FLOAT, BITS_PER_UNIT*16, 16, 16, VOIDmode, VOIDmode)
/* Complex modes. */
DEF_MACHMODE (QCmode, "QC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*2, 2, 1, HCmode)
DEF_MACHMODE (HCmode, "HC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*4, 4, 2, SCmode)
DEF_MACHMODE (SCmode, "SC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*8, 8, 4, DCmode)
DEF_MACHMODE (DCmode, "DC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*16, 16, 8, XCmode)
DEF_MACHMODE (XCmode, "XC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*24, 24, 12, TCmode)
DEF_MACHMODE (TCmode, "TC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*32, 32, 16, VOIDmode)
DEF_MACHMODE (QCmode, "QC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*2, 2, 1, HCmode, VOIDmode)
DEF_MACHMODE (HCmode, "HC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*4, 4, 2, SCmode, VOIDmode)
DEF_MACHMODE (SCmode, "SC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*8, 8, 4, DCmode, VOIDmode)
DEF_MACHMODE (DCmode, "DC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*16, 16, 8, XCmode, VOIDmode)
DEF_MACHMODE (XCmode, "XC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*24, 24, 12, TCmode, VOIDmode)
DEF_MACHMODE (TCmode, "TC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*32, 32, 16, VOIDmode, VOIDmode)
DEF_MACHMODE (CQImode, "CQI", MODE_COMPLEX_INT, BITS_PER_UNIT*2, 2, 1, CHImode)
DEF_MACHMODE (CHImode, "CHI", MODE_COMPLEX_INT, BITS_PER_UNIT*4, 4, 2, CSImode)
DEF_MACHMODE (CSImode, "CSI", MODE_COMPLEX_INT, BITS_PER_UNIT*8, 8, 4, CDImode)
DEF_MACHMODE (CDImode, "CDI", MODE_COMPLEX_INT, BITS_PER_UNIT*16, 16, 8, CTImode)
DEF_MACHMODE (CTImode, "CTI", MODE_COMPLEX_INT, BITS_PER_UNIT*32, 32, 16, COImode)
DEF_MACHMODE (COImode, "COI", MODE_COMPLEX_INT, BITS_PER_UNIT*64, 64, 32, VOIDmode)
DEF_MACHMODE (CQImode, "CQI", MODE_COMPLEX_INT, BITS_PER_UNIT*2, 2, 1, CHImode, VOIDmode)
DEF_MACHMODE (CHImode, "CHI", MODE_COMPLEX_INT, BITS_PER_UNIT*4, 4, 2, CSImode, VOIDmode)
DEF_MACHMODE (CSImode, "CSI", MODE_COMPLEX_INT, BITS_PER_UNIT*8, 8, 4, CDImode, VOIDmode)
DEF_MACHMODE (CDImode, "CDI", MODE_COMPLEX_INT, BITS_PER_UNIT*16, 16, 8, CTImode, VOIDmode)
DEF_MACHMODE (CTImode, "CTI", MODE_COMPLEX_INT, BITS_PER_UNIT*32, 32, 16, COImode, VOIDmode)
DEF_MACHMODE (COImode, "COI", MODE_COMPLEX_INT, BITS_PER_UNIT*64, 64, 32, VOIDmode, VOIDmode)
/* Vector modes. */
/* There are no V1xx vector modes. These are equivalent to normal
@ -114,43 +118,43 @@ DEF_MACHMODE (COImode, "COI", MODE_COMPLEX_INT, BITS_PER_UNIT*64, 64, 32, VOIDmo
/* The wider mode field for vectors follows in order of increasing bit
size with QI coming before HI, HI before SI, and SI before DI
within same bit sizes. */
DEF_MACHMODE (V2QImode, "V2QI", MODE_VECTOR_INT, BITS_PER_UNIT*2, 2, 1, V4QImode)
DEF_MACHMODE (V2HImode, "V2HI", MODE_VECTOR_INT, BITS_PER_UNIT*4, 4, 2, V8QImode)
DEF_MACHMODE (V2SImode, "V2SI", MODE_VECTOR_INT, BITS_PER_UNIT*8, 8, 4, V16QImode)
DEF_MACHMODE (V2DImode, "V2DI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 8, V8SImode)
DEF_MACHMODE (V2QImode, "V2QI", MODE_VECTOR_INT, BITS_PER_UNIT*2, 2, 1, V4QImode, QImode)
DEF_MACHMODE (V2HImode, "V2HI", MODE_VECTOR_INT, BITS_PER_UNIT*4, 4, 2, V8QImode, HImode)
DEF_MACHMODE (V2SImode, "V2SI", MODE_VECTOR_INT, BITS_PER_UNIT*8, 8, 4, V16QImode, SImode)
DEF_MACHMODE (V2DImode, "V2DI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 8, V8SImode, DImode)
DEF_MACHMODE (V4QImode, "V4QI", MODE_VECTOR_INT, BITS_PER_UNIT*4, 4, 1, V2HImode)
DEF_MACHMODE (V4HImode, "V4HI", MODE_VECTOR_INT, BITS_PER_UNIT*8, 8, 2, V2SImode)
DEF_MACHMODE (V4SImode, "V4SI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 4, V2DImode)
DEF_MACHMODE (V4DImode, "V4DI", MODE_VECTOR_INT, BITS_PER_UNIT*32, 32, 8, V8DImode)
DEF_MACHMODE (V4QImode, "V4QI", MODE_VECTOR_INT, BITS_PER_UNIT*4, 4, 1, V2HImode, QImode)
DEF_MACHMODE (V4HImode, "V4HI", MODE_VECTOR_INT, BITS_PER_UNIT*8, 8, 2, V2SImode, HImode)
DEF_MACHMODE (V4SImode, "V4SI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 4, V2DImode, SImode)
DEF_MACHMODE (V4DImode, "V4DI", MODE_VECTOR_INT, BITS_PER_UNIT*32, 32, 8, V8DImode, DImode)
DEF_MACHMODE (V8QImode, "V8QI", MODE_VECTOR_INT, BITS_PER_UNIT*8, 8, 1, V4HImode)
DEF_MACHMODE (V8HImode, "V8HI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 2, V4SImode)
DEF_MACHMODE (V8SImode, "V8SI", MODE_VECTOR_INT, BITS_PER_UNIT*32, 32, 4, V4DImode)
DEF_MACHMODE (V8DImode, "V8DI", MODE_VECTOR_INT, BITS_PER_UNIT*64, 64, 8, VOIDmode)
DEF_MACHMODE (V8QImode, "V8QI", MODE_VECTOR_INT, BITS_PER_UNIT*8, 8, 1, V4HImode, QImode)
DEF_MACHMODE (V8HImode, "V8HI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 2, V4SImode, HImode)
DEF_MACHMODE (V8SImode, "V8SI", MODE_VECTOR_INT, BITS_PER_UNIT*32, 32, 4, V4DImode, SImode)
DEF_MACHMODE (V8DImode, "V8DI", MODE_VECTOR_INT, BITS_PER_UNIT*64, 64, 8, VOIDmode, DImode)
DEF_MACHMODE (V16QImode, "V16QI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 1, V8HImode)
DEF_MACHMODE (V16QImode, "V16QI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 1, V8HImode, QImode)
DEF_MACHMODE (V2SFmode, "V2SF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*8, 8, 4, V4SFmode)
DEF_MACHMODE (V2DFmode, "V2DF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*16, 16, 8, V8SFmode)
DEF_MACHMODE (V2SFmode, "V2SF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*8, 8, 4, V4SFmode, SFmode)
DEF_MACHMODE (V2DFmode, "V2DF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*16, 16, 8, V8SFmode, DFmode)
DEF_MACHMODE (V4SFmode, "V4SF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*16, 16, 4, V2DFmode)
DEF_MACHMODE (V4DFmode, "V4DF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*32, 32, 8, V8DFmode)
DEF_MACHMODE (V4SFmode, "V4SF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*16, 16, 4, V2DFmode, SFmode)
DEF_MACHMODE (V4DFmode, "V4DF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*32, 32, 8, V8DFmode, DFmode)
DEF_MACHMODE (V8SFmode, "V8SF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*32, 32, 4,V4DFmode)
DEF_MACHMODE (V8DFmode, "V8DF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*64, 64, 8, VOIDmode)
DEF_MACHMODE (V16SFmode, "V16SF", MODE_VECTOR_FLOAT, 512, 64, 4, VOIDmode)
DEF_MACHMODE (V8SFmode, "V8SF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*32, 32, 4,V4DFmode, SFmode)
DEF_MACHMODE (V8DFmode, "V8DF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*64, 64, 8, VOIDmode, DFmode)
DEF_MACHMODE (V16SFmode, "V16SF", MODE_VECTOR_FLOAT, 512, 64, 4, VOIDmode, SFmode)
/* BLKmode is used for structures, arrays, etc.
that fit no more specific mode. */
DEF_MACHMODE (BLKmode, "BLK", MODE_RANDOM, 0, 0, 0, VOIDmode)
DEF_MACHMODE (BLKmode, "BLK", MODE_RANDOM, 0, 0, 0, VOIDmode, VOIDmode)
/* The modes for representing the condition codes come last. CCmode
is always defined. Additional modes for the condition code can be
specified in the EXTRA_CC_MODES macro. All MODE_CC modes are the
same width as SImode and have VOIDmode as their next wider mode. */
#define CC(E, M) DEF_MACHMODE (E, M, MODE_CC, BITS_PER_UNIT*4, 4, 4, VOIDmode)
#define CC(E, M) DEF_MACHMODE (E, M, MODE_CC, BITS_PER_UNIT*4, 4, 4, VOIDmode, VOIDmode)
CC (CCmode, "CC")
@ -167,7 +171,7 @@ EXTRA_CC_MODES
lot of redundancy in ports that support both 32-bit and 64-bit targets. */
#ifdef GENERATOR_FILE
#undef Pmode
DEF_MACHMODE (Pmode, "P", MODE_RANDOM, 0, 0, 0, VOIDmode)
DEF_MACHMODE (Pmode, "P", MODE_RANDOM, 0, 0, 0, VOIDmode, VOIDmode)
#endif
/*

View File

@ -24,7 +24,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* Make an enum class that gives all the machine modes. */
#define DEF_MACHMODE(SYM, NAME, TYPE, BITSIZE, SIZE, UNIT, WIDER) SYM,
#define DEF_MACHMODE(SYM, NAME, TYPE, BITSIZE, SIZE, UNIT, WIDER, INNER) SYM,
enum machine_mode {
#include "machmode.def"
@ -107,6 +107,12 @@ extern const unsigned HOST_WIDE_INT mode_mask_array[NUM_MACHINE_MODES];
#define GET_MODE_MASK(MODE) mode_mask_array[(int) (MODE)]
extern const enum machine_mode inner_mode_array[NUM_MACHINE_MODES];
/* Return the mode of the inner elements in a vector. */
#define GET_MODE_INNER(MODE) inner_mode_array[(int) (MODE)]
#endif /* defined (HOST_WIDE_INT) && ! defined GET_MODE_MASK */
#if ! defined GET_MODE_WIDER_MODE || ! defined GET_MODE_ALIGNMENT \

View File

@ -707,6 +707,22 @@ print_node (file, prefix, node, indent)
}
break;
case VECTOR_CST:
{
tree vals = TREE_VECTOR_CST_ELTS (node);
char buf[10];
tree link;
int i;
i = 0;
for (link = vals; link; link = TREE_CHAIN (link), ++i)
{
sprintf (buf, "elt%d: ", i);
print_node (file, buf, TREE_VALUE (link), indent + 4);
}
}
break;
case COMPLEX_CST:
print_node (file, "real", TREE_REALPART (node), indent + 4);
print_node (file, "imag", TREE_IMAGPART (node), indent + 4);

View File

@ -753,6 +753,7 @@ find_single_use_1 (dest, loc)
case LABEL_REF:
case SYMBOL_REF:
case CONST_DOUBLE:
case CONST_VECTOR:
case CLOBBER:
return 0;

View File

@ -2416,6 +2416,7 @@ reg_scan_mark_refs (x, insn, note_flag, min_regno)
case CONST:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case CC0:
case PC:
case SYMBOL_REF:

View File

@ -678,6 +678,7 @@ scan_rtx (insn, loc, class, action, type, earlyclobber)
case CONST:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case LABEL_REF:
case CC0:

View File

@ -4927,6 +4927,7 @@ subst_reg_equivs (ad, insn)
case CONST_INT:
case CONST:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case LABEL_REF:
case PC:

View File

@ -2282,6 +2282,7 @@ eliminate_regs (x, mem_mode, insn)
{
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case CONST:
case SYMBOL_REF:
case CODE_LABEL:
@ -2660,6 +2661,7 @@ elimination_effects (x, mem_mode)
{
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case CONST:
case SYMBOL_REF:
case CODE_LABEL:
@ -3749,6 +3751,7 @@ scan_paradoxical_subregs (x)
case SYMBOL_REF:
case LABEL_REF:
case CONST_DOUBLE:
case CONST_VECTOR: /* shouldn't happen, but just in case. */
case CC0:
case PC:
case USE:

View File

@ -212,6 +212,7 @@ mark_referenced_resources (x, res, include_delayed_effects)
case CONST:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case PC:
case SYMBOL_REF:
case LABEL_REF:
@ -645,6 +646,7 @@ mark_set_resources (x, res, in_dest, mark_type)
case USE:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case LABEL_REF:
case SYMBOL_REF:
case CONST:

View File

@ -115,7 +115,7 @@ const char * const rtx_name[NUM_RTX_CODE] = {
/* Indexed by machine mode, gives the name of that machine mode.
This name does not include the letters "mode". */
#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER) NAME,
#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) NAME,
const char * const mode_name[NUM_MACHINE_MODES] = {
#include "machmode.def"
@ -125,7 +125,7 @@ const char * const mode_name[NUM_MACHINE_MODES] = {
/* Indexed by machine mode, gives the class mode for GET_MODE_CLASS. */
#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER) CLASS,
#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) CLASS,
const enum mode_class mode_class[NUM_MACHINE_MODES] = {
#include "machmode.def"
@ -136,7 +136,7 @@ const enum mode_class mode_class[NUM_MACHINE_MODES] = {
/* Indexed by machine mode, gives the length of the mode, in bits.
GET_MODE_BITSIZE uses this. */
#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER) BITSIZE,
#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) BITSIZE,
const unsigned short mode_bitsize[NUM_MACHINE_MODES] = {
#include "machmode.def"
@ -147,7 +147,7 @@ const unsigned short mode_bitsize[NUM_MACHINE_MODES] = {
/* Indexed by machine mode, gives the length of the mode, in bytes.
GET_MODE_SIZE uses this. */
#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER) SIZE,
#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) SIZE,
const unsigned char mode_size[NUM_MACHINE_MODES] = {
#include "machmode.def"
@ -158,7 +158,7 @@ const unsigned char mode_size[NUM_MACHINE_MODES] = {
/* Indexed by machine mode, gives the length of the mode's subunit.
GET_MODE_UNIT_SIZE uses this. */
#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER) UNIT,
#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) UNIT,
const unsigned char mode_unit_size[NUM_MACHINE_MODES] = {
#include "machmode.def" /* machine modes are documented here */
@ -170,7 +170,7 @@ const unsigned char mode_unit_size[NUM_MACHINE_MODES] = {
(QI -> HI -> SI -> DI, etc.) Widening multiply instructions
use this. */
#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER) \
#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) \
(unsigned char) WIDER,
const unsigned char mode_wider_mode[NUM_MACHINE_MODES] = {
@ -179,7 +179,7 @@ const unsigned char mode_wider_mode[NUM_MACHINE_MODES] = {
#undef DEF_MACHMODE
#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER) \
#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) \
((BITSIZE) >= HOST_BITS_PER_WIDE_INT) ? ~(unsigned HOST_WIDE_INT) 0 : ((unsigned HOST_WIDE_INT) 1 << (BITSIZE)) - 1,
/* Indexed by machine mode, gives mask of significant bits in mode. */
@ -188,6 +188,17 @@ const unsigned HOST_WIDE_INT mode_mask_array[NUM_MACHINE_MODES] = {
#include "machmode.def"
};
#undef DEF_MACHMODE
#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) INNER,
/* Indexed by machine mode, gives the mode of the inner elements in a
vector type. */
const enum machine_mode inner_mode_array[NUM_MACHINE_MODES] = {
#include "machmode.def"
};
/* Indexed by mode class, gives the narrowest mode for each class.
The Q modes are always of width 1 (2 for complex) - it is impossible
for any mode to be narrower.
@ -346,6 +357,7 @@ copy_rtx (orig)
case QUEUED:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case CODE_LABEL:
case PC:
@ -455,6 +467,7 @@ copy_most_rtx (orig, may_share)
case QUEUED:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case CODE_LABEL:
case PC:
@ -560,7 +573,13 @@ unsigned int
get_mode_alignment (mode)
enum machine_mode mode;
{
unsigned int alignment = GET_MODE_UNIT_SIZE (mode);
unsigned int alignment;
if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
|| GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
alignment = GET_MODE_UNIT_SIZE (mode);
else
alignment = GET_MODE_SIZE (mode);
/* Extract the LSB of the size. */
alignment = alignment & -alignment;
@ -626,6 +645,7 @@ rtx_equal_p (x, y)
case SCRATCH:
case CONST_DOUBLE:
case CONST_INT:
case CONST_VECTOR:
return 0;
default:

View File

@ -585,6 +585,9 @@ DEF_RTL_EXPR(CONST_INT, "const_int", "w", 'o')
there may be from 1 to 4; see rtl.c. */
DEF_RTL_EXPR(CONST_DOUBLE, "const_double", CONST_DOUBLE_FORMAT, 'o')
/* Describes a vector constant. */
DEF_RTL_EXPR(CONST_VECTOR, "const_vector", "E", 'x')
/* String constant. Used only for attributes right now. */
DEF_RTL_EXPR(CONST_STRING, "const_string", "s", 'o')
@ -972,10 +975,6 @@ DEF_RTL_EXPR(VEC_SELECT, "vec_select", "ee", 'x')
combined and is the concatenation of the two source vectors. */
DEF_RTL_EXPR(VEC_CONCAT, "vec_concat", "ee", 'x')
/* Describes a vector constant. Each part of the PARALLEL that is operand 0
describes a constant for one of the subparts. */
DEF_RTL_EXPR(VEC_CONST, "vec_const", "e", 'x')
/* Describes an operation that converts a small vector into a larger one by
duplicating the input values. The output vector mode must have the same
submodes as the input vector mode, and the number of output parts must be

View File

@ -255,6 +255,7 @@ struct rtvec_def {
(GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
|| GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE \
|| GET_CODE (X) == CONST || GET_CODE (X) == HIGH \
|| GET_CODE (X) == CONST_VECTOR \
|| GET_CODE (X) == CONSTANT_P_RTX)
/* General accessor macros for accessing the fields of an rtx. */
@ -823,6 +824,12 @@ extern const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS];
/* Link for chain of all CONST_DOUBLEs in use in current function. */
#define CONST_DOUBLE_CHAIN(r) XCEXP (r, 0, CONST_DOUBLE)
/* For a CONST_VECTOR, return element #n. */
#define CONST_VECTOR_ELT(RTX, N) XCVECEXP (RTX, 0, N, CONST_VECTOR)
/* For a CONST_VECTOR, return the number of elements in a vector. */
#define CONST_VECTOR_NUNITS(RTX) XCVECLEN (RTX, 0, CONST_VECTOR)
/* For a SUBREG rtx, SUBREG_REG extracts the value we want a subreg of.
SUBREG_BYTE extracts the byte-number. */

View File

@ -64,6 +64,7 @@ rtx_unstable_p (x)
case CONST:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case LABEL_REF:
return 0;
@ -139,6 +140,7 @@ rtx_varies_p (x, for_alias)
case CONST:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case LABEL_REF:
return 0;
@ -502,6 +504,7 @@ count_occurrences (x, find, count_dest)
case REG:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case CODE_LABEL:
case PC:
@ -580,7 +583,8 @@ reg_mentioned_p (reg, in)
case CONST_INT:
return GET_CODE (reg) == CONST_INT && INTVAL (in) == INTVAL (reg);
case CONST_VECTOR:
case CONST_DOUBLE:
/* These are kept unique for a given value. */
return 0;
@ -829,6 +833,7 @@ regs_set_between_p (x, start, end)
{
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case CONST:
case SYMBOL_REF:
case LABEL_REF:
@ -875,6 +880,7 @@ modified_between_p (x, start, end)
{
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case CONST:
case SYMBOL_REF:
case LABEL_REF:
@ -930,6 +936,7 @@ modified_in_p (x, insn)
{
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case CONST:
case SYMBOL_REF:
case LABEL_REF:
@ -2021,6 +2028,7 @@ volatile_insn_p (x)
case CONST_INT:
case CONST:
case CONST_DOUBLE:
case CONST_VECTOR:
case CC0:
case PC:
case REG:
@ -2087,6 +2095,7 @@ volatile_refs_p (x)
case CONST_INT:
case CONST:
case CONST_DOUBLE:
case CONST_VECTOR:
case CC0:
case PC:
case REG:
@ -2153,6 +2162,7 @@ side_effects_p (x)
case CONST_INT:
case CONST:
case CONST_DOUBLE:
case CONST_VECTOR:
case CC0:
case PC:
case REG:
@ -2231,6 +2241,7 @@ may_trap_p (x)
/* Handle these cases quickly. */
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case LABEL_REF:
case CONST:
@ -2339,6 +2350,7 @@ inequality_comparisons_p (x)
case CC0:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case CONST:
case LABEL_REF:
case SYMBOL_REF:
@ -2452,6 +2464,7 @@ replace_regs (x, reg_map, nregs, replace_dest)
case CC0:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case CONST:
case SYMBOL_REF:
case LABEL_REF:
@ -2542,6 +2555,7 @@ computed_jump_p_1 (x)
case CONST:
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case REG:
return 1;

View File

@ -723,6 +723,7 @@ sched_analyze_2 (deps, x, insn)
{
case CONST_INT:
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
case CONST:
case LABEL_REF:

View File

@ -1223,6 +1223,7 @@ walk_tree (tp, func, data, htab_)
case IDENTIFIER_NODE:
case INTEGER_CST:
case REAL_CST:
case VECTOR_CST:
case STRING_CST:
case REAL_TYPE:
case COMPLEX_TYPE:

View File

@ -558,6 +558,35 @@ build_int_2_wide (low, hi)
return t;
}
/* Return a new VECTOR_CST node whose type is TYPE and whose values
are in a list pointed by VALS. */
tree
build_vector (type, vals)
tree type, vals;
{
tree v = make_node (VECTOR_CST);
int over1 = 0, over2 = 0;
tree link;
TREE_VECTOR_CST_ELTS (v) = vals;
TREE_TYPE (v) = type;
/* Iterate through elements and check for overflow. */
for (link = vals; link; link = TREE_CHAIN (link))
{
tree value = TREE_VALUE (link);
over1 |= TREE_OVERFLOW (value);
over2 |= TREE_CONSTANT_OVERFLOW (value);
}
TREE_OVERFLOW (v) = over1;
TREE_CONSTANT_OVERFLOW (v) = over2;
return v;
}
/* Return a new REAL_CST node whose type is TYPE and value is D. */
tree

View File

@ -269,6 +269,9 @@ DEFTREECODE (REAL_CST, "real_cst", 'c', 3)
Also there is TREE_CST_RTL. */
DEFTREECODE (COMPLEX_CST, "complex_cst", 'c', 3)
/* Contents are in TREE_VECTOR_CST_ELTS field. */
DEFTREECODE (VECTOR_CST, "vector_cst", 'c', 3)
/* Contents are TREE_STRING_LENGTH and TREE_STRING_POINTER fields.
Also there is TREE_CST_RTL. */
DEFTREECODE (STRING_CST, "string_cst", 'c', 3)

View File

@ -175,14 +175,14 @@ struct tree_common
TREE_VIA_VIRTUAL in
TREE_LIST or TREE_VEC
TREE_CONSTANT_OVERFLOW in
INTEGER_CST, REAL_CST, COMPLEX_CST
INTEGER_CST, REAL_CST, COMPLEX_CST, VECTOR_CST
TREE_SYMBOL_REFERENCED in
IDENTIFIER_NODE
public_flag:
TREE_OVERFLOW in
INTEGER_CST, REAL_CST, COMPLEX_CST
INTEGER_CST, REAL_CST, COMPLEX_CST, VECTOR_CST
TREE_PUBLIC in
VAR_DECL or FUNCTION_DECL or IDENTIFIER_NODE
TREE_VIA_PUBLIC in
@ -512,9 +512,10 @@ extern void tree_class_check_failed PARAMS ((const tree, int,
chain is via a `virtual' declaration. */
#define TREE_VIA_VIRTUAL(NODE) ((NODE)->common.static_flag)
/* In an INTEGER_CST, REAL_CST, or COMPLEX_CST, this means there was an
overflow in folding. This is distinct from TREE_OVERFLOW because ANSI C
requires a diagnostic when overflows occur in constant expressions. */
/* In an INTEGER_CST, REAL_CST, COMPLEX_CST, or VECTOR_CST this means
there was an overflow in folding. This is distinct from
TREE_OVERFLOW because ANSI C requires a diagnostic when overflows
occur in constant expressions. */
#define TREE_CONSTANT_OVERFLOW(NODE) ((NODE)->common.static_flag)
/* In an IDENTIFIER_NODE, this means that assemble_name was called with
@ -522,9 +523,10 @@ extern void tree_class_check_failed PARAMS ((const tree, int,
#define TREE_SYMBOL_REFERENCED(NODE) \
(IDENTIFIER_NODE_CHECK (NODE)->common.static_flag)
/* In an INTEGER_CST, REAL_CST, of COMPLEX_CST, this means there was an
overflow in folding, and no warning has been issued for this subexpression.
TREE_OVERFLOW implies TREE_CONSTANT_OVERFLOW, but not vice versa. */
/* In an INTEGER_CST, REAL_CST, COMPLEX_CST, or VECTOR_CST, this means
there was an overflow in folding, and no warning has been issued
for this subexpression. TREE_OVERFLOW implies
TREE_CONSTANT_OVERFLOW, but not vice versa. */
#define TREE_OVERFLOW(NODE) ((NODE)->common.public_flag)
/* In a VAR_DECL or FUNCTION_DECL,
@ -707,9 +709,9 @@ struct tree_int_cst
} int_cst;
};
/* In REAL_CST, STRING_CST, COMPLEX_CST nodes, and CONSTRUCTOR nodes,
and generally in all kinds of constants that could
be given labels (rather than being immediate). */
/* In REAL_CST, STRING_CST, COMPLEX_CST, VECTOR_CST nodes, and
CONSTRUCTOR nodes, and generally in all kinds of constants that
could be given labels (rather than being immediate). */
#define TREE_CST_RTL(NODE) (CST_OR_CONSTRUCTOR_CHECK (NODE)->real_cst.rtl)
@ -752,6 +754,16 @@ struct tree_complex
tree real;
tree imag;
};
/* In a VECTOR_CST node. */
#define TREE_VECTOR_CST_ELTS(NODE) (VECTOR_CST_CHECK (NODE)->vector.elements)
struct tree_vector
{
struct tree_common common;
rtx rtl;
tree elements;
};
#include "hashtable.h"
@ -1843,6 +1855,7 @@ union tree_node
struct tree_common common;
struct tree_int_cst int_cst;
struct tree_real_cst real_cst;
struct tree_vector vector;
struct tree_string string;
struct tree_complex complex;
struct tree_identifier identifier;
@ -2093,6 +2106,7 @@ extern tree build PARAMS ((enum tree_code, tree, ...));
extern tree build_nt PARAMS ((enum tree_code, ...));
extern tree build_int_2_wide PARAMS ((unsigned HOST_WIDE_INT, HOST_WIDE_INT));
extern tree build_vector PARAMS ((tree, tree));
extern tree build_real PARAMS ((tree, REAL_VALUE_TYPE));
extern tree build_real_from_int_cst PARAMS ((tree, tree));
extern tree build_complex PARAMS ((tree, tree, tree));

View File

@ -2382,7 +2382,8 @@ decode_addr_const (exp, value)
value->offset = offset;
}
enum kind { RTX_UNKNOWN, RTX_DOUBLE, RTX_INT, RTX_UNSPEC };
/* We do RTX_UNSPEC + XINT (blah), so nothing can go after RTX_UNSPEC. */
enum kind { RTX_UNKNOWN, RTX_DOUBLE, RTX_INT, RTX_VECTOR, RTX_UNSPEC };
struct rtx_const
{
ENUM_BITFIELD(kind) kind : 16;
@ -2391,6 +2392,10 @@ struct rtx_const
union real_extract du;
struct addr_const addr;
struct {HOST_WIDE_INT high, low;} di;
/* The max vector size we have is 8 wide. This should be enough. */
HOST_WIDE_INT veclo[16];
HOST_WIDE_INT vechi[16];
} un;
};
@ -3580,6 +3585,34 @@ decode_rtx_const (mode, x, value)
}
break;
case CONST_VECTOR:
{
int units, i;
rtx elt;
units = CONST_VECTOR_NUNITS (x);
value->kind = RTX_VECTOR;
value->mode = mode;
for (i = 0; i < units; ++i)
{
elt = CONST_VECTOR_ELT (x, i);
if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
{
value->un.veclo[i] = (HOST_WIDE_INT) INTVAL (elt);
value->un.vechi[i] = 0;
}
else if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
{
value->un.veclo[i] = (HOST_WIDE_INT) CONST_DOUBLE_LOW (elt);
value->un.vechi[i] = (HOST_WIDE_INT) CONST_DOUBLE_HIGH (elt);
}
else
abort ();
}
}
break;
case CONST_INT:
value->un.addr.offset = INTVAL (x);
break;
@ -4007,6 +4040,46 @@ output_constant_pool (fnname, fndecl)
assemble_integer (x, GET_MODE_SIZE (pool->mode), pool->align, 1);
break;
case MODE_VECTOR_FLOAT:
{
int i, units;
rtx elt;
if (GET_CODE (x) != CONST_VECTOR)
abort ();
units = CONST_VECTOR_NUNITS (x);
for (i = 0; i < units; i++)
{
elt = CONST_VECTOR_ELT (x, i);
memcpy ((char *) &u,
(char *) &CONST_DOUBLE_LOW (elt),
sizeof u);
assemble_real (u.d, GET_MODE_INNER (pool->mode), pool->align);
}
}
break;
case MODE_VECTOR_INT:
{
int i, units;
rtx elt;
if (GET_CODE (x) != CONST_VECTOR)
abort ();
units = CONST_VECTOR_NUNITS (x);
for (i = 0; i < units; i++)
{
elt = CONST_VECTOR_ELT (x, i);
assemble_integer (elt, GET_MODE_UNIT_SIZE (pool->mode),
pool->align, 1);
}
}
break;
default:
abort ();
}
@ -4255,6 +4328,7 @@ initializer_constant_valid_p (value, endtype)
return TREE_STATIC (value) ? null_pointer_node : 0;
case INTEGER_CST:
case VECTOR_CST:
case REAL_CST:
case STRING_CST:
case COMPLEX_CST: