/* Implement TARGET_MANGLE_TYPE. */
static const char *
-alpha_mangle_type (tree type)
+alpha_mangle_type (const_tree type)
{
if (TYPE_MAIN_VARIANT (type) == long_double_type_node
&& TARGET_LONG_DOUBLE_128)
if (!(target_flags_explicit & MASK_LONG_DOUBLE_128))
target_flags |= MASK_LONG_DOUBLE_128;
#endif
+
+ /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
+ can be optimized to ap = __builtin_next_arg (0). */
+ if (TARGET_ABI_UNICOSMK)
+ targetm.expand_builtin_va_start = NULL;
}
\f
/* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
function in the current unit of translation. */
static bool
-decl_has_samegp (tree decl)
+decl_has_samegp (const_tree decl)
{
/* Functions that are not local can be overridden, and thus may
not share the same gp. */
/* Return true if EXP should be placed in the small data section. */
static bool
-alpha_in_small_data_p (tree exp)
+alpha_in_small_data_p (const_tree exp)
{
/* We want to merge strings, so we never consider them small data. */
if (TREE_CODE (exp) == STRING_CST)
alpha_emit_xfloating_compare (enum rtx_code *pcode, rtx op0, rtx op1)
{
enum rtx_code cmp_code, res_code;
- rtx func, out, operands[2];
+ rtx func, out, operands[2], note;
/* X_floating library comparison functions return
-1 unordered
operands[1] = op1;
out = gen_reg_rtx (DImode);
- /* ??? Strange mode for equiv because what's actually returned
- is -1,0,1, not a proper boolean value. */
- alpha_emit_xfloating_libcall (func, out, operands, 2,
- gen_rtx_fmt_ee (cmp_code, CCmode, op0, op1));
+ /* What's actually returned is -1,0,1, not a proper boolean value,
+ so use an EXPR_LIST as with a generic libcall instead of a
+ comparison type expression. */
+ note = gen_rtx_EXPR_LIST (VOIDmode, op1, NULL_RTX);
+ note = gen_rtx_EXPR_LIST (VOIDmode, op0, note);
+ note = gen_rtx_EXPR_LIST (VOIDmode, func, note);
+ alpha_emit_xfloating_libcall (func, out, operands, 2, note);
return out;
}
seq = get_insns ();
end_sequence ();
- emit_insn_at_entry (seq);
+
+ /* We used to simply emit the sequence after entry_of_function.
+ However this breaks the CFG if the first instruction in the
+ first block is not the NOTE_INSN_BASIC_BLOCK, for example a
+ label. Emit the sequence properly on the edge. We are only
+ invoked from dw2_build_landing_pads and finish_eh_generation
+ will call commit_edge_insertions thanks to a kludge. */
+ insert_insn_on_edge (seq, single_succ_edge (ENTRY_BLOCK_PTR));
cfun->machine->gp_save_rtx = m;
}
addr = memory_address (mode, plus_constant (tramp, cxtofs));
emit_move_insn (gen_rtx_MEM (mode, addr), cxt);
- /* This has been disabled since the hint only has a 32k range, and in
- no existing OS is the stack within 32k of the text segment. */
- if (0 && jmpofs >= 0)
- {
- /* Compute hint value. */
- temp = force_operand (plus_constant (tramp, jmpofs+4), NULL_RTX);
- temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1,
- OPTAB_WIDEN);
- temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
- build_int_cst (NULL_TREE, 2), NULL_RTX, 1);
- temp = expand_and (SImode, gen_lowpart (SImode, temp),
- GEN_INT (0x3fff), 0);
-
- /* Merge in the hint. */
- addr = memory_address (SImode, plus_constant (tramp, jmpofs));
- temp1 = force_reg (SImode, gen_rtx_MEM (SImode, addr));
- temp1 = expand_and (SImode, temp1, GEN_INT (0xffffc000), NULL_RTX);
- temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1,
- OPTAB_WIDEN);
- emit_move_insn (gen_rtx_MEM (SImode, addr), temp1);
- }
-
#ifdef ENABLE_EXECUTE_STACK
emit_library_call (init_one_libfunc ("__enable_execute_stack"),
0, VOIDmode, 1, tramp, Pmode);
/* Return true if TYPE must be returned in memory, instead of in registers. */
static bool
-alpha_return_in_memory (tree type, tree fndecl ATTRIBUTE_UNUSED)
+alpha_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED)
{
enum machine_mode mode = VOIDmode;
int size;
static bool
alpha_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
enum machine_mode mode,
- tree type ATTRIBUTE_UNUSED,
+ const_tree type ATTRIBUTE_UNUSED,
bool named ATTRIBUTE_UNUSED)
{
return mode == TFmode || mode == TCmode;
$f0 for floating-point functions. */
rtx
-function_value (tree valtype, tree func ATTRIBUTE_UNUSED,
+function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED,
enum machine_mode mode)
{
unsigned int regnum, dummy;
should not split these values. */
static bool
-alpha_split_complex_arg (tree type)
+alpha_split_complex_arg (const_tree type)
{
return TYPE_MODE (type) != TCmode;
}
if ((TREE_CODE (rhs) != NOP_EXPR
&& TREE_CODE (rhs) != CONVERT_EXPR
- && (TREE_CODE (rhs) != PLUS_EXPR
+ && ((TREE_CODE (rhs) != PLUS_EXPR
+ && TREE_CODE (rhs) != POINTER_PLUS_EXPR)
|| TREE_CODE (TREE_OPERAND (rhs, 1)) != INTEGER_CST
|| !host_integerp (TREE_OPERAND (rhs, 1), 1)))
|| TREE_CODE (TREE_OPERAND (rhs, 0)) != SSA_NAME)
current statement. */
static bool
-alpha_stdarg_optimize_hook (struct stdarg_info *si, tree lhs, tree rhs)
+alpha_stdarg_optimize_hook (struct stdarg_info *si, const_tree lhs, const_tree rhs)
{
tree base, offset, arg1, arg2;
int offset_arg = 1;
lhs = va_list_skip_additions (TREE_OPERAND (rhs, 0));
if (lhs == NULL_TREE
- || TREE_CODE (lhs) != PLUS_EXPR)
+ || TREE_CODE (lhs) != POINTER_PLUS_EXPR)
return false;
base = TREE_OPERAND (lhs, 0);
#endif
}
-void
+static void
alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
{
HOST_WIDE_INT offset;
valist, offset_field, NULL_TREE);
t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
- t = build2 (PLUS_EXPR, ptr_type_node, t,
- build_int_cst (NULL_TREE, offset));
+ t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t,
+ size_int (offset));
t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (base_field), base_field, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
/* Build the final address and force that value into a temporary. */
- addr = build2 (PLUS_EXPR, ptr_type, fold_convert (ptr_type, base),
- fold_convert (ptr_type, addend));
+ addr = build2 (POINTER_PLUS_EXPR, ptr_type, fold_convert (ptr_type, base),
+ fold_convert (sizetype, addend));
internal_post = NULL;
gimplify_expr (&addr, pre_p, &internal_post, is_gimple_val, fb_rvalue);
append_to_statement_list (internal_post, pre_p);
final_start_function (insn, file, 1);
final (insn, file, 1);
final_end_function ();
+ free_after_compilation (cfun);
}
#endif /* TARGET_ABI_OSF */
\f
registers. */
static bool
-unicosmk_must_pass_in_stack (enum machine_mode mode, tree type)
+unicosmk_must_pass_in_stack (enum machine_mode mode, const_tree type)
{
if (type == NULL)
return false;
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK alpha_output_mi_thunk_osf
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
-#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
+#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
#undef TARGET_STDARG_OPTIMIZE_HOOK
#define TARGET_STDARG_OPTIMIZE_HOOK alpha_stdarg_optimize_hook
#endif
#define TARGET_MACHINE_DEPENDENT_REORG alpha_reorg
#undef TARGET_PROMOTE_FUNCTION_ARGS
-#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
+#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true
#undef TARGET_PROMOTE_FUNCTION_RETURN
-#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
+#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true
#undef TARGET_PROMOTE_PROTOTYPES
-#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_false
+#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_false
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY alpha_return_in_memory
#undef TARGET_PASS_BY_REFERENCE
#undef TARGET_BUILD_BUILTIN_VA_LIST
#define TARGET_BUILD_BUILTIN_VA_LIST alpha_build_builtin_va_list
+#undef TARGET_EXPAND_BUILTIN_VA_START
+#define TARGET_EXPAND_BUILTIN_VA_START alpha_va_start
+
/* The Alpha architecture does not require sequential consistency. See
http://www.cs.umd.edu/~pugh/java/memoryModel/AlphaReordering.html
for an example of how it can be violated in practice. */