From: Richard Henderson Date: Wed, 19 Jan 2011 18:46:30 +0000 (-0800) Subject: mn10300: tidy pic address loading X-Git-Tag: upstream/12.2.0~86982 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=040c57570147b0a05c29339dd778378b8cf15a56;p=platform%2Fupstream%2Fgcc.git mn10300: tidy pic address loading There's little reason to greatly complicate things by splitting the pic_load patterns and using complex rtl to make it work out. Instead, use the %= marker to generate unique numbers and emit the entire load_pic sequence at once. At the same time, collect all references to outgoing_args_size into mn10300_frame_size, and all computations of register save area size into mn10300_initial_offset. From-SVN: r169012 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5a85c70..dcdd569 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,24 @@ 2011-01-19 Richard Henderson + * config/mn10300/mn10300.c (mn10300_unspec_int_label_counter): Remove. + (mn10300_asm_output_addr_const_extra): Don't handle UNSPEC_INT_LABEL. + (mn10300_legitimate_constant_p): Likewise. + (mn10300_can_use_return_insn): Use mn10300_initial_offset. + (mn10300_frame_size): New. + (mn10300_expand_prologue): Use it. + (mn10300_expand_epilogue): Likewise. + (mn10300_initial_offset): Likewise. + * config/mn10300/mn10300-protos.h: Update. + * config/mn10300/mn10300.h (mn10300_unspec_int_label_counter): Remove. + * config/mn10300/mn10300.md (UNSPEC_INT_LABEL): Remove. + (prologue, epilogue, return_internal): Tidy output code. + (mn10300_store_multiple_operation, return): Likewise. + (int_label, pop_pic_reg, GOTaddr2picreg): Remove. + (am33_loadPC, mn10300_loadPC, call_next_insn): Remove. + (add_GOT_to_pic_reg, add_GOT_to_any_reg): Remove. + (load_pic, am33_load_pic): New. + (mn10300_load_pic0, mn10300_load_pic1): New. + * config/mn10300/mn10300-modes.def (CCZN, CCZNC): New modes. * config/mn10300/mn10300.c (CC_FLAG_Z): New. (CC_FLAG_N, CC_FLAG_C, CC_FLAG_V): New. diff --git a/gcc/config/mn10300/mn10300-protos.h b/gcc/config/mn10300/mn10300-protos.h index 28a9412..c25ba9b 100644 --- a/gcc/config/mn10300/mn10300-protos.h +++ b/gcc/config/mn10300/mn10300-protos.h @@ -49,6 +49,7 @@ extern int mn10300_can_use_return_insn (void); extern void mn10300_expand_prologue (void); extern void mn10300_expand_epilogue (void); extern int mn10300_initial_offset (int, int); +extern int mn10300_frame_size (void); #undef Mmode #undef Cstar diff --git a/gcc/config/mn10300/mn10300.c b/gcc/config/mn10300/mn10300.c index 7535253..b2c2460 100644 --- a/gcc/config/mn10300/mn10300.c +++ b/gcc/config/mn10300/mn10300.c @@ -44,10 +44,6 @@ #include "target-def.h" #include "df.h" -/* This is used by GOTaddr2picreg to uniquely identify - UNSPEC_INT_LABELs. */ -int mn10300_unspec_int_label_counter; - /* This is used in the am33_2.0-linux-gnu port, in which global symbol names are not prefixed by underscores, to tell whether to prefix a label with a plus sign or not, so that the assembler can tell @@ -544,10 +540,6 @@ mn10300_asm_output_addr_const_extra (FILE *file, rtx x) { switch (XINT (x, 1)) { - case UNSPEC_INT_LABEL: - asm_fprintf (file, ".%LLIL" HOST_WIDE_INT_PRINT_DEC, - INTVAL (XVECEXP (x, 0, 0))); - break; case UNSPEC_PIC: /* GLOBAL_OFFSET_TABLE or local symbols, no suffix. */ output_addr_const (file, XVECEXP (x, 0, 0)); @@ -634,24 +626,7 @@ mn10300_print_reg_list (FILE *file, int mask) int mn10300_can_use_return_insn (void) { - /* size includes the fixed stack space needed for function calls. */ - int size = get_frame_size () + crtl->outgoing_args_size; - - /* And space for the return pointer. */ - size += crtl->outgoing_args_size ? 4 : 0; - - return (reload_completed - && size == 0 - && !df_regs_ever_live_p (2) - && !df_regs_ever_live_p (3) - && !df_regs_ever_live_p (6) - && !df_regs_ever_live_p (7) - && !df_regs_ever_live_p (14) - && !df_regs_ever_live_p (15) - && !df_regs_ever_live_p (16) - && !df_regs_ever_live_p (17) - && fp_regs_to_save () == 0 - && !frame_pointer_needed); + return !mn10300_initial_offset (ARG_POINTER_REGNUM, STACK_POINTER_REGNUM); } /* Returns the set of live, callee-saved registers as a bitmask. The @@ -760,11 +735,7 @@ mn10300_gen_multiple_store (unsigned int mask) void mn10300_expand_prologue (void) { - HOST_WIDE_INT size; - - /* SIZE includes the fixed stack space needed for function calls. */ - size = get_frame_size () + crtl->outgoing_args_size; - size += (crtl->outgoing_args_size ? 4 : 0); + HOST_WIDE_INT size = mn10300_frame_size (); /* If we use any of the callee-saved registers, save them now. */ mn10300_gen_multiple_store (mn10300_get_live_callee_saved_regs ()); @@ -1017,17 +988,13 @@ mn10300_expand_prologue (void) GEN_INT (-size)))); if (flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM)) - emit_insn (gen_GOTaddr2picreg ()); + emit_insn (gen_load_pic ()); } void mn10300_expand_epilogue (void) { - HOST_WIDE_INT size; - - /* SIZE includes the fixed stack space needed for function calls. */ - size = get_frame_size () + crtl->outgoing_args_size; - size += (crtl->outgoing_args_size ? 4 : 0); + HOST_WIDE_INT size = mn10300_frame_size (); if (TARGET_AM33_2 && fp_regs_to_save ()) { @@ -1442,54 +1409,37 @@ mn10300_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i, } int +mn10300_frame_size (void) +{ + /* size includes the fixed stack space needed for function calls. */ + int size = get_frame_size () + crtl->outgoing_args_size; + + /* And space for the return pointer. */ + size += crtl->outgoing_args_size ? 4 : 0; + + return size; +} + +int mn10300_initial_offset (int from, int to) { + int diff = 0; + + gcc_assert (from == ARG_POINTER_REGNUM || from == FRAME_POINTER_REGNUM); + gcc_assert (to == FRAME_POINTER_REGNUM || to == STACK_POINTER_REGNUM); + + if (to == STACK_POINTER_REGNUM) + diff = mn10300_frame_size (); + /* The difference between the argument pointer and the frame pointer is the size of the callee register save area. */ - if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM) + if (from == ARG_POINTER_REGNUM) { - if (df_regs_ever_live_p (2) || df_regs_ever_live_p (3) - || df_regs_ever_live_p (6) || df_regs_ever_live_p (7) - || df_regs_ever_live_p (14) || df_regs_ever_live_p (15) - || df_regs_ever_live_p (16) || df_regs_ever_live_p (17) - || fp_regs_to_save () - || frame_pointer_needed) - return REG_SAVE_BYTES - + 4 * fp_regs_to_save (); - else - return 0; + diff += REG_SAVE_BYTES; + diff += 4 * fp_regs_to_save (); } - /* The difference between the argument pointer and the stack pointer is - the sum of the size of this function's frame, the callee register save - area, and the fixed stack space needed for function calls (if any). */ - if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM) - { - if (df_regs_ever_live_p (2) || df_regs_ever_live_p (3) - || df_regs_ever_live_p (6) || df_regs_ever_live_p (7) - || df_regs_ever_live_p (14) || df_regs_ever_live_p (15) - || df_regs_ever_live_p (16) || df_regs_ever_live_p (17) - || fp_regs_to_save () - || frame_pointer_needed) - return (get_frame_size () + REG_SAVE_BYTES - + 4 * fp_regs_to_save () - + (crtl->outgoing_args_size - ? crtl->outgoing_args_size + 4 : 0)); - else - return (get_frame_size () - + (crtl->outgoing_args_size - ? crtl->outgoing_args_size + 4 : 0)); - } - - /* The difference between the frame pointer and stack pointer is the sum - of the size of this function's frame and the fixed stack space needed - for function calls (if any). */ - if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM) - return (get_frame_size () - + (crtl->outgoing_args_size - ? crtl->outgoing_args_size + 4 : 0)); - - gcc_unreachable (); + return diff; } /* Worker function for TARGET_RETURN_IN_MEMORY. */ @@ -2087,7 +2037,6 @@ mn10300_legitimate_constant_p (rtx x) { switch (XINT (x, 1)) { - case UNSPEC_INT_LABEL: case UNSPEC_PIC: case UNSPEC_GOT: case UNSPEC_GOTOFF: diff --git a/gcc/config/mn10300/mn10300.h b/gcc/config/mn10300/mn10300.h index 21d3633..b10f450 100644 --- a/gcc/config/mn10300/mn10300.h +++ b/gcc/config/mn10300/mn10300.h @@ -53,8 +53,6 @@ } \ while (0) -extern GTY(()) int mn10300_unspec_int_label_counter; - enum processor_type { PROCESSOR_MN10300, diff --git a/gcc/config/mn10300/mn10300.md b/gcc/config/mn10300/mn10300.md index 152477c..2477cb3 100644 --- a/gcc/config/mn10300/mn10300.md +++ b/gcc/config/mn10300/mn10300.md @@ -31,7 +31,6 @@ (MDR_REG 50) (CC_REG 51) - (UNSPEC_INT_LABEL 0) (UNSPEC_PIC 1) (UNSPEC_GOT 2) (UNSPEC_GOTOFF 3) @@ -294,7 +293,6 @@ (match_operand:SI 1 "impossible_plus_operand" "")) (clobber (match_operand:SI 2 "register_operand" "=&A"))] "" - " { rtx dest, scratch, other; @@ -336,16 +334,7 @@ emit_move_insn (dest, scratch); } DONE; -}") - -(define_insn "pop_pic_reg" - [(set (reg:SI PIC_REG) - (mem:SI (post_inc:SI (reg:SI SP_REG))))] - "reload_completed" - "movm (sp),[a2]" - [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") - (const_int 44) (const_int 33)))] -) +}) (define_expand "movsi" [(set (match_operand:SI 0 "nonimmediate_operand") @@ -1141,13 +1130,10 @@ (define_expand "builtin_setjmp_receiver" [(match_operand 0 "" "")] "flag_pic" - " { - if (flag_pic) - emit_insn (gen_GOTaddr2picreg ()); - + emit_insn (gen_load_pic ()); DONE; -}") +}) (define_expand "casesi" [(match_operand:SI 0 "register_operand") @@ -1612,16 +1598,14 @@ (define_expand "prologue" [(const_int 0)] "" - "mn10300_expand_prologue (); DONE;") + { mn10300_expand_prologue (); DONE; } +) (define_expand "epilogue" [(return)] "" - " - { - mn10300_expand_epilogue (); - DONE; - }") + { mn10300_expand_epilogue (); DONE; } +) (define_insn "return_internal" [(const_int 2) @@ -1638,13 +1622,12 @@ (match_operand:SI 0 "const_int_operand" "i") (return)] "" - "* - { - fputs (\"\\tret \", asm_out_file); - mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs ()); - fprintf (asm_out_file, \",%d\\n\", (int) INTVAL (operands[0])); - return \"\"; - }" +{ + fputs ("\tret ", asm_out_file); + mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs ()); + fprintf (asm_out_file, ",%d\n", (int) INTVAL (operands[0])); + return ""; +} ;; Assumes that there will be no more than 8 regs to pop [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") (const_int 1414) (const_int 1313)))] @@ -1655,15 +1638,14 @@ [(match_parallel 0 "mn10300_store_multiple_operation" [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_operand 1 "" "")))])] "" - "* - { - fputs (\"\\tmovm \", asm_out_file); - mn10300_print_reg_list (asm_out_file, - mn10300_store_multiple_operation (operands[0], - VOIDmode)); - fprintf (asm_out_file, \",(sp)\\n\"); - return \"\"; - }" +{ + fputs ("\tmovm ", asm_out_file); + mn10300_print_reg_list (asm_out_file, + mn10300_store_multiple_operation (operands[0], + VOIDmode)); + fprintf (asm_out_file, ",(sp)\n"); + return ""; +} ;; Assume that no more than 8 registers will be pushed. [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") (const_int 99) (const_int 88)))] @@ -1672,116 +1654,67 @@ (define_insn "return" [(return)] "mn10300_can_use_return_insn ()" - "* -{ - rtx next = next_active_insn (insn); - - if (next - && JUMP_P (next) - && GET_CODE (PATTERN (next)) == RETURN) - return \"\"; - else - return \"rets\"; -}" + "rets" [(set_attr "timings" "66")] ) -(define_expand "int_label" - [(unspec [(match_operand:SI 0 "" "")] UNSPEC_INT_LABEL)] - "" "") - -(define_expand "GOTaddr2picreg" - [(match_dup 0)] - "" " +(define_expand "load_pic" + [(const_int 0)] + "flag_pic" { - /* It would be nice to be able to have int_label keep track of the - counter and all, but if we add C code to it, we'll get an insn - back, and we just want the pattern. */ - operands[0] = gen_int_label (GEN_INT (mn10300_unspec_int_label_counter++)); if (TARGET_AM33) - emit_insn (gen_am33_loadPC (operands[0])); + emit_insn (gen_am33_load_pic (pic_offset_table_rtx)); + else if (mn10300_frame_size () == 0) + emit_insn (gen_mn10300_load_pic0 (pic_offset_table_rtx)); else - emit_insn (gen_mn10300_loadPC (operands[0])); - emit_insn (gen_add_GOT_to_pic_reg (copy_rtx (operands[0]))); + emit_insn (gen_mn10300_load_pic1 (pic_offset_table_rtx)); DONE; -} -") +}) -(define_insn "am33_loadPC" - [(parallel - [(set (reg:SI PIC_REG) (pc)) - (use (match_operand 0 "" ""))])] +(define_insn "am33_load_pic" + [(set (match_operand:SI 0 "register_operand" "=a") + (unspec:SI [(const_int 0)] UNSPEC_GOT)) + (clobber (reg:CC CC_REG))] "TARGET_AM33" - "%0:\;mov pc,a2" +{ + operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME); + return ".LPIC%=:\;mov pc,%0\;add %1-(.LPIC%=-.),%0"; +} + [(set_attr "timings" "33")] ) -(define_insn_and_split "mn10300_loadPC" - [(parallel - [(set (reg:SI PIC_REG) (pc)) - (use (match_operand 0 "" ""))])] - "! TARGET_AM33" - "#" - "&& reload_completed" - [(match_operand 0 "" "")] - { - rtx sp_reg = gen_rtx_REG (SImode, SP_REG); - int need_stack_space = (get_frame_size () == 0 - && crtl->outgoing_args_size == 0); - - if (need_stack_space) - emit_insn (gen_addsi3 (sp_reg, sp_reg, GEN_INT (-4))); - - emit_insn (gen_call_next_insn (operands[0])); - - if (need_stack_space) - emit_insn (gen_pop_pic_reg ()); - else - emit_move_insn (pic_offset_table_rtx, gen_rtx_MEM (SImode, sp_reg)); - DONE; - } +;; Load pic register with push/pop of stack. +(define_insn "mn10300_load_pic0" + [(set (match_operand:SI 0 "register_operand" "=a") + (unspec:SI [(const_int 0)] UNSPEC_GOT)) + (clobber (reg:SI MDR_REG)) + (clobber (reg:CC CC_REG))] + "" +{ + operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME); + return ("add -4,sp\;" + "calls .LPIC%=\n" + ".LPIC%=:\;" + "movm (sp),[%0]\;" + "add %1-(.LPIC%=-.),%0"); +} + [(set_attr "timings" "88")] ) -(define_insn "call_next_insn" - [(parallel - [(set (mem:SI (reg:SI SP_REG)) (pc)) - (use (match_operand 0 "" ""))])] - "reload_completed" - "calls %0\;%0:" - [(set_attr "timings" "44")] -) - -(define_expand "add_GOT_to_pic_reg" - [(parallel [(set (reg:SI PIC_REG) - (plus:SI - (reg:SI PIC_REG) - (const:SI - (unspec:SI [(minus:SI - (match_dup 1) - (const (minus:SI - (const (match_operand:SI 0 "" "")) - (pc)))) - ] UNSPEC_PIC)))) - (clobber (reg:CC CC_REG)) - ]) - ] - "" - "operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);" -) - -(define_expand "add_GOT_to_any_reg" - [(parallel [(set (match_operand:SI 0 "" "") - (plus:SI - (match_operand:SI 1 "" "") - (const - (unspec [(minus:SI - (match_dup 3) - (const (minus:SI - (const (match_operand:SI 2 "" "")) - (pc)))) - ] UNSPEC_PIC)))) - (clobber (reg:CC CC_REG)) - ]) - ] +;; Load pic register re-using existing stack space. +(define_insn "mn10300_load_pic1" + [(set (match_operand:SI 0 "register_operand" "=a") + (unspec:SI [(const_int 0)] UNSPEC_GOT)) + (clobber (mem:SI (reg:SI SP_REG))) + (clobber (reg:SI MDR_REG)) + (clobber (reg:CC CC_REG))] "" - "operands[3] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);" +{ + operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME); + return ("calls .LPIC%=\n" + ".LPIC%=:\;" + "mov (sp),%0\;" + "add %1-(.LPIC%=-.),%0"); +} + [(set_attr "timings" "66")] )