summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/config/alpha
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2002-05-09 20:02:13 +0000
committerobrien <obrien@FreeBSD.org>2002-05-09 20:02:13 +0000
commitc8f5fc7032940ad6633f932ac40cade82ec4d0cc (patch)
tree29a0f0a6c79a69ecc64f612947a0fe5904311713 /contrib/gcc/config/alpha
parentc9ab9ae440a8066b2c2b85b157b1fdadcf09916a (diff)
downloadFreeBSD-src-c8f5fc7032940ad6633f932ac40cade82ec4d0cc.zip
FreeBSD-src-c8f5fc7032940ad6633f932ac40cade82ec4d0cc.tar.gz
Gcc 3.1.0 pre-release from the FSF anoncvs repo on 9-May-2002 15:57:15 EDT.
Diffstat (limited to 'contrib/gcc/config/alpha')
-rw-r--r--contrib/gcc/config/alpha/alpha-protos.h6
-rw-r--r--contrib/gcc/config/alpha/alpha.c469
-rw-r--r--contrib/gcc/config/alpha/alpha.h14
-rw-r--r--contrib/gcc/config/alpha/alpha.md179
-rw-r--r--contrib/gcc/config/alpha/elf.h50
-rw-r--r--contrib/gcc/config/alpha/freebsd.h30
-rw-r--r--contrib/gcc/config/alpha/linux.h4
-rw-r--r--contrib/gcc/config/alpha/netbsd.h14
-rw-r--r--contrib/gcc/config/alpha/osf.h25
-rw-r--r--contrib/gcc/config/alpha/t-vms4
-rw-r--r--contrib/gcc/config/alpha/vms.h51
-rw-r--r--contrib/gcc/config/alpha/x-vms2
-rw-r--r--contrib/gcc/config/alpha/xm-vms.h3
13 files changed, 553 insertions, 298 deletions
diff --git a/contrib/gcc/config/alpha/alpha-protos.h b/contrib/gcc/config/alpha/alpha-protos.h
index 2ff0350..c6fdd04 100644
--- a/contrib/gcc/config/alpha/alpha-protos.h
+++ b/contrib/gcc/config/alpha/alpha-protos.h
@@ -59,7 +59,7 @@ extern int current_file_function_operand PARAMS ((rtx, enum machine_mode));
extern int direct_call_operand PARAMS ((rtx, enum machine_mode));
extern int local_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int small_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int some_small_symbolic_mem_operand PARAMS ((rtx, enum machine_mode));
+extern int some_small_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int global_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int call_operand PARAMS ((rtx, enum machine_mode));
extern int symbolic_operand PARAMS ((rtx, enum machine_mode));
@@ -90,7 +90,7 @@ extern rtx alpha_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
extern rtx alpha_legitimize_reload_address PARAMS ((rtx, enum machine_mode,
int, int, int));
-extern rtx split_small_symbolic_mem_operand PARAMS ((rtx));
+extern rtx split_small_symbolic_operand PARAMS ((rtx));
extern void get_aligned_mem PARAMS ((rtx, rtx *, rtx *));
extern rtx get_unaligned_address PARAMS ((rtx, int));
@@ -163,6 +163,8 @@ extern rtx function_arg PARAMS ((CUMULATIVE_ARGS, enum machine_mode,
#endif
extern void alpha_start_function PARAMS ((FILE *, const char *, tree));
extern void alpha_end_function PARAMS ((FILE *, const char *, tree));
+extern void alpha_output_mi_thunk_osf PARAMS ((FILE *, tree,
+ HOST_WIDE_INT, tree));
extern void alpha_encode_section_info PARAMS ((tree));
#endif /* TREE CODE */
diff --git a/contrib/gcc/config/alpha/alpha.c b/contrib/gcc/config/alpha/alpha.c
index 0a1be01..c91e68c 100644
--- a/contrib/gcc/config/alpha/alpha.c
+++ b/contrib/gcc/config/alpha/alpha.c
@@ -46,9 +46,7 @@ Boston, MA 02111-1307, USA. */
#include "tm_p.h"
#include "target.h"
#include "target-def.h"
-
-/* External data. */
-extern int rtx_equal_function_value_matters;
+#include "debug.h"
/* Specify which cpu to schedule for. */
@@ -116,9 +114,9 @@ int alpha_this_gpdisp_sequence_number;
/* Declarations of static functions. */
static bool decl_in_text_section
PARAMS ((tree));
-static int some_small_symbolic_mem_operand_1
+static int some_small_symbolic_operand_1
PARAMS ((rtx *, void *));
-static int split_small_symbolic_mem_operand_1
+static int split_small_symbolic_operand_1
PARAMS ((rtx *, void *));
static bool local_symbol_p
PARAMS ((rtx));
@@ -1874,61 +1872,55 @@ alpha_legitimize_address (x, scratch, mode)
so that sched2 has the proper dependency information. */
int
-some_small_symbolic_mem_operand (x, mode)
+some_small_symbolic_operand (x, mode)
rtx x;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
- return for_each_rtx (&x, some_small_symbolic_mem_operand_1, NULL);
+ return for_each_rtx (&x, some_small_symbolic_operand_1, NULL);
}
static int
-some_small_symbolic_mem_operand_1 (px, data)
+some_small_symbolic_operand_1 (px, data)
rtx *px;
void *data ATTRIBUTE_UNUSED;
{
rtx x = *px;
- if (GET_CODE (x) != MEM)
- return 0;
- x = XEXP (x, 0);
-
- /* If this is an ldq_u type address, discard the outer AND. */
- if (GET_CODE (x) == AND)
- x = XEXP (x, 0);
+ /* Don't re-split. */
+ if (GET_CODE (x) == LO_SUM)
+ return -1;
- return small_symbolic_operand (x, Pmode) ? 1 : -1;
+ return small_symbolic_operand (x, Pmode) != 0;
}
rtx
-split_small_symbolic_mem_operand (x)
+split_small_symbolic_operand (x)
rtx x;
{
x = copy_insn (x);
- for_each_rtx (&x, split_small_symbolic_mem_operand_1, NULL);
+ for_each_rtx (&x, split_small_symbolic_operand_1, NULL);
return x;
}
static int
-split_small_symbolic_mem_operand_1 (px, data)
+split_small_symbolic_operand_1 (px, data)
rtx *px;
void *data ATTRIBUTE_UNUSED;
{
rtx x = *px;
- if (GET_CODE (x) != MEM)
- return 0;
-
- px = &XEXP (x, 0), x = *px;
- if (GET_CODE (x) == AND)
- px = &XEXP (x, 0), x = *px;
+ /* Don't re-split. */
+ if (GET_CODE (x) == LO_SUM)
+ return -1;
if (small_symbolic_operand (x, Pmode))
{
x = gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, x);
*px = x;
+ return -1;
}
- return -1;
+ return 0;
}
/* Try a machine-dependent way of reloading an illegitimate address
@@ -2236,15 +2228,39 @@ alpha_emit_set_const (target, mode, c, n)
HOST_WIDE_INT c;
int n;
{
- rtx pat;
+ rtx result = 0;
+ rtx orig_target = target;
int i;
+ /* If we can't make any pseudos, TARGET is an SImode hard register, we
+ can't load this constant in one insn, do this in DImode. */
+ if (no_new_pseudos && mode == SImode
+ && GET_CODE (target) == REG && REGNO (target) < FIRST_PSEUDO_REGISTER
+ && (result = alpha_emit_set_const_1 (target, mode, c, 1)) == 0)
+ {
+ target = gen_lowpart (DImode, target);
+ mode = DImode;
+ }
+
/* Try 1 insn, then 2, then up to N. */
for (i = 1; i <= n; i++)
- if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0)
- return pat;
+ {
+ result = alpha_emit_set_const_1 (target, mode, c, i);
+ if (result)
+ {
+ rtx insn = get_last_insn ();
+ rtx set = single_set (insn);
+ if (! CONSTANT_P (SET_SRC (set)))
+ set_unique_reg_note (get_last_insn (), REG_EQUAL, GEN_INT (c));
+ break;
+ }
+ }
- return 0;
+ /* Allow for the case where we changed the mode of TARGET. */
+ if (result == target)
+ result = orig_target;
+
+ return result;
}
/* Internal routine for the above to check for N or below insns. */
@@ -2260,18 +2276,8 @@ alpha_emit_set_const_1 (target, mode, c, n)
int i, bits;
/* Use a pseudo if highly optimizing and still generating RTL. */
rtx subtarget
- = (flag_expensive_optimizations && rtx_equal_function_value_matters
- ? 0 : target);
- rtx temp;
-
-#if HOST_BITS_PER_WIDE_INT == 64
- /* We are only called for SImode and DImode. If this is SImode, ensure that
- we are sign extended to a full word. This does not make any sense when
- cross-compiling on a narrow machine. */
-
- if (mode == SImode)
- c = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
-#endif
+ = (flag_expensive_optimizations && !no_new_pseudos ? 0 : target);
+ rtx temp, insn;
/* If this is a sign-extended 32-bit constant, we can do this in at most
three insns, so do it if we have enough insns left. We always have
@@ -2312,12 +2318,28 @@ alpha_emit_set_const_1 (target, mode, c, n)
{
temp = copy_to_suggested_reg (GEN_INT (high << 16), subtarget, mode);
+ /* As of 2002-02-23, addsi3 is only available when not optimizing.
+ This means that if we go through expand_binop, we'll try to
+ generate extensions, etc, which will require new pseudos, which
+ will fail during some split phases. The SImode add patterns
+ still exist, but are not named. So build the insns by hand. */
+
if (extra != 0)
- temp = expand_binop (mode, add_optab, temp, GEN_INT (extra << 16),
- subtarget, 0, OPTAB_WIDEN);
+ {
+ if (! subtarget)
+ subtarget = gen_reg_rtx (mode);
+ insn = gen_rtx_PLUS (mode, temp, GEN_INT (extra << 16));
+ insn = gen_rtx_SET (VOIDmode, subtarget, insn);
+ emit_insn (insn);
+ temp = subtarget;
+ }
- return expand_binop (mode, add_optab, temp, GEN_INT (low),
- target, 0, OPTAB_WIDEN);
+ if (target == NULL)
+ target = gen_reg_rtx (mode);
+ insn = gen_rtx_PLUS (mode, temp, GEN_INT (low));
+ insn = gen_rtx_SET (VOIDmode, target, insn);
+ emit_insn (insn);
+ return target;
}
}
@@ -2326,8 +2348,7 @@ alpha_emit_set_const_1 (target, mode, c, n)
we can't make pseudos, we can't do anything since the expand_binop
and expand_unop calls will widen and try to make pseudos. */
- if (n == 1
- || (mode == SImode && ! rtx_equal_function_value_matters))
+ if (n == 1 || (mode == SImode && no_new_pseudos))
return 0;
/* Next, see if we can load a related constant and then shift and possibly
@@ -2508,7 +2529,26 @@ alpha_expand_mov (mode, operands)
/* Allow legitimize_address to perform some simplifications. */
if (mode == Pmode && symbolic_operand (operands[1], mode))
{
- rtx tmp = alpha_legitimize_address (operands[1], operands[0], mode);
+ rtx tmp;
+
+ /* With RTL inlining, at -O3, rtl is generated, stored, then actually
+ compiled at the end of compilation. In the meantime, someone can
+ re-encode-section-info on some symbol changing it e.g. from global
+ to local-not-small. If this happens, we'd have emitted a plain
+ load rather than a high+losum load and not recognize the insn.
+
+ So if rtl inlining is in effect, we delay the global/not-global
+ decision until rest_of_compilation by wrapping it in an
+ UNSPEC_SYMBOL. */
+ if (TARGET_EXPLICIT_RELOCS && flag_inline_functions
+ && rtx_equal_function_value_matters
+ && global_symbolic_operand (operands[1], mode))
+ {
+ emit_insn (gen_movdi_er_maybe_g (operands[0], operands[1]));
+ return true;
+ }
+
+ tmp = alpha_legitimize_address (operands[1], operands[0], mode);
if (tmp)
{
operands[1] = tmp;
@@ -2784,21 +2824,29 @@ alpha_emit_conditional_branch (code)
1 true
Convert the compare against the raw return value. */
- if (code == UNORDERED || code == ORDERED)
- cmp_code = EQ;
- else
- cmp_code = code;
+ switch (code)
+ {
+ case UNORDERED:
+ cmp_code = EQ;
+ code = LT;
+ break;
+ case ORDERED:
+ cmp_code = EQ;
+ code = GE;
+ break;
+ case NE:
+ cmp_code = NE;
+ code = NE;
+ break;
+ default:
+ cmp_code = code;
+ code = GT;
+ break;
+ }
op0 = alpha_emit_xfloating_compare (cmp_code, op0, op1);
op1 = const0_rtx;
alpha_compare.fp_p = 0;
-
- if (code == UNORDERED)
- code = LT;
- else if (code == ORDERED)
- code = GE;
- else
- code = GT;
}
/* The general case: fold the comparison code to the types of compares
@@ -4985,7 +5033,10 @@ alpha_return_addr (count, frame)
rtx
alpha_gp_save_rtx ()
{
- return get_hard_reg_initial_val (DImode, 29);
+ rtx r = get_hard_reg_initial_val (DImode, 29);
+ if (GET_CODE (r) != MEM)
+ r = gen_mem_addressof (r, NULL_TREE);
+ return r;
}
static int
@@ -4993,10 +5044,6 @@ alpha_ra_ever_killed ()
{
rtx top;
-#ifdef ASM_OUTPUT_MI_THUNK
- if (current_function_is_thunk)
- return 0;
-#endif
if (!has_hard_reg_initial_val (Pmode, REG_RA))
return regs_ever_live[REG_RA];
@@ -5512,12 +5559,13 @@ alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
OPTAB_WIDEN);
temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
build_int_2 (2, 0), NULL_RTX, 1);
- temp = expand_and (gen_lowpart (SImode, temp), GEN_INT (0x3fff), 0);
+ 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 (temp1, GEN_INT (0xffffc000), NULL_RTX);
+ 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);
@@ -5759,9 +5807,8 @@ rtx
alpha_va_arg (valist, type)
tree valist, type;
{
- HOST_WIDE_INT tsize;
rtx addr;
- tree t;
+ tree t, type_size, rounded_size;
tree offset_field, base_field, addr_tree, addend;
tree wide_type, wide_ofs;
int indirect = 0;
@@ -5769,7 +5816,18 @@ alpha_va_arg (valist, type)
if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
return std_expand_builtin_va_arg (valist, type);
- tsize = ((TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT + 7) / 8) * 8;
+ if (type == error_mark_node
+ || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
+ || TREE_OVERFLOW (type_size))
+ rounded_size = size_zero_node;
+ else
+ rounded_size = fold (build (MULT_EXPR, sizetype,
+ fold (build (TRUNC_DIV_EXPR, sizetype,
+ fold (build (PLUS_EXPR, sizetype,
+ type_size,
+ size_int (7))),
+ size_int (8))),
+ size_int (8)));
base_field = TYPE_FIELDS (TREE_TYPE (valist));
offset_field = TREE_CHAIN (base_field);
@@ -5779,6 +5837,17 @@ alpha_va_arg (valist, type)
offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
valist, offset_field);
+ /* If the type could not be passed in registers, skip the block
+ reserved for the registers. */
+ if (MUST_PASS_IN_STACK (TYPE_MODE (type), type))
+ {
+ t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field,
+ build (MAX_EXPR, TREE_TYPE (offset_field),
+ offset_field, build_int_2 (6*8, 0)));
+ TREE_SIDE_EFFECTS (t) = 1;
+ expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ }
+
wide_type = make_signed_type (64);
wide_ofs = save_expr (build1 (CONVERT_EXPR, wide_type, offset_field));
@@ -5787,7 +5856,7 @@ alpha_va_arg (valist, type)
if (TYPE_MODE (type) == TFmode || TYPE_MODE (type) == TCmode)
{
indirect = 1;
- tsize = UNITS_PER_WORD;
+ rounded_size = size_int (UNITS_PER_WORD);
}
else if (FLOAT_TYPE_P (type))
{
@@ -5811,7 +5880,7 @@ alpha_va_arg (valist, type)
t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field,
build (PLUS_EXPR, TREE_TYPE (offset_field),
- offset_field, build_int_2 (tsize, 0)));
+ offset_field, rounded_size));
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -5835,7 +5904,8 @@ alpha_va_arg (valist, type)
descriptior to generate. */
/* Nonzero if we need a stack procedure. */
-static int alpha_is_stack_procedure;
+enum alpha_procedure_types {PT_NULL = 0, PT_REGISTER = 1, PT_STACK = 2};
+static enum alpha_procedure_types alpha_procedure_type;
/* Register number (either FP or SP) that is used to unwind the frame. */
static int vms_unwind_regno;
@@ -5859,43 +5929,48 @@ alpha_sa_mask (imaskP, fmaskP)
unsigned long fmask = 0;
unsigned int i;
-#ifdef ASM_OUTPUT_MI_THUNK
- if (!current_function_is_thunk)
-#endif
+ /* Irritatingly, there are two kinds of thunks -- those created with
+ ASM_OUTPUT_MI_THUNK and those with DECL_THUNK_P that go through
+ the regular part of the compiler. In the ASM_OUTPUT_MI_THUNK case
+ we don't have valid register life info, but assemble_start_function
+ wants to output .frame and .mask directives. */
+ if (current_function_is_thunk && !no_new_pseudos)
{
- if (TARGET_ABI_OPEN_VMS && alpha_is_stack_procedure)
- imask |= (1L << HARD_FRAME_POINTER_REGNUM);
+ *imaskP = 0;
+ *fmaskP = 0;
+ return;
+ }
- /* One for every register we have to save. */
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (! fixed_regs[i] && ! call_used_regs[i]
- && regs_ever_live[i] && i != REG_RA
- && (!TARGET_ABI_UNICOSMK || i != HARD_FRAME_POINTER_REGNUM))
- {
- if (i < 32)
- imask |= (1L << i);
- else
- fmask |= (1L << (i - 32));
- }
+ if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
+ imask |= (1L << HARD_FRAME_POINTER_REGNUM);
- /* We need to restore these for the handler. */
- if (current_function_calls_eh_return)
- {
- for (i = 0; ; ++i)
- {
- unsigned regno = EH_RETURN_DATA_REGNO (i);
- if (regno == INVALID_REGNUM)
- break;
- imask |= 1L << regno;
- }
- }
+ /* One for every register we have to save. */
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (! fixed_regs[i] && ! call_used_regs[i]
+ && regs_ever_live[i] && i != REG_RA
+ && (!TARGET_ABI_UNICOSMK || i != HARD_FRAME_POINTER_REGNUM))
+ {
+ if (i < 32)
+ imask |= (1L << i);
+ else
+ fmask |= (1L << (i - 32));
+ }
+
+ /* We need to restore these for the handler. */
+ if (current_function_calls_eh_return)
+ for (i = 0; ; ++i)
+ {
+ unsigned regno = EH_RETURN_DATA_REGNO (i);
+ if (regno == INVALID_REGNUM)
+ break;
+ imask |= 1L << regno;
+ }
- /* If any register spilled, then spill the return address also. */
- /* ??? This is required by the Digital stack unwind specification
- and isn't needed if we're doing Dwarf2 unwinding. */
- if (imask || fmask || alpha_ra_ever_killed ())
- imask |= (1L << REG_RA);
- }
+ /* If any register spilled, then spill the return address also. */
+ /* ??? This is required by the Digital stack unwind specification
+ and isn't needed if we're doing Dwarf2 unwinding. */
+ if (imask || fmask || alpha_ra_ever_killed ())
+ imask |= (1L << REG_RA);
*imaskP = imask;
*fmaskP = fmask;
@@ -5931,17 +6006,16 @@ alpha_sa_size ()
use alloca and have not determined that we need a frame for other
reasons. */
- alpha_is_stack_procedure = (sa_size
- || get_frame_size() != 0
- || current_function_outgoing_args_size
- || current_function_varargs
- || current_function_stdarg
- || current_function_calls_alloca
- || frame_pointer_needed);
+ alpha_procedure_type
+ = (sa_size || get_frame_size() != 0
+ || current_function_outgoing_args_size || current_function_varargs
+ || current_function_stdarg || current_function_calls_alloca
+ || frame_pointer_needed)
+ ? PT_STACK : PT_REGISTER;
/* Always reserve space for saving callee-saved registers if we
need a frame as required by the calling convention. */
- if (alpha_is_stack_procedure)
+ if (alpha_procedure_type == PT_STACK)
sa_size = 14;
}
else if (TARGET_ABI_OPEN_VMS)
@@ -5949,22 +6023,29 @@ alpha_sa_size ()
/* Start by assuming we can use a register procedure if we don't
make any calls (REG_RA not used) or need to save any
registers and a stack procedure if we do. */
- alpha_is_stack_procedure = ((mask[0] >> REG_RA) & 1);
+ if ((mask[0] >> REG_RA) & 1)
+ alpha_procedure_type = PT_STACK;
+ else if (get_frame_size() != 0)
+ alpha_procedure_type = PT_REGISTER;
+ else
+ alpha_procedure_type = PT_NULL;
- /* Don't reserve space for saving RA yet. Do that later after we've
+ /* Don't reserve space for saving FP & RA yet. Do that later after we've
made the final decision on stack procedure vs register procedure. */
- if (alpha_is_stack_procedure)
- sa_size--;
+ if (alpha_procedure_type == PT_STACK)
+ sa_size -= 2;
/* Decide whether to refer to objects off our PV via FP or PV.
If we need FP for something else or if we receive a nonlocal
goto (which expects PV to contain the value), we must use PV.
Otherwise, start by assuming we can use FP. */
- vms_base_regno = (frame_pointer_needed
- || current_function_has_nonlocal_label
- || alpha_is_stack_procedure
- || current_function_outgoing_args_size
- ? REG_PV : HARD_FRAME_POINTER_REGNUM);
+
+ vms_base_regno
+ = (frame_pointer_needed
+ || current_function_has_nonlocal_label
+ || alpha_procedure_type == PT_STACK
+ || current_function_outgoing_args_size)
+ ? REG_PV : HARD_FRAME_POINTER_REGNUM;
/* If we want to copy PV into FP, we need to find some register
in which to save FP. */
@@ -5975,15 +6056,17 @@ alpha_sa_size ()
if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
vms_save_fp_regno = i;
- if (vms_save_fp_regno == -1)
- vms_base_regno = REG_PV, alpha_is_stack_procedure = 1;
+ if (vms_save_fp_regno == -1 && alpha_procedure_type == PT_REGISTER)
+ vms_base_regno = REG_PV, alpha_procedure_type = PT_STACK;
+ else if (alpha_procedure_type == PT_NULL)
+ vms_base_regno = REG_PV;
/* Stack unwinding should be done via FP unless we use it for PV. */
vms_unwind_regno = (vms_base_regno == REG_PV
? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
/* If this is a stack procedure, allow space for saving FP and RA. */
- if (alpha_is_stack_procedure)
+ if (alpha_procedure_type == PT_STACK)
sa_size += 2;
}
else
@@ -6000,7 +6083,7 @@ int
alpha_pv_save_size ()
{
alpha_sa_size ();
- return alpha_is_stack_procedure ? 8 : 0;
+ return alpha_procedure_type == PT_STACK ? 8 : 0;
}
int
@@ -6043,10 +6126,8 @@ alpha_does_function_need_gp ()
if (TARGET_PROFILING_NEEDS_GP && current_function_profile)
return 1;
-#ifdef ASM_OUTPUT_MI_THUNK
if (current_function_is_thunk)
return 1;
-#endif
/* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
Even if we are a static function, we still need to do this in case
@@ -6151,13 +6232,13 @@ alpha_expand_prologue ()
frame_size = get_frame_size ();
if (TARGET_ABI_OPEN_VMS)
frame_size = ALPHA_ROUND (sa_size
- + (alpha_is_stack_procedure ? 8 : 0)
+ + (alpha_procedure_type == PT_STACK ? 8 : 0)
+ frame_size
+ current_function_pretend_args_size);
else if (TARGET_ABI_UNICOSMK)
/* We have to allocate space for the DSIB if we generate a frame. */
frame_size = ALPHA_ROUND (sa_size
- + (alpha_is_stack_procedure ? 48 : 0))
+ + (alpha_procedure_type == PT_STACK ? 48 : 0))
+ ALPHA_ROUND (frame_size
+ current_function_outgoing_args_size);
else
@@ -6312,7 +6393,7 @@ alpha_expand_prologue ()
}
/* Save regs in stack order. Beginning with VMS PV. */
- if (TARGET_ABI_OPEN_VMS && alpha_is_stack_procedure)
+ if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
{
mem = gen_rtx_MEM (DImode, stack_pointer_rtx);
set_mem_alias_set (mem, alpha_sr_alias_set);
@@ -6348,7 +6429,7 @@ alpha_expand_prologue ()
reg_offset += 8;
}
}
- else if (TARGET_ABI_UNICOSMK && alpha_is_stack_procedure)
+ else if (TARGET_ABI_UNICOSMK && alpha_procedure_type == PT_STACK)
{
/* The standard frame on the T3E includes space for saving registers.
We just have to use it. We don't have to save the return address and
@@ -6377,17 +6458,18 @@ alpha_expand_prologue ()
if (TARGET_ABI_OPEN_VMS)
{
- if (!alpha_is_stack_procedure)
- /* Register frame procedures save the fp. */
- /* ??? Ought to have a dwarf2 save for this. */
+ if (alpha_procedure_type == PT_REGISTER)
+ /* Register frame procedures save the fp.
+ ?? Ought to have a dwarf2 save for this. */
emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
hard_frame_pointer_rtx);
- if (vms_base_regno != REG_PV)
+ if (alpha_procedure_type != PT_NULL && vms_base_regno != REG_PV)
emit_insn (gen_force_movdi (gen_rtx_REG (DImode, vms_base_regno),
gen_rtx_REG (DImode, REG_PV)));
- if (vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
+ if (alpha_procedure_type != PT_NULL
+ && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
/* If we have to allocate space for outgoing args, do it now. */
@@ -6460,12 +6542,12 @@ alpha_start_function (file, fnname, decl)
frame_size = get_frame_size ();
if (TARGET_ABI_OPEN_VMS)
frame_size = ALPHA_ROUND (sa_size
- + (alpha_is_stack_procedure ? 8 : 0)
+ + (alpha_procedure_type == PT_STACK ? 8 : 0)
+ frame_size
+ current_function_pretend_args_size);
else if (TARGET_ABI_UNICOSMK)
frame_size = ALPHA_ROUND (sa_size
- + (alpha_is_stack_procedure ? 48 : 0))
+ + (alpha_procedure_type == PT_STACK ? 48 : 0))
+ ALPHA_ROUND (frame_size
+ current_function_outgoing_args_size);
else
@@ -6512,7 +6594,9 @@ alpha_start_function (file, fnname, decl)
/* If the function needs GP, we'll write the "..ng" label there.
Otherwise, do it here. */
- if (TARGET_ABI_OSF && ! alpha_function_needs_gp)
+ if (TARGET_ABI_OSF
+ && ! alpha_function_needs_gp
+ && ! current_function_is_thunk)
{
putc ('$', file);
assemble_name (file, fnname);
@@ -6583,7 +6667,7 @@ alpha_start_function (file, fnname, decl)
fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1L << REG_RA));
if (fmask)
fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
- if (!alpha_is_stack_procedure)
+ if (alpha_procedure_type == PT_REGISTER)
fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
}
else if (!flag_inhibit_size_directive)
@@ -6627,7 +6711,9 @@ alpha_start_function (file, fnname, decl)
ASM_OUTPUT_LABEL (file, fnname);
fprintf (file, "\t.pdesc ");
assemble_name (file, fnname);
- fprintf (file, "..en,%s\n", alpha_is_stack_procedure ? "stack" : "reg");
+ fprintf (file, "..en,%s\n",
+ alpha_procedure_type == PT_STACK ? "stack"
+ : alpha_procedure_type == PT_REGISTER ? "reg" : "null");
alpha_need_linkage (fnname, 1);
text_section ();
#endif
@@ -6646,7 +6732,8 @@ alpha_output_function_end_prologue (file)
else if (TARGET_ABI_WINDOWS_NT)
fputs ("\t.prologue 0\n", file);
else if (!flag_inhibit_size_directive)
- fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
+ fprintf (file, "\t.prologue %d\n",
+ alpha_function_needs_gp || current_function_is_thunk);
}
/* Write function epilogue. */
@@ -6680,12 +6767,12 @@ alpha_expand_epilogue ()
frame_size = get_frame_size ();
if (TARGET_ABI_OPEN_VMS)
frame_size = ALPHA_ROUND (sa_size
- + (alpha_is_stack_procedure ? 8 : 0)
+ + (alpha_procedure_type == PT_STACK ? 8 : 0)
+ frame_size
+ current_function_pretend_args_size);
else if (TARGET_ABI_UNICOSMK)
frame_size = ALPHA_ROUND (sa_size
- + (alpha_is_stack_procedure ? 48 : 0))
+ + (alpha_procedure_type == PT_STACK ? 48 : 0))
+ ALPHA_ROUND (frame_size
+ current_function_outgoing_args_size);
else
@@ -6695,14 +6782,20 @@ alpha_expand_epilogue ()
+ current_function_pretend_args_size));
if (TARGET_ABI_OPEN_VMS)
- reg_offset = 8;
+ {
+ if (alpha_procedure_type == PT_STACK)
+ reg_offset = 8;
+ else
+ reg_offset = 0;
+ }
else
reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
alpha_sa_mask (&imask, &fmask);
- fp_is_frame_pointer = ((TARGET_ABI_OPEN_VMS && alpha_is_stack_procedure)
- || (!TARGET_ABI_OPEN_VMS && frame_pointer_needed));
+ fp_is_frame_pointer
+ = ((TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
+ || (!TARGET_ABI_OPEN_VMS && frame_pointer_needed));
fp_offset = 0;
sa_reg = stack_pointer_rtx;
@@ -6769,7 +6862,7 @@ alpha_expand_epilogue ()
reg_offset += 8;
}
}
- else if (TARGET_ABI_UNICOSMK && alpha_is_stack_procedure)
+ else if (TARGET_ABI_UNICOSMK && alpha_procedure_type == PT_STACK)
{
/* Restore callee-saved general-purpose registers. */
@@ -6889,13 +6982,13 @@ alpha_expand_epilogue ()
}
else
{
- if (TARGET_ABI_OPEN_VMS && !alpha_is_stack_procedure)
+ if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_REGISTER)
{
emit_insn (gen_blockage ());
FRP (emit_move_insn (hard_frame_pointer_rtx,
gen_rtx_REG (DImode, vms_save_fp_regno)));
}
- else if (TARGET_ABI_UNICOSMK && !alpha_is_stack_procedure)
+ else if (TARGET_ABI_UNICOSMK && alpha_procedure_type != PT_STACK)
{
/* Decrement the frame pointer if the function does not have a
frame. */
@@ -6946,6 +7039,76 @@ alpha_end_function (file, fnname, decl)
unicosmk_output_deferred_case_vectors (file);
}
}
+
+/* Emit a tail call to FUNCTION after adjusting THIS by DELTA.
+
+ In order to avoid the hordes of differences between generated code
+ with and without TARGET_EXPLICIT_RELOCS, and to avoid duplicating
+ lots of code loading up large constants, generate rtl and emit it
+ instead of going straight to text.
+
+ Not sure why this idea hasn't been explored before... */
+
+void
+alpha_output_mi_thunk_osf (file, thunk_fndecl, delta, function)
+ FILE *file;
+ tree thunk_fndecl ATTRIBUTE_UNUSED;
+ HOST_WIDE_INT delta;
+ tree function;
+{
+ HOST_WIDE_INT hi, lo;
+ rtx this, insn, funexp;
+
+ /* We always require a valid GP. */
+ emit_insn (gen_prologue_ldgp ());
+ emit_note (NULL, NOTE_INSN_PROLOGUE_END);
+
+ /* Find the "this" pointer. If the function returns a structure,
+ the structure return pointer is in $16. */
+ if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function))))
+ this = gen_rtx_REG (Pmode, 17);
+ else
+ this = gen_rtx_REG (Pmode, 16);
+
+ /* Add DELTA. When possible we use ldah+lda. Otherwise load the
+ entire constant for the add. */
+ lo = ((delta & 0xffff) ^ 0x8000) - 0x8000;
+ hi = (((delta - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
+ if (hi + lo == delta)
+ {
+ if (hi)
+ emit_insn (gen_adddi3 (this, this, GEN_INT (hi)));
+ if (lo)
+ emit_insn (gen_adddi3 (this, this, GEN_INT (lo)));
+ }
+ else
+ {
+ rtx tmp = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 0),
+ delta, -(delta < 0));
+ emit_insn (gen_adddi3 (this, 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, const0_rtx));
+ SIBLING_CALL_P (insn) = 1;
+
+ /* 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 ();
+}
/* Debugging support. */
@@ -8628,7 +8791,7 @@ static void
unicosmk_gen_dsib (imaskP)
unsigned long * imaskP;
{
- if (alpha_is_stack_procedure)
+ if (alpha_procedure_type == PT_STACK)
{
const char *ssib_name;
rtx mem;
diff --git a/contrib/gcc/config/alpha/alpha.h b/contrib/gcc/config/alpha/alpha.h
index dd8d820..b2363bc 100644
--- a/contrib/gcc/config/alpha/alpha.h
+++ b/contrib/gcc/config/alpha/alpha.h
@@ -43,12 +43,6 @@ Boston, MA 02111-1307, USA. */
#define CPP_SUBTARGET_SPEC ""
#endif
-/* Set the spec to use for signed char. The default tests the above macro
- but DEC's compiler can't handle the conditional in a "constant"
- operand. */
-
-#define SIGNED_CHAR_SPEC "%{funsigned-char:-D__CHAR_UNSIGNED__}"
-
#define WORD_SWITCH_TAKES_ARG(STR) \
(!strcmp (STR, "rpath") || DEFAULT_WORD_SWITCH_TAKES_ARG(STR))
@@ -2079,7 +2073,8 @@ do { \
{"reg_no_subreg_operand", {REG}}, \
{"addition_operation", {PLUS}}, \
{"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST}}, \
- {"some_small_symbolic_mem_operand", {SET, PARALLEL}},
+ {"some_small_symbolic_operand", {SET, PARALLEL, PREFETCH, UNSPEC, \
+ UNSPEC_VOLATILE}},
/* Define the `__builtin_va_list' type for the ABI. */
#define BUILD_VA_LIST_TYPE(VALIST) \
@@ -2242,3 +2237,8 @@ do { \
/* Generate calls to memcpy, etc., not bcopy, etc. */
#define TARGET_MEM_FUNCTIONS 1
+
+/* 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) \
+ alpha_output_mi_thunk_osf (FILE, THUNK_FNDECL, DELTA, FUNCTION)
diff --git a/contrib/gcc/config/alpha/alpha.md b/contrib/gcc/config/alpha/alpha.md
index b987de8..785a61d 100644
--- a/contrib/gcc/config/alpha/alpha.md
+++ b/contrib/gcc/config/alpha/alpha.md
@@ -39,6 +39,7 @@
(UNSPEC_LITERAL 11)
(UNSPEC_LITUSE 12)
(UNSPEC_SIBCALL 13)
+ (UNSPEC_SYMBOL 14)
])
;; UNSPEC_VOLATILE:
@@ -518,31 +519,14 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(sign_extend:DI (match_dup 1)))]
"")
-;; Do addsi3 the way expand_binop would do if we didn't have one. This
-;; generates better code. We have the anonymous addsi3 pattern below in
-;; case combine wants to make it.
+;; Don't say we have addsi3 if optimizing. This generates better code. We
+;; have the anonymous addsi3 pattern below in case combine wants to make it.
(define_expand "addsi3"
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
(match_operand:SI 2 "add_operand" "")))]
- ""
-{
- if (optimize)
- {
- rtx op1 = gen_lowpart (DImode, operands[1]);
- rtx op2 = gen_lowpart (DImode, operands[2]);
-
- if (! cse_not_expected)
- {
- rtx tmp = gen_reg_rtx (DImode);
- emit_insn (gen_adddi3 (tmp, op1, op2));
- emit_move_insn (gen_lowpart (DImode, operands[0]), tmp);
- }
- else
- emit_insn (gen_adddi3 (gen_lowpart (DImode, operands[0]), op1, op2));
- DONE;
- }
-})
+ "! optimize"
+ "")
(define_insn "*addsi_internal"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
@@ -581,6 +565,17 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
addl %r1,%2,%0
subl %r1,%n2,%0")
+(define_insn "*addsi_se2"
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (sign_extend:DI
+ (subreg:SI (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
+ (match_operand:DI 2 "sext_add_operand" "rI,O"))
+ 0)))]
+ ""
+ "@
+ addl %r1,%2,%0
+ subl %r1,%n2,%0")
+
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(sign_extend:DI
@@ -844,24 +839,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
[(set (match_operand:SI 0 "register_operand" "")
(minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
(match_operand:SI 2 "reg_or_8bit_operand" "")))]
- ""
-{
- if (optimize)
- {
- rtx op1 = gen_lowpart (DImode, operands[1]);
- rtx op2 = gen_lowpart (DImode, operands[2]);
-
- if (! cse_not_expected)
- {
- rtx tmp = gen_reg_rtx (DImode);
- emit_insn (gen_subdi3 (tmp, op1, op2));
- emit_move_insn (gen_lowpart (DImode, operands[0]), tmp);
- }
- else
- emit_insn (gen_subdi3 (gen_lowpart (DImode, operands[0]), op1, op2));
- DONE;
- }
-})
+ "! optimize"
+ "")
(define_insn "*subsi_internal"
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -877,6 +856,15 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
""
"subl %r1,%2,%0")
+(define_insn "*subsi_se2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (sign_extend:DI
+ (subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
+ (match_operand:DI 2 "reg_or_8bit_operand" "rI"))
+ 0)))]
+ ""
+ "subl %r1,%2,%0")
+
(define_insn "subvsi3"
[(set (match_operand:SI 0 "register_operand" "=r")
(minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
@@ -1610,23 +1598,20 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
}
[(set_attr "type" "iadd,shift")])
-;; ??? The following pattern is made by combine, but earlier phases
-;; (specifically flow) can't handle it. This occurs in jump.c. Deal
-;; with this in a better way at some point.
-;;(define_insn ""
-;; [(set (match_operand:DI 0 "register_operand" "=r")
-;; (sign_extend:DI
-;; (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
-;; (match_operand:DI 2 "const_int_operand" "P"))
-;; 0)))]
-;; "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
-;;{
-;; if (operands[2] == const1_rtx)
-;; return "addl %r1,%r1,%0";
-;; else
-;; return "s%P2addl %r1,0,%0";
-;;}
-;; [(set_attr "type" "iadd")])
+(define_insn "*ashldi_se"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (sign_extend:DI
+ (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
+ (match_operand:DI 2 "const_int_operand" "P"))
+ 0)))]
+ "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
+{
+ if (operands[2] == const1_rtx)
+ return "addl %r1,%r1,%0";
+ else
+ return "s%P2addl %r1,0,%0";
+}
+ [(set_attr "type" "iadd")])
(define_insn "lshrdi3"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -5111,6 +5096,16 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
""
"call_pal 0x86"
[(set_attr "type" "ibr")])
+
+;; BUGCHK is documented common to OSF/1 and VMS PALcode.
+;; NT does not document anything at 0x81 -- presumably it would generate
+;; the equivalent of SIGILL, but this isn't that important.
+;; ??? Presuming unicosmk uses either OSF/1 or VMS PALcode.
+(define_insn "trap"
+ [(trap_if (const_int 1) (const_int 0))]
+ "!TARGET_ABI_WINDOWS_NT"
+ "call_pal 0x81"
+ [(set_attr "type" "ibr")])
;; Finally, we have the basic data motion insns. The byte and word insns
;; are done via define_expand. Start with the floating-point insns, since
@@ -5292,10 +5287,11 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
itofs %1,%0"
[(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")])
-(define_insn "*movsi_nt_vms"
+(define_insn "*movsi_nt_vms_nofix"
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m")
(match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f"))]
"(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS)
+ && !TARGET_FIX
&& (register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))"
"@
@@ -5310,6 +5306,27 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
st%, %R1,%0"
[(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
+(define_insn "*movsi_nt_vms_fix"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m,r,*f")
+ (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f,*f,r"))]
+ "(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS)
+ && TARGET_FIX
+ && (register_operand (operands[0], SImode)
+ || reg_or_0_operand (operands[1], SImode))"
+ "@
+ bis $31,%1,%0
+ lda %0,%1
+ ldah %0,%h1
+ lda %0,%1
+ ldl %0,%1
+ stl %r1,%0
+ cpys %R1,%R1,%0
+ ld%, %0,%1
+ st%, %R1,%0
+ ftois %1,%0
+ itofs %1,%0"
+ [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
+
(define_insn "*movhi_nobwx"
[(set (match_operand:HI 0 "register_operand" "=r,r")
(match_operand:HI 1 "input_operand" "rJ,n"))]
@@ -5501,10 +5518,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
"operands[2] = pic_offset_table_rtx;")
(define_split
- [(match_operand 0 "some_small_symbolic_mem_operand" "")]
+ [(match_operand 0 "some_small_symbolic_operand" "")]
"TARGET_EXPLICIT_RELOCS && reload_completed"
[(match_dup 0)]
- "operands[0] = split_small_symbolic_mem_operand (operands[0]);")
+ "operands[0] = split_small_symbolic_operand (operands[0]);")
(define_insn "movdi_er_high_g"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -5531,6 +5548,41 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(const_int 0)] UNSPEC_LITERAL))]
"operands[2] = pic_offset_table_rtx;")
+;; With RTL inlining, at -O3, rtl is generated, stored, then actually
+;; compiled at the end of compilation. In the meantime, someone can
+;; re-encode-section-info on some symbol changing it e.g. from global
+;; to local-not-small. If this happens, we'd have emitted a plain
+;; load rather than a high+losum load and not recognize the insn.
+;;
+;; So if rtl inlining is in effect, we delay the global/not-global
+;; decision until rest_of_compilation by wrapping it in an UNSPEC_SYMBOL.
+
+(define_insn_and_split "movdi_er_maybe_g"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
+ UNSPEC_SYMBOL))]
+ "TARGET_EXPLICIT_RELOCS && flag_inline_functions"
+ "#"
+ ""
+ [(set (match_dup 0) (match_dup 1))]
+{
+ if (local_symbolic_operand (operands[1], Pmode)
+ && !small_symbolic_operand (operands[1], Pmode))
+ {
+ rtx subtarget = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
+ rtx tmp;
+
+ tmp = gen_rtx_HIGH (Pmode, operands[1]);
+ if (reload_completed)
+ tmp = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmp);
+ emit_insn (gen_rtx_SET (VOIDmode, subtarget, tmp));
+
+ tmp = gen_rtx_LO_SUM (Pmode, subtarget, operands[1]);
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], tmp));
+ DONE;
+ }
+})
+
(define_insn "*movdi_er_nofix"
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q")
(match_operand:DI 1 "input_operand" "rJ,K,L,T,s,m,rJ,*fJ,Q,*f"))]
@@ -6700,13 +6752,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(set_attr "type" "multi")])
(define_insn "*exception_receiver_2"
- [(unspec_volatile [(match_operand:DI 0 "nonimmediate_operand" "r,m")]
- UNSPECV_EHR)]
+ [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_EHR)]
"TARGET_LD_BUGGY_LDGP"
- "@
- bis $31,%0,$29
- ldq $29,%0"
- [(set_attr "type" "ilog,ild")])
+ "ldq $29,%0"
+ [(set_attr "type" "ild")])
(define_expand "nonlocal_goto_receiver"
[(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
diff --git a/contrib/gcc/config/alpha/elf.h b/contrib/gcc/config/alpha/elf.h
index cf33a9e..05853c2 100644
--- a/contrib/gcc/config/alpha/elf.h
+++ b/contrib/gcc/config/alpha/elf.h
@@ -168,6 +168,16 @@ do { \
ASM_OUTPUT_SKIP((FILE), (SIZE)); \
} while (0)
+/* This says how to output assembler code to declare an
+ uninitialized external linkage data object. */
+
+#undef ASM_OUTPUT_ALIGNED_BSS
+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
+do { \
+ ASM_GLOBALIZE_LABEL (FILE, NAME); \
+ ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN); \
+} while (0)
+
/* Biggest alignment supported by the object file format of this
machine. Use this macro to limit the alignment which can be
specified using the `__attribute__ ((aligned (N)))' construct. If
@@ -473,11 +483,32 @@ do { \
/* This is how we tell the assembler that two symbols have the same value. */
#undef ASM_OUTPUT_DEF
-#define ASM_OUTPUT_DEF(FILE, NAME1, NAME2) \
- do { assemble_name(FILE, NAME1); \
- fputs(" = ", FILE); \
- assemble_name(FILE, NAME2); \
- fputc('\n', FILE); } while (0)
+#define ASM_OUTPUT_DEF(FILE, ALIAS, NAME) \
+ do { \
+ assemble_name(FILE, ALIAS); \
+ fputs(" = ", FILE); \
+ assemble_name(FILE, NAME); \
+ fputc('\n', FILE); \
+ } while (0)
+
+#undef ASM_OUTPUT_DEF_FROM_DECLS
+#define ASM_OUTPUT_DEF_FROM_DECLS(FILE, DECL, TARGET) \
+ do { \
+ const char *alias = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
+ const char *name = IDENTIFIER_POINTER (TARGET); \
+ if (TREE_CODE (DECL) == FUNCTION_DECL) \
+ { \
+ fputc ('$', FILE); \
+ assemble_name (FILE, alias); \
+ fputs ("..ng = $", FILE); \
+ assemble_name (FILE, name); \
+ fputs ("..ng\n", FILE); \
+ } \
+ assemble_name(FILE, alias); \
+ fputs(" = ", FILE); \
+ assemble_name(FILE, name); \
+ fputc('\n', FILE); \
+ } while (0)
/* The following macro defines the format used to output the second
operand of the .type assembler directive. Different svr4 assemblers
@@ -602,17 +633,14 @@ do { \
/* Provide a STARTFILE_SPEC appropriate for ELF. Here we add the
(even more) magical crtbegin.o file which provides part of the
support for getting C++ file-scope static object constructed
- before entering `main'.
+ before entering `main'. */
- Don't bother seeing crtstuff.c -- there is absolutely no hope
- of getting that file to understand multiple GPs. We provide a
- hand-coded assembly version. */
-
#undef STARTFILE_SPEC
#define STARTFILE_SPEC \
"%{!shared: \
%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\
- crti.o%s %{shared:crtbeginS.o%s}%{!shared:crtbegin.o%s}"
+ crti.o%s %{static:crtbeginT.o%s}\
+ %{!static:%{shared:crtbeginS.o%s}%{!shared:crtbegin.o%s}}"
/* Provide a ENDFILE_SPEC appropriate for ELF. Here we tack on the
magical crtend.o file which provides part of the support for
diff --git a/contrib/gcc/config/alpha/freebsd.h b/contrib/gcc/config/alpha/freebsd.h
index 351fb84..35a9e65 100644
--- a/contrib/gcc/config/alpha/freebsd.h
+++ b/contrib/gcc/config/alpha/freebsd.h
@@ -1,5 +1,5 @@
/* Definitions for DEC Alpha/AXP running FreeBSD using the ELF format
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2002 Free Software Foundation, Inc.
Contributed by David E. O'Brien <obrien@FreeBSD.org> and BSDi.
This file is part of GNU CC.
@@ -25,14 +25,14 @@ Boston, MA 02111-1307, USA. */
deal with the Alpha's FP issues. */
#undef CPP_SPEC
-#define CPP_SPEC "%(cpp_cpu) \
+#define CPP_SPEC "%(cpp_cpu) %(cpp_subtarget) -D__ELF__ \
%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} \
%{posix:-D_POSIX_SOURCE} \
%{mieee:-D_IEEE_FP} \
%{mieee-with-inexact:-D_IEEE_FP -D_IEEE_FP_INEXACT}"
#undef LINK_SPEC
-#define LINK_SPEC "-m elf64alpha %{G*} %{relax:-relax} \
+#define LINK_SPEC "%{G*} %{relax:-relax} \
%{p:%e`-p' not supported; use `-pg' and gprof(1)} \
%{Wl,*:%*} \
%{assert*} %{R*} %{rpath*} %{defsym*} \
@@ -44,16 +44,6 @@ Boston, MA 02111-1307, USA. */
%{!dynamic-linker:-dynamic-linker /usr/libexec/ld-elf.so.1}} \
%{static:-Bstatic}}"
-/* Provide an ASM_SPEC appropriate for a FreeBSD/Alpha target. This differs
- from the generic FreeBSD ASM_SPEC in that no special handling of PIC is
- necessary on the Alpha. */
-/* Per Richard Henderson <rth@cygnus.com>, it is better to use the `.arch'
- directive in the assembly file. alpha/elf.h gives us this in
- "ASM_FILE_START".
-#undef ASM_SPEC
-#define ASM_SPEC " %| %{mcpu=*:-m%*}"
-*/
-
/************************[ Target stuff ]***********************************/
@@ -65,18 +55,18 @@ Boston, MA 02111-1307, USA. */
#undef WCHAR_TYPE
#undef WCHAR_UNSIGNED
-#define WCHAR_UNSIGNED 0
+#define WCHAR_UNSIGNED 0
#undef WCHAR_TYPE_SIZE
-#define WCHAR_TYPE_SIZE 32
+#define WCHAR_TYPE_SIZE 32
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (FreeBSD/alpha ELF)");
-#define TARGET_ELF 1
+#define TARGET_ELF 1
#undef TARGET_DEFAULT
-#define TARGET_DEFAULT (MASK_FP | MASK_FPREGS | MASK_GAS)
+#define TARGET_DEFAULT (MASK_FP | MASK_FPREGS | MASK_GAS)
#undef HAS_INIT_SECTION
@@ -89,3 +79,9 @@ Boston, MA 02111-1307, USA. */
#undef DBX_CONTIN_CHAR
#define DBX_CONTIN_CHAR '?'
+
+/* Don't default to pcc-struct-return, we want to retain compatibility with
+ older FreeBSD releases AND pcc-struct-return may not be reentrant. */
+
+#undef DEFAULT_PCC_STRUCT_RETURN
+#define DEFAULT_PCC_STRUCT_RETURN 0
diff --git a/contrib/gcc/config/alpha/linux.h b/contrib/gcc/config/alpha/linux.h
index 8a1b93f..912d7b26 100644
--- a/contrib/gcc/config/alpha/linux.h
+++ b/contrib/gcc/config/alpha/linux.h
@@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler,
for Alpha Linux-based GNU systems.
- Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 2002 Free Software Foundation, Inc.
Contributed by Richard Henderson.
This file is part of GNU CC.
@@ -25,7 +25,7 @@ Boston, MA 02111-1307, USA. */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES \
-"-Dlinux -Dunix -Asystem=linux -D_LONGLONG -D__alpha__ " \
+"-D__gnu_linux__ -Dlinux -Dunix -Asystem=linux -D_LONGLONG -D__alpha__ " \
SUB_CPP_PREDEFINES
/* The GNU C++ standard library requires that these macros be defined. */
diff --git a/contrib/gcc/config/alpha/netbsd.h b/contrib/gcc/config/alpha/netbsd.h
index 7eacce2..e5551da 100644
--- a/contrib/gcc/config/alpha/netbsd.h
+++ b/contrib/gcc/config/alpha/netbsd.h
@@ -79,19 +79,5 @@ Boston, MA 02111-1307, USA. */
%{!shared:crtend%O%s} %{shared:crtendS%O%s}"
-/* Make gcc agree with <machine/ansi.h> */
-
-#undef WCHAR_TYPE
-#define WCHAR_TYPE "int"
-
-#undef WCHAR_UNSIGNED
-#define WCHAR_UNSIGNED 0
-
-#undef WCHAR_TYPE_SIZE
-#define WCHAR_TYPE_SIZE 32
-
-#undef WINT_TYPE
-#define WINT_TYPE "int"
-
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (NetBSD/alpha ELF)");
diff --git a/contrib/gcc/config/alpha/osf.h b/contrib/gcc/config/alpha/osf.h
index 250974c..efb0a16 100644
--- a/contrib/gcc/config/alpha/osf.h
+++ b/contrib/gcc/config/alpha/osf.h
@@ -47,7 +47,8 @@ Boston, MA 02111-1307, USA. */
#undef CPP_SUBTARGET_SPEC
#define CPP_SUBTARGET_SPEC \
-"%{pthread|threads:-D_REENTRANT} %{threads:-D_PTHREAD_USE_D4} %(cpp_xfloat)"
+"%{pthread|threads:-D_REENTRANT} %{threads:-D_PTHREAD_USE_D4} %(cpp_xfloat) \
+-D__EXTERN_PREFIX"
/* Under OSF4, -p and -pg require -lprof1, and -lprof1 requires -lpdf. */
@@ -56,12 +57,13 @@ Boston, MA 02111-1307, USA. */
%{threads: -lpthreads} %{pthread|threads: -lpthread -lmach -lexc} -lc"
/* Pass "-G 8" to ld because Alpha's CC does. Pass -O3 if we are
- optimizing, -O1 if we are not. Pass -shared, -non_shared or
+ optimizing, -O1 if we are not. Pass -S to silence `weak symbol
+ multiply defined' warnings. Pass -shared, -non_shared or
-call_shared as appropriate. Pass -hidden_symbol so that our
constructor and call-frame data structures are not accidentally
overridden. */
#define LINK_SPEC \
- "-G 8 %{O*:-O3} %{!O*:-O1} %{static:-non_shared} \
+ "-G 8 %{O*:-O3} %{!O*:-O1} -S %{static:-non_shared} \
%{!static:%{shared:-shared -hidden_symbol _GLOBAL_*} \
%{!shared:-call_shared}} %{pg} %{taso} %{rpath*}"
@@ -93,19 +95,18 @@ Boston, MA 02111-1307, USA. */
#define ASM_OLDAS_SPEC ""
-/* No point in running CPP on our assembler output. */
-#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_GAS) != 0
-/* Don't pass -g to GNU as, because some versions don't accept this option. */
-#define ASM_SPEC "%{malpha-as:-g %(asm_oldas)} -nocpp %{pg}"
-#else
/* In OSF/1 v3.2c, the assembler by default does not output file names which
causes mips-tfile to fail. Passing -g to the assembler fixes this problem.
??? Strictly speaking, we need -g only if the user specifies -g. Passing
it always means that we get slightly larger than necessary object files
if the user does not specify -g. If we don't pass -g, then mips-tfile
will need to be fixed to work in this case. Pass -O0 since some
- optimization are broken and don't help us anyway. */
-#define ASM_SPEC "%{!mgas:-g %(asm_oldas)} -nocpp %{pg} -O0"
+ optimization are broken and don't help us anyway. Pass -nocpp because
+ there's no point in running CPP on our assembler output. */
+#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_GAS) != 0
+#define ASM_SPEC "%{malpha-as:-g %(asm_oldas) -nocpp %{pg} -O0}"
+#else
+#define ASM_SPEC "%{!mgas:-g %(asm_oldas) -nocpp %{pg} -O0}"
#endif
/* Specify to run a post-processor, mips-tfile after the assembler
@@ -209,3 +210,7 @@ __enable_execute_stack (addr) \
/* Handle #pragma weak and #pragma pack. */
#undef HANDLE_SYSV_PRAGMA
#define HANDLE_SYSV_PRAGMA 1
+
+/* Handle #pragma extern_prefix. Technically only needed for Tru64 5.x,
+ but easier to manipulate preprocessor bits from here. */
+#define HANDLE_PRAGMA_EXTERN_PREFIX 1
diff --git a/contrib/gcc/config/alpha/t-vms b/contrib/gcc/config/alpha/t-vms
index 5057c31..516d3ec 100644
--- a/contrib/gcc/config/alpha/t-vms
+++ b/contrib/gcc/config/alpha/t-vms
@@ -20,3 +20,7 @@ vcrt0.o: $(CRT0_S) $(GCC_PASSES)
pcrt0.o: $(CRT0_S) $(GCC_PASSES)
decc -c /names=as_is $(srcdir)/config/alpha/vms-psxcrt0.c -o pcrt0.o
+MULTILIB_OPTIONS = mcpu=ev6
+MULTILIB_DIRNAMES = ev6
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
diff --git a/contrib/gcc/config/alpha/vms.h b/contrib/gcc/config/alpha/vms.h
index a01556e..ffc3275 100644
--- a/contrib/gcc/config/alpha/vms.h
+++ b/contrib/gcc/config/alpha/vms.h
@@ -251,6 +251,12 @@ typedef struct {int num_args; enum avms_arg_type atypes[6];} avms_arg_info;
alpha_write_verstamp (FILE); \
fprintf (FILE, "\t.set noreorder\n"); \
fprintf (FILE, "\t.set volatile\n"); \
+ if (TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX) \
+ { \
+ fprintf (FILE, "\t.arch %s\n", \
+ (TARGET_CPU_EV6 ? "ev6" \
+ : TARGET_MAX ? "pca56" : "ev56")); \
+ } \
ASM_OUTPUT_SOURCE_FILENAME (FILE, main_input_filename); \
}
@@ -385,22 +391,14 @@ do { \
#define LINK_EH_SPEC "vms-dwarf2eh.o%s "
#ifdef IN_LIBGCC2
-#include <libicb.h>
#include <pdscdef.h>
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
do { \
- unsigned long handle; \
- PDSCDEF *pv; \
- INVO_CONTEXT_BLK invo; \
+ PDSCDEF *pv = *((PDSCDEF **) (CONTEXT)->reg [29]); \
\
- memset (&invo, 0, sizeof (INVO_CONTEXT_BLK)); \
- \
- invo.libicb$q_ireg [29] = *((long long *) (CONTEXT)->reg [29]); \
- invo.libicb$q_ireg [30] = (long long) (CONTEXT)->cfa; \
- handle = LIB$GET_INVO_HANDLE (&invo); \
- LIB$GET_INVO_CONTEXT (handle, &invo); \
- pv = (PDSCDEF *) invo.libicb$ph_procedure_descriptor; \
+ if (pv && ((long) pv & 0x7) == 0) /* low bits 0 means address */ \
+ pv = *(PDSCDEF **) pv; \
\
if (pv && ((pv->pdsc$w_flags & 0xf) == PDSC$K_KIND_FP_STACK)) \
{ \
@@ -426,6 +424,19 @@ do { \
\
goto SUCCESS; \
} \
+ else if (pv && ((pv->pdsc$w_flags & 0xf) == PDSC$K_KIND_FP_REGISTER)) \
+ { \
+ (FS)->cfa_offset = pv->pdsc$l_size; \
+ (FS)->cfa_reg = pv->pdsc$w_flags & PDSC$M_BASE_REG_IS_FP ? 29 : 30; \
+ (FS)->retaddr_column = 26; \
+ (FS)->cfa_how = CFA_REG_OFFSET; \
+ (FS)->regs.reg[26].loc.reg = pv->pdsc$b_save_ra; \
+ (FS)->regs.reg[26].how = REG_SAVED_REG; \
+ (FS)->regs.reg[29].loc.reg = pv->pdsc$b_save_fp; \
+ (FS)->regs.reg[29].how = REG_SAVED_REG; \
+ \
+ goto SUCCESS; \
+ } \
} while (0)
#endif
@@ -508,11 +519,17 @@ do { \
#define NAME__MAIN "__gccmain"
#define SYMBOL__MAIN __gccmain
+#define MD_EXEC_PREFIX "/gnu/lib/gcc-lib/"
+#define MD_STARTFILE_PREFIX "/gnu/lib/gcc-lib/"
+
/* Specify the list of include file directories. */
-#define INCLUDE_DEFAULTS \
-{ \
- { "/gnu_gxx_include", 0, 1, 1 }, \
- { "/gnu_cc_include", 0, 0, 0 }, \
- { "/gnu/include", 0, 0, 0 }, \
- { 0, 0, 0, 0 } \
+#define INCLUDE_DEFAULTS \
+{ \
+ { "/gnu/lib/gcc-lib/include", 0, 0, 0 }, \
+ { "/gnu_gxx_include", 0, 1, 1 }, \
+ { "/gnu_cc_include", 0, 0, 0 }, \
+ { "/gnu/include", 0, 0, 0 }, \
+ { 0, 0, 0, 0 } \
}
+
+#define LONGLONG_STANDALONE 1
diff --git a/contrib/gcc/config/alpha/x-vms b/contrib/gcc/config/alpha/x-vms
index f53f1c7..c98f03d 100644
--- a/contrib/gcc/config/alpha/x-vms
+++ b/contrib/gcc/config/alpha/x-vms
@@ -1,6 +1,8 @@
# Under VMS, directory names cannot contain dots.
version:=$(shell echo $(gcc_version) | sed -e 's/\./_/g')
+libsubdir=$(libdir)/gcc-lib
+
# Rules for linker and compiler wrappers. These are only useful on
# a VMS host.
EXTRA_PROGRAMS=ld.exe decc.exe
diff --git a/contrib/gcc/config/alpha/xm-vms.h b/contrib/gcc/config/alpha/xm-vms.h
index d728ec1..7bfceba 100644
--- a/contrib/gcc/config/alpha/xm-vms.h
+++ b/contrib/gcc/config/alpha/xm-vms.h
@@ -37,6 +37,9 @@ Boston, MA 02111-1307, USA. */
/* Open files in stream mode if not otherwise explicitly specified */
#define __UNIX_FOPEN 1
+/* Write to stdout using fputc to avoid record terminators in pipes */
+#define __UNIX_FWRITE 1
+
#define STDC_HEADERS 1
#define HOST_EXECUTABLE_SUFFIX ".exe"
OpenPOWER on IntegriCloud