diff options
author | kan <kan@FreeBSD.org> | 2003-11-07 02:43:04 +0000 |
---|---|---|
committer | kan <kan@FreeBSD.org> | 2003-11-07 02:43:04 +0000 |
commit | b09448931ae541a7a60fd1cf0ebac14b627fba69 (patch) | |
tree | 980c917e2cc50183c4d566d9a0f9a1c818e6a6cd /contrib/gcc/config/ia64 | |
parent | dc227ec3ae9a56f16c472206f51e4838bb53a644 (diff) | |
download | FreeBSD-src-b09448931ae541a7a60fd1cf0ebac14b627fba69.zip FreeBSD-src-b09448931ae541a7a60fd1cf0ebac14b627fba69.tar.gz |
Gcc 3.3.3 20031106.
Diffstat (limited to 'contrib/gcc/config/ia64')
-rw-r--r-- | contrib/gcc/config/ia64/hpux.h | 16 | ||||
-rw-r--r-- | contrib/gcc/config/ia64/ia64-protos.h | 3 | ||||
-rw-r--r-- | contrib/gcc/config/ia64/ia64.c | 194 | ||||
-rw-r--r-- | contrib/gcc/config/ia64/ia64.h | 56 | ||||
-rw-r--r-- | contrib/gcc/config/ia64/ia64.md | 20 | ||||
-rw-r--r-- | contrib/gcc/config/ia64/ia64intrin.h | 8 | ||||
-rw-r--r-- | contrib/gcc/config/ia64/libgcc-ia64.ver | 3 | ||||
-rw-r--r-- | contrib/gcc/config/ia64/unwind-ia64.c | 18 |
8 files changed, 223 insertions, 95 deletions
diff --git a/contrib/gcc/config/ia64/hpux.h b/contrib/gcc/config/ia64/hpux.h index 56c601b..90303ea 100644 --- a/contrib/gcc/config/ia64/hpux.h +++ b/contrib/gcc/config/ia64/hpux.h @@ -49,6 +49,13 @@ do { \ } \ } while (0) +#undef CPP_SPEC +#define CPP_SPEC \ + "%{mt|pthread:-D_REENTRANT -D_THREAD_SAFE -D_POSIX_C_SOURCE=199506L}" +/* aCC defines also -DRWSTD_MULTI_THREAD, -DRW_MULTI_THREAD. These + affect only aCC's C++ library (Rogue Wave-derived) which we do not + use, and they violate the user's name space. */ + #undef ASM_EXTRA_SPEC #define ASM_EXTRA_SPEC "%{milp32:-milp32} %{mlp64:-mlp64}" @@ -68,6 +75,7 @@ do { \ #undef LIB_SPEC #define LIB_SPEC \ "%{!shared: \ + %{mt|pthread:-lpthread} \ %{p:%{!mlp64:-L/usr/lib/hpux32/libp} \ %{mlp64:-L/usr/lib/hpux64/libp} -lprof} \ %{pg:%{!mlp64:-L/usr/lib/hpux32/libp} \ @@ -134,6 +142,10 @@ do { \ #undef TARGET_HPUX_LD #define TARGET_HPUX_LD 1 +/* The HPUX dynamic linker objects to weak symbols with no + definitions, so do not use them in gthr-posix.h. */ +#define GTHREAD_USE_WEAK 0 + /* Put out the needed function declarations at the end. */ #define ASM_FILE_END(STREAM) ia64_hpux_asm_file_end(STREAM) @@ -144,6 +156,10 @@ do { \ #undef DTORS_SECTION_ASM_OP #define DTORS_SECTION_ASM_OP "\t.section\t.fini_array,\t\"aw\",\"fini_array\"" +/* The init_array/fini_array technique does not permit the use of + initialization priorities. */ +#define SUPPORTS_INIT_PRIORITY 0 + #undef READONLY_DATA_SECTION_ASM_OP #define READONLY_DATA_SECTION_ASM_OP "\t.section\t.rodata,\t\"a\",\t\"progbits\"" diff --git a/contrib/gcc/config/ia64/ia64-protos.h b/contrib/gcc/config/ia64/ia64-protos.h index 72c2279..f25bb02 100644 --- a/contrib/gcc/config/ia64/ia64-protos.h +++ b/contrib/gcc/config/ia64/ia64-protos.h @@ -135,6 +135,9 @@ extern void ia64_override_options PARAMS((void)); extern int ia64_dbx_register_number PARAMS((int)); extern bool ia64_function_ok_for_sibcall PARAMS ((tree)); +extern rtx ia64_return_addr_rtx PARAMS ((HOST_WIDE_INT, rtx)); +extern void ia64_split_return_addr_rtx PARAMS ((rtx)); + #ifdef SDATA_SECTION_ASM_OP extern void sdata_section PARAMS ((void)); #endif diff --git a/contrib/gcc/config/ia64/ia64.c b/contrib/gcc/config/ia64/ia64.c index 0f34d8f..12f3204 100644 --- a/contrib/gcc/config/ia64/ia64.c +++ b/contrib/gcc/config/ia64/ia64.c @@ -175,8 +175,9 @@ static rtx ia64_expand_fetch_and_op PARAMS ((optab, enum machine_mode, tree, rtx)); static rtx ia64_expand_op_and_fetch PARAMS ((optab, enum machine_mode, tree, rtx)); -static rtx ia64_expand_compare_and_swap PARAMS ((enum machine_mode, int, - tree, rtx)); +static rtx ia64_expand_compare_and_swap PARAMS ((enum machine_mode, + enum machine_mode, + int, tree, rtx)); static rtx ia64_expand_lock_test_and_set PARAMS ((enum machine_mode, tree, rtx)); static rtx ia64_expand_lock_release PARAMS ((enum machine_mode, tree, rtx)); @@ -1154,6 +1155,7 @@ ia64_expand_move (op0, op1) if ((tls_kind = tls_symbolic_operand (op1, Pmode))) { rtx tga_op1, tga_op2, tga_ret, tga_eqv, tmp, insns; + rtx orig_op0 = op0; switch (tls_kind) { @@ -1177,8 +1179,10 @@ ia64_expand_move (op0, op1) insns = get_insns (); end_sequence (); + if (GET_MODE (op0) != Pmode) + op0 = tga_ret; emit_libcall_block (insns, op0, tga_ret, op1); - return NULL_RTX; + break; case TLS_MODEL_LOCAL_DYNAMIC: /* ??? This isn't the completely proper way to do local-dynamic @@ -1206,20 +1210,15 @@ ia64_expand_move (op0, op1) tmp = gen_reg_rtx (Pmode); emit_libcall_block (insns, tmp, tga_ret, tga_eqv); - if (register_operand (op0, Pmode)) - tga_ret = op0; - else - tga_ret = gen_reg_rtx (Pmode); + if (!register_operand (op0, Pmode)) + op0 = gen_reg_rtx (Pmode); if (TARGET_TLS64) { - emit_insn (gen_load_dtprel (tga_ret, op1)); - emit_insn (gen_adddi3 (tga_ret, tmp, tga_ret)); + emit_insn (gen_load_dtprel (op0, op1)); + emit_insn (gen_adddi3 (op0, tmp, op0)); } else - emit_insn (gen_add_dtprel (tga_ret, tmp, op1)); - if (tga_ret == op0) - return NULL_RTX; - op1 = tga_ret; + emit_insn (gen_add_dtprel (op0, tmp, op1)); break; case TLS_MODEL_INITIAL_EXEC: @@ -1229,35 +1228,32 @@ ia64_expand_move (op0, op1) RTX_UNCHANGING_P (tmp) = 1; tmp = force_reg (Pmode, tmp); - if (register_operand (op0, Pmode)) - op1 = op0; - else - op1 = gen_reg_rtx (Pmode); - emit_insn (gen_adddi3 (op1, tmp, gen_thread_pointer ())); - if (op1 == op0) - return NULL_RTX; + if (!register_operand (op0, Pmode)) + op0 = gen_reg_rtx (Pmode); + emit_insn (gen_adddi3 (op0, tmp, gen_thread_pointer ())); break; case TLS_MODEL_LOCAL_EXEC: - if (register_operand (op0, Pmode)) - tmp = op0; - else - tmp = gen_reg_rtx (Pmode); + if (!register_operand (op0, Pmode)) + op0 = gen_reg_rtx (Pmode); if (TARGET_TLS64) { - emit_insn (gen_load_tprel (tmp, op1)); - emit_insn (gen_adddi3 (tmp, gen_thread_pointer (), tmp)); + emit_insn (gen_load_tprel (op0, op1)); + emit_insn (gen_adddi3 (op0, gen_thread_pointer (), op0)); } else - emit_insn (gen_add_tprel (tmp, gen_thread_pointer (), op1)); - if (tmp == op0) - return NULL_RTX; - op1 = tmp; + emit_insn (gen_add_tprel (op0, gen_thread_pointer (), op1)); break; default: abort (); } + + if (orig_op0 == op0) + return NULL_RTX; + if (GET_MODE (orig_op0) == Pmode) + return op0; + return gen_lowpart (GET_MODE (orig_op0), op0); } else if (!TARGET_NO_PIC && (symbolic_operand (op1, Pmode) || @@ -2015,10 +2011,6 @@ ia64_initial_elimination_offset (from, to) abort (); break; - case RETURN_ADDRESS_POINTER_REGNUM: - offset = 0; - break; - default: abort (); } @@ -2369,17 +2361,6 @@ ia64_expand_prologue () reg_names[current_frame_info.reg_fp] = tmp; } - /* Fix up the return address placeholder. */ - /* ??? We can fail if __builtin_return_address is used, and we didn't - allocate a register in which to save b0. I can't think of a way to - eliminate RETURN_ADDRESS_POINTER_REGNUM to a local register and - then be sure that I got the right one. Further, reload doesn't seem - to care if an eliminable register isn't used, and "eliminates" it - anyway. */ - if (regs_ever_live[RETURN_ADDRESS_POINTER_REGNUM] - && current_frame_info.reg_save_b0 != 0) - XINT (return_address_pointer_rtx, 0) = current_frame_info.reg_save_b0; - /* We don't need an alloc instruction if we've used no outputs or locals. */ if (current_frame_info.n_local_regs == 0 && current_frame_info.n_output_regs == 0 @@ -2936,6 +2917,72 @@ ia64_direct_return () return 0; } +/* Return the magic cookie that we use to hold the return address + during early compilation. */ + +rtx +ia64_return_addr_rtx (count, frame) + HOST_WIDE_INT count; + rtx frame ATTRIBUTE_UNUSED; +{ + if (count != 0) + return NULL; + return gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_RET_ADDR); +} + +/* Split this value after reload, now that we know where the return + address is saved. */ + +void +ia64_split_return_addr_rtx (dest) + rtx dest; +{ + rtx src; + + if (TEST_HARD_REG_BIT (current_frame_info.mask, BR_REG (0))) + { + if (current_frame_info.reg_save_b0 != 0) + src = gen_rtx_REG (DImode, current_frame_info.reg_save_b0); + else + { + HOST_WIDE_INT off; + unsigned int regno; + + /* Compute offset from CFA for BR0. */ + /* ??? Must be kept in sync with ia64_expand_prologue. */ + off = (current_frame_info.spill_cfa_off + + current_frame_info.spill_size); + for (regno = GR_REG (1); regno <= GR_REG (31); ++regno) + if (TEST_HARD_REG_BIT (current_frame_info.mask, regno)) + off -= 8; + + /* Convert CFA offset to a register based offset. */ + if (frame_pointer_needed) + src = hard_frame_pointer_rtx; + else + { + src = stack_pointer_rtx; + off += current_frame_info.total_size; + } + + /* Load address into scratch register. */ + if (CONST_OK_FOR_I (off)) + emit_insn (gen_adddi3 (dest, src, GEN_INT (off))); + else + { + emit_move_insn (dest, GEN_INT (off)); + emit_insn (gen_adddi3 (dest, src, dest)); + } + + src = gen_rtx_MEM (Pmode, dest); + } + } + else + src = gen_rtx_REG (DImode, BR_REG (0)); + + emit_move_insn (dest, src); +} + int ia64_hard_regno_rename_ok (from, to) int from; @@ -3085,9 +3132,6 @@ ia64_output_function_epilogue (file, size) { int i; - /* Reset from the function's potential modifications. */ - XINT (return_address_pointer_rtx, 0) = RETURN_ADDRESS_POINTER_REGNUM; - if (current_frame_info.reg_fp) { const char *tmp = reg_names[HARD_FRAME_POINTER_REGNUM]; @@ -7060,7 +7104,8 @@ ia64_emit_nops () { while (bundle_pos < 3) { - emit_insn_before (gen_nop_type (b->t[bundle_pos]), insn); + if (b->t[bundle_pos] != TYPE_L) + emit_insn_before (gen_nop_type (b->t[bundle_pos]), insn); bundle_pos++; } continue; @@ -7666,11 +7711,16 @@ ia64_init_builtins () psi_type_node, integer_type_node, integer_type_node, NULL_TREE); - /* __sync_val_compare_and_swap_di, __sync_bool_compare_and_swap_di */ + /* __sync_val_compare_and_swap_di */ tree di_ftype_pdi_di_di = build_function_type_list (long_integer_type_node, pdi_type_node, long_integer_type_node, long_integer_type_node, NULL_TREE); + /* __sync_bool_compare_and_swap_di */ + tree si_ftype_pdi_di_di + = build_function_type_list (integer_type_node, + pdi_type_node, long_integer_type_node, + long_integer_type_node, NULL_TREE); /* __sync_synchronize */ tree void_ftype_void = build_function_type (void_type_node, void_list_node); @@ -7703,7 +7753,7 @@ ia64_init_builtins () IA64_BUILTIN_VAL_COMPARE_AND_SWAP_DI); def_builtin ("__sync_bool_compare_and_swap_si", si_ftype_psi_si_si, IA64_BUILTIN_BOOL_COMPARE_AND_SWAP_SI); - def_builtin ("__sync_bool_compare_and_swap_di", di_ftype_pdi_di_di, + def_builtin ("__sync_bool_compare_and_swap_di", si_ftype_pdi_di_di, IA64_BUILTIN_BOOL_COMPARE_AND_SWAP_DI); def_builtin ("__sync_synchronize", void_ftype_void, @@ -7943,7 +7993,8 @@ ia64_expand_op_and_fetch (binoptab, mode, arglist, target) */ static rtx -ia64_expand_compare_and_swap (mode, boolp, arglist, target) +ia64_expand_compare_and_swap (rmode, mode, boolp, arglist, target) + enum machine_mode rmode; enum machine_mode mode; int boolp; tree arglist; @@ -7991,7 +8042,7 @@ ia64_expand_compare_and_swap (mode, boolp, arglist, target) if (boolp) { if (! target) - target = gen_reg_rtx (mode); + target = gen_reg_rtx (rmode); return emit_store_flag_force (target, EQ, tmp, old, mode, 1, 1); } else @@ -8066,11 +8117,16 @@ ia64_expand_builtin (exp, target, subtarget, mode, ignore) tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); unsigned int fcode = DECL_FUNCTION_CODE (fndecl); tree arglist = TREE_OPERAND (exp, 1); + enum machine_mode rmode = VOIDmode; switch (fcode) { case IA64_BUILTIN_BOOL_COMPARE_AND_SWAP_SI: case IA64_BUILTIN_VAL_COMPARE_AND_SWAP_SI: + mode = SImode; + rmode = SImode; + break; + case IA64_BUILTIN_LOCK_TEST_AND_SET_SI: case IA64_BUILTIN_LOCK_RELEASE_SI: case IA64_BUILTIN_FETCH_AND_ADD_SI: @@ -8089,7 +8145,15 @@ ia64_expand_builtin (exp, target, subtarget, mode, ignore) break; case IA64_BUILTIN_BOOL_COMPARE_AND_SWAP_DI: + mode = DImode; + rmode = SImode; + break; + case IA64_BUILTIN_VAL_COMPARE_AND_SWAP_DI: + mode = DImode; + rmode = DImode; + break; + case IA64_BUILTIN_LOCK_TEST_AND_SET_DI: case IA64_BUILTIN_LOCK_RELEASE_DI: case IA64_BUILTIN_FETCH_AND_ADD_DI: @@ -8115,11 +8179,13 @@ ia64_expand_builtin (exp, target, subtarget, mode, ignore) { case IA64_BUILTIN_BOOL_COMPARE_AND_SWAP_SI: case IA64_BUILTIN_BOOL_COMPARE_AND_SWAP_DI: - return ia64_expand_compare_and_swap (mode, 1, arglist, target); + return ia64_expand_compare_and_swap (rmode, mode, 1, arglist, + target); case IA64_BUILTIN_VAL_COMPARE_AND_SWAP_SI: case IA64_BUILTIN_VAL_COMPARE_AND_SWAP_DI: - return ia64_expand_compare_and_swap (mode, 0, arglist, target); + return ia64_expand_compare_and_swap (rmode, mode, 0, arglist, + target); case IA64_BUILTIN_SYNCHRONIZE: emit_insn (gen_mf ()); @@ -8368,6 +8434,9 @@ ia64_output_mi_thunk (file, thunk, delta, vcall_offset, function) emit_note (NULL, NOTE_INSN_PROLOGUE_END); this = gen_rtx_REG (Pmode, IN_REG (0)); + if (TARGET_ILP32) + emit_insn (gen_ptr_extend (this, + gen_rtx_REG (ptr_mode, IN_REG (0)))); /* Apply the constant offset, if required. */ if (delta) @@ -8389,7 +8458,14 @@ ia64_output_mi_thunk (file, thunk, delta, vcall_offset, function) rtx vcall_offset_rtx = GEN_INT (vcall_offset); rtx tmp = gen_rtx_REG (Pmode, 2); - emit_move_insn (tmp, gen_rtx_MEM (Pmode, this)); + if (TARGET_ILP32) + { + rtx t = gen_rtx_REG (ptr_mode, 2); + emit_move_insn (t, gen_rtx_MEM (ptr_mode, this)); + emit_insn (gen_ptr_extend (tmp, t)); + } + else + emit_move_insn (tmp, gen_rtx_MEM (Pmode, this)); if (!CONST_OK_FOR_J (vcall_offset)) { @@ -8399,7 +8475,11 @@ ia64_output_mi_thunk (file, thunk, delta, vcall_offset, function) } emit_insn (gen_adddi3 (tmp, tmp, vcall_offset_rtx)); - emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp)); + if (TARGET_ILP32) + emit_move_insn (gen_rtx_REG (ptr_mode, 2), + gen_rtx_MEM (ptr_mode, tmp)); + else + emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp)); emit_insn (gen_adddi3 (this, this, tmp)); } diff --git a/contrib/gcc/config/ia64/ia64.h b/contrib/gcc/config/ia64/ia64.h index 724405a..60d0143 100644 --- a/contrib/gcc/config/ia64/ia64.h +++ b/contrib/gcc/config/ia64/ia64.h @@ -436,7 +436,7 @@ while (0) 64 predicate registers, 8 branch registers, one frame pointer, and several "application" registers. */ -#define FIRST_PSEUDO_REGISTER 335 +#define FIRST_PSEUDO_REGISTER 334 /* Ranges for the various kinds of registers. */ #define ADDL_REGNO_P(REGNO) ((unsigned HOST_WIDE_INT) (REGNO) <= 3) @@ -445,9 +445,7 @@ while (0) #define PR_REGNO_P(REGNO) ((REGNO) >= 256 && (REGNO) <= 319) #define BR_REGNO_P(REGNO) ((REGNO) >= 320 && (REGNO) <= 327) #define GENERAL_REGNO_P(REGNO) \ - (GR_REGNO_P (REGNO) \ - || (REGNO) == FRAME_POINTER_REGNUM \ - || (REGNO) == RETURN_ADDRESS_POINTER_REGNUM) + (GR_REGNO_P (REGNO) || (REGNO) == FRAME_POINTER_REGNUM) #define GR_REG(REGNO) ((REGNO) + 0) #define FR_REG(REGNO) ((REGNO) + 128) @@ -457,11 +455,11 @@ while (0) #define IN_REG(REGNO) ((REGNO) + 112) #define LOC_REG(REGNO) ((REGNO) + 32) -#define AR_CCV_REGNUM 330 -#define AR_UNAT_REGNUM 331 -#define AR_PFS_REGNUM 332 -#define AR_LC_REGNUM 333 -#define AR_EC_REGNUM 334 +#define AR_CCV_REGNUM 329 +#define AR_UNAT_REGNUM 330 +#define AR_PFS_REGNUM 331 +#define AR_LC_REGNUM 332 +#define AR_EC_REGNUM 333 #define IN_REGNO_P(REGNO) ((REGNO) >= IN_REG (0) && (REGNO) <= IN_REG (7)) #define LOC_REGNO_P(REGNO) ((REGNO) >= LOC_REG (0) && (REGNO) <= LOC_REG (79)) @@ -524,8 +522,8 @@ while (0) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ /* Branch registers. */ \ 0, 0, 0, 0, 0, 0, 0, 0, \ - /*FP RA CCV UNAT PFS LC EC */ \ - 1, 1, 1, 1, 1, 0, 1 \ + /*FP CCV UNAT PFS LC EC */ \ + 1, 1, 1, 1, 0, 1 \ } /* Like `FIXED_REGISTERS' but has 1 for each register that is clobbered @@ -559,8 +557,8 @@ while (0) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ /* Branch registers. */ \ 1, 0, 0, 0, 0, 0, 1, 1, \ - /*FP RA CCV UNAT PFS LC EC */ \ - 1, 1, 1, 1, 1, 0, 1 \ + /*FP CCV UNAT PFS LC EC */ \ + 1, 1, 1, 1, 0, 1 \ } /* Like `CALL_USED_REGISTERS' but used to overcome a historical @@ -597,8 +595,8 @@ while (0) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ /* Branch registers. */ \ 1, 0, 0, 0, 0, 0, 1, 1, \ - /*FP RA CCV UNAT PFS LC EC */ \ - 0, 0, 1, 0, 1, 0, 0 \ + /*FP CCV UNAT PFS LC EC */ \ + 0, 1, 0, 1, 0, 0 \ } @@ -744,7 +742,7 @@ while (0) /* Special branch registers. */ \ R_BR (0), \ /* Other fixed registers. */ \ - FRAME_POINTER_REGNUM, RETURN_ADDRESS_POINTER_REGNUM, \ + FRAME_POINTER_REGNUM, \ AR_CCV_REGNUM, AR_UNAT_REGNUM, AR_PFS_REGNUM, AR_LC_REGNUM, \ AR_EC_REGNUM \ } @@ -873,11 +871,11 @@ enum reg_class /* AR_M_REGS. */ \ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ - 0x00000000, 0x00000000, 0x0C00 }, \ + 0x00000000, 0x00000000, 0x0600 }, \ /* AR_I_REGS. */ \ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ - 0x00000000, 0x00000000, 0x7000 }, \ + 0x00000000, 0x00000000, 0x3800 }, \ /* ADDL_REGS. */ \ { 0x0000000F, 0x00000000, 0x00000000, 0x00000000, \ 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ @@ -885,7 +883,7 @@ enum reg_class /* GR_REGS. */ \ { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \ 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ - 0x00000000, 0x00000000, 0x0300 }, \ + 0x00000000, 0x00000000, 0x0100 }, \ /* FR_REGS. */ \ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \ @@ -893,15 +891,15 @@ enum reg_class /* GR_AND_BR_REGS. */ \ { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \ 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ - 0x00000000, 0x00000000, 0x03FF }, \ + 0x00000000, 0x00000000, 0x01FF }, \ /* GR_AND_FR_REGS. */ \ { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \ - 0x00000000, 0x00000000, 0x0300 }, \ + 0x00000000, 0x00000000, 0x0100 }, \ /* ALL_REGS. */ \ { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \ - 0xFFFFFFFF, 0xFFFFFFFF, 0x7FFF }, \ + 0xFFFFFFFF, 0xFFFFFFFF, 0x3FFF }, \ } /* A C expression whose value is a register class containing hard register @@ -1119,7 +1117,7 @@ enum reg_class DYNAMIC_CHAIN_ADDRESS and SETUP_FRAME_ADDRESS (for the reg stack flush). */ #define RETURN_ADDR_RTX(COUNT, FRAME) \ - ((COUNT) == 0 ? return_address_pointer_rtx : const0_rtx) + ia64_return_addr_rtx (COUNT, FRAME) /* A C expression whose value is RTL representing the location of the incoming return address at the beginning of any function, before the prologue. This @@ -1180,13 +1178,6 @@ enum reg_class REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) = 64; \ } while (0) -/* The register number for the return address register. For IA-64, this - is not actually a pointer as the name suggests, but that's a name that - gen_rtx_REG already takes care to keep unique. We modify - return_address_pointer_rtx in ia64_expand_prologue to reference the - final output regnum. */ -#define RETURN_ADDRESS_POINTER_REGNUM 329 - /* Register numbers used for passing a function's static chain pointer. */ /* ??? The ABI sez the static chain should be passed as a normal parameter. */ #define STATIC_CHAIN_REGNUM 15 @@ -1210,7 +1201,6 @@ enum reg_class {ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \ {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ {FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \ - {RETURN_ADDRESS_POINTER_REGNUM, BR_REG (0)}, \ } /* A C expression that returns nonzero if the compiler is allowed to try to @@ -1934,8 +1924,8 @@ do { \ "p60", "p61", "p62", "p63", \ /* Branch registers. */ \ "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", \ - /* Frame pointer. Return address. */ \ - "sfp", "retaddr", "ar.ccv", "ar.unat", "ar.pfs", "ar.lc", "ar.ec", \ + /* Frame pointer. Application registers. */ \ + "sfp", "ar.ccv", "ar.unat", "ar.pfs", "ar.lc", "ar.ec", \ } /* If defined, a C initializer for an array of structures containing a name and diff --git a/contrib/gcc/config/ia64/ia64.md b/contrib/gcc/config/ia64/ia64.md index 4baa5d3..3b88d9f 100644 --- a/contrib/gcc/config/ia64/ia64.md +++ b/contrib/gcc/config/ia64/ia64.md @@ -73,6 +73,7 @@ (UNSPEC_BUNDLE_SELECTOR 23) (UNSPEC_ADDP4 24) (UNSPEC_PROLOGUE_USE 25) + (UNSPEC_RET_ADDR 26) ]) (define_constants @@ -416,6 +417,25 @@ DONE; }) +;; This is used as a placeholder for the return address during early +;; compilation. We won't know where we've placed this until during +;; reload, at which point it can wind up in b0, a general register, +;; or memory. The only safe destination under these conditions is a +;; general register. + +(define_insn_and_split "*movdi_ret_addr" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(const_int 0)] UNSPEC_RET_ADDR))] + "" + "#" + "reload_completed" + [(const_int 0)] +{ + ia64_split_return_addr_rtx (operands[0]); + DONE; +} + [(set_attr "itanium_class" "ialu")]) + (define_insn "*movdi_internal" [(set (match_operand:DI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b, r,*e, r,*d, r,*c") diff --git a/contrib/gcc/config/ia64/ia64intrin.h b/contrib/gcc/config/ia64/ia64intrin.h index c7bbd33..262dc20 100644 --- a/contrib/gcc/config/ia64/ia64intrin.h +++ b/contrib/gcc/config/ia64/ia64intrin.h @@ -19,13 +19,11 @@ extern long __sync_val_compare_and_swap_di (long *, long, long); __sync_val_compare_and_swap_di((long *)(PTR),(long)(OLD),(long)(NEW))) extern int __sync_bool_compare_and_swap_si (int *, int, int); -extern long __sync_bool_compare_and_swap_di (long *, long, long); +extern int __sync_bool_compare_and_swap_di (long *, long, long); #define __sync_bool_compare_and_swap(PTR, OLD, NEW) \ ((sizeof (*(PTR)) == sizeof(int)) \ - ? (__typeof__(*(PTR))) \ - __sync_bool_compare_and_swap_si((int *)(PTR),(int)(OLD),(int)(NEW)) \ - : (__typeof__(*(PTR))) \ - __sync_bool_compare_and_swap_di((long *)(PTR),(long)(OLD),(long)(NEW))) + ? __sync_bool_compare_and_swap_si((int *)(PTR),(int)(OLD),(int)(NEW)) \ + : __sync_bool_compare_and_swap_di((long *)(PTR),(long)(OLD),(long)(NEW))) extern void __sync_lock_release_si (int *); extern void __sync_lock_release_di (long *); diff --git a/contrib/gcc/config/ia64/libgcc-ia64.ver b/contrib/gcc/config/ia64/libgcc-ia64.ver index 2ffb693..cd76990 100644 --- a/contrib/gcc/config/ia64/libgcc-ia64.ver +++ b/contrib/gcc/config/ia64/libgcc-ia64.ver @@ -7,3 +7,6 @@ GCC_3.0 { __ia64_trampoline __ia64_backtrace } +GCC_3.3.2 { + _Unwind_GetBSP +} diff --git a/contrib/gcc/config/ia64/unwind-ia64.c b/contrib/gcc/config/ia64/unwind-ia64.c index 12e46ae..88d236b 100644 --- a/contrib/gcc/config/ia64/unwind-ia64.c +++ b/contrib/gcc/config/ia64/unwind-ia64.c @@ -1665,6 +1665,14 @@ _Unwind_GetCFA (struct _Unwind_Context *context) return (_Unwind_Ptr) context->psp; } +/* Get the value of the Backing Store Pointer as saved in CONTEXT. */ + +_Unwind_Word +_Unwind_GetBSP (struct _Unwind_Context *context) +{ + return (_Unwind_Ptr) context->bsp; +} + static _Unwind_Reason_Code uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs) @@ -1786,6 +1794,11 @@ uw_update_reg_address (struct _Unwind_Context *context, addr = ia64_rse_skip_regs ((unsigned long *) context->bsp, rval - 32); else if (rval >= 2) addr = context->ireg[rval - 2].loc; + else if (rval == 0) + { + static const unsigned long dummy; + addr = (void *) &dummy; + } else abort (); break; @@ -1837,6 +1850,11 @@ uw_update_reg_address (struct _Unwind_Context *context, context->ireg[regno - UNW_REG_R2].nat = context->ireg[rval - 2].nat; } + else if (rval == 0) + { + context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_NONE; + context->ireg[regno - UNW_REG_R2].nat.off = 0; + } else abort (); break; |