comparison gcc/config/csky/csky.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents
children 1830386684a0
comparison
equal deleted inserted replaced
111:04ced10e8804 131:84e7813d76e9
1 /* GCC backend functions for C-SKY targets.
2 Copyright (C) 2018 Free Software Foundation, Inc.
3 Contributed by C-SKY Microsystems and Mentor Graphics.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published
9 by the Free Software Foundation; either version 3, or (at your
10 option) any later version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
20
21 #define IN_TARGET_CODE 1
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "memmodel.h"
27 #include "backend.h"
28 #include "target.h"
29 #include "rtl.h"
30 #include "tree.h"
31 #include "cfghooks.h"
32 #include "df.h"
33 #include "tm_p.h"
34 #include "stringpool.h"
35 #include "attribs.h"
36 #include "optabs.h"
37 #include "regs.h"
38 #include "emit-rtl.h"
39 #include "recog.h"
40 #include "cgraph.h"
41 #include "c-family/c-common.h"
42 #include "cpplib.h"
43 #include "diagnostic-core.h"
44 #include "alias.h"
45 #include "fold-const.h"
46 #include "stor-layout.h"
47 #include "calls.h"
48 #include "varasm.h"
49 #include "output.h"
50 #include "insn-attr.h"
51 #include "flags.h"
52 #include "reload.h"
53 #include "explow.h"
54 #include "expr.h"
55 #include "cfgrtl.h"
56 #include "sched-int.h"
57 #include "common/common-target.h"
58 #include "langhooks.h"
59 #include "intl.h"
60 #include "libfuncs.h"
61 #include "params.h"
62 #include "opts.h"
63 #include "dumpfile.h"
64 #include "target-globals.h"
65 #include "builtins.h"
66 #include "tm-constrs.h"
67 #include "rtl-iter.h"
68 #include "pass_manager.h"
69 #include "tree-pass.h"
70 #include "context.h"
71
72 /* This file should be included last. */
73 #include "target-def.h"
74
75 /* Stack and register size macros. */
76
77 #define CSKY_NUM_WORDS(SIZE) \
78 (((SIZE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
79 #define CSKY_NUM_REGS(MODE) \
80 CSKY_NUM_WORDS (GET_MODE_SIZE (MODE))
81 #define CSKY_STACK_ALIGN(SIZE) \
82 (CSKY_NUM_WORDS (SIZE) * UNITS_PER_WORD)
83
84 /* Offsets and range macros. */
85
86 #define CSKY_LD16_MAX_OFFSET(MODE) \
87 (31 * GET_MODE_SIZE (MODE))
88 #define CSKY_LD32_MAX_OFFSET(MODE) \
89 (4095 * GET_MODE_SIZE (MODE))
90 #define CSKY_LD16_OFFSET_MASK(MODE) \
91 (CSKY_LD16_MAX_OFFSET (MODE) + GET_MODE_SIZE (MODE) - 1)
92
93 #define CSKY_ADDI16_MAX_IMM 256
94 #define CSKY_SUBI16_MAX_IMM 256
95
96 #define CSKY_CONSTPOOL_LABEL_PREFIX "LCP"
97
98 /* Array of the smallest class containing reg number REGNO, indexed by
99 REGNO. Used by REGNO_REG_CLASS. */
100 enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER] =
101 {
102 /* Registers r0-r7. */
103 MINI_REGS, MINI_REGS, MINI_REGS, MINI_REGS,
104 MINI_REGS, MINI_REGS, MINI_REGS, MINI_REGS,
105 /* Registers r8-r15. */
106 LOW_REGS, LOW_REGS, LOW_REGS, LOW_REGS,
107 LOW_REGS, LOW_REGS, SP_REGS, LOW_REGS,
108 /* Registers r16-r31. */
109 GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
110 GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
111 GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
112 GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
113 /* Reserved. */
114 RESERVE_REGS,
115 /* CC,HI,LO registers. */
116 C_REGS, HI_REGS, LO_REGS,
117 /* Reserved. */
118 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
119 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
120 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
121 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
122 /* Vec registers. */
123 V_REGS, V_REGS, V_REGS, V_REGS,
124 V_REGS, V_REGS, V_REGS, V_REGS,
125 V_REGS, V_REGS, V_REGS, V_REGS,
126 V_REGS, V_REGS, V_REGS, V_REGS,
127 /* Reserved. */
128 RESERVE_REGS, RESERVE_REGS,
129 /* Register epc. */
130 OTHER_REGS
131 };
132
133 /* Arrays that map GCC register numbers to debugger register numbers,
134 '-1' means that is INVALID_REGNUM.
135 TODO: which rules according to here ? */
136 const int csky_dbx_regno[FIRST_PSEUDO_REGISTER] =
137 {
138 0, 1, 2, 3, 4, 5, 6, 7,
139 8, 9, 10, 11, 12, 13, 14, 15,
140 16, 17, 18, 19, 20, 21, 22, 23,
141 24, 25, 26, 27, 28, 29, 30, 31,
142 -1, -1, 36, 37, -1, -1, -1, -1,
143 -1, -1, -1, -1, -1, -1, -1, -1,
144 -1, -1, -1, -1, 56, 57, 58, 59,
145 60, 61, 62, 63, 64, 65, 66, 67,
146 68, 69, 70, 71, -1, -1, 72
147 };
148
149 /* Table of machine attributes. */
150 static tree csky_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
151 static tree csky_handle_isr_attribute (tree *, tree, tree, int, bool *);
152 static const struct attribute_spec csky_attribute_table[] =
153 {
154 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
155 affects_type_identity, handler, exclude } */
156 { "naked", 0, 0, true, false, false, false, csky_handle_fndecl_attribute, NULL },
157 /* Interrupt Service Routines have special prologue and epilogue requirements. */
158 { "interrupt", 0, 1, false, false, false, false, csky_handle_isr_attribute, NULL },
159 { "isr", 0, 1, false, false, false, false, csky_handle_isr_attribute, NULL },
160 { NULL, 0, 0, false, false, false, false, NULL, NULL }
161 };
162
163 /* A C structure for machine-specific, per-function data.
164 This is added to the cfun structure. */
165 typedef struct GTY(()) machine_function
166 {
167 /* Records if LR has to be saved for far jumps. */
168 int far_jump_used;
169 /* Records the type of the current function. */
170 unsigned long func_type;
171 /* Record if the function has a variable argument list. */
172 int uses_anonymous_args;
173
174 /* Stack frame layout information. If frame_init_p is true,
175 these fields have been initialized and don't need to be
176 recomputed. */
177 unsigned int reg_mask; /* non-volatile reg saves */
178 int arg_size; /* stdarg spills (bytes) */
179 int reg_size; /* non-volatile reg saves (bytes) */
180 int local_size; /* locals */
181 int outbound_size; /* arg overflow on calls out */
182 int frame_size; /* total static size of stack frame */
183 int local_offset;
184 int reg_offset;
185 int arg_offset;
186 int frame_init_p;
187
188 } machine_function;
189
190 /* These macros are for the func_type values above. */
191 #define CSKY_FT_TYPE_MASK ((1 << 3) - 1)
192 #define CSKY_FT_UNKNOWN 0 /* Type not been determined */
193 #define CSKY_FT_NORMAL 1 /* Normal function */
194 #define CSKY_FT_ISR 4 /* Interrupt service routine */
195 #define CSKY_FT_FIQ 5 /* Fast interrupt service routine */
196 #define CSKY_FT_EXCEPTION 6 /* Exception handler */
197 #define CSKY_FT_INTERRUPT (1 << 2) /* overlap CSKY_FT_ISR */
198 #define CSKY_FT_NAKED (1 << 3) /* No prologue and epilogue */
199 #define CSKY_FUNCTION_TYPE(t) ((t) & CSKY_FT_TYPE_MASK)
200 #define CSKY_FUNCTION_IS_INTERRUPT(t) ((t) & CSKY_FT_INTERRUPT)
201 #define CSKY_FUNCTION_IS_NAKED(t) ((t) & CSKY_FT_NAKED)
202
203 struct csky_processors
204 {
205 const char *const name;
206 enum csky_processor_type core;
207 const char *arch;
208 enum csky_base_architecture base_arch;
209 enum csky_isa_feature isa_bits[CSKY_ISA_FEATURE_GET (max)];
210 };
211
212 static struct csky_processors all_cores[] =
213 {
214 #undef CSKY_CORE
215 #define CSKY_CORE(NAME, CORE, X, ARCH, ISA) \
216 {NAME, TARGET_CPU_##CORE, #ARCH, CSKY_BASE_ARCH_##ARCH, \
217 {ISA CSKY_ISA_FEATURE_GET (none)}},
218 #include "csky_cores.def"
219 #undef CSKY_CORE
220 {NULL, TARGET_CPU_csky_none, NULL, CSKY_BASE_ARCH_NONE, \
221 {CSKY_ISA_FEATURE_GET (none)}}
222 };
223
224 static struct csky_processors all_architectures[] =
225 {
226 #undef CSKY_ARCH
227 #define CSKY_ARCH(NAME, CORE, ARCH, ISA) \
228 {NAME, TARGET_CPU_##CORE, #ARCH, CSKY_BASE_ARCH_##ARCH, \
229 {ISA CSKY_ISA_FEATURE_GET (none)}},
230 #include "csky_cores.def"
231 #undef CSKY_ARCH
232 {NULL, TARGET_CPU_csky_none, NULL, CSKY_BASE_ARCH_NONE, \
233 {CSKY_ISA_FEATURE_GET (none)}}
234 };
235
236 struct csky_fpu_desc
237 {
238 const char *name;
239 enum csky_isa_feature isa_bits[CSKY_ISA_FEATURE_GET (max)];
240 };
241
242 static const struct csky_fpu_desc all_fpus[] =
243 {
244 #undef CSKY_FPU
245 #define CSKY_FPU(NAME, CNAME, ISA) \
246 {NAME, {ISA CSKY_ISA_FEATURE_GET (none)}},
247 #include "csky_cores.def"
248 #undef CSKY_FPU
249 };
250
251 /* Active target architecture. */
252 struct csky_build_target
253 {
254 /* Name of the target CPU, if known, or NULL if the target CPU was not
255 specified by the user (and inferred from the -march option). */
256 const char *core_name;
257 /* Name of the target ARCH. NULL if there is a selected CPU. */
258 const char *arch_name;
259 /* Preprocessor substring (never NULL). */
260 const char *arch_pp_name;
261 /* CPU identifier for the core we're compiling for (architecturally). */
262 enum csky_processor_type arch_core;
263 /* The base architecture value. */
264 enum csky_base_architecture base_arch;
265 /* Bitmap encapsulating the isa_bits for the target environment. */
266 sbitmap isa;
267 };
268
269 struct csky_build_target csky_active_target;
270
271 /* The following are used in the .md file as equivalents to bits. */
272 int csky_arch_isa_features[CSKY_ISA_FEATURE_GET (max)] = {0};
273
274 /* The highest CSKY architecture version supported by the target. */
275 enum csky_base_architecture csky_base_arch = CSKY_TARGET_ARCH_GET (NONE);
276
277 /* Forward definitions of types. */
278 typedef struct minipool_node Mnode;
279 typedef struct minipool_fixup Mfix;
280
281 static GTY(()) int tls_labelno;
282
283
284 /* Maximum constant offset that can be added/subtracted from SP in a
285 single instruction. For ck801, this is for addsp/subsp, otherwise
286 it is the range of addi/subi. */
287 #define CSKY_MAX_SP_ADJUST \
288 (CSKY_TARGET_ARCH (CK801) ? 508 : 4096)
289
290
291 /* Implement TARGET_CPU_CPP_BUILTINS. */
292
293 #define builtin_define(MACRO) cpp_define (pfile, MACRO)
294
295 void
296 csky_cpu_cpp_builtins (cpp_reader *pfile)
297 {
298 const char *arch_name = csky_active_target.arch_pp_name;
299 char *pp_name = (char *) alloca (1 + strlen (arch_name) + 4);
300 sprintf (pp_name, "__%s__", arch_name);
301 builtin_define (pp_name);
302
303 builtin_define ("__csky__=2");
304 builtin_define ("__CSKY__=2");
305 builtin_define ("__ckcore__=2");
306 builtin_define ("__CKCORE__=2");
307
308 builtin_define ("__CSKYABIV2__");
309 builtin_define ("__cskyabiv2__");
310 builtin_define ("__CSKYABI__=2");
311 builtin_define ("__cskyabi__=2");
312
313 if (TARGET_BIG_ENDIAN)
314 {
315 builtin_define ("__ckcoreBE__");
316 builtin_define ("__cskyBE__");
317 builtin_define ("__cskybe__");
318 builtin_define ("__CSKYBE__");
319 }
320 else
321 {
322 builtin_define ("__ckcoreLE__");
323 builtin_define ("__cskyLE__");
324 builtin_define ("__cskyle__");
325 builtin_define ("__CSKYLE__");
326 }
327
328 if (TARGET_HARD_FLOAT)
329 {
330 builtin_define ("__csky_hard_float__");
331 builtin_define ("__CSKY_HARD_FLOAT__");
332 }
333 else
334 {
335 builtin_define ("__csky_soft_float__");
336 builtin_define ("__CSKY_SOFT_FLOAT__");
337 }
338
339 if (CSKY_ISA_FEATURE (fpv2_sf))
340 {
341 builtin_define ("__csky_fpuv2__");
342 builtin_define ("__CSKY_FPUV2__");
343 }
344
345 if (TARGET_ELRW)
346 {
347 builtin_define ("__csky_elrw__");
348 builtin_define ("__CSKY_ELRW__");
349 }
350 if (TARGET_ISTACK)
351 {
352 builtin_define ("__csky_istack__");
353 builtin_define ("__CSKY_ISTACK__");
354 }
355 if (TARGET_MP)
356 {
357 builtin_define ("__csky_mp__");
358 builtin_define ("__CSKY_MP__");
359 }
360 if (TARGET_CP)
361 {
362 builtin_define ("__csky_cp__");
363 builtin_define ("__CSKY_CP__");
364 }
365 if (TARGET_CACHE)
366 {
367 builtin_define ("__csky_cache__");
368 builtin_define ("__CSKY_CACHE__");
369 }
370 if (TARGET_SECURITY)
371 {
372 builtin_define ("__csky_security__");
373 builtin_define ("__CSKY_SECURITY__");
374 }
375 if (TARGET_TRUST)
376 {
377 builtin_define ("__csky_trust__");
378 builtin_define ("__CSKY_TRUST__");
379 }
380 if (TARGET_DSP)
381 {
382 builtin_define ("__csky_dsp__");
383 builtin_define ("__CSKY_DSP__");
384 }
385 if (TARGET_EDSP)
386 {
387 builtin_define ("__csky_edsp__");
388 builtin_define ("__CSKY_EDSP__");
389 }
390 if (TARGET_VDSP)
391 {
392 builtin_define ("__csky_vdsp__");
393 builtin_define ("__CSKY_VDSP__");
394 }
395 }
396
397
398 /******************************************************************
399 * Storage Layout *
400 ******************************************************************/
401
402
403 #undef TARGET_PROMOTE_FUNCTION_MODE
404 #define TARGET_PROMOTE_FUNCTION_MODE \
405 default_promote_function_mode_always_promote
406
407 #undef TARGET_CONSTANT_ALIGNMENT
408 #define TARGET_CONSTANT_ALIGNMENT csky_constant_alignment
409
410
411 /******************************************************************
412 * Stack Layout and Calling Conventions *
413 ******************************************************************/
414
415 #undef TARGET_CAN_ELIMINATE
416 #define TARGET_CAN_ELIMINATE csky_can_eliminate
417
418 #undef TARGET_FUNCTION_ARG
419 #define TARGET_FUNCTION_ARG csky_function_arg
420
421 #undef TARGET_FUNCTION_ARG_ADVANCE
422 #define TARGET_FUNCTION_ARG_ADVANCE csky_function_arg_advance
423
424 #undef TARGET_FUNCTION_VALUE
425 #define TARGET_FUNCTION_VALUE csky_function_value
426
427 #undef TARGET_LIBCALL_VALUE
428 #define TARGET_LIBCALL_VALUE csky_libcall_value
429
430 #undef TARGET_FUNCTION_VALUE_REGNO_P
431 #define TARGET_FUNCTION_VALUE_REGNO_P csky_function_value_regno_p
432
433 #undef TARGET_SPLIT_COMPLEX_ARG
434 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
435
436 #undef TARGET_PROMOTE_PROTOTYPES
437 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
438
439 #undef TARGET_MUST_PASS_IN_STACK
440 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
441
442 #undef TARGET_ARG_PARTIAL_BYTES
443 #define TARGET_ARG_PARTIAL_BYTES csky_arg_partial_bytes
444
445 #undef TARGET_PASS_BY_REFERENCE
446 #define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_must_pass_in_stack
447
448 #undef TARGET_ASM_OUTPUT_MI_THUNK
449 #define TARGET_ASM_OUTPUT_MI_THUNK csky_output_mi_thunk
450
451 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
452 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK \
453 hook_bool_const_tree_hwi_hwi_const_tree_true
454
455 #undef TARGET_ASM_FUNCTION_PROLOGUE
456 #define TARGET_ASM_FUNCTION_PROLOGUE csky_output_function_prologue
457
458 #undef TARGET_ASM_FUNCTION_EPILOGUE
459 #define TARGET_ASM_FUNCTION_EPILOGUE csky_output_function_epilogue
460
461 #undef TARGET_WARN_FUNC_RETURN
462 #define TARGET_WARN_FUNC_RETURN csky_warn_func_return
463
464 #undef TARGET_RETURN_IN_MEMORY
465 #define TARGET_RETURN_IN_MEMORY csky_return_in_memory
466
467
468 /******************************************************************
469 * Implementing the Varargs Macros *
470 ******************************************************************/
471
472
473 #undef TARGET_SETUP_INCOMING_VARARGS
474 #define TARGET_SETUP_INCOMING_VARARGS csky_setup_incoming_varargs
475
476
477 /******************************************************************
478 * Implicit Calls to Library Routines *
479 ******************************************************************/
480
481
482 #undef TARGET_INIT_LIBFUNCS
483 #define TARGET_INIT_LIBFUNCS csky_init_libfuncs
484
485
486 /******************************************************************
487 * Dividing the Output into Sections (Texts, Data, . . . ) *
488 ******************************************************************/
489
490
491 #undef TARGET_HAVE_TLS
492 #define TARGET_HAVE_TLS TARGET_CSKY_LINUX
493
494
495 /******************************************************************
496 * Defining target-specific uses of __attribute__ *
497 ******************************************************************/
498
499
500 #undef TARGET_ATTRIBUTE_TABLE
501 #define TARGET_ATTRIBUTE_TABLE csky_attribute_table
502
503 #undef TARGET_OPTION_OVERRIDE
504 #define TARGET_OPTION_OVERRIDE csky_option_override
505
506
507 /* Implement the BRANCH_COST target macro. */
508
509 int
510 csky_default_branch_cost (bool speed_p ATTRIBUTE_UNUSED,
511 bool predictable_p ATTRIBUTE_UNUSED)
512 {
513 return csky_branch_cost;
514 }
515
516 bool
517 csky_default_logical_op_non_short_circuit (void)
518 {
519 return BRANCH_COST (optimize_function_for_speed_p (cfun), false) >= 2;
520 }
521
522 /******************************************************************
523 * Register Usage *
524 ******************************************************************/
525
526 #undef TARGET_HARD_REGNO_NREGS
527 #define TARGET_HARD_REGNO_NREGS csky_hard_regno_nregs
528
529 #undef TARGET_HARD_REGNO_MODE_OK
530 #define TARGET_HARD_REGNO_MODE_OK csky_hard_regno_mode_ok
531
532 #undef TARGET_MODES_TIEABLE_P
533 #define TARGET_MODES_TIEABLE_P csky_modes_tieable_p
534
535 #undef TARGET_CAN_CHANGE_MODE_CLASS
536 #define TARGET_CAN_CHANGE_MODE_CLASS csky_can_change_mode_class
537
538 #undef TARGET_CONDITIONAL_REGISTER_USAGE
539 #define TARGET_CONDITIONAL_REGISTER_USAGE csky_conditional_register_usage
540
541 #undef TARGET_CLASS_LIKELY_SPILLED_P
542 #define TARGET_CLASS_LIKELY_SPILLED_P csky_class_likely_spilled_p
543
544 #undef TARGET_PREFERRED_RELOAD_CLASS
545 #define TARGET_PREFERRED_RELOAD_CLASS csky_preferred_reload_class
546
547 #undef TARGET_CLASS_MAX_NREGS
548 #define TARGET_CLASS_MAX_NREGS csky_class_max_nregs
549
550 #undef TARGET_SECONDARY_RELOAD
551 #define TARGET_SECONDARY_RELOAD csky_secondary_reload
552
553 #undef TARGET_SPILL_CLASS
554 #define TARGET_SPILL_CLASS csky_spill_class
555
556
557 /******************************************************************
558 * Addressing Modes *
559 ******************************************************************/
560
561
562 #undef TARGET_CANNOT_FORCE_CONST_MEM
563 #define TARGET_CANNOT_FORCE_CONST_MEM csky_cannot_force_const_mem
564
565 #undef TARGET_LEGITIMATE_CONSTANT_P
566 #define TARGET_LEGITIMATE_CONSTANT_P csky_legitimate_constant_p
567
568 #undef TARGET_LEGITIMIZE_ADDRESS
569 #define TARGET_LEGITIMIZE_ADDRESS csky_legitimize_address
570
571 #undef TARGET_LEGITIMATE_ADDRESS_P
572 #define TARGET_LEGITIMATE_ADDRESS_P csky_legitimate_address_p
573
574
575 /******************************************************************
576 * Others *
577 ******************************************************************/
578
579
580 #undef TARGET_CANNOT_COPY_INSN_P
581 #define TARGET_CANNOT_COPY_INSN_P csky_cannot_copy_insn_p
582
583
584 /******************************************************************
585 * Assembler Format *
586 ******************************************************************/
587
588
589 #undef TARGET_PRINT_OPERAND
590 #define TARGET_PRINT_OPERAND csky_print_operand
591
592 #undef TARGET_PRINT_OPERAND_ADDRESS
593 #define TARGET_PRINT_OPERAND_ADDRESS csky_print_operand_address
594
595 #undef TARGET_ASM_UNALIGNED_HI_OP
596 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
597
598 #undef TARGET_ASM_UNALIGNED_SI_OP
599 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
600
601 #undef TARGET_DWARF_REGISTER_SPAN
602 #define TARGET_DWARF_REGISTER_SPAN csky_dwarf_register_span
603
604
605 /******************************************************************
606 * Miscellaneous Parameters *
607 ******************************************************************/
608
609
610 #undef TARGET_MACHINE_DEPENDENT_REORG
611 #define TARGET_MACHINE_DEPENDENT_REORG csky_reorg
612
613 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
614 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS csky_allocate_stack_slots_for_args
615
616 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
617 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
618
619
620 /******************************************************************
621 * Trampolines for Nested Functions *
622 ******************************************************************/
623
624
625 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
626 #define TARGET_ASM_TRAMPOLINE_TEMPLATE csky_asm_trampoline_template
627 #undef TARGET_TRAMPOLINE_INIT
628 #define TARGET_TRAMPOLINE_INIT csky_trampoline_init
629
630 /* The low bit is ignored by jsr and jmp instructions so is safe to use. */
631 #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
632 #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1
633
634 /******************************************************************
635 * Describing Relative Costs of Operations *
636 ******************************************************************/
637
638
639 #undef TARGET_REGISTER_MOVE_COST
640 #define TARGET_REGISTER_MOVE_COST csky_register_move_cost
641
642 #undef TARGET_MEMORY_MOVE_COST
643 #define TARGET_MEMORY_MOVE_COST csky_memory_move_cost
644
645 #undef TARGET_RTX_COSTS
646 #define TARGET_RTX_COSTS csky_rtx_costs
647
648 #undef TARGET_ADDRESS_COST
649 #define TARGET_ADDRESS_COST csky_address_cost
650
651
652 /******************************************************************
653 * Anchor address *
654 ******************************************************************/
655
656
657 /* FIXME: the max offset is related to mode size, the following is
658 defined according to SImode. How to deal with HImode and
659 QImode, and should the min offset be defined? */
660 #undef TARGET_MAX_ANCHOR_OFFSET
661 #define TARGET_MAX_ANCHOR_OFFSET \
662 ((TARGET_MINI_REGISTERS && optimize_size) ? 127 : 4095)
663
664
665 /******************************************************************
666 * Condition Code Status *
667 ******************************************************************/
668
669
670 #undef TARGET_FIXED_CONDITION_CODE_REGS
671 #define TARGET_FIXED_CONDITION_CODE_REGS csky_fixed_condition_code_regs
672
673
674 /******************************************************************
675 * Adjusting the Instruction Scheduler *
676 ******************************************************************/
677
678
679 #undef TARGET_SCHED_ISSUE_RATE
680 #define TARGET_SCHED_ISSUE_RATE csky_sched_issue_rate
681
682 #undef TARGET_SCHED_ADJUST_COST
683 #define TARGET_SCHED_ADJUST_COST csky_sched_adjust_cost
684
685
686 /* The declaration of functions. */
687 static void push_csky_minipool_fix (rtx_insn *, HOST_WIDE_INT, rtx *,
688 machine_mode, rtx);
689 static void csky_print_operand (FILE *stream, rtx x, int code);
690
691
692 /* Define a table to map ISR attribute arguments onto function type
693 modifiers. */
694
695 typedef struct
696 {
697 const char *const arg;
698 const unsigned long return_value;
699 } isr_attribute_entry;
700
701 static const isr_attribute_entry isr_attribute_map[] =
702 {
703 {"irq", CSKY_FT_ISR },
704 {"IRQ", CSKY_FT_ISR },
705 {"fiq", CSKY_FT_FIQ },
706 {"FIQ", CSKY_FT_FIQ },
707 {NULL, CSKY_FT_NORMAL }
708 };
709
710
711 /* Return the function type of the current function, if it has not been
712 determined, return CSKY_FT_UNKNOWN. */
713
714 static unsigned long
715 get_csky_isr_type (tree argument)
716 {
717 const isr_attribute_entry *ptr;
718 const char *arg;
719
720 /* if argument is NULL, set default value ISR. */
721 if (argument == NULL_TREE)
722 return CSKY_FT_ISR;
723
724 if (TREE_VALUE (argument) == NULL_TREE
725 || TREE_CODE (TREE_VALUE (argument)) != STRING_CST)
726 return CSKY_FT_UNKNOWN;
727
728 arg = TREE_STRING_POINTER (TREE_VALUE (argument));
729
730 for (ptr = isr_attribute_map; ptr->arg != NULL; ptr++)
731 if (strcmp (arg, ptr->arg) == 0)
732 return ptr->return_value;
733
734 return CSKY_FT_UNKNOWN;
735 }
736
737 /* Classify cfun as a normal function or some sort of interrupt
738 handler, and set the corresponding bits in cfun->machine->func_type. */
739
740 static unsigned long
741 get_csky_current_func_type (void)
742 {
743 if (CSKY_FUNCTION_TYPE (cfun->machine->func_type) == CSKY_FT_UNKNOWN)
744 {
745 unsigned long type = CSKY_FT_UNKNOWN;
746 tree a;
747 tree attr;
748
749 gcc_assert (TREE_CODE (current_function_decl) == FUNCTION_DECL);
750
751 attr = DECL_ATTRIBUTES (current_function_decl);
752 a = lookup_attribute ("naked", attr);
753 if (a != NULL_TREE)
754 type |= CSKY_FT_NAKED;
755 a = lookup_attribute ("isr", attr);
756 if (a == NULL_TREE)
757 a = lookup_attribute ("interrupt", attr);
758 if (a == NULL_TREE)
759 type |= CSKY_FT_NORMAL;
760 else
761 type |= get_csky_isr_type (TREE_VALUE (a));
762
763 cfun->machine->func_type = type;
764 }
765
766 return cfun->machine->func_type;
767 }
768
769 /* These typedefs are located at the start of this file, so that
770 they can be used in the prototypes there. This comment is to
771 remind readers of that fact so that the following structures
772 can be understood more easily.
773
774 typedef struct minipool_node Mnode;
775 typedef struct minipool_fixup Mfix; */
776
777 struct minipool_node
778 {
779 /* Doubly linked chain of entries. */
780 Mnode *next;
781 Mnode *prev;
782 /* The maximum offset into the code that this entry can be placed. While
783 pushing fixes for forward references, all entries are sorted in order
784 of increasing max_address. */
785 HOST_WIDE_INT max_address;
786 /* Similarly for an entry inserted for a backwards ref. */
787 HOST_WIDE_INT min_address;
788 /* The number of fixes referencing this entry. This can become zero
789 if we "unpush" an entry. In this case we ignore the entry when we
790 come to emit the code. */
791 int refcount;
792 /* The offset from the start of the minipool. */
793 HOST_WIDE_INT offset;
794 /* The value in table. */
795 rtx value;
796 /* The mode of value. */
797 machine_mode mode;
798 /* The size of the value. */
799 int fix_size;
800 };
801
802 struct minipool_fixup
803 {
804 Mfix *next;
805 rtx_insn *insn;
806 HOST_WIDE_INT address;
807 rtx *loc;
808 machine_mode mode;
809 int fix_size;
810 rtx value;
811 Mnode *minipool;
812 HOST_WIDE_INT forwards;
813 HOST_WIDE_INT backwards;
814 };
815
816 static Mnode *minipool_vector_head;
817 static Mnode *minipool_vector_tail;
818 static rtx minipool_vector_label;
819 static HOST_WIDE_INT constpool_label_no = 0;
820
821 /* Obstack for minipool constant handling. */
822 static struct obstack minipool_obstack;
823 static char *minipool_startobj;
824 /* The linked list of all minipool fixes required for this function. */
825 Mfix *minipool_fix_head;
826 Mfix *minipool_fix_tail;
827 /* The fix entry for the current minipool, once it has been placed. */
828 Mfix *minipool_barrier;
829
830 /* Allow GC scanning of the minipool obstack. */
831 static void
832 csky_add_gc_roots (void)
833 {
834 gcc_obstack_init (&minipool_obstack);
835 minipool_startobj = (char *) obstack_alloc (&minipool_obstack, 0);
836 }
837
838 /* Implement TARGET_CONSTANT_ALIGNMENT.
839 Make strings word-aligned so strcpy from constants will be faster. */
840 static HOST_WIDE_INT
841 csky_constant_alignment (const_tree exp, HOST_WIDE_INT align)
842 {
843 if (TREE_CODE (exp) == STRING_CST
844 && !optimize_size
845 && align < BITS_PER_WORD)
846 return BITS_PER_WORD;
847 return align;
848 }
849
850 /* Record that there is a natural barrier in the insn stream at
851 ADDRESS. */
852
853 static void
854 push_csky_minipool_barrier (rtx_insn *insn, HOST_WIDE_INT address)
855 {
856 Mfix *fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (*fix));
857
858 fix->insn = insn;
859 fix->address = address;
860
861 fix->next = NULL;
862 if (minipool_fix_head != NULL)
863 minipool_fix_tail->next = fix;
864 else
865 minipool_fix_head = fix;
866
867 minipool_fix_tail = fix;
868 }
869
870 /* Compute the size of a vector jump table. */
871
872 static HOST_WIDE_INT
873 get_csky_jump_table_size (rtx insn)
874 {
875 /* ADDR_VECs only take room if read-only data does into the text
876 section. */
877 if (JUMP_TABLES_IN_TEXT_SECTION || readonly_data_section == text_section)
878 {
879 rtx body = PATTERN (insn);
880 int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0;
881 HOST_WIDE_INT size;
882 HOST_WIDE_INT modesize;
883
884 modesize = GET_MODE_SIZE (GET_MODE (body));
885 size = modesize * XVECLEN (body, elt);
886 switch (modesize)
887 {
888 case 1:
889 /* Round up size of TBB table to a halfword boundary. */
890 size = (size + 1) & ~(HOST_WIDE_INT)1;
891 break;
892 case 2:
893 /* No padding necessary for TBH. */
894 break;
895 case 4:
896 break;
897 default:
898 gcc_unreachable ();
899 }
900 return size;
901 }
902
903 return 0;
904 }
905
906
907 /* Scan INSN and note any of its operands that need fixing.
908 If DO_PUSHES is false we do not actually push any of the fixups
909 needed. The function returns TRUE if any fixups were needed/pushed. */
910
911 static bool
912 note_csky_invalid_constants (rtx_insn *insn, HOST_WIDE_INT address,
913 int do_pushes)
914 {
915 bool result = false;
916 int opno;
917
918 extract_constrain_insn (insn);
919
920 if (recog_data.n_alternatives == 0)
921 return false;
922
923 /* Fill in recog_op_alt with information about the constraints of
924 this insn. */
925 preprocess_constraints (insn);
926
927 const operand_alternative *op_alt = which_op_alt ();
928 for (opno = 0; opno < recog_data.n_operands; opno++)
929 {
930 /* Things we need to fix can only occur in inputs. */
931 if (recog_data.operand_type[opno] != OP_IN)
932 continue;
933
934 /* If this alternative is a memory reference, then any mention
935 of constants in this alternative is really to fool reload
936 into allowing us to accept one there. We need to fix them up
937 now so that we output the right code. */
938 if (op_alt[opno].memory_ok)
939 {
940 rtx op = recog_data.operand[opno];
941
942 if (CONSTANT_P (op))
943 {
944 if (do_pushes)
945 push_csky_minipool_fix (insn, address,
946 recog_data.operand_loc[opno],
947 recog_data.operand_mode[opno], op);
948 result = true;
949 }
950 }
951 }
952
953 return result;
954 }
955
956
957 /* Add a constant to the minipool for a forward reference. Returns the
958 node added or NULL if the constant will not fit in this pool. */
959
960 static Mnode *
961 add_csky_minipool_forward_ref (Mfix *fix)
962 {
963 /* If set, max_mp is the first pool_entry that has a lower
964 constraint than the one we are trying to add. */
965 Mnode *max_mp = NULL;
966 HOST_WIDE_INT max_address = fix->address + fix->forwards;
967 Mnode *mp;
968
969 /* If the minipool starts before the end of FIX->INSN then this FIX
970 can not be placed into the current pool. Furthermore, adding the
971 new constant pool entry may cause the pool to start FIX_SIZE bytes
972 earlier. */
973 if (minipool_vector_head
974 && (fix->address + get_attr_length (fix->insn)
975 >= minipool_vector_head->max_address - fix->fix_size))
976 return NULL;
977
978 /* Scan the pool to see if a constant with the same value has
979 already been added. While we are doing this, also note the
980 location where we must insert the constant if it doesn't already
981 exist. */
982 for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
983 {
984 if (GET_CODE (fix->value) == GET_CODE (mp->value)
985 && fix->mode == mp->mode
986 && (GET_CODE (fix->value) != CODE_LABEL
987 || (CODE_LABEL_NUMBER (fix->value)
988 == CODE_LABEL_NUMBER (mp->value)))
989 && rtx_equal_p (fix->value, mp->value))
990 {
991 /* More than one fix references this entry. */
992 mp->refcount++;
993 return mp;
994 }
995
996 /* Note the insertion point if necessary. */
997 if (max_mp == NULL && mp->max_address > max_address)
998 max_mp = mp;
999 }
1000
1001 /* The value is not currently in the minipool, so we need to create
1002 a new entry for it. If MAX_MP is NULL, the entry will be put on
1003 the end of the list since the placement is less constrained than
1004 any existing entry. Otherwise, we insert the new fix before
1005 MAX_MP and, if necessary, adjust the constraints on the other
1006 entries. */
1007 mp = XNEW (Mnode);
1008 mp->fix_size = fix->fix_size;
1009 mp->mode = fix->mode;
1010 mp->value = fix->value;
1011 mp->refcount = 1;
1012 /* Not yet required for a backwards ref. */
1013 mp->min_address = -65536;
1014
1015 if (max_mp == NULL)
1016 {
1017 mp->max_address = max_address;
1018 mp->next = NULL;
1019 mp->prev = minipool_vector_tail;
1020
1021 if (mp->prev == NULL)
1022 {
1023 minipool_vector_head = mp;
1024 minipool_vector_label
1025 = gen_csky_constpool_label (gen_rtx_CONST_INT (VOIDmode,
1026 constpool_label_no++));
1027 }
1028 else
1029 mp->prev->next = mp;
1030
1031 minipool_vector_tail = mp;
1032 }
1033 else
1034 {
1035 if (max_address > max_mp->max_address - mp->fix_size)
1036 mp->max_address = max_mp->max_address - mp->fix_size;
1037 else
1038 mp->max_address = max_address;
1039
1040 mp->next = max_mp;
1041 mp->prev = max_mp->prev;
1042 max_mp->prev = mp;
1043 if (mp->prev != NULL)
1044 mp->prev->next = mp;
1045 else
1046 minipool_vector_head = mp;
1047 }
1048
1049 /* Save the new entry. */
1050 max_mp = mp;
1051
1052 /* Scan over the preceding entries and adjust their addresses as
1053 required. */
1054 while (mp->prev != NULL
1055 && mp->prev->max_address > mp->max_address - mp->prev->fix_size)
1056 {
1057 mp->prev->max_address = mp->max_address - mp->prev->fix_size;
1058 mp = mp->prev;
1059 }
1060
1061 return max_mp;
1062 }
1063
1064
1065 /* Return the cost of forcibly inserting a barrier after INSN. */
1066
1067 static int
1068 get_csky_barrier_cost (rtx_insn *insn)
1069 {
1070 /* Basing the location of the pool on the loop depth is preferable,
1071 but at the moment, the basic block information seems to be
1072 corrupt by this stage of the compilation. */
1073 int base_cost = 50;
1074 rtx next = next_nonnote_insn (insn);
1075
1076 if (next != NULL && GET_CODE (next) == CODE_LABEL)
1077 base_cost -= 20;
1078
1079 switch (GET_CODE (insn))
1080 {
1081 case CODE_LABEL:
1082 /* It will always be better to place the table before the label, rather
1083 than after it. */
1084 return 50;
1085
1086 case INSN:
1087 case CALL_INSN:
1088 return base_cost;
1089
1090 case JUMP_INSN:
1091 return base_cost - 10;
1092
1093 default:
1094 return base_cost + 10;
1095 }
1096 }
1097
1098
1099 /* Find the best place in the insn stream in the range
1100 (FIX->address,MAX_ADDRESS) to forcibly insert a minipool barrier.
1101 Create the barrier by inserting a jump and add a new fix entry for
1102 it. */
1103 static Mfix *
1104 create_csky_fix_barrier (Mfix *fix, Mfix *fix_next,
1105 HOST_WIDE_INT max_address)
1106 {
1107 rtx_barrier *barrier;
1108 rtx_insn *from = (fix ? fix->insn : get_insns ());
1109 /* The instruction after which we will insert the jump. */
1110 rtx_insn *selected = NULL;
1111 int selected_cost;
1112 /* The address at which the jump instruction will be placed. */
1113 HOST_WIDE_INT selected_address = 0;
1114 Mfix *new_fix;
1115 HOST_WIDE_INT count = (fix ? fix->address : 0);
1116 HOST_WIDE_INT max_count = max_address;
1117 rtx_code_label *label = gen_label_rtx ();
1118
1119 selected_cost = get_csky_barrier_cost (from);
1120
1121 while (from && count < max_count)
1122 {
1123 int new_cost;
1124 rtx_jump_table_data *table;
1125
1126 /* Count the length of this insn. */
1127 count += get_attr_length (from);
1128
1129 /* If there is a jump table, add its length. */
1130 if (tablejump_p (from, NULL, &table))
1131 {
1132 count += get_csky_jump_table_size (table);
1133
1134 /* Jump tables aren't in a basic block, so base the cost on
1135 the dispatch insn. If we select this location, we will
1136 still put the pool after the table. */
1137 new_cost = get_csky_barrier_cost (from);
1138
1139 if (count < max_count
1140 && (!selected || new_cost <= selected_cost))
1141 {
1142 selected = table;
1143 selected_cost = new_cost;
1144 selected_address = count;
1145 }
1146
1147 /* Continue after the dispatch table. */
1148 from = NEXT_INSN (table);
1149 continue;
1150 }
1151
1152 new_cost = get_csky_barrier_cost (from);
1153
1154 if (count < max_count
1155 && (!selected || new_cost <= selected_cost))
1156 {
1157 selected = from;
1158 selected_cost = new_cost;
1159 selected_address = count;
1160 }
1161
1162 from = NEXT_INSN (from);
1163 }
1164
1165 /* Make sure that we found a place to insert the jump. */
1166 gcc_assert (selected);
1167
1168 /* Create a new JUMP_INSN that branches around a barrier. */
1169 from = emit_jump_insn_after (gen_jump (label), selected);
1170 JUMP_LABEL (from) = label;
1171 barrier = emit_barrier_after (from);
1172 emit_label_after (label, barrier);
1173
1174 /* Create a minipool barrier entry for the new barrier. */
1175 new_fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (* new_fix));
1176 new_fix->insn = barrier;
1177 new_fix->address = selected_address;
1178 if (fix)
1179 {
1180 new_fix->next = fix->next;
1181 fix->next = new_fix;
1182 }
1183 else
1184 new_fix->next = fix_next;
1185
1186 return new_fix;
1187 }
1188
1189
1190 /* Print a symbolic form of the constant X to the dump file F.
1191 This is used for dump output for -mconstpool in the target-dependent
1192 reorg pass. */
1193
1194 static void
1195 print_csky_value (FILE *f, rtx x)
1196 {
1197 switch (GET_CODE (x))
1198 {
1199 case CONST_INT:
1200 fprintf (f, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
1201 return;
1202
1203 case CONST_DOUBLE:
1204 fprintf (f, "<0x%lx,0x%lx>", (long)XWINT (x, 2), (long)XWINT (x, 3));
1205 return;
1206
1207 case CONST_VECTOR:
1208 {
1209 int i;
1210
1211 fprintf (f, "<");
1212 for (i = 0; i < CONST_VECTOR_NUNITS (x); i++)
1213 {
1214 fprintf (f, HOST_WIDE_INT_PRINT_HEX,
1215 INTVAL (CONST_VECTOR_ELT (x, i)));
1216 if (i < (CONST_VECTOR_NUNITS (x) - 1))
1217 fputc (',', f);
1218 }
1219 fprintf (f, ">");
1220 }
1221 return;
1222
1223 case CONST_STRING:
1224 fprintf (f, "\"%s\"", XSTR (x, 0));
1225 return;
1226
1227 case SYMBOL_REF:
1228 fprintf (f, "`%s'", XSTR (x, 0));
1229 return;
1230
1231 case LABEL_REF:
1232 fprintf (f, "L%d", INSN_UID (XEXP (x, 0)));
1233 return;
1234
1235 case CONST:
1236 print_csky_value (f, XEXP (x, 0));
1237 return;
1238
1239 case PLUS:
1240 print_csky_value (f, XEXP (x, 0));
1241 fprintf (f, "+");
1242 print_csky_value (f, XEXP (x, 1));
1243 return;
1244
1245 case PC:
1246 fprintf (f, "pc");
1247 return;
1248
1249 default:
1250 fprintf (f, "????");
1251 return;
1252 }
1253 }
1254
1255
1256 /* Record INSN, which will need fixing up to load a value from the
1257 minipool. ADDRESS is the offset of the insn since the start of the
1258 function; LOC is a pointer to the part of the insn which requires
1259 fixing; VALUE is the constant that must be loaded, which is of type
1260 MODE. */
1261
1262 static void
1263 push_csky_minipool_fix (rtx_insn *insn, HOST_WIDE_INT address, rtx *loc,
1264 machine_mode mode, rtx value)
1265 {
1266 #define CSKY_ELRW16_RANGE 1400
1267 #define CSKY_LRW16_RANGE 700
1268 #define CSKY_CONSTANT_POOL_RANGE (TARGET_ELRW ? CSKY_ELRW16_RANGE \
1269 : CSKY_LRW16_RANGE)
1270
1271 /* Fixes less than a word need padding out to a word boundary. */
1272 #define CSKY_MINIPOOL_FIX_SIZE(mode) \
1273 (GET_MODE_SIZE ((mode)) >= 4 ? GET_MODE_SIZE ((mode)) : 4)
1274
1275 Mfix *fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (*fix));
1276
1277 fix->insn = insn;
1278 fix->address = address;
1279 fix->loc = loc;
1280 fix->mode = mode;
1281 fix->fix_size = CSKY_MINIPOOL_FIX_SIZE (mode);
1282 fix->value = value;
1283 fix->forwards = CSKY_CONSTANT_POOL_RANGE;
1284 fix->backwards = 0;
1285 fix->minipool = NULL;
1286
1287 /* If an insn doesn't have a range defined for it, then it isn't
1288 expecting to be reworked by this code. Better to stop now than
1289 to generate duff assembly code. */
1290 gcc_assert (fix->forwards || fix->backwards);
1291
1292 if (dump_file)
1293 {
1294 fprintf (dump_file,
1295 ";; %smode fixup for i%d; addr %lu, range (%ld,%ld): ",
1296 GET_MODE_NAME (mode),
1297 INSN_UID (insn), (unsigned long) address,
1298 -1 * (long)fix->backwards, (long)fix->forwards);
1299 print_csky_value (dump_file, fix->value);
1300 fprintf (dump_file, "\n");
1301 }
1302
1303 /* Add it to the chain of fixes. */
1304 fix->next = NULL;
1305
1306 if (minipool_fix_head != NULL)
1307 minipool_fix_tail->next = fix;
1308 else
1309 minipool_fix_head = fix;
1310
1311 minipool_fix_tail = fix;
1312 }
1313
1314
1315 /* Fill in the offsets for minipool entries. */
1316
1317 static void
1318 assign_csky_minipool_offsets (Mfix *barrier)
1319 {
1320 HOST_WIDE_INT offset = 0;
1321 Mnode *mp;
1322
1323 minipool_barrier = barrier;
1324
1325 for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
1326 {
1327 mp->offset = offset;
1328
1329 if (mp->refcount > 0)
1330 offset += mp->fix_size;
1331 }
1332 }
1333
1334
1335 /* Output the literal table. */
1336
1337 static HOST_WIDE_INT
1338 dump_csky_minipool (rtx_insn *scan)
1339 {
1340 Mnode *mp;
1341 Mnode *nmp;
1342 HOST_WIDE_INT pool_length = 0;
1343
1344 if (dump_file)
1345 fprintf (dump_file,
1346 ";; Emitting minipool after insn %u;\
1347 address %ld; align %d (bytes)\n",
1348 INSN_UID (scan), (unsigned long) minipool_barrier->address, 4);
1349
1350 scan = emit_insn_after (gen_align_4 (), scan);
1351 scan = emit_insn_after (minipool_vector_label, scan);
1352
1353 for (mp = minipool_vector_head; mp != NULL; mp = nmp)
1354 {
1355 if (mp->refcount > 0)
1356 {
1357 if (dump_file)
1358 {
1359 fprintf (dump_file, ";; Offset %u, min %ld, max %ld ",
1360 (unsigned) mp->offset, (unsigned long) mp->min_address,
1361 (unsigned long) mp->max_address);
1362 print_csky_value (dump_file, mp->value);
1363 fputc ('\n', dump_file);
1364 }
1365
1366 switch (mp->fix_size)
1367 {
1368 case 4:
1369 scan = emit_insn_after (gen_consttable_4 (mp->value), scan);
1370 pool_length += 4;
1371 break;
1372 case 8:
1373 scan = emit_insn_after (gen_consttable_8 (mp->value), scan);
1374 pool_length += 8;
1375 break;
1376 default:
1377 gcc_unreachable ();
1378 }
1379 }
1380
1381 nmp = mp->next;
1382 free (mp);
1383 }
1384
1385 minipool_vector_head = minipool_vector_tail = NULL;
1386 scan = emit_barrier_after (scan);
1387
1388 return pool_length;
1389 }
1390
1391 /* Return true if INSN is a minipool load or instruction that will be
1392 converted to one. It is assumed that INSN has type attribute "load". */
1393
1394 bool
1395 csky_minipool_load_p (rtx_insn *insn)
1396 {
1397 rtx op1, addr;
1398
1399 extract_insn_cached (insn);
1400
1401 op1 = recog_data.operand[1];
1402
1403 /* This is a constant that has not yet been turned into
1404 a minipool load. */
1405 if (CONSTANT_P (op1))
1406 return true;
1407
1408 /* Constant pool loads are label_refs. */
1409 if (GET_CODE (op1) == ZERO_EXTEND || GET_CODE (op1) == SIGN_EXTEND)
1410 op1 = XEXP (op1, 0);
1411 if (GET_CODE (op1) != MEM)
1412 return false;
1413 addr = XEXP (op1, 0);
1414 if (GET_CODE (addr) == PLUS && CONST_INT_P (XEXP (addr, 1)))
1415 addr = XEXP (addr, 0);
1416 return GET_CODE (addr) == LABEL_REF;
1417 }
1418
1419
1420 /* Compute the attribute "length" of push or pop insn, according to
1421 the registers it uses. */
1422
1423 int
1424 csky_compute_pushpop_length (rtx *operands)
1425 {
1426 rtx parallel_op = operands[2];
1427 /* Initialize to elements number of PARALLEL. */
1428 unsigned indx = XVECLEN (parallel_op, 0) - 1;
1429 unsigned first_indx = 0;
1430 unsigned regno = REGNO (operands[1]);
1431
1432 if (regno > CSKY_LR_REGNUM)
1433 return 4;
1434
1435 /* Check each register in the list. */
1436 for (; indx > first_indx; indx--)
1437 {
1438 regno = REGNO (XEXP (XVECEXP (parallel_op, 0, indx), 0));
1439 /* If a register number higher than 15 is included, a 32-bit insn
1440 is used. */
1441 if (regno > CSKY_LR_REGNUM)
1442 return 4;
1443 }
1444
1445 return 2;
1446 }
1447
1448 /* Emit constant pools for -mconstpool. */
1449 static void
1450 csky_emit_constant_pools (void)
1451 {
1452 rtx_insn *insn;
1453 HOST_WIDE_INT address = 0;
1454 Mfix *fix;
1455
1456 minipool_fix_head = minipool_fix_tail = NULL;
1457
1458 /* The first insn must always be a note, or the code below won't
1459 scan it properly. */
1460 insn = get_insns ();
1461 gcc_assert (NOTE_P (insn));
1462
1463 /* Scan the insns and record the operands that need fixing. */
1464 for (insn = next_nonnote_insn (insn); insn;
1465 insn = next_nonnote_insn (insn))
1466 {
1467 if (BARRIER_P (insn))
1468 push_csky_minipool_barrier (insn, address);
1469 else if (INSN_P (insn))
1470 {
1471 rtx_jump_table_data *table;
1472
1473 note_csky_invalid_constants (insn, address, true);
1474 address += get_attr_length (insn);
1475
1476 /* If the insn is a vector jump, add the size of the table
1477 and skip the table. */
1478 if (tablejump_p (insn, NULL, &table))
1479 {
1480 address += get_csky_jump_table_size (table);
1481 insn = table;
1482 }
1483 }
1484 }
1485
1486 fix = minipool_fix_head;
1487
1488 /* Now scan the fixups and perform the required changes. */
1489 while (fix)
1490 {
1491 Mfix *ftmp;
1492 Mfix *last_added_fix;
1493 Mfix *last_barrier = NULL;
1494 Mfix *this_fix;
1495 Mnode *mp;
1496 bool has_pending_const = false;
1497
1498 /* Check if there is any pending constant not processed. */
1499 for (mp = minipool_vector_head; mp; mp = mp->next)
1500 if (mp->refcount > 0)
1501 {
1502 has_pending_const = true;
1503 break;
1504 }
1505
1506 /* If no pending constant, skip over barrier insns. */
1507 if (has_pending_const == false)
1508 {
1509 while (fix && BARRIER_P (fix->insn))
1510 fix = fix->next;
1511 if (fix == NULL)
1512 break;
1513 }
1514
1515 last_added_fix = NULL;
1516
1517 for (ftmp = fix; ftmp; ftmp = ftmp->next)
1518 {
1519 if (BARRIER_P (ftmp->insn))
1520 {
1521 if (minipool_vector_head
1522 && ftmp->address >= minipool_vector_head->max_address)
1523 break;
1524
1525 last_barrier = ftmp;
1526 }
1527 else
1528 {
1529 ftmp->minipool = add_csky_minipool_forward_ref (ftmp);
1530 if (ftmp->minipool == NULL)
1531 break;
1532 }
1533 last_added_fix = ftmp; /* Keep track of the last fix added. */
1534 }
1535
1536 /* If the last added fix is a barrier, dump minipool after it. */
1537 if (last_added_fix && BARRIER_P (last_added_fix->insn))
1538 ftmp = last_barrier;
1539 else
1540 {
1541 /* ftmp is first fix that we can't fit into this pool.
1542 Insert a new barrier in the code somewhere between the previous
1543 fix and this one, and arrange to jump around it. */
1544 HOST_WIDE_INT max_address;
1545
1546 /* The last item on the list of fixes must be a barrier, so
1547 we can never run off the end of the list of fixes without
1548 last_barrier being set. */
1549 gcc_assert (ftmp);
1550
1551 /* Check that there isn't another fix that is in range that
1552 we couldn't fit into this pool because the pool was
1553 already too large: we need to put the pool before such an
1554 instruction. The pool itself may come just after the
1555 fix because create_csky_fix_barrier also allows space for a
1556 jump instruction. */
1557 max_address = minipool_vector_head->max_address;
1558 if (ftmp->address < max_address)
1559 max_address = ftmp->address + 1;
1560 last_barrier = create_csky_fix_barrier (last_added_fix, ftmp,
1561 max_address);
1562 }
1563
1564 assign_csky_minipool_offsets (last_barrier);
1565
1566 /* Scan over the fixes we have identified for this pool, fixing them
1567 up and adding the constants to the pool itself. */
1568 for (this_fix = fix; this_fix && ftmp != this_fix;
1569 this_fix = this_fix->next)
1570 {
1571 if (GET_CODE (this_fix->insn) != BARRIER)
1572 {
1573 rtx addr
1574 = plus_constant (Pmode,
1575 gen_rtx_LABEL_REF (VOIDmode,
1576 minipool_vector_label),
1577 this_fix->minipool->offset);
1578 rtx insn_body = PATTERN (this_fix->insn);
1579 rtx src = XEXP (insn_body, 1);
1580 *this_fix->loc = gen_rtx_MEM (this_fix->mode, addr);
1581 if (GET_CODE (this_fix->value) == SYMBOL_REF)
1582 emit_insn_after (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
1583 gen_rtvec (1, src),
1584 VUNSPEC_SYMBOL_REF),
1585 this_fix->insn);
1586 }
1587 }
1588 dump_csky_minipool (last_barrier->insn);
1589 fix = ftmp;
1590 if (fix->next == NULL)
1591 break;
1592 }
1593
1594 /* Free the minipool memory. */
1595 obstack_free (&minipool_obstack, minipool_startobj);
1596 }
1597
1598
1599 /* Implement TARGET_MACHINE_DEPENDENT_REORG. This handles
1600 -mconstpool output. */
1601
1602 static void
1603 csky_reorg (void)
1604 {
1605 if (TARGET_CONSTANT_POOL)
1606 csky_emit_constant_pools ();
1607 }
1608
1609
1610 /* Check to see if the current function contains a branch insn with the
1611 far jump attribute set. Such a function uses the LR register. */
1612
1613 static bool
1614 csky_far_jump_used_p (void)
1615 {
1616 rtx_insn *insn;
1617 if (cfun->machine->far_jump_used)
1618 return true;
1619
1620 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1621 if (GET_CODE (insn) == JUMP_INSN
1622 /* Ignore tablejump patterns. */
1623 && GET_CODE (PATTERN (insn)) != ADDR_VEC
1624 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
1625 && get_attr_far_jump (insn) == FAR_JUMP_YES)
1626 {
1627 cfun->machine->far_jump_used = 1;
1628 return true;
1629 }
1630 return false;
1631 }
1632
1633
1634 /* Return the mask of registers used by the current function. Set
1635 COUNT to the number of registers used. */
1636
1637 static unsigned int
1638 get_csky_live_regs (int *count)
1639 {
1640 int reg;
1641 unsigned int live_regs_mask = 0;
1642
1643 *count = 0;
1644 for (reg = 0; reg < CSKY_NGPR_REGS; reg++)
1645 {
1646 bool save = false;
1647
1648 /* Ignore unsupported registers. */
1649 if (CSKY_TARGET_ARCH (CK801) && reg > 8 && reg < 13)
1650 continue;
1651 if ((CSKY_TARGET_ARCH (CK801)
1652 || CSKY_TARGET_ARCH (CK802)
1653 || CSKY_TARGET_ARCH (CK803))
1654 && reg > 15)
1655 break;
1656
1657 /* Caller-saved registers marked as used. */
1658 if (df_regs_ever_live_p (reg) && !call_really_used_regs[reg])
1659 save = true;
1660
1661 /* Frame pointer marked used. */
1662 else if (frame_pointer_needed && reg == FRAME_POINTER_REGNUM)
1663 save = true;
1664
1665 /* This is required for CK801/802 where FP is a fixed reg, otherwise
1666 we end up with no FP value available to the DWARF-2 unwinder. */
1667 else if (crtl->calls_eh_return && reg == FRAME_POINTER_REGNUM)
1668 save = true;
1669
1670 /* CK801/802 also need special handling for LR because it's clobbered
1671 by far jumps. */
1672 else if ((CSKY_TARGET_ARCH (CK801) || CSKY_TARGET_ARCH (CK802))
1673 && reg == CSKY_LR_REGNUM
1674 && (!crtl->is_leaf || csky_far_jump_used_p ()))
1675 save = true;
1676
1677 /* Register is used for EH data return. */
1678 else if (crtl->calls_eh_return
1679 && reg >= CSKY_FIRST_EH_RETDATA_REGNUM
1680 && reg <= CSKY_LAST_EH_RETDATA_REGNUM)
1681 save = true;
1682
1683 /* We need a temporary reg to hold the offset for adjusting the SP
1684 for a large stack frame. */
1685 if (reg == CSKY_STACKADJUST_REGNUM
1686 && cfun->machine->reg_offset > CSKY_MAX_SP_ADJUST * 2)
1687 save = true;
1688
1689 /* Add reg to the mask. */
1690 if (save)
1691 {
1692 (*count)++;
1693 live_regs_mask |= (1 << reg);
1694 }
1695 }
1696 return live_regs_mask;
1697 }
1698
1699 /* Compute the stack frame layout, storing sizes of the various pieces
1700 in cfun->machine.
1701
1702 Stack frames constructed in the prologue look like:
1703 ... caller's frame ...
1704 incoming SP -> caller's outbound argument overflow
1705 argument spill
1706 optional FP -> register save
1707 local variables
1708 alloca() space
1709 adjusted SP -> outbound argument overflow
1710
1711 with SP/FP pointing at the base (low address) of the respective area,
1712 and each area aligned to a word boundary. */
1713
1714 static void
1715 csky_layout_stack_frame (void)
1716 {
1717 machine_function *infp = cfun->machine;
1718 int reg_count;
1719
1720 if (infp->frame_init_p)
1721 return;
1722
1723 /* Get sizes of local variables & outbound arguments. */
1724 infp->outbound_size = CSKY_STACK_ALIGN (crtl->outgoing_args_size);
1725 infp->local_offset = infp->outbound_size;
1726 infp->local_size = CSKY_STACK_ALIGN (get_frame_size ());
1727 infp->reg_offset = infp->local_offset + infp->local_size;
1728
1729 /* Now compute size of argument spill + saved regs. These do not
1730 need explicit alignment since they are already word-sized. */
1731 infp->reg_mask = get_csky_live_regs (&reg_count);
1732 infp->reg_size = reg_count * UNITS_PER_WORD;
1733 infp->arg_offset = infp->reg_offset + infp->reg_size;
1734 infp->arg_size = crtl->args.pretend_args_size;
1735 infp->frame_size = infp->arg_offset + infp->arg_size;
1736 infp->frame_init_p = reload_completed;
1737 }
1738
1739 /* Implement TARGET_CAN_ELIMINATE. */
1740 static bool
1741 csky_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
1742 {
1743 if (to == STACK_POINTER_REGNUM)
1744 return !frame_pointer_needed;
1745 return true;
1746 }
1747
1748 /* Worker function for INITIAL_ELIMINATION_OFFSET macro.
1749 Define the offset between two registers, one to be eliminated, and
1750 the other its replacement, at the start of a routine. */
1751
1752 HOST_WIDE_INT
1753 csky_initial_elimination_offset (int from, int to)
1754 {
1755 int offset;
1756
1757 csky_layout_stack_frame ();
1758
1759 /* Set OFFSET to the offset to the initial stack pointer. */
1760 switch (from)
1761 {
1762 case FRAME_POINTER_REGNUM:
1763 offset = cfun->machine->reg_offset;
1764 break;
1765
1766 case ARG_POINTER_REGNUM:
1767 offset = cfun->machine->arg_offset;
1768 break;
1769
1770 default:
1771 gcc_unreachable ();
1772 }
1773
1774 /* If we are asked for the offset to the frame pointer instead,
1775 then subtract the difference between the frame pointer and stack
1776 pointer. */
1777 if (to == FRAME_POINTER_REGNUM)
1778 offset -= cfun->machine->reg_offset;
1779 return offset;
1780 }
1781
1782
1783 /* Determine where to put an argument to a function.
1784 Value is zero to push the argument on the stack,
1785 or a hard register in which to store the argument.
1786
1787 MODE is the argument's machine mode.
1788 TYPE is the data type of the argument (as a tree).
1789 This is null for libcalls where that information may
1790 not be available.
1791 CUM is a variable of type CUMULATIVE_ARGS which gives info about
1792 the preceding args and about the function being called.
1793 NAMED is nonzero if this argument is a named parameter
1794 (otherwise it is an extra parameter matching an ellipsis). */
1795 static rtx
1796 csky_function_arg (cumulative_args_t pcum_v, machine_mode mode,
1797 const_tree type ATTRIBUTE_UNUSED,
1798 bool named ATTRIBUTE_UNUSED)
1799 {
1800 CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
1801
1802 if (*pcum < CSKY_NPARM_REGS)
1803 return gen_rtx_REG (mode, CSKY_FIRST_PARM_REGNUM + *pcum);
1804
1805 return NULL_RTX;
1806 }
1807
1808
1809 /* Return the number of registers (words) needed to pass an argument of
1810 MODE and TYPE. */
1811
1812 static int
1813 csky_num_arg_regs (machine_mode mode, const_tree type)
1814 {
1815 int size;
1816
1817 if (type && mode == BLKmode)
1818 size = int_size_in_bytes (type);
1819 else
1820 size = GET_MODE_SIZE (mode);
1821
1822 return CSKY_NUM_WORDS (size);
1823 }
1824
1825
1826 /* Implement TARGET_FUNCTION_ARG_ADVANCE. */
1827
1828 static void
1829 csky_function_arg_advance (cumulative_args_t pcum_v, machine_mode mode,
1830 const_tree type, bool named ATTRIBUTE_UNUSED)
1831 {
1832 CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
1833 int param_size = csky_num_arg_regs (mode, type);
1834
1835 if (*pcum + param_size > CSKY_NPARM_REGS)
1836 *pcum = CSKY_NPARM_REGS;
1837 else
1838 *pcum += param_size;
1839 }
1840
1841
1842 /* Implement TARGET_FUNCTION_VALUE. */
1843 static rtx
1844 csky_function_value (const_tree type, const_tree func,
1845 bool outgoing ATTRIBUTE_UNUSED)
1846 {
1847 machine_mode mode;
1848 int unsignedp ATTRIBUTE_UNUSED;
1849 int size;
1850
1851 mode = TYPE_MODE (type);
1852 size = int_size_in_bytes (type);
1853
1854 /* Since we promote return types, we must promote the mode here too. */
1855 if (INTEGRAL_TYPE_P (type))
1856 {
1857 mode = promote_function_mode (type, mode, &unsignedp, func, 1);
1858 return gen_rtx_REG (mode, CSKY_FIRST_RET_REGNUM);
1859 }
1860
1861 if (mode == BLKmode && size > UNITS_PER_WORD
1862 && size <= UNITS_PER_WORD * 2)
1863 {
1864 rtx ret_regs[2];
1865 ret_regs[0] = gen_rtx_EXPR_LIST (SImode,
1866 gen_rtx_REG (SImode,
1867 CSKY_FIRST_RET_REGNUM),
1868 GEN_INT (0 * UNITS_PER_WORD));
1869 ret_regs[1] = gen_rtx_EXPR_LIST (SImode,
1870 gen_rtx_REG (SImode,
1871 CSKY_FIRST_RET_REGNUM + 1),
1872 GEN_INT (1 * UNITS_PER_WORD));
1873
1874 rtvec vec = gen_rtvec (2, ret_regs[0], ret_regs[1]);
1875
1876 return gen_rtx_PARALLEL (mode, vec);
1877 }
1878
1879 return gen_rtx_REG (mode, CSKY_FIRST_RET_REGNUM);
1880 }
1881
1882
1883 /* Implement TARGET_LIBCALL_VALUE. */
1884 static rtx
1885 csky_libcall_value (machine_mode mode,
1886 const_rtx libcall ATTRIBUTE_UNUSED)
1887 {
1888 return gen_rtx_REG (mode, CSKY_FIRST_RET_REGNUM);
1889 }
1890
1891
1892 /* Implement TARGET_FUNCTION_VALUE_REGNO_P.
1893 On C-SKY, only r0 can return results. */
1894
1895 static bool
1896 csky_function_value_regno_p (const unsigned int regno)
1897 {
1898 return (regno == CSKY_FIRST_RET_REGNUM);
1899 }
1900
1901
1902 /* Return an RTX indicating where the return address to the
1903 calling function can be found. */
1904 rtx
1905 csky_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
1906 {
1907 if (count != 0)
1908 return NULL_RTX;
1909
1910 return get_hard_reg_initial_val (Pmode, CSKY_LR_REGNUM);
1911 }
1912
1913
1914 /* Implement TARGET_ARG_PARTIAL_BYTES.
1915 Return the number of bytes at the beginning of an argument
1916 that must be put in registers. The value must be zero for arguments
1917 that are passed entirely in registers or
1918 that are entirely pushed on the stack. */
1919 static int
1920 csky_arg_partial_bytes (cumulative_args_t pcum_v, machine_mode mode,
1921 tree type, bool named ATTRIBUTE_UNUSED)
1922 {
1923 CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
1924 int param_size = csky_num_arg_regs (mode, type);
1925
1926 if (*pcum < CSKY_NPARM_REGS
1927 && *pcum + param_size > CSKY_NPARM_REGS)
1928 return (CSKY_NPARM_REGS - *pcum) * UNITS_PER_WORD;
1929
1930 return 0;
1931 }
1932
1933
1934 /* Implement TARGET_SETUP_INCOMING_VARARGS.
1935 On C-Sky the copy from the argument registers to the stack is emitted
1936 by the prologue hooks, so here we just have to note how much stack space
1937 to save. */
1938
1939 static void
1940 csky_setup_incoming_varargs (cumulative_args_t pcum_v,
1941 machine_mode mode,
1942 tree type,
1943 int *pretend_size,
1944 int second_time ATTRIBUTE_UNUSED)
1945 {
1946 CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
1947 CUMULATIVE_ARGS local_cum;
1948 cumulative_args_t local_cum_v = pack_cumulative_args (&local_cum);
1949 int regs_to_push;
1950
1951 cfun->machine->uses_anonymous_args = 1;
1952 local_cum = *pcum;
1953 csky_function_arg_advance (local_cum_v, mode, type, true);
1954 regs_to_push = CSKY_NPARM_REGS - local_cum;
1955 if (regs_to_push)
1956 *pretend_size = regs_to_push * UNITS_PER_WORD;
1957 }
1958
1959
1960 /* Implement TARGET_ASM_OUTPUT_MI_THUNK.
1961 Output code to add DELTA to the first argument, and then jump
1962 to FUNCTION. Used for C++ multiple inheritance. */
1963
1964 static void
1965 csky_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
1966 HOST_WIDE_INT delta,
1967 HOST_WIDE_INT vcall_offset,
1968 tree function)
1969 {
1970 const char *thiz = "a0";
1971 const char *reg0 = "t0";
1972 const char *reg1 = "t1";
1973 int maxoff = 4096; /* Constant range for addi/subi. */
1974
1975 final_start_function (emit_barrier (), file, 1);
1976
1977 rtx fnaddr = XEXP (DECL_RTL (function), 0);
1978
1979 if (CSKY_TARGET_ARCH (CK801))
1980 {
1981 /* CK801 can't use t registers and has only 16-bit addi/subi. */
1982 reg0 = "l0";
1983 reg1 = "l1";
1984 maxoff = 256;
1985 if (vcall_offset > maxoff || vcall_offset < -maxoff)
1986 fprintf (file, "\tpush\tl0, l1\n");
1987 else if (delta > maxoff || delta < -maxoff)
1988 fprintf (file, "\tpush\tl0\n");
1989 }
1990
1991 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
1992 thiz = "a1";
1993
1994 /* Add delta to this_rtx. */
1995 if (delta != 0)
1996 {
1997 if (delta > maxoff || delta < -maxoff)
1998 {
1999 fprintf (file, "\tlrw\t%s, %ld\n", reg0, (long)delta);
2000 fprintf (file, "\taddu\t%s, %s, %s\n", thiz, thiz, reg0);
2001 }
2002 else
2003 fprintf (file, "\t%s\t%s, %s, %ld\n",
2004 (delta > 0 ? "addi" : "subi"), thiz, thiz,
2005 (long)(delta > 0 ? delta : -delta));
2006 }
2007
2008 /* If needed, add *(*this_rtx + vcall_offset) to this_rtx. */
2009 if (vcall_offset != 0)
2010 {
2011 fprintf (file, "\tld.w\t%s, (%s, 0)\n", reg0, thiz);
2012
2013 if (vcall_offset > maxoff || vcall_offset < -maxoff)
2014 {
2015 fprintf (file, "\tlrw\t%s, %ld\n", reg1, (long)vcall_offset);
2016 fprintf (file, "\taddu\t%s, %s, %s\n", reg0, reg0, reg1);
2017 }
2018 else
2019 fprintf (file, "\t%s\t%s, %s, %ld\n",
2020 (vcall_offset > 0 ? "addi" : "subi"), reg0, reg0,
2021 (long)(vcall_offset > 0 ? vcall_offset : -vcall_offset));
2022
2023 /* Load the offset and add it to this_rtx */
2024 fprintf (file, "\tld.w\t%s, (%s, 0)\n", reg0, reg0);
2025 fprintf (file, "\taddu\t%s, %s, %s\n", thiz, thiz, reg0);
2026 }
2027
2028 /* We must pop the scratch regs individually instead of using the
2029 "pop" insn, which also does a return. */
2030 if (CSKY_TARGET_ARCH (CK801))
2031 {
2032 if (vcall_offset > maxoff || vcall_offset < -maxoff)
2033 {
2034 fprintf (file, "\tld.w\tl0, (sp, 0)\n");
2035 fprintf (file, "\tld.w\tl1, (sp, 4)\n");
2036 fprintf (file, "\taddi\t sp, sp, 8\n");
2037 }
2038 else if (delta > maxoff || delta < -maxoff)
2039 {
2040 fprintf (file, "\tld.w\tl0, (sp, 0)\n");
2041 fprintf (file, "\taddi\tsp, sp, 4\n");
2042 }
2043 }
2044
2045 fprintf (file, "\tjbr\t");
2046 output_addr_const (file, fnaddr);
2047 fprintf (file, "\n");
2048
2049 final_end_function ();
2050 }
2051
2052
2053 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE.
2054 Conditionally modify five variables fixed_regs, call_used_regs, global_regs,
2055 reg_names, and reg_class_contents, to take into account any dependence of
2056 these register sets on target flags.
2057
2058 CK801 has registers r0-r8 and r13-r15. CK802 and CK803 have registers
2059 r0-r15 (the "low" registers). Other cpus use registers r0-r31 with
2060 -mhigh-registers, otherwise also only r0-r15.
2061
2062 CK801 only has 16-bit instructions, most of which can only reference
2063 r0-r7 (the "mini" registers). So we mark regs outside that range as
2064 fixed. -msmart can be used on other arch variants to force the same
2065 behavior because it results in smaller code size.
2066
2067 TODO: investigate whether it's beneficial to use r8-r13 as a spill
2068 class when TARGET_MINI_REGISTERS instead of making them unusable by
2069 the register allocator. */
2070
2071 static void
2072 csky_conditional_register_usage (void)
2073 {
2074 /* Only use mini registers in smart mode or 801. */
2075 if (TARGET_MINI_REGISTERS)
2076 {
2077 int i;
2078
2079 for (i = (CSKY_LAST_MINI_REGNUM + 1); i < 32; i++)
2080 {
2081 fixed_regs[i] = 1;
2082 call_used_regs[i] = 1;
2083 call_really_used_regs[i] = 1;
2084 }
2085 }
2086 /* For some targets, the high registers are not supported.
2087 CPUs other than ck801/ck802/ck803 use high registers
2088 depending on -mhigh-registers option. */
2089 else if (CSKY_TARGET_ARCH (CK802)
2090 || CSKY_TARGET_ARCH (CK803)
2091 || !TARGET_HIGH_REGISTERS)
2092 {
2093 int i;
2094
2095 for (i = CSKY_FIRST_HIGH_REGNUM; i <= CSKY_LAST_HIGH_REGNUM; i++)
2096 {
2097 fixed_regs[i] = 1;
2098 call_used_regs[i] = 1;
2099 call_really_used_regs[i] = 1;
2100 }
2101 }
2102
2103 /* On CK801/CK802 we must mark lr as a fixed register because it is
2104 used to implement far jumps.
2105 FIXME: perhaps there should be a command-line option controlling
2106 use of lr for far jumps on ck802 when !TARGET_MINI_REGS, when
2107 you really want lr to be available to the register allocator and
2108 you know there are no far jumps in the code. */
2109 if (CSKY_TARGET_ARCH (CK801) || CSKY_TARGET_ARCH (CK802))
2110 {
2111 fixed_regs[CSKY_LR_REGNUM] = 1;
2112 call_used_regs[CSKY_LR_REGNUM] = 1;
2113 call_really_used_regs[CSKY_LR_REGNUM] = 0;
2114 }
2115
2116 /* The hi/lo registers are only supported in dsp mode. */
2117 if (!TARGET_DSP)
2118 {
2119 fixed_regs[CSKY_HI_REGNUM] = 1;
2120 call_used_regs[CSKY_HI_REGNUM] = 1;
2121 call_really_used_regs[CSKY_HI_REGNUM] = 1;
2122
2123 fixed_regs[CSKY_LO_REGNUM] = 1;
2124 call_used_regs[CSKY_LO_REGNUM] = 1;
2125 call_really_used_regs[CSKY_LO_REGNUM] = 1;
2126 }
2127
2128 /* The V_REGS are only supported in hard float mode. */
2129 if (!TARGET_HARD_FLOAT)
2130 {
2131 int regno;
2132
2133 for (regno = CSKY_FIRST_VFP_REGNUM;
2134 regno <= CSKY_LAST_VFP_REGNUM; regno++)
2135 {
2136 fixed_regs[regno] = 1;
2137 call_used_regs[regno] = 1;
2138 call_really_used_regs[regno] = 1;
2139 }
2140 }
2141
2142 /* In pic mode, the gb register is not available for register
2143 allocation. Since gb is not clobbered by function
2144 calls, set its call_really_used_regs to 0. */
2145 if (flag_pic)
2146 {
2147 fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
2148 call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
2149 call_really_used_regs[PIC_OFFSET_TABLE_REGNUM] = 0;
2150 }
2151 }
2152
2153 /* Implement TARGET_HARD_REGNO_NREGS. */
2154 static unsigned int
2155 csky_hard_regno_nregs (unsigned int regno, machine_mode mode)
2156 {
2157 if (regno >= CSKY_FIRST_VFP_REGNUM && !CSKY_TARGET_ARCH (CK803))
2158 return 1;
2159 else
2160 return CSKY_NUM_REGS (mode);
2161 }
2162
2163 /* Implement TARGET_HARD_REGNO_MODE_OK. Return true if REGNO is a
2164 valid register for holding a quantity of type MODE. */
2165
2166 static bool
2167 csky_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
2168 {
2169 int nregs = CSKY_NUM_REGS (mode);
2170
2171 /* We can't handle more than doubleword sizes for any register. */
2172 if (nregs > 2)
2173 return false;
2174
2175 /* For general registers, return true if mode is one word size.
2176 When the size is larger than one word size, there should
2177 be two successive hard registers to put the data. */
2178 if (regno < CSKY_NGPR_REGS)
2179 {
2180 if (nregs < 2)
2181 return true;
2182 else if (TARGET_MINI_REGISTERS)
2183 return (regno < CSKY_LAST_MINI_REGNUM);
2184 else if (CSKY_TARGET_ARCH (CK802)
2185 || CSKY_TARGET_ARCH (CK803)
2186 || !TARGET_HIGH_REGISTERS)
2187 /* Without high register, r15 cannot hold doubleword data. */
2188 return (regno < (CSKY_SP_REGNUM - 1));
2189 else
2190 return (regno < (CSKY_SP_REGNUM - 1)
2191 || (regno >= CSKY_LR_REGNUM
2192 && regno < CSKY_LAST_HIGH_UNFIXED_REGNUM));
2193 }
2194 else if (regno == CSKY_CC_REGNUM)
2195 return (mode == CCmode);
2196 else if (regno == CSKY_HI_REGNUM || regno == CSKY_LO_REGNUM)
2197 {
2198 /* Don't allocate hi,lo register for float data even
2199 if in dsp mode, because it will cause high cost
2200 to reload data from hi,lo register. */
2201 if (!TARGET_DSP || mode == SFmode || mode == DFmode)
2202 return false;
2203 else if (nregs == 2)
2204 return (regno == CSKY_HI_REGNUM);
2205 else
2206 return true;
2207 }
2208 else if (CSKY_VREG_P (regno) && TARGET_HARD_FLOAT)
2209 return true;
2210
2211 return false;
2212 }
2213
2214 /* Implement TARGET_MODES_TIEABLE_P. We can't tie DFmode with other modes
2215 when V_REGs might be in use because those registers mess with the stored
2216 bits. */
2217 static bool
2218 csky_modes_tieable_p (machine_mode mode1, machine_mode mode2)
2219 {
2220 return !(TARGET_HARD_FLOAT
2221 && mode1 != mode2
2222 && (mode1 == DFmode || mode2 == DFmode));
2223 }
2224
2225 /* Implement TARGET_CAN_CHANGE_MODE_CLASS.
2226 V_REG registers can't do subreg as all values are reformatted to
2227 internal precision. */
2228 static bool
2229 csky_can_change_mode_class (machine_mode from,
2230 machine_mode to,
2231 reg_class_t rclass)
2232 {
2233 return (GET_MODE_SIZE (from) == GET_MODE_SIZE (to)
2234 || !reg_classes_intersect_p (V_REGS, rclass));
2235 }
2236
2237 /* Implement TARGET_CLASS_LIKELY_SPILLED_P.
2238 We need to define this for MINI_REGS when we only use r0 - r7.
2239 Otherwise we can end up using r0-r4 for function arguments, and don't
2240 have enough left over to do doubleword arithmetic. */
2241
2242 static bool
2243 csky_class_likely_spilled_p (reg_class_t rclass)
2244 {
2245 if ((TARGET_MINI_REGISTERS && rclass == MINI_REGS)
2246 || rclass == C_REGS)
2247 return true;
2248
2249 return false;
2250 }
2251
2252
2253 /* Implement TARGET_PREFERRED_RELOAD_CLASS.
2254 Given an rtx X being reloaded into a reg required to be
2255 in class CLASS, return the class of reg to actually use.
2256 In general this is just CLASS. */
2257
2258 static reg_class_t
2259 csky_preferred_reload_class (rtx x, reg_class_t rclass)
2260 {
2261 if (TARGET_HARD_FLOAT
2262 && CONST_DOUBLE_P (x)
2263 && (GET_MODE (x) == DFmode || GET_MODE (x) == SFmode)
2264 && rclass == NO_REGS)
2265 return GENERAL_REGS;
2266 return rclass;
2267 }
2268
2269
2270 /* Implement TARGET_CLASS_MAX_NREGS.
2271 Return the maximum number of consecutive registers of class rclass needed
2272 to hold a value of mode mode.
2273 On the csky, this is the size of MODE in words,
2274 except in the FP regs, where a single reg is always enough. */
2275
2276 static unsigned char
2277 csky_class_max_nregs (reg_class_t rclass, machine_mode mode)
2278 {
2279 if (rclass == V_REGS)
2280 return 1;
2281 else
2282 return CSKY_NUM_REGS (mode);
2283 }
2284
2285
2286 /* Implement TARGET_SECONDARY_RELOAD.
2287 If copying a register of RCLASS from/to X requires an intermediate
2288 register, the hook should return the REGISTER_CLASS required for this
2289 intermediate register.
2290 If no intermediate register is required, it should return NO_REGS.
2291 If more than one intermediate register is required, describe the one
2292 that is closest in the copy chain to the reload register. */
2293
2294 reg_class_t
2295 csky_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x,
2296 reg_class_t rclass,
2297 machine_mode mode,
2298 secondary_reload_info *sri ATTRIBUTE_UNUSED)
2299 {
2300 int regno = -1;
2301
2302 /* Extract the real regno from X. */
2303 if (GET_CODE (x) == SIGN_EXTEND)
2304 {
2305 int off = 0;
2306
2307 x = XEXP (x, 0);
2308
2309 if (reg_renumber)
2310 regno = true_regnum (x);
2311 else
2312 {
2313 while (GET_CODE (x) == SUBREG)
2314 {
2315 off += subreg_regno_offset (REGNO (SUBREG_REG (x)),
2316 GET_MODE (SUBREG_REG (x)),
2317 SUBREG_BYTE (x), GET_MODE (x));
2318 x = SUBREG_REG (x);
2319 }
2320
2321 if (GET_CODE (x) == REG)
2322 regno = REGNO (x) + off;
2323 }
2324 }
2325 else if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
2326 regno = true_regnum (x);
2327
2328 /* We always require a general register when copying anything to
2329 HI/LO_REGNUM, except when copying an SImode value from HI/LO_REGNUM
2330 to a general register, or when copying from register 0. */
2331 if ((rclass == HILO_REGS || rclass == LO_REGS || rclass == HI_REGS)
2332 && !CSKY_GENERAL_REGNO_P (regno))
2333 return GENERAL_REGS;
2334
2335 if (rclass == V_REGS && !CSKY_GENERAL_REGNO_P (regno))
2336 {
2337 /* Reload between vector reg and memory does not need an
2338 intermediate register. */
2339 if (MEM_P (x) && (mode == SFmode || mode == DFmode))
2340 return NO_REGS;
2341 else
2342 return GENERAL_REGS;
2343 }
2344
2345 return NO_REGS;
2346 }
2347
2348 /* Implement TARGET_SPILL_CLASS.
2349 Try spilling to a larger register class before spilling to memory. */
2350
2351 static reg_class_t
2352 csky_spill_class (reg_class_t rclass, machine_mode mode ATTRIBUTE_UNUSED)
2353 {
2354 if ((rclass == MINI_REGS && !TARGET_MINI_REGISTERS)
2355 || (rclass == LOW_REGS && TARGET_HIGH_REGISTERS))
2356 return GENERAL_REGS;
2357 return NO_REGS;
2358 }
2359
2360 /* Convert a static initializer array of feature bits to sbitmap
2361 representation. */
2362 static void
2363 csky_initialize_isa (sbitmap isa, const enum csky_isa_feature *isa_bits)
2364 {
2365 bitmap_clear (isa);
2366 while (*isa_bits != CSKY_ISA_FEATURE_GET (none))
2367 bitmap_set_bit (isa, *(isa_bits++));
2368 }
2369
2370
2371 /* Configure a build target TARGET from the user-specified options OPTS and
2372 OPTS_SET. */
2373 static void
2374 csky_configure_build_target (struct csky_build_target *target,
2375 struct cl_target_option *opts,
2376 struct gcc_options *opts_set)
2377 {
2378 const struct csky_processors *csky_selected_tune = NULL;
2379 struct csky_processors *csky_selected_cpu = NULL;
2380 struct csky_processors *csky_selected_arch = NULL;
2381 sbitmap all_sbits = sbitmap_alloc (CSKY_ISA_FEATURE_GET (max));
2382 bitmap_clear (all_sbits);
2383
2384 bitmap_clear (target->isa);
2385 target->core_name = NULL;
2386 target->arch_name = NULL;
2387
2388 if (opts_set->x_csky_arch_option)
2389 csky_selected_arch = &all_architectures[opts->x_csky_arch_option];
2390
2391 if (opts_set->x_csky_cpu_option)
2392 {
2393 csky_selected_cpu = &all_cores[opts->x_csky_cpu_option];
2394 csky_selected_tune = &all_cores[opts->x_csky_cpu_option];
2395 }
2396
2397 if (csky_selected_cpu)
2398 {
2399 /* TODO: support combination of features
2400 between different cpu & arch, should based on arch. */
2401 if (csky_selected_arch
2402 && (csky_selected_cpu->base_arch != csky_selected_arch->base_arch))
2403 warning (0, "cpu %s is not based on arch %s, ignoring the arch",
2404 csky_selected_cpu->name, csky_selected_arch->name);
2405 if (!csky_selected_arch)
2406 csky_selected_arch = &all_architectures[csky_selected_cpu->base_arch];
2407 csky_initialize_isa (all_sbits, csky_selected_arch->isa_bits);
2408 target->core_name = csky_selected_cpu->name;
2409 }
2410 else if (csky_selected_arch)
2411 {
2412 csky_selected_cpu = csky_selected_arch;
2413 target->arch_name = csky_selected_arch->name;
2414 }
2415 else /* If the user did not specify a processor, choose one for them. */
2416 {
2417 csky_selected_cpu = &all_cores[TARGET_CPU_DEFAULT];
2418 csky_selected_arch = &all_architectures[csky_selected_cpu->base_arch];
2419 csky_initialize_isa (all_sbits, csky_selected_arch->isa_bits);
2420 target->core_name = csky_selected_cpu->name;
2421 }
2422
2423 /* The selected cpu may be an architecture, so lookup tuning by core ID. */
2424 if (!csky_selected_tune)
2425 csky_selected_tune = &all_cores[csky_selected_cpu->core];
2426 gcc_assert (csky_selected_tune);
2427
2428 gcc_assert (csky_selected_arch);
2429 gcc_assert (csky_selected_cpu);
2430 csky_initialize_isa (target->isa, csky_selected_cpu->isa_bits);
2431 bitmap_ior (target->isa, target->isa, all_sbits);
2432
2433 /* Finish initializing the target structure. */
2434 target->arch_pp_name = csky_selected_cpu->arch;
2435 target->base_arch = csky_selected_cpu->base_arch;
2436 target->arch_core = csky_selected_cpu->core;
2437
2438 sbitmap_free (all_sbits);
2439 }
2440
2441
2442 /* Implement TARGET_OPTION_OVERRIDE. */
2443
2444 static void
2445 csky_option_override (void)
2446 {
2447 csky_active_target.isa = sbitmap_alloc (CSKY_ISA_FEATURE_GET (max));
2448
2449 /* Create the default target_options structure. We need this early
2450 to configure the overall build target. */
2451 target_option_default_node = target_option_current_node
2452 = build_target_option_node (&global_options);
2453
2454 csky_configure_build_target (&csky_active_target,
2455 TREE_TARGET_OPTION (target_option_default_node),
2456 &global_options_set);
2457
2458 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2459 SUBTARGET_OVERRIDE_OPTIONS;
2460 #endif
2461
2462 csky_base_arch = csky_active_target.base_arch;
2463
2464 if (flag_pic && !(CSKY_TARGET_ARCH (CK810) || CSKY_TARGET_ARCH (CK807)))
2465 {
2466 flag_pic = 0;
2467 warning (0, "%qs is not supported by arch %s",
2468 "-fPIC", csky_active_target.arch_pp_name);
2469 }
2470
2471 /* Check floating-point options for consistency. */
2472 if (TARGET_HARD_FLOAT)
2473 {
2474 const struct csky_fpu_desc *csky_selected_fpu = NULL;
2475
2476 if (csky_fpu_index == TARGET_FPU_auto)
2477 {
2478 const char *target_fpu_name;
2479 bool ok;
2480 int fpu_index;
2481
2482 #ifdef CSKY_FPUTYPE_DEFAULT
2483 target_fpu_name = CSKY_FPUTYPE_DEFAULT;
2484 #else
2485 target_fpu_name = "fpv2";
2486 #endif
2487
2488 if (csky_active_target.core_name != NULL
2489 && !strchr (csky_active_target.core_name, 'f'))
2490 target_fpu_name = "auto";
2491 else if (CSKY_TARGET_ARCH (CK803) || !TARGET_DOUBLE_FLOAT)
2492 target_fpu_name = "fpv2_sf";
2493 else if (TARGET_DOUBLE_FLOAT && TARGET_FDIVDU)
2494 target_fpu_name = "fpv2_divd";
2495
2496 ok = opt_enum_arg_to_value (OPT_mfpu_, target_fpu_name, &fpu_index,
2497 CL_TARGET);
2498 gcc_assert (ok);
2499 csky_fpu_index = (enum csky_fpu_type) fpu_index;
2500 }
2501
2502 if (CSKY_TARGET_ARCH (CK801) || CSKY_TARGET_ARCH (CK802))
2503 error ("%qs is not supported by arch %s",
2504 "-mhard-float", csky_active_target.arch_pp_name);
2505 else if (csky_fpu_index == TARGET_FPU_auto)
2506 error ("%<-mhard-float%> is not supported by the selected CPU");
2507 else
2508 {
2509 csky_selected_fpu = &all_fpus[csky_fpu_index];
2510 sbitmap fpu_bits = sbitmap_alloc (CSKY_ISA_FEATURE_GET (max));
2511 csky_initialize_isa (fpu_bits, csky_selected_fpu->isa_bits);
2512
2513 bitmap_ior (csky_active_target.isa, csky_active_target.isa,
2514 fpu_bits);
2515
2516 sbitmap_free (fpu_bits);
2517 }
2518 }
2519 else
2520 {
2521 if (TARGET_DOUBLE_FLOAT > 0)
2522 warning (0, "%<-mdouble-float%> ignored without %<-mhard-float%>");
2523 TARGET_DOUBLE_FLOAT = 0;
2524 if (TARGET_FDIVDU > 0)
2525 warning (0, "%<-mfdivdu%> ignored without %<-mhard-float%>");
2526 TARGET_FDIVDU = 0;
2527 }
2528
2529 /* Extended LRW instructions are enabled by default on CK801, disabled
2530 otherwise. */
2531 if (TARGET_ELRW == -1)
2532 TARGET_ELRW = CSKY_TARGET_ARCH (CK801);
2533
2534 /* DSP is enabled either by the processor feature or -mdsp
2535 command-line option. There is no -mno-dsp option as the assembler
2536 doesn't take one. */
2537 if (!TARGET_DSP)
2538 TARGET_DSP = CSKY_ISA_FEATURE (dsp);
2539
2540 /* There's both -mdiv and -mno-div. Take default from processor if
2541 neither is specified explicitly. */
2542 if (TARGET_DIV == -1)
2543 TARGET_DIV = CSKY_ISA_FEATURE (div);
2544
2545 /* TARGET_CONSTANT_POOL is mandatory for CK801 and CK802 and optional
2546 for other CPUs.
2547 The reason why the compiler has to generate constant pools for CK801/2
2548 instead of deferring to the assembler is that these cores don't have a
2549 long branch instruction other than jbsr, which clobbers lr. So for
2550 the compiler to correctly save/restore lr it has to know whether there
2551 are long branches, which depends on having accurate branch length
2552 counts, which in turn depends on having control over where constant
2553 pools are placed. */
2554 if ((CSKY_TARGET_ARCH (CK801) || CSKY_TARGET_ARCH (CK802))
2555 && !TARGET_CONSTANT_POOL)
2556 error ("%qs is not supported by arch %s",
2557 "-mno-constpool", csky_active_target.arch_pp_name);
2558 else if (TARGET_CONSTANT_POOL == -1)
2559 TARGET_CONSTANT_POOL = (CSKY_TARGET_ARCH (CK801)
2560 || CSKY_TARGET_ARCH (CK802));
2561
2562 /* TARGET_MINI_REGISTERS is mandatory for CK801, the default for CK802,
2563 and optional for other CPUs. TARGET_HIGH_REGISTERS is incompatible
2564 with TARGET_MINI_REGISTERS, is not supported by CK801/802/803,
2565 and is the default for other processors.
2566 See csky_conditional_register_usage. */
2567 if (TARGET_MINI_REGISTERS > 0 && TARGET_HIGH_REGISTERS > 0)
2568 error ("%<-msmart%> is incompatible with %<-mhigh-registers%>");
2569 else if (CSKY_TARGET_ARCH (CK801)
2570 || CSKY_TARGET_ARCH (CK802)
2571 || CSKY_TARGET_ARCH (CK803))
2572 {
2573 if (CSKY_TARGET_ARCH (CK801)
2574 || (CSKY_TARGET_ARCH (CK802) && TARGET_MINI_REGISTERS == -1))
2575 TARGET_MINI_REGISTERS = 1;
2576 else if (TARGET_MINI_REGISTERS == -1)
2577 TARGET_MINI_REGISTERS = 0;
2578 if (TARGET_HIGH_REGISTERS > 0)
2579 warning (0, "%qs is not supported by arch %s",
2580 "-mhigh-registers", csky_active_target.arch_pp_name);
2581 TARGET_HIGH_REGISTERS = 0;
2582 }
2583 else
2584 {
2585 if (TARGET_MINI_REGISTERS == -1)
2586 TARGET_MINI_REGISTERS = 0;
2587 if (TARGET_HIGH_REGISTERS == -1)
2588 TARGET_HIGH_REGISTERS = !TARGET_MINI_REGISTERS;
2589 }
2590
2591 /* -mmultiple-stld is the default for everything but CK801, which
2592 doesn't support it. */
2593 if (CSKY_TARGET_ARCH (CK801))
2594 {
2595 if (TARGET_MULTIPLE_STLD > 0)
2596 warning (0, "%qs is not supported by arch %s",
2597 "-mmultiple-stld", csky_active_target.arch_pp_name);
2598 TARGET_MULTIPLE_STLD = 0;
2599 }
2600
2601 /* Initialize boolean versions of the architectural flags, for use
2602 in the .md file. */
2603
2604 #undef CSKY_ISA
2605 #define CSKY_ISA(IDENT, DESC) \
2606 { \
2607 csky_arch_isa_features[CSKY_ISA_FEATURE_GET (IDENT)] = \
2608 bitmap_bit_p (csky_active_target.isa, CSKY_ISA_FEATURE_GET (IDENT)); \
2609 }
2610 #include "csky_isa.def"
2611 #undef CSKY_ISA
2612
2613 /* TODO */
2614
2615 /* Resynchronize the saved target options. */
2616 cl_target_option_save (TREE_TARGET_OPTION (target_option_default_node),
2617 &global_options);
2618
2619 #ifdef ENABLE_TPF_DEBUG
2620 /* Don't emit DWARF4 unless specifically selected. The TPF
2621 debuggers do not yet support DWARF 3/4. */
2622 if (!global_options_set.x_dwarf_strict)
2623 dwarf_strict = 1;
2624 if (!global_options_set.x_dwarf_version)
2625 dwarf_version = 3;
2626 #endif
2627
2628 /* Don't run the scheduler before reload by default,
2629 since it tends to increase register pressure. */
2630 if (!global_options_set.x_flag_schedule_insns)
2631 flag_schedule_insns = 0;
2632
2633 csky_add_gc_roots ();
2634 }
2635
2636
2637 /* Return TRUE if X contains any references to TLS symbols. */
2638
2639 bool
2640 csky_tls_referenced_p (rtx x)
2641 {
2642 if (!TARGET_TLS)
2643 return false;
2644
2645 subrtx_iterator::array_type array;
2646 FOR_EACH_SUBRTX (iter, array, x, ALL)
2647 {
2648 const_rtx x = *iter;
2649 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x) != 0)
2650 return true;
2651
2652 /* Don't recurse into UNSPEC_TLS looking for TLS symbols; these are
2653 TLS offsets, not real symbol references. */
2654 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLS)
2655 iter.skip_subrtxes ();
2656 }
2657 return false;
2658 }
2659
2660
2661 /* Implement TARGET_CANNOT_FORCE_CONST_MEM.
2662 Determine if it's legal to put X into the constant pool. This
2663 is not possible for the address of thread-local symbols, which
2664 is checked above. */
2665
2666 static bool
2667 csky_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED,
2668 rtx x)
2669 {
2670 return csky_tls_referenced_p (x);
2671 }
2672
2673
2674 /* Implement TARGET_LEGITIMATE_CONSTANT_P. Returns nonzero if the
2675 constant value X is a legitimate general operand.
2676 It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
2677
2678 static bool
2679 csky_legitimate_constant_p (machine_mode mode, rtx x)
2680 {
2681 return (!csky_cannot_force_const_mem (mode, x)
2682 && CONSTANT_P (x));
2683 }
2684
2685
2686 /* Return true if X is valid as an CSKY addressing register. */
2687
2688 static bool
2689 is_csky_address_register_rtx_p (rtx x, int strict_p)
2690 {
2691 int regno;
2692
2693 if (!x)
2694 return false;
2695 if (!REG_P (x))
2696 return false;
2697
2698 regno = REGNO (x);
2699
2700 if (strict_p)
2701 return (CSKY_GENERAL_REGNO_P (regno)
2702 || CSKY_GENERAL_REGNO_P (reg_renumber[regno]));
2703 else
2704 return CSKY_GENERAL_REGNO_P (regno) || regno >= FIRST_PSEUDO_REGISTER;
2705 }
2706
2707
2708 /* Return TRUE if X is a thread-local symbol. */
2709
2710 static bool
2711 csky_tls_symbol_p (rtx x)
2712 {
2713 if (!TARGET_TLS)
2714 return false;
2715
2716 if (GET_CODE (x) != SYMBOL_REF)
2717 return false;
2718
2719 return SYMBOL_REF_TLS_MODEL (x) != 0;
2720 }
2721
2722
2723 /* Handle lazy initialization of __tls_get_addr libfunc. */
2724 static GTY(()) rtx tls_get_addr_libfunc;
2725
2726 static rtx
2727 get_tls_get_addr (void)
2728 {
2729 if (!tls_get_addr_libfunc)
2730 tls_get_addr_libfunc = init_one_libfunc ("__tls_get_addr");
2731 return tls_get_addr_libfunc;
2732 }
2733
2734
2735 /* Emit a call to __tls_get_addr. */
2736
2737 static rtx_insn *
2738 csky_call_tls_get_addr (rtx x, rtx reg, rtx *valuep, int reloc)
2739 {
2740 rtx label, labelno, unspec, tmp;
2741 rtx_insn *insns;
2742
2743 start_sequence ();
2744
2745 labelno = GEN_INT (tls_labelno++);
2746 label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_TLS_LABEL);
2747 unspec = gen_rtx_UNSPEC (Pmode,
2748 gen_rtvec (3, x, GEN_INT (reloc), label),
2749 UNSPEC_TLS);
2750 tmp = gen_reg_rtx (SImode);
2751 emit_move_insn (reg, unspec);
2752 emit_move_insn (tmp, label);
2753 emit_insn (gen_addsi3 (reg, reg, tmp));
2754 *valuep = emit_library_call_value (get_tls_get_addr (),
2755 NULL_RTX, LCT_PURE, /* LCT_CONST? */
2756 Pmode, reg, Pmode);
2757 insns = get_insns ();
2758 end_sequence ();
2759 return insns;
2760 }
2761
2762 /* Helper function for csky_legitimize_address, to handle the TLS cases.
2763 REG is a scratch register and may be null. */
2764
2765 rtx
2766 csky_legitimize_tls_address (rtx x, rtx reg)
2767 {
2768 rtx dest, tp, label, labelno, unspec, ret, eqv, addend, tmp;
2769 rtx_insn *insns;
2770 unsigned int model = SYMBOL_REF_TLS_MODEL (x);
2771
2772 if (!reg)
2773 reg = gen_reg_rtx (SImode);
2774
2775 switch (model)
2776 {
2777 case TLS_MODEL_GLOBAL_DYNAMIC:
2778 insns = csky_call_tls_get_addr (x, reg, &ret, TLS_GD32);
2779 dest = gen_reg_rtx (Pmode);
2780 emit_libcall_block (insns, dest, ret, x);
2781 return dest;
2782
2783 case TLS_MODEL_LOCAL_DYNAMIC:
2784 insns = csky_call_tls_get_addr (x, reg, &ret, TLS_LDM32);
2785
2786 /* Attach a unique REG_EQUIV, to allow the RTL optimizers to
2787 share the LDM result with other LD model accesses. */
2788 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const1_rtx), UNSPEC_TLS);
2789 dest = gen_reg_rtx (Pmode);
2790 emit_libcall_block (insns, dest, ret, eqv);
2791
2792 /* Load the addend. */
2793 addend = gen_rtx_UNSPEC (Pmode,
2794 gen_rtvec (2, x, GEN_INT (TLS_LDO32)),
2795 UNSPEC_TLS);
2796 addend = force_reg (SImode, addend);
2797 return gen_rtx_PLUS (Pmode, dest, addend);
2798
2799 case TLS_MODEL_INITIAL_EXEC:
2800 labelno = GEN_INT (tls_labelno++);
2801 label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_TLS_LABEL);
2802 unspec = gen_rtx_UNSPEC (Pmode,
2803 gen_rtvec (3, x, GEN_INT (TLS_IE32), label),
2804 UNSPEC_TLS);
2805 tmp = gen_reg_rtx (SImode);
2806 emit_move_insn (reg, unspec);
2807 emit_move_insn (tmp, label);
2808 emit_insn (gen_addsi3 (reg, reg, tmp));
2809 emit_move_insn (reg, gen_const_mem (Pmode, reg));
2810 tp = gen_rtx_REG (SImode, CSKY_TLS_REGNUM);
2811 return gen_rtx_PLUS (Pmode, tp, reg);
2812
2813 case TLS_MODEL_LOCAL_EXEC:
2814 unspec = gen_rtx_UNSPEC (Pmode,
2815 gen_rtvec (2, x, GEN_INT (TLS_LE32)),
2816 UNSPEC_TLS);
2817 emit_move_insn (reg, unspec);
2818 tp = gen_rtx_REG (SImode, CSKY_TLS_REGNUM);
2819 return gen_rtx_PLUS (Pmode, tp, reg);
2820
2821 default:
2822 abort ();
2823 }
2824 }
2825
2826
2827 /* Implement TARGET_LEGITIMIZE_ADDRESS. */
2828
2829 static rtx
2830 csky_legitimize_address (rtx x, rtx orig_x ATTRIBUTE_UNUSED,
2831 machine_mode mode)
2832 {
2833 if (csky_tls_symbol_p (x))
2834 return csky_legitimize_tls_address (x, NULL_RTX);
2835
2836 if (GET_CODE (x) == PLUS)
2837 {
2838 rtx xop0 = XEXP (x, 0);
2839 rtx xop1 = XEXP (x, 1);
2840
2841 if (is_csky_address_register_rtx_p (xop0, 0)
2842 && CONST_INT_P (xop1))
2843 {
2844 HOST_WIDE_INT offset = INTVAL (xop1);
2845
2846 /* Try to replace ld32 rx,(ry, offset), to addi16 rz, oimm8
2847 and ld16 rx,(rz, new_ld_offset) to avoid emitting a
2848 32-bit ld, but this addi has a range limitation. */
2849 if (optimize_size
2850 && offset > CSKY_LD16_MAX_OFFSET (mode)
2851 && offset <= (CSKY_ADDI16_MAX_IMM
2852 + CSKY_LD16_MAX_OFFSET (mode)))
2853 {
2854 HOST_WIDE_INT new_ld_offset
2855 = offset & CSKY_LD16_OFFSET_MASK (mode);
2856
2857 xop0 = force_operand (plus_constant (Pmode, xop0,
2858 offset - new_ld_offset),
2859 NULL_RTX);
2860 x = plus_constant (Pmode, xop0, new_ld_offset);
2861 }
2862 else if (offset < 0 && offset >= (-CSKY_SUBI16_MAX_IMM))
2863 x = force_operand (x, NULL_RTX);
2864 else if (offset > CSKY_LD16_MAX_OFFSET (mode)
2865 || offset < 0)
2866 {
2867 /* For the remaining cases, force the constant into a
2868 register. */
2869 xop1 = force_reg (SImode, xop1);
2870 x = gen_rtx_PLUS (SImode, xop0, xop1);
2871 }
2872 }
2873
2874 /* If the index is store in register, force the
2875 base to register. */
2876 if (is_csky_address_register_rtx_p (xop1, 0)
2877 && !is_csky_address_register_rtx_p (xop0, 0))
2878 {
2879 xop0 = force_operand (xop0, NULL_RTX);
2880 x = gen_rtx_PLUS (SImode, xop0, xop1);
2881 }
2882 }
2883 /* Make sure to take full advantage of the pre-indexed addressing mode
2884 with absolute addresses which often allows for the base register to
2885 be factorized for multiple adjacent memory references, and it might
2886 even allows for the mini pool to be avoided entirely. */
2887 else if (CONST_INT_P (x) && optimize > 0)
2888 {
2889 HOST_WIDE_INT mask, base, index;
2890 rtx base_reg;
2891
2892 mask = CSKY_LD16_OFFSET_MASK (mode);
2893 base = INTVAL (x) & ~mask;
2894 index = INTVAL (x) & mask;
2895 base_reg = force_reg (SImode, GEN_INT (base));
2896 x = plus_constant (Pmode, base_reg, index);
2897 }
2898
2899 return x;
2900 }
2901
2902
2903 /* Return nonzero if INDEX is valid for an address index operand.
2904 ck801 use 16 bits ld
2905 ck802 use 16 and 32 bits ld
2906 others use ld and ldr. */
2907
2908 static int
2909 ck801_legitimate_index_p (machine_mode mode, rtx index,
2910 int strict_p ATTRIBUTE_UNUSED)
2911 {
2912 enum rtx_code code = GET_CODE (index);
2913
2914 /* When the mode size is larger than 4, we may use two ld instruction
2915 to get data, the index and (index+1) should be valid. */
2916 if (GET_MODE_SIZE (mode) >= 8)
2917 return (code == CONST_INT
2918 && INTVAL (index) < CSKY_LD16_MAX_OFFSET (SImode)
2919 && INTVAL (index) >= 0 && (INTVAL (index) & 3) == 0);
2920
2921 if (code == CONST_INT && GET_MODE_SIZE (mode) > 0
2922 && INTVAL (index) <= CSKY_LD16_MAX_OFFSET (mode)
2923 && INTVAL (index) >= 0)
2924 return ((INTVAL (index) % GET_MODE_SIZE (mode)) == 0);
2925
2926 return 0;
2927 }
2928
2929
2930 static int
2931 ck802_legitimate_index_p (machine_mode mode, rtx index,
2932 int strict_p ATTRIBUTE_UNUSED)
2933 {
2934 enum rtx_code code = GET_CODE (index);
2935
2936 /* When the mode size is larger than 4, we may use two ld instruction
2937 to get data, the index and (index+1) should be valid. */
2938 if (GET_MODE_SIZE (mode) >= 8)
2939 return (code == CONST_INT
2940 && INTVAL (index) < CSKY_LD32_MAX_OFFSET (SImode)
2941 && INTVAL (index) >= 0 && (INTVAL (index) & 3) == 0);
2942
2943 if (code == CONST_INT && GET_MODE_SIZE (mode) > 0
2944 && INTVAL (index) <= CSKY_LD32_MAX_OFFSET (mode)
2945 && INTVAL (index) >= 0)
2946 return ((INTVAL (index) % GET_MODE_SIZE (mode)) == 0);
2947
2948 return 0;
2949 }
2950
2951
2952 /* The instruction ldr rz, (rx, ry << i), i can be 0,1,2,3.
2953 Check that SHIFT is valid, that the code is MULT, and that
2954 the shift is a power of 2. */
2955
2956 static bool
2957 is_ldr_shift_p (HOST_WIDE_INT shift, enum rtx_code code)
2958 {
2959 if (code == ASHIFT)
2960 return (shift >= 0 && shift <= 3);
2961 else if (code == MULT)
2962 return (shift == 1
2963 || shift == 2
2964 || shift == 4
2965 || shift == 8);
2966 else
2967 return false;
2968 }
2969
2970
2971 static int
2972 ck810_legitimate_index_p (machine_mode mode, rtx index, int strict_p)
2973 {
2974 enum rtx_code code = GET_CODE (index);
2975
2976 if (TARGET_HARD_FLOAT
2977 && (mode == SFmode || mode == DFmode))
2978 return (code == CONST_INT && INTVAL (index) < 1024
2979 && INTVAL (index) >= 0
2980 && (INTVAL (index) & 3) == 0);
2981
2982 if (code == CONST_INT)
2983 {
2984 /* When the mode size is larger than 4, we may use two ld instruction
2985 to get data, the index and (index+1) should be valid. */
2986 if (GET_MODE_SIZE (mode) >= 8)
2987 return (INTVAL (index) < CSKY_LD32_MAX_OFFSET (SImode)
2988 && INTVAL (index) >= 0 && (INTVAL (index) & 3) == 0);
2989
2990 if (GET_MODE_SIZE (mode) > 0
2991 && INTVAL (index) <= CSKY_LD32_MAX_OFFSET (mode)
2992 && INTVAL (index) >= 0)
2993 return ((INTVAL (index) % GET_MODE_SIZE (mode)) == 0);
2994 }
2995 /* Allow ld.w rx, (gb, sym@got) when -fpic specially. */
2996 else if (code == UNSPEC)
2997 return (flag_pic == 1
2998 && (XINT (index, 1) == UNSPEC_PIC_SYMBOL_PLT
2999 || XINT (index, 1) == UNSPEC_PIC_SYMBOL_GOT));
3000 /* The follow index is for ldr instruction, the ldr cannot
3001 load dword data, so the mode size should not be larger than
3002 4. */
3003 else if (GET_MODE_SIZE (mode) <= 4)
3004 {
3005 if (is_csky_address_register_rtx_p (index, strict_p))
3006 return 1;
3007 else if (code == MULT || code == ASHIFT)
3008 {
3009 rtx xiop0 = XEXP (index, 0);
3010 rtx xiop1 = XEXP (index, 1);
3011
3012 /* FIXME can the xiop1 be the reg and xiop0 be the int when mult? */
3013 return (is_csky_address_register_rtx_p (xiop0, strict_p)
3014 && CONST_INT_P (xiop1)
3015 && is_ldr_shift_p (INTVAL (xiop1), code));
3016 }
3017 }
3018
3019 return 0;
3020 }
3021
3022
3023 static int
3024 csky_legitimate_index_p (machine_mode mode, rtx index, int strict_p)
3025 {
3026 if (CSKY_TARGET_ARCH (CK801))
3027 return ck801_legitimate_index_p (mode, index, strict_p);
3028 else if (CSKY_TARGET_ARCH (CK802))
3029 return ck802_legitimate_index_p (mode, index, strict_p);
3030 else
3031 return ck810_legitimate_index_p (mode, index, strict_p);
3032 }
3033
3034
3035 /* Implement TARGET_LEGITIMATE_ADDRESS_P.
3036 Recognizes RTL expressions that are valid memory addresses for an
3037 instruction. The MODE argument is the machine mode for the MEM
3038 expression that wants to use this address.
3039
3040 It only recognizes address in canonical form. LEGITIMIZE_ADDRESS should
3041 convert common non-canonical forms to canonical form so that they will
3042 be recognized. */
3043
3044 static bool
3045 csky_legitimate_address_p (machine_mode mode, rtx addr, bool strict_p)
3046 {
3047 enum rtx_code code = GET_CODE (addr);
3048
3049 /* Match the RTX form emitted for constant pool references.
3050 After reload constants split into minipools will have addresses
3051 from a LABEL_REF. */
3052 if (reload_completed
3053 && ((code == LABEL_REF)
3054 || (code == CONST
3055 && GET_CODE (XEXP (addr, 0)) == PLUS
3056 && GET_CODE (XEXP (XEXP (addr, 0), 0)) == LABEL_REF
3057 && CONST_INT_P (XEXP (XEXP (addr, 0), 1)))))
3058 return 1;
3059
3060 if (is_csky_address_register_rtx_p (addr, strict_p))
3061 return 1;
3062 /* It is a pc-relative load, may be generated for constpool. */
3063 else if (GET_CODE (addr) == LABEL_REF)
3064 return 1;
3065
3066 if (code == PLUS)
3067 {
3068 rtx xop0 = XEXP (addr, 0);
3069 rtx xop1 = XEXP (addr, 1);
3070
3071 return ((is_csky_address_register_rtx_p (xop0, strict_p)
3072 && csky_legitimate_index_p (mode, xop1, strict_p))
3073 || (is_csky_address_register_rtx_p (xop1, strict_p)
3074 && csky_legitimate_index_p (mode, xop0, strict_p)));
3075 }
3076
3077 return 0;
3078 }
3079
3080
3081 /* Functions to save and restore machine-specific function data. */
3082
3083 static struct machine_function *
3084 csky_init_machine_status (void)
3085 {
3086 struct machine_function *machine;
3087
3088 machine = ggc_cleared_alloc<machine_function> ();
3089
3090 #if CSKY_FT_UNKNOWN != 0
3091 machine->func_type = CSKY_FT_UNKNOWN;
3092 #endif
3093 return machine;
3094 }
3095
3096
3097 /* Implement INIT_EXPANDERS. */
3098
3099 void
3100 csky_init_expanders (void)
3101 {
3102 /* Arrange to initialize and mark the machine per-function status. */
3103 init_machine_status = csky_init_machine_status;
3104 }
3105
3106
3107 /* Implement TARGET_CANNOT_COPY_INSN_P.
3108 We must not copy any rtx that uses a pc-relative address. */
3109
3110 static bool
3111 csky_cannot_copy_insn_p (rtx_insn *insn)
3112 {
3113 subrtx_iterator::array_type array;
3114 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), ALL)
3115 {
3116 const_rtx x = *iter;
3117 if (GET_CODE (x) == UNSPEC
3118 && (XINT (x, 1) == UNSPEC_TLS_LABEL
3119 || XINT (x, 1) == UNSPEC_PIC_SYMBOL_GOTPC_GRS))
3120 return true;
3121 }
3122 return false;
3123 }
3124
3125
3126 /* Extract the parts of an RTL expression that is a valid memory address
3127 for an instruction. Return FALSE if it is a invalid memory address. */
3128
3129 struct csky_address
3130 {
3131 rtx base, index, symbol, label, disp;
3132 HOST_WIDE_INT scale;
3133 };
3134
3135 static bool
3136 decompose_csky_address (rtx addr, struct csky_address *out)
3137 {
3138 rtx base = NULL_RTX, index = NULL_RTX, disp = NULL_RTX;
3139 HOST_WIDE_INT scale = 1;
3140 rtx scale_rtx = NULL_RTX;
3141 int i;
3142
3143 out->base = out->index = out->symbol = out->label = out->disp = NULL_RTX;
3144 out->scale = 0;
3145
3146 if (REG_P (addr))
3147 {
3148 out->base = addr;
3149 return true;
3150 }
3151
3152 if (GET_CODE (addr) == LABEL_REF)
3153 {
3154 out->label = addr;
3155 return true;
3156 }
3157
3158 if (GET_CODE (addr) == CONST)
3159 addr = XEXP (addr, 0);
3160
3161 if (GET_CODE (addr) == PLUS)
3162 {
3163 rtx addends[2], op;
3164
3165 addends[0] = XEXP (addr, 0);
3166 addends[1] = XEXP (addr, 1);
3167
3168 if (GET_CODE (addends[0]) == LABEL_REF && CONST_INT_P (addends[1]))
3169 {
3170 out->label = addends[0];
3171 out->disp = addends[1];
3172 return true;
3173 }
3174
3175 if (!REG_P (addends[0]))
3176 std::swap (addends[0], addends[1]);
3177
3178 for (i = 0; i < 2; ++i)
3179 {
3180 op = addends[i];
3181 switch (GET_CODE (op))
3182 {
3183 case REG:
3184 if (!base)
3185 base = op;
3186 else if (!index)
3187 index = op;
3188 else
3189 return false;
3190 break;
3191 case CONST_INT:
3192 case UNSPEC:
3193 if (disp)
3194 return false;
3195 disp = op;
3196 break;
3197 case MULT:
3198 if (index)
3199 return false;
3200 index = XEXP (op, 0);
3201 scale_rtx = XEXP (op, 1);
3202 if (!CONST_INT_P (index) && !CONST_INT_P (scale_rtx))
3203 return false;
3204 else if (CONST_INT_P (index))
3205 std::swap (index, scale_rtx);
3206 scale = INTVAL (scale_rtx);
3207 break;
3208 case ASHIFT:
3209 if (index)
3210 return false;
3211 index = XEXP (op, 0);
3212 scale_rtx = XEXP (op, 1);
3213 if (!CONST_INT_P (scale_rtx))
3214 return false;
3215 scale = scale << INTVAL (scale_rtx);
3216 break;
3217 default:
3218 return false;
3219 }
3220 }
3221 }
3222
3223 if (!base)
3224 return false;
3225
3226 out->base = base;
3227 out->index = index;
3228 out->disp = disp;
3229 out->scale = scale;
3230
3231 return true;
3232 }
3233
3234 /* Helper function for the csky_simple_mem_operand predicate. Returns
3235 true if OP is an address of the form reg + displacement. */
3236
3237 bool
3238 csky_simple_addr_operand_p (rtx op)
3239 {
3240 struct csky_address addr;
3241
3242 if (!decompose_csky_address (op, &addr))
3243 return false;
3244
3245 /* FIXME The PIC related code.
3246 Check if load the symbol address from got table. */
3247 if (addr.disp && GET_CODE (addr.disp) == UNSPEC)
3248 return false;
3249 if (!addr.index && !addr.symbol)
3250 return true;
3251 return false;
3252 }
3253
3254
3255 /* Print the UNSPEC operand in X to the STREAM. */
3256
3257 static void
3258 csky_output_pic_addr_const (FILE *stream, rtx x, int code)
3259 {
3260
3261 if (GET_CODE (x) != UNSPEC)
3262 return;
3263
3264 if (UNSPEC_TLS == XINT (x, 1))
3265 {
3266 /* FIXME It is not reached */
3267 return;
3268 }
3269
3270 csky_print_operand (stream, XVECEXP (x, 0, 0), code);
3271
3272 switch (XINT (x, 1))
3273 {
3274 case UNSPEC_PIC_SYMBOL_GOTOFF:
3275 fputs ("@GOTOFF", stream);
3276 break;
3277 case UNSPEC_PIC_SYMBOL_PLT:
3278 fputs ("@PLT", stream);
3279 break;
3280 case UNSPEC_PIC_SYMBOL_GOT:
3281 fputs ("@GOT", stream);
3282 break;
3283 case UNSPEC_PIC_SYMBOL_GOTPC:
3284 fputs ("@GOTPC", stream);
3285 break;
3286 case UNSPEC_PIC_SYMBOL_BSR:
3287 break;
3288 default:
3289 break;
3290 }
3291 }
3292
3293
3294 /* Output the constpool label according to the rtx expression X. */
3295
3296 static void
3297 csky_output_constpool_label (FILE *stream, rtx x)
3298 {
3299 char buf[15];
3300
3301 gcc_assert (GET_CODE (x) == LABEL_REF);
3302 x = XEXP (x, 0);
3303
3304 if (GET_CODE (x) == UNSPEC_VOLATILE && XINT (x, 1) == VUNSPEC_POOL_LABEL)
3305 {
3306 ASM_GENERATE_INTERNAL_LABEL (buf, CSKY_CONSTPOOL_LABEL_PREFIX,
3307 INTVAL (XVECEXP (x, 0, 0)));
3308 assemble_name (stream, buf);
3309 }
3310 }
3311
3312
3313 /* Implement TARGET_PRINT_OPERAND_ADDRESS. */
3314
3315 static void
3316 csky_print_operand_address (FILE *stream,
3317 machine_mode mode ATTRIBUTE_UNUSED,
3318 rtx x)
3319 {
3320
3321 struct csky_address addr;
3322
3323 decompose_csky_address (x, &addr);
3324
3325 if (addr.label && addr.disp && GET_CODE (addr.disp) == CONST_INT)
3326 {
3327 fprintf (stream, "[");
3328 csky_output_constpool_label (stream, addr.label);
3329 fprintf (stream, "+%d]", (int) INTVAL (addr.disp));
3330 }
3331 else if (addr.label)
3332 {
3333 fprintf (stream, "[");
3334 csky_output_constpool_label (stream, addr.label);
3335 fprintf (stream, "]");
3336 }
3337 else if (addr.symbol && addr.disp && GET_CODE (addr.disp) == CONST_INT)
3338 {
3339 fprintf (stream, "[");
3340 output_addr_const (stream, addr.symbol);
3341 fprintf (stream, "+%d]", (int) INTVAL (addr.disp));
3342 }
3343 else if (addr.symbol)
3344 {
3345 fprintf (stream, "[");
3346 output_addr_const (stream, addr.symbol);
3347 fprintf (stream, "]");
3348 }
3349 else if (addr.disp && GET_CODE (addr.disp) == CONST_INT)
3350 fprintf (stream, "(%s, %d)",
3351 reg_names[REGNO (addr.base)], (int) INTVAL (addr.disp));
3352 else if (addr.disp && GET_CODE (addr.disp) == UNSPEC)
3353 {
3354 if (REGNO (addr.base) != CSKY_GB_REGNUM)
3355 fprintf (stream, "(%s, ", reg_names[REGNO (addr.base)]);
3356 else
3357 fprintf (stream, "[");
3358 csky_output_pic_addr_const (stream, addr.disp, 0);
3359 fprintf (stream, "%s", (REGNO (addr.base) != CSKY_GB_REGNUM)
3360 ? ")" : "]");
3361 }
3362 else if (addr.index)
3363 fprintf (stream, "(%s, %s << %d)",
3364 reg_names[REGNO (addr.base)], reg_names[REGNO (addr.index)],
3365 exact_log2 ((int) (addr.scale)));
3366 else
3367 fprintf (stream, "(%s, 0)", reg_names[REGNO (addr.base)]);
3368 }
3369
3370
3371 /* Implement TARGET_PRINT_OPERAND.
3372 Print operand X (an rtx) in assembler syntax to file STREAM
3373 according to modifier CODE.
3374
3375 'N' print the log2(X+1), mainly used for bmaski
3376 'P' print the log2(X)
3377 'Q' print the log2(~X)
3378 'O' print a decimal number
3379 'M' print a decimal number as its negative
3380 'R' print the next register or memory location along, i.e. the lsw in
3381 a double word value
3382 'H' print the high 16 bits of a constant. */
3383
3384 static void
3385 csky_print_operand (FILE *stream, rtx x, int code)
3386 {
3387 switch (code)
3388 {
3389 case 'N':
3390 if ((INTVAL (x) & 0xffffffff) == 0xffffffff)
3391 fprintf (stream, "0");
3392 else
3393 fprintf (stream, "%d",
3394 (int) exact_log2 ((INTVAL (x) & 0xffffffff) + 1) % 32);
3395 break;
3396 case 'P':
3397 fprintf (stream, "%d",
3398 (int) exact_log2 (INTVAL (x) & 0xffffffff));
3399 break;
3400 case 'Q':
3401 fprintf (stream, "%d",
3402 (int) exact_log2 (~INTVAL (x) & 0xffffffff));
3403 break;
3404 case 'O':
3405 fprintf (stream, "%d", (int) INTVAL (x));
3406 break;
3407 case 'M':
3408 fprintf (stream, "%d", (int) (-INTVAL (x)));
3409 break;
3410 case 'R':
3411 /* Next location along in memory or register. */
3412 switch (GET_CODE (x))
3413 {
3414 case REG:
3415 fputs (reg_names[REGNO (x) + 1], stream);
3416 break;
3417 case MEM:
3418 csky_print_operand_address
3419 (stream, GET_MODE (x), XEXP (adjust_address (x, SImode, 4), 0));
3420 break;
3421 default:
3422 gcc_unreachable ();
3423 }
3424 break;
3425 case 'H':
3426 fprintf (stream, "%ld", (long)((INTVAL (x) & 0xFFFF0000) >> 16));
3427 break;
3428 default:
3429 switch (GET_CODE (x))
3430 {
3431 case REG:
3432 fputs (reg_names[REGNO (x)], stream);
3433 break;
3434 case MEM:
3435 output_address (GET_MODE (x), XEXP (x, 0));
3436 break;
3437 case UNSPEC:
3438 csky_output_pic_addr_const (stream, x, code);
3439 break;
3440 default:
3441 output_addr_const (stream, x);
3442 break;
3443 }
3444 break;
3445 }
3446 }
3447
3448
3449
3450 /* Implement TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS. */
3451
3452 static bool
3453 csky_allocate_stack_slots_for_args (void)
3454 {
3455 /* Naked functions should not allocate stack slots for arguments. */
3456 return !CSKY_FUNCTION_IS_NAKED (get_csky_current_func_type ());
3457 }
3458
3459
3460 /* Can we generate a constant with a single instruction, without using
3461 lrw? */
3462
3463 static int
3464 const_ok_for_cskyv2 (HOST_WIDE_INT value)
3465 {
3466 /* Try exact power of two. It can be generated by bgeni. */
3467 if (CSKY_CONST_OK_FOR_Ub (value))
3468 return 1;
3469
3470 /* Try exact power of two - 1. It can be generated by bmaski. */
3471 if (CSKY_CONST_OK_FOR_Uc (value) && value != -1)
3472 return 1;
3473
3474 /* Try if it can be generated by movi. */
3475 if (CSKY_CONST_OK_FOR_I (value))
3476 return 1;
3477
3478 /* The constant can be generated by movih.
3479 Notice that movih is a 32-bit instruction. */
3480 if (CSKY_CONST_OK_FOR_MOVIH (value))
3481 return 1;
3482
3483 return 0;
3484 }
3485
3486
3487 /* Tricks for synthesizing constants from values that can be directly
3488 manipulated by machine instructions. */
3489
3490 enum csky_inline_const_type
3491 {
3492 IC_UNINLINABLE = 0, /* Not inlineable */
3493 IC_SINGLE, /* Single instruction */
3494 IC_APPEND_NOT, /* Single instruction followed by a not */
3495 IC_APPEND_ADDI, /* Single insn followed by an addi */
3496 IC_APPEND_SUBI, /* Single insn followed by a subi */
3497 IC_BGENI_ADDI, /* Single insn(bgeni) followed by an addi */
3498 IC_BGENI_SUBI, /* Single insn(bgeni) followed by a subi */
3499 IC_APPEND_BSETI, /* Single insn followed by bseti */
3500 IC_APPEND_MOVI, /* Single insn followed by movi */
3501 IC_APPEND_BCLRI, /* Single insn followed by bclri */
3502 IC_APPEND_ROTLI, /* Single insn followed by rotli */
3503 IC_APPEND_LSLI, /* Single insn followed by lsli */
3504 IC_APPEND_IXH, /* Single insn followed by ixh */
3505 IC_APPEND_IXW /* Single insn followed by ixw */
3506 };
3507
3508
3509 /* Try tricks to load a constant inline and return the trick number if
3510 success, or IC_UNINLINABLE. */
3511
3512 static enum csky_inline_const_type
3513 try_csky_constant_tricks (HOST_WIDE_INT value, HOST_WIDE_INT *x,
3514 HOST_WIDE_INT *y)
3515 {
3516 HOST_WIDE_INT i, value_invert;
3517 unsigned HOST_WIDE_INT bit, shf, rot, lobits, hibits;
3518
3519 value &= 0xffffffff;
3520 value_invert = ~value & 0xffffffff;
3521
3522 if (const_ok_for_cskyv2 (value))
3523 {
3524 *x = value;
3525 return IC_SINGLE;
3526 }
3527
3528 /* Since movih is 32 bits, do not use it here, better code may
3529 be generated later. */
3530 if (const_ok_for_cskyv2 (value_invert)
3531 && !CSKY_CONST_OK_FOR_MOVIH (value_invert))
3532 {
3533 *x = value_invert;
3534 return IC_APPEND_NOT;
3535 }
3536
3537 /* One immediate generate instruction, and one 16-bit subi or addi. */
3538 for (i = 1; i <= 32; i++)
3539 {
3540 if (const_ok_for_cskyv2 (value - i)
3541 && !CSKY_CONST_OK_FOR_MOVIH (value - i))
3542 {
3543 *x = value - i;
3544 *y = i;
3545 return IC_APPEND_ADDI;
3546 }
3547
3548 if (const_ok_for_cskyv2 (value + i)
3549 && !CSKY_CONST_OK_FOR_MOVIH (value - i))
3550 {
3551 *x = value + i;
3552 *y = i;
3553 return IC_APPEND_SUBI;
3554 }
3555 }
3556
3557 /* Generate bgeni + addi. */
3558 if (CSKY_CONST_OK_FOR_Ub (value & 0xfffff000))
3559 {
3560 *x = (value & 0xfffff000);
3561 *y = (value & 0xfff);
3562 return IC_BGENI_ADDI;
3563 }
3564
3565 /* Generate bgeni + subi. */
3566 lobits = value & 0xfff;
3567 hibits = (unsigned HOST_WIDE_INT)(value & 0xfffff000) + (1 << 12);
3568 if (exact_log2 (hibits) >= 1
3569 && exact_log2 (hibits) <= 30
3570 && lobits != 0)
3571 {
3572 *x = hibits;
3573 *y = (0x1000 - lobits);
3574 return IC_BGENI_SUBI;
3575 }
3576
3577 /* One immediate generate instruction, and one bseti or bclri. */
3578 bit = 0x80000000ULL;
3579 for (i = 0; i <= 31; i++)
3580 {
3581 if (const_ok_for_cskyv2 (value & ~bit)
3582 && !CSKY_CONST_OK_FOR_MOVIH (value & ~bit))
3583 {
3584 *y = bit;
3585 *x = (value & ~bit);
3586 return IC_APPEND_BSETI;
3587 }
3588
3589 if (const_ok_for_cskyv2 (value | bit)
3590 && !CSKY_CONST_OK_FOR_MOVIH (value | bit))
3591 {
3592 *y = ~bit & 0xffffffff;
3593 *x = value | bit;
3594 return IC_APPEND_BCLRI;
3595 }
3596
3597 bit >>= 1;
3598 }
3599
3600 /* One immediate generate instruction, and one rotli or lsli. */
3601 shf = value;
3602 rot = value;
3603 for (i = 1; i < 31; i++)
3604 {
3605 int c;
3606
3607 /* Rotate left. */
3608 c = rot << 31;
3609 rot >>= 1;
3610 rot &= 0x7FFFFFFF;
3611 rot |= c;
3612
3613 if (const_ok_for_cskyv2 (rot) && !CSKY_CONST_OK_FOR_MOVIH (rot))
3614 {
3615 *y = i;
3616 *x = rot;
3617 return IC_APPEND_ROTLI;
3618 }
3619
3620 /* Can't use logical shift when low order bit is one. */
3621 if (shf & 1)
3622 shf = 0;
3623 else
3624 shf >>= 1;
3625
3626 if (shf != 0 && const_ok_for_cskyv2 (shf)
3627 && !CSKY_CONST_OK_FOR_MOVIH (shf))
3628 {
3629 *y = i;
3630 *x = shf;
3631 return IC_APPEND_LSLI;
3632 }
3633 }
3634
3635 /* One immediate generate instruction, and one ixh. */
3636 if (CSKY_ISA_FEATURE (E2)
3637 && (value % 3) == 0
3638 && const_ok_for_cskyv2 (value / 3)
3639 && !CSKY_CONST_OK_FOR_MOVIH (value / 3))
3640 {
3641 *x = value / 3;
3642 return IC_APPEND_IXH;
3643 }
3644
3645 /* One immediate generate instruction, and one ixw. */
3646 if (CSKY_ISA_FEATURE (E2)
3647 && (value % 5) == 0
3648 && const_ok_for_cskyv2 (value / 5)
3649 && !CSKY_CONST_OK_FOR_MOVIH (value / 5))
3650 {
3651 *x = value / 5;
3652 return IC_APPEND_IXW;
3653 }
3654
3655 /* Generate movih + bseti. */
3656 if (CSKY_CONST_OK_FOR_Ub (value & 0xffff))
3657 {
3658 *x = value & 0xffff0000;
3659 *y = value & 0xffff;
3660 return IC_APPEND_BSETI;
3661 }
3662
3663 /* Generate movih + not. */
3664 if (CSKY_CONST_OK_FOR_MOVIH (value_invert))
3665 {
3666 *x = value_invert;
3667 return IC_APPEND_NOT;
3668 }
3669
3670 /* One movih, and one 16bits addi or subi. */
3671 for (i = 1; i <= 32; i++)
3672 {
3673 if (CSKY_CONST_OK_FOR_MOVIH (value - i))
3674 {
3675 *x = value - i;
3676 *y = i;
3677 return IC_APPEND_ADDI;
3678 }
3679
3680 if (CSKY_CONST_OK_FOR_MOVIH (value + i))
3681 {
3682 *x = value + i;
3683 *y = i;
3684 return IC_APPEND_SUBI;
3685 }
3686 }
3687
3688 /* One movih, and one bseti or bclri. */
3689 bit = 0x80000000ULL;
3690 for (i = 0; i <= 31; i++)
3691 {
3692 if (CSKY_CONST_OK_FOR_MOVIH (value & ~bit))
3693 {
3694 *y = bit;
3695 *x = value & ~bit;
3696 return IC_APPEND_BSETI;
3697 }
3698
3699 if (CSKY_CONST_OK_FOR_MOVIH (value | bit))
3700 {
3701 *y = ~bit & 0xffffffff;
3702 *x = value | bit;
3703 return IC_APPEND_BCLRI;
3704 }
3705
3706 bit >>= 1;
3707 }
3708
3709 /* One movih, and one rotli or lsli. */
3710 shf = value;
3711 rot = value;
3712 for (i = 1; i < 31; i++)
3713 {
3714 int c;
3715
3716 /* Rotate left. */
3717 c = rot << 31;
3718 rot >>= 1;
3719 rot &= 0x7FFFFFFF;
3720 rot |= c;
3721
3722 if (CSKY_CONST_OK_FOR_MOVIH (rot))
3723 {
3724 *y = i;
3725 *x = rot;
3726 return IC_APPEND_ROTLI;
3727 }
3728
3729 /* Can't use logical shift when low order bit is one. */
3730 if (shf & 1)
3731 shf = 0;
3732 else
3733 shf >>= 1;
3734
3735 if (shf != 0 && CSKY_CONST_OK_FOR_MOVIH (shf))
3736 {
3737 *y = i;
3738 *x = shf;
3739 return IC_APPEND_LSLI;
3740 }
3741 }
3742
3743 return IC_UNINLINABLE;
3744 }
3745
3746
3747 /* Actually output a constant using a trick.
3748 FIXME: I think this would be better handled by a splitter than at the
3749 asm output level. */
3750
3751 static const char *
3752 csky_output_inline_const (machine_mode mode, rtx operands[])
3753 {
3754 HOST_WIDE_INT x = 0, y = 0;
3755 enum csky_inline_const_type trick_type;
3756 rtx out_operands[3];
3757 char buf[256];
3758 char load_op[128];
3759 const char *dst_fmt;
3760 HOST_WIDE_INT value = INTVAL (operands[1]);
3761 int ivalue = (int) value;
3762 unsigned int uvalue = (unsigned int) value;
3763
3764 trick_type = try_csky_constant_tricks (value, &x, &y);
3765 /* lrw's are handled separately: Large inlinable constants never get
3766 turned into lrw's. Our caller uses try_csky_constant_tricks to back
3767 off to an lrw rather than calling this routine. */
3768 gcc_assert (trick_type != IC_UNINLINABLE);
3769
3770 /* Operands: 0 = dst, 1 = load immedate., 2 = adjust immedate. */
3771 out_operands[0] = operands[0];
3772 out_operands[1] = GEN_INT (x);
3773 if (trick_type != IC_SINGLE && trick_type != IC_APPEND_NOT)
3774 out_operands[2] = GEN_INT (y);
3775
3776 /* Select dst format based on mode. */
3777 if (mode == DImode && TARGET_BIG_ENDIAN)
3778 dst_fmt = "%R0";
3779 else
3780 dst_fmt = "%0";
3781
3782 /* Try movi16: 0~31,movi32: 0~65535. */
3783 if (CSKY_CONST_OK_FOR_I (x))
3784 sprintf (load_op, "movi\t%s, %%1", dst_fmt);
3785 /* Try exact power of two - 1. */
3786 else if (CSKY_CONST_OK_FOR_Uc (x))
3787 sprintf (load_op, "bmaski\t%s, %%N1", dst_fmt);
3788 /* Try movih. */
3789 else if (CSKY_CONST_OK_FOR_MOVIH (x))
3790 sprintf (load_op, "movih\t%s, %%H1", dst_fmt);
3791 else
3792 {
3793 sprintf (load_op, "BADMOVI-inline_const %s, %%1", dst_fmt);
3794 gcc_unreachable ();
3795 }
3796
3797 switch (trick_type)
3798 {
3799 case IC_SINGLE:
3800 strcpy (buf, load_op);
3801 break;
3802 /* Add instruction 'not'. */
3803 case IC_APPEND_NOT:
3804 sprintf (buf, "%s\n\tnot\t%s, %s\t// %d 0x%x", load_op, dst_fmt,
3805 dst_fmt, ivalue, uvalue);
3806 break;
3807 /* Add instruction 'addi'. */
3808 case IC_APPEND_ADDI:
3809 sprintf (buf, "%s\n\taddi\t%s, %s, %%2\t// %d 0x%x", load_op,
3810 dst_fmt, dst_fmt, ivalue, uvalue);
3811 break;
3812 /* Add instruction 'subi'. */
3813 case IC_APPEND_SUBI:
3814 sprintf (buf, "%s\n\tsubi\t%s, %s, %%2\t// %d 0x%x", load_op,
3815 dst_fmt, dst_fmt, ivalue, uvalue);
3816 break;
3817 /* Add instruction 'addi', the last instruction is bgeni. */
3818 case IC_BGENI_ADDI:
3819 sprintf (buf, "%s\n\taddi\t%s, %s, %%2\t// %d 0x%x", load_op,
3820 dst_fmt, dst_fmt, ivalue, uvalue);
3821 break;
3822 /* Add instruction 'subi', the last instruction is bgeni. */
3823 case IC_BGENI_SUBI:
3824 sprintf (buf, "%s\n\tsubi\t%s, %s, %%2\t// %d 0x%x", load_op,
3825 dst_fmt, dst_fmt, ivalue, uvalue);
3826 break;
3827 /* Add instruction 'bseti'. */
3828 case IC_APPEND_BSETI:
3829 sprintf (buf, "%s\n\tbseti\t%s, %s, %%P2\t// %d 0x%x", load_op,
3830 dst_fmt, dst_fmt, ivalue, uvalue);
3831 break;
3832 /* Add instruction 'movi'. */
3833 case IC_APPEND_MOVI:
3834 sprintf (buf, "%s\n\tmovi\t%s, %%2\t// %d 0x%x", load_op, dst_fmt,
3835 ivalue, uvalue);
3836 break;
3837 /* Add instruction 'bclri'. */
3838 case IC_APPEND_BCLRI:
3839 sprintf (buf, "%s\n\tbclri\t%s, %s, %%Q2\t// %d 0x%x", load_op,
3840 dst_fmt, dst_fmt, ivalue, uvalue);
3841 break;
3842 /* Add instruction 'rotli'. */
3843 case IC_APPEND_ROTLI:
3844 sprintf (buf, "%s\n\trotli\t%s, %s, %%2\t// %d 0x%x", load_op,
3845 dst_fmt, dst_fmt, ivalue, uvalue);
3846 break;
3847 /* Add instruction 'lsli'. */
3848 case IC_APPEND_LSLI:
3849 sprintf (buf, "%s\n\tlsli\t%s, %s, %%2\t// %d 0x%x", load_op,
3850 dst_fmt, dst_fmt, ivalue, uvalue);
3851 break;
3852 /* Add instruction 'ixh'. */
3853 case IC_APPEND_IXH:
3854 sprintf (buf, "%s\n\tixh\t%s, %s, %s\t// %d 0x%x", load_op,
3855 dst_fmt, dst_fmt, dst_fmt, ivalue, uvalue);
3856 break;
3857 /* Add instruction 'ixw'. */
3858 case IC_APPEND_IXW:
3859 sprintf (buf, "%s\n\tixw\t%s, %s, %s\t// %d 0x%x", load_op,
3860 dst_fmt, dst_fmt, dst_fmt, ivalue, uvalue);
3861 break;
3862 default:
3863 return "";
3864 }
3865
3866 output_asm_insn (buf, out_operands);
3867
3868 return "";
3869 }
3870
3871 /* This is a helper function for the Uo constraint for movsi patterns. */
3872
3873 bool
3874 csky_inlinable_constant (HOST_WIDE_INT value)
3875 {
3876 HOST_WIDE_INT x, y;
3877 return (!(CSKY_TARGET_ARCH (CK802) || CSKY_TARGET_ARCH (CK801))
3878 && try_csky_constant_tricks (value, &x, &y));
3879 }
3880
3881
3882 /* Return true if the constant VAL can be expressed by an 8-bit constant
3883 with a shift value, filling in *BASE and *SHIFT. */
3884
3885 bool
3886 csky_shifted_imm8_constant (unsigned HOST_WIDE_INT val,
3887 unsigned int *base, unsigned int *shift)
3888 {
3889 unsigned HOST_WIDE_INT mask = 0xff;
3890 int i;
3891 val = val & (unsigned HOST_WIDE_INT) 0xffffffffu;
3892 if (val == 0)
3893 return 0;
3894
3895 for (i = 0; i < 25; i++)
3896 if ((val & (mask << i)) == val)
3897 {
3898 if (base)
3899 *base = (unsigned int) (val >> i);
3900 if (shift)
3901 *shift = (unsigned int) i;
3902 return true;
3903 }
3904
3905 return false;
3906 }
3907
3908
3909 /* Output a move of a word or less value. */
3910
3911 const char *
3912 csky_output_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
3913 machine_mode mode ATTRIBUTE_UNUSED)
3914 {
3915 rtx dst = operands[0];
3916 rtx src = operands[1];
3917 struct csky_address op0, op1;
3918
3919 if (REG_P (dst))
3920 {
3921 /* The situation mov reg to reg. */
3922 if (REG_P (src))
3923 {
3924 int dstreg = REGNO (dst);
3925 int srcreg = REGNO (src);
3926
3927 /* hilo registers exchange their places,
3928 and their order of Dimode as same as other
3929 general registers in LITTLE_ENDIAN mode. */
3930 if (TARGET_BIG_ENDIAN)
3931 {
3932 if (dstreg == CSKY_HI_REGNUM)
3933 return "mthi\t%1";
3934 else if (dstreg == CSKY_LO_REGNUM)
3935 return "mtlo\t%1";
3936 else if (srcreg == CSKY_HI_REGNUM)
3937 return "mfhi\t%0";
3938 else if (srcreg == CSKY_LO_REGNUM)
3939 return "mflo\t%0";
3940 }
3941 else
3942 {
3943 if (dstreg == CSKY_HI_REGNUM)
3944 return "mtlo\t%1";
3945 else if (dstreg == CSKY_LO_REGNUM)
3946 return "mthi\t%1";
3947 else if (srcreg == CSKY_HI_REGNUM)
3948 return "mflo\t%0";
3949 else if (srcreg == CSKY_LO_REGNUM)
3950 return "mfhi\t%0";
3951 }
3952
3953 if (CSKY_VREG_P (dstreg) && CSKY_VREG_P (srcreg))
3954 return "fmovs\t%0, %1";
3955 if (CSKY_VREG_P (dstreg))
3956 return "fmtvrl\t%0, %1";
3957 if (CSKY_VREG_P (srcreg))
3958 return "fmfvrl\t%0, %1";
3959
3960 if (REGNO (src) == CSKY_CC_REGNUM)
3961 return "mvc\t%0";
3962 else
3963 return "mov\t%0, %1";
3964 }
3965 /* The situation mov memory to reg. */
3966 else if (GET_CODE (src) == MEM)
3967 {
3968 decompose_csky_address (XEXP (src, 0), &op1);
3969
3970 if (op1.index)
3971 switch (GET_MODE (src))
3972 {
3973 case E_HImode:
3974 return "ldr.h\t%0, %1";
3975 case E_QImode:
3976 return "ldr.b\t%0, %1";
3977 case E_SImode:
3978 case E_SFmode:
3979 if (CSKY_VREG_P (REGNO (dst)))
3980 return "fldrs\t%0, %1";
3981 else
3982 return "ldr.w\t%0, %1";
3983 default:
3984 gcc_unreachable ();
3985 }
3986 /* Generate lrw rx, [LABEL]. This happens when the compiler
3987 generates constant pool references and uses lrw to get the
3988 constant into memory. */
3989 else if (op1.label)
3990 return "lrw\t%0, %1";
3991 /* Generate lrs.w rx, [symbol@GOT/PLT]. */
3992 else if (flag_pic == 1 && op1.disp && GET_CODE (op1.disp) == UNSPEC)
3993 return "lrs.w\t%0, %1";
3994 else
3995 switch (GET_MODE (src))
3996 {
3997 case E_HImode:
3998 return "ld.h\t%0, %1";
3999 case E_QImode:
4000 return "ld.b\t%0, %1";
4001 case E_SFmode:
4002 case E_SImode:
4003 if (CSKY_VREG_P (REGNO (dst)))
4004 return "flds\t%0, %1";
4005 else
4006 return "ld.w\t%0, %1";
4007 default:
4008 gcc_unreachable ();
4009 }
4010 }
4011 /* The situation mov integer to reg. */
4012 else if (GET_CODE (src) == CONST_INT ||
4013 (GET_CODE (src) == CONST_DOUBLE && GET_MODE (src) == SFmode))
4014 {
4015 HOST_WIDE_INT x, y;
4016 const REAL_VALUE_TYPE *d;
4017 long l;
4018
4019 if (GET_CODE (src) == CONST_DOUBLE && GET_MODE (src) == SFmode)
4020 {
4021 d = CONST_DOUBLE_REAL_VALUE (src);
4022 REAL_VALUE_TO_TARGET_SINGLE (*d, l);
4023 operands[1] = GEN_INT (l);
4024 src = operands[1];
4025 }
4026
4027 if (try_csky_constant_tricks (INTVAL (src), &x, &y))
4028 return csky_output_inline_const (SImode, operands);
4029 /* Return '#' to split it. */
4030 else if (CSKY_CONST_OK_FOR_T (INTVAL (src)))
4031 return "#";
4032 else
4033 return "lrw\t%0, %x1\t";
4034 }
4035 else if (TARGET_ANCHOR && GET_CODE (src) == SYMBOL_REF)
4036 {
4037 if (SYMBOL_REF_FUNCTION_P (src))
4038 return "lrw\t%0, %1@BTEXT";
4039 else
4040 return "lrw\t%0, %1@BDATA";
4041 }
4042 else if (GET_CODE (src) == UNSPEC
4043 && XINT (src, 1) == UNSPEC_PIC_SYMBOL_GRS)
4044 return "grs\t%0, %1";
4045 else
4046 return "lrw\t%0, %1";
4047 }
4048 else if (GET_CODE (dst) == MEM)
4049 {
4050 decompose_csky_address (XEXP (dst, 0), &op0);
4051
4052 if (op0.index)
4053 switch (GET_MODE (src))
4054 {
4055 case E_HImode:
4056 return "str.h\t%1, %0";
4057 case E_QImode:
4058 return "str.b\t%1, %0";
4059 case E_SFmode:
4060 case E_SImode:
4061 if (CSKY_VREG_P (REGNO (src)))
4062 return "fstrs\t%1, %0";
4063 else
4064 return "str.w\t%1, %0";
4065 default:
4066 gcc_unreachable ();
4067 }
4068 else
4069 switch (GET_MODE (dst))
4070 {
4071 case E_HImode:
4072 return "st.h\t%1, %0";
4073 case E_QImode:
4074 return "st.b\t%1, %0";
4075 case E_SImode:
4076 case E_SFmode:
4077 if (CSKY_VREG_P (REGNO (src)))
4078 return "fsts\t%1, %0";
4079 else
4080 return "st.w\t%1, %0";
4081 default:
4082 gcc_unreachable ();
4083 }
4084 }
4085
4086 gcc_unreachable ();
4087 }
4088
4089
4090 /* Output a move of a word or less value. Specific for ck801. */
4091
4092 const char *
4093 csky_output_ck801_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
4094 machine_mode mode ATTRIBUTE_UNUSED)
4095 {
4096 rtx dst = operands[0];
4097 rtx src = operands[1];
4098 struct csky_address op1;
4099
4100 if (REG_P (dst))
4101 {
4102 if (REG_P (src))
4103 return "mov\t%0, %1";
4104 else if (GET_CODE (src) == MEM)
4105 {
4106 decompose_csky_address (XEXP (src, 0), &op1);
4107
4108 /* Generate lrw rx, [LABEL]. This happens when the compiler
4109 generates constant pool references and uses lrw to get the
4110 constant in memory. */
4111 if (op1.label)
4112 return "lrw\t%0, %1";
4113 else
4114 switch (GET_MODE (src))
4115 {
4116 case E_HImode:
4117 return "ld.h\t%0, %1";
4118 case E_QImode:
4119 return "ld.b\t%0, %1";
4120 case E_SFmode:
4121 case E_SImode:
4122 return "ld.w\t%0, %1";
4123 default:
4124 gcc_unreachable ();
4125 }
4126 }
4127 else if (GET_CODE (src) == CONST_INT)
4128 {
4129 if (REGNO (dst) > 7)
4130 return "lrw\t%0, %x1\t";
4131 else if (CSKY_CONST_OK_FOR_N (INTVAL (src) + 1))
4132 return "movi\t%0, %1";
4133 /* Return '#' to split it. */
4134 else if (CSKY_CONST_OK_FOR_T (INTVAL (src)))
4135 return "#";
4136 else if (csky_shifted_imm8_constant (INTVAL (src), NULL, NULL))
4137 return "#";
4138 else
4139 return "lrw\t%0, %x1\t";
4140 }
4141 else if (GET_CODE (src) == CONST_DOUBLE && GET_MODE (src) == SFmode)
4142 {
4143 const REAL_VALUE_TYPE *d;
4144 long l;
4145
4146 d = CONST_DOUBLE_REAL_VALUE (src);
4147 REAL_VALUE_TO_TARGET_SINGLE (*d, l);
4148 operands[1] = GEN_INT (l);
4149 src = operands[1];
4150
4151 if (CSKY_CONST_OK_FOR_N (INTVAL (src) + 1))
4152 return "movi\t%0, %1";
4153 else
4154 return "lrw\t%0, %x1\t";
4155 }
4156 else if (TARGET_ANCHOR && GET_CODE (src) == SYMBOL_REF)
4157 {
4158 if (SYMBOL_REF_FUNCTION_P (src))
4159 return "lrw\t%0, %1@BTEXT";
4160 else
4161 return "lrw\t%0, %1@BDATA";
4162 }
4163 else
4164 return "lrw\t%0, %1";
4165 }
4166 else if (GET_CODE (dst) == MEM)
4167 switch (GET_MODE (dst))
4168 {
4169 case E_HImode:
4170 return "st.h\t%1, %0";
4171 case E_QImode:
4172 return "st.b\t%1, %0";
4173 case E_SImode:
4174 case E_SFmode:
4175 return "st.w\t%1, %0";
4176 default:
4177 gcc_unreachable ();
4178 }
4179
4180 gcc_unreachable ();
4181 }
4182
4183
4184 /* Return a sequence of instructions to perform DI or DF move.
4185 Since the CSKY cannot move a DI or DF in one instruction, we have
4186 to take care when we see overlapping source and dest registers. */
4187
4188 const char *
4189 csky_output_movedouble (rtx operands[],
4190 machine_mode mode ATTRIBUTE_UNUSED)
4191 {
4192 rtx dst = operands[0];
4193 rtx src = operands[1];
4194
4195 if (REG_P (dst))
4196 {
4197 if (REG_P (src))
4198 {
4199 int dstreg = REGNO (dst);
4200 int srcreg = REGNO (src);
4201
4202 if (CSKY_HILO_REG_P (srcreg))
4203 {
4204 if (TARGET_BIG_ENDIAN)
4205 return "mfhi\t%0\n\tmflo\t%R0";
4206 else
4207 return "mfhi\t%R0\n\tmflo\t%0";
4208 }
4209 else if (CSKY_HILO_REG_P (dstreg))
4210 {
4211 if (TARGET_BIG_ENDIAN)
4212 return "mthi\t%1\n\tmtlo\t%R1";
4213 else
4214 return "mthi\t%R1\n\tmtlo\t%1";
4215 }
4216 else if (CSKY_VREG_P (srcreg) && CSKY_VREG_P (dstreg))
4217 return "fmovd\t%0, %1";
4218 else if (CSKY_VREG_P (srcreg))
4219 {
4220 /* Since the vector registers in fpuv2_soft processors
4221 like ck803f are 32 bits wide, just one insn is needed
4222 to complete the move operation. */
4223 if (TARGET_SOFT_FPU)
4224 return "fmfvrl\t%0, %1";
4225 else if (TARGET_BIG_ENDIAN)
4226 return "fmfvrh\t%0, %1\n\tfmfvrl\t%R0, %1";
4227 else
4228 return "fmfvrh\t%R0, %1\n\tfmfvrl\t%0, %1";
4229 }
4230 else if (CSKY_VREG_P (dstreg))
4231 {
4232 if (TARGET_SOFT_FPU)
4233 return "fmtvrl\t%0, %1";
4234 else if (TARGET_BIG_ENDIAN)
4235 return "fmtvrh\t%0, %1\n\tfmtvrl\t%0, %R1";
4236 else
4237 return "fmtvrh\t%0, %R1\n\tfmtvrl\t%0, %1";
4238 }
4239
4240 /* Ensure the second source not overwritten. */
4241 if (srcreg + 1 == dstreg)
4242 return "mov\t%R0, %R1\n\tmov\t%0, %1";
4243 else
4244 return "mov\t%0, %1\n\tmov\t%R0, %R1";
4245 }
4246 else if (GET_CODE (src) == MEM)
4247 {
4248 rtx memexp = XEXP (src, 0);
4249 int dstreg = REGNO (dst);
4250 int basereg = -1;
4251 struct csky_address op0;
4252
4253 decompose_csky_address (XEXP (src, 0), &op0);
4254
4255 if (GET_CODE (memexp) == LABEL_REF
4256 || (GET_CODE (memexp) == CONST
4257 && GET_CODE (XEXP (memexp, 0)) == PLUS
4258 && GET_CODE (XEXP (XEXP (memexp, 0), 0)) == LABEL_REF))
4259 return "lrw\t%0, [%1]\n\tlrw\t%R0, [%R1]";
4260 else if (GET_CODE (memexp) == REG)
4261 basereg = REGNO (memexp);
4262 else if (GET_CODE (memexp) == PLUS)
4263 {
4264 if (GET_CODE (XEXP (memexp, 0)) == REG)
4265 basereg = REGNO (XEXP (memexp, 0));
4266 else if (GET_CODE (XEXP (memexp, 1)) == REG)
4267 basereg = REGNO (XEXP (memexp, 1));
4268 else
4269 gcc_unreachable ();
4270 }
4271 else
4272 gcc_unreachable ();
4273
4274
4275 /* When FPUV2. */
4276 if (CSKY_VREG_P (dstreg))
4277 {
4278 if (op0.index)
4279 return "fldrd\t%0, %1";
4280 else
4281 return "fldd\t%0, %1";
4282 }
4283 /* FIXME length attribute is wrong here. */
4284 if (dstreg == basereg)
4285 /* Just load them in reverse order. */
4286 return "ld.w\t%R0, %R1\n\tld.w\t%0, %1";
4287 else
4288 return "ld.w\t%0, %1\n\tld.w\t%R0, %R1";
4289 }
4290 else if (GET_CODE (src) == CONST_INT || GET_CODE (src) == CONST_DOUBLE)
4291 {
4292 split_double (src, operands + 2, operands + 3);
4293
4294 if (CSKY_CONST_OK_FOR_I (INTVAL (operands[2])))
4295 output_asm_insn ("movi\t%0, %2", operands);
4296 else if (CSKY_CONST_OK_FOR_Uc (INTVAL (operands[2])))
4297 output_asm_insn ("bmaski\t%0, %N2", operands);
4298 else if (CSKY_CONST_OK_FOR_Ub (INTVAL (operands[2])))
4299 output_asm_insn ("bgeni\t%0, %P2", operands);
4300 else
4301 output_asm_insn ("lrw\t%0, %2", operands);
4302
4303 if (CSKY_CONST_OK_FOR_I (INTVAL (operands[3])))
4304 output_asm_insn ("movi\t%R0, %3", operands);
4305 else if (CSKY_CONST_OK_FOR_Uc (INTVAL (operands[3])))
4306 output_asm_insn ("bmaski\t%R0, %N3", operands);
4307
4308 else if (CSKY_CONST_OK_FOR_Ub (INTVAL (operands[3])))
4309 output_asm_insn ("bgeni\t%R0, %P3", operands);
4310 else
4311 output_asm_insn ("lrw\t%R0, %3", operands);
4312
4313 return "";
4314 }
4315 else
4316 gcc_unreachable ();
4317 }
4318 else if (GET_CODE (dst) == MEM && GET_CODE (src) == REG)
4319 {
4320 rtx memexp = XEXP (dst, 0);
4321 int srcreg = REGNO (src);
4322 int basereg = -1;
4323 struct csky_address op0;
4324
4325 decompose_csky_address (XEXP (dst, 0), &op0);
4326
4327 if (GET_CODE (memexp) == REG)
4328 basereg = REGNO (memexp);
4329 else if (GET_CODE (memexp) == PLUS)
4330 {
4331 if (GET_CODE (XEXP (memexp, 0)) == REG)
4332 basereg = REGNO (XEXP (memexp, 0));
4333 else if (GET_CODE (XEXP (memexp, 1)) == REG)
4334 basereg = REGNO (XEXP (memexp, 1));
4335 else
4336 gcc_unreachable ();
4337 }
4338 else
4339 gcc_unreachable ();
4340
4341 /* When FPUV2. */
4342 if (CSKY_VREG_P (srcreg))
4343 {
4344 if (op0.index)
4345 return "fstrd\t%1, %0";
4346 else
4347 return "fstd\t%1, %0";
4348 }
4349 /* FIXME length attribute is wrong here. */
4350 if (srcreg == basereg)
4351 /* Just load them in reverse order. */
4352 return "st.w\t%R1, %R0\n\tst.w\t%1, %0";
4353 else
4354 return "st.w\t%1, %0\n\tst.w\t%R1, %R0";
4355 }
4356 else
4357 gcc_unreachable ();
4358 }
4359
4360
4361 const char *
4362 csky_output_ck801_movedouble (rtx operands[],
4363 machine_mode mode ATTRIBUTE_UNUSED)
4364 {
4365 rtx dst = operands[0];
4366 rtx src = operands[1];
4367
4368 if (REG_P (dst))
4369 {
4370 if (REG_P (src))
4371 {
4372 int dstreg = REGNO (dst);
4373 int srcreg = REGNO (src);
4374
4375 /* Ensure the second source not overwritten. */
4376 if (srcreg + 1 == dstreg)
4377 return "mov\t%R0, %R1\n\tmov\t%0, %1";
4378 else
4379 return "mov\t%0, %1\n\tmov\t%R0, %R1";
4380 }
4381 else if (GET_CODE (src) == MEM)
4382 {
4383 rtx memexp = XEXP (src, 0);
4384 int dstreg = REGNO (dst);
4385 int basereg = -1;
4386 struct csky_address op0;
4387
4388 decompose_csky_address (XEXP (src, 0), &op0);
4389
4390 if (GET_CODE (memexp) == LABEL_REF
4391 || (GET_CODE (memexp) == CONST
4392 && GET_CODE (XEXP (memexp, 0)) == PLUS
4393 && GET_CODE (XEXP (XEXP (memexp, 0), 0)) == LABEL_REF))
4394 return "lrw\t%0, [%1]\n\tlrw\t%R0, [%R1]";
4395 else if (GET_CODE (memexp) == REG)
4396 basereg = REGNO (memexp);
4397 else if (GET_CODE (memexp) == PLUS)
4398 {
4399 if (GET_CODE (XEXP (memexp, 0)) == REG)
4400 basereg = REGNO (XEXP (memexp, 0));
4401 else if (GET_CODE (XEXP (memexp, 1)) == REG)
4402 basereg = REGNO (XEXP (memexp, 1));
4403 else
4404 gcc_unreachable ();
4405 }
4406 else
4407 gcc_unreachable ();
4408
4409 /* FIXME length attribute is wrong here. */
4410 if (dstreg == basereg)
4411 /* Just load them in reverse order. */
4412 return "ld.w\t%R0, %R1\n\tld.w\t%0, %1";
4413 else
4414 return "ld.w\t%0, %1\n\tld.w\t%R0, %R1";
4415 }
4416 else if (GET_CODE (src) == CONST_INT || GET_CODE (src) == CONST_DOUBLE)
4417 {
4418 split_double (src, operands + 2, operands + 3);
4419
4420 if (REGNO (dst) <= 7
4421 && CSKY_CONST_OK_FOR_N (INTVAL (operands[2]) + 1))
4422 output_asm_insn ("movi\t%0, %2", operands);
4423 else
4424 output_asm_insn ("lrw\t%0, %2", operands);
4425
4426
4427 if (REGNO (dst) <= 6
4428 && CSKY_CONST_OK_FOR_N (INTVAL (operands[3]) + 1))
4429 output_asm_insn ("movi\t%R0, %3", operands);
4430 else
4431 output_asm_insn ("lrw\t%R0, %3", operands);
4432
4433 return "";
4434
4435
4436 }
4437 else
4438 gcc_unreachable ();
4439 }
4440 else if (GET_CODE (dst) == MEM && GET_CODE (src) == REG)
4441 {
4442 rtx memexp = XEXP (dst, 0);
4443 int srcreg = REGNO (src);
4444 int basereg = -1;
4445 struct csky_address op0;
4446
4447 decompose_csky_address (XEXP (dst, 0), &op0);
4448
4449 if (GET_CODE (memexp) == REG)
4450 basereg = REGNO (memexp);
4451 else if (GET_CODE (memexp) == PLUS)
4452 {
4453 if (GET_CODE (XEXP (memexp, 0)) == REG)
4454 basereg = REGNO (XEXP (memexp, 0));
4455 else if (GET_CODE (XEXP (memexp, 1)) == REG)
4456 basereg = REGNO (XEXP (memexp, 1));
4457 else
4458 gcc_unreachable ();
4459 }
4460 else
4461 gcc_unreachable ();
4462
4463 /* FIXME length attribute is wrong here. */
4464 if (srcreg == basereg)
4465 /* Just load them in reverse order. */
4466 return "st.w\t%R1, %R0\n\tst.w\t%1, %0";
4467 else
4468 return "st.w\t%1, %0\n\tst.w\t%R1, %R0";
4469 }
4470 else
4471 gcc_unreachable ();
4472 }
4473
4474 /* Split operands for an AND expression when OPERANDS[2] is a constant.
4475 Note operands[0] is marked earlyclobber in this case and can be
4476 overwritten. Return true if "DONE", false otherwise. */
4477 bool
4478 csky_split_and (rtx *operands)
4479 {
4480 HOST_WIDE_INT mask = INTVAL (operands[2]);
4481 rtx not_value = GEN_INT (~mask);
4482 int i;
4483
4484 /* All zeros or all ones can be handled by a move instruction. */
4485 if (mask == 0)
4486 {
4487 emit_move_insn (operands[0], const0_rtx);
4488 return true;
4489 }
4490 if (mask == -1)
4491 {
4492 emit_move_insn (operands[0], operands[1]);
4493 return true;
4494 }
4495
4496 /* Check for constants that can be handled directly by the 32-bit andi
4497 instruction. */
4498 if (CSKY_ISA_FEATURE (E2) && csky_arith_O_operand (operands[2], SImode))
4499 return false;
4500
4501 /* Try to transform to andni instruction. */
4502 if (CSKY_ISA_FEATURE (E2) && csky_arith_O_operand (not_value, SImode))
4503 {
4504 emit_insn (gen_cskyv2_andnsi3 (operands[0], not_value, operands[1]));
4505 return true;
4506 }
4507
4508 /* If there are only one or two 0 bits in the constant, we can
4509 replace the operation with bclri instructions on those bits.
4510 Note CK801 has only the 16-bit bclri that operates on a single
4511 register, so we must count a move if we are post-reload. */
4512 if (popcount_hwi (~mask & 0xffffffff)
4513 <= (reload_completed && !CSKY_ISA_FEATURE (E2) ? 1 : 2))
4514 {
4515 rtx input = operands[1];
4516
4517 if (!CSKY_ISA_FEATURE (E2))
4518 {
4519 emit_move_insn (operands[0], input);
4520 input = operands[0];
4521 }
4522
4523 for (i = 0; i < 32; i++)
4524 if ((mask & (1 << i)) == 0x0)
4525 {
4526 emit_insn (gen_bclri (operands[0], input, GEN_INT (i)));
4527 input = operands[0];
4528 }
4529 return true;
4530 }
4531
4532 /* If the constant mask is outside the [0, 4095] range for
4533 constraint O, or if constraint O is not allowed (ck801),
4534 maybe the constant is a contiguous bit range that we can
4535 handle by bit extract (low bits) or shifts (high bits). */
4536 for (i = (CSKY_ISA_FEATURE (E2) ? 13 : 1); i < 32; i++)
4537 {
4538 if ((((HOST_WIDE_INT) 1) << i) - 1 == mask)
4539 {
4540 if (CSKY_ISA_FEATURE (2E3))
4541 emit_insn (gen_cskyv2_extzv (operands[0], operands[1],
4542 GEN_INT (i), const0_rtx));
4543 else
4544 {
4545 rtx shift = GEN_INT (32 - i);
4546 rtx reg = (reload_completed
4547 ? operands[0] : gen_reg_rtx (SImode));
4548
4549 emit_insn (gen_ashlsi3 (reg, operands[1], shift));
4550 emit_insn (gen_lshrsi3 (operands[0], reg, shift));
4551 }
4552 return true;
4553 }
4554 else if ((((HOST_WIDE_INT) 1) << i) - 1 == ~mask)
4555 {
4556 rtx shift = GEN_INT (i);
4557 rtx reg = (reload_completed
4558 ? operands[0] : gen_reg_rtx (SImode));
4559
4560 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
4561 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
4562 return true;
4563 }
4564 }
4565
4566 /* If the constant is a negative number, it seems better to use
4567 andn and copy the NOT_VALUE to a register instead of the
4568 original value, since the NOT_VALUE is always smaller and thus
4569 more likely to be representable as a small constant.
4570 This transformation can only be done before reload because
4571 it requires a temporary. Hopefully register allocation can get
4572 rid of the extra move required for CK801. */
4573 if (!reload_completed && INTVAL (operands[2]) < 0)
4574 {
4575 rtx reg = copy_to_mode_reg (SImode, not_value);
4576
4577 if (CSKY_ISA_FEATURE (E2))
4578 emit_insn (gen_cskyv2_andnsi3 (operands[0], reg, operands[1]));
4579 else
4580 {
4581 emit_move_insn (operands[0], operands[1]);
4582 emit_insn (gen_ck801_andnsi3 (operands[0], reg, operands[0]));
4583 }
4584 return true;
4585 }
4586
4587 /* If the above ways are all not working, move the constant
4588 to a register. We can clobber operands[0] as it is
4589 marked earlyclobber in the insn constraints, but then we have to
4590 swap operands 1 and 2 to match the constraints on the 2-operand
4591 16-bit and instruction. */
4592 if (reload_completed)
4593 {
4594 emit_move_insn (operands[0], operands[2]);
4595 operands[2] = operands[1];
4596 operands[1] = operands[0];
4597 }
4598 else
4599 operands[2] = copy_to_mode_reg (SImode, operands[2]);
4600 return false;
4601 }
4602
4603 /* Split operands for an IOR expression when OPERANDS[2] is a constant.
4604 Note operands[0] is marked earlyclobber in this case and can be
4605 overwritten. Return true if "DONE", false otherwise. */
4606 bool
4607 csky_split_ior (rtx *operands)
4608 {
4609 HOST_WIDE_INT mask = INTVAL (operands[2]);
4610 int i;
4611
4612 /* All zeros or all ones can be handled by a move instruction. */
4613 if (mask == 0)
4614 {
4615 emit_move_insn (operands[0], operands[1]);
4616 return true;
4617 }
4618 if (mask == -1)
4619 {
4620 emit_move_insn (operands[0], gen_int_mode (-1, SImode));
4621 return true;
4622 }
4623
4624 /* Check for constants that can be handled directly by the 32-bit ori
4625 instruction. */
4626 if (CSKY_ISA_FEATURE (E2) && csky_literal_I_operand (operands[2], SImode))
4627 return false;
4628
4629 /* If there are only one or two 1 bits in the value, we can replace
4630 the operation with bseti instructions to set those bits.
4631 Note CK801 has only the 16-bit bclri that operates on a single
4632 register, so we must count a move if we are post-reload. */
4633 if (popcount_hwi (mask & 0xffffffff)
4634 <= (reload_completed && !CSKY_ISA_FEATURE (E2) ? 1 : 2))
4635 {
4636 rtx input = operands[1];
4637
4638 if (!CSKY_ISA_FEATURE (E2))
4639 {
4640 emit_move_insn (operands[0], input);
4641 input = operands[0];
4642 }
4643
4644 for (i = 0; i < 32; i++)
4645 if (mask & (1 << i))
4646 {
4647 emit_insn (gen_bseti (operands[0], input, GEN_INT (i)));
4648 input = operands[0];
4649 }
4650 return true;
4651 }
4652
4653 /* If the above ways are all not working, move the constant
4654 to a register. We can clobber operands[0] as it is
4655 marked earlyclobber in the insn constraints, but then we have to
4656 swap operands 1 and 2 to match the constraints on the 2-operand
4657 16-bit ior instruction. */
4658 if (reload_completed)
4659 {
4660 emit_move_insn (operands[0], operands[2]);
4661 operands[2] = operands[1];
4662 operands[1] = operands[0];
4663 }
4664 else
4665 operands[2] = copy_to_mode_reg (SImode, operands[2]);
4666 return false;
4667 }
4668
4669
4670 /* Split operands for an XOR expression when OPERANDS[2] is a constant.
4671 Note operands[0] is marked earlyclobber in this case and can be
4672 overwritten. Return true if "DONE", false otherwise. */
4673 bool
4674 csky_split_xor (rtx *operands)
4675 {
4676 HOST_WIDE_INT mask = INTVAL (operands[2]);
4677
4678 /* All zeros can be turned into move instruction. */
4679 if (mask == 0)
4680 {
4681 emit_move_insn (operands[0], operands[1]);
4682 return true;
4683 }
4684
4685 /* All ones can be turned into a bitwise not. */
4686 if (mask == -1)
4687 {
4688 if (CSKY_ISA_FEATURE (E2))
4689 emit_insn (gen_cskyv2_one_cmplsi2 (operands[0], operands[1]));
4690 else
4691 {
4692 emit_move_insn (operands[0], operands[1]);
4693 emit_insn (gen_ck801_one_cmplsi2 (operands[0], operands[0]));
4694 }
4695 return true;
4696 }
4697
4698 /* Check for constants that can be handled directly by the 32-bit xori
4699 instruction. */
4700 if (CSKY_ISA_FEATURE (E2) && csky_arith_O_operand (operands[2], SImode))
4701 return false;
4702
4703 /* If the above ways are all not working, move the constant
4704 to a register. We can clobber operands[0] as it is
4705 marked earlyclobber in the insn constraints, but then we have to
4706 swap operands 1 and 2 to match the constraints on the 2-operand
4707 16-bit ior instruction. */
4708 if (reload_completed)
4709 {
4710 emit_move_insn (operands[0], operands[2]);
4711 operands[2] = operands[1];
4712 operands[1] = operands[0];
4713 }
4714 else
4715 operands[2] = copy_to_mode_reg (SImode, operands[2]);
4716 return false;
4717 }
4718
4719
4720 /* Return true if X is an address form involving a symbol or label ref. */
4721 bool
4722 csky_symbolic_address_p (rtx x)
4723 {
4724 switch (GET_CODE (x))
4725 {
4726 case SYMBOL_REF:
4727 case LABEL_REF:
4728 return 1;
4729 case CONST:
4730 x = XEXP (x, 0);
4731 return ((GET_CODE (XEXP (x, 0)) == SYMBOL_REF
4732 || GET_CODE (XEXP (x, 0)) == LABEL_REF)
4733 && GET_CODE (XEXP (x, 1)) == CONST_INT);
4734 default:
4735 return 0;
4736 }
4737 }
4738
4739
4740 /* Emit a comparison instruction.
4741 Return true if an inverted comparison is generated. */
4742
4743 bool
4744 csky_emit_compare (enum rtx_code code, rtx op0, rtx op1)
4745 {
4746 bool invert;
4747 rtx cc_reg = gen_rtx_REG (CCmode, CSKY_CC_REGNUM);
4748
4749 if (GET_CODE (op1) == CONST_INT)
4750 {
4751 HOST_WIDE_INT val = INTVAL (op1);
4752
4753 switch (code)
4754 {
4755 case GTU:
4756 /* Unsigned (GTU 0) is the same as (NE 0); everything else is
4757 converted below to LEU (reversed cmphs). */
4758 if (val == 0)
4759 code = NE;
4760 /* Check whether (GTU A imm) can become (GEU A imm + 1). */
4761 else if (TARGET_MINI_REGISTERS
4762 ? CSKY_CONST_OK_FOR_J (val + 1)
4763 : CSKY_CONST_OK_FOR_Uk (val + 1))
4764 {
4765 op1 = GEN_INT (val + 1);
4766 code = GEU;
4767 }
4768 break;
4769 /* Check whether (LE A imm) can become (LT A imm + 1),
4770 or (GT A imm) can become (GE A imm + 1). */
4771 case GT:
4772 case LE:
4773 if (TARGET_MINI_REGISTERS
4774 ? CSKY_CONST_OK_FOR_J (val + 1)
4775 : CSKY_CONST_OK_FOR_Uk (val + 1))
4776 {
4777 op1 = GEN_INT (val + 1);
4778 code = code == LE ? LT : GE;
4779 }
4780 break;
4781
4782 default:
4783 break;
4784 }
4785 }
4786
4787 if (CONSTANT_P (op1) && GET_CODE (op1) != CONST_INT)
4788 op1 = force_reg (GET_MODE (op1), op1);
4789
4790 /* cmpnei: 0-31 (K immediate)
4791 ti: 1-32 (J immediate, 0 using btsti x,31). */
4792 invert = false;
4793 switch (code)
4794 {
4795 /* Use inverted condition, cmpne. */
4796 case EQ:
4797 code = NE;
4798 invert = true;
4799 /* Fall through. */
4800 /* Use normal condition, cmpne. */
4801 case NE:
4802 if (GET_CODE (op1) == CONST_INT
4803 && (TARGET_MINI_REGISTERS
4804 ? !csky_literal_K_operand (op1, SImode)
4805 : !csky_literal_I_operand (op1, SImode)))
4806 op1 = force_reg (SImode, op1);
4807 break;
4808
4809 /* Use inverted condition, reversed cmplt. */
4810 case LE:
4811 code = GT;
4812 invert = true;
4813 /* Fall through. */
4814 /* Use normal condition, reversed cmplt. */
4815 case GT:
4816 if (GET_CODE (op1) == CONST_INT)
4817 op1 = force_reg (SImode, op1);
4818 break;
4819
4820 /* Use inverted condition, cmplt. */
4821 case GE:
4822 code = LT;
4823 invert = true;
4824 /* Fall through. */
4825 /* Use normal condition, cmplt. */
4826 case LT:
4827 /* covered by btsti x,31. */
4828 if (GET_CODE (op1) == CONST_INT && INTVAL (op1) != 0
4829 && (TARGET_MINI_REGISTERS
4830 ? !csky_literal_J_operand (op1, SImode)
4831 : !csky_literal_Uk_operand (op1, SImode)))
4832 op1 = force_reg (SImode, op1);
4833 break;
4834
4835 /* Use inverted condition, cmple. */
4836 case GTU:
4837 /* We coped with unsigned > 0 above. */
4838 gcc_assert (GET_CODE (op1) != CONST_INT || INTVAL (op1) != 0);
4839 code = LEU;
4840 invert = true;
4841 /* Fall through. */
4842 /* Use normal condition, reversed cmphs. */
4843 case LEU:
4844 if (GET_CODE (op1) == CONST_INT && INTVAL (op1) != 0)
4845 op1 = force_reg (SImode, op1);
4846 break;
4847
4848 /* Use inverted condition, cmphs. */
4849 case LTU:
4850 code = GEU;
4851 invert = true;
4852 /* Fall through. */
4853 /* Use normal condition, cmphs. */
4854 case GEU:
4855 if (GET_CODE (op1) == CONST_INT && INTVAL (op1) != 0
4856 && (TARGET_MINI_REGISTERS
4857 ? !csky_literal_J_operand (op1, SImode)
4858 : !csky_literal_Uk_operand (op1, SImode)))
4859 op1 = force_reg (SImode, op1);
4860 break;
4861
4862 default:
4863 break;
4864 }
4865
4866 emit_insn (gen_rtx_SET (cc_reg,
4867 gen_rtx_fmt_ee (code, CCmode, op0, op1)));
4868 return invert;
4869 }
4870
4871 /* Return true if push/pop can be used to save/restore all the registers
4872 indicated by MASK. We currently don't attempt to handle situations where
4873 some of the registers could be handled by push/pop and others saved and
4874 restored individually. */
4875
4876 static bool
4877 csky_can_use_pushpop (unsigned int mask)
4878 {
4879 int i;
4880 int end_reg;
4881
4882 if (!TARGET_PUSHPOP)
4883 return false;
4884
4885 if (mask == 0)
4886 return false;
4887
4888 /* Regs 0-3, 12-14, 18-27, 29-31 cannot be in the mask. */
4889 if (mask & 0xeffc700f)
4890 return false;
4891
4892 /* Regs in the range r4-r11 must be contiguous. */
4893 for (end_reg = 0, i = 11; i >= 4; i--)
4894 {
4895 if (!end_reg && (mask & (1 << i)))
4896 end_reg = i;
4897 if (end_reg && !(mask & (1 << i)))
4898 return false;
4899 }
4900
4901 /* Likewise for regs in the range r16-r17. */
4902 for (end_reg = 0, i = 17; i >= 16; i--)
4903 {
4904 if (!end_reg && (mask & (1 << i)))
4905 end_reg = i;
4906 if (end_reg && !(mask & (1 << i)))
4907 return false;
4908 }
4909
4910 return true;
4911 }
4912
4913
4914 /* Return true if store/load multiple instructions can be used to
4915 save/restore at least some of the registers indicated by MASK.
4916 Unlike the push/pop case, this does handle partial ranges.
4917 Set *BR and *ER to the beginning and end (respectively) of the
4918 register range that can be handled. */
4919
4920 static bool
4921 csky_can_use_ldstm (int mask, int *br, int *er)
4922 {
4923 int regno;
4924 int begin_reg = 0, end_reg = 0;
4925 int count = 0;
4926
4927 if (!TARGET_MULTIPLE_STLD)
4928 return false;
4929
4930 /* We'll only handle registers in the range 4-11, the contiguous range
4931 of caller-saved registers. Higher-numbered registers are handled
4932 individually in addition to this, but we'll give up on doing ldstm
4933 entirely if we need to save/restore the low-numbered EH registers. */
4934 if (mask & 0xf)
4935 return false;
4936
4937 for (regno = 4; regno <= 11; regno++)
4938 {
4939 if (mask & 1 << regno)
4940 {
4941 if (!begin_reg)
4942 begin_reg = regno;
4943 end_reg = regno;
4944 count++;
4945 }
4946 else if (begin_reg)
4947 break;
4948 }
4949
4950 if (count >= CSKY_MIN_MULTIPLE_STLD && count <= CSKY_MAX_MULTIPLE_STLD)
4951 {
4952 if (br)
4953 *br = begin_reg;
4954 if (er)
4955 *er = end_reg;
4956 return true;
4957 }
4958 return false;
4959 }
4960
4961
4962 const char *
4963 csky_output_return_instruction (void)
4964 {
4965 unsigned long func_type = get_csky_current_func_type ();
4966
4967 if (CSKY_FUNCTION_IS_NAKED (func_type))
4968 return "";
4969 if (CSKY_FUNCTION_IS_INTERRUPT (func_type))
4970 return "ipop\n\tnir\n";
4971 else
4972 return "rts\n";
4973 }
4974
4975
4976 /* Adjust the stack pointer by OFFSET bytes. OFFSET is negative if this
4977 is in the prologue, positive if in the epilogue. This may require
4978 multiple instructions and/or use of CSKY_STACKADJUST_REGNUM as
4979 a scratch register. Emit CFA notes as appropriate. */
4980 static void
4981 expand_csky_stack_adjust (int offset)
4982 {
4983 rtx set;
4984 rtx_insn *insn;
4985 int size = (offset > 0 ? offset : -offset);
4986
4987 if (offset == 0)
4988 return;
4989
4990 /* If OFFSET is too large for addi/subi, load it into
4991 CSKY_STACKADJUST_REGNUM and use a register add/sub instead.
4992 This case is not mentioned in the ABI documentation, but it is
4993 supported by GDB prologue analysis provided that the instruction(s)
4994 to initialize CSKY_STACKADJUST_REGNUM appear directly before
4995 the sub. Depending on the value of OFFSET, this might be a
4996 lrw instruction or the "tricks" used by csky_output_inline_const to
4997 encode special-case integer constants. */
4998 if (size > CSKY_MAX_SP_ADJUST * 2)
4999 {
5000 rtx tmp, dwarf;
5001
5002 /* We should have reserved the scratch register already in
5003 csky_layout_stack_frame. */
5004 gcc_assert (cfun->machine->reg_size != 0
5005 && (cfun->machine->reg_mask
5006 & (1 << CSKY_STACKADJUST_REGNUM)));
5007
5008 /* Prevent the optimizer from reordering these instructions to
5009 keep GDB happy. */
5010 if (!flag_sched_prolog)
5011 emit_insn (gen_blockage ());
5012
5013 tmp = gen_rtx_REG (SImode, CSKY_STACKADJUST_REGNUM);
5014 emit_move_insn (tmp, GEN_INT (size));
5015
5016 if (offset > 0)
5017 set = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp);
5018 else
5019 set = gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp);
5020 insn = emit_insn (set);
5021 RTX_FRAME_RELATED_P (insn) = 1;
5022 dwarf = gen_rtx_SET (stack_pointer_rtx,
5023 plus_constant (Pmode, stack_pointer_rtx, offset));
5024 add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
5025
5026 /* More make GDB happy. */
5027 if (!flag_sched_prolog)
5028 emit_insn (gen_blockage ());
5029 }
5030
5031 /* Use one or two addi or subi insns to adjust stack. */
5032 else
5033 while (size)
5034 {
5035 int delta = (size > CSKY_MAX_SP_ADJUST
5036 ? CSKY_MAX_SP_ADJUST : size);
5037
5038 if (offset > 0)
5039 set = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
5040 GEN_INT (delta));
5041 else
5042 set = gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
5043 GEN_INT (delta));
5044 insn = emit_insn (set);
5045 RTX_FRAME_RELATED_P (insn) = 1;
5046 size -= delta;
5047 }
5048 }
5049
5050
5051 /* Generate and emit an insn that we will recognize as a push_multi.
5052 Unfortunately, since this insn does not reflect very well the actual
5053 semantics of the operation, we need to annotate the insn for the benefit
5054 of DWARF2 frame unwind information. DWARF_REGS_MASK is a subset of
5055 MASK for registers that should be annotated for DWARF2 frame unwind
5056 information. */
5057
5058 static rtx
5059 emit_csky_regs_push (unsigned long mask)
5060 {
5061 int num_regs = 0;
5062 int i, j;
5063 rtx par;
5064 rtx dwarf;
5065 rtx tmp;
5066 int dwarf_par_index;
5067
5068 for (i = 0; i < CSKY_NGPR_REGS; i++)
5069 {
5070 if (mask & (1 << i))
5071 num_regs++;
5072 }
5073
5074 /* The reg range for push is:r4-r11,r15-r17,r28. */
5075 gcc_assert (num_regs && num_regs <= 12);
5076
5077 /* For the body of the insn we are going to generate an UNSPEC in
5078 parallel with several USEs. This allows the insn to be recognized
5079 by the push_multi pattern in the csky.md file.
5080
5081 The body of the insn looks something like this:
5082
5083 (parallel [
5084 (set (mem:BLK (pre_modify:SI (reg:SI sp)
5085 (const_int:SI <num>)))
5086 (unspec:BLK [(reg:SI r4)] UNSPEC_PUSHPOP_MULT))
5087 (use (reg:SI XX))
5088 (use (reg:SI YY))
5089 ...
5090 ])
5091
5092 For the frame note however, we try to be more explicit and actually
5093 show each register being stored into the stack frame, plus a (single)
5094 decrement of the stack pointer. We do it this way in order to be
5095 friendly to the stack unwinding code, which only wants to see a single
5096 stack decrement per instruction. The RTL we generate for the note looks
5097 something like this:
5098
5099 (sequence [
5100 (set (reg:SI sp) (plus:SI (reg:SI sp) (const_int -20)))
5101 (set (mem:SI (reg:SI sp)) (reg:SI r4))
5102 (set (mem:SI (plus:SI (reg:SI sp) (const_int 4))) (reg:SI XX))
5103 (set (mem:SI (plus:SI (reg:SI sp) (const_int 8))) (reg:SI YY))
5104 ...
5105 ])
5106
5107 FIXME:: In an ideal world the PRE_MODIFY would not exist and
5108 instead we'd have a parallel expression detailing all
5109 the stores to the various memory addresses so that debug
5110 information is more up-to-date. Remember however while writing
5111 this to take care of the constraints with the push instruction.
5112
5113 Note also that this has to be taken care of for the VFP registers.
5114
5115 For more see PR43399. */
5116
5117 par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num_regs));
5118 dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (num_regs + 1));
5119 dwarf_par_index = 1;
5120
5121 for (i = 0; i < CSKY_NGPR_REGS; i++)
5122 if (mask & (1 << i))
5123 {
5124 rtx reg = gen_rtx_REG (SImode, i);
5125 rtx addr = plus_constant (Pmode, stack_pointer_rtx, -4 * num_regs);
5126 tmp = gen_frame_mem (BLKmode,
5127 gen_rtx_PRE_MODIFY (Pmode,
5128 stack_pointer_rtx, addr));
5129 XVECEXP (par, 0, 0)
5130 = gen_rtx_SET (tmp,
5131 gen_rtx_UNSPEC (BLKmode,
5132 gen_rtvec (1, reg),
5133 UNSPEC_PUSHPOP_MULT));
5134 tmp = gen_rtx_SET (gen_frame_mem (SImode, stack_pointer_rtx),
5135 reg);
5136 RTX_FRAME_RELATED_P (tmp) = 1;
5137 XVECEXP (dwarf, 0, dwarf_par_index++) = tmp;
5138
5139 break;
5140 }
5141
5142 for (j = 1, i++; j < num_regs; i++)
5143 if (mask & (1 << i))
5144 {
5145 rtx reg = gen_rtx_REG (SImode, i);
5146 rtx addr = plus_constant (Pmode, stack_pointer_rtx, 4 * j);
5147 tmp = gen_rtx_SET (gen_frame_mem (SImode, addr), reg);
5148 RTX_FRAME_RELATED_P (tmp) = 1;
5149 XVECEXP (par, 0, j) = gen_rtx_USE (VOIDmode, reg);
5150 XVECEXP (dwarf, 0, dwarf_par_index++) = tmp;
5151 j++;
5152 }
5153
5154 par = emit_insn (par);
5155
5156 tmp = gen_rtx_SET (stack_pointer_rtx,
5157 plus_constant (Pmode, stack_pointer_rtx, -4 * num_regs));
5158 RTX_FRAME_RELATED_P (tmp) = 1;
5159 XVECEXP (dwarf, 0, 0) = tmp;
5160
5161 add_reg_note (par, REG_FRAME_RELATED_EXPR, dwarf);
5162 RTX_FRAME_RELATED_P (par) = 1;
5163
5164 return par;
5165 }
5166
5167
5168 /* Generate and emit an insn pattern that we will recognize as a pop_multi.
5169 SAVED_REGS_MASK shows which registers need to be restored.
5170
5171 Unfortunately, since this insn does not reflect very well the actual
5172 semantics of the operation, we need to annotate the insn for the benefit
5173 of DWARF2 frame unwind information. */
5174
5175 static void
5176 emit_csky_regs_pop (unsigned long mask)
5177 {
5178 int num_regs = 0;
5179 int i, j;
5180 rtx par;
5181
5182 for (i = 0; i < CSKY_NGPR_REGS; i++)
5183 if (mask & (1 << i))
5184 num_regs++;
5185
5186 /* The reg range for push is:r4-r11,r15-r17,r28. */
5187 gcc_assert (num_regs && num_regs <= 12);
5188
5189 /* The first element is (return),
5190 the second element is
5191 (set (reg:SI 'first reg number')
5192 (unspec:SI [(mem)] UNSPEC_PUSHPOP_MULT),
5193 the rest elements is (use (reg:SI 'rest reg number')),
5194 so the length should be number of register to be poped
5195 plus one. */
5196 par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num_regs + 1));
5197
5198 XVECEXP (par, 0, 0) = ret_rtx;
5199
5200 for (i = 0; i < CSKY_NGPR_REGS; i++)
5201 if (mask & (1 << i))
5202 {
5203 rtx reg = gen_rtx_REG (SImode, i);
5204 rtx addr = plus_constant (Pmode, stack_pointer_rtx, 4 * num_regs);
5205 rtx tmp = gen_frame_mem (SImode,
5206 gen_rtx_POST_MODIFY (Pmode,
5207 stack_pointer_rtx, addr));
5208 XVECEXP (par, 0, 1)
5209 = gen_rtx_SET (reg,
5210 gen_rtx_UNSPEC (SImode,
5211 gen_rtvec (1, tmp),
5212 UNSPEC_PUSHPOP_MULT));
5213 break;
5214 }
5215
5216 for (j = 2, i++; j < (num_regs + 1); i++)
5217 if (mask & (1 << i))
5218 {
5219 rtx reg = gen_rtx_REG (SImode, i);
5220 XVECEXP (par, 0, j) = gen_rtx_USE (VOIDmode, reg);
5221 j++;
5222 }
5223
5224 par = emit_jump_insn (par);
5225 }
5226
5227
5228 /* Generate the function prologue. */
5229
5230 void
5231 csky_expand_prologue (void)
5232 {
5233 rtx_insn *insn;
5234 unsigned long func_type = get_csky_current_func_type ();
5235 unsigned int reg_mask;
5236 int reg_size;
5237
5238 if (CSKY_FUNCTION_IS_NAKED (func_type))
5239 {
5240 if (flag_stack_usage_info)
5241 current_function_static_stack_size = 0;
5242 return;
5243 }
5244
5245 csky_layout_stack_frame ();
5246 reg_mask = cfun->machine->reg_mask;
5247 reg_size = cfun->machine->reg_size;
5248
5249 /* Adjust stack pointer past argument overflow area. */
5250 if (cfun->machine->arg_size != 0)
5251 {
5252 int offset = cfun->machine->arg_size;
5253 expand_csky_stack_adjust (- offset);
5254
5255 /* If we have a parameter passed partially in regs and partially
5256 in memory, the registers will have been stored to memory already
5257 in function.c. So we only need to copy varargs from registers
5258 to stack. */
5259 if (cfun->machine->uses_anonymous_args)
5260 {
5261 int rn = CSKY_FIRST_PARM_REGNUM + CSKY_NPARM_REGS - 1;
5262 for (offset -= 4; offset >= 0; offset -= 4, rn--)
5263 {
5264 rtx dst = gen_frame_mem (SImode,
5265 plus_constant (Pmode,
5266 stack_pointer_rtx,
5267 offset));
5268 insn = emit_move_insn (dst, gen_rtx_REG (SImode, rn));
5269 RTX_FRAME_RELATED_P (insn) = 1;
5270 }
5271 }
5272 }
5273
5274 /* Push caller-saved registers to stack. */
5275 if (csky_can_use_pushpop (reg_mask))
5276 emit_csky_regs_push (reg_mask);
5277 else if (reg_size)
5278 {
5279 int sreg = -1, ereg = -1;
5280 bool stm_p = csky_can_use_ldstm (reg_mask, &sreg, &ereg);
5281 int stm_regs = stm_p ? ereg - sreg + 1 : 0;
5282 int stm_size = stm_regs * 4;
5283
5284 /* First adjust the SP to the low end of the register save area. */
5285 expand_csky_stack_adjust (- reg_size);
5286
5287 /* Emit individual register saves. Even if we are going to emit an
5288 stm, we may need to save individual registers above that too. */
5289 if (reg_size > stm_size)
5290 {
5291 int offset = reg_size - 4;
5292 int regno = 31;
5293 for ( ; regno > ereg; regno--)
5294 if (reg_mask & (1 << regno))
5295 {
5296 rtx dst = gen_rtx_MEM (SImode,
5297 plus_constant (Pmode,
5298 stack_pointer_rtx,
5299 offset));
5300 rtx insn = emit_insn (gen_movsi (dst,
5301 gen_rtx_REG (SImode, regno)));
5302 RTX_FRAME_RELATED_P (insn) = 1;
5303 if (offset == stm_size)
5304 break;
5305 offset -= 4;
5306 }
5307 }
5308
5309 /* If possible, emit a stm to do a bulk store of sequential
5310 registers to the stack. Note that it is an error in the ABI
5311 documentation that it doesn't list stm as a valid prologue
5312 instruction. */
5313 if (stm_p)
5314 {
5315 rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (stm_regs));
5316 int regno, slot;
5317 for (regno = sreg, slot = 0; regno <= ereg; regno++, slot++)
5318 {
5319 rtx reg = gen_rtx_REG (SImode, regno);
5320 rtx addr = plus_constant (Pmode, stack_pointer_rtx, slot * 4);
5321 rtx set = gen_rtx_SET (gen_frame_mem (SImode, addr), reg);
5322 RTX_FRAME_RELATED_P (set) = 1;
5323 XVECEXP (par, 0, slot) = set;
5324 }
5325 insn = emit_insn (par);
5326 RTX_FRAME_RELATED_P (insn) = 1;
5327 }
5328 }
5329
5330 /* Initialize hard frame pointer, if necessary. It points at the base
5331 of the register save area. */
5332 if (frame_pointer_needed)
5333 {
5334 insn = emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
5335 RTX_FRAME_RELATED_P (insn) = 1;
5336 }
5337
5338 /* Reserve stack space for locals and outgoing args. */
5339 expand_csky_stack_adjust (- cfun->machine->reg_offset);
5340
5341 /* Put the GOT address in reg_gb for PIC, using R13 as a scratch.
5342 See section 4.7.1 in the ABI documentation,
5343 "Function Prologue for PIC". */
5344 if (flag_pic && (reg_mask & (1 << PIC_OFFSET_TABLE_REGNUM)))
5345 {
5346 rtx l1 = gen_label_rtx ();
5347 rtx grs_label = gen_rtx_LABEL_REF (SImode, l1);
5348 rtx reg_gb = gen_rtx_REG (SImode, PIC_OFFSET_TABLE_REGNUM);
5349 rtx reg_temp = gen_rtx_REG (SImode, 13);
5350
5351 rtx tmp0_unspec = gen_rtx_UNSPEC (Pmode,
5352 gen_rtvec (1, grs_label),
5353 UNSPEC_PIC_SYMBOL_GOTPC_GRS);
5354 rtx tmp1_unspec = gen_rtx_UNSPEC (Pmode,
5355 gen_rtvec (1, grs_label),
5356 UNSPEC_PIC_SYMBOL_GOTPC);
5357
5358 emit_insn (gen_prologue_get_pc (tmp0_unspec));
5359 emit_move_insn (reg_temp, tmp1_unspec);
5360 emit_insn (gen_addsi3 (reg_gb, reg_gb, reg_temp));
5361 }
5362
5363 if (flag_stack_usage_info)
5364 current_function_static_stack_size = cfun->machine->frame_size;
5365
5366 if (!flag_sched_prolog)
5367 emit_insn (gen_blockage ());
5368 }
5369
5370 void
5371 csky_expand_epilogue (void)
5372 {
5373 unsigned long func_type = get_csky_current_func_type ();
5374 unsigned int reg_mask;
5375 int reg_size;
5376 int adjust;
5377 rtx_insn *insn;
5378
5379 if (!flag_sched_prolog)
5380 emit_insn (gen_blockage ());
5381
5382 if (CSKY_FUNCTION_IS_NAKED (func_type))
5383 {
5384 emit_jump_insn (gen_simple_return ());
5385 return;
5386 }
5387
5388 /* Get the frame information. */
5389 csky_layout_stack_frame ();
5390 reg_mask = cfun->machine->reg_mask;
5391 reg_size = cfun->machine->reg_size;
5392 adjust = reg_size + cfun->machine->arg_size;
5393
5394 /* Restore the SP to the base of the register save area. */
5395 if (frame_pointer_needed)
5396 {
5397 insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
5398 RTX_FRAME_RELATED_P (insn) = 1;
5399 }
5400 else
5401 expand_csky_stack_adjust (cfun->machine->reg_offset);
5402
5403 /* Restore the callee-saved registers. */
5404 if (csky_can_use_pushpop (reg_mask)
5405 && cfun->machine->arg_size == 0
5406 && !CSKY_FUNCTION_IS_INTERRUPT (func_type)
5407 && !crtl->calls_eh_return)
5408 {
5409 /* Pop includes an implicit return, so we are done. */
5410 emit_csky_regs_pop (reg_mask);
5411 return;
5412 }
5413 else if (reg_size)
5414 {
5415 int sreg = -1, ereg = -1;
5416 bool ldm_p = csky_can_use_ldstm (reg_mask, &sreg, &ereg);
5417 int ldm_regs = ldm_p ? ereg - sreg + 1 : 0;
5418 int ldm_size = ldm_regs * 4;
5419
5420 /* Emit individual register loads. Even if we are going to emit an
5421 ldm, we may need to load individual registers above that too. */
5422 if (reg_size > ldm_size)
5423 {
5424 int offset = reg_size - 4;
5425 int regno = 31;
5426 for ( ; regno > ereg; regno--)
5427 if (reg_mask & (1 << regno))
5428 {
5429 rtx src = gen_frame_mem (SImode,
5430 plus_constant (Pmode,
5431 stack_pointer_rtx,
5432 offset));
5433 rtx reg = gen_rtx_REG (SImode, regno);
5434 insn = emit_move_insn (reg, src);
5435 RTX_FRAME_RELATED_P (insn) = 1;
5436 add_reg_note (insn, REG_CFA_RESTORE, reg);
5437 if (offset == ldm_size)
5438 break;
5439 offset -= 4;
5440 }
5441 }
5442
5443 /* If possible, emit a ldm to do a bulk load of sequential
5444 registers from the stack. */
5445 if (ldm_p)
5446 {
5447 rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (ldm_regs));
5448 int regno, slot;
5449 for (regno = sreg, slot = 0; regno <= ereg; regno++, slot++)
5450 {
5451 rtx reg = gen_rtx_REG (SImode, regno);
5452 rtx addr = plus_constant (Pmode, stack_pointer_rtx, slot * 4);
5453 rtx set = gen_rtx_SET (reg, gen_frame_mem (SImode, addr));
5454 XVECEXP (par, 0, slot) = set;
5455 }
5456 insn = emit_insn (par);
5457 RTX_FRAME_RELATED_P (insn) = 1;
5458 for (regno = sreg; regno <= ereg; regno++)
5459 {
5460 rtx reg = gen_rtx_REG (SImode, regno);
5461 add_reg_note (insn, REG_CFA_RESTORE, reg);
5462 }
5463 }
5464 }
5465
5466 /* Emit the final stack pointer adjustment to deallocate the saved
5467 registers and incoming argument area. */
5468 expand_csky_stack_adjust (adjust);
5469
5470 /* Extra stack adjustment for exception handler return. */
5471 if (crtl->calls_eh_return)
5472 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
5473 EH_RETURN_STACKADJ_RTX));
5474
5475 /* Now we can return. */
5476 emit_jump_insn (gen_simple_return ());
5477 }
5478
5479
5480 static void
5481 csky_output_function_prologue (FILE *f)
5482 {
5483 unsigned long func_type = get_csky_current_func_type ();
5484
5485 switch ((int) CSKY_FUNCTION_TYPE (func_type))
5486 {
5487 default:
5488 case CSKY_FT_NORMAL:
5489 break;
5490 case CSKY_FT_INTERRUPT:
5491 {
5492 asm_fprintf (f, "\t# Interrupt Service Routine.\n");
5493 asm_fprintf (f, "\tnie\n\tipush\n");
5494 break;
5495 }
5496 case CSKY_FT_FIQ:
5497 asm_fprintf (f, "\t# Fast Interrupt Service Routine.\n");
5498 break;
5499 case CSKY_FT_EXCEPTION:
5500 asm_fprintf (f, "\t# CSKY Exception Handler.\n");
5501 break;
5502 case CSKY_FT_NAKED:
5503 asm_fprintf (f, "\t# Naked Function: prologue and epilogue \
5504 provided by programmer.\n");
5505 return;
5506 }
5507
5508 csky_layout_stack_frame ();
5509
5510 /* Generate .stack_size function-name, size for callgraph;
5511 the default stack size is 0. */
5512 if (TARGET_STACK_SIZE && cfun->machine->frame_size > 0)
5513 {
5514 gcc_assert (current_function_decl != NULL);
5515 const char *func_name =
5516 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
5517 if (func_name[0] == '*')
5518 asm_fprintf (f, "\t.stack_size %s, %d\n",
5519 &func_name[1], cfun->machine->frame_size);
5520 else
5521 asm_fprintf (f, "\t.stack_size %s, %d\n",
5522 func_name, cfun->machine->frame_size);
5523 }
5524 }
5525
5526
5527 static void
5528 csky_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED)
5529 {
5530
5531 }
5532
5533
5534 /* Helper for csky_eh_return splitter: store the call frame exception
5535 handler address in lr. */
5536 void
5537 csky_set_eh_return_address (rtx source, rtx scratch)
5538 {
5539 HOST_WIDE_INT delta = 0;
5540 rtx basereg, addr;
5541 unsigned int reg_mask;
5542
5543 csky_layout_stack_frame ();
5544 reg_mask = cfun->machine->reg_mask;
5545
5546 if (reg_mask & (1 << CSKY_LR_REGNUM))
5547 {
5548 /* Find LR in the stack frame. */
5549 int i = 0;
5550
5551 if (frame_pointer_needed)
5552 {
5553 basereg = frame_pointer_rtx;
5554 delta = 0;
5555 }
5556 else
5557 {
5558 basereg = stack_pointer_rtx;
5559 delta = cfun->machine->reg_offset;
5560 }
5561
5562 /* At this point, (basereg + delta) points at the low end of
5563 the reg save area. Regs are saved sequentially from low
5564 to high from this address. */
5565 for (i = 0; i < CSKY_LR_REGNUM; i++)
5566 if (reg_mask & (1 << i))
5567 delta += 4;
5568
5569 if ((CSKY_TARGET_ARCH (CK801) && delta >= CSKY_LD16_MAX_OFFSET (Pmode))
5570 || delta >= CSKY_LD32_MAX_OFFSET (Pmode))
5571 {
5572 emit_insn (gen_movsi (scratch, GEN_INT (delta)));
5573 emit_insn (gen_addsi3 (scratch, scratch, basereg));
5574 addr = scratch;
5575 }
5576 else
5577 addr = plus_constant (Pmode, basereg, delta);
5578 emit_move_insn (gen_frame_mem (Pmode, addr), source);
5579 }
5580 else
5581 emit_move_insn (gen_rtx_REG (Pmode, CSKY_LR_REGNUM), source);
5582 }
5583
5584 /* Return TRUE if X references a SYMBOL_REF. */
5585
5586 bool
5587 csky_symbol_mentioned_p (rtx x)
5588 {
5589 const char *fmt;
5590 int i;
5591
5592 if (GET_CODE (x) == SYMBOL_REF)
5593 return true;
5594
5595 fmt = GET_RTX_FORMAT (GET_CODE (x));
5596 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
5597 {
5598 if (fmt[i] == 'E')
5599 {
5600 int j;
5601
5602 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
5603 if (csky_symbol_mentioned_p (XVECEXP (x, i, j)))
5604 return true;
5605 }
5606 else if (fmt[i] == 'e' && csky_symbol_mentioned_p (XEXP (x, i)))
5607 return true;
5608 }
5609 return false;
5610 }
5611
5612
5613 /* Return TRUE if X references a LABEL_REF. */
5614
5615 bool
5616 csky_label_mentioned_p (rtx x)
5617 {
5618 const char *fmt;
5619 int i;
5620
5621 if (GET_CODE (x) == LABEL_REF)
5622 return true;
5623
5624 fmt = GET_RTX_FORMAT (GET_CODE (x));
5625 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
5626 {
5627 if (fmt[i] == 'E')
5628 {
5629 int j;
5630
5631 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
5632 if (csky_label_mentioned_p (XVECEXP (x, i, j)))
5633 return true;
5634 }
5635 else if (fmt[i] == 'e' && csky_label_mentioned_p (XEXP (x, i)))
5636 return true;
5637 }
5638
5639 return false;
5640 }
5641
5642
5643 static bool
5644 tls_unspec_mentioned_p (rtx x)
5645 {
5646 switch (GET_CODE (x))
5647 {
5648 case CONST:
5649 return tls_unspec_mentioned_p (XEXP (x, 0));
5650
5651 case UNSPEC:
5652 if (XINT (x, 1) == UNSPEC_TLS)
5653 return true;
5654
5655 /* Fall through. */
5656 default:
5657 return false;
5658 }
5659 }
5660
5661
5662 /* Implement LEGITIMATE_PIC_OPERAND_P. */
5663 bool
5664 csky_legitimate_pic_operand_p (rtx x)
5665 {
5666 if (tls_unspec_mentioned_p (x))
5667 return true;
5668 if (csky_symbol_mentioned_p (x) || csky_label_mentioned_p (x))
5669 return false;
5670 return true;
5671 }
5672
5673 rtx
5674 csky_legitimize_pic_address (rtx orig, rtx reg, bool gotrel_p)
5675 {
5676 rtx pic_reg = gen_rtx_REG (SImode, PIC_OFFSET_TABLE_REGNUM);
5677 bool optimize_p = false;
5678
5679 if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
5680 {
5681 rtx pic_ref, address, rtx_tmp;
5682 rtx insn;
5683 rtx pic_reg = gen_rtx_REG (SImode, PIC_OFFSET_TABLE_REGNUM);
5684 int subregs = 0;
5685
5686 if (reg == 0)
5687 {
5688 gcc_assert (can_create_pseudo_p ());
5689 reg = gen_reg_rtx (Pmode);
5690 subregs = 1;
5691 }
5692
5693 if (subregs)
5694 address = gen_reg_rtx (Pmode);
5695 else
5696 address = reg;
5697
5698 if (GET_CODE (orig) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (orig))
5699 {
5700 /* When gotrel_p generate sym@GOT, otherwise generate sym@PLT. */
5701 rtx_tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig),
5702 (gotrel_p
5703 ? UNSPEC_PIC_SYMBOL_GOT
5704 : UNSPEC_PIC_SYMBOL_PLT));
5705 optimize_p = gotrel_p;
5706 if (flag_pic != 1)
5707 {
5708 emit_move_insn (address, rtx_tmp);
5709 rtx_tmp = gen_rtx_MULT (Pmode, address, GEN_INT (1));
5710 }
5711 pic_ref = gen_const_mem (Pmode,
5712 gen_rtx_PLUS (Pmode, pic_reg, rtx_tmp));
5713 }
5714 else
5715 {
5716 /* bsr symbol */
5717 if (flag_pic == 1 && !gotrel_p)
5718 {
5719 pic_ref = gen_rtx_UNSPEC (Pmode,
5720 gen_rtvec (1, orig),
5721 UNSPEC_PIC_SYMBOL_BSR);
5722 return pic_ref;
5723 }
5724 /* grs rx, symbol */
5725 else if (flag_pic == 1 && (GET_CODE (orig) == SYMBOL_REF)
5726 && SYMBOL_REF_FUNCTION_P (orig))
5727 {
5728 pic_ref = gen_rtx_UNSPEC (Pmode,
5729 gen_rtvec (1, orig),
5730 UNSPEC_PIC_SYMBOL_GRS);
5731 return pic_ref;
5732 }
5733 /* lrw rx, symbol@GOTOFF; add rx, rx, gb */
5734 else
5735 {
5736 rtx_tmp = gen_rtx_UNSPEC (Pmode,
5737 gen_rtvec (1, orig),
5738 UNSPEC_PIC_SYMBOL_GOTOFF);
5739 emit_move_insn (address, rtx_tmp);
5740 pic_ref = gen_rtx_PLUS (Pmode, address, pic_reg);
5741 optimize_p = true;
5742 }
5743 }
5744
5745 insn = emit_move_insn (reg, pic_ref);
5746 /* Put a REG_EQUAL note on this insn,
5747 so that it can be optimized by loop. */
5748 if (optimize_p)
5749 set_unique_reg_note (insn, REG_EQUAL, orig);
5750
5751 return reg;
5752 }
5753 else if (GET_CODE (orig) == CONST)
5754 {
5755 rtx base, offset;
5756
5757 if (GET_CODE (XEXP (orig, 0)) == PLUS
5758 && XEXP (XEXP (orig, 0), 1) == pic_reg)
5759 return orig;
5760
5761 if (reg == 0)
5762 {
5763 gcc_assert (can_create_pseudo_p ());
5764 reg = gen_reg_rtx (Pmode);
5765 }
5766
5767 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
5768
5769 base = csky_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
5770 reg, gotrel_p);
5771 offset = csky_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
5772 base == reg ? 0 : reg, gotrel_p);
5773
5774 if (GET_CODE (offset) == CONST_INT)
5775 return plus_constant (Pmode, base, INTVAL (offset));
5776
5777 return gen_rtx_PLUS (Pmode, base, offset);
5778 }
5779
5780 return orig;
5781 }
5782
5783
5784 /* Functions to output assembly code for a function call. */
5785
5786 char *
5787 csky_output_call (rtx *operands, int index)
5788 {
5789 static char buffer[20];
5790 rtx addr = operands[index];
5791
5792 if (REG_P (addr))
5793 sprintf (buffer, "jsr\t%%%d", index);
5794 else if (flag_pic && (GET_CODE (addr) == UNSPEC))
5795 sprintf (buffer, "bsr\t%%%d", index);
5796 else
5797 sprintf (buffer, "jbsr\t%%%d", index);
5798
5799 return buffer;
5800 }
5801
5802
5803 /* Worker function for TARGET_ASM_TRAMPOLINE_TEMPLATE.
5804 Output assembler code for a block containing the constant parts
5805 of a trampoline, leaving space for the variable parts.
5806 Note that STATIC_CHAIN_REGNUM is t1 (aka r12) on ck801 and
5807 t1 (r13) otherwise. */
5808
5809 static void
5810 csky_asm_trampoline_template (FILE *f)
5811 {
5812 if (CSKY_ISA_FEATURE (2E3))
5813 {
5814 fprintf (f, "\tlrw\t%s, [.Lstatic_chain]\n",
5815 reg_names[STATIC_CHAIN_REGNUM]);
5816 fprintf (f, "\tjmpi\t[.Lfunc_address]\n");
5817 /* 2 32-bit insns = 8 bytes. */
5818 }
5819 else if (CSKY_TARGET_ARCH (CK801))
5820 {
5821 /* It's hard to provide general support for trampolines on this
5822 core. We need a register other than the one holding the
5823 static chain (r13) to hold the function pointer for the
5824 indirect jump to it. But ck801 has such a limited register set
5825 there is no other call-clobbered scratch register available -- in
5826 particular, this core does not have r12, which we use for the
5827 ck802 case below. If we use a callee-saved register like r4,
5828 saving the old value on the stack screws up the stack frame
5829 if there are overflow arguments pushed on the stack
5830 by the caller. In theory we could test for that and handle
5831 limited cases with parameters that all fit in r0-r3 with no
5832 stack overflow, but punt for now. */
5833 sorry ("Nested function trampolines not supported on CK801.");
5834 }
5835 else
5836 {
5837 fprintf (f, "\tlrw\t%s, [.Lfunc_address]\n",
5838 reg_names[CSKY_T1_REGNUM]);
5839 fprintf (f, "\tlrw\t%s, [.Lstatic_chain]\n",
5840 reg_names[STATIC_CHAIN_REGNUM]);
5841 fprintf (f, "\tjmp\t%s\n",
5842 reg_names[CSKY_T1_REGNUM]);
5843 /* To align constant pool on a word boundary. */
5844 fprintf (f, "\t.align 2\n");
5845 /* 2 32-bit lrw insns + 16-bit jump + 16-bit pad = 12 bytes. */
5846 }
5847
5848 fprintf (f, ".Lstatic_chain:\n");
5849 fprintf (f, "\t.long 0\n");
5850 fprintf (f, ".Lfunc_address:\n");
5851 fprintf (f, "\t.long 0\n");
5852 /* 2 words of constant pool = 8 bytes. */
5853 }
5854
5855 /* Worker function for TARGET_TRAMPOLINE_INIT. */
5856
5857 static void
5858 csky_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
5859 {
5860 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
5861 rtx mem, a_tramp;
5862 int pool = TRAMPOLINE_SIZE - 8;
5863
5864 emit_block_move (m_tramp, assemble_trampoline_template (),
5865 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5866
5867 mem = adjust_address (m_tramp, SImode, pool);
5868 emit_move_insn (mem, chain_value);
5869 mem = adjust_address (m_tramp, SImode, pool + 4);
5870 emit_move_insn (mem, fnaddr);
5871
5872 a_tramp = XEXP (m_tramp, 0);
5873 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__clear_cache"),
5874 LCT_NORMAL, VOIDmode, a_tramp, Pmode,
5875 plus_constant (Pmode, a_tramp, TRAMPOLINE_SIZE), Pmode);
5876 }
5877
5878
5879 /* Emit a comparison insn for float values.
5880 Return true if the comparison is inverted. */
5881
5882 bool
5883 csky_emit_compare_float (enum rtx_code code, rtx op0, rtx op1)
5884 {
5885 rtx cc_reg = gen_rtx_REG (CCmode, CSKY_CC_REGNUM);
5886 bool invert;
5887 machine_mode mode = GET_MODE (op1);
5888
5889 if (op1 != CONST0_RTX (mode))
5890 op1 = force_reg (mode, op1);
5891
5892 invert = false;
5893 switch (code)
5894 {
5895 case EQ:
5896 code = NE;
5897 invert = true;
5898 break;
5899
5900 case NE:
5901 break;
5902 case LE:
5903 if (op1 == CONST0_RTX (mode))
5904 op1 = force_reg (mode, op1);
5905 break;
5906 case GT:
5907 if (op1 == CONST0_RTX (mode))
5908 op1 = force_reg (mode, op1);
5909 break;
5910 case GE:
5911 break;
5912 case LT:
5913 if (op1 == CONST0_RTX (mode))
5914 {
5915 code = GE;
5916 invert = true;
5917 }
5918 break;
5919 case UNORDERED:
5920 break;
5921 case ORDERED:
5922 code = UNORDERED;
5923 invert = true;
5924 break;
5925
5926 default:
5927 break;
5928 }
5929
5930 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_fmt_ee (code, CCmode, op0, op1)));
5931
5932 return invert;
5933 }
5934
5935 /* Support for the Q memory constraint. Returns true if OP is a MEM RTX
5936 with an address consisting of base + index or base + displacement. */
5937 bool
5938 csky_valid_fpuv2_mem_operand (rtx op)
5939 {
5940 struct csky_address addr;
5941
5942 if (GET_CODE (op) != MEM)
5943 return false;
5944
5945 if (!decompose_csky_address (XEXP (op, 0), &addr))
5946 return false;
5947
5948 /* Verify base register. */
5949 if (!is_csky_address_register_rtx_p (addr.base, 0))
5950 return false;
5951
5952 /* Verify index operand. */
5953 if (addr.index)
5954 {
5955 if (!is_csky_address_register_rtx_p (addr.index, 0))
5956 return false;
5957
5958 if (addr.scale == 1 || addr.scale == 2 || addr.scale == 4
5959 || addr.scale == 8)
5960 return true;
5961
5962 return false;
5963 }
5964 /* Verify disp operand. */
5965 else if (addr.disp)
5966 {
5967 rtx disp = addr.disp;
5968
5969 if (!CONST_INT_P (disp))
5970 return false;
5971
5972 if (((unsigned) INTVAL (disp) % 4) == 0
5973 && (unsigned) INTVAL (disp) <= (unsigned) 1020)
5974 return true;
5975
5976 return false;
5977 }
5978 return true;
5979 }
5980
5981
5982 /* Returns the (interrupt) function type of the current
5983 function, or CSKY_FT_UNKNOWN if the type cannot be determined. */
5984
5985 static unsigned long
5986 csky_isr_value (tree argument)
5987 {
5988 const isr_attribute_entry *ptr;
5989 const char *arg;
5990
5991 /* No argument - default to IRQ. */
5992 if (argument == NULL_TREE)
5993 return CSKY_FT_ISR;
5994
5995 /* Get the value of the argument. */
5996 if (TREE_VALUE (argument) == NULL_TREE
5997 || TREE_CODE (TREE_VALUE (argument)) != STRING_CST)
5998 return CSKY_FT_UNKNOWN;
5999
6000 arg = TREE_STRING_POINTER (TREE_VALUE (argument));
6001
6002 /* Check it against the list of known arguments. */
6003 for (ptr = isr_attribute_map; ptr->arg != NULL; ptr++)
6004 if (strcmp (arg, ptr->arg) == 0)
6005 return ptr->return_value;
6006
6007 /* An unrecognized interrupt type. */
6008 return CSKY_FT_UNKNOWN;
6009 }
6010
6011 /* Handle an attribute requiring a FUNCTION_DECL;
6012 arguments as in struct attribute_spec.handler. */
6013
6014 static tree
6015 csky_handle_fndecl_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
6016 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
6017 {
6018 if (TREE_CODE (*node) != FUNCTION_DECL)
6019 {
6020 warning (OPT_Wattributes, "%qE attribute only applies to functions",
6021 name);
6022 *no_add_attrs = true;
6023 }
6024
6025 return NULL_TREE;
6026 }
6027
6028 /* Handle an "interrupt" or "isr" attribute;
6029 arguments as in struct attribute_spec.handler. */
6030
6031 static tree
6032 csky_handle_isr_attribute (tree *node, tree name, tree args, int flags,
6033 bool *no_add_attrs)
6034 {
6035
6036 if (!TARGET_ISTACK)
6037 {
6038 warning (OPT_Wattributes, "%qE attribute ignored without -mistack",
6039 name);
6040 *no_add_attrs = true;
6041 return NULL_TREE;
6042 }
6043
6044 if (DECL_P (*node))
6045 {
6046 if (TREE_CODE (*node) != FUNCTION_DECL)
6047 {
6048 warning (OPT_Wattributes, "%qE attribute only applies to functions",
6049 name);
6050 *no_add_attrs = true;
6051 }
6052 }
6053 else
6054 {
6055 if (TREE_CODE (*node) == FUNCTION_TYPE
6056 || TREE_CODE (*node) == METHOD_TYPE)
6057 {
6058 if (csky_isr_value (args) == CSKY_FT_UNKNOWN)
6059 {
6060 warning (OPT_Wattributes, "%qE attribute ignored", name);
6061 *no_add_attrs = true;
6062 }
6063 }
6064 else if (TREE_CODE (*node) == POINTER_TYPE
6065 && (TREE_CODE (TREE_TYPE (*node)) == FUNCTION_TYPE
6066 || TREE_CODE (TREE_TYPE (*node)) == METHOD_TYPE)
6067 && csky_isr_value (args) != CSKY_FT_UNKNOWN)
6068 {
6069 *node = build_variant_type_copy (*node);
6070 TREE_TYPE (*node) = build_type_attribute_variant (TREE_TYPE (*node),
6071 tree_cons (name, args, TYPE_ATTRIBUTES (TREE_TYPE (*node))));
6072 *no_add_attrs = true;
6073 }
6074 else if (flags & ((int)ATTR_FLAG_DECL_NEXT
6075 | (int)ATTR_FLAG_FUNCTION_NEXT
6076 | (int)ATTR_FLAG_ARRAY_NEXT))
6077 {
6078 *no_add_attrs = true;
6079 return tree_cons (name, args, NULL_TREE);
6080 }
6081 else
6082 warning (OPT_Wattributes, "%qE attribute ignored", name);
6083 }
6084 return NULL_TREE;
6085 }
6086
6087
6088 /* Implement TARGET_REGISTER_MOVE_COST: compute extra cost of moving data
6089 between one register class and another. */
6090
6091 int
6092 csky_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
6093 reg_class_t from, reg_class_t to)
6094 {
6095 #define GR_REG_CLASS_P(CLASS) \
6096 ((CLASS) == GENERAL_REGS || (CLASS) == MINI_REGS || (CLASS) == SP_REGS \
6097 || (CLASS) == LOW_REGS)
6098
6099 #define HILO_REG_CLASS_P(CLASS) \
6100 ((CLASS) == HI_REGS || (CLASS) == LO_REGS || (CLASS) == HILO_REGS)
6101
6102 #define V_REG_CLASS_P(CLASS) \
6103 ((CLASS) == V_REGS)
6104
6105 if (V_REG_CLASS_P (from) && V_REG_CLASS_P (to))
6106 return 2;
6107
6108 if ((V_REG_CLASS_P (from) && GR_REG_CLASS_P (to))
6109 || (GR_REG_CLASS_P (from) && V_REG_CLASS_P (to)))
6110 return 6;
6111
6112 if ((HILO_REG_CLASS_P (from) && GR_REG_CLASS_P (to))
6113 || (GR_REG_CLASS_P (from) && HILO_REG_CLASS_P (to)))
6114 return 16;
6115
6116 if (HILO_REG_CLASS_P (from) && HILO_REG_CLASS_P (to))
6117 return 32;
6118
6119 if ((HILO_REG_CLASS_P (from) && V_REG_CLASS_P (to))
6120 || (V_REG_CLASS_P (from) && HILO_REG_CLASS_P (to)))
6121 return 64;
6122
6123 return 2;
6124 }
6125
6126
6127 /* Implement TARGET_MEMORY_MOVE_COST: compute the cost of moving data
6128 between registers and memory. */
6129
6130 int
6131 csky_memory_move_cost (machine_mode mode, reg_class_t rclass,
6132 bool in)
6133 {
6134 return (4 + memory_move_secondary_cost (mode, rclass, in));
6135 }
6136
6137
6138 /* TARGET_RTX_COSTS helper for ck801/ck802. */
6139
6140 static bool
6141 ck802_ck801_rtx_costs (rtx x, int code, int outer_code, int *total,
6142 bool speed)
6143 {
6144 machine_mode mode = GET_MODE (x);
6145 switch (code)
6146 {
6147 /* Accessing memory costs quite a lot for first word; */
6148 case MEM:
6149 *total = COSTS_N_INSNS (1 + CSKY_NUM_REGS (mode));
6150 return false;
6151 case DIV:
6152 case UDIV:
6153 case MOD:
6154 case UMOD:
6155 *total = 100;
6156 return true;
6157
6158 case ROTATE:
6159 case ROTATERT:
6160 case ASHIFT:
6161 case LSHIFTRT:
6162 case ASHIFTRT:
6163 if (speed)
6164 *total = 2;
6165 else
6166 *total = COSTS_N_INSNS (1);
6167 return false;
6168
6169 case MINUS:
6170 case PLUS:
6171 *total = COSTS_N_INSNS (CSKY_NUM_REGS (mode));
6172 return false;
6173
6174 case AND:
6175 {
6176 enum rtx_code subcode = GET_CODE (XEXP (x, 1));
6177
6178 /* If subcode is "not", we'll try to combine it into e.g. "andn"
6179 instruction, so give AND itself zero cost. */
6180 if (subcode == NOT)
6181 {
6182 *total = 0;
6183 return false;
6184 }
6185 }
6186 /* Fall through. */
6187 case XOR:
6188 case IOR:
6189 *total = COSTS_N_INSNS (CSKY_NUM_REGS (mode));
6190 return false;
6191
6192 case MULT:
6193 /* FIXME: is ixw supported on ck801/ck802? */
6194 /* We can use "ix.h/w" insn to replace multiply by 2 or 4.
6195 "ix.h/w" is a 32-bit insn, so let its cost be a little less than
6196 "mult" insn. */
6197 if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)))
6198 {
6199 unsigned HOST_WIDE_INT m
6200 = (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)));
6201 if ((m == 2 || m == 4) && outer_code == PLUS)
6202 {
6203 *total = 2;
6204 return true;
6205 }
6206 else
6207 {
6208 /* Because mult is relatively slower than other operations,
6209 we try to use other insns when optimizing for speed.
6210 When optimizing for size, give it lower cost. */
6211 if (speed)
6212 {
6213 *total = COSTS_N_INSNS (10 * CSKY_NUM_REGS (mode));
6214 return true;
6215 }
6216 int cycle = 0;
6217 while (m)
6218 {
6219 m >>= 2;
6220 cycle++;
6221 }
6222 *total = COSTS_N_INSNS (1) + cycle;
6223 return false;
6224 }
6225 }
6226 if (!speed)
6227 *total = COSTS_N_INSNS (1);
6228 return false;
6229
6230 case NEG:
6231 /* Usually, we use subtract from 0 to substitute for neg, and
6232 it costs 1 extra insn to move 0 to a register. */
6233 *total = COSTS_N_INSNS (2 * CSKY_NUM_REGS (mode));
6234 return false;
6235
6236 case NOT:
6237 *total = COSTS_N_INSNS (CSKY_NUM_REGS (mode));
6238 return false;
6239
6240 case COMPARE:
6241 *total = COSTS_N_INSNS (1);
6242 return false;
6243
6244 case SIGN_EXTEND:
6245 case ZERO_EXTEND:
6246 *total = COSTS_N_INSNS (CSKY_NUM_REGS (mode));
6247 return false;
6248
6249 case SIGN_EXTRACT:
6250 case ZERO_EXTRACT:
6251 if (REG_P (XEXP (x, 0))
6252 && CONST_INT_P (XEXP (x, 1))
6253 && CONST_INT_P (XEXP (x, 2))
6254 && INTVAL (XEXP (x, 1)) == 8
6255 && INTVAL (XEXP (x, 2)) % 8 == 0)
6256 {
6257 *total = COSTS_N_INSNS (1);
6258 return true;
6259 }
6260 *total = COSTS_N_INSNS (CSKY_NUM_REGS (mode));
6261 return false;
6262
6263 case CONST_INT:
6264 {
6265 unsigned HOST_WIDE_INT t = (unsigned HOST_WIDE_INT) (INTVAL (x));
6266
6267 if (outer_code == COMPARE)
6268 {
6269 if (t < 0x10000)
6270 *total = 0;
6271 else
6272 *total = COSTS_N_INSNS (2);
6273 }
6274 else if (outer_code == AND || outer_code == IOR || outer_code == XOR)
6275 {
6276 /* "andi,xori,ori" are 32-bit insns, so let it cost a
6277 little more. */
6278 if (t < 0x1000)
6279 {
6280 /* Try replacing "andi" by "sextb/h", so let it cost more. */
6281 if (outer_code == AND && (t == 0xff || t == 0xffff))
6282 {
6283 *total = 8;
6284 return true;
6285 }
6286 *total = 2;
6287 }
6288 else if (t < 0x10000)
6289 *total = COSTS_N_INSNS (1);
6290 else
6291 *total = COSTS_N_INSNS (2);
6292 }
6293 else if (outer_code == PLUS || outer_code == MINUS)
6294 {
6295 /* "addi/subi rx,ry,imm", if imm<9, it is more often a
6296 16-bit insn. If imm>=9, use "movi" insn; it's probably
6297 less than "addi/subi". */
6298 if (t < 9)
6299 *total = 0;
6300 else if (t < 0x1000)
6301 *total = 2;
6302 else if (t < 0x10000)
6303 *total = COSTS_N_INSNS (1);
6304 else
6305 *total = COSTS_N_INSNS (2);
6306 }
6307 else if (outer_code == ROTATE || outer_code == ROTATERT
6308 || outer_code == LSHIFTRT || outer_code == ASHIFTRT
6309 || outer_code == ASHIFT)
6310 {
6311 if (t < 32)
6312 *total = 0;
6313 else
6314 *total = COSTS_N_INSNS (2);
6315 }
6316 else
6317 {
6318 if (t < 0x10000)
6319 if (outer_code == SET && t < 256)
6320 *total = 0;
6321 else
6322 *total = COSTS_N_INSNS (1);
6323 else
6324 *total = COSTS_N_INSNS (2);
6325 }
6326 }
6327 return true;
6328
6329 case CONST:
6330 case LABEL_REF:
6331 case SYMBOL_REF:
6332 *total = COSTS_N_INSNS (3);
6333 return true;
6334 default:
6335 return false;
6336 }
6337 }
6338
6339
6340 /* TARGET_RTX_COSTS helper for ck803. */
6341
6342 static bool
6343 ck803_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
6344 int *total, bool speed ATTRIBUTE_UNUSED)
6345 {
6346 switch (code)
6347 {
6348 case SET:
6349 if (MEM_P (XEXP (x, 1)))
6350 {
6351 struct csky_address op1;
6352 bool address_valid
6353 = decompose_csky_address (XEXP (XEXP (x, 1), 0), &op1);
6354 if (op1.index)
6355 {
6356 *total = COSTS_N_INSNS (3);
6357 return true;
6358 }
6359 else if (address_valid)
6360 {
6361 *total = COSTS_N_INSNS (1);
6362 return true;
6363 }
6364 }
6365 if (REG_P (XEXP (x, 0)) && (GET_CODE (XEXP (x, 1)) == PLUS))
6366 {
6367 rtx sub_exp = XEXP (x, 1);
6368 if (REG_P (XEXP (sub_exp, 0)) && REG_P (XEXP (sub_exp, 1)))
6369 {
6370 *total = COSTS_N_INSNS (1);
6371 return true;
6372 }
6373 }
6374 return false;
6375 case MULT:
6376 if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)))
6377 {
6378 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6379 if (val % 2 == 0 && val < 0xffffffff && val > 0)
6380 {
6381 *total = COSTS_N_INSNS (1);
6382 return true;
6383 }
6384 }
6385 return false;
6386
6387 case CONST:
6388 case LABEL_REF:
6389 case SYMBOL_REF:
6390 *total = COSTS_N_INSNS (3);
6391 return true;
6392 default:
6393 return false;
6394 }
6395 }
6396
6397 /* TARGET_RTX_COSTS helper for ck807+ arches. */
6398
6399 static bool
6400 ck807_ck810_rtx_costs (rtx x, int code,
6401 int outer_code ATTRIBUTE_UNUSED,
6402 int *total, bool speed ATTRIBUTE_UNUSED)
6403 {
6404 switch (code)
6405 {
6406 case MULT:
6407 if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)))
6408 {
6409 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6410 if (val % 2 == 0 && val < 0xffffffff && val > 0)
6411 {
6412 *total = COSTS_N_INSNS (1);
6413 return true;
6414 }
6415 }
6416 return false;
6417
6418 case CONST:
6419 case LABEL_REF:
6420 case SYMBOL_REF:
6421 *total = COSTS_N_INSNS (3);
6422 return true;
6423 default:
6424 return false;
6425 }
6426 }
6427
6428
6429 /* Implement TARGET_RTX_COSTS, to compute a (partial) cost for rtx X.
6430 Return true if the complete cost has been computed, and false if
6431 subexpressions should be scanned. In either case, *TOTAL contains
6432 the cost result. */
6433
6434 static bool
6435 csky_rtx_costs (rtx x, machine_mode mode ATTRIBUTE_UNUSED, int outer_code,
6436 int opno ATTRIBUTE_UNUSED, int *total, bool speed)
6437 {
6438 int code = GET_CODE (x);
6439
6440 if (CSKY_TARGET_ARCH (CK802) || CSKY_TARGET_ARCH (CK801))
6441 return ck802_ck801_rtx_costs (x, code, outer_code, total, speed);
6442 else if (CSKY_TARGET_ARCH (CK803))
6443 return ck803_rtx_costs (x, code, outer_code, total, speed);
6444 else if (CSKY_TARGET_ARCH (CK807) || CSKY_TARGET_ARCH (CK810))
6445 return ck807_ck810_rtx_costs (x, code, outer_code, total, speed);
6446 else
6447 gcc_unreachable ();
6448 }
6449
6450 /* Emit assembly code for CASESI. This is only used on CK801 and CK802
6451 when optimizing for size, and uses helper functions in libgcc instead
6452 of doing the control transfer inline. */
6453
6454 const char *
6455 csky_output_casesi (rtx *operands)
6456 {
6457 rtx diff_vec = PATTERN (NEXT_INSN (as_a <rtx_insn *> (operands[0])));
6458
6459 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
6460
6461 switch (GET_MODE (diff_vec))
6462 {
6463 case E_QImode:
6464 return (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned
6465 ? "jbsr\t___gnu_csky_case_uqi"
6466 : "jbsr\t___gnu_csky_case_sqi");
6467 case E_HImode:
6468 return (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned
6469 ? "jbsr\t___gnu_csky_case_uhi"
6470 : "jbsr\t___gnu_csky_case_shi");
6471 case E_SImode:
6472 return "jbsr\t___gnu_csky_case_si";
6473 default:
6474 gcc_unreachable ();
6475 }
6476 }
6477
6478 /* Implement TARGET_SCHED_ISSUE_RATE. Lookup the issue rate in the
6479 per-core tuning structs. */
6480 static int
6481 csky_sched_issue_rate (void)
6482 {
6483 if (CSKY_TARGET_ARCH (CK810))
6484 return 2;
6485 else
6486 return 1;
6487 }
6488
6489
6490 /* This function implements the target macro TARGET_SCHED_ADJUST_COST.
6491 It corrects the value of COST based on the relationship between
6492 INSN and DEP through the dependence DEP_TYPE. It returns the new
6493 value. */
6494
6495 static int
6496 csky_sched_adjust_cost (rtx_insn *insn,
6497 int dep_type,
6498 rtx_insn *dep,
6499 int cost,
6500 unsigned int dw ATTRIBUTE_UNUSED)
6501 {
6502 if (dep_type == REG_DEP_ANTI || dep_type == REG_DEP_OUTPUT)
6503 return 0;
6504 /* The REG_DEP_TRUE situation. */
6505 else if (recog_memoized (insn) >= 0 && recog_memoized (dep) >= 0)
6506 {
6507 enum attr_type insn_type = get_attr_type (insn);
6508 if (CSKY_TARGET_ARCH (CK803))
6509 {
6510 /* The ld or st's base reg depends on the pre insn,
6511 it will delay 1 cycle. */
6512 if (insn_type == TYPE_LOAD || insn_type == TYPE_STORE)
6513 {
6514 rtx pattern = PATTERN (insn);
6515
6516 gcc_assert (GET_CODE (pattern) == SET);
6517 rtx addr = (insn_type == TYPE_LOAD
6518 ? SET_SRC (pattern) : SET_DEST (pattern));
6519
6520 enum rtx_code code = GET_CODE (addr);
6521 if (code == ZERO_EXTEND || code == SIGN_EXTEND)
6522 addr = XEXP (addr, 0);
6523 gcc_assert (GET_CODE (addr) == MEM);
6524
6525 rtx base = XEXP (addr, 0);
6526 rtx reg = NULL_RTX;
6527 if (REG_P (base))
6528 reg = base;
6529 if (GET_CODE (base) == PLUS
6530 && GET_CODE (XEXP (base, 0)) == REG)
6531 reg = XEXP (base, 0);
6532 if ((reg != NULL_RTX) && reg_set_p (reg, PATTERN (dep)))
6533 return 2;
6534 }
6535 }
6536 else if (CSKY_TARGET_ARCH (CK802))
6537 {
6538 if ((insn_type == TYPE_CALL_JSR || insn_type == TYPE_BRANCH_JMP)
6539 && get_attr_type (dep) != TYPE_LOAD)
6540 return 1;
6541
6542 if (insn_type == TYPE_LOAD || insn_type == TYPE_STORE)
6543 {
6544 rtx pattern = PATTERN (insn);
6545
6546 gcc_assert (GET_CODE (pattern) == SET);
6547
6548 rtx addr = (insn_type == TYPE_LOAD
6549 ? SET_SRC (pattern) : SET_DEST (pattern));
6550
6551 enum rtx_code code = GET_CODE (addr);
6552 if (code == ZERO_EXTEND || code == SIGN_EXTEND)
6553 addr = XEXP (addr, 0);
6554 gcc_assert (GET_CODE (addr) == MEM);
6555
6556 rtx base = XEXP (addr, 0);
6557 rtx reg = NULL_RTX;
6558 if (REG_P (base))
6559 reg = base;
6560 if (GET_CODE (base) == PLUS
6561 && GET_CODE (XEXP (base, 0)) == REG)
6562 reg = XEXP (base, 0);
6563 if ((reg != NULL_RTX) && reg_set_p (reg, PATTERN (dep))
6564 && get_attr_type (dep) != TYPE_LOAD)
6565 return 1;
6566
6567 if (insn_type == TYPE_STORE
6568 && reg_referenced_p (SET_SRC (pattern), PATTERN (dep)))
6569 return 1;
6570 }
6571 }
6572 }
6573 return cost;
6574 }
6575
6576 static bool
6577 csky_warn_func_return (tree decl)
6578 {
6579 /* Naked functions are implemented entirely in assembly, including the
6580 return sequence, so suppress warnings about this. */
6581 return lookup_attribute ("naked", DECL_ATTRIBUTES (decl)) == NULL_TREE;
6582 }
6583
6584
6585 /* Implement TARGET_RETURN_IN_MEMORY to decide whether TYPE should be
6586 returned in memory (true) or in a register (false).
6587 FNTYPE is the type of the function making the call. */
6588 static bool
6589 csky_return_in_memory (const_tree type,
6590 const_tree fntype ATTRIBUTE_UNUSED)
6591 {
6592 const HOST_WIDE_INT size = int_size_in_bytes (type);
6593 return (size == -1 || size > 2 * UNITS_PER_WORD);
6594 }
6595
6596
6597 /* Implement TARGET_DWARF_REGISTER_SPAN.
6598 Dwarf models VFP registers as 64-bit or 128-bit registers default.
6599 GCC models tham as 32-bit registers, so we need to describe this to
6600 the DWARF generation code. Other registers can use the default. */
6601 static rtx
6602 csky_dwarf_register_span (rtx rtl)
6603 {
6604 machine_mode mode;
6605 unsigned regno;
6606 rtx parts[16];
6607 int nregs;
6608 int i;
6609
6610 regno = REGNO (rtl);
6611 if (!CSKY_VREG_P (regno))
6612 return NULL_RTX;
6613
6614 mode = GET_MODE (rtl);
6615 if (GET_MODE_SIZE (mode) < 8)
6616 return NULL_RTX;
6617
6618 if (TARGET_SOFT_FPU)
6619 {
6620 nregs = GET_MODE_SIZE (mode) / 4;
6621 for (i = 0; i < nregs; i += 2)
6622 if (TARGET_BIG_ENDIAN)
6623 {
6624 parts[i] = gen_rtx_REG (SImode, regno + i + 1);
6625 parts[i + 1] = gen_rtx_REG (SImode, regno + i);
6626 }
6627 else
6628 {
6629 parts[i] = gen_rtx_REG (SImode, regno + i);
6630 parts[i + 1] = gen_rtx_REG (SImode, regno + i + 1);
6631 }
6632 }
6633 else
6634 {
6635 /* FIXME: dwarf2 considers all general registers to be the same
6636 as the CPU bit width. Transform the 64-bit FPU registers to
6637 32 bits here, and we will modify the unwind processing to
6638 fit CSKY architecture later. */
6639 nregs = GET_MODE_SIZE (mode) / 8;
6640 for (i = 0; i < nregs; i++)
6641 parts[i] = gen_rtx_REG (SImode, regno + i);
6642 }
6643
6644 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nregs , parts));
6645 }
6646
6647 /* Implement TARGET_INIT_LIBFUNCS. */
6648
6649 static void
6650 csky_init_libfuncs (void)
6651 {
6652 if (TARGET_CSKY_LINUX)
6653 init_sync_libfuncs (UNITS_PER_WORD);
6654 if (!TARGET_LIBCCRT)
6655 return;
6656
6657 #define CSKY_GCC_SYM(sym) "__csky_ccrt_" # sym
6658
6659 /* int */
6660
6661 /* Arithmetic functions */
6662 set_optab_libfunc (ashl_optab, DImode, CSKY_GCC_SYM (ashldi3));
6663 set_optab_libfunc (ashr_optab, DImode, CSKY_GCC_SYM (ashrdi3));
6664 set_optab_libfunc (sdiv_optab, SImode, CSKY_GCC_SYM (divsi3));
6665 set_optab_libfunc (sdiv_optab, DImode, CSKY_GCC_SYM (divdi3));
6666 set_optab_libfunc (lshr_optab, DImode, CSKY_GCC_SYM (lshrdi3));
6667 set_optab_libfunc (smod_optab, SImode, CSKY_GCC_SYM (modsi3));
6668 set_optab_libfunc (smod_optab, DImode, CSKY_GCC_SYM (moddi3));
6669 set_optab_libfunc (smul_optab, DImode, CSKY_GCC_SYM (muldi3));
6670 set_optab_libfunc (neg_optab, DImode, CSKY_GCC_SYM (negdi2));
6671 set_optab_libfunc (udiv_optab, SImode, CSKY_GCC_SYM (udivsi3));
6672 set_optab_libfunc (udiv_optab, DImode, CSKY_GCC_SYM (udivdi3));
6673 set_optab_libfunc (udivmod_optab, DImode, CSKY_GCC_SYM (udivmoddi4));
6674 set_optab_libfunc (umod_optab, SImode, CSKY_GCC_SYM (umodsi3));
6675 set_optab_libfunc (umod_optab, DImode, CSKY_GCC_SYM (umoddi3));
6676
6677 /* Comparison functions */
6678 set_optab_libfunc (cmp_optab, DImode, CSKY_GCC_SYM (cmpdi2));
6679 set_optab_libfunc (ucmp_optab, DImode, CSKY_GCC_SYM (ucmpdi2));
6680
6681 /* Trapping arithmetic functions */
6682 set_optab_libfunc (absv_optab, SImode, CSKY_GCC_SYM (absvsi2));
6683 set_optab_libfunc (absv_optab, DImode, CSKY_GCC_SYM (absvdi2));
6684 set_optab_libfunc (addv_optab, SImode, CSKY_GCC_SYM (addvsi3));
6685 set_optab_libfunc (addv_optab, DImode, CSKY_GCC_SYM (addvdi3));
6686 set_optab_libfunc (smulv_optab, SImode, CSKY_GCC_SYM (mulvsi3));
6687 set_optab_libfunc (smulv_optab, DImode, CSKY_GCC_SYM (mulvdi3));
6688 set_optab_libfunc (negv_optab, SImode, CSKY_GCC_SYM (negvsi2));
6689 set_optab_libfunc (negv_optab, DImode, CSKY_GCC_SYM (negvdi2));
6690 set_optab_libfunc (subv_optab, SImode, CSKY_GCC_SYM (subvsi3));
6691 set_optab_libfunc (subv_optab, DImode, CSKY_GCC_SYM (subvdi3));
6692
6693 /* Bit operations */
6694 set_optab_libfunc (clz_optab, SImode, CSKY_GCC_SYM (clzsi2));
6695 set_optab_libfunc (clz_optab, DImode, CSKY_GCC_SYM (clzdi2));
6696 set_optab_libfunc (ctz_optab, SImode, CSKY_GCC_SYM (ctzsi2));
6697 set_optab_libfunc (ctz_optab, DImode, CSKY_GCC_SYM (ctzdi2));
6698 set_optab_libfunc (ffs_optab, DImode, CSKY_GCC_SYM (ffsdi2));
6699 set_optab_libfunc (parity_optab, SImode, CSKY_GCC_SYM (paritysi2));
6700 set_optab_libfunc (parity_optab, DImode, CSKY_GCC_SYM (paritydi2));
6701 set_optab_libfunc (popcount_optab,SImode, CSKY_GCC_SYM (popcountsi2));
6702 set_optab_libfunc (popcount_optab,DImode, CSKY_GCC_SYM (popcountdi2));
6703 set_optab_libfunc (bswap_optab, SImode, CSKY_GCC_SYM (bswapsi2));
6704 set_optab_libfunc (bswap_optab, DImode, CSKY_GCC_SYM (bswapdi2));
6705
6706 /* float */
6707
6708 /* Arithmetic functions */
6709 set_optab_libfunc (add_optab, SFmode, CSKY_GCC_SYM (addsf3));
6710 set_optab_libfunc (add_optab, DFmode, CSKY_GCC_SYM (adddf3));
6711 set_optab_libfunc (sub_optab, SFmode, CSKY_GCC_SYM (subsf3));
6712 set_optab_libfunc (sub_optab, DFmode, CSKY_GCC_SYM (subdf3));
6713 set_optab_libfunc (smul_optab, SFmode, CSKY_GCC_SYM (mulsf3));
6714 set_optab_libfunc (smul_optab, DFmode, CSKY_GCC_SYM (muldf3));
6715 set_optab_libfunc (sdiv_optab, SFmode, CSKY_GCC_SYM (divsf3));
6716 set_optab_libfunc (sdiv_optab, DFmode, CSKY_GCC_SYM (divdf3));
6717 set_optab_libfunc (neg_optab, SFmode, CSKY_GCC_SYM (negsf2));
6718 set_optab_libfunc (neg_optab, DFmode, CSKY_GCC_SYM (negdf2));
6719
6720 /* Conversion functions */
6721 set_conv_libfunc (sext_optab, DFmode, SFmode, CSKY_GCC_SYM (extendsfdf2));
6722 set_conv_libfunc (trunc_optab, SFmode, DFmode, CSKY_GCC_SYM (truncdfsf2));
6723 set_conv_libfunc (sfix_optab, SImode, SFmode, CSKY_GCC_SYM (fixsfsi));
6724 set_conv_libfunc (sfix_optab, SImode, DFmode, CSKY_GCC_SYM (fixdfsi));
6725 set_conv_libfunc (sfix_optab, DImode, SFmode, CSKY_GCC_SYM (fixsfdi));
6726 set_conv_libfunc (sfix_optab, DImode, DFmode, CSKY_GCC_SYM (fixdfdi));
6727 set_conv_libfunc (ufix_optab, SImode, SFmode, CSKY_GCC_SYM (fixunssfsi));
6728 set_conv_libfunc (ufix_optab, SImode, DFmode, CSKY_GCC_SYM (fixunsdfsi));
6729 set_conv_libfunc (ufix_optab, DImode, SFmode, CSKY_GCC_SYM (fixunssfdi));
6730 set_conv_libfunc (ufix_optab, DImode, DFmode, CSKY_GCC_SYM (fixunsdfdi));
6731 set_conv_libfunc (sfloat_optab, SFmode, SImode, CSKY_GCC_SYM (floatsisf));
6732 set_conv_libfunc (sfloat_optab, DFmode, SImode, CSKY_GCC_SYM (floatsidf));
6733 set_conv_libfunc (sfloat_optab, SFmode, DImode, CSKY_GCC_SYM (floatdisf));
6734 set_conv_libfunc (sfloat_optab, DFmode, DImode, CSKY_GCC_SYM (floatdidf));
6735 set_conv_libfunc (ufloat_optab, SFmode, SImode, CSKY_GCC_SYM (floatunsisf));
6736 set_conv_libfunc (ufloat_optab, DFmode, SImode, CSKY_GCC_SYM (floatunsidf));
6737 set_conv_libfunc (ufloat_optab, SFmode, DImode, CSKY_GCC_SYM (floatundisf));
6738 set_conv_libfunc (ufloat_optab, DFmode, DImode, CSKY_GCC_SYM (floatundidf));
6739
6740 /* Comparison functions */
6741 set_optab_libfunc (cmp_optab, SFmode, CSKY_GCC_SYM (cmpsf2));
6742 set_optab_libfunc (cmp_optab, DFmode, CSKY_GCC_SYM (cmpdf2));
6743 set_optab_libfunc (unord_optab, SFmode, CSKY_GCC_SYM (unordsf2));
6744 set_optab_libfunc (unord_optab, DFmode, CSKY_GCC_SYM (unorddf2));
6745 set_optab_libfunc (eq_optab, SFmode, CSKY_GCC_SYM (eqsf2));
6746 set_optab_libfunc (eq_optab, DFmode, CSKY_GCC_SYM (eqdf2));
6747 set_optab_libfunc (ne_optab, SFmode, CSKY_GCC_SYM (nesf2));
6748 set_optab_libfunc (ne_optab, DFmode, CSKY_GCC_SYM (nedf2));
6749 set_optab_libfunc (ge_optab, SFmode, CSKY_GCC_SYM (gesf2));
6750 set_optab_libfunc (ge_optab, DFmode, CSKY_GCC_SYM (gedf2));
6751 set_optab_libfunc (lt_optab, SFmode, CSKY_GCC_SYM (ltsf2));
6752 set_optab_libfunc (lt_optab, DFmode, CSKY_GCC_SYM (ltdf2));
6753 set_optab_libfunc (le_optab, SFmode, CSKY_GCC_SYM (lesf2));
6754 set_optab_libfunc (le_optab, DFmode, CSKY_GCC_SYM (ledf2));
6755 set_optab_libfunc (gt_optab, SFmode, CSKY_GCC_SYM (gtsf2));
6756 set_optab_libfunc (gt_optab, DFmode, CSKY_GCC_SYM (gtdf2));
6757 }
6758
6759
6760 /* Implement TARGET_ADDRESS_COST to estimate cost of the memory address X.
6761 For C-SKY, (register) and (register + offset) have the same cost.
6762 Other situations cost more. */
6763
6764 static int
6765 csky_address_cost (rtx x, machine_mode mode ATTRIBUTE_UNUSED,
6766 addr_space_t as ATTRIBUTE_UNUSED,
6767 bool speed ATTRIBUTE_UNUSED)
6768 {
6769 enum rtx_code code = GET_CODE (x);
6770
6771 if (code == REG)
6772 return COSTS_N_INSNS (1);
6773 if (code == PLUS
6774 && REG_P (XEXP (x, 0))
6775 && CONST_INT_P (XEXP (x, 1)))
6776 return COSTS_N_INSNS (1);
6777
6778 return COSTS_N_INSNS (3);
6779 }
6780
6781
6782 /* Implement TARGET_FIXED_CONDITION_CODE_REGS. */
6783
6784 static bool
6785 csky_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
6786 {
6787 *p1 = CSKY_CC_REGNUM;
6788 *p2 = INVALID_REGNUM;
6789 return true;
6790 }
6791
6792
6793 struct gcc_target targetm = TARGET_INITIALIZER;
6794
6795 #include "gt-csky.h"