comparison gcc/config/xtensa/xtensa.c @ 55:77e2b8dfacca gcc-4.4.5

update it from 4.4.3 to 4.5.0
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Fri, 12 Feb 2010 23:39:51 +0900
parents a06113de4d67
children b7f97abdc517
comparison
equal deleted inserted replaced
52:c156f1bd5cd9 55:77e2b8dfacca
1 /* Subroutines for insn-output.c for Tensilica's Xtensa architecture. 1 /* Subroutines for insn-output.c for Tensilica's Xtensa architecture.
2 Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 2 Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
3 Free Software Foundation, Inc. 3 Free Software Foundation, Inc.
4 Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica. 4 Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
5 5
6 This file is part of GCC. 6 This file is part of GCC.
7 7
69 ITEST_LTU, 69 ITEST_LTU,
70 ITEST_LEU, 70 ITEST_LEU,
71 ITEST_MAX 71 ITEST_MAX
72 }; 72 };
73 73
74 /* Cached operands, and operator to compare for use in set/branch on
75 condition codes. */
76 rtx branch_cmp[2];
77
78 /* what type of branch to use */
79 enum cmp_type branch_type;
80
81 /* Array giving truth value on whether or not a given hard register 74 /* Array giving truth value on whether or not a given hard register
82 can support a given mode. */ 75 can support a given mode. */
83 char xtensa_hard_regno_mode_ok[(int) MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER]; 76 char xtensa_hard_regno_mode_ok[(int) MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER];
84 77
85 /* Current frame size calculated by compute_frame_size. */ 78 /* Current frame size calculated by compute_frame_size. */
87 80
88 /* Largest block move to handle in-line. */ 81 /* Largest block move to handle in-line. */
89 #define LARGEST_MOVE_RATIO 15 82 #define LARGEST_MOVE_RATIO 15
90 83
91 /* Define the structure for the machine field in struct function. */ 84 /* Define the structure for the machine field in struct function. */
92 struct machine_function GTY(()) 85 struct GTY(()) machine_function
93 { 86 {
94 int accesses_prev_frame; 87 int accesses_prev_frame;
95 bool need_a7_copy; 88 bool need_a7_copy;
96 bool vararg_a7; 89 bool vararg_a7;
97 rtx vararg_a7_copy; 90 rtx vararg_a7_copy;
126 }; 119 };
127 120
128 static enum internal_test map_test_to_internal_test (enum rtx_code); 121 static enum internal_test map_test_to_internal_test (enum rtx_code);
129 static rtx gen_int_relational (enum rtx_code, rtx, rtx, int *); 122 static rtx gen_int_relational (enum rtx_code, rtx, rtx, int *);
130 static rtx gen_float_relational (enum rtx_code, rtx, rtx); 123 static rtx gen_float_relational (enum rtx_code, rtx, rtx);
131 static rtx gen_conditional_move (rtx); 124 static rtx gen_conditional_move (enum rtx_code, enum machine_mode, rtx, rtx);
132 static rtx fixup_subreg_mem (rtx); 125 static rtx fixup_subreg_mem (rtx);
133 static struct machine_function * xtensa_init_machine_status (void); 126 static struct machine_function * xtensa_init_machine_status (void);
134 static rtx xtensa_legitimize_tls_address (rtx); 127 static rtx xtensa_legitimize_tls_address (rtx);
128 static rtx xtensa_legitimize_address (rtx, rtx, enum machine_mode);
135 static bool xtensa_return_in_msb (const_tree); 129 static bool xtensa_return_in_msb (const_tree);
136 static void printx (FILE *, signed int); 130 static void printx (FILE *, signed int);
137 static void xtensa_function_epilogue (FILE *, HOST_WIDE_INT); 131 static void xtensa_function_epilogue (FILE *, HOST_WIDE_INT);
138 static rtx xtensa_builtin_saveregs (void); 132 static rtx xtensa_builtin_saveregs (void);
133 static bool xtensa_legitimate_address_p (enum machine_mode, rtx, bool);
139 static unsigned int xtensa_multibss_section_type_flags (tree, const char *, 134 static unsigned int xtensa_multibss_section_type_flags (tree, const char *,
140 int) ATTRIBUTE_UNUSED; 135 int) ATTRIBUTE_UNUSED;
141 static section *xtensa_select_rtx_section (enum machine_mode, rtx, 136 static section *xtensa_select_rtx_section (enum machine_mode, rtx,
142 unsigned HOST_WIDE_INT); 137 unsigned HOST_WIDE_INT);
143 static bool xtensa_rtx_costs (rtx, int, int, int *, bool); 138 static bool xtensa_rtx_costs (rtx, int, int, int *, bool);
148 static rtx xtensa_function_value (const_tree, const_tree, bool); 143 static rtx xtensa_function_value (const_tree, const_tree, bool);
149 static void xtensa_init_builtins (void); 144 static void xtensa_init_builtins (void);
150 static tree xtensa_fold_builtin (tree, tree, bool); 145 static tree xtensa_fold_builtin (tree, tree, bool);
151 static rtx xtensa_expand_builtin (tree, rtx, rtx, enum machine_mode, int); 146 static rtx xtensa_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
152 static void xtensa_va_start (tree, rtx); 147 static void xtensa_va_start (tree, rtx);
148 static bool xtensa_frame_pointer_required (void);
149 static rtx xtensa_static_chain (const_tree, bool);
150 static void xtensa_asm_trampoline_template (FILE *);
151 static void xtensa_trampoline_init (rtx, tree, rtx);
153 152
154 static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] = 153 static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] =
155 REG_ALLOC_ORDER; 154 REG_ALLOC_ORDER;
156 155
157 156
173 #define TARGET_ASM_SELECT_RTX_SECTION xtensa_select_rtx_section 172 #define TARGET_ASM_SELECT_RTX_SECTION xtensa_select_rtx_section
174 173
175 #undef TARGET_DEFAULT_TARGET_FLAGS 174 #undef TARGET_DEFAULT_TARGET_FLAGS
176 #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD) 175 #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD)
177 176
177 #undef TARGET_LEGITIMIZE_ADDRESS
178 #define TARGET_LEGITIMIZE_ADDRESS xtensa_legitimize_address
179
178 #undef TARGET_RTX_COSTS 180 #undef TARGET_RTX_COSTS
179 #define TARGET_RTX_COSTS xtensa_rtx_costs 181 #define TARGET_RTX_COSTS xtensa_rtx_costs
180 #undef TARGET_ADDRESS_COST 182 #undef TARGET_ADDRESS_COST
181 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0 183 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
182 184
184 #define TARGET_BUILD_BUILTIN_VA_LIST xtensa_build_builtin_va_list 186 #define TARGET_BUILD_BUILTIN_VA_LIST xtensa_build_builtin_va_list
185 187
186 #undef TARGET_EXPAND_BUILTIN_VA_START 188 #undef TARGET_EXPAND_BUILTIN_VA_START
187 #define TARGET_EXPAND_BUILTIN_VA_START xtensa_va_start 189 #define TARGET_EXPAND_BUILTIN_VA_START xtensa_va_start
188 190
189 #undef TARGET_PROMOTE_FUNCTION_ARGS 191 #undef TARGET_PROMOTE_FUNCTION_MODE
190 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true 192 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
191 #undef TARGET_PROMOTE_FUNCTION_RETURN
192 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true
193 #undef TARGET_PROMOTE_PROTOTYPES 193 #undef TARGET_PROMOTE_PROTOTYPES
194 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true 194 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
195 195
196 #undef TARGET_RETURN_IN_MEMORY 196 #undef TARGET_RETURN_IN_MEMORY
197 #define TARGET_RETURN_IN_MEMORY xtensa_return_in_memory 197 #define TARGET_RETURN_IN_MEMORY xtensa_return_in_memory
223 #undef TARGET_HAVE_TLS 223 #undef TARGET_HAVE_TLS
224 #define TARGET_HAVE_TLS (TARGET_THREADPTR && HAVE_AS_TLS) 224 #define TARGET_HAVE_TLS (TARGET_THREADPTR && HAVE_AS_TLS)
225 225
226 #undef TARGET_CANNOT_FORCE_CONST_MEM 226 #undef TARGET_CANNOT_FORCE_CONST_MEM
227 #define TARGET_CANNOT_FORCE_CONST_MEM xtensa_tls_referenced_p 227 #define TARGET_CANNOT_FORCE_CONST_MEM xtensa_tls_referenced_p
228
229 #undef TARGET_LEGITIMATE_ADDRESS_P
230 #define TARGET_LEGITIMATE_ADDRESS_P xtensa_legitimate_address_p
231
232 #undef TARGET_FRAME_POINTER_REQUIRED
233 #define TARGET_FRAME_POINTER_REQUIRED xtensa_frame_pointer_required
234
235 #undef TARGET_STATIC_CHAIN
236 #define TARGET_STATIC_CHAIN xtensa_static_chain
237 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
238 #define TARGET_ASM_TRAMPOLINE_TEMPLATE xtensa_asm_trampoline_template
239 #undef TARGET_TRAMPOLINE_INIT
240 #define TARGET_TRAMPOLINE_INIT xtensa_trampoline_init
228 241
229 struct gcc_target targetm = TARGET_INITIALIZER; 242 struct gcc_target targetm = TARGET_INITIALIZER;
230 243
231 244
232 /* Functions to test Xtensa immediate operand validity. */ 245 /* Functions to test Xtensa immediate operand validity. */
706 return gen_rtx_fmt_ee (invert ? EQ : NE, VOIDmode, brtmp, const0_rtx); 719 return gen_rtx_fmt_ee (invert ? EQ : NE, VOIDmode, brtmp, const0_rtx);
707 } 720 }
708 721
709 722
710 void 723 void
711 xtensa_expand_conditional_branch (rtx *operands, enum rtx_code test_code) 724 xtensa_expand_conditional_branch (rtx *operands, enum machine_mode mode)
712 { 725 {
713 enum cmp_type type = branch_type; 726 enum rtx_code test_code = GET_CODE (operands[0]);
714 rtx cmp0 = branch_cmp[0]; 727 rtx cmp0 = operands[1];
715 rtx cmp1 = branch_cmp[1]; 728 rtx cmp1 = operands[2];
716 rtx cmp; 729 rtx cmp;
717 int invert; 730 int invert;
718 rtx label1, label2; 731 rtx label1, label2;
719 732
720 switch (type) 733 switch (mode)
721 { 734 {
722 case CMP_DF: 735 case DFmode:
723 default: 736 default:
724 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1)); 737 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1));
725 738
726 case CMP_SI: 739 case SImode:
727 invert = FALSE; 740 invert = FALSE;
728 cmp = gen_int_relational (test_code, cmp0, cmp1, &invert); 741 cmp = gen_int_relational (test_code, cmp0, cmp1, &invert);
729 break; 742 break;
730 743
731 case CMP_SF: 744 case SFmode:
732 if (!TARGET_HARD_FLOAT) 745 if (!TARGET_HARD_FLOAT)
733 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, 746 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode,
734 cmp0, cmp1)); 747 cmp0, cmp1));
735 invert = FALSE; 748 invert = FALSE;
736 cmp = gen_float_relational (test_code, cmp0, cmp1); 749 cmp = gen_float_relational (test_code, cmp0, cmp1);
737 break; 750 break;
738 } 751 }
739 752
740 /* Generate the branch. */ 753 /* Generate the branch. */
741 754
742 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[0]); 755 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
743 label2 = pc_rtx; 756 label2 = pc_rtx;
744 757
745 if (invert) 758 if (invert)
746 { 759 {
747 label2 = label1; 760 label2 = label1;
754 label2))); 767 label2)));
755 } 768 }
756 769
757 770
758 static rtx 771 static rtx
759 gen_conditional_move (rtx cmp) 772 gen_conditional_move (enum rtx_code code, enum machine_mode mode,
760 { 773 rtx op0, rtx op1)
761 enum rtx_code code = GET_CODE (cmp); 774 {
762 rtx op0 = branch_cmp[0]; 775 if (mode == SImode)
763 rtx op1 = branch_cmp[1]; 776 {
764 777 rtx cmp;
765 if (branch_type == CMP_SI) 778
766 {
767 /* Jump optimization calls get_condition() which canonicalizes 779 /* Jump optimization calls get_condition() which canonicalizes
768 comparisons like (GE x <const>) to (GT x <const-1>). 780 comparisons like (GE x <const>) to (GT x <const-1>).
769 Transform those comparisons back to GE, since that is the 781 Transform those comparisons back to GE, since that is the
770 comparison supported in Xtensa. We shouldn't have to 782 comparison supported in Xtensa. We shouldn't have to
771 transform <LE x const> comparisons, because neither 783 transform <LE x const> comparisons, because neither
819 return 0; 831 return 0;
820 832
821 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1); 833 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
822 } 834 }
823 835
824 if (TARGET_HARD_FLOAT && (branch_type == CMP_SF)) 836 if (TARGET_HARD_FLOAT && mode == SFmode)
825 return gen_float_relational (code, op0, op1); 837 return gen_float_relational (code, op0, op1);
826 838
827 return 0; 839 return 0;
828 } 840 }
829 841
830 842
831 int 843 int
832 xtensa_expand_conditional_move (rtx *operands, int isflt) 844 xtensa_expand_conditional_move (rtx *operands, int isflt)
833 { 845 {
834 rtx cmp; 846 rtx dest = operands[0];
847 rtx cmp = operands[1];
848 enum machine_mode cmp_mode = GET_MODE (XEXP (cmp, 0));
835 rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx); 849 rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx);
836 850
837 if (!(cmp = gen_conditional_move (operands[1]))) 851 if (!(cmp = gen_conditional_move (GET_CODE (cmp), cmp_mode,
852 XEXP (cmp, 0), XEXP (cmp, 1))))
838 return 0; 853 return 0;
839 854
840 if (isflt) 855 if (isflt)
841 gen_fn = (branch_type == CMP_SI 856 gen_fn = (cmp_mode == SImode
842 ? gen_movsfcc_internal0 857 ? gen_movsfcc_internal0
843 : gen_movsfcc_internal1); 858 : gen_movsfcc_internal1);
844 else 859 else
845 gen_fn = (branch_type == CMP_SI 860 gen_fn = (cmp_mode == SImode
846 ? gen_movsicc_internal0 861 ? gen_movsicc_internal0
847 : gen_movsicc_internal1); 862 : gen_movsicc_internal1);
848 863
849 emit_insn (gen_fn (operands[0], XEXP (cmp, 0), 864 emit_insn (gen_fn (dest, XEXP (cmp, 0), operands[2], operands[3], cmp));
850 operands[2], operands[3], cmp));
851 return 1; 865 return 1;
852 } 866 }
853 867
854 868
855 int 869 int
856 xtensa_expand_scc (rtx *operands) 870 xtensa_expand_scc (rtx operands[4], enum machine_mode cmp_mode)
857 { 871 {
858 rtx dest = operands[0]; 872 rtx dest = operands[0];
859 rtx cmp = operands[1]; 873 rtx cmp;
860 rtx one_tmp, zero_tmp; 874 rtx one_tmp, zero_tmp;
861 rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx); 875 rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx);
862 876
863 if (!(cmp = gen_conditional_move (cmp))) 877 if (!(cmp = gen_conditional_move (GET_CODE (operands[1]), cmp_mode,
878 operands[2], operands[3])))
864 return 0; 879 return 0;
865 880
866 one_tmp = gen_reg_rtx (SImode); 881 one_tmp = gen_reg_rtx (SImode);
867 zero_tmp = gen_reg_rtx (SImode); 882 zero_tmp = gen_reg_rtx (SImode);
868 emit_insn (gen_movsi (one_tmp, const_true_rtx)); 883 emit_insn (gen_movsi (one_tmp, const_true_rtx));
869 emit_insn (gen_movsi (zero_tmp, const0_rtx)); 884 emit_insn (gen_movsi (zero_tmp, const0_rtx));
870 885
871 gen_fn = (branch_type == CMP_SI 886 gen_fn = (cmp_mode == SImode
872 ? gen_movsicc_internal0 887 ? gen_movsicc_internal0
873 : gen_movsicc_internal1); 888 : gen_movsicc_internal1);
874 emit_insn (gen_fn (dest, XEXP (cmp, 0), one_tmp, zero_tmp, cmp)); 889 emit_insn (gen_fn (dest, XEXP (cmp, 0), one_tmp, zero_tmp, cmp));
875 return 1; 890 return 1;
876 } 891 }
1529 1544
1530 1545
1531 void 1546 void
1532 xtensa_setup_frame_addresses (void) 1547 xtensa_setup_frame_addresses (void)
1533 { 1548 {
1534 /* Set flag to cause FRAME_POINTER_REQUIRED to be set. */ 1549 /* Set flag to cause TARGET_FRAME_POINTER_REQUIRED to return true. */
1535 cfun->machine->accesses_prev_frame = 1; 1550 cfun->machine->accesses_prev_frame = 1;
1536 1551
1537 emit_library_call 1552 emit_library_call
1538 (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_libgcc_window_spill"), 1553 (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_libgcc_window_spill"),
1539 0, VOIDmode, 0); 1554 0, VOIDmode, 0);
1871 gen_rtx_PLUS (Pmode, plus0, addmi_offset))); 1886 gen_rtx_PLUS (Pmode, plus0, addmi_offset)));
1872 return gen_rtx_PLUS (Pmode, temp, GEN_INT (INTVAL (plus1) & 0xff)); 1887 return gen_rtx_PLUS (Pmode, temp, GEN_INT (INTVAL (plus1) & 0xff));
1873 } 1888 }
1874 } 1889 }
1875 1890
1876 return NULL_RTX; 1891 return x;
1877 } 1892 }
1878 1893
1879 1894
1880 /* Helper for xtensa_tls_referenced_p. */ 1895 /* Helper for xtensa_tls_referenced_p. */
1881 1896
2490 + (WINDOW_SIZE * UNITS_PER_WORD)); 2505 + (WINDOW_SIZE * UNITS_PER_WORD));
2491 return xtensa_current_frame_size; 2506 return xtensa_current_frame_size;
2492 } 2507 }
2493 2508
2494 2509
2495 int 2510 bool
2496 xtensa_frame_pointer_required (void) 2511 xtensa_frame_pointer_required (void)
2497 { 2512 {
2498 /* The code to expand builtin_frame_addr and builtin_return_addr 2513 /* The code to expand builtin_frame_addr and builtin_return_addr
2499 currently uses the hard_frame_pointer instead of frame_pointer. 2514 currently uses the hard_frame_pointer instead of frame_pointer.
2500 This seems wrong but maybe it's necessary for other architectures. 2515 This seems wrong but maybe it's necessary for other architectures.
2501 This function is derived from the i386 code. */ 2516 This function is derived from the i386 code. */
2502 2517
2503 if (cfun->machine->accesses_prev_frame) 2518 if (cfun->machine->accesses_prev_frame)
2504 return 1; 2519 return true;
2505 2520
2506 return 0; 2521 return false;
2507 } 2522 }
2508 2523
2509 2524
2510 /* minimum frame = reg save area (4 words) plus static chain (1 word) 2525 /* minimum frame = reg save area (4 words) plus static chain (1 word)
2511 and the total number of words must be a multiple of 128 bits. */ 2526 and the total number of words must be a multiple of 128 bits. */
2646 xtensa_build_builtin_va_list (void) 2661 xtensa_build_builtin_va_list (void)
2647 { 2662 {
2648 tree f_stk, f_reg, f_ndx, record, type_decl; 2663 tree f_stk, f_reg, f_ndx, record, type_decl;
2649 2664
2650 record = (*lang_hooks.types.make_type) (RECORD_TYPE); 2665 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
2651 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record); 2666 type_decl = build_decl (BUILTINS_LOCATION,
2652 2667 TYPE_DECL, get_identifier ("__va_list_tag"), record);
2653 f_stk = build_decl (FIELD_DECL, get_identifier ("__va_stk"), 2668
2669 f_stk = build_decl (BUILTINS_LOCATION,
2670 FIELD_DECL, get_identifier ("__va_stk"),
2654 ptr_type_node); 2671 ptr_type_node);
2655 f_reg = build_decl (FIELD_DECL, get_identifier ("__va_reg"), 2672 f_reg = build_decl (BUILTINS_LOCATION,
2673 FIELD_DECL, get_identifier ("__va_reg"),
2656 ptr_type_node); 2674 ptr_type_node);
2657 f_ndx = build_decl (FIELD_DECL, get_identifier ("__va_ndx"), 2675 f_ndx = build_decl (BUILTINS_LOCATION,
2676 FIELD_DECL, get_identifier ("__va_ndx"),
2658 integer_type_node); 2677 integer_type_node);
2659 2678
2660 DECL_FIELD_CONTEXT (f_stk) = record; 2679 DECL_FIELD_CONTEXT (f_stk) = record;
2661 DECL_FIELD_CONTEXT (f_reg) = record; 2680 DECL_FIELD_CONTEXT (f_reg) = record;
2662 DECL_FIELD_CONTEXT (f_ndx) = record; 2681 DECL_FIELD_CONTEXT (f_ndx) = record;
2843 array = create_tmp_var (ptr_type_node, NULL); 2862 array = create_tmp_var (ptr_type_node, NULL);
2844 2863
2845 lab_over = NULL; 2864 lab_over = NULL;
2846 if (!targetm.calls.must_pass_in_stack (TYPE_MODE (type), type)) 2865 if (!targetm.calls.must_pass_in_stack (TYPE_MODE (type), type))
2847 { 2866 {
2848 lab_false = create_artificial_label (); 2867 lab_false = create_artificial_label (UNKNOWN_LOCATION);
2849 lab_over = create_artificial_label (); 2868 lab_over = create_artificial_label (UNKNOWN_LOCATION);
2850 2869
2851 t = build2 (GT_EXPR, boolean_type_node, unshare_expr (ndx), 2870 t = build2 (GT_EXPR, boolean_type_node, unshare_expr (ndx),
2852 build_int_cst (integer_type_node, 2871 build_int_cst (integer_type_node,
2853 MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD)); 2872 MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD));
2854 t = build3 (COND_EXPR, void_type_node, t, 2873 t = build3 (COND_EXPR, void_type_node, t,
2874 if (orig_ndx <= __MAX_ARGS_IN_REGISTERS * 4) 2893 if (orig_ndx <= __MAX_ARGS_IN_REGISTERS * 4)
2875 (AP).__va_ndx = 32 + __va_size (TYPE); 2894 (AP).__va_ndx = 32 + __va_size (TYPE);
2876 __array = (AP).__va_stk; 2895 __array = (AP).__va_stk;
2877 } */ 2896 } */
2878 2897
2879 lab_false2 = create_artificial_label (); 2898 lab_false2 = create_artificial_label (UNKNOWN_LOCATION);
2880 2899
2881 t = build2 (GT_EXPR, boolean_type_node, unshare_expr (orig_ndx), 2900 t = build2 (GT_EXPR, boolean_type_node, unshare_expr (orig_ndx),
2882 build_int_cst (integer_type_node, 2901 build_int_cst (integer_type_node,
2883 MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD)); 2902 MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD));
2884 t = build3 (COND_EXPR, void_type_node, t, 2903 t = build3 (COND_EXPR, void_type_node, t,
3416 && TYPE_PRECISION (valtype) < BITS_PER_WORD) 3435 && TYPE_PRECISION (valtype) < BITS_PER_WORD)
3417 ? SImode : TYPE_MODE (valtype), 3436 ? SImode : TYPE_MODE (valtype),
3418 outgoing ? GP_OUTGOING_RETURN : GP_RETURN); 3437 outgoing ? GP_OUTGOING_RETURN : GP_RETURN);
3419 } 3438 }
3420 3439
3440 /* The static chain is passed in memory. Provide rtx giving 'mem'
3441 expressions that denote where they are stored. */
3442
3443 static rtx
3444 xtensa_static_chain (const_tree ARG_UNUSED (fndecl), bool incoming_p)
3445 {
3446 rtx base = incoming_p ? arg_pointer_rtx : stack_pointer_rtx;
3447 return gen_frame_mem (Pmode, plus_constant (base, -5 * UNITS_PER_WORD));
3448 }
3449
3450
3421 /* TRAMPOLINE_TEMPLATE: For Xtensa, the trampoline must perform an ENTRY 3451 /* TRAMPOLINE_TEMPLATE: For Xtensa, the trampoline must perform an ENTRY
3422 instruction with a minimal stack frame in order to get some free 3452 instruction with a minimal stack frame in order to get some free
3423 registers. Once the actual call target is known, the proper stack frame 3453 registers. Once the actual call target is known, the proper stack frame
3424 size is extracted from the ENTRY instruction at the target and the 3454 size is extracted from the ENTRY instruction at the target and the
3425 current frame is adjusted to match. The trampoline then transfers 3455 current frame is adjusted to match. The trampoline then transfers
3426 control to the instruction following the ENTRY at the target. Note: 3456 control to the instruction following the ENTRY at the target. Note:
3427 this assumes that the target begins with an ENTRY instruction. */ 3457 this assumes that the target begins with an ENTRY instruction. */
3428 3458
3429 void 3459 static void
3430 xtensa_trampoline_template (FILE *stream) 3460 xtensa_asm_trampoline_template (FILE *stream)
3431 { 3461 {
3432 bool use_call0 = (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS); 3462 bool use_call0 = (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS);
3433 3463
3434 fprintf (stream, "\t.begin no-transform\n"); 3464 fprintf (stream, "\t.begin no-transform\n");
3435 fprintf (stream, "\tentry\tsp, %d\n", MIN_FRAME_SIZE); 3465 fprintf (stream, "\tentry\tsp, %d\n", MIN_FRAME_SIZE);
3492 fprintf (stream, "\tnop\n"); 3522 fprintf (stream, "\tnop\n");
3493 3523
3494 fprintf (stream, "\t.end no-transform\n"); 3524 fprintf (stream, "\t.end no-transform\n");
3495 } 3525 }
3496 3526
3497 3527 static void
3498 void 3528 xtensa_trampoline_init (rtx m_tramp, tree fndecl, rtx chain)
3499 xtensa_initialize_trampoline (rtx addr, rtx func, rtx chain) 3529 {
3500 { 3530 rtx func = XEXP (DECL_RTL (fndecl), 0);
3501 bool use_call0 = (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS); 3531 bool use_call0 = (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS);
3502 int chain_off = use_call0 ? 12 : 8; 3532 int chain_off = use_call0 ? 12 : 8;
3503 int func_off = use_call0 ? 16 : 12; 3533 int func_off = use_call0 ? 16 : 12;
3504 emit_move_insn (gen_rtx_MEM (SImode, plus_constant (addr, chain_off)), chain); 3534
3505 emit_move_insn (gen_rtx_MEM (SImode, plus_constant (addr, func_off)), func); 3535 emit_block_move (m_tramp, assemble_trampoline_template (),
3536 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
3537
3538 emit_move_insn (adjust_address (m_tramp, SImode, chain_off), chain);
3539 emit_move_insn (adjust_address (m_tramp, SImode, func_off), func);
3506 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_sync_caches"), 3540 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_sync_caches"),
3507 0, VOIDmode, 1, addr, Pmode); 3541 0, VOIDmode, 1, XEXP (m_tramp, 0), Pmode);
3508 } 3542 }
3509 3543
3510 3544
3511 #include "gt-xtensa.h" 3545 #include "gt-xtensa.h"