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 (&reg_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