Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/cris/cris.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* Definitions for GCC. Part of the machine description for CRIS. | 1 /* Definitions for GCC. Part of the machine description for CRIS. |
2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, | 2 Copyright (C) 1998-2017 Free Software Foundation, Inc. |
3 2008, 2009, 2010 Free Software Foundation, Inc. | |
4 Contributed by Axis Communications. Written by Hans-Peter Nilsson. | 3 Contributed by Axis Communications. Written by Hans-Peter Nilsson. |
5 | 4 |
6 This file is part of GCC. | 5 This file is part of GCC. |
7 | 6 |
8 GCC is free software; you can redistribute it and/or modify | 7 GCC is free software; you can redistribute it and/or modify |
20 <http://www.gnu.org/licenses/>. */ | 19 <http://www.gnu.org/licenses/>. */ |
21 | 20 |
22 #include "config.h" | 21 #include "config.h" |
23 #include "system.h" | 22 #include "system.h" |
24 #include "coretypes.h" | 23 #include "coretypes.h" |
25 #include "tm.h" | 24 #include "backend.h" |
25 #include "target.h" | |
26 #include "rtl.h" | 26 #include "rtl.h" |
27 #include "tree.h" | |
28 #include "stringpool.h" | |
29 #include "attribs.h" | |
30 #include "cfghooks.h" | |
31 #include "df.h" | |
32 #include "memmodel.h" | |
33 #include "tm_p.h" | |
34 #include "optabs.h" | |
27 #include "regs.h" | 35 #include "regs.h" |
28 #include "hard-reg-set.h" | 36 #include "emit-rtl.h" |
29 #include "insn-config.h" | 37 #include "recog.h" |
38 #include "cgraph.h" | |
39 #include "diagnostic-core.h" | |
30 #include "conditions.h" | 40 #include "conditions.h" |
31 #include "insn-attr.h" | 41 #include "insn-attr.h" |
32 #include "flags.h" | 42 #include "alias.h" |
33 #include "tree.h" | 43 #include "varasm.h" |
44 #include "stor-layout.h" | |
45 #include "calls.h" | |
46 #include "explow.h" | |
34 #include "expr.h" | 47 #include "expr.h" |
35 #include "except.h" | |
36 #include "function.h" | |
37 #include "diagnostic-core.h" | |
38 #include "recog.h" | |
39 #include "reload.h" | 48 #include "reload.h" |
40 #include "tm_p.h" | |
41 #include "debug.h" | |
42 #include "output.h" | 49 #include "output.h" |
43 #include "target.h" | 50 #include "tm-constrs.h" |
51 #include "builtins.h" | |
52 | |
53 /* This file should be included last. */ | |
44 #include "target-def.h" | 54 #include "target-def.h" |
45 #include "ggc.h" | |
46 #include "optabs.h" | |
47 #include "df.h" | |
48 | 55 |
49 /* Usable when we have an amount to add or subtract, and want the | 56 /* Usable when we have an amount to add or subtract, and want the |
50 optimal size of the insn. */ | 57 optimal size of the insn. */ |
51 #define ADDITIVE_SIZE_MODIFIER(size) \ | 58 #define ADDITIVE_SIZE_MODIFIER(size) \ |
52 ((size) <= 63 ? "q" : (size) <= 255 ? "u.b" : (size) <= 65535 ? "u.w" : ".d") | 59 ((size) <= 63 ? "q" : (size) <= 255 ? "u.b" : (size) <= 65535 ? "u.w" : ".d") |
82 static int in_code = 0; | 89 static int in_code = 0; |
83 | 90 |
84 /* Fix for reg_overlap_mentioned_p. */ | 91 /* Fix for reg_overlap_mentioned_p. */ |
85 static int cris_reg_overlap_mentioned_p (rtx, rtx); | 92 static int cris_reg_overlap_mentioned_p (rtx, rtx); |
86 | 93 |
87 static enum machine_mode cris_promote_function_mode (const_tree, enum machine_mode, | 94 static machine_mode cris_promote_function_mode (const_tree, machine_mode, |
88 int *, const_tree, int); | 95 int *, const_tree, int); |
89 | 96 |
97 static unsigned int cris_atomic_align_for_mode (machine_mode); | |
98 | |
90 static void cris_print_base (rtx, FILE *); | 99 static void cris_print_base (rtx, FILE *); |
91 | 100 |
92 static void cris_print_index (rtx, FILE *); | 101 static void cris_print_index (rtx, FILE *); |
93 | 102 |
94 static void cris_output_addr_const (FILE *, rtx); | 103 static void cris_output_addr_const (FILE *, rtx); |
95 | 104 |
96 static struct machine_function * cris_init_machine_status (void); | 105 static struct machine_function * cris_init_machine_status (void); |
97 | 106 |
98 static rtx cris_struct_value_rtx (tree, int); | 107 static rtx cris_struct_value_rtx (tree, int); |
99 | 108 |
100 static void cris_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, | 109 static void cris_setup_incoming_varargs (cumulative_args_t, machine_mode, |
101 tree type, int *, int); | 110 tree type, int *, int); |
102 | 111 |
103 static int cris_initial_frame_pointer_offset (void); | 112 static int cris_initial_frame_pointer_offset (void); |
104 | 113 |
105 static void cris_operand_lossage (const char *, rtx); | 114 static void cris_operand_lossage (const char *, rtx); |
106 | 115 |
107 static int cris_reg_saved_in_regsave_area (unsigned int, bool); | 116 static int cris_reg_saved_in_regsave_area (unsigned int, bool); |
108 | 117 |
109 static void cris_print_operand (FILE *, rtx, int); | 118 static void cris_print_operand (FILE *, rtx, int); |
110 | 119 |
111 static void cris_print_operand_address (FILE *, rtx); | 120 static void cris_print_operand_address (FILE *, machine_mode, rtx); |
112 | 121 |
113 static bool cris_print_operand_punct_valid_p (unsigned char code); | 122 static bool cris_print_operand_punct_valid_p (unsigned char code); |
123 | |
124 static bool cris_output_addr_const_extra (FILE *, rtx); | |
114 | 125 |
115 static void cris_conditional_register_usage (void); | 126 static void cris_conditional_register_usage (void); |
116 | 127 |
117 static void cris_asm_output_mi_thunk | 128 static void cris_asm_output_mi_thunk |
118 (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree); | 129 (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree); |
119 | 130 |
120 static void cris_file_start (void); | 131 static void cris_file_start (void); |
121 static void cris_init_libfuncs (void); | 132 static void cris_init_libfuncs (void); |
122 | 133 |
123 static int cris_register_move_cost (enum machine_mode, reg_class_t, reg_class_t); | 134 static reg_class_t cris_preferred_reload_class (rtx, reg_class_t); |
124 static int cris_memory_move_cost (enum machine_mode, reg_class_t, bool); | 135 |
125 static bool cris_rtx_costs (rtx, int, int, int *, bool); | 136 static int cris_register_move_cost (machine_mode, reg_class_t, reg_class_t); |
126 static int cris_address_cost (rtx, bool); | 137 static int cris_memory_move_cost (machine_mode, reg_class_t, bool); |
127 static bool cris_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, | 138 static bool cris_rtx_costs (rtx, machine_mode, int, int, int *, bool); |
139 static int cris_address_cost (rtx, machine_mode, addr_space_t, bool); | |
140 static bool cris_pass_by_reference (cumulative_args_t, machine_mode, | |
128 const_tree, bool); | 141 const_tree, bool); |
129 static int cris_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, | 142 static int cris_arg_partial_bytes (cumulative_args_t, machine_mode, |
130 tree, bool); | 143 tree, bool); |
131 static rtx cris_function_arg (CUMULATIVE_ARGS *, enum machine_mode, | 144 static rtx cris_function_arg (cumulative_args_t, machine_mode, |
132 const_tree, bool); | 145 const_tree, bool); |
133 static rtx cris_function_incoming_arg (CUMULATIVE_ARGS *, | 146 static rtx cris_function_incoming_arg (cumulative_args_t, |
134 enum machine_mode, const_tree, bool); | 147 machine_mode, const_tree, bool); |
135 static void cris_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, | 148 static void cris_function_arg_advance (cumulative_args_t, machine_mode, |
136 const_tree, bool); | 149 const_tree, bool); |
137 static tree cris_md_asm_clobbers (tree, tree, tree); | 150 static rtx_insn *cris_md_asm_adjust (vec<rtx> &, vec<rtx> &, |
138 | 151 vec<const char *> &, |
139 static bool cris_handle_option (size_t, const char *, int); | 152 vec<rtx> &, HARD_REG_SET &); |
153 static bool cris_cannot_force_const_mem (machine_mode, rtx); | |
154 | |
140 static void cris_option_override (void); | 155 static void cris_option_override (void); |
141 | 156 |
142 static bool cris_frame_pointer_required (void); | 157 static bool cris_frame_pointer_required (void); |
143 | 158 |
144 static void cris_asm_trampoline_template (FILE *); | 159 static void cris_asm_trampoline_template (FILE *); |
145 static void cris_trampoline_init (rtx, tree, rtx); | 160 static void cris_trampoline_init (rtx, tree, rtx); |
146 | 161 |
147 static rtx cris_function_value(const_tree, const_tree, bool); | 162 static rtx cris_function_value(const_tree, const_tree, bool); |
148 static rtx cris_libcall_value (enum machine_mode, const_rtx); | 163 static rtx cris_libcall_value (machine_mode, const_rtx); |
164 static bool cris_function_value_regno_p (const unsigned int); | |
165 static void cris_file_end (void); | |
166 static unsigned int cris_hard_regno_nregs (unsigned int, machine_mode); | |
167 static bool cris_hard_regno_mode_ok (unsigned int, machine_mode); | |
168 static HOST_WIDE_INT cris_static_rtx_alignment (machine_mode); | |
169 static HOST_WIDE_INT cris_constant_alignment (const_tree, HOST_WIDE_INT); | |
149 | 170 |
150 /* This is the parsed result of the "-max-stack-stackframe=" option. If | 171 /* This is the parsed result of the "-max-stack-stackframe=" option. If |
151 it (still) is zero, then there was no such option given. */ | 172 it (still) is zero, then there was no such option given. */ |
152 int cris_max_stackframe = 0; | 173 int cris_max_stackframe = 0; |
153 | 174 |
154 /* This is the parsed result of the "-march=" option, if given. */ | 175 /* This is the parsed result of the "-march=" option, if given. */ |
155 int cris_cpu_version = CRIS_DEFAULT_CPU_VERSION; | 176 int cris_cpu_version = CRIS_DEFAULT_CPU_VERSION; |
156 | |
157 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ | |
158 | |
159 static const struct default_options cris_option_optimization_table[] = | |
160 { | |
161 { OPT_LEVELS_2_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, | |
162 { OPT_LEVELS_NONE, 0, NULL, 0 } | |
163 }; | |
164 | 177 |
165 #undef TARGET_ASM_ALIGNED_HI_OP | 178 #undef TARGET_ASM_ALIGNED_HI_OP |
166 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t" | 179 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t" |
167 #undef TARGET_ASM_ALIGNED_SI_OP | 180 #undef TARGET_ASM_ALIGNED_SI_OP |
168 #define TARGET_ASM_ALIGNED_SI_OP "\t.dword\t" | 181 #define TARGET_ASM_ALIGNED_SI_OP "\t.dword\t" |
185 #define TARGET_PRINT_OPERAND cris_print_operand | 198 #define TARGET_PRINT_OPERAND cris_print_operand |
186 #undef TARGET_PRINT_OPERAND_ADDRESS | 199 #undef TARGET_PRINT_OPERAND_ADDRESS |
187 #define TARGET_PRINT_OPERAND_ADDRESS cris_print_operand_address | 200 #define TARGET_PRINT_OPERAND_ADDRESS cris_print_operand_address |
188 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P | 201 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P |
189 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P cris_print_operand_punct_valid_p | 202 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P cris_print_operand_punct_valid_p |
203 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA | |
204 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA cris_output_addr_const_extra | |
190 | 205 |
191 #undef TARGET_CONDITIONAL_REGISTER_USAGE | 206 #undef TARGET_CONDITIONAL_REGISTER_USAGE |
192 #define TARGET_CONDITIONAL_REGISTER_USAGE cris_conditional_register_usage | 207 #define TARGET_CONDITIONAL_REGISTER_USAGE cris_conditional_register_usage |
193 | 208 |
194 #undef TARGET_ASM_OUTPUT_MI_THUNK | 209 #undef TARGET_ASM_OUTPUT_MI_THUNK |
196 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK | 211 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK |
197 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall | 212 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall |
198 | 213 |
199 #undef TARGET_ASM_FILE_START | 214 #undef TARGET_ASM_FILE_START |
200 #define TARGET_ASM_FILE_START cris_file_start | 215 #define TARGET_ASM_FILE_START cris_file_start |
216 #undef TARGET_ASM_FILE_END | |
217 #define TARGET_ASM_FILE_END cris_file_end | |
201 | 218 |
202 #undef TARGET_INIT_LIBFUNCS | 219 #undef TARGET_INIT_LIBFUNCS |
203 #define TARGET_INIT_LIBFUNCS cris_init_libfuncs | 220 #define TARGET_INIT_LIBFUNCS cris_init_libfuncs |
221 | |
222 #undef TARGET_LRA_P | |
223 #define TARGET_LRA_P hook_bool_void_false | |
224 | |
225 #undef TARGET_LEGITIMATE_ADDRESS_P | |
226 #define TARGET_LEGITIMATE_ADDRESS_P cris_legitimate_address_p | |
227 | |
228 #undef TARGET_LEGITIMATE_CONSTANT_P | |
229 #define TARGET_LEGITIMATE_CONSTANT_P cris_legitimate_constant_p | |
230 | |
231 #undef TARGET_PREFERRED_RELOAD_CLASS | |
232 #define TARGET_PREFERRED_RELOAD_CLASS cris_preferred_reload_class | |
204 | 233 |
205 #undef TARGET_REGISTER_MOVE_COST | 234 #undef TARGET_REGISTER_MOVE_COST |
206 #define TARGET_REGISTER_MOVE_COST cris_register_move_cost | 235 #define TARGET_REGISTER_MOVE_COST cris_register_move_cost |
207 #undef TARGET_MEMORY_MOVE_COST | 236 #undef TARGET_MEMORY_MOVE_COST |
208 #define TARGET_MEMORY_MOVE_COST cris_memory_move_cost | 237 #define TARGET_MEMORY_MOVE_COST cris_memory_move_cost |
211 #undef TARGET_ADDRESS_COST | 240 #undef TARGET_ADDRESS_COST |
212 #define TARGET_ADDRESS_COST cris_address_cost | 241 #define TARGET_ADDRESS_COST cris_address_cost |
213 | 242 |
214 #undef TARGET_PROMOTE_FUNCTION_MODE | 243 #undef TARGET_PROMOTE_FUNCTION_MODE |
215 #define TARGET_PROMOTE_FUNCTION_MODE cris_promote_function_mode | 244 #define TARGET_PROMOTE_FUNCTION_MODE cris_promote_function_mode |
245 | |
246 #undef TARGET_ATOMIC_ALIGN_FOR_MODE | |
247 #define TARGET_ATOMIC_ALIGN_FOR_MODE cris_atomic_align_for_mode | |
216 | 248 |
217 #undef TARGET_STRUCT_VALUE_RTX | 249 #undef TARGET_STRUCT_VALUE_RTX |
218 #define TARGET_STRUCT_VALUE_RTX cris_struct_value_rtx | 250 #define TARGET_STRUCT_VALUE_RTX cris_struct_value_rtx |
219 #undef TARGET_SETUP_INCOMING_VARARGS | 251 #undef TARGET_SETUP_INCOMING_VARARGS |
220 #define TARGET_SETUP_INCOMING_VARARGS cris_setup_incoming_varargs | 252 #define TARGET_SETUP_INCOMING_VARARGS cris_setup_incoming_varargs |
226 #define TARGET_FUNCTION_ARG cris_function_arg | 258 #define TARGET_FUNCTION_ARG cris_function_arg |
227 #undef TARGET_FUNCTION_INCOMING_ARG | 259 #undef TARGET_FUNCTION_INCOMING_ARG |
228 #define TARGET_FUNCTION_INCOMING_ARG cris_function_incoming_arg | 260 #define TARGET_FUNCTION_INCOMING_ARG cris_function_incoming_arg |
229 #undef TARGET_FUNCTION_ARG_ADVANCE | 261 #undef TARGET_FUNCTION_ARG_ADVANCE |
230 #define TARGET_FUNCTION_ARG_ADVANCE cris_function_arg_advance | 262 #define TARGET_FUNCTION_ARG_ADVANCE cris_function_arg_advance |
231 #undef TARGET_MD_ASM_CLOBBERS | 263 #undef TARGET_MD_ASM_ADJUST |
232 #define TARGET_MD_ASM_CLOBBERS cris_md_asm_clobbers | 264 #define TARGET_MD_ASM_ADJUST cris_md_asm_adjust |
233 #undef TARGET_DEFAULT_TARGET_FLAGS | 265 |
234 #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | CRIS_SUBTARGET_DEFAULT) | 266 #undef TARGET_CANNOT_FORCE_CONST_MEM |
235 #undef TARGET_HANDLE_OPTION | 267 #define TARGET_CANNOT_FORCE_CONST_MEM cris_cannot_force_const_mem |
236 #define TARGET_HANDLE_OPTION cris_handle_option | 268 |
237 #undef TARGET_FRAME_POINTER_REQUIRED | 269 #undef TARGET_FRAME_POINTER_REQUIRED |
238 #define TARGET_FRAME_POINTER_REQUIRED cris_frame_pointer_required | 270 #define TARGET_FRAME_POINTER_REQUIRED cris_frame_pointer_required |
239 | 271 |
240 #undef TARGET_OPTION_OVERRIDE | 272 #undef TARGET_OPTION_OVERRIDE |
241 #define TARGET_OPTION_OVERRIDE cris_option_override | 273 #define TARGET_OPTION_OVERRIDE cris_option_override |
242 #undef TARGET_OPTION_OPTIMIZATION_TABLE | |
243 #define TARGET_OPTION_OPTIMIZATION_TABLE cris_option_optimization_table | |
244 | 274 |
245 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE | 275 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE |
246 #define TARGET_ASM_TRAMPOLINE_TEMPLATE cris_asm_trampoline_template | 276 #define TARGET_ASM_TRAMPOLINE_TEMPLATE cris_asm_trampoline_template |
247 #undef TARGET_TRAMPOLINE_INIT | 277 #undef TARGET_TRAMPOLINE_INIT |
248 #define TARGET_TRAMPOLINE_INIT cris_trampoline_init | 278 #define TARGET_TRAMPOLINE_INIT cris_trampoline_init |
249 | 279 |
250 #undef TARGET_FUNCTION_VALUE | 280 #undef TARGET_FUNCTION_VALUE |
251 #define TARGET_FUNCTION_VALUE cris_function_value | 281 #define TARGET_FUNCTION_VALUE cris_function_value |
252 #undef TARGET_LIBCALL_VALUE | 282 #undef TARGET_LIBCALL_VALUE |
253 #define TARGET_LIBCALL_VALUE cris_libcall_value | 283 #define TARGET_LIBCALL_VALUE cris_libcall_value |
284 #undef TARGET_FUNCTION_VALUE_REGNO_P | |
285 #define TARGET_FUNCTION_VALUE_REGNO_P cris_function_value_regno_p | |
286 | |
287 #undef TARGET_HARD_REGNO_NREGS | |
288 #define TARGET_HARD_REGNO_NREGS cris_hard_regno_nregs | |
289 #undef TARGET_HARD_REGNO_MODE_OK | |
290 #define TARGET_HARD_REGNO_MODE_OK cris_hard_regno_mode_ok | |
291 | |
292 #undef TARGET_STATIC_RTX_ALIGNMENT | |
293 #define TARGET_STATIC_RTX_ALIGNMENT cris_static_rtx_alignment | |
294 #undef TARGET_CONSTANT_ALIGNMENT | |
295 #define TARGET_CONSTANT_ALIGNMENT cris_constant_alignment | |
254 | 296 |
255 struct gcc_target targetm = TARGET_INITIALIZER; | 297 struct gcc_target targetm = TARGET_INITIALIZER; |
256 | 298 |
257 /* Helper for cris_load_multiple_op and cris_ret_movem_op. */ | 299 /* Helper for cris_load_multiple_op and cris_ret_movem_op. */ |
258 | 300 |
490 cris_cfun_uses_pic_table (void) | 532 cris_cfun_uses_pic_table (void) |
491 { | 533 { |
492 return crtl->uses_pic_offset_table; | 534 return crtl->uses_pic_offset_table; |
493 } | 535 } |
494 | 536 |
537 /* Worker function for TARGET_CANNOT_FORCE_CONST_MEM. | |
538 We can't put PIC addresses in the constant pool, not even the ones that | |
539 can be reached as pc-relative as we can't tell when or how to do that. */ | |
540 | |
541 static bool | |
542 cris_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x) | |
543 { | |
544 enum cris_symbol_type t = cris_symbol_type_of (x); | |
545 | |
546 return | |
547 t == cris_unspec | |
548 || t == cris_got_symbol | |
549 || t == cris_rel_symbol; | |
550 } | |
551 | |
495 /* Given an rtx, return the text string corresponding to the CODE of X. | 552 /* Given an rtx, return the text string corresponding to the CODE of X. |
496 Intended for use in the assembly language output section of a | 553 Intended for use in the assembly language output section of a |
497 define_insn. */ | 554 define_insn. */ |
498 | 555 |
499 const char * | 556 const char * |
502 cris_output_insn_is_bound = 0; | 559 cris_output_insn_is_bound = 0; |
503 switch (GET_CODE (x)) | 560 switch (GET_CODE (x)) |
504 { | 561 { |
505 case PLUS: | 562 case PLUS: |
506 return "add"; | 563 return "add"; |
507 break; | |
508 | 564 |
509 case MINUS: | 565 case MINUS: |
510 return "sub"; | 566 return "sub"; |
511 break; | |
512 | 567 |
513 case MULT: | 568 case MULT: |
514 /* This function is for retrieving a part of an instruction name for | 569 /* This function is for retrieving a part of an instruction name for |
515 an operator, for immediate output. If that ever happens for | 570 an operator, for immediate output. If that ever happens for |
516 MULT, we need to apply TARGET_MUL_BUG in the caller. Make sure | 571 MULT, we need to apply TARGET_MUL_BUG in the caller. Make sure |
518 internal_error ("MULT case in cris_op_str"); | 573 internal_error ("MULT case in cris_op_str"); |
519 break; | 574 break; |
520 | 575 |
521 case DIV: | 576 case DIV: |
522 return "div"; | 577 return "div"; |
523 break; | |
524 | 578 |
525 case AND: | 579 case AND: |
526 return "and"; | 580 return "and"; |
527 break; | |
528 | 581 |
529 case IOR: | 582 case IOR: |
530 return "or"; | 583 return "or"; |
531 break; | |
532 | 584 |
533 case XOR: | 585 case XOR: |
534 return "xor"; | 586 return "xor"; |
535 break; | |
536 | 587 |
537 case NOT: | 588 case NOT: |
538 return "not"; | 589 return "not"; |
539 break; | |
540 | 590 |
541 case ASHIFT: | 591 case ASHIFT: |
542 return "lsl"; | 592 return "lsl"; |
543 break; | |
544 | 593 |
545 case LSHIFTRT: | 594 case LSHIFTRT: |
546 return "lsr"; | 595 return "lsr"; |
547 break; | |
548 | 596 |
549 case ASHIFTRT: | 597 case ASHIFTRT: |
550 return "asr"; | 598 return "asr"; |
551 break; | |
552 | 599 |
553 case UMIN: | 600 case UMIN: |
554 /* Used to control the sign/zero-extend character for the 'E' modifier. | 601 /* Used to control the sign/zero-extend character for the 'E' modifier. |
555 BOUND has none. */ | 602 BOUND has none. */ |
556 cris_output_insn_is_bound = 1; | 603 cris_output_insn_is_bound = 1; |
557 return "bound"; | 604 return "bound"; |
558 break; | |
559 | 605 |
560 default: | 606 default: |
561 return "Unknown operator"; | 607 return "Unknown operator"; |
562 break; | |
563 } | 608 } |
564 } | 609 } |
565 | 610 |
566 /* Emit an error message when we're in an asm, and a fatal error for | 611 /* Emit an error message when we're in an asm, and a fatal error for |
567 "normal" insns. Formatted output isn't easily implemented, since we | 612 "normal" insns. Formatted output isn't easily implemented, since we |
585 if (!CONST_INT_P (index) || INTVAL (index) >= 0) | 630 if (!CONST_INT_P (index) || INTVAL (index) >= 0) |
586 putc ('+', file); | 631 putc ('+', file); |
587 | 632 |
588 if (REG_P (index)) | 633 if (REG_P (index)) |
589 fprintf (file, "$%s.b", reg_names[REGNO (index)]); | 634 fprintf (file, "$%s.b", reg_names[REGNO (index)]); |
590 else if (CONSTANT_P (index)) | 635 else if (CRIS_CONSTANT_P (index)) |
591 cris_output_addr_const (file, index); | 636 cris_output_addr_const (file, index); |
592 else if (GET_CODE (index) == MULT) | 637 else if (GET_CODE (index) == MULT) |
593 { | 638 { |
594 fprintf (file, "$%s.", | 639 fprintf (file, "$%s.", |
595 reg_names[REGNO (XEXP (index, 0))]); | 640 reg_names[REGNO (XEXP (index, 0))]); |
701 switch (code) | 746 switch (code) |
702 { | 747 { |
703 case 'b': | 748 case 'b': |
704 /* Print the unsigned supplied integer as if it were signed | 749 /* Print the unsigned supplied integer as if it were signed |
705 and < 0, i.e print 255 or 65535 as -1, 254, 65534 as -2, etc. */ | 750 and < 0, i.e print 255 or 65535 as -1, 254, 65534 as -2, etc. */ |
706 if (!CONST_INT_P (x) | 751 if (!satisfies_constraint_O (x)) |
707 || !CRIS_CONST_OK_FOR_LETTER_P (INTVAL (x), 'O')) | |
708 LOSE_AND_RETURN ("invalid operand for 'b' modifier", x); | 752 LOSE_AND_RETURN ("invalid operand for 'b' modifier", x); |
709 fprintf (file, HOST_WIDE_INT_PRINT_DEC, | 753 fprintf (file, HOST_WIDE_INT_PRINT_DEC, |
710 INTVAL (x)| (INTVAL (x) <= 255 ? ~255 : ~65535)); | 754 INTVAL (x)| (INTVAL (x) <= 255 ? ~255 : ~65535)); |
711 return; | 755 return; |
712 | 756 |
765 INTVAL (XEXP (addr, 1)) < 0 ? "" : "+", | 809 INTVAL (XEXP (addr, 1)) < 0 ? "" : "+", |
766 (int) INTVAL (XEXP (addr, 1))); | 810 (int) INTVAL (XEXP (addr, 1))); |
767 return; | 811 return; |
768 } | 812 } |
769 } | 813 } |
770 output_address (addr); | 814 output_address (VOIDmode, addr); |
771 } | 815 } |
772 return; | 816 return; |
773 | 817 |
774 case 'p': | 818 case 'p': |
775 /* Adjust a power of two to its log2. */ | 819 /* Adjust a power of two to its log2. */ |
904 though; it should remain as it was. */ | 948 though; it should remain as it was. */ |
905 if (GET_CODE (XEXP (adj_mem, 0)) != POST_INC) | 949 if (GET_CODE (XEXP (adj_mem, 0)) != POST_INC) |
906 adj_mem | 950 adj_mem |
907 = adjust_address (adj_mem, GET_MODE (adj_mem), size / 2); | 951 = adjust_address (adj_mem, GET_MODE (adj_mem), size / 2); |
908 | 952 |
909 output_address (XEXP (adj_mem, 0)); | 953 output_address (VOIDmode, XEXP (adj_mem, 0)); |
910 return; | 954 return; |
911 } | 955 } |
912 | 956 |
913 default: | 957 default: |
914 LOSE_AND_RETURN ("invalid operand for 'H' modifier", x); | 958 LOSE_AND_RETURN ("invalid operand for 'H' modifier", x); |
975 if (!CONST_INT_P (operand)) | 1019 if (!CONST_INT_P (operand)) |
976 LOSE_AND_RETURN ("invalid operand for 'A' modifier", x); | 1020 LOSE_AND_RETURN ("invalid operand for 'A' modifier", x); |
977 fprintf (file, INTVAL (operand) < 0 ? "adds.w" : "addq"); | 1021 fprintf (file, INTVAL (operand) < 0 ? "adds.w" : "addq"); |
978 return; | 1022 return; |
979 | 1023 |
1024 case 'P': | |
1025 /* For const_int operands, print the additive mnemonic and the | |
1026 modified operand (byte-sized operands don't save anything): | |
1027 N=MIN_INT..-65536: add.d N | |
1028 -65535..-64: subu.w -N | |
1029 -63..-1: subq -N | |
1030 0..63: addq N | |
1031 64..65535: addu.w N | |
1032 65536..MAX_INT: add.d N. | |
1033 (Emitted mnemonics are capitalized to simplify testing.) | |
1034 For anything else (N.B: only register is valid), print "add.d". */ | |
1035 if (REG_P (operand)) | |
1036 { | |
1037 fprintf (file, "Add.d "); | |
1038 | |
1039 /* Deal with printing the operand by dropping through to the | |
1040 normal path. */ | |
1041 break; | |
1042 } | |
1043 else | |
1044 { | |
1045 int val; | |
1046 gcc_assert (CONST_INT_P (operand)); | |
1047 | |
1048 val = INTVAL (operand); | |
1049 if (!IN_RANGE (val, -65535, 65535)) | |
1050 fprintf (file, "Add.d %d", val); | |
1051 else if (val <= -64) | |
1052 fprintf (file, "Subu.w %d", -val); | |
1053 else if (val <= -1) | |
1054 fprintf (file, "Subq %d", -val); | |
1055 else if (val <= 63) | |
1056 fprintf (file, "Addq %d", val); | |
1057 else if (val <= 65535) | |
1058 fprintf (file, "Addu.w %d", val); | |
1059 return; | |
1060 } | |
1061 break; | |
1062 | |
1063 case 'q': | |
1064 /* If the operand is an integer -31..31, print "q" else ".d". */ | |
1065 if (CONST_INT_P (operand) && IN_RANGE (INTVAL (operand), -31, 31)) | |
1066 fprintf (file, "q"); | |
1067 else | |
1068 fprintf (file, ".d"); | |
1069 return; | |
1070 | |
980 case 'd': | 1071 case 'd': |
981 /* If this is a GOT symbol, force it to be emitted as :GOT and | 1072 /* If this is a GOT symbol, force it to be emitted as :GOT and |
982 :GOTPLT regardless of -fpic (i.e. not as :GOT16, :GOTPLT16). | 1073 :GOTPLT regardless of -fpic (i.e. not as :GOT16, :GOTPLT16). |
983 Avoid making this too much of a special case. */ | 1074 Avoid making this too much of a special case. */ |
984 if (flag_pic == 1 && CONSTANT_P (operand)) | 1075 if (flag_pic == 1 && CRIS_CONSTANT_P (operand)) |
985 { | 1076 { |
986 int flag_pic_save = flag_pic; | 1077 int flag_pic_save = flag_pic; |
987 | 1078 |
988 flag_pic = 2; | 1079 flag_pic = 2; |
989 cris_output_addr_const (file, operand); | 1080 cris_output_addr_const (file, operand); |
1044 internal_error ("internal error: bad register: %d", REGNO (operand)); | 1135 internal_error ("internal error: bad register: %d", REGNO (operand)); |
1045 fprintf (file, "$%s", reg_names[REGNO (operand)]); | 1136 fprintf (file, "$%s", reg_names[REGNO (operand)]); |
1046 return; | 1137 return; |
1047 | 1138 |
1048 case MEM: | 1139 case MEM: |
1049 output_address (XEXP (operand, 0)); | 1140 output_address (GET_MODE (operand), XEXP (operand, 0)); |
1050 return; | 1141 return; |
1051 | 1142 |
1052 case CONST_DOUBLE: | 1143 case CONST_DOUBLE: |
1053 if (GET_MODE (operand) == VOIDmode) | 1144 if (GET_MODE (operand) == VOIDmode) |
1054 /* A long long constant. */ | 1145 /* A long long constant. */ |
1055 output_addr_const (file, operand); | 1146 output_addr_const (file, operand); |
1056 else | 1147 else |
1057 { | 1148 { |
1058 /* Only single precision is allowed as plain operands the | 1149 /* Only single precision is allowed as plain operands the |
1059 moment. FIXME: REAL_VALUE_FROM_CONST_DOUBLE isn't | 1150 moment. */ |
1060 documented. */ | |
1061 REAL_VALUE_TYPE r; | |
1062 long l; | 1151 long l; |
1063 | 1152 |
1064 /* FIXME: Perhaps check overflow of the "single". */ | 1153 /* FIXME: Perhaps check overflow of the "single". */ |
1065 REAL_VALUE_FROM_CONST_DOUBLE (r, operand); | 1154 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operand), l); |
1066 REAL_VALUE_TO_TARGET_SINGLE (r, l); | |
1067 | 1155 |
1068 fprintf (file, "0x%lx", l); | 1156 fprintf (file, "0x%lx", l); |
1069 } | 1157 } |
1070 return; | 1158 return; |
1071 | 1159 |
1099 } | 1187 } |
1100 | 1188 |
1101 default: | 1189 default: |
1102 /* No need to handle all strange variants, let output_addr_const | 1190 /* No need to handle all strange variants, let output_addr_const |
1103 do it for us. */ | 1191 do it for us. */ |
1104 if (CONSTANT_P (operand)) | 1192 if (CRIS_CONSTANT_P (operand)) |
1105 { | 1193 { |
1106 cris_output_addr_const (file, operand); | 1194 cris_output_addr_const (file, operand); |
1107 return; | 1195 return; |
1108 } | 1196 } |
1109 | 1197 |
1118 } | 1206 } |
1119 | 1207 |
1120 /* The PRINT_OPERAND_ADDRESS worker. */ | 1208 /* The PRINT_OPERAND_ADDRESS worker. */ |
1121 | 1209 |
1122 static void | 1210 static void |
1123 cris_print_operand_address (FILE *file, rtx x) | 1211 cris_print_operand_address (FILE *file, machine_mode /*mode*/, rtx x) |
1124 { | 1212 { |
1125 /* All these were inside MEM:s so output indirection characters. */ | 1213 /* All these were inside MEM:s so output indirection characters. */ |
1126 putc ('[', file); | 1214 putc ('[', file); |
1127 | 1215 |
1128 if (CONSTANT_ADDRESS_P (x)) | 1216 if (CONSTANT_ADDRESS_P (x)) |
1129 cris_output_addr_const (file, x); | 1217 cris_output_addr_const (file, x); |
1130 else if (BASE_OR_AUTOINCR_P (x)) | 1218 else if (cris_base_or_autoincr_p (x, true)) |
1131 cris_print_base (x, file); | 1219 cris_print_base (x, file); |
1132 else if (GET_CODE (x) == PLUS) | 1220 else if (GET_CODE (x) == PLUS) |
1133 { | 1221 { |
1134 rtx x1, x2; | 1222 rtx x1, x2; |
1135 | 1223 |
1136 x1 = XEXP (x, 0); | 1224 x1 = XEXP (x, 0); |
1137 x2 = XEXP (x, 1); | 1225 x2 = XEXP (x, 1); |
1138 if (BASE_P (x1)) | 1226 if (cris_base_p (x1, true)) |
1139 { | 1227 { |
1140 cris_print_base (x1, file); | 1228 cris_print_base (x1, file); |
1141 cris_print_index (x2, file); | 1229 cris_print_index (x2, file); |
1142 } | 1230 } |
1143 else if (BASE_P (x2)) | 1231 else if (cris_base_p (x2, true)) |
1144 { | 1232 { |
1145 cris_print_base (x2, file); | 1233 cris_print_base (x2, file); |
1146 cris_print_index (x1, file); | 1234 cris_print_index (x1, file); |
1147 } | 1235 } |
1148 else | 1236 else |
1176 | 1264 |
1177 /* The return-address is stored just above the saved frame-pointer (if | 1265 /* The return-address is stored just above the saved frame-pointer (if |
1178 present). Apparently we can't eliminate from the frame-pointer in | 1266 present). Apparently we can't eliminate from the frame-pointer in |
1179 that direction, so use the incoming args (maybe pretended) pointer. */ | 1267 that direction, so use the incoming args (maybe pretended) pointer. */ |
1180 return count == 0 | 1268 return count == 0 |
1181 ? gen_rtx_MEM (Pmode, plus_constant (virtual_incoming_args_rtx, -4)) | 1269 ? gen_rtx_MEM (Pmode, plus_constant (Pmode, virtual_incoming_args_rtx, -4)) |
1182 : NULL_RTX; | 1270 : NULL_RTX; |
1183 } | 1271 } |
1184 | 1272 |
1185 /* Accessor used in cris.md:return because cfun->machine isn't available | 1273 /* Accessor used in cris.md:return because cfun->machine isn't available |
1186 there. */ | 1274 there. */ |
1200 { | 1288 { |
1201 return cfun->machine->return_type == CRIS_RETINSN_RET ? false | 1289 return cfun->machine->return_type == CRIS_RETINSN_RET ? false |
1202 : cris_return_address_on_stack (); | 1290 : cris_return_address_on_stack (); |
1203 } | 1291 } |
1204 | 1292 |
1205 /* This used to be the INITIAL_FRAME_POINTER_OFFSET worker; now only | 1293 /* This handles FP -> SP elimination offset. */ |
1206 handles FP -> SP elimination offset. */ | |
1207 | 1294 |
1208 static int | 1295 static int |
1209 cris_initial_frame_pointer_offset (void) | 1296 cris_initial_frame_pointer_offset (void) |
1210 { | 1297 { |
1211 int regno; | 1298 int regno; |
1217 if (crtl->uses_pic_offset_table) | 1304 if (crtl->uses_pic_offset_table) |
1218 { | 1305 { |
1219 push_topmost_sequence (); | 1306 push_topmost_sequence (); |
1220 got_really_used | 1307 got_really_used |
1221 = reg_used_between_p (pic_offset_table_rtx, get_insns (), | 1308 = reg_used_between_p (pic_offset_table_rtx, get_insns (), |
1222 NULL_RTX); | 1309 NULL); |
1223 pop_topmost_sequence (); | 1310 pop_topmost_sequence (); |
1224 } | 1311 } |
1225 | 1312 |
1226 /* And 4 for each register pushed. */ | 1313 /* And 4 for each register pushed. */ |
1227 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) | 1314 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) |
1275 return ap_fp_offset + fp_sp_offset - 4; | 1362 return ap_fp_offset + fp_sp_offset - 4; |
1276 | 1363 |
1277 gcc_unreachable (); | 1364 gcc_unreachable (); |
1278 } | 1365 } |
1279 | 1366 |
1367 /* Nonzero if X is a hard reg that can be used as an index. */ | |
1368 static inline bool | |
1369 reg_ok_for_base_p (const_rtx x, bool strict) | |
1370 { | |
1371 return ((! strict && ! HARD_REGISTER_P (x)) | |
1372 || REGNO_OK_FOR_BASE_P (REGNO (x))); | |
1373 } | |
1374 | |
1375 /* Nonzero if X is a hard reg that can be used as an index. */ | |
1376 static inline bool | |
1377 reg_ok_for_index_p (const_rtx x, bool strict) | |
1378 { | |
1379 return reg_ok_for_base_p (x, strict); | |
1380 } | |
1381 | |
1382 /* No symbol can be used as an index (or more correct, as a base) together | |
1383 with a register with PIC; the PIC register must be there. */ | |
1384 | |
1385 bool | |
1386 cris_constant_index_p (const_rtx x) | |
1387 { | |
1388 return (CRIS_CONSTANT_P (x) && (!flag_pic || cris_valid_pic_const (x, true))); | |
1389 } | |
1390 | |
1391 /* True if X is a valid base register. */ | |
1392 | |
1393 bool | |
1394 cris_base_p (const_rtx x, bool strict) | |
1395 { | |
1396 return (REG_P (x) && reg_ok_for_base_p (x, strict)); | |
1397 } | |
1398 | |
1399 /* True if X is a valid index register. */ | |
1400 | |
1401 static inline bool | |
1402 cris_index_p (const_rtx x, bool strict) | |
1403 { | |
1404 return (REG_P (x) && reg_ok_for_index_p (x, strict)); | |
1405 } | |
1406 | |
1407 /* True if X is a valid base register with or without autoincrement. */ | |
1408 | |
1409 bool | |
1410 cris_base_or_autoincr_p (const_rtx x, bool strict) | |
1411 { | |
1412 return (cris_base_p (x, strict) | |
1413 || (GET_CODE (x) == POST_INC | |
1414 && cris_base_p (XEXP (x, 0), strict) | |
1415 && REGNO (XEXP (x, 0)) != CRIS_ACR_REGNUM)); | |
1416 } | |
1417 | |
1418 /* True if X is a valid (register) index for BDAP, i.e. [Rs].S or [Rs+].S. */ | |
1419 | |
1420 bool | |
1421 cris_bdap_index_p (const_rtx x, bool strict) | |
1422 { | |
1423 return ((MEM_P (x) | |
1424 && GET_MODE (x) == SImode | |
1425 && cris_base_or_autoincr_p (XEXP (x, 0), strict)) | |
1426 || (GET_CODE (x) == SIGN_EXTEND | |
1427 && MEM_P (XEXP (x, 0)) | |
1428 && (GET_MODE (XEXP (x, 0)) == HImode | |
1429 || GET_MODE (XEXP (x, 0)) == QImode) | |
1430 && cris_base_or_autoincr_p (XEXP (XEXP (x, 0), 0), strict))); | |
1431 } | |
1432 | |
1433 /* True if X is a valid (register) index for BIAP, i.e. Rd.m. */ | |
1434 | |
1435 bool | |
1436 cris_biap_index_p (const_rtx x, bool strict) | |
1437 { | |
1438 return (cris_index_p (x, strict) | |
1439 || (GET_CODE (x) == MULT | |
1440 && cris_index_p (XEXP (x, 0), strict) | |
1441 && cris_scale_int_operand (XEXP (x, 1), VOIDmode))); | |
1442 } | |
1443 | |
1444 /* Worker function for TARGET_LEGITIMATE_ADDRESS_P. | |
1445 | |
1446 A PIC operand looks like a normal symbol here. At output we dress it | |
1447 in "[rPIC+symbol:GOT]" (global symbol) or "rPIC+symbol:GOTOFF" (local | |
1448 symbol) so we exclude all addressing modes where we can't replace a | |
1449 plain "symbol" with that. A global PIC symbol does not fit anywhere | |
1450 here (but is thankfully a general_operand in itself). A local PIC | |
1451 symbol is valid for the plain "symbol + offset" case. */ | |
1452 | |
1453 bool | |
1454 cris_legitimate_address_p (machine_mode mode, rtx x, bool strict) | |
1455 { | |
1456 const_rtx x1, x2; | |
1457 | |
1458 if (cris_base_or_autoincr_p (x, strict)) | |
1459 return true; | |
1460 else if (TARGET_V32) | |
1461 /* Nothing else is valid then. */ | |
1462 return false; | |
1463 else if (cris_constant_index_p (x)) | |
1464 return true; | |
1465 /* Indexed? */ | |
1466 else if (GET_CODE (x) == PLUS) | |
1467 { | |
1468 x1 = XEXP (x, 0); | |
1469 x2 = XEXP (x, 1); | |
1470 /* BDAP o, Rd. */ | |
1471 if ((cris_base_p (x1, strict) && cris_constant_index_p (x2)) | |
1472 || (cris_base_p (x2, strict) && cris_constant_index_p (x1)) | |
1473 /* BDAP Rs[+], Rd. */ | |
1474 || (GET_MODE_SIZE (mode) <= UNITS_PER_WORD | |
1475 && ((cris_base_p (x1, strict) | |
1476 && cris_bdap_index_p (x2, strict)) | |
1477 || (cris_base_p (x2, strict) | |
1478 && cris_bdap_index_p (x1, strict)) | |
1479 /* BIAP.m Rs, Rd */ | |
1480 || (cris_base_p (x1, strict) | |
1481 && cris_biap_index_p (x2, strict)) | |
1482 || (cris_base_p (x2, strict) | |
1483 && cris_biap_index_p (x1, strict))))) | |
1484 return true; | |
1485 } | |
1486 else if (MEM_P (x)) | |
1487 { | |
1488 /* DIP (Rs). Reject [[reg+]] and [[reg]] for DImode (long long). */ | |
1489 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD | |
1490 && cris_base_or_autoincr_p (XEXP (x, 0), strict)) | |
1491 return true; | |
1492 } | |
1493 | |
1494 return false; | |
1495 } | |
1496 | |
1497 /* Worker function for TARGET_LEGITIMATE_CONSTANT_P. We have to handle | |
1498 PIC constants that aren't legitimized. FIXME: there used to be a | |
1499 guarantee that the target LEGITIMATE_CONSTANT_P didn't have to handle | |
1500 PIC constants, but no more (4.7 era); testcase: glibc init-first.c. | |
1501 While that may be seen as a bug, that guarantee seems a wart by design, | |
1502 so don't bother; fix the documentation instead. */ | |
1503 | |
1504 bool | |
1505 cris_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x) | |
1506 { | |
1507 enum cris_symbol_type t; | |
1508 | |
1509 if (flag_pic) | |
1510 return LEGITIMATE_PIC_OPERAND_P (x); | |
1511 | |
1512 t = cris_symbol_type_of (x); | |
1513 | |
1514 return | |
1515 t == cris_no_symbol | |
1516 || t == cris_offsettable_symbol | |
1517 || t == cris_unspec; | |
1518 } | |
1519 | |
1280 /* Worker function for LEGITIMIZE_RELOAD_ADDRESS. */ | 1520 /* Worker function for LEGITIMIZE_RELOAD_ADDRESS. */ |
1281 | 1521 |
1282 bool | 1522 bool |
1283 cris_reload_address_legitimized (rtx x, | 1523 cris_reload_address_legitimized (rtx x, |
1284 enum machine_mode mode ATTRIBUTE_UNUSED, | 1524 machine_mode mode ATTRIBUTE_UNUSED, |
1285 int opnum ATTRIBUTE_UNUSED, | 1525 int opnum ATTRIBUTE_UNUSED, |
1286 int itype, | 1526 int itype, |
1287 int ind_levels ATTRIBUTE_UNUSED) | 1527 int ind_levels ATTRIBUTE_UNUSED) |
1288 { | 1528 { |
1289 enum reload_type type = (enum reload_type) itype; | 1529 enum reload_type type = (enum reload_type) itype; |
1350 } | 1590 } |
1351 | 1591 |
1352 return false; | 1592 return false; |
1353 } | 1593 } |
1354 | 1594 |
1595 | |
1596 /* Worker function for TARGET_PREFERRED_RELOAD_CLASS. | |
1597 | |
1598 It seems like gcc (2.7.2 and 2.9x of 2000-03-22) may send "NO_REGS" as | |
1599 the class for a constant (testcase: __Mul in arit.c). To avoid forcing | |
1600 out a constant into the constant pool, we will trap this case and | |
1601 return something a bit more sane. FIXME: Check if this is a bug. | |
1602 Beware that we must not "override" classes that can be specified as | |
1603 constraint letters, or else asm operands using them will fail when | |
1604 they need to be reloaded. FIXME: Investigate whether that constitutes | |
1605 a bug. */ | |
1606 | |
1607 static reg_class_t | |
1608 cris_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, reg_class_t rclass) | |
1609 { | |
1610 if (rclass != ACR_REGS | |
1611 && rclass != MOF_REGS | |
1612 && rclass != MOF_SRP_REGS | |
1613 && rclass != SRP_REGS | |
1614 && rclass != CC0_REGS | |
1615 && rclass != SPECIAL_REGS) | |
1616 return GENNONACR_REGS; | |
1617 | |
1618 return rclass; | |
1619 } | |
1620 | |
1355 /* Worker function for TARGET_REGISTER_MOVE_COST. */ | 1621 /* Worker function for TARGET_REGISTER_MOVE_COST. */ |
1356 | 1622 |
1357 static int | 1623 static int |
1358 cris_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED, | 1624 cris_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED, |
1359 reg_class_t from, reg_class_t to) | 1625 reg_class_t from, reg_class_t to) |
1360 { | 1626 { |
1361 if (!TARGET_V32) | |
1362 { | |
1363 /* Pretend that classes that we don't support are ALL_REGS, so | |
1364 we give them the highest cost. */ | |
1365 if (from != SPECIAL_REGS && from != MOF_REGS | |
1366 && from != GENERAL_REGS && from != GENNONACR_REGS) | |
1367 from = ALL_REGS; | |
1368 | |
1369 if (to != SPECIAL_REGS && to != MOF_REGS | |
1370 && to != GENERAL_REGS && to != GENNONACR_REGS) | |
1371 to = ALL_REGS; | |
1372 } | |
1373 | |
1374 /* Can't move to and from a SPECIAL_REGS register, so we have to say | 1627 /* Can't move to and from a SPECIAL_REGS register, so we have to say |
1375 their move cost within that class is higher. How about 7? That's 3 | 1628 their move cost within that class is higher. How about 7? That's 3 |
1376 for a move to a GENERAL_REGS register, 3 for the move from the | 1629 for a move to a GENERAL_REGS register, 3 for the move from the |
1377 GENERAL_REGS register, and 1 for the increased register pressure. | 1630 GENERAL_REGS register, and 1 for the increased register pressure. |
1378 Also, it's higher than the memory move cost, which is in order. | 1631 Also, it's higher than the memory move cost, as it should. |
1379 We also do this for ALL_REGS, since we don't want that class to be | 1632 We also do this for ALL_REGS, since we don't want that class to be |
1380 preferred (even to memory) at all where GENERAL_REGS doesn't fit. | 1633 preferred (even to memory) at all where GENERAL_REGS doesn't fit. |
1381 Whenever it's about to be used, it's for SPECIAL_REGS. If we don't | 1634 Whenever it's about to be used, it's for SPECIAL_REGS. If we don't |
1382 present a higher cost for ALL_REGS than memory, a SPECIAL_REGS may be | 1635 present a higher cost for ALL_REGS than memory, a SPECIAL_REGS may be |
1383 used when a GENERAL_REGS should be used, even if there are call-saved | 1636 used when a GENERAL_REGS should be used, even if there are call-saved |
1384 GENERAL_REGS left to allocate. This is because the fall-back when | 1637 GENERAL_REGS left to allocate. This is because the fall-back when |
1385 the most preferred register class isn't available, isn't the next | 1638 the most preferred register class isn't available, isn't the next |
1386 (or next good) wider register class, but the *most widest* register | 1639 (or next good) wider register class, but the *most widest* register |
1387 class. */ | 1640 class. FIXME: pre-IRA comment, perhaps obsolete now. */ |
1388 | 1641 |
1389 if ((reg_classes_intersect_p (from, SPECIAL_REGS) | 1642 if ((reg_classes_intersect_p (from, SPECIAL_REGS) |
1390 && reg_classes_intersect_p (to, SPECIAL_REGS)) | 1643 && reg_classes_intersect_p (to, SPECIAL_REGS)) |
1391 || from == ALL_REGS || to == ALL_REGS) | 1644 || from == ALL_REGS || to == ALL_REGS) |
1392 return 7; | 1645 return 7; |
1393 | 1646 |
1647 /* Make moves to/from SPECIAL_REGS slightly more expensive, as we | |
1648 generally prefer GENERAL_REGS. */ | |
1394 if (reg_classes_intersect_p (from, SPECIAL_REGS) | 1649 if (reg_classes_intersect_p (from, SPECIAL_REGS) |
1395 || reg_classes_intersect_p (to, SPECIAL_REGS)) | 1650 || reg_classes_intersect_p (to, SPECIAL_REGS)) |
1396 return 3; | 1651 return 3; |
1397 | 1652 |
1398 return 2; | 1653 return 2; |
1402 | 1657 |
1403 This isn't strictly correct for v0..3 in buswidth-8bit mode, but should | 1658 This isn't strictly correct for v0..3 in buswidth-8bit mode, but should |
1404 suffice. */ | 1659 suffice. */ |
1405 | 1660 |
1406 static int | 1661 static int |
1407 cris_memory_move_cost (enum machine_mode mode, | 1662 cris_memory_move_cost (machine_mode mode, |
1408 reg_class_t rclass ATTRIBUTE_UNUSED, | 1663 reg_class_t rclass ATTRIBUTE_UNUSED, |
1409 bool in ATTRIBUTE_UNUSED) | 1664 bool in ATTRIBUTE_UNUSED) |
1410 { | 1665 { |
1411 if (mode == QImode | 1666 if (mode == QImode |
1412 || mode == HImode) | 1667 || mode == HImode) |
1546 else if (SET_SRC (exp) == const0_rtx | 1801 else if (SET_SRC (exp) == const0_rtx |
1547 || (REG_P (SET_SRC (exp)) | 1802 || (REG_P (SET_SRC (exp)) |
1548 && (REGNO (SET_SRC (exp)) | 1803 && (REGNO (SET_SRC (exp)) |
1549 > CRIS_LAST_GENERAL_REGISTER)) | 1804 > CRIS_LAST_GENERAL_REGISTER)) |
1550 || (TARGET_V32 | 1805 || (TARGET_V32 |
1551 && GET_CODE (SET_SRC (exp)) == CONST_INT | 1806 && REG_P (SET_DEST (exp)) |
1552 && CRIS_CONST_OK_FOR_LETTER_P (INTVAL (SET_SRC (exp)), | 1807 && satisfies_constraint_I (SET_SRC (exp)))) |
1553 'I'))) | |
1554 { | 1808 { |
1555 /* There's no CC0 change for this case. Just check | 1809 /* There's no CC0 change for this case. Just check |
1556 for overlap. */ | 1810 for overlap. */ |
1557 if (cc_status.value1 | 1811 if (cc_status.value1 |
1558 && modified_in_p (cc_status.value1, insn)) | 1812 && modified_in_p (cc_status.value1, insn)) |
1669 | 1923 |
1670 Currently a jumble of the old peek-inside-the-insn and the newer | 1924 Currently a jumble of the old peek-inside-the-insn and the newer |
1671 check-cc-attribute methods. */ | 1925 check-cc-attribute methods. */ |
1672 | 1926 |
1673 void | 1927 void |
1674 cris_notice_update_cc (rtx exp, rtx insn) | 1928 cris_notice_update_cc (rtx exp, rtx_insn *insn) |
1675 { | 1929 { |
1676 enum attr_cc attrval = get_attr_cc (insn); | 1930 enum attr_cc attrval = get_attr_cc (insn); |
1677 | 1931 |
1678 /* Check if user specified "-mcc-init" as a bug-workaround. Remember | 1932 /* Check if user specified "-mcc-init" as a bug-workaround. Remember |
1679 to still set CC_REVERSED as below, since that's required by some | 1933 to still set CC_REVERSED as below, since that's required by some |
1762 | 2016 |
1763 if (crtl->uses_pic_offset_table) | 2017 if (crtl->uses_pic_offset_table) |
1764 { | 2018 { |
1765 push_topmost_sequence (); | 2019 push_topmost_sequence (); |
1766 got_really_used | 2020 got_really_used |
1767 = reg_used_between_p (pic_offset_table_rtx, get_insns (), NULL_RTX); | 2021 = reg_used_between_p (pic_offset_table_rtx, get_insns (), NULL); |
1768 pop_topmost_sequence (); | 2022 pop_topmost_sequence (); |
1769 } | 2023 } |
1770 | 2024 |
1771 /* No simple epilogue if there are saved registers. */ | 2025 /* No simple epilogue if there are saved registers. */ |
1772 for (regno = 0; regno < reglimit; regno++) | 2026 for (regno = 0; regno < reglimit; regno++) |
1773 if (cris_reg_saved_in_regsave_area (regno, got_really_used)) | 2027 if (cris_reg_saved_in_regsave_area (regno, got_really_used)) |
1774 return false; | 2028 return false; |
1775 | 2029 |
1776 return true; | 2030 return true; |
2031 } | |
2032 | |
2033 /* Emit checking that MEM is aligned for an access in MODE, failing | |
2034 that, executing a "break 8" (or call to abort, if "break 8" is | |
2035 disabled). */ | |
2036 | |
2037 void | |
2038 cris_emit_trap_for_misalignment (rtx mem) | |
2039 { | |
2040 rtx addr, reg, ok_label, andop; | |
2041 rtx_insn *jmp; | |
2042 int natural_alignment; | |
2043 gcc_assert (MEM_P (mem)); | |
2044 | |
2045 natural_alignment = GET_MODE_SIZE (GET_MODE (mem)); | |
2046 addr = XEXP (mem, 0); | |
2047 reg = force_reg (Pmode, addr); | |
2048 ok_label = gen_label_rtx (); | |
2049 | |
2050 /* This will yield a btstq without a separate register used, usually - | |
2051 with the exception for PRE hoisting the "and" but not the branch | |
2052 around the trap: see testsuite/gcc.target/cris/sync-3s.c. */ | |
2053 andop = gen_rtx_AND (Pmode, reg, GEN_INT (natural_alignment - 1)); | |
2054 emit_cmp_and_jump_insns (force_reg (SImode, andop), const0_rtx, EQ, | |
2055 NULL_RTX, Pmode, 1, ok_label); | |
2056 jmp = get_last_insn (); | |
2057 gcc_assert (JUMP_P (jmp)); | |
2058 | |
2059 predict_insn_def (jmp, PRED_NORETURN, TAKEN); | |
2060 expand_builtin_trap (); | |
2061 emit_label (ok_label); | |
1777 } | 2062 } |
1778 | 2063 |
1779 /* Expand a return insn (just one insn) marked as using SRP or stack | 2064 /* Expand a return insn (just one insn) marked as using SRP or stack |
1780 slot depending on parameter ON_STACK. */ | 2065 slot depending on parameter ON_STACK. */ |
1781 | 2066 |
1786 tell "ret" from "jump [sp+]". Some, but not all, other parts of | 2071 tell "ret" from "jump [sp+]". Some, but not all, other parts of |
1787 GCC expect just (return) to do the right thing when optimizing, so | 2072 GCC expect just (return) to do the right thing when optimizing, so |
1788 we do that until they're fixed. Currently, all return insns in a | 2073 we do that until they're fixed. Currently, all return insns in a |
1789 function must be the same (not really a limiting factor) so we need | 2074 function must be the same (not really a limiting factor) so we need |
1790 to check that it doesn't change half-way through. */ | 2075 to check that it doesn't change half-way through. */ |
1791 emit_jump_insn (gen_rtx_RETURN (VOIDmode)); | 2076 emit_jump_insn (ret_rtx); |
1792 | 2077 |
1793 CRIS_ASSERT (cfun->machine->return_type != CRIS_RETINSN_RET || !on_stack); | 2078 CRIS_ASSERT (cfun->machine->return_type != CRIS_RETINSN_RET || !on_stack); |
1794 CRIS_ASSERT (cfun->machine->return_type != CRIS_RETINSN_JUMP || on_stack); | 2079 CRIS_ASSERT (cfun->machine->return_type != CRIS_RETINSN_JUMP || on_stack); |
1795 | 2080 |
1796 cfun->machine->return_type | 2081 cfun->machine->return_type |
1800 /* Compute a (partial) cost for rtx X. Return true if the complete | 2085 /* Compute a (partial) cost for rtx X. Return true if the complete |
1801 cost has been computed, and false if subexpressions should be | 2086 cost has been computed, and false if subexpressions should be |
1802 scanned. In either case, *TOTAL contains the cost result. */ | 2087 scanned. In either case, *TOTAL contains the cost result. */ |
1803 | 2088 |
1804 static bool | 2089 static bool |
1805 cris_rtx_costs (rtx x, int code, int outer_code, int *total, | 2090 cris_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno, |
1806 bool speed) | 2091 int *total, bool speed) |
1807 { | 2092 { |
2093 int code = GET_CODE (x); | |
2094 | |
1808 switch (code) | 2095 switch (code) |
1809 { | 2096 { |
1810 case CONST_INT: | 2097 case CONST_INT: |
1811 { | 2098 { |
1812 HOST_WIDE_INT val = INTVAL (x); | 2099 HOST_WIDE_INT val = INTVAL (x); |
1832 case SYMBOL_REF: | 2119 case SYMBOL_REF: |
1833 *total = 6; | 2120 *total = 6; |
1834 return true; | 2121 return true; |
1835 | 2122 |
1836 case CONST_DOUBLE: | 2123 case CONST_DOUBLE: |
1837 if (x != CONST0_RTX (GET_MODE (x) == VOIDmode ? DImode : GET_MODE (x))) | 2124 if (x != CONST0_RTX (mode == VOIDmode ? DImode : mode)) |
1838 *total = 12; | 2125 *total = 12; |
1839 else | 2126 else |
1840 /* Make 0.0 cheap, else test-insns will not be used. */ | 2127 /* Make 0.0 cheap, else test-insns will not be used. */ |
1841 *total = 0; | 2128 *total = 0; |
1842 return true; | 2129 return true; |
1849 combined value be larger than the separate insns. The insn | 2136 combined value be larger than the separate insns. The insn |
1850 validity is checked elsewhere by combine. | 2137 validity is checked elsewhere by combine. |
1851 | 2138 |
1852 FIXME: this case is a stop-gap for 4.3 and 4.4, this whole | 2139 FIXME: this case is a stop-gap for 4.3 and 4.4, this whole |
1853 function should be rewritten. */ | 2140 function should be rewritten. */ |
1854 if (outer_code == PLUS && BIAP_INDEX_P (x)) | 2141 if (outer_code == PLUS && cris_biap_index_p (x, false)) |
1855 { | 2142 { |
1856 *total = 0; | 2143 *total = 0; |
1857 return true; | 2144 return true; |
1858 } | 2145 } |
1859 | 2146 |
1891 | 2178 |
1892 case AND: | 2179 case AND: |
1893 if (CONST_INT_P (XEXP (x, 1)) | 2180 if (CONST_INT_P (XEXP (x, 1)) |
1894 /* Two constants may actually happen before optimization. */ | 2181 /* Two constants may actually happen before optimization. */ |
1895 && !CONST_INT_P (XEXP (x, 0)) | 2182 && !CONST_INT_P (XEXP (x, 0)) |
1896 && !CRIS_CONST_OK_FOR_LETTER_P (INTVAL (XEXP (x, 1)), 'I')) | 2183 && !satisfies_constraint_I (XEXP (x, 1))) |
1897 { | 2184 { |
1898 *total | 2185 *total |
1899 = (rtx_cost (XEXP (x, 0), (enum rtx_code) outer_code, speed) + 2 | 2186 = (rtx_cost (XEXP (x, 0), mode, (enum rtx_code) outer_code, |
1900 + 2 * GET_MODE_NUNITS (GET_MODE (XEXP (x, 0)))); | 2187 opno, speed) + 2 |
2188 + 2 * GET_MODE_NUNITS (mode)); | |
1901 return true; | 2189 return true; |
1902 } | 2190 } |
1903 return false; | 2191 return false; |
1904 | 2192 |
1905 case ZERO_EXTRACT: | 2193 case ZERO_EXTRACT: |
1906 if (outer_code != COMPARE) | 2194 if (outer_code != COMPARE) |
1907 return false; | 2195 return false; |
1908 /* fall through */ | 2196 /* fall through */ |
1909 | 2197 |
1910 case ZERO_EXTEND: case SIGN_EXTEND: | 2198 case ZERO_EXTEND: case SIGN_EXTEND: |
1911 *total = rtx_cost (XEXP (x, 0), (enum rtx_code) outer_code, speed); | 2199 *total = rtx_cost (XEXP (x, 0), VOIDmode, (enum rtx_code) outer_code, |
2200 opno, speed); | |
1912 return true; | 2201 return true; |
1913 | 2202 |
1914 default: | 2203 default: |
1915 return false; | 2204 return false; |
1916 } | 2205 } |
1917 } | 2206 } |
1918 | 2207 |
1919 /* The ADDRESS_COST worker. */ | 2208 /* The ADDRESS_COST worker. */ |
1920 | 2209 |
1921 static int | 2210 static int |
1922 cris_address_cost (rtx x, bool speed ATTRIBUTE_UNUSED) | 2211 cris_address_cost (rtx x, machine_mode mode ATTRIBUTE_UNUSED, |
2212 addr_space_t as ATTRIBUTE_UNUSED, | |
2213 bool speed ATTRIBUTE_UNUSED) | |
1923 { | 2214 { |
1924 /* The metric to use for the cost-macros is unclear. | 2215 /* The metric to use for the cost-macros is unclear. |
1925 The metric used here is (the number of cycles needed) / 2, | 2216 The metric used here is (the number of cycles needed) / 2, |
1926 where we consider equal a cycle for a word of code and a cycle to | 2217 where we consider equal a cycle for a word of code and a cycle to |
1927 read memory. FIXME: Adding "+ 1" to all values would avoid | 2218 read memory. FIXME: Adding "+ 1" to all values would avoid |
1930 Unfortunately(?) such a hack would expose other pessimizations, | 2221 Unfortunately(?) such a hack would expose other pessimizations, |
1931 at least with g++.dg/tree-ssa/ivopts-1.C, adding insns to the | 2222 at least with g++.dg/tree-ssa/ivopts-1.C, adding insns to the |
1932 loop there, without apparent reason. */ | 2223 loop there, without apparent reason. */ |
1933 | 2224 |
1934 /* The cheapest addressing modes get 0, since nothing extra is needed. */ | 2225 /* The cheapest addressing modes get 0, since nothing extra is needed. */ |
1935 if (BASE_OR_AUTOINCR_P (x)) | 2226 if (cris_base_or_autoincr_p (x, false)) |
1936 return 0; | 2227 return 0; |
1937 | 2228 |
1938 /* An indirect mem must be a DIP. This means two bytes extra for code, | 2229 /* An indirect mem must be a DIP. This means two bytes extra for code, |
1939 and 4 bytes extra for memory read, i.e. (2 + 4) / 2. */ | 2230 and 4 bytes extra for memory read, i.e. (2 + 4) / 2. */ |
1940 if (MEM_P (x)) | 2231 if (MEM_P (x)) |
1960 gcc_assert (REG_P (tem1) || GET_CODE (tem1) == MULT); | 2251 gcc_assert (REG_P (tem1) || GET_CODE (tem1) == MULT); |
1961 | 2252 |
1962 /* A BIAP is 2 extra bytes for the prefix insn, nothing more. We | 2253 /* A BIAP is 2 extra bytes for the prefix insn, nothing more. We |
1963 recognize the typical MULT which is always in tem1 because of | 2254 recognize the typical MULT which is always in tem1 because of |
1964 insn canonicalization. */ | 2255 insn canonicalization. */ |
1965 if ((GET_CODE (tem1) == MULT && BIAP_INDEX_P (tem1)) | 2256 if ((GET_CODE (tem1) == MULT && cris_biap_index_p (tem1, false)) |
1966 || REG_P (tem2)) | 2257 || REG_P (tem2)) |
1967 return 2 / 2; | 2258 return 2 / 2; |
1968 | 2259 |
1969 /* A BDAP (quick) is 2 extra bytes. Any constant operand to the | 2260 /* A BDAP (quick) is 2 extra bytes. Any constant operand to the |
1970 PLUS is always found in tem2. */ | 2261 PLUS is always found in tem2. */ |
1971 if (CONST_INT_P (tem2) && INTVAL (tem2) < 128 && INTVAL (tem2) >= -128) | 2262 if (CONST_INT_P (tem2) && INTVAL (tem2) < 128 && INTVAL (tem2) >= -128) |
1972 return 2 / 2; | 2263 return 2 / 2; |
1973 | 2264 |
1974 /* A BDAP -32768 .. 32767 is like BDAP quick, but with 2 extra | 2265 /* A BDAP -32768 .. 32767 is like BDAP quick, but with 2 extra |
1975 bytes. */ | 2266 bytes. */ |
1976 if (CONST_INT_P (tem2) | 2267 if (satisfies_constraint_L (tem2)) |
1977 && CRIS_CONST_OK_FOR_LETTER_P (INTVAL (tem2), 'L')) | |
1978 return (2 + 2) / 2; | 2268 return (2 + 2) / 2; |
1979 | 2269 |
1980 /* A BDAP with some other constant is 2 bytes extra. */ | 2270 /* A BDAP with some other constant is 2 bytes extra. */ |
1981 if (CONSTANT_P (tem2)) | 2271 if (CRIS_CONSTANT_P (tem2)) |
1982 return (2 + 2 + 2) / 2; | 2272 return (2 + 2 + 2) / 2; |
1983 | 2273 |
1984 /* BDAP with something indirect should have a higher cost than | 2274 /* BDAP with something indirect should have a higher cost than |
1985 BIAP with register. FIXME: Should it cost like a MEM or more? */ | 2275 BIAP with register. FIXME: Should it cost like a MEM or more? */ |
1986 return (2 + 2 + 2) / 2; | 2276 return (2 + 2 + 2) / 2; |
2018 rtx val_rtx = ops[rval]; | 2308 rtx val_rtx = ops[rval]; |
2019 | 2309 |
2020 /* The operands may be swapped. Canonicalize them in reg_rtx and | 2310 /* The operands may be swapped. Canonicalize them in reg_rtx and |
2021 val_rtx, where reg_rtx always is a reg (for this constraint to | 2311 val_rtx, where reg_rtx always is a reg (for this constraint to |
2022 match). */ | 2312 match). */ |
2023 if (! BASE_P (reg_rtx)) | 2313 if (! cris_base_p (reg_rtx, reload_in_progress || reload_completed)) |
2024 reg_rtx = val_rtx, val_rtx = ops[rreg]; | 2314 reg_rtx = val_rtx, val_rtx = ops[rreg]; |
2025 | 2315 |
2026 /* Don't forget to check that reg_rtx really is a reg. If it isn't, | 2316 /* Don't forget to check that reg_rtx really is a reg. If it isn't, |
2027 we have no business. */ | 2317 we have no business. */ |
2028 if (! BASE_P (reg_rtx)) | 2318 if (! cris_base_p (reg_rtx, reload_in_progress || reload_completed)) |
2029 return 0; | 2319 return 0; |
2030 | 2320 |
2031 /* Don't do this when -mno-split. */ | 2321 /* Don't do this when -mno-split. */ |
2032 if (!TARGET_SIDE_EFFECT_PREFIXES) | 2322 if (!TARGET_SIDE_EFFECT_PREFIXES) |
2033 return 0; | 2323 return 0; |
2048 return 0; | 2338 return 0; |
2049 | 2339 |
2050 /* Check if the lvalue register is the same as the "other | 2340 /* Check if the lvalue register is the same as the "other |
2051 operand". If so, the result is undefined and we shouldn't do | 2341 operand". If so, the result is undefined and we shouldn't do |
2052 this. FIXME: Check again. */ | 2342 this. FIXME: Check again. */ |
2053 if ((BASE_P (ops[lreg]) | 2343 if ((cris_base_p (ops[lreg], reload_in_progress || reload_completed) |
2054 && BASE_P (ops[other_op]) | 2344 && cris_base_p (ops[other_op], |
2345 reload_in_progress || reload_completed) | |
2055 && REGNO (ops[lreg]) == REGNO (ops[other_op])) | 2346 && REGNO (ops[lreg]) == REGNO (ops[other_op])) |
2056 || rtx_equal_p (ops[other_op], ops[lreg])) | 2347 || rtx_equal_p (ops[other_op], ops[lreg])) |
2057 return 0; | 2348 return 0; |
2058 } | 2349 } |
2059 | 2350 |
2062 || ops[rval] == frame_pointer_rtx | 2353 || ops[rval] == frame_pointer_rtx |
2063 || (other_op >= 0 && ops[other_op] == frame_pointer_rtx)) | 2354 || (other_op >= 0 && ops[other_op] == frame_pointer_rtx)) |
2064 return 0; | 2355 return 0; |
2065 | 2356 |
2066 if (code == PLUS | 2357 if (code == PLUS |
2067 && ! BASE_P (val_rtx)) | 2358 && ! cris_base_p (val_rtx, reload_in_progress || reload_completed)) |
2068 { | 2359 { |
2069 | 2360 |
2070 /* Do not allow rx = rx + n if a normal add or sub with same size | 2361 /* Do not allow rx = rx + n if a normal add or sub with same size |
2071 would do. */ | 2362 would do. */ |
2072 if (rtx_equal_p (ops[lreg], reg_rtx) | 2363 if (rtx_equal_p (ops[lreg], reg_rtx) |
2073 && CONST_INT_P (val_rtx) | 2364 && CONST_INT_P (val_rtx) |
2074 && (INTVAL (val_rtx) <= 63 && INTVAL (val_rtx) >= -63)) | 2365 && (INTVAL (val_rtx) <= 63 && INTVAL (val_rtx) >= -63)) |
2075 return 0; | 2366 return 0; |
2076 | 2367 |
2077 /* Check allowed cases, like [r(+)?].[bwd] and const. */ | 2368 /* Check allowed cases, like [r(+)?].[bwd] and const. */ |
2078 if (CONSTANT_P (val_rtx)) | 2369 if (CRIS_CONSTANT_P (val_rtx)) |
2079 return 1; | 2370 return 1; |
2080 | 2371 |
2081 if (MEM_P (val_rtx) && BASE_OR_AUTOINCR_P (XEXP (val_rtx, 0))) | 2372 if (MEM_P (val_rtx) |
2373 && cris_base_or_autoincr_p (XEXP (val_rtx, 0), | |
2374 reload_in_progress || reload_completed)) | |
2082 return 1; | 2375 return 1; |
2083 | 2376 |
2084 if (GET_CODE (val_rtx) == SIGN_EXTEND | 2377 if (GET_CODE (val_rtx) == SIGN_EXTEND |
2085 && MEM_P (XEXP (val_rtx, 0)) | 2378 && MEM_P (XEXP (val_rtx, 0)) |
2086 && BASE_OR_AUTOINCR_P (XEXP (XEXP (val_rtx, 0), 0))) | 2379 && cris_base_or_autoincr_p (XEXP (XEXP (val_rtx, 0), 0), |
2380 reload_in_progress || reload_completed)) | |
2087 return 1; | 2381 return 1; |
2088 | 2382 |
2089 /* If we got here, it's not a valid addressing mode. */ | 2383 /* If we got here, it's not a valid addressing mode. */ |
2090 return 0; | 2384 return 0; |
2091 } | 2385 } |
2092 else if (code == MULT | 2386 else if (code == MULT |
2093 || (code == PLUS && BASE_P (val_rtx))) | 2387 || (code == PLUS |
2388 && cris_base_p (val_rtx, | |
2389 reload_in_progress || reload_completed))) | |
2094 { | 2390 { |
2095 /* Do not allow rx = rx + ry.S, since it doesn't give better code. */ | 2391 /* Do not allow rx = rx + ry.S, since it doesn't give better code. */ |
2096 if (rtx_equal_p (ops[lreg], reg_rtx) | 2392 if (rtx_equal_p (ops[lreg], reg_rtx) |
2097 || (mult == 1 && rtx_equal_p (ops[lreg], val_rtx))) | 2393 || (mult == 1 && rtx_equal_p (ops[lreg], val_rtx))) |
2098 return 0; | 2394 return 0; |
2100 /* Do not allow bad multiply-values. */ | 2396 /* Do not allow bad multiply-values. */ |
2101 if (mult != 1 && mult != 2 && mult != 4) | 2397 if (mult != 1 && mult != 2 && mult != 4) |
2102 return 0; | 2398 return 0; |
2103 | 2399 |
2104 /* Only allow r + ... */ | 2400 /* Only allow r + ... */ |
2105 if (! BASE_P (reg_rtx)) | 2401 if (! cris_base_p (reg_rtx, reload_in_progress || reload_completed)) |
2106 return 0; | 2402 return 0; |
2107 | 2403 |
2108 /* If we got here, all seems ok. | 2404 /* If we got here, all seems ok. |
2109 (All checks need to be done above). */ | 2405 (All checks need to be done above). */ |
2110 return 1; | 2406 return 1; |
2116 | 2412 |
2117 /* Whether next_cc0_user of insn is LE or GT or requires a real compare | 2413 /* Whether next_cc0_user of insn is LE or GT or requires a real compare |
2118 insn for other reasons. */ | 2414 insn for other reasons. */ |
2119 | 2415 |
2120 bool | 2416 bool |
2121 cris_cc0_user_requires_cmp (rtx insn) | 2417 cris_cc0_user_requires_cmp (rtx_insn *insn) |
2122 { | 2418 { |
2123 rtx cc0_user = NULL; | 2419 rtx_insn *cc0_user = NULL; |
2124 rtx body; | 2420 rtx body; |
2125 rtx set; | 2421 rtx set; |
2126 | 2422 |
2127 gcc_assert (insn != NULL); | 2423 gcc_assert (insn != NULL); |
2128 | 2424 |
2172 in = XEXP (in, 0); | 2468 in = XEXP (in, 0); |
2173 | 2469 |
2174 return reg_overlap_mentioned_p (x, in); | 2470 return reg_overlap_mentioned_p (x, in); |
2175 } | 2471 } |
2176 | 2472 |
2177 /* The TARGET_ASM_NAMED_SECTION worker. | |
2178 We just dispatch to the functions for ELF and a.out. */ | |
2179 | |
2180 void | |
2181 cris_target_asm_named_section (const char *name, unsigned int flags, | |
2182 tree decl) | |
2183 { | |
2184 if (! TARGET_ELF) | |
2185 default_no_named_section (name, flags, decl); | |
2186 else | |
2187 default_elf_asm_named_section (name, flags, decl); | |
2188 } | |
2189 | |
2190 /* Return TRUE iff X is a CONST valid for e.g. indexing. | 2473 /* Return TRUE iff X is a CONST valid for e.g. indexing. |
2191 ANY_OPERAND is 0 if X is in a CALL_P insn or movsi, 1 | 2474 ANY_OPERAND is 0 if X is in a CALL_P insn or movsi, 1 |
2192 elsewhere. */ | 2475 elsewhere. */ |
2193 | 2476 |
2194 bool | 2477 bool |
2195 cris_valid_pic_const (rtx x, bool any_operand) | 2478 cris_valid_pic_const (const_rtx x, bool any_operand) |
2196 { | 2479 { |
2197 gcc_assert (flag_pic); | 2480 gcc_assert (flag_pic); |
2198 | 2481 |
2199 switch (GET_CODE (x)) | 2482 switch (GET_CODE (x)) |
2200 { | 2483 { |
2233 return true; | 2516 return true; |
2234 default: | 2517 default: |
2235 gcc_unreachable (); | 2518 gcc_unreachable (); |
2236 } | 2519 } |
2237 | 2520 |
2238 return cris_pic_symbol_type_of (x) == cris_no_symbol; | 2521 return cris_symbol_type_of (x) == cris_no_symbol; |
2239 } | 2522 } |
2240 | 2523 |
2241 /* Helper function to find the right PIC-type symbol to generate, | 2524 /* Helper function to find the right symbol-type to generate, |
2242 given the original (non-PIC) representation. */ | 2525 given the original (non-PIC) representation. */ |
2243 | 2526 |
2244 enum cris_pic_symbol_type | 2527 enum cris_symbol_type |
2245 cris_pic_symbol_type_of (rtx x) | 2528 cris_symbol_type_of (const_rtx x) |
2246 { | 2529 { |
2247 switch (GET_CODE (x)) | 2530 switch (GET_CODE (x)) |
2248 { | 2531 { |
2249 case SYMBOL_REF: | 2532 case SYMBOL_REF: |
2250 return SYMBOL_REF_LOCAL_P (x) | 2533 return flag_pic |
2251 ? cris_rel_symbol : cris_got_symbol; | 2534 ? (SYMBOL_REF_LOCAL_P (x) |
2535 ? cris_rel_symbol : cris_got_symbol) | |
2536 : cris_offsettable_symbol; | |
2252 | 2537 |
2253 case LABEL_REF: | 2538 case LABEL_REF: |
2254 return cris_rel_symbol; | 2539 return flag_pic ? cris_rel_symbol : cris_offsettable_symbol; |
2255 | 2540 |
2256 case CONST: | 2541 case CONST: |
2257 return cris_pic_symbol_type_of (XEXP (x, 0)); | 2542 return cris_symbol_type_of (XEXP (x, 0)); |
2258 | 2543 |
2259 case PLUS: | 2544 case PLUS: |
2260 case MINUS: | 2545 case MINUS: |
2261 { | 2546 { |
2262 enum cris_pic_symbol_type t1 = cris_pic_symbol_type_of (XEXP (x, 0)); | 2547 enum cris_symbol_type t1 = cris_symbol_type_of (XEXP (x, 0)); |
2263 enum cris_pic_symbol_type t2 = cris_pic_symbol_type_of (XEXP (x, 1)); | 2548 enum cris_symbol_type t2 = cris_symbol_type_of (XEXP (x, 1)); |
2264 | 2549 |
2265 gcc_assert (t1 == cris_no_symbol || t2 == cris_no_symbol); | 2550 gcc_assert (t1 == cris_no_symbol || t2 == cris_no_symbol); |
2266 | 2551 |
2267 if (t1 == cris_got_symbol || t1 == cris_got_symbol) | 2552 if (t1 == cris_got_symbol || t2 == cris_got_symbol) |
2268 return cris_got_symbol_needing_fixup; | 2553 return cris_got_symbol_needing_fixup; |
2269 | 2554 |
2270 return t1 != cris_no_symbol ? t1 : t2; | 2555 return t1 != cris_no_symbol ? t1 : t2; |
2271 } | 2556 } |
2272 | 2557 |
2273 case CONST_INT: | 2558 case CONST_INT: |
2274 case CONST_DOUBLE: | 2559 case CONST_DOUBLE: |
2275 return cris_no_symbol; | 2560 return cris_no_symbol; |
2276 | 2561 |
2277 case UNSPEC: | 2562 case UNSPEC: |
2278 /* Likely an offsettability-test attempting to add a constant to | 2563 return cris_unspec; |
2279 a GOTREAD symbol, which can't be handled. */ | |
2280 return cris_invalid_pic_symbol; | |
2281 | 2564 |
2282 default: | 2565 default: |
2283 fatal_insn ("unrecognized supposed constant", x); | 2566 fatal_insn ("unrecognized supposed constant", x); |
2284 } | 2567 } |
2285 | 2568 |
2293 { | 2576 { |
2294 /* Symbols are not valid PIC operands as-is; just constants. */ | 2577 /* Symbols are not valid PIC operands as-is; just constants. */ |
2295 return cris_valid_pic_const (x, true); | 2578 return cris_valid_pic_const (x, true); |
2296 } | 2579 } |
2297 | 2580 |
2581 /* Queue an .ident string in the queue of top-level asm statements. | |
2582 If the front-end is done, we must be being called from toplev.c. | |
2583 In that case, do nothing. */ | |
2584 void | |
2585 cris_asm_output_ident (const char *string) | |
2586 { | |
2587 if (symtab->state != PARSING) | |
2588 return; | |
2589 | |
2590 default_asm_output_ident_directive (string); | |
2591 } | |
2592 | |
2298 /* The ASM_OUTPUT_CASE_END worker. */ | 2593 /* The ASM_OUTPUT_CASE_END worker. */ |
2299 | 2594 |
2300 void | 2595 void |
2301 cris_asm_output_case_end (FILE *stream, int num, rtx table) | 2596 cris_asm_output_case_end (FILE *stream, int num, rtx_insn *table) |
2302 { | 2597 { |
2598 /* Step back, over the label for the table, to the actual casejump and | |
2599 assert that we find only what's expected. */ | |
2600 rtx_insn *whole_jump_insn = prev_nonnote_nondebug_insn (table); | |
2601 gcc_assert (whole_jump_insn != NULL_RTX && LABEL_P (whole_jump_insn)); | |
2602 whole_jump_insn = prev_nonnote_nondebug_insn (whole_jump_insn); | |
2603 gcc_assert (whole_jump_insn != NULL_RTX | |
2604 && (JUMP_P (whole_jump_insn) | |
2605 || (TARGET_V32 && INSN_P (whole_jump_insn) | |
2606 && GET_CODE (PATTERN (whole_jump_insn)) == SEQUENCE))); | |
2607 /* Get the pattern of the casejump, so we can extract the default label. */ | |
2608 rtx whole_jump_pat = PATTERN (whole_jump_insn); | |
2609 | |
2303 if (TARGET_V32) | 2610 if (TARGET_V32) |
2304 { | 2611 { |
2305 rtx whole_jump_insn = PATTERN (PREV_INSN (PREV_INSN (table))); | |
2306 | |
2307 /* This can be a SEQUENCE, meaning the delay-slot of the jump is | 2612 /* This can be a SEQUENCE, meaning the delay-slot of the jump is |
2308 filled. */ | 2613 filled. We also output the offset word a little differently. */ |
2309 rtx parallel_jump | 2614 rtx parallel_jump |
2310 = (GET_CODE (whole_jump_insn) == SEQUENCE | 2615 = (GET_CODE (whole_jump_pat) == SEQUENCE |
2311 ? PATTERN (XVECEXP (whole_jump_insn, 0, 0)) : whole_jump_insn); | 2616 ? PATTERN (XVECEXP (whole_jump_pat, 0, 0)) : whole_jump_pat); |
2312 | 2617 |
2313 asm_fprintf (stream, | 2618 asm_fprintf (stream, |
2314 "\t.word %LL%d-.%s\n", | 2619 "\t.word %LL%d-.%s\n", |
2315 CODE_LABEL_NUMBER (XEXP (XEXP (XEXP (XVECEXP | 2620 CODE_LABEL_NUMBER (XEXP (XEXP (XEXP (XVECEXP |
2316 (parallel_jump, 0, 0), | 2621 (parallel_jump, 0, 0), |
2321 | 2626 |
2322 asm_fprintf (stream, | 2627 asm_fprintf (stream, |
2323 "\t.word %LL%d-%LL%d%s\n", | 2628 "\t.word %LL%d-%LL%d%s\n", |
2324 CODE_LABEL_NUMBER (XEXP | 2629 CODE_LABEL_NUMBER (XEXP |
2325 (XEXP | 2630 (XEXP |
2326 (XEXP | 2631 (XEXP (XVECEXP (whole_jump_pat, 0, 0), 1), |
2327 (XVECEXP | |
2328 (PATTERN | |
2329 (PREV_INSN | |
2330 (PREV_INSN (table))), 0, 0), 1), | |
2331 2), 0)), | 2632 2), 0)), |
2332 num, | 2633 num, |
2333 (TARGET_PDEBUG ? "; default" : "")); | 2634 (TARGET_PDEBUG ? "; default" : "")); |
2334 } | |
2335 | |
2336 /* TARGET_HANDLE_OPTION worker. We just store the values into local | |
2337 variables here. Checks for correct semantics are in | |
2338 cris_option_override. */ | |
2339 | |
2340 static bool | |
2341 cris_handle_option (size_t code, const char *arg ATTRIBUTE_UNUSED, | |
2342 int value ATTRIBUTE_UNUSED) | |
2343 { | |
2344 switch (code) | |
2345 { | |
2346 case OPT_metrax100: | |
2347 target_flags | |
2348 |= (MASK_SVINTO | |
2349 + MASK_ETRAX4_ADD | |
2350 + MASK_ALIGN_BY_32); | |
2351 break; | |
2352 | |
2353 case OPT_mno_etrax100: | |
2354 target_flags | |
2355 &= ~(MASK_SVINTO | |
2356 + MASK_ETRAX4_ADD | |
2357 + MASK_ALIGN_BY_32); | |
2358 break; | |
2359 | |
2360 case OPT_m32_bit: | |
2361 case OPT_m32bit: | |
2362 target_flags | |
2363 |= (MASK_STACK_ALIGN | |
2364 + MASK_CONST_ALIGN | |
2365 + MASK_DATA_ALIGN | |
2366 + MASK_ALIGN_BY_32); | |
2367 break; | |
2368 | |
2369 case OPT_m16_bit: | |
2370 case OPT_m16bit: | |
2371 target_flags | |
2372 |= (MASK_STACK_ALIGN | |
2373 + MASK_CONST_ALIGN | |
2374 + MASK_DATA_ALIGN); | |
2375 break; | |
2376 | |
2377 case OPT_m8_bit: | |
2378 case OPT_m8bit: | |
2379 target_flags | |
2380 &= ~(MASK_STACK_ALIGN | |
2381 + MASK_CONST_ALIGN | |
2382 + MASK_DATA_ALIGN); | |
2383 break; | |
2384 | |
2385 default: | |
2386 break; | |
2387 } | |
2388 | |
2389 CRIS_SUBTARGET_HANDLE_OPTION(code, arg, value); | |
2390 | |
2391 return true; | |
2392 } | 2635 } |
2393 | 2636 |
2394 /* The TARGET_OPTION_OVERRIDE worker. | 2637 /* The TARGET_OPTION_OVERRIDE worker. |
2395 As is the norm, this also parses -mfoo=bar type parameters. */ | 2638 As is the norm, this also parses -mfoo=bar type parameters. */ |
2396 | 2639 |
2499 force_reg the addresses, effectively forcing flag_no_function_cse | 2742 force_reg the addresses, effectively forcing flag_no_function_cse |
2500 to 0. */ | 2743 to 0. */ |
2501 flag_no_function_cse = 1; | 2744 flag_no_function_cse = 1; |
2502 } | 2745 } |
2503 | 2746 |
2504 if (write_symbols == DWARF2_DEBUG && ! TARGET_ELF) | |
2505 { | |
2506 warning (0, "that particular -g option is invalid with -maout and -melinux"); | |
2507 write_symbols = DBX_DEBUG; | |
2508 } | |
2509 | |
2510 /* Set the per-function-data initializer. */ | 2747 /* Set the per-function-data initializer. */ |
2511 init_machine_status = cris_init_machine_status; | 2748 init_machine_status = cris_init_machine_status; |
2512 } | 2749 } |
2513 | 2750 |
2514 /* The TARGET_ASM_OUTPUT_MI_THUNK worker. */ | 2751 /* The TARGET_ASM_OUTPUT_MI_THUNK worker. */ |
2518 tree thunkdecl ATTRIBUTE_UNUSED, | 2755 tree thunkdecl ATTRIBUTE_UNUSED, |
2519 HOST_WIDE_INT delta, | 2756 HOST_WIDE_INT delta, |
2520 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED, | 2757 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED, |
2521 tree funcdecl) | 2758 tree funcdecl) |
2522 { | 2759 { |
2760 /* Make sure unwind info is emitted for the thunk if needed. */ | |
2761 final_start_function (emit_barrier (), stream, 1); | |
2762 | |
2523 if (delta > 0) | 2763 if (delta > 0) |
2524 fprintf (stream, "\tadd%s " HOST_WIDE_INT_PRINT_DEC ",$%s\n", | 2764 fprintf (stream, "\tadd%s " HOST_WIDE_INT_PRINT_DEC ",$%s\n", |
2525 ADDITIVE_SIZE_MODIFIER (delta), delta, | 2765 ADDITIVE_SIZE_MODIFIER (delta), delta, |
2526 reg_names[CRIS_FIRST_ARG_REG]); | 2766 reg_names[CRIS_FIRST_ARG_REG]); |
2527 else if (delta < 0) | 2767 else if (delta < 0) |
2537 | 2777 |
2538 if (TARGET_V32) | 2778 if (TARGET_V32) |
2539 { | 2779 { |
2540 fprintf (stream, "\tba "); | 2780 fprintf (stream, "\tba "); |
2541 assemble_name (stream, name); | 2781 assemble_name (stream, name); |
2542 fprintf (stream, "%s\n", CRIS_PLT_PCOFFSET_SUFFIX); | 2782 fprintf (stream, "%s\n\tnop\n", CRIS_PLT_PCOFFSET_SUFFIX); |
2543 } | 2783 } |
2544 else | 2784 else |
2545 { | 2785 { |
2546 fprintf (stream, "add.d "); | 2786 fprintf (stream, "\tadd.d "); |
2547 assemble_name (stream, name); | 2787 assemble_name (stream, name); |
2548 fprintf (stream, "%s,$pc\n", CRIS_PLT_PCOFFSET_SUFFIX); | 2788 fprintf (stream, "%s,$pc\n", CRIS_PLT_PCOFFSET_SUFFIX); |
2549 } | 2789 } |
2550 } | 2790 } |
2551 else | 2791 else |
2552 { | 2792 { |
2553 fprintf (stream, "jump "); | 2793 fprintf (stream, "\tjump "); |
2554 assemble_name (stream, XSTR (XEXP (DECL_RTL (funcdecl), 0), 0)); | 2794 assemble_name (stream, XSTR (XEXP (DECL_RTL (funcdecl), 0), 0)); |
2555 fprintf (stream, "\n"); | 2795 fprintf (stream, "\n"); |
2556 | 2796 |
2557 if (TARGET_V32) | 2797 if (TARGET_V32) |
2558 fprintf (stream, "\tnop\n"); | 2798 fprintf (stream, "\tnop\n"); |
2559 } | 2799 } |
2800 | |
2801 final_end_function (); | |
2560 } | 2802 } |
2561 | 2803 |
2562 /* Boilerplate emitted at start of file. | 2804 /* Boilerplate emitted at start of file. |
2563 | 2805 |
2564 NO_APP *only at file start* means faster assembly. It also means | 2806 NO_APP *only at file start* means faster assembly. It also means |
2565 comments are not allowed. In some cases comments will be output | 2807 comments are not allowed. In some cases comments will be output |
2566 for debugging purposes. Make sure they are allowed then. | 2808 for debugging purposes. Make sure they are allowed then. */ |
2567 | |
2568 We want a .file directive only if TARGET_ELF. */ | |
2569 static void | 2809 static void |
2570 cris_file_start (void) | 2810 cris_file_start (void) |
2571 { | 2811 { |
2572 /* These expressions can vary at run time, so we cannot put | 2812 /* These expressions can vary at run time, so we cannot put |
2573 them into TARGET_INITIALIZER. */ | 2813 them into TARGET_INITIALIZER. */ |
2574 targetm.asm_file_start_app_off = !(TARGET_PDEBUG || flag_print_asm_name); | 2814 targetm.asm_file_start_app_off = !(TARGET_PDEBUG || flag_print_asm_name); |
2575 targetm.asm_file_start_file_directive = TARGET_ELF; | |
2576 | 2815 |
2577 default_file_start (); | 2816 default_file_start (); |
2817 } | |
2818 | |
2819 /* Output that goes at the end of the file, similarly. */ | |
2820 | |
2821 static void | |
2822 cris_file_end (void) | |
2823 { | |
2824 /* For CRIS, the default is to assume *no* executable stack, so output | |
2825 an executable-stack-note only when needed. */ | |
2826 if (TARGET_LINUX && trampolines_created) | |
2827 file_end_indicate_exec_stack (); | |
2578 } | 2828 } |
2579 | 2829 |
2580 /* Rename the function calls for integer multiply and divide. */ | 2830 /* Rename the function calls for integer multiply and divide. */ |
2581 static void | 2831 static void |
2582 cris_init_libfuncs (void) | 2832 cris_init_libfuncs (void) |
2584 set_optab_libfunc (smul_optab, SImode, "__Mul"); | 2834 set_optab_libfunc (smul_optab, SImode, "__Mul"); |
2585 set_optab_libfunc (sdiv_optab, SImode, "__Div"); | 2835 set_optab_libfunc (sdiv_optab, SImode, "__Div"); |
2586 set_optab_libfunc (udiv_optab, SImode, "__Udiv"); | 2836 set_optab_libfunc (udiv_optab, SImode, "__Udiv"); |
2587 set_optab_libfunc (smod_optab, SImode, "__Mod"); | 2837 set_optab_libfunc (smod_optab, SImode, "__Mod"); |
2588 set_optab_libfunc (umod_optab, SImode, "__Umod"); | 2838 set_optab_libfunc (umod_optab, SImode, "__Umod"); |
2839 | |
2840 /* Atomic data being unaligned is unfortunately a reality. | |
2841 Deal with it. */ | |
2842 if (TARGET_ATOMICS_MAY_CALL_LIBFUNCS) | |
2843 { | |
2844 set_optab_libfunc (sync_compare_and_swap_optab, SImode, | |
2845 "__cris_atcmpxchgr32"); | |
2846 set_optab_libfunc (sync_compare_and_swap_optab, HImode, | |
2847 "__cris_atcmpxchgr16"); | |
2848 } | |
2589 } | 2849 } |
2590 | 2850 |
2591 /* The INIT_EXPANDERS worker sets the per-function-data initializer and | 2851 /* The INIT_EXPANDERS worker sets the per-function-data initializer and |
2592 mark functions. */ | 2852 mark functions. */ |
2593 | 2853 |
2600 /* Zero initialization is OK for all current fields. */ | 2860 /* Zero initialization is OK for all current fields. */ |
2601 | 2861 |
2602 static struct machine_function * | 2862 static struct machine_function * |
2603 cris_init_machine_status (void) | 2863 cris_init_machine_status (void) |
2604 { | 2864 { |
2605 return ggc_alloc_cleared_machine_function (); | 2865 return ggc_cleared_alloc<machine_function> (); |
2606 } | 2866 } |
2607 | 2867 |
2608 /* Split a 2 word move (DI or presumably DF) into component parts. | 2868 /* Split a 2 word move (DI or presumably DF) into component parts. |
2609 Originally a copy of gen_split_move_double in m32r.c. */ | 2869 Originally a copy of gen_split_move_double in m32r.c. */ |
2610 | 2870 |
2611 rtx | 2871 rtx |
2612 cris_split_movdx (rtx *operands) | 2872 cris_split_movdx (rtx *operands) |
2613 { | 2873 { |
2614 enum machine_mode mode = GET_MODE (operands[0]); | 2874 machine_mode mode = GET_MODE (operands[0]); |
2615 rtx dest = operands[0]; | 2875 rtx dest = operands[0]; |
2616 rtx src = operands[1]; | 2876 rtx src = operands[1]; |
2617 rtx val; | 2877 rtx val; |
2618 | 2878 |
2619 /* We used to have to handle (SUBREG (MEM)) here, but that should no | 2879 /* We used to have to handle (SUBREG (MEM)) here, but that should no |
2634 int reverse = (dregno == sregno + 1); | 2894 int reverse = (dregno == sregno + 1); |
2635 | 2895 |
2636 /* We normally copy the low-numbered register first. However, if | 2896 /* We normally copy the low-numbered register first. However, if |
2637 the first register operand 0 is the same as the second register of | 2897 the first register operand 0 is the same as the second register of |
2638 operand 1, we must copy in the opposite order. */ | 2898 operand 1, we must copy in the opposite order. */ |
2639 emit_insn (gen_rtx_SET (VOIDmode, | 2899 emit_insn (gen_rtx_SET (operand_subword (dest, reverse, TRUE, mode), |
2640 operand_subword (dest, reverse, TRUE, mode), | |
2641 operand_subword (src, reverse, TRUE, mode))); | 2900 operand_subword (src, reverse, TRUE, mode))); |
2642 | 2901 |
2643 emit_insn (gen_rtx_SET (VOIDmode, | 2902 emit_insn (gen_rtx_SET (operand_subword (dest, !reverse, TRUE, mode), |
2644 operand_subword (dest, !reverse, TRUE, mode), | |
2645 operand_subword (src, !reverse, TRUE, mode))); | 2903 operand_subword (src, !reverse, TRUE, mode))); |
2646 } | 2904 } |
2647 /* Constant-to-reg copy. */ | 2905 /* Constant-to-reg copy. */ |
2648 else if (CONST_INT_P (src) || GET_CODE (src) == CONST_DOUBLE) | 2906 else if (CONST_INT_P (src) || GET_CODE (src) == CONST_DOUBLE) |
2649 { | 2907 { |
2650 rtx words[2]; | 2908 rtx words[2]; |
2651 split_double (src, &words[0], &words[1]); | 2909 split_double (src, &words[0], &words[1]); |
2652 emit_insn (gen_rtx_SET (VOIDmode, | 2910 emit_insn (gen_rtx_SET (operand_subword (dest, 0, TRUE, mode), |
2653 operand_subword (dest, 0, TRUE, mode), | |
2654 words[0])); | 2911 words[0])); |
2655 | 2912 |
2656 emit_insn (gen_rtx_SET (VOIDmode, | 2913 emit_insn (gen_rtx_SET (operand_subword (dest, 1, TRUE, mode), |
2657 operand_subword (dest, 1, TRUE, mode), | |
2658 words[1])); | 2914 words[1])); |
2659 } | 2915 } |
2660 /* Mem-to-reg copy. */ | 2916 /* Mem-to-reg copy. */ |
2661 else if (MEM_P (src)) | 2917 else if (MEM_P (src)) |
2662 { | 2918 { |
2663 /* If the high-address word is used in the address, we must load it | 2919 /* If the high-address word is used in the address, we must load it |
2664 last. Otherwise, load it first. */ | 2920 last. Otherwise, load it first. */ |
2665 rtx addr = XEXP (src, 0); | 2921 rtx addr = XEXP (src, 0); |
2666 int reverse | 2922 int reverse = (refers_to_regno_p (dregno, addr) != 0); |
2667 = (refers_to_regno_p (dregno, dregno + 1, addr, NULL) != 0); | |
2668 | 2923 |
2669 /* The original code implies that we can't do | 2924 /* The original code implies that we can't do |
2670 move.x [rN+],rM move.x [rN],rM+1 | 2925 move.x [rN+],rM move.x [rN],rM+1 |
2671 when rN is dead, because of REG_NOTES damage. That is | 2926 when rN is dead, because of REG_NOTES damage. That is |
2672 consistent with what I've seen, so don't try it. | 2927 consistent with what I've seen, so don't try it. |
2682 /* Whenever we emit insns with post-incremented | 2937 /* Whenever we emit insns with post-incremented |
2683 addresses ourselves, we must add a post-inc note | 2938 addresses ourselves, we must add a post-inc note |
2684 manually. */ | 2939 manually. */ |
2685 mem = change_address (src, SImode, addr); | 2940 mem = change_address (src, SImode, addr); |
2686 insn | 2941 insn |
2687 = gen_rtx_SET (VOIDmode, | 2942 = gen_rtx_SET (operand_subword (dest, 0, TRUE, mode), mem); |
2688 operand_subword (dest, 0, TRUE, mode), mem); | |
2689 insn = emit_insn (insn); | 2943 insn = emit_insn (insn); |
2690 if (GET_CODE (XEXP (mem, 0)) == POST_INC) | 2944 if (GET_CODE (XEXP (mem, 0)) == POST_INC) |
2691 REG_NOTES (insn) | 2945 REG_NOTES (insn) |
2692 = alloc_EXPR_LIST (REG_INC, XEXP (XEXP (mem, 0), 0), | 2946 = alloc_EXPR_LIST (REG_INC, XEXP (XEXP (mem, 0), 0), |
2693 REG_NOTES (insn)); | 2947 REG_NOTES (insn)); |
2694 | 2948 |
2695 mem = copy_rtx (mem); | 2949 mem = copy_rtx (mem); |
2696 insn | 2950 insn |
2697 = gen_rtx_SET (VOIDmode, | 2951 = gen_rtx_SET (operand_subword (dest, 1, TRUE, mode), mem); |
2698 operand_subword (dest, 1, TRUE, mode), mem); | |
2699 insn = emit_insn (insn); | 2952 insn = emit_insn (insn); |
2700 if (GET_CODE (XEXP (mem, 0)) == POST_INC) | 2953 if (GET_CODE (XEXP (mem, 0)) == POST_INC) |
2701 REG_NOTES (insn) | 2954 REG_NOTES (insn) |
2702 = alloc_EXPR_LIST (REG_INC, XEXP (XEXP (mem, 0), 0), | 2955 = alloc_EXPR_LIST (REG_INC, XEXP (XEXP (mem, 0), 0), |
2703 REG_NOTES (insn)); | 2956 REG_NOTES (insn)); |
2710 safety. */ | 2963 safety. */ |
2711 if (side_effects_p (addr)) | 2964 if (side_effects_p (addr)) |
2712 fatal_insn ("unexpected side-effects in address", addr); | 2965 fatal_insn ("unexpected side-effects in address", addr); |
2713 | 2966 |
2714 emit_insn (gen_rtx_SET | 2967 emit_insn (gen_rtx_SET |
2715 (VOIDmode, | 2968 (operand_subword (dest, reverse, TRUE, mode), |
2716 operand_subword (dest, reverse, TRUE, mode), | |
2717 change_address | 2969 change_address |
2718 (src, SImode, | 2970 (src, SImode, |
2719 plus_constant (addr, | 2971 plus_constant (Pmode, addr, |
2720 reverse * UNITS_PER_WORD)))); | 2972 reverse * UNITS_PER_WORD)))); |
2721 emit_insn (gen_rtx_SET | 2973 emit_insn (gen_rtx_SET |
2722 (VOIDmode, | 2974 (operand_subword (dest, ! reverse, TRUE, mode), |
2723 operand_subword (dest, ! reverse, TRUE, mode), | |
2724 change_address | 2975 change_address |
2725 (src, SImode, | 2976 (src, SImode, |
2726 plus_constant (addr, | 2977 plus_constant (Pmode, addr, |
2727 (! reverse) * | 2978 (! reverse) * |
2728 UNITS_PER_WORD)))); | 2979 UNITS_PER_WORD)))); |
2729 } | 2980 } |
2730 } | 2981 } |
2731 else | 2982 else |
2746 | 2997 |
2747 /* Whenever we emit insns with post-incremented addresses | 2998 /* Whenever we emit insns with post-incremented addresses |
2748 ourselves, we must add a post-inc note manually. */ | 2999 ourselves, we must add a post-inc note manually. */ |
2749 mem = change_address (dest, SImode, addr); | 3000 mem = change_address (dest, SImode, addr); |
2750 insn | 3001 insn |
2751 = gen_rtx_SET (VOIDmode, | 3002 = gen_rtx_SET (mem, operand_subword (src, 0, TRUE, mode)); |
2752 mem, operand_subword (src, 0, TRUE, mode)); | |
2753 insn = emit_insn (insn); | 3003 insn = emit_insn (insn); |
2754 if (GET_CODE (XEXP (mem, 0)) == POST_INC) | 3004 if (GET_CODE (XEXP (mem, 0)) == POST_INC) |
2755 REG_NOTES (insn) | 3005 REG_NOTES (insn) |
2756 = alloc_EXPR_LIST (REG_INC, XEXP (XEXP (mem, 0), 0), | 3006 = alloc_EXPR_LIST (REG_INC, XEXP (XEXP (mem, 0), 0), |
2757 REG_NOTES (insn)); | 3007 REG_NOTES (insn)); |
2758 | 3008 |
2759 mem = copy_rtx (mem); | 3009 mem = copy_rtx (mem); |
2760 insn | 3010 insn = gen_rtx_SET (mem, operand_subword (src, 1, TRUE, mode)); |
2761 = gen_rtx_SET (VOIDmode, | |
2762 mem, | |
2763 operand_subword (src, 1, TRUE, mode)); | |
2764 insn = emit_insn (insn); | 3011 insn = emit_insn (insn); |
2765 if (GET_CODE (XEXP (mem, 0)) == POST_INC) | 3012 if (GET_CODE (XEXP (mem, 0)) == POST_INC) |
2766 REG_NOTES (insn) | 3013 REG_NOTES (insn) |
2767 = alloc_EXPR_LIST (REG_INC, XEXP (XEXP (mem, 0), 0), | 3014 = alloc_EXPR_LIST (REG_INC, XEXP (XEXP (mem, 0), 0), |
2768 REG_NOTES (insn)); | 3015 REG_NOTES (insn)); |
2774 GO_IF_LEGITIMATE_ADDRESS, but we're here for your safety. */ | 3021 GO_IF_LEGITIMATE_ADDRESS, but we're here for your safety. */ |
2775 if (side_effects_p (addr)) | 3022 if (side_effects_p (addr)) |
2776 fatal_insn ("unexpected side-effects in address", addr); | 3023 fatal_insn ("unexpected side-effects in address", addr); |
2777 | 3024 |
2778 emit_insn (gen_rtx_SET | 3025 emit_insn (gen_rtx_SET |
2779 (VOIDmode, | 3026 (change_address (dest, SImode, addr), |
2780 change_address (dest, SImode, addr), | |
2781 operand_subword (src, 0, TRUE, mode))); | 3027 operand_subword (src, 0, TRUE, mode))); |
2782 | 3028 |
2783 emit_insn (gen_rtx_SET | 3029 emit_insn (gen_rtx_SET |
2784 (VOIDmode, | 3030 (change_address (dest, SImode, |
2785 change_address (dest, SImode, | 3031 plus_constant (Pmode, addr, |
2786 plus_constant (addr, | |
2787 UNITS_PER_WORD)), | 3032 UNITS_PER_WORD)), |
2788 operand_subword (src, 1, TRUE, mode))); | 3033 operand_subword (src, 1, TRUE, mode))); |
2789 } | 3034 } |
2790 } | 3035 } |
2791 | 3036 |
2825 /* A reference may have been optimized out (like the abort () in | 3070 /* A reference may have been optimized out (like the abort () in |
2826 fde_split in unwind-dw2-fde.c, at least 3.2.1) so check that | 3071 fde_split in unwind-dw2-fde.c, at least 3.2.1) so check that |
2827 it's still used. */ | 3072 it's still used. */ |
2828 push_topmost_sequence (); | 3073 push_topmost_sequence (); |
2829 got_really_used | 3074 got_really_used |
2830 = reg_used_between_p (pic_offset_table_rtx, get_insns (), NULL_RTX); | 3075 = reg_used_between_p (pic_offset_table_rtx, get_insns (), NULL); |
2831 pop_topmost_sequence (); | 3076 pop_topmost_sequence (); |
2832 } | 3077 } |
2833 | 3078 |
2834 /* Align the size to what's best for the CPU model. */ | 3079 /* Align the size to what's best for the CPU model. */ |
2835 if (TARGET_STACK_ALIGN) | 3080 if (TARGET_STACK_ALIGN) |
2851 | 3096 |
2852 for (regno = CRIS_FIRST_ARG_REG + CRIS_MAX_ARGS_IN_REGS - 1; | 3097 for (regno = CRIS_FIRST_ARG_REG + CRIS_MAX_ARGS_IN_REGS - 1; |
2853 stdarg_regs > 0; | 3098 stdarg_regs > 0; |
2854 regno--, pretend -= 4, stdarg_regs--) | 3099 regno--, pretend -= 4, stdarg_regs--) |
2855 { | 3100 { |
2856 insn = emit_insn (gen_rtx_SET (VOIDmode, | 3101 insn = emit_insn (gen_rtx_SET (stack_pointer_rtx, |
2857 stack_pointer_rtx, | 3102 plus_constant (Pmode, |
2858 plus_constant (stack_pointer_rtx, | 3103 stack_pointer_rtx, |
2859 -4))); | 3104 -4))); |
2860 /* FIXME: When dwarf2 frame output and unless asynchronous | 3105 /* FIXME: When dwarf2 frame output and unless asynchronous |
2861 exceptions, make dwarf2 bundle together all stack | 3106 exceptions, make dwarf2 bundle together all stack |
2862 adjustments like it does for registers between stack | 3107 adjustments like it does for registers between stack |
2863 adjustments. */ | 3108 adjustments. */ |
2864 RTX_FRAME_RELATED_P (insn) = 1; | 3109 RTX_FRAME_RELATED_P (insn) = 1; |
2865 | 3110 |
2866 mem = gen_rtx_MEM (SImode, stack_pointer_rtx); | 3111 mem = gen_rtx_MEM (SImode, stack_pointer_rtx); |
2867 set_mem_alias_set (mem, get_varargs_alias_set ()); | 3112 set_mem_alias_set (mem, get_varargs_alias_set ()); |
2868 insn = emit_move_insn (mem, gen_rtx_raw_REG (SImode, regno)); | 3113 insn = emit_move_insn (mem, gen_raw_REG (SImode, regno)); |
2869 | 3114 |
2870 /* Note the absence of RTX_FRAME_RELATED_P on the above insn: | 3115 /* Note the absence of RTX_FRAME_RELATED_P on the above insn: |
2871 the value isn't restored, so we don't want to tell dwarf2 | 3116 the value isn't restored, so we don't want to tell dwarf2 |
2872 that it's been stored to stack, else EH handling info would | 3117 that it's been stored to stack, else EH handling info would |
2873 get confused. */ | 3118 get confused. */ |
2879 } | 3124 } |
2880 | 3125 |
2881 /* Save SRP if not a leaf function. */ | 3126 /* Save SRP if not a leaf function. */ |
2882 if (return_address_on_stack) | 3127 if (return_address_on_stack) |
2883 { | 3128 { |
2884 insn = emit_insn (gen_rtx_SET (VOIDmode, | 3129 insn = emit_insn (gen_rtx_SET (stack_pointer_rtx, |
2885 stack_pointer_rtx, | 3130 plus_constant (Pmode, stack_pointer_rtx, |
2886 plus_constant (stack_pointer_rtx, | |
2887 -4 - pretend))); | 3131 -4 - pretend))); |
2888 pretend = 0; | 3132 pretend = 0; |
2889 RTX_FRAME_RELATED_P (insn) = 1; | 3133 RTX_FRAME_RELATED_P (insn) = 1; |
2890 | 3134 |
2891 mem = gen_rtx_MEM (SImode, stack_pointer_rtx); | 3135 mem = gen_rtx_MEM (SImode, stack_pointer_rtx); |
2892 set_mem_alias_set (mem, get_frame_alias_set ()); | 3136 set_mem_alias_set (mem, get_frame_alias_set ()); |
2893 insn = emit_move_insn (mem, gen_rtx_raw_REG (SImode, CRIS_SRP_REGNUM)); | 3137 insn = emit_move_insn (mem, gen_raw_REG (SImode, CRIS_SRP_REGNUM)); |
2894 RTX_FRAME_RELATED_P (insn) = 1; | 3138 RTX_FRAME_RELATED_P (insn) = 1; |
2895 framesize += 4; | 3139 framesize += 4; |
2896 } | 3140 } |
2897 | 3141 |
2898 /* Set up the frame pointer, if needed. */ | 3142 /* Set up the frame pointer, if needed. */ |
2899 if (frame_pointer_needed) | 3143 if (frame_pointer_needed) |
2900 { | 3144 { |
2901 insn = emit_insn (gen_rtx_SET (VOIDmode, | 3145 insn = emit_insn (gen_rtx_SET (stack_pointer_rtx, |
2902 stack_pointer_rtx, | 3146 plus_constant (Pmode, stack_pointer_rtx, |
2903 plus_constant (stack_pointer_rtx, | |
2904 -4 - pretend))); | 3147 -4 - pretend))); |
2905 pretend = 0; | 3148 pretend = 0; |
2906 RTX_FRAME_RELATED_P (insn) = 1; | 3149 RTX_FRAME_RELATED_P (insn) = 1; |
2907 | 3150 |
2908 mem = gen_rtx_MEM (SImode, stack_pointer_rtx); | 3151 mem = gen_rtx_MEM (SImode, stack_pointer_rtx); |
2951 && (cris_cpu_version >= CRIS_CPU_SVINTO || n_saved == 1) | 3194 && (cris_cpu_version >= CRIS_CPU_SVINTO || n_saved == 1) |
2952 && TARGET_SIDE_EFFECT_PREFIXES) | 3195 && TARGET_SIDE_EFFECT_PREFIXES) |
2953 { | 3196 { |
2954 mem | 3197 mem |
2955 = gen_rtx_MEM (SImode, | 3198 = gen_rtx_MEM (SImode, |
2956 plus_constant (stack_pointer_rtx, | 3199 plus_constant (Pmode, stack_pointer_rtx, |
2957 -(n_saved * 4 + size))); | 3200 -(n_saved * 4 + size))); |
2958 set_mem_alias_set (mem, get_frame_alias_set ()); | 3201 set_mem_alias_set (mem, get_frame_alias_set ()); |
2959 insn | 3202 insn |
2960 = cris_emit_movem_store (mem, GEN_INT (n_saved), | 3203 = cris_emit_movem_store (mem, GEN_INT (n_saved), |
2961 -(n_saved * 4 + size), | 3204 -(n_saved * 4 + size), |
2962 true); | 3205 true); |
2963 } | 3206 } |
2964 else | 3207 else |
2965 { | 3208 { |
2966 insn | 3209 insn |
2967 = gen_rtx_SET (VOIDmode, | 3210 = gen_rtx_SET (stack_pointer_rtx, |
2968 stack_pointer_rtx, | 3211 plus_constant (Pmode, stack_pointer_rtx, |
2969 plus_constant (stack_pointer_rtx, | |
2970 -(n_saved * 4 + size))); | 3212 -(n_saved * 4 + size))); |
2971 insn = emit_insn (insn); | 3213 insn = emit_insn (insn); |
2972 RTX_FRAME_RELATED_P (insn) = 1; | 3214 RTX_FRAME_RELATED_P (insn) = 1; |
2973 | 3215 |
2974 mem = gen_rtx_MEM (SImode, stack_pointer_rtx); | 3216 mem = gen_rtx_MEM (SImode, stack_pointer_rtx); |
2980 framesize += n_saved * 4 + size; | 3222 framesize += n_saved * 4 + size; |
2981 last_movem_reg = -1; | 3223 last_movem_reg = -1; |
2982 size = 0; | 3224 size = 0; |
2983 } | 3225 } |
2984 | 3226 |
2985 insn = emit_insn (gen_rtx_SET (VOIDmode, | 3227 insn = emit_insn (gen_rtx_SET (stack_pointer_rtx, |
2986 stack_pointer_rtx, | 3228 plus_constant (Pmode, |
2987 plus_constant (stack_pointer_rtx, | 3229 stack_pointer_rtx, |
2988 -4 - size))); | 3230 -4 - size))); |
2989 RTX_FRAME_RELATED_P (insn) = 1; | 3231 RTX_FRAME_RELATED_P (insn) = 1; |
2990 | 3232 |
2991 mem = gen_rtx_MEM (SImode, stack_pointer_rtx); | 3233 mem = gen_rtx_MEM (SImode, stack_pointer_rtx); |
2992 set_mem_alias_set (mem, get_frame_alias_set ()); | 3234 set_mem_alias_set (mem, get_frame_alias_set ()); |
2993 insn = emit_move_insn (mem, gen_rtx_raw_REG (SImode, regno)); | 3235 insn = emit_move_insn (mem, gen_raw_REG (SImode, regno)); |
2994 RTX_FRAME_RELATED_P (insn) = 1; | 3236 RTX_FRAME_RELATED_P (insn) = 1; |
2995 | 3237 |
2996 framesize += 4 + size; | 3238 framesize += 4 + size; |
2997 size = 0; | 3239 size = 0; |
2998 } | 3240 } |
3012 && (cris_cpu_version >= CRIS_CPU_SVINTO || n_saved == 1) | 3254 && (cris_cpu_version >= CRIS_CPU_SVINTO || n_saved == 1) |
3013 && TARGET_SIDE_EFFECT_PREFIXES) | 3255 && TARGET_SIDE_EFFECT_PREFIXES) |
3014 { | 3256 { |
3015 mem | 3257 mem |
3016 = gen_rtx_MEM (SImode, | 3258 = gen_rtx_MEM (SImode, |
3017 plus_constant (stack_pointer_rtx, | 3259 plus_constant (Pmode, stack_pointer_rtx, |
3018 -(n_saved * 4 + size))); | 3260 -(n_saved * 4 + size))); |
3019 set_mem_alias_set (mem, get_frame_alias_set ()); | 3261 set_mem_alias_set (mem, get_frame_alias_set ()); |
3020 insn = cris_emit_movem_store (mem, GEN_INT (n_saved), | 3262 insn = cris_emit_movem_store (mem, GEN_INT (n_saved), |
3021 -(n_saved * 4 + size), true); | 3263 -(n_saved * 4 + size), true); |
3022 } | 3264 } |
3023 else | 3265 else |
3024 { | 3266 { |
3025 insn | 3267 insn |
3026 = gen_rtx_SET (VOIDmode, | 3268 = gen_rtx_SET (stack_pointer_rtx, |
3027 stack_pointer_rtx, | 3269 plus_constant (Pmode, stack_pointer_rtx, |
3028 plus_constant (stack_pointer_rtx, | |
3029 -(n_saved * 4 + size))); | 3270 -(n_saved * 4 + size))); |
3030 insn = emit_insn (insn); | 3271 insn = emit_insn (insn); |
3031 RTX_FRAME_RELATED_P (insn) = 1; | 3272 RTX_FRAME_RELATED_P (insn) = 1; |
3032 | 3273 |
3033 mem = gen_rtx_MEM (SImode, stack_pointer_rtx); | 3274 mem = gen_rtx_MEM (SImode, stack_pointer_rtx); |
3037 | 3278 |
3038 framesize += n_saved * 4 + size; | 3279 framesize += n_saved * 4 + size; |
3039 /* We have to put outgoing argument space after regs. */ | 3280 /* We have to put outgoing argument space after regs. */ |
3040 if (cfoa_size) | 3281 if (cfoa_size) |
3041 { | 3282 { |
3042 insn = emit_insn (gen_rtx_SET (VOIDmode, | 3283 insn = emit_insn (gen_rtx_SET (stack_pointer_rtx, |
3043 stack_pointer_rtx, | 3284 plus_constant (Pmode, |
3044 plus_constant (stack_pointer_rtx, | 3285 stack_pointer_rtx, |
3045 -cfoa_size))); | 3286 -cfoa_size))); |
3046 RTX_FRAME_RELATED_P (insn) = 1; | 3287 RTX_FRAME_RELATED_P (insn) = 1; |
3047 framesize += cfoa_size; | 3288 framesize += cfoa_size; |
3048 } | 3289 } |
3049 } | 3290 } |
3050 else if ((size + cfoa_size) > 0) | 3291 else if ((size + cfoa_size) > 0) |
3051 { | 3292 { |
3052 insn = emit_insn (gen_rtx_SET (VOIDmode, | 3293 insn = emit_insn (gen_rtx_SET (stack_pointer_rtx, |
3053 stack_pointer_rtx, | 3294 plus_constant (Pmode, |
3054 plus_constant (stack_pointer_rtx, | 3295 stack_pointer_rtx, |
3055 -(cfoa_size + size)))); | 3296 -(cfoa_size + size)))); |
3056 RTX_FRAME_RELATED_P (insn) = 1; | 3297 RTX_FRAME_RELATED_P (insn) = 1; |
3057 framesize += size + cfoa_size; | 3298 framesize += size + cfoa_size; |
3058 } | 3299 } |
3059 | 3300 |
3104 /* A reference may have been optimized out (like the abort () in | 3345 /* A reference may have been optimized out (like the abort () in |
3105 fde_split in unwind-dw2-fde.c, at least 3.2.1) so check that | 3346 fde_split in unwind-dw2-fde.c, at least 3.2.1) so check that |
3106 it's still used. */ | 3347 it's still used. */ |
3107 push_topmost_sequence (); | 3348 push_topmost_sequence (); |
3108 got_really_used | 3349 got_really_used |
3109 = reg_used_between_p (pic_offset_table_rtx, get_insns (), NULL_RTX); | 3350 = reg_used_between_p (pic_offset_table_rtx, get_insns (), NULL); |
3110 pop_topmost_sequence (); | 3351 pop_topmost_sequence (); |
3111 } | 3352 } |
3112 | 3353 |
3113 /* Align byte count of stack frame. */ | 3354 /* Align byte count of stack frame. */ |
3114 if (TARGET_STACK_ALIGN) | 3355 if (TARGET_STACK_ALIGN) |
3145 | 3386 |
3146 if (argspace_offset) | 3387 if (argspace_offset) |
3147 { | 3388 { |
3148 /* There is an area for outgoing parameters located before | 3389 /* There is an area for outgoing parameters located before |
3149 the saved registers. We have to adjust for that. */ | 3390 the saved registers. We have to adjust for that. */ |
3150 emit_insn (gen_rtx_SET (VOIDmode, | 3391 emit_insn (gen_rtx_SET (stack_pointer_rtx, |
3151 stack_pointer_rtx, | 3392 plus_constant (Pmode, stack_pointer_rtx, |
3152 plus_constant (stack_pointer_rtx, | |
3153 argspace_offset))); | 3393 argspace_offset))); |
3154 /* Make sure we only do this once. */ | 3394 /* Make sure we only do this once. */ |
3155 argspace_offset = 0; | 3395 argspace_offset = 0; |
3156 } | 3396 } |
3157 | 3397 |
3158 mem = gen_rtx_MEM (SImode, gen_rtx_POST_INC (SImode, | 3398 mem = gen_rtx_MEM (SImode, gen_rtx_POST_INC (SImode, |
3159 stack_pointer_rtx)); | 3399 stack_pointer_rtx)); |
3160 set_mem_alias_set (mem, get_frame_alias_set ()); | 3400 set_mem_alias_set (mem, get_frame_alias_set ()); |
3161 insn = emit_move_insn (gen_rtx_raw_REG (SImode, regno), mem); | 3401 insn = emit_move_insn (gen_raw_REG (SImode, regno), mem); |
3162 | 3402 |
3163 /* Whenever we emit insns with post-incremented addresses | 3403 /* Whenever we emit insns with post-incremented addresses |
3164 ourselves, we must add a post-inc note manually. */ | 3404 ourselves, we must add a post-inc note manually. */ |
3165 REG_NOTES (insn) | 3405 REG_NOTES (insn) |
3166 = alloc_EXPR_LIST (REG_INC, stack_pointer_rtx, REG_NOTES (insn)); | 3406 = alloc_EXPR_LIST (REG_INC, stack_pointer_rtx, REG_NOTES (insn)); |
3171 { | 3411 { |
3172 rtx insn; | 3412 rtx insn; |
3173 | 3413 |
3174 if (argspace_offset) | 3414 if (argspace_offset) |
3175 { | 3415 { |
3176 emit_insn (gen_rtx_SET (VOIDmode, | 3416 emit_insn (gen_rtx_SET (stack_pointer_rtx, |
3177 stack_pointer_rtx, | 3417 plus_constant (Pmode, stack_pointer_rtx, |
3178 plus_constant (stack_pointer_rtx, | |
3179 argspace_offset))); | 3418 argspace_offset))); |
3180 argspace_offset = 0; | 3419 argspace_offset = 0; |
3181 } | 3420 } |
3182 | 3421 |
3183 mem = gen_rtx_MEM (SImode, | 3422 mem = gen_rtx_MEM (SImode, |
3230 | 3469 |
3231 /* Handle space for outgoing parameters that hasn't been handled | 3470 /* Handle space for outgoing parameters that hasn't been handled |
3232 yet. */ | 3471 yet. */ |
3233 size += argspace_offset; | 3472 size += argspace_offset; |
3234 | 3473 |
3235 emit_insn (gen_rtx_SET (VOIDmode, | 3474 emit_insn (gen_rtx_SET (stack_pointer_rtx, |
3236 stack_pointer_rtx, | 3475 plus_constant (Pmode, stack_pointer_rtx, size))); |
3237 plus_constant (stack_pointer_rtx, size))); | |
3238 } | 3476 } |
3239 | 3477 |
3240 /* If this function has no pushed register parameters | 3478 /* If this function has no pushed register parameters |
3241 (stdargs/varargs), and if it is not a leaf function, then we have | 3479 (stdargs/varargs), and if it is not a leaf function, then we have |
3242 the return address on the stack. */ | 3480 the return address on the stack. */ |
3244 { | 3482 { |
3245 if (TARGET_V32 || crtl->calls_eh_return) | 3483 if (TARGET_V32 || crtl->calls_eh_return) |
3246 { | 3484 { |
3247 rtx mem; | 3485 rtx mem; |
3248 rtx insn; | 3486 rtx insn; |
3249 rtx srpreg = gen_rtx_raw_REG (SImode, CRIS_SRP_REGNUM); | 3487 rtx srpreg = gen_raw_REG (SImode, CRIS_SRP_REGNUM); |
3250 mem = gen_rtx_MEM (SImode, | 3488 mem = gen_rtx_MEM (SImode, |
3251 gen_rtx_POST_INC (SImode, | 3489 gen_rtx_POST_INC (SImode, |
3252 stack_pointer_rtx)); | 3490 stack_pointer_rtx)); |
3253 set_mem_alias_set (mem, get_frame_alias_set ()); | 3491 set_mem_alias_set (mem, get_frame_alias_set ()); |
3254 insn = emit_move_insn (srpreg, mem); | 3492 insn = emit_move_insn (srpreg, mem); |
3259 = alloc_EXPR_LIST (REG_INC, stack_pointer_rtx, REG_NOTES (insn)); | 3497 = alloc_EXPR_LIST (REG_INC, stack_pointer_rtx, REG_NOTES (insn)); |
3260 | 3498 |
3261 if (crtl->calls_eh_return) | 3499 if (crtl->calls_eh_return) |
3262 emit_insn (gen_addsi3 (stack_pointer_rtx, | 3500 emit_insn (gen_addsi3 (stack_pointer_rtx, |
3263 stack_pointer_rtx, | 3501 stack_pointer_rtx, |
3264 gen_rtx_raw_REG (SImode, | 3502 gen_raw_REG (SImode, CRIS_STACKADJ_REG))); |
3265 CRIS_STACKADJ_REG))); | |
3266 cris_expand_return (false); | 3503 cris_expand_return (false); |
3267 } | 3504 } |
3268 else | 3505 else |
3269 cris_expand_return (true); | 3506 cris_expand_return (true); |
3270 | 3507 |
3277 { | 3514 { |
3278 /* If SRP is stored on the way, we need to restore it first. */ | 3515 /* If SRP is stored on the way, we need to restore it first. */ |
3279 if (return_address_on_stack) | 3516 if (return_address_on_stack) |
3280 { | 3517 { |
3281 rtx mem; | 3518 rtx mem; |
3282 rtx srpreg = gen_rtx_raw_REG (SImode, CRIS_SRP_REGNUM); | 3519 rtx srpreg = gen_raw_REG (SImode, CRIS_SRP_REGNUM); |
3283 rtx insn; | 3520 rtx insn; |
3284 | 3521 |
3285 mem = gen_rtx_MEM (SImode, | 3522 mem = gen_rtx_MEM (SImode, |
3286 gen_rtx_POST_INC (SImode, | 3523 gen_rtx_POST_INC (SImode, |
3287 stack_pointer_rtx)); | 3524 stack_pointer_rtx)); |
3292 ourselves, we must add a post-inc note manually. */ | 3529 ourselves, we must add a post-inc note manually. */ |
3293 REG_NOTES (insn) | 3530 REG_NOTES (insn) |
3294 = alloc_EXPR_LIST (REG_INC, stack_pointer_rtx, REG_NOTES (insn)); | 3531 = alloc_EXPR_LIST (REG_INC, stack_pointer_rtx, REG_NOTES (insn)); |
3295 } | 3532 } |
3296 | 3533 |
3297 emit_insn (gen_rtx_SET (VOIDmode, | 3534 emit_insn (gen_rtx_SET (stack_pointer_rtx, |
3298 stack_pointer_rtx, | 3535 plus_constant (Pmode, stack_pointer_rtx, |
3299 plus_constant (stack_pointer_rtx, pretend))); | 3536 pretend))); |
3300 } | 3537 } |
3301 | 3538 |
3302 /* Perform the "physical" unwinding that the EH machinery calculated. */ | 3539 /* Perform the "physical" unwinding that the EH machinery calculated. */ |
3303 if (crtl->calls_eh_return) | 3540 if (crtl->calls_eh_return) |
3304 emit_insn (gen_addsi3 (stack_pointer_rtx, | 3541 emit_insn (gen_addsi3 (stack_pointer_rtx, |
3305 stack_pointer_rtx, | 3542 stack_pointer_rtx, |
3306 gen_rtx_raw_REG (SImode, | 3543 gen_raw_REG (SImode, CRIS_STACKADJ_REG))); |
3307 CRIS_STACKADJ_REG))); | |
3308 cris_expand_return (false); | 3544 cris_expand_return (false); |
3309 } | 3545 } |
3310 | 3546 |
3311 /* Worker function for generating movem from mem for load_multiple. */ | 3547 /* Worker function for generating movem from mem for load_multiple. */ |
3312 | 3548 |
3342 + (GET_CODE (XEXP (src, 0)) == POST_INC)); | 3578 + (GET_CODE (XEXP (src, 0)) == POST_INC)); |
3343 | 3579 |
3344 if (GET_CODE (XEXP (src, 0)) == POST_INC) | 3580 if (GET_CODE (XEXP (src, 0)) == POST_INC) |
3345 { | 3581 { |
3346 RTVEC_ELT (vec, nprefix + 1) | 3582 RTVEC_ELT (vec, nprefix + 1) |
3347 = gen_rtx_SET (VOIDmode, srcreg, plus_constant (srcreg, nregs * 4)); | 3583 = gen_rtx_SET (srcreg, plus_constant (Pmode, srcreg, nregs * 4)); |
3348 eltno++; | 3584 eltno++; |
3349 } | 3585 } |
3350 | 3586 |
3351 src = replace_equiv_address (src, srcreg); | 3587 src = replace_equiv_address (src, srcreg); |
3352 RTVEC_ELT (vec, nprefix) | 3588 RTVEC_ELT (vec, nprefix) |
3353 = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, regno), src); | 3589 = gen_rtx_SET (gen_rtx_REG (SImode, regno), src); |
3354 regno += regno_inc; | 3590 regno += regno_inc; |
3355 | 3591 |
3356 for (i = 1; i < nregs; i++, eltno++) | 3592 for (i = 1; i < nregs; i++, eltno++) |
3357 { | 3593 { |
3358 RTVEC_ELT (vec, nprefix + eltno) | 3594 RTVEC_ELT (vec, nprefix + eltno) |
3359 = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, regno), | 3595 = gen_rtx_SET (gen_rtx_REG (SImode, regno), |
3360 adjust_address_nv (src, SImode, i * 4)); | 3596 adjust_address_nv (src, SImode, i * 4)); |
3361 regno += regno_inc; | 3597 regno += regno_inc; |
3362 } | 3598 } |
3363 | 3599 |
3364 return gen_rtx_PARALLEL (VOIDmode, vec); | 3600 return gen_rtx_PARALLEL (VOIDmode, vec); |
3397 /* Don't use movem for just one insn. The insns are equivalent except | 3633 /* Don't use movem for just one insn. The insns are equivalent except |
3398 for the pipeline hazard (on v32); movem does not forward the loaded | 3634 for the pipeline hazard (on v32); movem does not forward the loaded |
3399 registers so there's a three cycles penalty for use. */ | 3635 registers so there's a three cycles penalty for use. */ |
3400 if (nregs == 1) | 3636 if (nregs == 1) |
3401 { | 3637 { |
3402 rtx mov = gen_rtx_SET (VOIDmode, dest, gen_rtx_REG (SImode, 0)); | 3638 rtx mov = gen_rtx_SET (dest, gen_rtx_REG (SImode, 0)); |
3403 | 3639 |
3404 if (increment == 0) | 3640 if (increment == 0) |
3405 { | 3641 { |
3406 insn = emit_insn (mov); | 3642 insn = emit_insn (mov); |
3407 if (frame_related) | 3643 if (frame_related) |
3412 /* If there was a request for a side-effect, create the ordinary | 3648 /* If there was a request for a side-effect, create the ordinary |
3413 parallel. */ | 3649 parallel. */ |
3414 vec = rtvec_alloc (2); | 3650 vec = rtvec_alloc (2); |
3415 | 3651 |
3416 RTVEC_ELT (vec, 0) = mov; | 3652 RTVEC_ELT (vec, 0) = mov; |
3417 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, destreg, | 3653 RTVEC_ELT (vec, 1) = gen_rtx_SET (destreg, plus_constant (Pmode, destreg, |
3418 plus_constant (destreg, increment)); | 3654 increment)); |
3419 if (frame_related) | 3655 if (frame_related) |
3420 { | 3656 { |
3421 RTX_FRAME_RELATED_P (mov) = 1; | 3657 RTX_FRAME_RELATED_P (mov) = 1; |
3422 RTX_FRAME_RELATED_P (RTVEC_ELT (vec, 1)) = 1; | 3658 RTX_FRAME_RELATED_P (RTVEC_ELT (vec, 1)) = 1; |
3423 } | 3659 } |
3424 } | 3660 } |
3425 else | 3661 else |
3426 { | 3662 { |
3427 vec = rtvec_alloc (nregs + (increment != 0 ? 1 : 0)); | 3663 vec = rtvec_alloc (nregs + (increment != 0 ? 1 : 0)); |
3428 RTVEC_ELT (vec, 0) | 3664 RTVEC_ELT (vec, 0) |
3429 = gen_rtx_SET (VOIDmode, | 3665 = gen_rtx_SET (replace_equiv_address (dest, |
3430 replace_equiv_address (dest, | 3666 plus_constant (Pmode, destreg, |
3431 plus_constant (destreg, | |
3432 increment)), | 3667 increment)), |
3433 gen_rtx_REG (SImode, regno)); | 3668 gen_rtx_REG (SImode, regno)); |
3434 regno += regno_inc; | 3669 regno += regno_inc; |
3435 | 3670 |
3436 /* The dwarf2 info wants this mark on each component in a parallel | 3671 /* The dwarf2 info wants this mark on each component in a parallel |
3440 RTX_FRAME_RELATED_P (RTVEC_ELT (vec, 0)) = 1; | 3675 RTX_FRAME_RELATED_P (RTVEC_ELT (vec, 0)) = 1; |
3441 | 3676 |
3442 if (increment != 0) | 3677 if (increment != 0) |
3443 { | 3678 { |
3444 RTVEC_ELT (vec, 1) | 3679 RTVEC_ELT (vec, 1) |
3445 = gen_rtx_SET (VOIDmode, destreg, | 3680 = gen_rtx_SET (destreg, plus_constant (Pmode, destreg, |
3446 plus_constant (destreg, | 3681 increment != 0 |
3447 increment != 0 | 3682 ? increment : nregs * 4)); |
3448 ? increment : nregs * 4)); | |
3449 eltno++; | 3683 eltno++; |
3450 | 3684 |
3451 if (frame_related) | 3685 if (frame_related) |
3452 RTX_FRAME_RELATED_P (RTVEC_ELT (vec, 1)) = 1; | 3686 RTX_FRAME_RELATED_P (RTVEC_ELT (vec, 1)) = 1; |
3453 | 3687 |
3458 } | 3692 } |
3459 | 3693 |
3460 for (i = 1; i < nregs; i++, eltno++) | 3694 for (i = 1; i < nregs; i++, eltno++) |
3461 { | 3695 { |
3462 RTVEC_ELT (vec, eltno) | 3696 RTVEC_ELT (vec, eltno) |
3463 = gen_rtx_SET (VOIDmode, adjust_address_nv (dest, SImode, i * 4), | 3697 = gen_rtx_SET (adjust_address_nv (dest, SImode, i * 4), |
3464 gen_rtx_REG (SImode, regno)); | 3698 gen_rtx_REG (SImode, regno)); |
3465 if (frame_related) | 3699 if (frame_related) |
3466 RTX_FRAME_RELATED_P (RTVEC_ELT (vec, eltno)) = 1; | 3700 RTX_FRAME_RELATED_P (RTVEC_ELT (vec, eltno)) = 1; |
3467 regno += regno_inc; | 3701 regno += regno_inc; |
3468 } | 3702 } |
3499 } | 3733 } |
3500 | 3734 |
3501 /* Worker function for expanding the address for PIC function calls. */ | 3735 /* Worker function for expanding the address for PIC function calls. */ |
3502 | 3736 |
3503 void | 3737 void |
3504 cris_expand_pic_call_address (rtx *opp) | 3738 cris_expand_pic_call_address (rtx *opp, rtx *markerp) |
3505 { | 3739 { |
3506 rtx op = *opp; | 3740 rtx op = *opp; |
3507 | 3741 |
3508 gcc_assert (MEM_P (op)); | 3742 gcc_assert (flag_pic && MEM_P (op)); |
3509 op = XEXP (op, 0); | 3743 op = XEXP (op, 0); |
3510 | 3744 |
3511 /* It might be that code can be generated that jumps to 0 (or to a | 3745 /* It might be that code can be generated that jumps to 0 (or to a |
3512 specific address). Don't die on that. (There is a | 3746 specific address). Don't die on that. (There is a |
3513 testcase.) */ | 3747 testcase.) */ |
3514 if (CONSTANT_ADDRESS_P (op) && !CONST_INT_P (op)) | 3748 if (CONSTANT_P (op) && !CONST_INT_P (op)) |
3515 { | 3749 { |
3516 enum cris_pic_symbol_type t = cris_pic_symbol_type_of (op); | 3750 enum cris_symbol_type t = cris_symbol_type_of (op); |
3517 | 3751 |
3518 CRIS_ASSERT (can_create_pseudo_p ()); | 3752 CRIS_ASSERT (can_create_pseudo_p ()); |
3519 | 3753 |
3520 /* For local symbols (non-PLT), just get the plain symbol | 3754 /* For local symbols (non-PLT), just get the plain symbol |
3521 reference into a register. For symbols that can be PLT, make | 3755 reference into a register. For symbols that can be PLT, make |
3537 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), | 3771 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), |
3538 CRIS_UNSPEC_PCREL)); | 3772 CRIS_UNSPEC_PCREL)); |
3539 } | 3773 } |
3540 else | 3774 else |
3541 op = force_reg (Pmode, op); | 3775 op = force_reg (Pmode, op); |
3776 | |
3777 /* A local call. */ | |
3778 *markerp = const0_rtx; | |
3542 } | 3779 } |
3543 else if (t == cris_got_symbol) | 3780 else if (t == cris_got_symbol) |
3544 { | 3781 { |
3545 if (TARGET_AVOID_GOTPLT) | 3782 if (TARGET_AVOID_GOTPLT) |
3546 { | 3783 { |
3547 /* Change a "jsr sym" into (allocate register rM, rO) | 3784 /* Change a "jsr sym" into (allocate register rM, rO) |
3548 "move.d (const (unspec [sym rPIC] CRIS_UNSPEC_PLT_GOTREL)),rM" | 3785 "move.d (const (unspec [sym] CRIS_UNSPEC_PLT_GOTREL)),rM" |
3549 "add.d rPIC,rM,rO", "jsr rO" for pre-v32 and | 3786 "add.d rPIC,rM,rO", "jsr rO" for pre-v32 and |
3550 "jsr (const (unspec [sym rPIC] CRIS_UNSPEC_PLT_PCREL))" | 3787 "jsr (const (unspec [sym] CRIS_UNSPEC_PLT_PCREL))" |
3551 for v32. */ | 3788 for v32. */ |
3552 rtx tem, rm, ro; | 3789 rtx tem, rm, ro; |
3553 gcc_assert (can_create_pseudo_p ()); | 3790 |
3554 crtl->uses_pic_offset_table = 1; | 3791 crtl->uses_pic_offset_table = 1; |
3555 tem = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op), | 3792 tem = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op), |
3556 TARGET_V32 | 3793 TARGET_V32 |
3557 ? CRIS_UNSPEC_PLT_PCREL | 3794 ? CRIS_UNSPEC_PLT_PCREL |
3558 : CRIS_UNSPEC_PLT_GOTREL); | 3795 : CRIS_UNSPEC_PLT_GOTREL); |
3602 other same symbols is unimportant. */ | 3839 other same symbols is unimportant. */ |
3603 set_mem_alias_set (mem, new_alias_set ()); | 3840 set_mem_alias_set (mem, new_alias_set ()); |
3604 MEM_NOTRAP_P (mem) = 1; | 3841 MEM_NOTRAP_P (mem) = 1; |
3605 op = mem; | 3842 op = mem; |
3606 } | 3843 } |
3844 | |
3845 /* We need to prepare this call to go through the PLT; we | |
3846 need to make GOT available. */ | |
3847 *markerp = pic_offset_table_rtx; | |
3607 } | 3848 } |
3608 else | 3849 else |
3609 /* Can't possibly get a GOT-needing-fixup for a function-call, | 3850 /* Can't possibly get anything else for a function-call, right? */ |
3610 right? */ | |
3611 fatal_insn ("unidentifiable call op", op); | 3851 fatal_insn ("unidentifiable call op", op); |
3612 | 3852 |
3613 *opp = replace_equiv_address (*opp, op); | 3853 /* If the validizing variant is called, it will try to validize |
3614 } | 3854 the address as a valid any-operand constant, but as it's only |
3855 valid for calls and moves, it will fail and always be forced | |
3856 into a register. */ | |
3857 *opp = replace_equiv_address_nv (*opp, op); | |
3858 } | |
3859 else | |
3860 /* Can't tell what locality a call to a non-constant address has; | |
3861 better make the GOT register alive at it. | |
3862 FIXME: Can we see whether the register has known constant | |
3863 contents? */ | |
3864 *markerp = pic_offset_table_rtx; | |
3615 } | 3865 } |
3616 | 3866 |
3617 /* Make sure operands are in the right order for an addsi3 insn as | 3867 /* Make sure operands are in the right order for an addsi3 insn as |
3618 generated by a define_split. Nothing but REG_P as the first | 3868 generated by a define_split. Nothing but REG_P as the first |
3619 operand is recognized by addsi3 after reload. OPERANDS contains | 3869 operand is recognized by addsi3 after reload. OPERANDS contains |
3682 } | 3932 } |
3683 else | 3933 else |
3684 assemble_name (file, buf); | 3934 assemble_name (file, buf); |
3685 } | 3935 } |
3686 | 3936 |
3687 /* Worker function for OUTPUT_ADDR_CONST_EXTRA. */ | 3937 /* Worker function for TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */ |
3688 | 3938 |
3689 bool | 3939 static bool |
3690 cris_output_addr_const_extra (FILE *file, rtx xconst) | 3940 cris_output_addr_const_extra (FILE *file, rtx xconst) |
3691 { | 3941 { |
3692 switch (GET_CODE (xconst)) | 3942 switch (GET_CODE (xconst)) |
3693 { | 3943 { |
3694 rtx x; | 3944 rtx x; |
3757 } | 4007 } |
3758 | 4008 |
3759 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */ | 4009 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */ |
3760 | 4010 |
3761 static void | 4011 static void |
3762 cris_setup_incoming_varargs (CUMULATIVE_ARGS *ca, | 4012 cris_setup_incoming_varargs (cumulative_args_t ca_v, |
3763 enum machine_mode mode ATTRIBUTE_UNUSED, | 4013 machine_mode mode ATTRIBUTE_UNUSED, |
3764 tree type ATTRIBUTE_UNUSED, | 4014 tree type ATTRIBUTE_UNUSED, |
3765 int *pretend_arg_size, | 4015 int *pretend_arg_size, |
3766 int second_time) | 4016 int second_time) |
3767 { | 4017 { |
4018 CUMULATIVE_ARGS *ca = get_cumulative_args (ca_v); | |
4019 | |
3768 if (ca->regs < CRIS_MAX_ARGS_IN_REGS) | 4020 if (ca->regs < CRIS_MAX_ARGS_IN_REGS) |
3769 { | 4021 { |
3770 int stdarg_regs = CRIS_MAX_ARGS_IN_REGS - ca->regs; | 4022 int stdarg_regs = CRIS_MAX_ARGS_IN_REGS - ca->regs; |
3771 cfun->machine->stdarg_regs = stdarg_regs; | 4023 cfun->machine->stdarg_regs = stdarg_regs; |
3772 *pretend_arg_size = stdarg_regs * 4; | 4024 *pretend_arg_size = stdarg_regs * 4; |
3780 | 4032 |
3781 /* Return true if TYPE must be passed by invisible reference. | 4033 /* Return true if TYPE must be passed by invisible reference. |
3782 For cris, we pass <= 8 bytes by value, others by reference. */ | 4034 For cris, we pass <= 8 bytes by value, others by reference. */ |
3783 | 4035 |
3784 static bool | 4036 static bool |
3785 cris_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, | 4037 cris_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, |
3786 enum machine_mode mode, const_tree type, | 4038 machine_mode mode, const_tree type, |
3787 bool named ATTRIBUTE_UNUSED) | 4039 bool named ATTRIBUTE_UNUSED) |
3788 { | 4040 { |
3789 return (targetm.calls.must_pass_in_stack (mode, type) | 4041 return (targetm.calls.must_pass_in_stack (mode, type) |
3790 || CRIS_FUNCTION_ARG_SIZE (mode, type) > 8); | 4042 || CRIS_FUNCTION_ARG_SIZE (mode, type) > 8); |
3791 } | 4043 } |
3792 | 4044 |
3793 /* A combination of defining TARGET_PROMOTE_FUNCTION_MODE, promoting arguments | 4045 /* A combination of defining TARGET_PROMOTE_FUNCTION_MODE, promoting arguments |
3794 and *not* defining TARGET_PROMOTE_PROTOTYPES or PROMOTE_MODE gives the | 4046 and *not* defining TARGET_PROMOTE_PROTOTYPES or PROMOTE_MODE gives the |
3795 best code size and speed for gcc, ipps and products in gcc-2.7.2. */ | 4047 best code size and speed for gcc, ipps and products in gcc-2.7.2. */ |
3796 | 4048 |
3797 enum machine_mode | 4049 machine_mode |
3798 cris_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, | 4050 cris_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, |
3799 enum machine_mode mode, | 4051 machine_mode mode, |
3800 int *punsignedp ATTRIBUTE_UNUSED, | 4052 int *punsignedp ATTRIBUTE_UNUSED, |
3801 const_tree fntype ATTRIBUTE_UNUSED, | 4053 const_tree fntype ATTRIBUTE_UNUSED, |
3802 int for_return) | 4054 int for_return) |
3803 { | 4055 { |
3804 /* Defining PROMOTE_FUNCTION_RETURN in gcc-2.7.2 uncovered bug 981110 (even | 4056 /* Defining PROMOTE_FUNCTION_RETURN in gcc-2.7.2 uncovered bug 981110 (even |
3807 if (for_return == 1) | 4059 if (for_return == 1) |
3808 return mode; | 4060 return mode; |
3809 return CRIS_PROMOTED_MODE (mode, *punsignedp, type); | 4061 return CRIS_PROMOTED_MODE (mode, *punsignedp, type); |
3810 } | 4062 } |
3811 | 4063 |
4064 /* Atomic types require alignment to be at least their "natural" size. */ | |
4065 | |
4066 static unsigned int | |
4067 cris_atomic_align_for_mode (machine_mode mode) | |
4068 { | |
4069 return GET_MODE_BITSIZE (mode); | |
4070 } | |
4071 | |
3812 /* Let's assume all functions return in r[CRIS_FIRST_ARG_REG] for the | 4072 /* Let's assume all functions return in r[CRIS_FIRST_ARG_REG] for the |
3813 time being. */ | 4073 time being. */ |
3814 | 4074 |
3815 static rtx | 4075 static rtx |
3816 cris_function_value(const_tree type, | 4076 cris_function_value(const_tree type, |
3822 | 4082 |
3823 /* Let's assume all functions return in r[CRIS_FIRST_ARG_REG] for the | 4083 /* Let's assume all functions return in r[CRIS_FIRST_ARG_REG] for the |
3824 time being. */ | 4084 time being. */ |
3825 | 4085 |
3826 static rtx | 4086 static rtx |
3827 cris_libcall_value (enum machine_mode mode, | 4087 cris_libcall_value (machine_mode mode, |
3828 const_rtx fun ATTRIBUTE_UNUSED) | 4088 const_rtx fun ATTRIBUTE_UNUSED) |
3829 { | 4089 { |
3830 return gen_rtx_REG (mode, CRIS_FIRST_ARG_REG); | 4090 return gen_rtx_REG (mode, CRIS_FIRST_ARG_REG); |
3831 } | 4091 } |
3832 | 4092 |
3833 /* Let's assume all functions return in r[CRIS_FIRST_ARG_REG] for the | 4093 /* Let's assume all functions return in r[CRIS_FIRST_ARG_REG] for the |
3834 time being. */ | 4094 time being. */ |
3835 | 4095 |
3836 bool | 4096 static bool |
3837 cris_function_value_regno_p (const unsigned int regno) | 4097 cris_function_value_regno_p (const unsigned int regno) |
3838 { | 4098 { |
3839 return (regno == CRIS_FIRST_ARG_REG); | 4099 return (regno == CRIS_FIRST_ARG_REG); |
3840 } | 4100 } |
3841 | 4101 |
3842 static int | 4102 static int |
3843 cris_arg_partial_bytes (CUMULATIVE_ARGS *ca, enum machine_mode mode, | 4103 cris_arg_partial_bytes (cumulative_args_t ca, machine_mode mode, |
3844 tree type, bool named ATTRIBUTE_UNUSED) | 4104 tree type, bool named ATTRIBUTE_UNUSED) |
3845 { | 4105 { |
3846 if (ca->regs == CRIS_MAX_ARGS_IN_REGS - 1 | 4106 if (get_cumulative_args (ca)->regs == CRIS_MAX_ARGS_IN_REGS - 1 |
3847 && !targetm.calls.must_pass_in_stack (mode, type) | 4107 && !targetm.calls.must_pass_in_stack (mode, type) |
3848 && CRIS_FUNCTION_ARG_SIZE (mode, type) > 4 | 4108 && CRIS_FUNCTION_ARG_SIZE (mode, type) > 4 |
3849 && CRIS_FUNCTION_ARG_SIZE (mode, type) <= 8) | 4109 && CRIS_FUNCTION_ARG_SIZE (mode, type) <= 8) |
3850 return UNITS_PER_WORD; | 4110 return UNITS_PER_WORD; |
3851 else | 4111 else |
3852 return 0; | 4112 return 0; |
3853 } | 4113 } |
3854 | 4114 |
3855 static rtx | 4115 static rtx |
3856 cris_function_arg_1 (const CUMULATIVE_ARGS *ca, | 4116 cris_function_arg_1 (cumulative_args_t ca_v, |
3857 enum machine_mode mode ATTRIBUTE_UNUSED, | 4117 machine_mode mode ATTRIBUTE_UNUSED, |
3858 const_tree type ATTRIBUTE_UNUSED, | 4118 const_tree type ATTRIBUTE_UNUSED, |
3859 bool named, bool incoming) | 4119 bool named, bool incoming) |
3860 { | 4120 { |
4121 const CUMULATIVE_ARGS *ca = get_cumulative_args (ca_v); | |
4122 | |
3861 if ((!incoming || named) && ca->regs < CRIS_MAX_ARGS_IN_REGS) | 4123 if ((!incoming || named) && ca->regs < CRIS_MAX_ARGS_IN_REGS) |
3862 return gen_rtx_REG (mode, CRIS_FIRST_ARG_REG + ca->regs); | 4124 return gen_rtx_REG (mode, CRIS_FIRST_ARG_REG + ca->regs); |
3863 else | 4125 else |
3864 return NULL_RTX; | 4126 return NULL_RTX; |
3865 } | 4127 } |
3866 | 4128 |
3867 /* Worker function for TARGET_FUNCTION_ARG. | 4129 /* Worker function for TARGET_FUNCTION_ARG. |
3868 The void_type_node is sent as a "closing" call. */ | 4130 The void_type_node is sent as a "closing" call. */ |
3869 | 4131 |
3870 static rtx | 4132 static rtx |
3871 cris_function_arg (CUMULATIVE_ARGS *ca, enum machine_mode mode, | 4133 cris_function_arg (cumulative_args_t ca, machine_mode mode, |
3872 const_tree type, bool named) | 4134 const_tree type, bool named) |
3873 { | 4135 { |
3874 return cris_function_arg_1 (ca, mode, type, named, false); | 4136 return cris_function_arg_1 (ca, mode, type, named, false); |
3875 } | 4137 } |
3876 | 4138 |
3880 that an argument is named, since incoming stdarg/varargs arguments are | 4142 that an argument is named, since incoming stdarg/varargs arguments are |
3881 pushed onto the stack, and we don't have to check against the "closing" | 4143 pushed onto the stack, and we don't have to check against the "closing" |
3882 void_type_node TYPE parameter. */ | 4144 void_type_node TYPE parameter. */ |
3883 | 4145 |
3884 static rtx | 4146 static rtx |
3885 cris_function_incoming_arg (CUMULATIVE_ARGS *ca, enum machine_mode mode, | 4147 cris_function_incoming_arg (cumulative_args_t ca, machine_mode mode, |
3886 const_tree type, bool named) | 4148 const_tree type, bool named) |
3887 { | 4149 { |
3888 return cris_function_arg_1 (ca, mode, type, named, true); | 4150 return cris_function_arg_1 (ca, mode, type, named, true); |
3889 } | 4151 } |
3890 | 4152 |
3891 /* Worker function for TARGET_FUNCTION_ARG_ADVANCE. */ | 4153 /* Worker function for TARGET_FUNCTION_ARG_ADVANCE. */ |
3892 | 4154 |
3893 static void | 4155 static void |
3894 cris_function_arg_advance (CUMULATIVE_ARGS *ca, enum machine_mode mode, | 4156 cris_function_arg_advance (cumulative_args_t ca_v, machine_mode mode, |
3895 const_tree type, bool named ATTRIBUTE_UNUSED) | 4157 const_tree type, bool named ATTRIBUTE_UNUSED) |
3896 { | 4158 { |
4159 CUMULATIVE_ARGS *ca = get_cumulative_args (ca_v); | |
4160 | |
3897 ca->regs += (3 + CRIS_FUNCTION_ARG_SIZE (mode, type)) / 4; | 4161 ca->regs += (3 + CRIS_FUNCTION_ARG_SIZE (mode, type)) / 4; |
3898 } | 4162 } |
3899 | 4163 |
3900 /* Worker function for TARGET_MD_ASM_CLOBBERS. */ | 4164 /* Worker function for TARGET_MD_ASM_ADJUST. */ |
3901 | 4165 |
3902 static tree | 4166 static rtx_insn * |
3903 cris_md_asm_clobbers (tree outputs, tree inputs, tree in_clobbers) | 4167 cris_md_asm_adjust (vec<rtx> &outputs, vec<rtx> &inputs, |
3904 { | 4168 vec<const char *> &constraints, |
3905 HARD_REG_SET mof_set; | 4169 vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs) |
3906 tree clobbers; | 4170 { |
3907 tree t; | 4171 /* For the time being, all asms clobber condition codes. |
3908 | 4172 Revisit when there's a reasonable use for inputs/outputs |
3909 CLEAR_HARD_REG_SET (mof_set); | 4173 that mention condition codes. */ |
3910 SET_HARD_REG_BIT (mof_set, CRIS_MOF_REGNUM); | 4174 clobbers.safe_push (gen_rtx_REG (CCmode, CRIS_CC0_REGNUM)); |
3911 | 4175 SET_HARD_REG_BIT (clobbered_regs, CRIS_CC0_REGNUM); |
3912 /* For the time being, all asms clobber condition codes. Revisit when | 4176 |
3913 there's a reasonable use for inputs/outputs that mention condition | 4177 /* Determine if the source using MOF. If it is, automatically |
3914 codes. */ | 4178 clobbering MOF would cause it to have impossible constraints. */ |
3915 clobbers | 4179 |
3916 = tree_cons (NULL_TREE, | 4180 /* Look for a use of the MOF constraint letter: h. */ |
3917 build_string (strlen (reg_names[CRIS_CC0_REGNUM]), | 4181 for (unsigned i = 0, n = constraints.length(); i < n; ++i) |
3918 reg_names[CRIS_CC0_REGNUM]), | 4182 if (strchr (constraints[i], 'h') != NULL) |
3919 in_clobbers); | 4183 return NULL; |
3920 | 4184 |
3921 for (t = outputs; t != NULL; t = TREE_CHAIN (t)) | 4185 /* Look for an output or an input that touches MOF. */ |
3922 { | 4186 rtx mof_reg = gen_rtx_REG (SImode, CRIS_MOF_REGNUM); |
3923 tree val = TREE_VALUE (t); | 4187 for (unsigned i = 0, n = outputs.length(); i < n; ++i) |
3924 | 4188 if (reg_overlap_mentioned_p (mof_reg, outputs[i])) |
3925 /* The constraint letter for the singleton register class of MOF | 4189 return NULL; |
3926 is 'h'. If it's mentioned in the constraints, the asm is | 4190 for (unsigned i = 0, n = inputs.length(); i < n; ++i) |
3927 MOF-aware and adding it to the clobbers would cause it to have | 4191 if (reg_overlap_mentioned_p (mof_reg, inputs[i])) |
3928 impossible constraints. */ | 4192 return NULL; |
3929 if (strchr (TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t))), | 4193 |
3930 'h') != NULL | 4194 /* No direct reference to MOF or its constraint. |
3931 || tree_overlaps_hard_reg_set (val, &mof_set) != NULL_TREE) | 4195 Clobber it for backward compatibility. */ |
3932 return clobbers; | 4196 clobbers.safe_push (mof_reg); |
3933 } | 4197 SET_HARD_REG_BIT (clobbered_regs, CRIS_MOF_REGNUM); |
3934 | 4198 return NULL; |
3935 for (t = inputs; t != NULL; t = TREE_CHAIN (t)) | |
3936 { | |
3937 tree val = TREE_VALUE (t); | |
3938 | |
3939 if (strchr (TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t))), | |
3940 'h') != NULL | |
3941 || tree_overlaps_hard_reg_set (val, &mof_set) != NULL_TREE) | |
3942 return clobbers; | |
3943 } | |
3944 | |
3945 return tree_cons (NULL_TREE, | |
3946 build_string (strlen (reg_names[CRIS_MOF_REGNUM]), | |
3947 reg_names[CRIS_MOF_REGNUM]), | |
3948 clobbers); | |
3949 } | 4199 } |
3950 | 4200 |
3951 /* Implement TARGET_FRAME_POINTER_REQUIRED. | 4201 /* Implement TARGET_FRAME_POINTER_REQUIRED. |
3952 | 4202 |
3953 Really only needed if the stack frame has variable length (alloca | 4203 Really only needed if the stack frame has variable length (alloca |
3955 PR38609 for the reason this isn't just 0. */ | 4205 PR38609 for the reason this isn't just 0. */ |
3956 | 4206 |
3957 bool | 4207 bool |
3958 cris_frame_pointer_required (void) | 4208 cris_frame_pointer_required (void) |
3959 { | 4209 { |
3960 return !current_function_sp_is_unchanging; | 4210 return !crtl->sp_is_unchanging; |
3961 } | 4211 } |
3962 | 4212 |
3963 /* Implement TARGET_ASM_TRAMPOLINE_TEMPLATE. | 4213 /* Implement TARGET_ASM_TRAMPOLINE_TEMPLATE. |
3964 | 4214 |
3965 This looks too complicated, and it is. I assigned r7 to be the | 4215 This looks too complicated, and it is. I assigned r7 to be the |
4036 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL); | 4286 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL); |
4037 | 4287 |
4038 if (TARGET_V32) | 4288 if (TARGET_V32) |
4039 { | 4289 { |
4040 mem = adjust_address (m_tramp, SImode, 6); | 4290 mem = adjust_address (m_tramp, SImode, 6); |
4041 emit_move_insn (mem, plus_constant (tramp, 38)); | 4291 emit_move_insn (mem, plus_constant (Pmode, tramp, 38)); |
4042 mem = adjust_address (m_tramp, SImode, 22); | 4292 mem = adjust_address (m_tramp, SImode, 22); |
4043 emit_move_insn (mem, chain_value); | 4293 emit_move_insn (mem, chain_value); |
4044 mem = adjust_address (m_tramp, SImode, 28); | 4294 mem = adjust_address (m_tramp, SImode, 28); |
4045 emit_move_insn (mem, fnaddr); | 4295 emit_move_insn (mem, fnaddr); |
4046 } | 4296 } |
4054 | 4304 |
4055 /* Note that there is no need to do anything with the cache for | 4305 /* Note that there is no need to do anything with the cache for |
4056 sake of a trampoline. */ | 4306 sake of a trampoline. */ |
4057 } | 4307 } |
4058 | 4308 |
4309 /* Implement TARGET_HARD_REGNO_NREGS. | |
4310 | |
4311 The VOIDmode test is so we can omit mode on anonymous insns. FIXME: | |
4312 Still needed in 2.9x, at least for Axis-20000319. */ | |
4313 | |
4314 static unsigned int | |
4315 cris_hard_regno_nregs (unsigned int, machine_mode mode) | |
4316 { | |
4317 if (mode == VOIDmode) | |
4318 return 1; | |
4319 return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD); | |
4320 } | |
4321 | |
4322 /* Implement TARGET_HARD_REGNO_MODE_OK. | |
4323 | |
4324 CRIS permits all registers to hold all modes. Well, except for the | |
4325 condition-code register. And we can't hold larger-than-register size | |
4326 modes in the last special register that can hold a full 32 bits. */ | |
4327 static bool | |
4328 cris_hard_regno_mode_ok (unsigned int regno, machine_mode mode) | |
4329 { | |
4330 return ((mode == CCmode || regno != CRIS_CC0_REGNUM) | |
4331 && (GET_MODE_SIZE (mode) <= UNITS_PER_WORD | |
4332 || (regno != CRIS_MOF_REGNUM && regno != CRIS_ACR_REGNUM))); | |
4333 } | |
4334 | |
4335 /* Return the preferred minimum alignment for a static object. */ | |
4336 | |
4337 static HOST_WIDE_INT | |
4338 cris_preferred_mininum_alignment (void) | |
4339 { | |
4340 if (!TARGET_CONST_ALIGN) | |
4341 return 8; | |
4342 if (TARGET_ALIGN_BY_32) | |
4343 return 32; | |
4344 return 16; | |
4345 } | |
4346 | |
4347 /* Implement TARGET_STATIC_RTX_ALIGNMENT. */ | |
4348 | |
4349 static HOST_WIDE_INT | |
4350 cris_static_rtx_alignment (machine_mode mode) | |
4351 { | |
4352 return MAX (cris_preferred_mininum_alignment (), GET_MODE_ALIGNMENT (mode)); | |
4353 } | |
4354 | |
4355 /* Implement TARGET_CONSTANT_ALIGNMENT. Note that this hook has the | |
4356 effect of making gcc believe that ALL references to constant stuff | |
4357 (in code segment, like strings) have this alignment. That is a rather | |
4358 rushed assumption. Luckily we do not care about the "alignment" | |
4359 operand to builtin memcpy (only place where it counts), so it doesn't | |
4360 affect any bad spots. */ | |
4361 | |
4362 static HOST_WIDE_INT | |
4363 cris_constant_alignment (const_tree, HOST_WIDE_INT basic_align) | |
4364 { | |
4365 return MAX (cris_preferred_mininum_alignment (), basic_align); | |
4366 } | |
4059 | 4367 |
4060 #if 0 | 4368 #if 0 |
4061 /* Various small functions to replace macros. Only called from a | 4369 /* Various small functions to replace macros. Only called from a |
4062 debugger. They might collide with gcc functions or system functions, | 4370 debugger. They might collide with gcc functions or system functions, |
4063 so only emit them when '#if 1' above. */ | 4371 so only emit them when '#if 1' above. */ |