]>
Commit | Line | Data |
---|---|---|
bdcee471 | 1 | /* Output routines for Sunplus S+CORE processor |
96e45421 JM |
2 | Copyright (C) 2005, 2007, 2008, 2009, 2010, 2011 |
3 | Free Software Foundation, Inc. | |
bdcee471 CL |
4 | Contributed by Sunnorth. |
5 | ||
6 | This file is part of GCC. | |
7 | ||
8 | GCC is free software; you can redistribute it and/or modify it | |
9 | under the terms of the GNU General Public License as published | |
2f83c7d6 | 10 | by the Free Software Foundation; either version 3, or (at your |
bdcee471 CL |
11 | option) any later version. |
12 | ||
13 | GCC is distributed in the hope that it will be useful, but WITHOUT | |
14 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
15 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | |
16 | License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
2f83c7d6 NC |
19 | along with GCC; see the file COPYING3. If not see |
20 | <http://www.gnu.org/licenses/>. */ | |
bdcee471 CL |
21 | |
22 | #include "config.h" | |
23 | #include "system.h" | |
24 | #include "coretypes.h" | |
25 | #include "tm.h" | |
bdcee471 CL |
26 | #include "rtl.h" |
27 | #include "regs.h" | |
28 | #include "hard-reg-set.h" | |
bdcee471 CL |
29 | #include "insn-config.h" |
30 | #include "conditions.h" | |
31 | #include "insn-attr.h" | |
32 | #include "recog.h" | |
718f9c0f | 33 | #include "diagnostic-core.h" |
bdcee471 CL |
34 | #include "output.h" |
35 | #include "tree.h" | |
36 | #include "function.h" | |
37 | #include "expr.h" | |
38 | #include "optabs.h" | |
39 | #include "flags.h" | |
40 | #include "reload.h" | |
41 | #include "tm_p.h" | |
42 | #include "ggc.h" | |
43 | #include "gstab.h" | |
44 | #include "hashtab.h" | |
45 | #include "debug.h" | |
46 | #include "target.h" | |
47 | #include "target-def.h" | |
48 | #include "integrate.h" | |
49 | #include "langhooks.h" | |
254f5222 | 50 | #include "score7.h" |
899cc0f4 | 51 | #include "df.h" |
96e45421 | 52 | #include "opts.h" |
bdcee471 | 53 | |
c5387660 JM |
54 | static void score_option_override (void); |
55 | ||
bdcee471 | 56 | #undef TARGET_ASM_FILE_START |
254f5222 | 57 | #define TARGET_ASM_FILE_START score_asm_file_start |
bdcee471 CL |
58 | |
59 | #undef TARGET_ASM_FILE_END | |
254f5222 | 60 | #define TARGET_ASM_FILE_END score_asm_file_end |
bdcee471 CL |
61 | |
62 | #undef TARGET_ASM_FUNCTION_PROLOGUE | |
254f5222 | 63 | #define TARGET_ASM_FUNCTION_PROLOGUE score_function_prologue |
bdcee471 CL |
64 | |
65 | #undef TARGET_ASM_FUNCTION_EPILOGUE | |
254f5222 CL |
66 | #define TARGET_ASM_FUNCTION_EPILOGUE score_function_epilogue |
67 | ||
c5387660 JM |
68 | #undef TARGET_OPTION_OVERRIDE |
69 | #define TARGET_OPTION_OVERRIDE score_option_override | |
9d6193a7 | 70 | |
506d7b68 PB |
71 | #undef TARGET_LEGITIMIZE_ADDRESS |
72 | #define TARGET_LEGITIMIZE_ADDRESS score_legitimize_address | |
73 | ||
bdcee471 | 74 | #undef TARGET_SCHED_ISSUE_RATE |
254f5222 | 75 | #define TARGET_SCHED_ISSUE_RATE score_issue_rate |
bdcee471 CL |
76 | |
77 | #undef TARGET_ASM_SELECT_RTX_SECTION | |
254f5222 | 78 | #define TARGET_ASM_SELECT_RTX_SECTION score_select_rtx_section |
bdcee471 CL |
79 | |
80 | #undef TARGET_IN_SMALL_DATA_P | |
254f5222 | 81 | #define TARGET_IN_SMALL_DATA_P score_in_small_data_p |
bdcee471 CL |
82 | |
83 | #undef TARGET_FUNCTION_OK_FOR_SIBCALL | |
254f5222 | 84 | #define TARGET_FUNCTION_OK_FOR_SIBCALL score_function_ok_for_sibcall |
bdcee471 CL |
85 | |
86 | #undef TARGET_STRICT_ARGUMENT_NAMING | |
254f5222 | 87 | #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true |
bdcee471 CL |
88 | |
89 | #undef TARGET_ASM_OUTPUT_MI_THUNK | |
254f5222 | 90 | #define TARGET_ASM_OUTPUT_MI_THUNK score_output_mi_thunk |
bdcee471 | 91 | |
cde0f3fd PB |
92 | #undef TARGET_PROMOTE_FUNCTION_MODE |
93 | #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote | |
bdcee471 CL |
94 | |
95 | #undef TARGET_PROMOTE_PROTOTYPES | |
996893ce | 96 | #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true |
bdcee471 CL |
97 | |
98 | #undef TARGET_MUST_PASS_IN_STACK | |
cf723ae8 | 99 | #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size |
bdcee471 CL |
100 | |
101 | #undef TARGET_ARG_PARTIAL_BYTES | |
cf723ae8 | 102 | #define TARGET_ARG_PARTIAL_BYTES score_arg_partial_bytes |
bdcee471 | 103 | |
3a2bd2f4 NF |
104 | #undef TARGET_FUNCTION_ARG |
105 | #define TARGET_FUNCTION_ARG score_function_arg | |
106 | ||
107 | #undef TARGET_FUNCTION_ARG_ADVANCE | |
108 | #define TARGET_FUNCTION_ARG_ADVANCE score_function_arg_advance | |
109 | ||
bdcee471 | 110 | #undef TARGET_PASS_BY_REFERENCE |
cf723ae8 | 111 | #define TARGET_PASS_BY_REFERENCE score_pass_by_reference |
bdcee471 CL |
112 | |
113 | #undef TARGET_RETURN_IN_MEMORY | |
cf723ae8 TS |
114 | #define TARGET_RETURN_IN_MEMORY score_return_in_memory |
115 | ||
116 | #undef TARGET_RTX_COSTS | |
117 | #define TARGET_RTX_COSTS score_rtx_costs | |
bdcee471 | 118 | |
99fc2502 CL |
119 | #undef TARGET_ADDRESS_COST |
120 | #define TARGET_ADDRESS_COST score_address_cost | |
121 | ||
c6c3dba9 PB |
122 | #undef TARGET_LEGITIMATE_ADDRESS_P |
123 | #define TARGET_LEGITIMATE_ADDRESS_P score_legitimate_address_p | |
124 | ||
7b5cbb57 AS |
125 | #undef TARGET_CAN_ELIMINATE |
126 | #define TARGET_CAN_ELIMINATE score_can_eliminate | |
127 | ||
5efd84c5 NF |
128 | #undef TARGET_CONDITIONAL_REGISTER_USAGE |
129 | #define TARGET_CONDITIONAL_REGISTER_USAGE score_conditional_register_usage | |
130 | ||
2f5bb28c RH |
131 | #undef TARGET_ASM_TRAMPOLINE_TEMPLATE |
132 | #define TARGET_ASM_TRAMPOLINE_TEMPLATE score_asm_trampoline_template | |
133 | #undef TARGET_TRAMPOLINE_INIT | |
134 | #define TARGET_TRAMPOLINE_INIT score_trampoline_init | |
135 | ||
254f5222 | 136 | struct extern_list *extern_head = 0; |
254f5222 CL |
137 | |
138 | /* default 0 = NO_REGS */ | |
139 | enum reg_class score_char_to_class[256]; | |
93ef7c1f | 140 | |
bdcee471 CL |
141 | /* Implement TARGET_RETURN_IN_MEMORY. In S+core, |
142 | small structures are returned in a register. | |
143 | Objects with varying size must still be returned in memory. */ | |
144 | static bool | |
996893ce | 145 | score_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED) |
bdcee471 | 146 | { |
9d6193a7 | 147 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
254f5222 | 148 | return score7_return_in_memory (type, fndecl); |
9d6193a7 CL |
149 | else |
150 | gcc_unreachable (); | |
bdcee471 CL |
151 | } |
152 | ||
153 | /* Return nonzero when an argument must be passed by reference. */ | |
154 | static bool | |
d5cc9181 | 155 | score_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, |
996893ce | 156 | enum machine_mode mode, const_tree type, |
bdcee471 CL |
157 | bool named ATTRIBUTE_UNUSED) |
158 | { | |
159 | /* If we have a variable-sized parameter, we have no choice. */ | |
160 | return targetm.calls.must_pass_in_stack (mode, type); | |
161 | } | |
162 | ||
bdcee471 CL |
163 | /* Implement TARGET_ASM_OUTPUT_MI_THUNK. Generate rtl rather than asm text |
164 | in order to avoid duplicating too much logic from elsewhere. */ | |
165 | static void | |
254f5222 CL |
166 | score_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, |
167 | HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset, | |
168 | tree function) | |
bdcee471 | 169 | { |
9d6193a7 | 170 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
996893ce | 171 | score7_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function); |
996893ce JR |
172 | else |
173 | gcc_unreachable (); | |
bdcee471 CL |
174 | } |
175 | ||
176 | /* Implement TARGET_FUNCTION_OK_FOR_SIBCALL. */ | |
177 | static bool | |
254f5222 CL |
178 | score_function_ok_for_sibcall (ATTRIBUTE_UNUSED tree decl, |
179 | ATTRIBUTE_UNUSED tree exp) | |
bdcee471 CL |
180 | { |
181 | return true; | |
182 | } | |
183 | ||
bdcee471 CL |
184 | /* Set up the stack and frame (if desired) for the function. */ |
185 | static void | |
254f5222 | 186 | score_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED) |
bdcee471 | 187 | { |
9d6193a7 | 188 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
996893ce | 189 | score7_function_prologue (file, size); |
996893ce JR |
190 | else |
191 | gcc_unreachable (); | |
bdcee471 CL |
192 | } |
193 | ||
194 | /* Do any necessary cleanup after a function to restore stack, frame, | |
195 | and regs. */ | |
196 | static void | |
254f5222 CL |
197 | score_function_epilogue (FILE *file, |
198 | HOST_WIDE_INT size ATTRIBUTE_UNUSED) | |
bdcee471 | 199 | { |
9d6193a7 | 200 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
996893ce | 201 | score7_function_epilogue (file, size); |
996893ce JR |
202 | else |
203 | gcc_unreachable (); | |
bdcee471 CL |
204 | } |
205 | ||
206 | /* Implement TARGET_SCHED_ISSUE_RATE. */ | |
207 | static int | |
254f5222 | 208 | score_issue_rate (void) |
bdcee471 CL |
209 | { |
210 | return 1; | |
211 | } | |
212 | ||
bdcee471 CL |
213 | /* Choose the section to use for the constant rtx expression X that has |
214 | mode MODE. */ | |
215 | static section * | |
254f5222 CL |
216 | score_select_rtx_section (enum machine_mode mode, rtx x, |
217 | unsigned HOST_WIDE_INT align) | |
bdcee471 | 218 | { |
9d6193a7 | 219 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
254f5222 | 220 | return score7_select_rtx_section (mode, x, align); |
9d6193a7 CL |
221 | else |
222 | gcc_unreachable (); | |
bdcee471 CL |
223 | } |
224 | ||
225 | /* Implement TARGET_IN_SMALL_DATA_P. */ | |
226 | static bool | |
996893ce | 227 | score_in_small_data_p (const_tree decl) |
bdcee471 | 228 | { |
9d6193a7 | 229 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
254f5222 | 230 | return score7_in_small_data_p (decl); |
9d6193a7 CL |
231 | else |
232 | gcc_unreachable (); | |
bdcee471 CL |
233 | } |
234 | ||
235 | /* Implement TARGET_ASM_FILE_START. */ | |
236 | static void | |
254f5222 | 237 | score_asm_file_start (void) |
bdcee471 | 238 | { |
9d6193a7 | 239 | if (TARGET_SCORE7D) |
254f5222 CL |
240 | fprintf (asm_out_file, "# Sunplus S+core7d %s rev=%s\n", |
241 | TARGET_LITTLE_ENDIAN ? "el" : "eb", SCORE_GCC_VERSION); | |
242 | else if (TARGET_SCORE7) | |
243 | fprintf (asm_out_file, "# Sunplus S+core7 %s rev=%s\n", | |
244 | TARGET_LITTLE_ENDIAN ? "el" : "eb", SCORE_GCC_VERSION); | |
254f5222 CL |
245 | else |
246 | fprintf (asm_out_file, "# Sunplus S+core unknown %s rev=%s\n", | |
247 | TARGET_LITTLE_ENDIAN ? "el" : "eb", SCORE_GCC_VERSION); | |
248 | ||
bdcee471 | 249 | default_file_start (); |
bdcee471 CL |
250 | |
251 | if (flag_pic) | |
252 | fprintf (asm_out_file, "\t.set pic\n"); | |
253 | } | |
254 | ||
255 | /* Implement TARGET_ASM_FILE_END. When using assembler macros, emit | |
256 | .externs for any small-data variables that turned out to be external. */ | |
bdcee471 | 257 | static void |
254f5222 | 258 | score_asm_file_end (void) |
bdcee471 | 259 | { |
9d6193a7 | 260 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
996893ce | 261 | score7_asm_file_end (); |
996893ce JR |
262 | else |
263 | gcc_unreachable (); | |
bdcee471 CL |
264 | } |
265 | ||
c5387660 JM |
266 | /* Implement TARGET_OPTION_OVERRIDE hook. */ |
267 | static void | |
268 | score_option_override (void) | |
254f5222 | 269 | { |
9d6193a7 | 270 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
996893ce | 271 | score7_option_override (); |
bdcee471 CL |
272 | } |
273 | ||
274 | /* Implement REGNO_REG_CLASS macro. */ | |
275 | int | |
276 | score_reg_class (int regno) | |
277 | { | |
9d6193a7 | 278 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
254f5222 | 279 | return score7_reg_class (regno); |
9d6193a7 CL |
280 | else |
281 | gcc_unreachable (); | |
bdcee471 CL |
282 | } |
283 | ||
284 | /* Implement PREFERRED_RELOAD_CLASS macro. */ | |
285 | enum reg_class | |
0a2aaacc | 286 | score_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, enum reg_class rclass) |
bdcee471 | 287 | { |
9d6193a7 | 288 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
0a2aaacc | 289 | return score7_preferred_reload_class (x, rclass); |
9d6193a7 CL |
290 | else |
291 | gcc_unreachable (); | |
bdcee471 CL |
292 | } |
293 | ||
294 | /* Implement SECONDARY_INPUT_RELOAD_CLASS | |
295 | and SECONDARY_OUTPUT_RELOAD_CLASS macro. */ | |
296 | enum reg_class | |
0a2aaacc | 297 | score_secondary_reload_class (enum reg_class rclass, |
bdcee471 CL |
298 | enum machine_mode mode ATTRIBUTE_UNUSED, |
299 | rtx x) | |
300 | { | |
9d6193a7 | 301 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
0a2aaacc | 302 | return score7_secondary_reload_class (rclass, mode, x); |
9d6193a7 CL |
303 | else |
304 | gcc_unreachable (); | |
bdcee471 CL |
305 | } |
306 | ||
bdcee471 CL |
307 | |
308 | /* Return truth value on whether or not a given hard register | |
309 | can support a given mode. */ | |
310 | int | |
311 | score_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode) | |
312 | { | |
9d6193a7 | 313 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
254f5222 | 314 | return score7_hard_regno_mode_ok (regno, mode); |
9d6193a7 CL |
315 | else |
316 | gcc_unreachable (); | |
bdcee471 CL |
317 | } |
318 | ||
7b5cbb57 AS |
319 | /* We can always eliminate to the hard frame pointer. We can eliminate |
320 | to the stack pointer unless a frame pointer is needed. */ | |
321 | ||
322 | static bool | |
323 | score_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) | |
324 | { | |
325 | return (to == HARD_FRAME_POINTER_REGNUM | |
326 | || (to == STACK_POINTER_REGNUM && !frame_pointer_needed)); | |
327 | } | |
328 | ||
bdcee471 CL |
329 | /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame |
330 | pointer or argument pointer. TO is either the stack pointer or | |
331 | hard frame pointer. */ | |
332 | HOST_WIDE_INT | |
333 | score_initial_elimination_offset (int from, | |
334 | int to ATTRIBUTE_UNUSED) | |
335 | { | |
9d6193a7 | 336 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
254f5222 | 337 | return score7_initial_elimination_offset (from, to); |
9d6193a7 CL |
338 | else |
339 | gcc_unreachable (); | |
bdcee471 CL |
340 | } |
341 | ||
342 | /* Argument support functions. */ | |
343 | ||
344 | /* Initialize CUMULATIVE_ARGS for a function. */ | |
345 | void | |
346 | score_init_cumulative_args (CUMULATIVE_ARGS *cum, | |
347 | tree fntype ATTRIBUTE_UNUSED, | |
348 | rtx libname ATTRIBUTE_UNUSED) | |
349 | { | |
350 | memset (cum, 0, sizeof (CUMULATIVE_ARGS)); | |
351 | } | |
352 | ||
3a2bd2f4 | 353 | /* Implement TARGET_FUNCTION_ARG_ADVANCE hook. */ |
996893ce | 354 | static void |
d5cc9181 | 355 | score_function_arg_advance (cumulative_args_t cum, enum machine_mode mode, |
3a2bd2f4 | 356 | const_tree type, bool named) |
bdcee471 | 357 | { |
9d6193a7 | 358 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
d5cc9181 | 359 | score7_function_arg_advance (get_cumulative_args (cum), mode, type, named); |
996893ce JR |
360 | else |
361 | gcc_unreachable (); | |
bdcee471 CL |
362 | } |
363 | ||
364 | /* Implement TARGET_ARG_PARTIAL_BYTES macro. */ | |
254f5222 | 365 | int |
d5cc9181 | 366 | score_arg_partial_bytes (cumulative_args_t cum, |
586de218 | 367 | enum machine_mode mode, tree type, bool named) |
bdcee471 | 368 | { |
9d6193a7 | 369 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
d5cc9181 JR |
370 | return score7_arg_partial_bytes (get_cumulative_args (cum), mode, type, |
371 | named); | |
9d6193a7 CL |
372 | else |
373 | gcc_unreachable (); | |
bdcee471 CL |
374 | } |
375 | ||
3a2bd2f4 | 376 | /* Implement TARGET_FUNCTION_ARG hook. */ |
996893ce | 377 | static rtx |
d5cc9181 | 378 | score_function_arg (cumulative_args_t cum, enum machine_mode mode, |
3a2bd2f4 | 379 | const_tree type, bool named) |
bdcee471 | 380 | { |
9d6193a7 | 381 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
d5cc9181 | 382 | return score7_function_arg (get_cumulative_args (cum), mode, type, named); |
9d6193a7 CL |
383 | else |
384 | gcc_unreachable (); | |
bdcee471 CL |
385 | } |
386 | ||
387 | /* Implement FUNCTION_VALUE and LIBCALL_VALUE. For normal calls, | |
388 | VALTYPE is the return type and MODE is VOIDmode. For libcalls, | |
389 | VALTYPE is null and MODE is the mode of the return value. */ | |
390 | rtx | |
996893ce | 391 | score_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED, |
bdcee471 CL |
392 | enum machine_mode mode) |
393 | { | |
9d6193a7 | 394 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
254f5222 | 395 | return score7_function_value (valtype, func, mode); |
9d6193a7 CL |
396 | else |
397 | gcc_unreachable (); | |
bdcee471 CL |
398 | } |
399 | ||
2f5bb28c RH |
400 | /* Implement TARGET_ASM_TRAMPOLINE_TEMPLATE. */ |
401 | static void | |
402 | score_asm_trampoline_template (FILE *f) | |
403 | { | |
9d6193a7 | 404 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
996893ce | 405 | score7_asm_trampoline_template (f); |
996893ce JR |
406 | else |
407 | gcc_unreachable (); | |
2f5bb28c RH |
408 | } |
409 | ||
410 | /* Implement TARGET_TRAMPOLINE_INIT. */ | |
411 | static void | |
412 | score_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) | |
bdcee471 | 413 | { |
9d6193a7 | 414 | if ( TARGET_SCORE7 || TARGET_SCORE7D) |
996893ce | 415 | score7_trampoline_init (m_tramp, fndecl, chain_value); |
9d6193a7 | 416 | else |
996893ce | 417 | gcc_unreachable (); |
bdcee471 CL |
418 | } |
419 | ||
420 | /* This function is used to implement REG_MODE_OK_FOR_BASE_P macro. */ | |
421 | int | |
422 | score_regno_mode_ok_for_base_p (int regno, int strict) | |
423 | { | |
9d6193a7 | 424 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
254f5222 | 425 | return score7_regno_mode_ok_for_base_p (regno, strict); |
9d6193a7 CL |
426 | else |
427 | gcc_unreachable (); | |
bdcee471 CL |
428 | } |
429 | ||
331d9186 | 430 | /* Implement TARGET_LEGITIMIZE_ADDRESS_P. */ |
996893ce | 431 | static bool |
c6c3dba9 | 432 | score_legitimate_address_p (enum machine_mode mode, rtx x, bool strict) |
bdcee471 | 433 | { |
9d6193a7 | 434 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
c6c3dba9 | 435 | return score7_legitimate_address_p (mode, x, strict); |
9d6193a7 CL |
436 | else |
437 | gcc_unreachable (); | |
bdcee471 CL |
438 | } |
439 | ||
506d7b68 | 440 | /* This function is used to implement LEGITIMIZE_ADDRESS. If X can |
bdcee471 | 441 | be legitimized in a way that the generic machinery might not expect, |
506d7b68 PB |
442 | return the new address, else return X. */ |
443 | static rtx | |
444 | score_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, | |
445 | enum machine_mode mode ATTRIBUTE_UNUSED) | |
bdcee471 | 446 | { |
9d6193a7 | 447 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
506d7b68 | 448 | return score7_legitimize_address (x); |
9d6193a7 CL |
449 | else |
450 | gcc_unreachable (); | |
bdcee471 CL |
451 | } |
452 | ||
453 | /* Return a number assessing the cost of moving a register in class | |
454 | FROM to class TO. */ | |
455 | int | |
456 | score_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED, | |
457 | enum reg_class from, enum reg_class to) | |
458 | { | |
9d6193a7 | 459 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
254f5222 | 460 | return score7_register_move_cost (mode, from, to); |
9d6193a7 CL |
461 | else |
462 | gcc_unreachable (); | |
bdcee471 CL |
463 | } |
464 | ||
254f5222 CL |
465 | /* Implement TARGET_RTX_COSTS macro. */ |
466 | bool | |
f40751dd JH |
467 | score_rtx_costs (rtx x, int code, int outer_code, int *total, |
468 | bool speed ATTRIBUTE_UNUSED) | |
cf723ae8 | 469 | { |
9d6193a7 | 470 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
899cc0f4 | 471 | return score7_rtx_costs (x, code, outer_code, total, speed); |
9d6193a7 CL |
472 | else |
473 | gcc_unreachable (); | |
254f5222 CL |
474 | } |
475 | ||
476 | /* Implement TARGET_ADDRESS_COST macro. */ | |
477 | int | |
f40751dd JH |
478 | score_address_cost (rtx addr, |
479 | bool speed ATTRIBUTE_UNUSED) | |
254f5222 | 480 | { |
9d6193a7 | 481 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
254f5222 | 482 | return score7_address_cost (addr); |
9d6193a7 CL |
483 | else |
484 | gcc_unreachable (); | |
cf723ae8 TS |
485 | } |
486 | ||
254f5222 CL |
487 | /* Implement ASM_OUTPUT_EXTERNAL macro. */ |
488 | int | |
489 | score_output_external (FILE *file ATTRIBUTE_UNUSED, | |
490 | tree decl, const char *name) | |
cf723ae8 | 491 | { |
9d6193a7 | 492 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
254f5222 | 493 | return score7_output_external (file, decl, name); |
9d6193a7 CL |
494 | else |
495 | gcc_unreachable (); | |
cf723ae8 TS |
496 | } |
497 | ||
254f5222 CL |
498 | /* Implement RETURN_ADDR_RTX. Note, we do not support moving |
499 | back to a previous frame. */ | |
500 | rtx | |
501 | score_return_addr (int count, rtx frame ATTRIBUTE_UNUSED) | |
cf723ae8 | 502 | { |
9d6193a7 | 503 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
254f5222 | 504 | return score7_return_addr (count, frame); |
9d6193a7 CL |
505 | else |
506 | gcc_unreachable (); | |
254f5222 | 507 | } |
cf723ae8 | 508 | |
254f5222 CL |
509 | /* Implement PRINT_OPERAND macro. */ |
510 | void | |
511 | score_print_operand (FILE *file, rtx op, int c) | |
512 | { | |
9d6193a7 | 513 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
996893ce | 514 | score7_print_operand (file, op, c); |
996893ce JR |
515 | else |
516 | gcc_unreachable (); | |
254f5222 | 517 | } |
cf723ae8 | 518 | |
254f5222 CL |
519 | /* Implement PRINT_OPERAND_ADDRESS macro. */ |
520 | void | |
521 | score_print_operand_address (FILE *file, rtx x) | |
522 | { | |
9d6193a7 | 523 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
996893ce | 524 | score7_print_operand_address (file, x); |
996893ce JR |
525 | else |
526 | gcc_unreachable (); | |
254f5222 | 527 | } |
cf723ae8 | 528 | |
254f5222 CL |
529 | /* Implement SELECT_CC_MODE macro. */ |
530 | enum machine_mode | |
531 | score_select_cc_mode (enum rtx_code op, rtx x, rtx y) | |
532 | { | |
9d6193a7 | 533 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
254f5222 | 534 | return score7_select_cc_mode (op, x, y); |
9d6193a7 CL |
535 | else |
536 | gcc_unreachable (); | |
254f5222 | 537 | } |
cf723ae8 | 538 | |
254f5222 CL |
539 | /* Return true if X is a symbolic constant that can be calculated in |
540 | the same way as a bare symbol. If it is, store the type of the | |
541 | symbol in *SYMBOL_TYPE. */ | |
542 | int | |
543 | score_symbolic_constant_p (rtx x, enum score_symbol_type *symbol_type) | |
544 | { | |
9d6193a7 | 545 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
254f5222 | 546 | return score7_symbolic_constant_p (x, symbol_type); |
9d6193a7 CL |
547 | else |
548 | gcc_unreachable (); | |
254f5222 | 549 | } |
cf723ae8 | 550 | |
254f5222 CL |
551 | /* Generate the prologue instructions for entry into a S+core function. */ |
552 | void | |
553 | score_prologue (void) | |
554 | { | |
9d6193a7 | 555 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
996893ce | 556 | score7_prologue (); |
996893ce JR |
557 | else |
558 | gcc_unreachable (); | |
254f5222 | 559 | } |
cf723ae8 | 560 | |
254f5222 CL |
561 | /* Generate the epilogue instructions in a S+core function. */ |
562 | void | |
563 | score_epilogue (int sibcall_p) | |
564 | { | |
9d6193a7 | 565 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
996893ce | 566 | score7_epilogue (sibcall_p); |
996893ce JR |
567 | else |
568 | gcc_unreachable (); | |
254f5222 | 569 | } |
cf723ae8 | 570 | |
254f5222 CL |
571 | /* Call and sibcall pattern all need call this function. */ |
572 | void | |
573 | score_call (rtx *ops, bool sib) | |
99fc2502 | 574 | { |
9d6193a7 | 575 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
996893ce | 576 | score7_call (ops, sib); |
996893ce JR |
577 | else |
578 | gcc_unreachable (); | |
99fc2502 CL |
579 | } |
580 | ||
254f5222 CL |
581 | /* Call value and sibcall value pattern all need call this function. */ |
582 | void | |
583 | score_call_value (rtx *ops, bool sib) | |
bdcee471 | 584 | { |
9d6193a7 | 585 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
996893ce | 586 | score7_call_value (ops, sib); |
996893ce JR |
587 | else |
588 | gcc_unreachable (); | |
bdcee471 CL |
589 | } |
590 | ||
bdcee471 | 591 | void |
254f5222 | 592 | score_movsicc (rtx *ops) |
bdcee471 | 593 | { |
9d6193a7 | 594 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
996893ce | 595 | score7_movsicc (ops); |
996893ce JR |
596 | else |
597 | gcc_unreachable (); | |
bdcee471 CL |
598 | } |
599 | ||
254f5222 CL |
600 | /* Machine Split */ |
601 | void | |
602 | score_movdi (rtx *ops) | |
bdcee471 | 603 | { |
9d6193a7 | 604 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
996893ce | 605 | score7_movdi (ops); |
996893ce JR |
606 | else |
607 | gcc_unreachable (); | |
bdcee471 CL |
608 | } |
609 | ||
bdcee471 | 610 | void |
254f5222 CL |
611 | score_zero_extract_andi (rtx *ops) |
612 | { | |
9d6193a7 | 613 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
996893ce | 614 | score7_zero_extract_andi (ops); |
996893ce JR |
615 | else |
616 | gcc_unreachable (); | |
254f5222 CL |
617 | } |
618 | ||
619 | /* Output asm insn for move. */ | |
620 | const char * | |
621 | score_move (rtx *ops) | |
622 | { | |
9d6193a7 | 623 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
254f5222 | 624 | return score7_move (ops); |
9d6193a7 CL |
625 | else |
626 | gcc_unreachable (); | |
254f5222 CL |
627 | } |
628 | ||
629 | /* Output asm insn for load. */ | |
630 | const char * | |
631 | score_linsn (rtx *ops, enum score_mem_unit unit, bool sign) | |
632 | { | |
9d6193a7 | 633 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
254f5222 | 634 | return score7_linsn (ops, unit, sign); |
9d6193a7 CL |
635 | else |
636 | gcc_unreachable (); | |
254f5222 CL |
637 | } |
638 | ||
639 | /* Output asm insn for store. */ | |
640 | const char * | |
641 | score_sinsn (rtx *ops, enum score_mem_unit unit) | |
642 | { | |
9d6193a7 | 643 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
254f5222 | 644 | return score7_sinsn (ops, unit); |
9d6193a7 CL |
645 | else |
646 | gcc_unreachable (); | |
254f5222 CL |
647 | } |
648 | ||
649 | /* Output asm insn for load immediate. */ | |
650 | const char * | |
651 | score_limm (rtx *ops) | |
652 | { | |
9d6193a7 | 653 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
254f5222 | 654 | return score7_limm (ops); |
9d6193a7 CL |
655 | else |
656 | gcc_unreachable (); | |
254f5222 CL |
657 | } |
658 | ||
659 | ||
660 | /* Generate add insn. */ | |
661 | const char * | |
662 | score_select_add_imm (rtx *ops, bool set_cc) | |
bdcee471 | 663 | { |
9d6193a7 | 664 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
254f5222 | 665 | return score7_select_add_imm (ops, set_cc); |
9d6193a7 CL |
666 | else |
667 | gcc_unreachable (); | |
254f5222 CL |
668 | } |
669 | ||
670 | /* Output arith insn. */ | |
671 | const char * | |
672 | score_select (rtx *ops, const char *inst_pre, | |
673 | bool commu, const char *letter, bool set_cc) | |
674 | { | |
9d6193a7 | 675 | if (TARGET_SCORE7 || TARGET_SCORE7D) |
254f5222 | 676 | return score7_select (ops, inst_pre, commu, letter, set_cc); |
bdcee471 | 677 | else |
9d6193a7 | 678 | gcc_unreachable (); |
99fc2502 CL |
679 | } |
680 | ||
5efd84c5 NF |
681 | static void |
682 | score_conditional_register_usage (void) | |
683 | { | |
684 | if (!flag_pic) | |
685 | fixed_regs[PIC_OFFSET_TABLE_REGNUM] = | |
686 | call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 0; | |
687 | } | |
688 | ||
bdcee471 | 689 | struct gcc_target targetm = TARGET_INITIALIZER; |