diff options
author | obrien <obrien@FreeBSD.org> | 2002-05-09 20:02:13 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2002-05-09 20:02:13 +0000 |
commit | c8f5fc7032940ad6633f932ac40cade82ec4d0cc (patch) | |
tree | 29a0f0a6c79a69ecc64f612947a0fe5904311713 /contrib/gcc/config/alpha | |
parent | c9ab9ae440a8066b2c2b85b157b1fdadcf09916a (diff) | |
download | FreeBSD-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.h | 6 | ||||
-rw-r--r-- | contrib/gcc/config/alpha/alpha.c | 469 | ||||
-rw-r--r-- | contrib/gcc/config/alpha/alpha.h | 14 | ||||
-rw-r--r-- | contrib/gcc/config/alpha/alpha.md | 179 | ||||
-rw-r--r-- | contrib/gcc/config/alpha/elf.h | 50 | ||||
-rw-r--r-- | contrib/gcc/config/alpha/freebsd.h | 30 | ||||
-rw-r--r-- | contrib/gcc/config/alpha/linux.h | 4 | ||||
-rw-r--r-- | contrib/gcc/config/alpha/netbsd.h | 14 | ||||
-rw-r--r-- | contrib/gcc/config/alpha/osf.h | 25 | ||||
-rw-r--r-- | contrib/gcc/config/alpha/t-vms | 4 | ||||
-rw-r--r-- | contrib/gcc/config/alpha/vms.h | 51 | ||||
-rw-r--r-- | contrib/gcc/config/alpha/x-vms | 2 | ||||
-rw-r--r-- | contrib/gcc/config/alpha/xm-vms.h | 3 |
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" |