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