diff options
author | Rong Xu <xur@google.com> | 2014-09-02 15:29:57 -0700 |
---|---|---|
committer | Rong Xu <xur@google.com> | 2014-09-02 15:29:57 -0700 |
commit | e97c99f15937e5762a973b25192aab824126a6d3 (patch) | |
tree | 7f0be3ff7c7d976af06887dc50accd68f7630a7f /gcc-4.9/gcc/config/pa | |
parent | f1c18afafc2b321465ae6b07ede127095942d7dc (diff) | |
download | toolchain_gcc-e97c99f15937e5762a973b25192aab824126a6d3.tar.gz toolchain_gcc-e97c99f15937e5762a973b25192aab824126a6d3.tar.bz2 toolchain_gcc-e97c99f15937e5762a973b25192aab824126a6d3.zip |
[gcc-4.9] Merge svn r214745 from google/gcc-4_9 branch.
Merge gcc-4_9 source r214745 from google/gcc-4_9 branch.
Change-Id: Ie6fa0fd72f4b4eec3adc4db4bb922e652d1c2605
Diffstat (limited to 'gcc-4.9/gcc/config/pa')
-rw-r--r-- | gcc-4.9/gcc/config/pa/pa-protos.h | 2 | ||||
-rw-r--r-- | gcc-4.9/gcc/config/pa/pa.c | 87 | ||||
-rw-r--r-- | gcc-4.9/gcc/config/pa/pa.h | 10 | ||||
-rw-r--r-- | gcc-4.9/gcc/config/pa/pa.md | 30 |
4 files changed, 67 insertions, 62 deletions
diff --git a/gcc-4.9/gcc/config/pa/pa-protos.h b/gcc-4.9/gcc/config/pa/pa-protos.h index 2659dcdf0..1e48da512 100644 --- a/gcc-4.9/gcc/config/pa/pa-protos.h +++ b/gcc-4.9/gcc/config/pa/pa-protos.h @@ -49,6 +49,8 @@ extern const char *pa_output_mul_insn (int, rtx); extern const char *pa_output_div_insn (rtx *, int, rtx); extern const char *pa_output_mod_insn (int, rtx); extern const char *pa_singlemove_string (rtx *); +extern void pa_output_addr_vec (rtx, rtx); +extern void pa_output_addr_diff_vec (rtx, rtx); extern void pa_output_arg_descriptor (rtx); extern void pa_output_global_address (FILE *, rtx, int); extern void pa_print_operand (FILE *, rtx, int); diff --git a/gcc-4.9/gcc/config/pa/pa.c b/gcc-4.9/gcc/config/pa/pa.c index 871e4e5c6..5a7598ca7 100644 --- a/gcc-4.9/gcc/config/pa/pa.c +++ b/gcc-4.9/gcc/config/pa/pa.c @@ -4155,8 +4155,7 @@ static void pa_output_function_epilogue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED) { rtx insn = get_last_insn (); - - last_address = 0; + bool extra_nop; /* pa_expand_epilogue does the dirty work now. We just need to output the assembler directives which denote the end @@ -4180,8 +4179,10 @@ pa_output_function_epilogue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED) if (insn && CALL_P (insn)) { fputs ("\tnop\n", file); - last_address += 4; + extra_nop = true; } + else + extra_nop = false; fputs ("\t.EXIT\n\t.PROCEND\n", file); @@ -4194,12 +4195,13 @@ pa_output_function_epilogue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED) cfun->machine->in_nsubspa = 2; } - /* Thunks do their own accounting. */ + /* Thunks do their own insn accounting. */ if (cfun->is_thunk) return; if (INSN_ADDRESSES_SET_P ()) { + last_address = extra_nop ? 4 : 0; insn = get_last_nonnote_insn (); last_address += INSN_ADDRESSES (INSN_UID (insn)); if (INSN_P (insn)) @@ -8293,12 +8295,16 @@ pa_asm_output_mi_thunk (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta, || ((DECL_SECTION_NAME (thunk_fndecl) == DECL_SECTION_NAME (function)) && last_address < 262132))) + /* In this case, we need to be able to reach the start of + the stub table even though the function is likely closer + and can be jumped to directly. */ || (targetm_common.have_named_sections && DECL_SECTION_NAME (thunk_fndecl) == NULL && DECL_SECTION_NAME (function) == NULL - && last_address < 262132) + && total_code_bytes < MAX_PCREL17F_OFFSET) + /* Likewise. */ || (!targetm_common.have_named_sections - && last_address < 262132)))) + && total_code_bytes < MAX_PCREL17F_OFFSET)))) { if (!val_14) output_asm_insn ("addil L'%2,%%r26", xoperands); @@ -8944,40 +8950,15 @@ pa_following_call (rtx insn) } /* We use this hook to perform a PA specific optimization which is difficult - to do in earlier passes. - - We surround the jump table itself with BEGIN_BRTAB and END_BRTAB - insns. Those insns mark where we should emit .begin_brtab and - .end_brtab directives when using GAS. This allows for better link - time optimizations. */ + to do in earlier passes. */ static void pa_reorg (void) { - rtx insn; - remove_useless_addtr_insns (1); if (pa_cpu < PROCESSOR_8000) pa_combine_instructions (); - - /* Still need brtab marker insns. FIXME: the presence of these - markers disables output of the branch table to readonly memory, - and any alignment directives that might be needed. Possibly, - the begin_brtab insn should be output before the label for the - table. This doesn't matter at the moment since the tables are - always output in the text section. */ - for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) - { - /* Find an ADDR_VEC insn. */ - if (! JUMP_TABLE_DATA_P (insn)) - continue; - - /* Now generate markers for the beginning and end of the - branch table. */ - emit_insn_before (gen_begin_brtab (), insn); - emit_insn_after (gen_end_brtab (), insn); - } } /* The PA has a number of odd instructions which can perform multiple @@ -10572,4 +10553,46 @@ pa_legitimize_reload_address (rtx ad, enum machine_mode mode, return NULL_RTX; } +/* Output address vector. */ + +void +pa_output_addr_vec (rtx lab, rtx body) +{ + int idx, vlen = XVECLEN (body, 0); + + targetm.asm_out.internal_label (asm_out_file, "L", CODE_LABEL_NUMBER (lab)); + if (TARGET_GAS) + fputs ("\t.begin_brtab\n", asm_out_file); + for (idx = 0; idx < vlen; idx++) + { + ASM_OUTPUT_ADDR_VEC_ELT + (asm_out_file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0))); + } + if (TARGET_GAS) + fputs ("\t.end_brtab\n", asm_out_file); +} + +/* Output address difference vector. */ + +void +pa_output_addr_diff_vec (rtx lab, rtx body) +{ + rtx base = XEXP (XEXP (body, 0), 0); + int idx, vlen = XVECLEN (body, 1); + + targetm.asm_out.internal_label (asm_out_file, "L", CODE_LABEL_NUMBER (lab)); + if (TARGET_GAS) + fputs ("\t.begin_brtab\n", asm_out_file); + for (idx = 0; idx < vlen; idx++) + { + ASM_OUTPUT_ADDR_DIFF_ELT + (asm_out_file, + body, + CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 1, idx), 0)), + CODE_LABEL_NUMBER (base)); + } + if (TARGET_GAS) + fputs ("\t.end_brtab\n", asm_out_file); +} + #include "gt-pa.h" diff --git a/gcc-4.9/gcc/config/pa/pa.h b/gcc-4.9/gcc/config/pa/pa.h index ac3f0ebe7..f6c9751a2 100644 --- a/gcc-4.9/gcc/config/pa/pa.h +++ b/gcc-4.9/gcc/config/pa/pa.h @@ -1193,6 +1193,16 @@ do { \ #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ fprintf (FILE, "\t.word L$%04d-L$%04d\n", VALUE, REL) +/* This is how to output an absolute case-vector. */ + +#define ASM_OUTPUT_ADDR_VEC(LAB,BODY) \ + pa_output_addr_vec ((LAB),(BODY)) + +/* This is how to output a relative case-vector. */ + +#define ASM_OUTPUT_ADDR_DIFF_VEC(LAB,BODY) \ + pa_output_addr_diff_vec ((LAB),(BODY)) + /* This is how to output an assembler line that says to advance the location counter to a multiple of 2**LOG bytes. */ diff --git a/gcc-4.9/gcc/config/pa/pa.md b/gcc-4.9/gcc/config/pa/pa.md index e55d0b86b..a9421ac2e 100644 --- a/gcc-4.9/gcc/config/pa/pa.md +++ b/gcc-4.9/gcc/config/pa/pa.md @@ -8508,36 +8508,6 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" [(set_attr "type" "move") (set_attr "length" "4")]) -;; These are just placeholders so we know where branch tables -;; begin and end. -(define_insn "begin_brtab" - [(const_int 1)] - "" - "* -{ - /* Only GAS actually supports this pseudo-op. */ - if (TARGET_GAS) - return \".begin_brtab\"; - else - return \"\"; -}" - [(set_attr "type" "move") - (set_attr "length" "0")]) - -(define_insn "end_brtab" - [(const_int 2)] - "" - "* -{ - /* Only GAS actually supports this pseudo-op. */ - if (TARGET_GAS) - return \".end_brtab\"; - else - return \"\"; -}" - [(set_attr "type" "move") - (set_attr "length" "0")]) - ;;; EH does longjmp's from and within the data section. Thus, ;;; an interspace branch is required for the longjmp implementation. ;;; Registers r1 and r2 are used as scratch registers for the jump |