PR96463: Optimise svld1rq from vectors for little endian AArch64 targets.
[official-gcc.git] / gcc / config / csky / csky.cc
blobe315e09a8fe97a4a91c778b7a1cc34d88289c8ba
1 /* GCC backend functions for C-SKY targets.
2 Copyright (C) 2018-2022 Free Software Foundation, Inc.
3 Contributed by C-SKY Microsystems and Mentor Graphics.
5 This file is part of GCC.
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.
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.
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/>. */
21 #define IN_TARGET_CODE 1
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 #include "opts.h"
72 /* This file should be included last. */
73 #include "target-def.h"
75 /* Stack and register size macros. */
77 #define CSKY_NUM_WORDS(SIZE) \
78 (((SIZE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
79 #define CSKY_NUM_REGS(MODE) \
80 CSKY_NUM_WORDS (GET_MODE_SIZE (MODE))
81 #define CSKY_STACK_ALIGN(SIZE) \
82 (CSKY_NUM_WORDS (SIZE) * UNITS_PER_WORD)
84 /* Offsets and range macros. */
86 #define CSKY_LD16_MAX_OFFSET(MODE) \
87 (31 * GET_MODE_SIZE (MODE))
88 #define CSKY_LD32_MAX_OFFSET(MODE) \
89 (4095 * GET_MODE_SIZE (MODE))
90 #define CSKY_LD16_OFFSET_MASK(MODE) \
91 (CSKY_LD16_MAX_OFFSET (MODE) + GET_MODE_SIZE (MODE) - 1)
93 #define CSKY_ADDI16_MAX_IMM 256
94 #define CSKY_SUBI16_MAX_IMM 256
96 #define CSKY_CONSTPOOL_LABEL_PREFIX "LCP"
98 /* Array of the smallest class containing reg number REGNO, indexed by
99 REGNO. Used by REGNO_REG_CLASS. */
100 enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER] =
102 /* Registers r0-r7. */
103 MINI_REGS, MINI_REGS, MINI_REGS, MINI_REGS,
104 MINI_REGS, MINI_REGS, MINI_REGS, MINI_REGS,
105 /* Registers r8-r15. */
106 LOW_REGS, LOW_REGS, LOW_REGS, LOW_REGS,
107 LOW_REGS, LOW_REGS, SP_REGS, LOW_REGS,
108 /* Registers r16-r31. */
109 GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
110 GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
111 GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
112 GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
113 /* Reserved. */
114 RESERVE_REGS,
115 /* CC,HI,LO registers. */
116 C_REGS, HILO_REGS, HILO_REGS,
117 /* Reserved. */
118 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
119 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
120 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
121 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
122 /* Vec registers. */
123 V_REGS, V_REGS, V_REGS, V_REGS,
124 V_REGS, V_REGS, V_REGS, V_REGS,
125 V_REGS, V_REGS, V_REGS, V_REGS,
126 V_REGS, V_REGS, V_REGS, V_REGS,
127 /* Reserved. */
128 RESERVE_REGS, RESERVE_REGS,
129 /* Register epc. */
130 OTHER_REGS,
131 /* Vec registers. */
132 V_REGS, V_REGS, V_REGS, V_REGS,
133 V_REGS, V_REGS, V_REGS, V_REGS,
134 V_REGS, V_REGS, V_REGS, V_REGS,
135 V_REGS, V_REGS, V_REGS, V_REGS,
136 /* Reserved. */
137 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
138 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
139 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
140 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
141 /* Reserved. */
142 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
143 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
144 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
145 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
146 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
147 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
148 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
149 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
151 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
152 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
153 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
154 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
155 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
156 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
157 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
158 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
160 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
161 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
162 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
163 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
164 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
165 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
166 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
167 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS, RESERVE_REGS,
169 RESERVE_REGS, RESERVE_REGS, RESERVE_REGS
172 /* Arrays that map GCC register numbers to debugger register numbers,
173 '-1' means that is INVALID_REGNUM.
174 TODO: which rules according to here ? */
175 const int csky_dbx_regno[FIRST_PSEUDO_REGISTER] =
177 0, 1, 2, 3, 4, 5, 6, 7,
178 8, 9, 10, 11, 12, 13, 14, 15,
179 16, 17, 18, 19, 20, 21, 22, 23,
180 24, 25, 26, 27, 28, 29, 30, 31,
181 -1, -1, 36, 37,
182 75, 79, 83, 87, 91, 95, 99, 103,
183 107, 111, 115, 119, 123, 127, 131, 135,
184 74, 78, 82, 86, 90, 94, 98, 102,
185 106, 110, 114, 118, 122, 126, 130, 134,
186 -1, -1, 72,
187 /* vr: 71 - 86 */
188 139, 143, 147, 151, 155, 159, 163, 167,
189 171, 175, 179, 183, 187, 191, 195, 199,
190 138, 142, 146, 150, 154, 158, 162, 166,
191 170, 174, 178, 182, 186, 190, 194, 198,
192 /* resereved */
193 -1, -1, -1, -1, -1, -1, -1, -1,
194 -1, -1, -1, -1, -1, -1, -1, -1,
195 -1, -1, -1, -1, -1, -1, -1, -1,
196 -1, -1, -1, -1, -1, -1, -1, -1,
198 -1, -1, -1, -1, -1, -1, -1, -1,
199 -1, -1, -1, -1, -1, -1, -1, -1,
200 -1, -1, -1, -1, -1, -1, -1, -1,
201 -1, -1, -1, -1, -1, -1, -1, -1,
203 -1, -1, -1, -1, -1, -1, -1, -1,
204 -1, -1, -1, -1, -1, -1, -1, -1,
205 -1, -1, -1, -1, -1, -1, -1, -1,
206 -1, -1, -1, -1, -1, -1, -1, -1,
208 -1, -1, -1
211 /* Table of machine attributes. */
212 static tree csky_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
213 static tree csky_handle_isr_attribute (tree *, tree, tree, int, bool *);
214 static const struct attribute_spec csky_attribute_table[] =
216 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
217 affects_type_identity, handler, exclude } */
218 { "naked", 0, 0, true, false, false, false, csky_handle_fndecl_attribute, NULL },
219 /* Interrupt Service Routines have special prologue and epilogue requirements. */
220 { "interrupt", 0, 1, false, false, false, false, csky_handle_isr_attribute, NULL },
221 { "isr", 0, 1, false, false, false, false, csky_handle_isr_attribute, NULL },
222 { NULL, 0, 0, false, false, false, false, NULL, NULL }
225 /* A C structure for machine-specific, per-function data.
226 This is added to the cfun structure. */
227 typedef struct GTY(()) machine_function
229 /* Records if LR has to be saved for far jumps. */
230 int far_jump_used;
231 /* Records the type of the current function. */
232 unsigned long func_type;
233 /* Record if the function has a variable argument list. */
234 int uses_anonymous_args;
236 /* Stack frame layout information. If frame_init_p is true,
237 these fields have been initialized and don't need to be
238 recomputed. */
239 unsigned int reg_mask; /* non-volatile reg saves */
240 int arg_size; /* stdarg spills (bytes) */
241 int reg_size; /* non-volatile reg saves (bytes) */
242 int local_size; /* locals */
243 int outbound_size; /* arg overflow on calls out */
244 int frame_size; /* total static size of stack frame */
245 int local_offset;
246 int reg_offset;
247 int arg_offset;
248 int frame_init_p;
250 } machine_function;
252 /* These macros are for the func_type values above. */
253 #define CSKY_FT_TYPE_MASK ((1 << 3) - 1)
254 #define CSKY_FT_UNKNOWN 0 /* Type not been determined */
255 #define CSKY_FT_NORMAL 1 /* Normal function */
256 #define CSKY_FT_ISR 4 /* Interrupt service routine */
257 #define CSKY_FT_FIQ 5 /* Fast interrupt service routine */
258 #define CSKY_FT_EXCEPTION 6 /* Exception handler */
259 #define CSKY_FT_INTERRUPT (1 << 2) /* overlap CSKY_FT_ISR */
260 #define CSKY_FT_NAKED (1 << 3) /* No prologue and epilogue */
261 #define CSKY_FUNCTION_TYPE(t) ((t) & CSKY_FT_TYPE_MASK)
262 #define CSKY_FUNCTION_IS_INTERRUPT(t) ((t) & CSKY_FT_INTERRUPT)
263 #define CSKY_FUNCTION_IS_NAKED(t) ((t) & CSKY_FT_NAKED)
265 struct csky_processors
267 const char *const name;
268 enum csky_processor_type core;
269 const char *arch;
270 enum csky_base_architecture base_arch;
271 enum csky_isa_feature isa_bits[CSKY_ISA_FEATURE_GET (max)];
274 static struct csky_processors all_cores[] =
276 #undef CSKY_CORE
277 #define CSKY_CORE(NAME, CORE, X, ARCH, ISA) \
278 {NAME, TARGET_CPU_##CORE, #ARCH, CSKY_BASE_ARCH_##ARCH, \
279 {ISA CSKY_ISA_FEATURE_GET (none)}},
280 #include "csky_cores.def"
281 #undef CSKY_CORE
282 {NULL, TARGET_CPU_csky_none, NULL, CSKY_BASE_ARCH_NONE, \
283 {CSKY_ISA_FEATURE_GET (none)}}
286 static struct csky_processors all_architectures[] =
288 #undef CSKY_ARCH
289 #define CSKY_ARCH(NAME, CORE, ARCH, ISA) \
290 {NAME, TARGET_CPU_##CORE, #ARCH, CSKY_BASE_ARCH_##ARCH, \
291 {ISA CSKY_ISA_FEATURE_GET (none)}},
292 #include "csky_cores.def"
293 #undef CSKY_ARCH
294 {NULL, TARGET_CPU_csky_none, NULL, CSKY_BASE_ARCH_NONE, \
295 {CSKY_ISA_FEATURE_GET (none)}}
298 struct csky_fpu_desc
300 const char *name;
301 enum csky_isa_feature isa_bits[CSKY_ISA_FEATURE_GET (max)];
304 static const struct csky_fpu_desc all_fpus[] =
306 #undef CSKY_FPU
307 #define CSKY_FPU(NAME, CNAME, ISA) \
308 {NAME, {ISA CSKY_ISA_FEATURE_GET (none)}},
309 #include "csky_cores.def"
310 #undef CSKY_FPU
313 /* Active target architecture. */
314 struct csky_build_target
316 /* Name of the target CPU, if known, or NULL if the target CPU was not
317 specified by the user (and inferred from the -march option). */
318 const char *core_name;
319 /* Name of the target ARCH. NULL if there is a selected CPU. */
320 const char *arch_name;
321 /* Preprocessor substring (never NULL). */
322 const char *arch_pp_name;
323 /* CPU identifier for the core we're compiling for (architecturally). */
324 enum csky_processor_type arch_core;
325 /* The base architecture value. */
326 enum csky_base_architecture base_arch;
327 /* Bitmap encapsulating the isa_bits for the target environment. */
328 sbitmap isa;
331 struct csky_build_target csky_active_target;
333 /* The following are used in the .md file as equivalents to bits. */
334 int csky_arch_isa_features[CSKY_ISA_FEATURE_GET (max)] = {0};
336 /* The highest CSKY architecture version supported by the target. */
337 enum csky_base_architecture csky_base_arch = CSKY_TARGET_ARCH_GET (NONE);
339 /* Forward definitions of types. */
340 typedef struct minipool_node Mnode;
341 typedef struct minipool_fixup Mfix;
343 static GTY(()) int tls_labelno;
346 /* Maximum constant offset that can be added/subtracted from SP in a
347 single instruction. For ck801, this is for addsp/subsp, otherwise
348 it is the range of addi/subi. */
349 #define CSKY_MAX_SP_ADJUST \
350 (CSKY_TARGET_ARCH (CK801) ? 508 : 4096)
353 /* Implement TARGET_CPU_CPP_BUILTINS. */
355 #define builtin_define(MACRO) cpp_define (pfile, MACRO)
357 void
358 csky_cpu_cpp_builtins (cpp_reader *pfile)
360 const char *arch_name = csky_active_target.arch_pp_name;
361 char *pp_name = (char *) alloca (1 + strlen (arch_name) + 4);
362 sprintf (pp_name, "__%s__", arch_name);
363 builtin_define (pp_name);
365 builtin_define ("__csky__=2");
366 builtin_define ("__CSKY__=2");
367 builtin_define ("__ckcore__=2");
368 builtin_define ("__CKCORE__=2");
370 builtin_define ("__CSKYABIV2__");
371 builtin_define ("__cskyabiv2__");
372 builtin_define ("__CSKYABI__=2");
373 builtin_define ("__cskyabi__=2");
375 if (TARGET_BIG_ENDIAN)
377 builtin_define ("__ckcoreBE__");
378 builtin_define ("__cskyBE__");
379 builtin_define ("__cskybe__");
380 builtin_define ("__CSKYBE__");
382 else
384 builtin_define ("__ckcoreLE__");
385 builtin_define ("__cskyLE__");
386 builtin_define ("__cskyle__");
387 builtin_define ("__CSKYLE__");
390 if (TARGET_HARD_FLOAT)
392 builtin_define ("__csky_hard_float__");
393 builtin_define ("__CSKY_HARD_FLOAT__");
394 if (TARGET_HARD_FLOAT_ABI)
396 builtin_define ("__csky_hard_float_abi__");
397 builtin_define ("__CSKY_HARD_FLOAT_ABI__");
399 if (TARGET_SINGLE_FPU)
401 builtin_define ("__csky_hard_float_fpu_sf__");
402 builtin_define ("__CSKY_HARD_FLOAT_FPU_SF__");
405 else
407 builtin_define ("__csky_soft_float__");
408 builtin_define ("__CSKY_SOFT_FLOAT__");
411 if (CSKY_ISA_FEATURE (fpv2_sf))
413 builtin_define ("__csky_fpuv2__");
414 builtin_define ("__CSKY_FPUV2__");
417 if (TARGET_SUPPORT_FPV3)
419 builtin_define ("__csky_fpuv3__");
420 builtin_define ("__CSKY_FPUV3__");
423 if (TARGET_ELRW)
425 builtin_define ("__csky_elrw__");
426 builtin_define ("__CSKY_ELRW__");
428 if (TARGET_ISTACK)
430 builtin_define ("__csky_istack__");
431 builtin_define ("__CSKY_ISTACK__");
433 if (TARGET_MP)
435 builtin_define ("__csky_mp__");
436 builtin_define ("__CSKY_MP__");
438 if (TARGET_CP)
440 builtin_define ("__csky_cp__");
441 builtin_define ("__CSKY_CP__");
443 if (TARGET_CACHE)
445 builtin_define ("__csky_cache__");
446 builtin_define ("__CSKY_CACHE__");
448 if (TARGET_SECURITY)
450 builtin_define ("__csky_security__");
451 builtin_define ("__CSKY_SECURITY__");
453 if (TARGET_TRUST)
455 builtin_define ("__csky_trust__");
456 builtin_define ("__CSKY_TRUST__");
458 if (TARGET_DSP)
460 builtin_define ("__csky_dsp__");
461 builtin_define ("__CSKY_DSP__");
463 if (TARGET_EDSP)
465 builtin_define ("__csky_edsp__");
466 builtin_define ("__CSKY_EDSP__");
468 if (TARGET_VDSP)
470 builtin_define ("__csky_vdsp__");
471 builtin_define ("__CSKY_VDSP__");
476 /******************************************************************
477 * Storage Layout *
478 ******************************************************************/
480 #undef TARGET_PROMOTE_FUNCTION_MODE
481 #define TARGET_PROMOTE_FUNCTION_MODE \
482 default_promote_function_mode_always_promote
484 #undef TARGET_CONSTANT_ALIGNMENT
485 #define TARGET_CONSTANT_ALIGNMENT csky_constant_alignment
487 #undef TARGET_MANGLE_TYPE
488 #define TARGET_MANGLE_TYPE csky_mangle_type
491 /******************************************************************
492 * Stack Layout and Calling Conventions *
493 ******************************************************************/
495 #undef TARGET_CAN_ELIMINATE
496 #define TARGET_CAN_ELIMINATE csky_can_eliminate
498 #undef TARGET_FUNCTION_ARG
499 #define TARGET_FUNCTION_ARG csky_function_arg
501 #undef TARGET_FUNCTION_ARG_ADVANCE
502 #define TARGET_FUNCTION_ARG_ADVANCE csky_function_arg_advance
504 #undef TARGET_FUNCTION_VALUE
505 #define TARGET_FUNCTION_VALUE csky_function_value
507 #undef TARGET_LIBCALL_VALUE
508 #define TARGET_LIBCALL_VALUE csky_libcall_value
510 #undef TARGET_FUNCTION_VALUE_REGNO_P
511 #define TARGET_FUNCTION_VALUE_REGNO_P csky_function_value_regno_p
513 #undef TARGET_SPLIT_COMPLEX_ARG
514 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
516 #undef TARGET_MUST_PASS_IN_STACK
517 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
519 #undef TARGET_ARG_PARTIAL_BYTES
520 #define TARGET_ARG_PARTIAL_BYTES csky_arg_partial_bytes
522 #undef TARGET_PASS_BY_REFERENCE
523 #define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_must_pass_in_stack
525 #undef TARGET_ASM_OUTPUT_MI_THUNK
526 #define TARGET_ASM_OUTPUT_MI_THUNK csky_output_mi_thunk
528 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
529 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK \
530 hook_bool_const_tree_hwi_hwi_const_tree_true
532 #undef TARGET_ASM_FUNCTION_PROLOGUE
533 #define TARGET_ASM_FUNCTION_PROLOGUE csky_output_function_prologue
535 #undef TARGET_ASM_FUNCTION_EPILOGUE
536 #define TARGET_ASM_FUNCTION_EPILOGUE csky_output_function_epilogue
538 #undef TARGET_WARN_FUNC_RETURN
539 #define TARGET_WARN_FUNC_RETURN csky_warn_func_return
541 #undef TARGET_RETURN_IN_MEMORY
542 #define TARGET_RETURN_IN_MEMORY csky_return_in_memory
545 /******************************************************************
546 * Implementing the Varargs Macros *
547 ******************************************************************/
550 #undef TARGET_SETUP_INCOMING_VARARGS
551 #define TARGET_SETUP_INCOMING_VARARGS csky_setup_incoming_varargs
554 /******************************************************************
555 * Implicit Calls to Library Routines *
556 ******************************************************************/
559 #undef TARGET_INIT_LIBFUNCS
560 #define TARGET_INIT_LIBFUNCS csky_init_libfuncs
563 /******************************************************************
564 * Dividing the Output into Sections (Texts, Data, . . . ) *
565 ******************************************************************/
568 #undef TARGET_HAVE_TLS
569 #define TARGET_HAVE_TLS TARGET_CSKY_LINUX
572 /******************************************************************
573 * Defining target-specific uses of __attribute__ *
574 ******************************************************************/
577 #undef TARGET_ATTRIBUTE_TABLE
578 #define TARGET_ATTRIBUTE_TABLE csky_attribute_table
580 #undef TARGET_OPTION_OVERRIDE
581 #define TARGET_OPTION_OVERRIDE csky_option_override
584 /* Implement the BRANCH_COST target macro. */
587 csky_default_branch_cost (bool speed_p ATTRIBUTE_UNUSED,
588 bool predictable_p ATTRIBUTE_UNUSED)
590 return csky_branch_cost;
593 bool
594 csky_default_logical_op_non_short_circuit (void)
596 return BRANCH_COST (optimize_function_for_speed_p (cfun), false) >= 2;
599 /******************************************************************
600 * Register Usage *
601 ******************************************************************/
603 #undef TARGET_HARD_REGNO_NREGS
604 #define TARGET_HARD_REGNO_NREGS csky_hard_regno_nregs
606 #undef TARGET_HARD_REGNO_MODE_OK
607 #define TARGET_HARD_REGNO_MODE_OK csky_hard_regno_mode_ok
609 #undef TARGET_MODES_TIEABLE_P
610 #define TARGET_MODES_TIEABLE_P csky_modes_tieable_p
612 #undef TARGET_CONDITIONAL_REGISTER_USAGE
613 #define TARGET_CONDITIONAL_REGISTER_USAGE csky_conditional_register_usage
615 #undef TARGET_CLASS_LIKELY_SPILLED_P
616 #define TARGET_CLASS_LIKELY_SPILLED_P csky_class_likely_spilled_p
618 #undef TARGET_PREFERRED_RELOAD_CLASS
619 #define TARGET_PREFERRED_RELOAD_CLASS csky_preferred_reload_class
621 #undef TARGET_CLASS_MAX_NREGS
622 #define TARGET_CLASS_MAX_NREGS csky_class_max_nregs
624 #undef TARGET_SECONDARY_RELOAD
625 #define TARGET_SECONDARY_RELOAD csky_secondary_reload
627 #undef TARGET_SPILL_CLASS
628 #define TARGET_SPILL_CLASS csky_spill_class
631 /******************************************************************
632 * Addressing Modes *
633 ******************************************************************/
636 #undef TARGET_CANNOT_FORCE_CONST_MEM
637 #define TARGET_CANNOT_FORCE_CONST_MEM csky_cannot_force_const_mem
639 #undef TARGET_LEGITIMATE_CONSTANT_P
640 #define TARGET_LEGITIMATE_CONSTANT_P csky_legitimate_constant_p
642 #undef TARGET_LEGITIMIZE_ADDRESS
643 #define TARGET_LEGITIMIZE_ADDRESS csky_legitimize_address
645 #undef TARGET_LEGITIMATE_ADDRESS_P
646 #define TARGET_LEGITIMATE_ADDRESS_P csky_legitimate_address_p
649 /******************************************************************
650 * Others *
651 ******************************************************************/
654 #undef TARGET_CANNOT_COPY_INSN_P
655 #define TARGET_CANNOT_COPY_INSN_P csky_cannot_copy_insn_p
658 /******************************************************************
659 * Assembler Format *
660 ******************************************************************/
663 #undef TARGET_PRINT_OPERAND
664 #define TARGET_PRINT_OPERAND csky_print_operand
666 #undef TARGET_PRINT_OPERAND_ADDRESS
667 #define TARGET_PRINT_OPERAND_ADDRESS csky_print_operand_address
669 #undef TARGET_ASM_UNALIGNED_HI_OP
670 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
672 #undef TARGET_ASM_UNALIGNED_SI_OP
673 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
675 #undef TARGET_DWARF_REGISTER_SPAN
676 #define TARGET_DWARF_REGISTER_SPAN csky_dwarf_register_span
679 /******************************************************************
680 * Miscellaneous Parameters *
681 ******************************************************************/
684 #undef TARGET_MACHINE_DEPENDENT_REORG
685 #define TARGET_MACHINE_DEPENDENT_REORG csky_reorg
687 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
688 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS csky_allocate_stack_slots_for_args
690 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
691 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
694 /******************************************************************
695 * Trampolines for Nested Functions *
696 ******************************************************************/
699 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
700 #define TARGET_ASM_TRAMPOLINE_TEMPLATE csky_asm_trampoline_template
701 #undef TARGET_TRAMPOLINE_INIT
702 #define TARGET_TRAMPOLINE_INIT csky_trampoline_init
704 /* The low bit is ignored by jsr and jmp instructions so is safe to use. */
705 #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
706 #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1
708 /******************************************************************
709 * Describing Relative Costs of Operations *
710 ******************************************************************/
713 #undef TARGET_REGISTER_MOVE_COST
714 #define TARGET_REGISTER_MOVE_COST csky_register_move_cost
716 #undef TARGET_MEMORY_MOVE_COST
717 #define TARGET_MEMORY_MOVE_COST csky_memory_move_cost
719 #undef TARGET_RTX_COSTS
720 #define TARGET_RTX_COSTS csky_rtx_costs
722 #undef TARGET_ADDRESS_COST
723 #define TARGET_ADDRESS_COST csky_address_cost
726 /******************************************************************
727 * Anchor address *
728 ******************************************************************/
731 /* FIXME: the max offset is related to mode size, the following is
732 defined according to SImode. How to deal with HImode and
733 QImode, and should the min offset be defined? */
734 #undef TARGET_MAX_ANCHOR_OFFSET
735 #define TARGET_MAX_ANCHOR_OFFSET \
736 ((TARGET_MINI_REGISTERS && optimize_size) ? 127 : 4095)
739 /******************************************************************
740 * Condition Code Status *
741 ******************************************************************/
744 #undef TARGET_FIXED_CONDITION_CODE_REGS
745 #define TARGET_FIXED_CONDITION_CODE_REGS csky_fixed_condition_code_regs
748 /******************************************************************
749 * Adjusting the Instruction Scheduler *
750 ******************************************************************/
753 #undef TARGET_SCHED_ISSUE_RATE
754 #define TARGET_SCHED_ISSUE_RATE csky_sched_issue_rate
756 #undef TARGET_SCHED_ADJUST_COST
757 #define TARGET_SCHED_ADJUST_COST csky_sched_adjust_cost
760 /******************************************************************
761 * Builtin *
762 ******************************************************************/
765 #undef TARGET_INIT_BUILTINS
766 #define TARGET_INIT_BUILTINS csky_init_builtins
769 /* The declaration of functions. */
770 static void push_csky_minipool_fix (rtx_insn *, HOST_WIDE_INT, rtx *,
771 machine_mode, rtx);
772 static void csky_print_operand (FILE *stream, rtx x, int code);
775 /* Define a table to map ISR attribute arguments onto function type
776 modifiers. */
778 typedef struct
780 const char *const arg;
781 const unsigned long return_value;
782 } isr_attribute_entry;
784 static const isr_attribute_entry isr_attribute_map[] =
786 {"irq", CSKY_FT_ISR },
787 {"IRQ", CSKY_FT_ISR },
788 {"fiq", CSKY_FT_FIQ },
789 {"FIQ", CSKY_FT_FIQ },
790 {NULL, CSKY_FT_NORMAL }
794 /* Return the function type of the current function, if it has not been
795 determined, return CSKY_FT_UNKNOWN. */
797 static unsigned long
798 get_csky_isr_type (tree argument)
800 const isr_attribute_entry *ptr;
801 const char *arg;
803 /* if argument is NULL, set default value ISR. */
804 if (argument == NULL_TREE)
805 return CSKY_FT_ISR;
807 if (TREE_VALUE (argument) == NULL_TREE
808 || TREE_CODE (TREE_VALUE (argument)) != STRING_CST)
809 return CSKY_FT_UNKNOWN;
811 arg = TREE_STRING_POINTER (TREE_VALUE (argument));
813 for (ptr = isr_attribute_map; ptr->arg != NULL; ptr++)
814 if (strcmp (arg, ptr->arg) == 0)
815 return ptr->return_value;
817 return CSKY_FT_UNKNOWN;
820 /* Classify cfun as a normal function or some sort of interrupt
821 handler, and set the corresponding bits in cfun->machine->func_type. */
823 static unsigned long
824 get_csky_current_func_type (void)
826 if (CSKY_FUNCTION_TYPE (cfun->machine->func_type) == CSKY_FT_UNKNOWN)
828 unsigned long type = CSKY_FT_UNKNOWN;
829 tree a;
830 tree attr;
832 gcc_assert (TREE_CODE (current_function_decl) == FUNCTION_DECL);
834 attr = DECL_ATTRIBUTES (current_function_decl);
835 a = lookup_attribute ("naked", attr);
836 if (a != NULL_TREE)
837 type |= CSKY_FT_NAKED;
838 a = lookup_attribute ("isr", attr);
839 if (a == NULL_TREE)
840 a = lookup_attribute ("interrupt", attr);
841 if (a == NULL_TREE)
842 type |= CSKY_FT_NORMAL;
843 else
844 type |= get_csky_isr_type (TREE_VALUE (a));
846 cfun->machine->func_type = type;
849 return cfun->machine->func_type;
852 /* These typedefs are located at the start of this file, so that
853 they can be used in the prototypes there. This comment is to
854 remind readers of that fact so that the following structures
855 can be understood more easily.
857 typedef struct minipool_node Mnode;
858 typedef struct minipool_fixup Mfix; */
860 struct minipool_node
862 /* Doubly linked chain of entries. */
863 Mnode *next;
864 Mnode *prev;
865 /* The maximum offset into the code that this entry can be placed. While
866 pushing fixes for forward references, all entries are sorted in order
867 of increasing max_address. */
868 HOST_WIDE_INT max_address;
869 /* Similarly for an entry inserted for a backwards ref. */
870 HOST_WIDE_INT min_address;
871 /* The number of fixes referencing this entry. This can become zero
872 if we "unpush" an entry. In this case we ignore the entry when we
873 come to emit the code. */
874 int refcount;
875 /* The offset from the start of the minipool. */
876 HOST_WIDE_INT offset;
877 /* The value in table. */
878 rtx value;
879 /* The mode of value. */
880 machine_mode mode;
881 /* The size of the value. */
882 int fix_size;
885 struct minipool_fixup
887 Mfix *next;
888 rtx_insn *insn;
889 HOST_WIDE_INT address;
890 rtx *loc;
891 machine_mode mode;
892 int fix_size;
893 rtx value;
894 Mnode *minipool;
895 HOST_WIDE_INT forwards;
896 HOST_WIDE_INT backwards;
899 static Mnode *minipool_vector_head;
900 static Mnode *minipool_vector_tail;
901 static rtx minipool_vector_label;
902 static HOST_WIDE_INT constpool_label_no = 0;
904 /* Obstack for minipool constant handling. */
905 static struct obstack minipool_obstack;
906 static char *minipool_startobj;
907 /* The linked list of all minipool fixes required for this function. */
908 Mfix *minipool_fix_head;
909 Mfix *minipool_fix_tail;
910 /* The fix entry for the current minipool, once it has been placed. */
911 Mfix *minipool_barrier;
913 /* Allow GC scanning of the minipool obstack. */
915 static void
916 csky_add_gc_roots (void)
918 gcc_obstack_init (&minipool_obstack);
919 minipool_startobj = (char *) obstack_alloc (&minipool_obstack, 0);
922 /* Implement TARGET_CONSTANT_ALIGNMENT.
923 Make strings word-aligned so strcpy from constants will be faster. */
925 static HOST_WIDE_INT
926 csky_constant_alignment (const_tree exp, HOST_WIDE_INT align)
928 if (TREE_CODE (exp) == STRING_CST
929 && !optimize_size
930 && align < BITS_PER_WORD)
931 return BITS_PER_WORD;
932 return align;
935 /* Record that there is a natural barrier in the insn stream at
936 ADDRESS. */
938 static void
939 push_csky_minipool_barrier (rtx_insn *insn, HOST_WIDE_INT address)
941 Mfix *fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (*fix));
943 fix->insn = insn;
944 fix->address = address;
946 fix->next = NULL;
947 if (minipool_fix_head != NULL)
948 minipool_fix_tail->next = fix;
949 else
950 minipool_fix_head = fix;
952 minipool_fix_tail = fix;
955 /* Compute the size of a vector jump table. */
957 static HOST_WIDE_INT
958 get_csky_jump_table_size (rtx insn)
960 /* ADDR_VECs only take room if read-only data does into the text
961 section. */
962 if (JUMP_TABLES_IN_TEXT_SECTION || readonly_data_section == text_section)
964 rtx body = PATTERN (insn);
965 int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0;
966 HOST_WIDE_INT size;
967 HOST_WIDE_INT modesize;
969 modesize = GET_MODE_SIZE (GET_MODE (body));
970 size = modesize * XVECLEN (body, elt);
971 switch (modesize)
973 case 1:
974 /* Round up size of TBB table to a halfword boundary. */
975 size = (size + 1) & ~(HOST_WIDE_INT)1;
976 break;
977 case 2:
978 /* No padding necessary for TBH. */
979 break;
980 case 4:
981 break;
982 default:
983 gcc_unreachable ();
985 return size;
988 return 0;
992 /* Scan INSN and note any of its operands that need fixing.
993 If DO_PUSHES is false we do not actually push any of the fixups
994 needed. The function returns TRUE if any fixups were needed/pushed. */
996 static bool
997 note_csky_invalid_constants (rtx_insn *insn, HOST_WIDE_INT address,
998 int do_pushes)
1000 bool result = false;
1001 int opno;
1003 extract_constrain_insn (insn);
1005 if (recog_data.n_alternatives == 0)
1006 return false;
1008 /* Fill in recog_op_alt with information about the constraints of
1009 this insn. */
1010 preprocess_constraints (insn);
1012 const operand_alternative *op_alt = which_op_alt ();
1013 for (opno = 0; opno < recog_data.n_operands; opno++)
1015 /* Things we need to fix can only occur in inputs. */
1016 if (recog_data.operand_type[opno] != OP_IN)
1017 continue;
1019 /* If this alternative is a memory reference, then any mention
1020 of constants in this alternative is really to fool reload
1021 into allowing us to accept one there. We need to fix them up
1022 now so that we output the right code. */
1023 if (op_alt[opno].memory_ok)
1025 rtx op = recog_data.operand[opno];
1027 if (CONSTANT_P (op))
1029 if (do_pushes)
1030 push_csky_minipool_fix (insn, address,
1031 recog_data.operand_loc[opno],
1032 recog_data.operand_mode[opno], op);
1033 result = true;
1038 return result;
1042 /* Add a constant to the minipool for a forward reference. Returns the
1043 node added or NULL if the constant will not fit in this pool. */
1045 static Mnode *
1046 add_csky_minipool_forward_ref (Mfix *fix)
1048 /* If set, max_mp is the first pool_entry that has a lower
1049 constraint than the one we are trying to add. */
1050 Mnode *max_mp = NULL;
1051 HOST_WIDE_INT max_address = fix->address + fix->forwards;
1052 Mnode *mp;
1054 /* If the minipool starts before the end of FIX->INSN then this FIX
1055 cannot be placed into the current pool. Furthermore, adding the
1056 new constant pool entry may cause the pool to start FIX_SIZE bytes
1057 earlier. */
1058 if (minipool_vector_head
1059 && (fix->address + get_attr_length (fix->insn)
1060 >= minipool_vector_head->max_address - fix->fix_size))
1061 return NULL;
1063 /* Scan the pool to see if a constant with the same value has
1064 already been added. While we are doing this, also note the
1065 location where we must insert the constant if it doesn't already
1066 exist. */
1067 for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
1069 if (GET_CODE (fix->value) == GET_CODE (mp->value)
1070 && fix->mode == mp->mode
1071 && (GET_CODE (fix->value) != CODE_LABEL
1072 || (CODE_LABEL_NUMBER (fix->value)
1073 == CODE_LABEL_NUMBER (mp->value)))
1074 && rtx_equal_p (fix->value, mp->value))
1076 /* More than one fix references this entry. */
1077 mp->refcount++;
1078 return mp;
1081 /* Note the insertion point if necessary. */
1082 if (max_mp == NULL && mp->max_address > max_address)
1083 max_mp = mp;
1086 /* The value is not currently in the minipool, so we need to create
1087 a new entry for it. If MAX_MP is NULL, the entry will be put on
1088 the end of the list since the placement is less constrained than
1089 any existing entry. Otherwise, we insert the new fix before
1090 MAX_MP and, if necessary, adjust the constraints on the other
1091 entries. */
1092 mp = XNEW (Mnode);
1093 mp->fix_size = fix->fix_size;
1094 mp->mode = fix->mode;
1095 mp->value = fix->value;
1096 mp->refcount = 1;
1097 /* Not yet required for a backwards ref. */
1098 mp->min_address = -65536;
1100 if (max_mp == NULL)
1102 mp->max_address = max_address;
1103 mp->next = NULL;
1104 mp->prev = minipool_vector_tail;
1106 if (mp->prev == NULL)
1108 minipool_vector_head = mp;
1109 minipool_vector_label
1110 = gen_csky_constpool_label (gen_rtx_CONST_INT (VOIDmode,
1111 constpool_label_no++));
1113 else
1114 mp->prev->next = mp;
1116 minipool_vector_tail = mp;
1118 else
1120 if (max_address > max_mp->max_address - mp->fix_size)
1121 mp->max_address = max_mp->max_address - mp->fix_size;
1122 else
1123 mp->max_address = max_address;
1125 mp->next = max_mp;
1126 mp->prev = max_mp->prev;
1127 max_mp->prev = mp;
1128 if (mp->prev != NULL)
1129 mp->prev->next = mp;
1130 else
1131 minipool_vector_head = mp;
1134 /* Save the new entry. */
1135 max_mp = mp;
1137 /* Scan over the preceding entries and adjust their addresses as
1138 required. */
1139 while (mp->prev != NULL
1140 && mp->prev->max_address > mp->max_address - mp->prev->fix_size)
1142 mp->prev->max_address = mp->max_address - mp->prev->fix_size;
1143 mp = mp->prev;
1146 return max_mp;
1150 /* Return the cost of forcibly inserting a barrier after INSN. */
1152 static int
1153 get_csky_barrier_cost (rtx_insn *insn)
1155 /* Basing the location of the pool on the loop depth is preferable,
1156 but at the moment, the basic block information seems to be
1157 corrupt by this stage of the compilation. */
1158 int base_cost = 50;
1159 rtx next = next_nonnote_insn (insn);
1161 if (next != NULL && GET_CODE (next) == CODE_LABEL)
1162 base_cost -= 20;
1164 switch (GET_CODE (insn))
1166 case CODE_LABEL:
1167 /* It will always be better to place the table before the label, rather
1168 than after it. */
1169 return 50;
1171 case INSN:
1172 case CALL_INSN:
1173 return base_cost;
1175 case JUMP_INSN:
1176 return base_cost - 10;
1178 default:
1179 return base_cost + 10;
1184 /* Find the best place in the insn stream in the range
1185 (FIX->address,MAX_ADDRESS) to forcibly insert a minipool barrier.
1186 Create the barrier by inserting a jump and add a new fix entry for
1187 it. */
1189 static Mfix *
1190 create_csky_fix_barrier (Mfix *fix, Mfix *fix_next,
1191 HOST_WIDE_INT max_address)
1193 rtx_barrier *barrier;
1194 rtx_insn *from = (fix ? fix->insn : get_insns ());
1195 /* The instruction after which we will insert the jump. */
1196 rtx_insn *selected = NULL;
1197 int selected_cost;
1198 /* The address at which the jump instruction will be placed. */
1199 HOST_WIDE_INT selected_address = 0;
1200 Mfix *new_fix;
1201 HOST_WIDE_INT count = (fix ? fix->address : 0);
1202 HOST_WIDE_INT max_count = max_address;
1203 rtx_code_label *label = gen_label_rtx ();
1205 selected_cost = get_csky_barrier_cost (from);
1207 while (from && count < max_count)
1209 int new_cost;
1210 rtx_jump_table_data *table;
1212 /* Count the length of this insn. */
1213 count += get_attr_length (from);
1215 /* If there is a jump table, add its length. */
1216 if (tablejump_p (from, NULL, &table))
1218 count += get_csky_jump_table_size (table);
1220 /* Jump tables aren't in a basic block, so base the cost on
1221 the dispatch insn. If we select this location, we will
1222 still put the pool after the table. */
1223 new_cost = get_csky_barrier_cost (from);
1225 if (count < max_count
1226 && (!selected || new_cost <= selected_cost))
1228 selected = table;
1229 selected_cost = new_cost;
1230 selected_address = count;
1233 /* Continue after the dispatch table. */
1234 from = NEXT_INSN (table);
1235 continue;
1238 new_cost = get_csky_barrier_cost (from);
1240 if (count < max_count
1241 && (!selected || new_cost <= selected_cost))
1243 selected = from;
1244 selected_cost = new_cost;
1245 selected_address = count;
1248 from = NEXT_INSN (from);
1251 /* Make sure that we found a place to insert the jump. */
1252 gcc_assert (selected);
1254 /* Create a new JUMP_INSN that branches around a barrier. */
1255 from = emit_jump_insn_after (gen_jump (label), selected);
1256 JUMP_LABEL (from) = label;
1257 barrier = emit_barrier_after (from);
1258 emit_label_after (label, barrier);
1260 /* Create a minipool barrier entry for the new barrier. */
1261 new_fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (* new_fix));
1262 new_fix->insn = barrier;
1263 new_fix->address = selected_address;
1264 if (fix)
1266 new_fix->next = fix->next;
1267 fix->next = new_fix;
1269 else
1270 new_fix->next = fix_next;
1272 return new_fix;
1276 /* Print a symbolic form of the constant X to the dump file F.
1277 This is used for dump output for -mconstpool in the target-dependent
1278 reorg pass. */
1280 static void
1281 print_csky_value (FILE *f, rtx x)
1283 switch (GET_CODE (x))
1285 case CONST_INT:
1286 fprintf (f, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
1287 return;
1289 case CONST_DOUBLE:
1290 fprintf (f, "<0x%lx,0x%lx>", (long)XWINT (x, 2), (long)XWINT (x, 3));
1291 return;
1293 case CONST_VECTOR:
1295 int i;
1297 fprintf (f, "<");
1298 for (i = 0; i < CONST_VECTOR_NUNITS (x); i++)
1300 fprintf (f, HOST_WIDE_INT_PRINT_HEX,
1301 INTVAL (CONST_VECTOR_ELT (x, i)));
1302 if (i < (CONST_VECTOR_NUNITS (x) - 1))
1303 fputc (',', f);
1305 fprintf (f, ">");
1307 return;
1309 case CONST_STRING:
1310 fprintf (f, "\"%s\"", XSTR (x, 0));
1311 return;
1313 case SYMBOL_REF:
1314 fprintf (f, "`%s'", XSTR (x, 0));
1315 return;
1317 case LABEL_REF:
1318 fprintf (f, "L%d", INSN_UID (XEXP (x, 0)));
1319 return;
1321 case CONST:
1322 print_csky_value (f, XEXP (x, 0));
1323 return;
1325 case PLUS:
1326 print_csky_value (f, XEXP (x, 0));
1327 fprintf (f, "+");
1328 print_csky_value (f, XEXP (x, 1));
1329 return;
1331 case PC:
1332 fprintf (f, "pc");
1333 return;
1335 default:
1336 fprintf (f, "????");
1337 return;
1342 /* Record INSN, which will need fixing up to load a value from the
1343 minipool. ADDRESS is the offset of the insn since the start of the
1344 function; LOC is a pointer to the part of the insn which requires
1345 fixing; VALUE is the constant that must be loaded, which is of type
1346 MODE. */
1348 static void
1349 push_csky_minipool_fix (rtx_insn *insn, HOST_WIDE_INT address, rtx *loc,
1350 machine_mode mode, rtx value)
1352 #define CSKY_ELRW16_RANGE 1400
1353 #define CSKY_LRW16_RANGE 700
1354 #define CSKY_CONSTANT_POOL_RANGE (TARGET_ELRW ? CSKY_ELRW16_RANGE \
1355 : CSKY_LRW16_RANGE)
1357 /* Fixes less than a word need padding out to a word boundary. */
1358 #define CSKY_MINIPOOL_FIX_SIZE(mode) \
1359 (GET_MODE_SIZE ((mode)) >= 4 ? GET_MODE_SIZE ((mode)) : 4)
1361 Mfix *fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (*fix));
1363 fix->insn = insn;
1364 fix->address = address;
1365 fix->loc = loc;
1366 fix->mode = mode;
1367 fix->fix_size = CSKY_MINIPOOL_FIX_SIZE (mode);
1368 fix->value = value;
1369 fix->forwards = CSKY_CONSTANT_POOL_RANGE;
1370 fix->backwards = 0;
1371 fix->minipool = NULL;
1373 /* If an insn doesn't have a range defined for it, then it isn't
1374 expecting to be reworked by this code. Better to stop now than
1375 to generate duff assembly code. */
1376 gcc_assert (fix->forwards || fix->backwards);
1378 if (dump_file)
1380 fprintf (dump_file,
1381 ";; %smode fixup for i%d; addr %lu, range (%ld,%ld): ",
1382 GET_MODE_NAME (mode),
1383 INSN_UID (insn), (unsigned long) address,
1384 -1 * (long)fix->backwards, (long)fix->forwards);
1385 print_csky_value (dump_file, fix->value);
1386 fprintf (dump_file, "\n");
1389 /* Add it to the chain of fixes. */
1390 fix->next = NULL;
1392 if (minipool_fix_head != NULL)
1393 minipool_fix_tail->next = fix;
1394 else
1395 minipool_fix_head = fix;
1397 minipool_fix_tail = fix;
1401 /* Fill in the offsets for minipool entries. */
1403 static void
1404 assign_csky_minipool_offsets (Mfix *barrier)
1406 HOST_WIDE_INT offset = 0;
1407 Mnode *mp;
1409 minipool_barrier = barrier;
1411 for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
1413 mp->offset = offset;
1415 if (mp->refcount > 0)
1416 offset += mp->fix_size;
1421 /* Output the literal table. */
1423 static HOST_WIDE_INT
1424 dump_csky_minipool (rtx_insn *scan)
1426 Mnode *mp;
1427 Mnode *nmp;
1428 HOST_WIDE_INT pool_length = 0;
1430 if (dump_file)
1431 fprintf (dump_file,
1432 ";; Emitting minipool after insn %u;\
1433 address %ld; align %d (bytes)\n",
1434 INSN_UID (scan), (unsigned long) minipool_barrier->address, 4);
1436 scan = emit_insn_after (gen_align_4 (), scan);
1437 scan = emit_insn_after (minipool_vector_label, scan);
1439 for (mp = minipool_vector_head; mp != NULL; mp = nmp)
1441 if (mp->refcount > 0)
1443 if (dump_file)
1445 fprintf (dump_file, ";; Offset %u, min %ld, max %ld ",
1446 (unsigned) mp->offset, (unsigned long) mp->min_address,
1447 (unsigned long) mp->max_address);
1448 print_csky_value (dump_file, mp->value);
1449 fputc ('\n', dump_file);
1452 switch (mp->fix_size)
1454 case 4:
1455 scan = emit_insn_after (gen_consttable_4 (mp->value), scan);
1456 pool_length += 4;
1457 break;
1458 case 8:
1459 scan = emit_insn_after (gen_consttable_8 (mp->value), scan);
1460 pool_length += 8;
1461 break;
1462 default:
1463 gcc_unreachable ();
1467 nmp = mp->next;
1468 free (mp);
1471 minipool_vector_head = minipool_vector_tail = NULL;
1472 scan = emit_barrier_after (scan);
1474 return pool_length;
1477 /* Return true if INSN is a minipool load or instruction that will be
1478 converted to one. It is assumed that INSN has type attribute "load". */
1480 bool
1481 csky_minipool_load_p (rtx_insn *insn)
1483 rtx op1, addr;
1485 extract_insn_cached (insn);
1487 op1 = recog_data.operand[1];
1489 /* This is a constant that has not yet been turned into
1490 a minipool load. */
1491 if (CONSTANT_P (op1))
1492 return true;
1494 /* Constant pool loads are label_refs. */
1495 if (GET_CODE (op1) == ZERO_EXTEND || GET_CODE (op1) == SIGN_EXTEND)
1496 op1 = XEXP (op1, 0);
1497 if (GET_CODE (op1) != MEM)
1498 return false;
1499 addr = XEXP (op1, 0);
1500 if (GET_CODE (addr) == PLUS && CONST_INT_P (XEXP (addr, 1)))
1501 addr = XEXP (addr, 0);
1502 return GET_CODE (addr) == LABEL_REF;
1506 /* Compute the attribute "length" of push or pop insn, according to
1507 the registers it uses. */
1510 csky_compute_pushpop_length (rtx *operands)
1512 rtx parallel_op = operands[2];
1513 /* Initialize to elements number of PARALLEL. */
1514 unsigned indx = XVECLEN (parallel_op, 0) - 1;
1515 unsigned first_indx = 0;
1516 unsigned regno = REGNO (operands[1]);
1518 if (regno > CSKY_LR_REGNUM)
1519 return 4;
1521 /* Check each register in the list. */
1522 for (; indx > first_indx; indx--)
1524 regno = REGNO (XEXP (XVECEXP (parallel_op, 0, indx), 0));
1525 /* If a register number higher than 15 is included, a 32-bit insn
1526 is used. */
1527 if (regno > CSKY_LR_REGNUM)
1528 return 4;
1531 return 2;
1534 /* Emit constant pools for -mconstpool. */
1536 static void
1537 csky_emit_constant_pools (void)
1539 rtx_insn *insn;
1540 HOST_WIDE_INT address = 0;
1541 Mfix *fix;
1543 minipool_fix_head = minipool_fix_tail = NULL;
1545 /* The first insn must always be a note, or the code below won't
1546 scan it properly. */
1547 insn = get_insns ();
1548 gcc_assert (NOTE_P (insn));
1550 /* Scan the insns and record the operands that need fixing. */
1551 for (insn = next_nonnote_insn (insn); insn;
1552 insn = next_nonnote_insn (insn))
1554 if (BARRIER_P (insn))
1555 push_csky_minipool_barrier (insn, address);
1556 else if (INSN_P (insn))
1558 rtx_jump_table_data *table;
1560 note_csky_invalid_constants (insn, address, true);
1561 address += get_attr_length (insn);
1563 /* If the insn is a vector jump, add the size of the table
1564 and skip the table. */
1565 if (tablejump_p (insn, NULL, &table))
1567 address += get_csky_jump_table_size (table);
1568 insn = table;
1573 fix = minipool_fix_head;
1575 /* Now scan the fixups and perform the required changes. */
1576 while (fix)
1578 Mfix *ftmp;
1579 Mfix *last_added_fix;
1580 Mfix *last_barrier = NULL;
1581 Mfix *this_fix;
1582 Mnode *mp;
1583 bool has_pending_const = false;
1585 /* Check if there is any pending constant not processed. */
1586 for (mp = minipool_vector_head; mp; mp = mp->next)
1587 if (mp->refcount > 0)
1589 has_pending_const = true;
1590 break;
1593 /* If no pending constant, skip over barrier insns. */
1594 if (has_pending_const == false)
1596 while (fix && BARRIER_P (fix->insn))
1597 fix = fix->next;
1598 if (fix == NULL)
1599 break;
1602 last_added_fix = NULL;
1604 for (ftmp = fix; ftmp; ftmp = ftmp->next)
1606 if (BARRIER_P (ftmp->insn))
1608 if (minipool_vector_head
1609 && ftmp->address >= minipool_vector_head->max_address)
1610 break;
1612 last_barrier = ftmp;
1614 else
1616 ftmp->minipool = add_csky_minipool_forward_ref (ftmp);
1617 if (ftmp->minipool == NULL)
1618 break;
1620 last_added_fix = ftmp; /* Keep track of the last fix added. */
1623 /* If the last added fix is a barrier, dump minipool after it. */
1624 if (last_added_fix && BARRIER_P (last_added_fix->insn))
1625 ftmp = last_barrier;
1626 else
1628 /* ftmp is first fix that we can't fit into this pool.
1629 Insert a new barrier in the code somewhere between the previous
1630 fix and this one, and arrange to jump around it. */
1631 HOST_WIDE_INT max_address;
1633 /* The last item on the list of fixes must be a barrier, so
1634 we can never run off the end of the list of fixes without
1635 last_barrier being set. */
1636 gcc_assert (ftmp);
1638 /* Check that there isn't another fix that is in range that
1639 we couldn't fit into this pool because the pool was
1640 already too large: we need to put the pool before such an
1641 instruction. The pool itself may come just after the
1642 fix because create_csky_fix_barrier also allows space for a
1643 jump instruction. */
1644 max_address = minipool_vector_head->max_address;
1645 if (ftmp->address < max_address)
1646 max_address = ftmp->address + 1;
1647 last_barrier = create_csky_fix_barrier (last_added_fix, ftmp,
1648 max_address);
1651 assign_csky_minipool_offsets (last_barrier);
1653 /* Scan over the fixes we have identified for this pool, fixing them
1654 up and adding the constants to the pool itself. */
1655 for (this_fix = fix; this_fix && ftmp != this_fix;
1656 this_fix = this_fix->next)
1658 if (GET_CODE (this_fix->insn) != BARRIER)
1660 rtx addr
1661 = plus_constant (Pmode,
1662 gen_rtx_LABEL_REF (VOIDmode,
1663 minipool_vector_label),
1664 this_fix->minipool->offset);
1665 rtx insn_body = PATTERN (this_fix->insn);
1666 rtx src = XEXP (insn_body, 1);
1667 *this_fix->loc = gen_rtx_MEM (this_fix->mode, addr);
1668 if (GET_CODE (this_fix->value) == SYMBOL_REF)
1669 emit_insn_after (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
1670 gen_rtvec (1, src),
1671 VUNSPEC_SYMBOL_REF),
1672 this_fix->insn);
1675 dump_csky_minipool (last_barrier->insn);
1676 fix = ftmp;
1677 if (fix->next == NULL)
1678 break;
1681 /* Free the minipool memory. */
1682 obstack_free (&minipool_obstack, minipool_startobj);
1686 /* Implement TARGET_MACHINE_DEPENDENT_REORG. This handles
1687 -mconstpool output. */
1689 static void
1690 csky_reorg (void)
1692 if (TARGET_CONSTANT_POOL)
1693 csky_emit_constant_pools ();
1697 /* Check to see if the current function contains a branch insn with the
1698 far jump attribute set. Such a function uses the LR register. */
1700 static bool
1701 csky_far_jump_used_p (void)
1703 rtx_insn *insn;
1704 if (cfun->machine->far_jump_used)
1705 return true;
1707 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1708 if (GET_CODE (insn) == JUMP_INSN
1709 /* Ignore tablejump patterns. */
1710 && GET_CODE (PATTERN (insn)) != ADDR_VEC
1711 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
1712 && get_attr_far_jump (insn) == FAR_JUMP_YES)
1714 cfun->machine->far_jump_used = 1;
1715 return true;
1717 return false;
1721 /* Return the mask of registers used by the current function. Set
1722 COUNT to the number of registers used. */
1724 static unsigned int
1725 get_csky_live_regs (int *count)
1727 int reg;
1728 unsigned int live_regs_mask = 0;
1730 *count = 0;
1731 for (reg = 0; reg < CSKY_NGPR_REGS; reg++)
1733 bool save = false;
1735 /* Ignore unsupported registers. */
1736 if (CSKY_TARGET_ARCH (CK801) && reg > 8 && reg < 13)
1737 continue;
1738 if ((CSKY_TARGET_ARCH (CK801)
1739 || CSKY_TARGET_ARCH (CK802)
1740 || CSKY_TARGET_ARCH (CK803))
1741 && reg > 15)
1742 break;
1744 /* Caller-saved registers marked as used. */
1745 if (df_regs_ever_live_p (reg) && !call_used_regs[reg])
1746 save = true;
1748 /* Frame pointer marked used. */
1749 else if (frame_pointer_needed && reg == HARD_FRAME_POINTER_REGNUM)
1750 save = true;
1752 /* This is required for CK801/802 where FP is a fixed reg, otherwise
1753 we end up with no FP value available to the DWARF-2 unwinder. */
1754 else if (crtl->calls_eh_return && reg == HARD_FRAME_POINTER_REGNUM)
1755 save = true;
1757 /* CK801/802 also need special handling for LR because it's clobbered
1758 by far jumps. */
1759 else if ((CSKY_TARGET_ARCH (CK801) || CSKY_TARGET_ARCH (CK802))
1760 && reg == CSKY_LR_REGNUM
1761 && (!crtl->is_leaf || csky_far_jump_used_p ()))
1762 save = true;
1764 /* Register is used for EH data return. */
1765 else if (crtl->calls_eh_return
1766 && reg >= CSKY_FIRST_EH_RETDATA_REGNUM
1767 && reg <= CSKY_LAST_EH_RETDATA_REGNUM)
1768 save = true;
1770 /* We need a temporary reg to hold the offset for adjusting the SP
1771 for a large stack frame. */
1772 if (reg == CSKY_STACKADJUST_REGNUM
1773 && cfun->machine->reg_offset > CSKY_MAX_SP_ADJUST * 2)
1774 save = true;
1776 /* Add reg to the mask. */
1777 if (save)
1779 (*count)++;
1780 live_regs_mask |= (1 << reg);
1783 return live_regs_mask;
1786 /* Compute the stack frame layout, storing sizes of the various pieces
1787 in cfun->machine.
1789 Stack frames constructed in the prologue look like:
1790 ... caller's frame ...
1791 incoming SP -> caller's outbound argument overflow
1792 argument spill
1793 optional FP -> register save
1794 local variables
1795 alloca() space
1796 adjusted SP -> outbound argument overflow
1798 with SP/FP pointing at the base (low address) of the respective area,
1799 and each area aligned to a word boundary. */
1801 static void
1802 csky_layout_stack_frame (void)
1804 machine_function *infp = cfun->machine;
1805 int reg_count;
1807 if (infp->frame_init_p)
1808 return;
1810 /* Get sizes of local variables & outbound arguments. */
1811 infp->outbound_size = CSKY_STACK_ALIGN (crtl->outgoing_args_size);
1812 infp->local_offset = infp->outbound_size;
1813 infp->local_size = CSKY_STACK_ALIGN (get_frame_size ());
1814 infp->reg_offset = infp->local_offset + infp->local_size;
1816 /* Now compute size of argument spill + saved regs. These do not
1817 need explicit alignment since they are already word-sized. */
1818 infp->reg_mask = get_csky_live_regs (&reg_count);
1819 infp->reg_size = reg_count * UNITS_PER_WORD;
1820 infp->arg_offset = infp->reg_offset + infp->reg_size;
1821 infp->arg_size = crtl->args.pretend_args_size;
1822 infp->frame_size = infp->arg_offset + infp->arg_size;
1823 infp->frame_init_p = reload_completed;
1826 /* Implement TARGET_CAN_ELIMINATE. */
1827 static bool
1828 csky_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
1830 if (to == FRAME_POINTER_REGNUM)
1831 return from != ARG_POINTER_REGNUM;
1832 if (to == STACK_POINTER_REGNUM)
1833 return !frame_pointer_needed;
1834 return true;
1837 /* Worker function for INITIAL_ELIMINATION_OFFSET macro.
1838 Define the offset between two registers, one to be eliminated, and
1839 the other its replacement, at the start of a routine. */
1841 HOST_WIDE_INT
1842 csky_initial_elimination_offset (int from, int to)
1844 int offset;
1846 csky_layout_stack_frame ();
1848 /* Set OFFSET to the offset to the initial stack pointer. */
1849 switch (from)
1851 case FRAME_POINTER_REGNUM:
1852 case HARD_FRAME_POINTER_REGNUM:
1853 offset = cfun->machine->reg_offset;
1854 break;
1856 case ARG_POINTER_REGNUM:
1857 offset = cfun->machine->arg_offset;
1858 break;
1860 default:
1861 gcc_unreachable ();
1864 /* If we are asked for the offset to the frame pointer instead,
1865 then subtract the difference between the frame pointer and stack
1866 pointer. */
1867 if (to == FRAME_POINTER_REGNUM || to == HARD_FRAME_POINTER_REGNUM)
1868 offset -= cfun->machine->reg_offset;
1869 return offset;
1873 /* Determine where to put an argument to a function.
1874 Value is zero to push the argument on the stack,
1875 or a hard register in which to store the argument.
1877 CUM is a variable of type CUMULATIVE_ARGS which gives info about
1878 the preceding args and about the function being called.
1879 ARG is a description of the argument. */
1881 static rtx
1882 csky_function_arg (cumulative_args_t pcum_v, const function_arg_info &arg)
1884 CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
1885 int reg = pcum->reg;
1886 machine_mode mode = arg.mode;
1888 if (FUNCTION_VARG_MODE_P(mode)
1889 && !pcum->is_stdarg)
1891 reg = pcum->freg;
1893 if (reg < CSKY_NPARM_FREGS)
1894 return gen_rtx_REG (mode, CSKY_FIRST_VFP_REGNUM + reg);
1895 else
1896 return NULL_RTX;
1899 if (reg < CSKY_NPARM_REGS)
1900 return gen_rtx_REG (mode, CSKY_FIRST_PARM_REGNUM + reg);
1902 return NULL_RTX;
1906 /* Return the number of registers (words) needed to pass an argument of
1907 MODE and TYPE. */
1909 static int
1910 csky_num_arg_regs (machine_mode mode, const_tree type, bool is_stdarg)
1912 int size;
1914 if (type && mode == BLKmode)
1915 size = int_size_in_bytes (type);
1916 else
1917 size = GET_MODE_SIZE (mode);
1919 if (TARGET_HARD_FLOAT_ABI
1920 && !is_stdarg)
1922 if (CSKY_VREG_MODE_P(mode)
1923 && !TARGET_SINGLE_FPU)
1924 return ((CSKY_NUM_WORDS (size) + 1) / 2);
1927 return CSKY_NUM_WORDS (size);
1931 /* Implement TARGET_FUNCTION_ARG_ADVANCE. */
1933 static void
1934 csky_function_arg_advance (cumulative_args_t pcum_v,
1935 const function_arg_info &arg)
1937 CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
1938 int *reg = &pcum->reg;
1939 machine_mode mode = arg.mode;
1941 int param_size = csky_num_arg_regs (mode, arg.type, pcum->is_stdarg);
1942 int param_regs_nums = CSKY_NPARM_REGS;
1944 if (FUNCTION_VARG_MODE_P(mode)
1945 && !pcum->is_stdarg)
1947 reg = &pcum->freg;
1948 param_regs_nums = CSKY_NPARM_FREGS;
1951 if (*reg + param_size > param_regs_nums)
1952 *reg = param_regs_nums;
1953 else
1954 *reg += param_size;
1958 /* Implement TARGET_FUNCTION_VALUE. */
1959 static rtx
1960 csky_function_value (const_tree type, const_tree func,
1961 bool outgoing ATTRIBUTE_UNUSED)
1963 machine_mode mode;
1964 int unsignedp ATTRIBUTE_UNUSED;
1965 int size;
1967 mode = TYPE_MODE (type);
1968 size = int_size_in_bytes (type);
1970 if (FUNCTION_VARG_MODE_P(mode))
1972 mode = promote_function_mode (type, mode, &unsignedp, func, 1);
1973 return gen_rtx_REG (mode, CSKY_FIRST_VFP_REGNUM);
1976 /* Since we promote return types, we must promote the mode here too. */
1977 if (INTEGRAL_TYPE_P (type))
1979 mode = promote_function_mode (type, mode, &unsignedp, func, 1);
1980 return gen_rtx_REG (mode, CSKY_FIRST_RET_REGNUM);
1983 if (mode == BLKmode && size > UNITS_PER_WORD
1984 && size <= UNITS_PER_WORD * 2)
1986 rtx ret_regs[2];
1987 ret_regs[0] = gen_rtx_EXPR_LIST (SImode,
1988 gen_rtx_REG (SImode,
1989 CSKY_FIRST_RET_REGNUM),
1990 GEN_INT (0 * UNITS_PER_WORD));
1991 ret_regs[1] = gen_rtx_EXPR_LIST (SImode,
1992 gen_rtx_REG (SImode,
1993 CSKY_FIRST_RET_REGNUM + 1),
1994 GEN_INT (1 * UNITS_PER_WORD));
1996 rtvec vec = gen_rtvec (2, ret_regs[0], ret_regs[1]);
1998 return gen_rtx_PARALLEL (mode, vec);
2001 return gen_rtx_REG (mode, CSKY_FIRST_RET_REGNUM);
2005 /* Implement TARGET_LIBCALL_VALUE. */
2007 static rtx
2008 csky_libcall_value (machine_mode mode,
2009 const_rtx libcall ATTRIBUTE_UNUSED)
2011 if (FUNCTION_VARG_MODE_P(mode))
2013 return gen_rtx_REG (mode, CSKY_FIRST_VFP_REGNUM);
2015 return gen_rtx_REG (mode, CSKY_FIRST_RET_REGNUM);
2019 /* Implement TARGET_FUNCTION_VALUE_REGNO_P.
2020 On C-SKY, only r0 can return results. */
2022 static bool
2023 csky_function_value_regno_p (const unsigned int regno)
2025 if (regno == CSKY_FIRST_RET_REGNUM
2026 || (TARGET_HARD_FLOAT_ABI
2027 && regno == CSKY_FIRST_VFP_REGNUM))
2028 return true;
2029 return false;
2033 /* Return an RTX indicating where the return address to the
2034 calling function can be found. */
2037 csky_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
2039 if (count != 0)
2040 return NULL_RTX;
2042 return get_hard_reg_initial_val (Pmode, CSKY_LR_REGNUM);
2046 /* Implement TARGET_ARG_PARTIAL_BYTES.
2047 Return the number of bytes at the beginning of an argument
2048 that must be put in registers. The value must be zero for arguments
2049 that are passed entirely in registers or
2050 that are entirely pushed on the stack. */
2052 static int
2053 csky_arg_partial_bytes (cumulative_args_t pcum_v, const function_arg_info &arg)
2055 CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
2056 int param_size = csky_num_arg_regs (arg.mode, arg.type, pcum->is_stdarg);
2057 int reg = pcum->reg;
2059 if (FUNCTION_VARG_MODE_P(arg.mode)
2060 && !pcum->is_stdarg)
2061 return 0;
2063 if (reg < CSKY_NPARM_REGS
2064 && reg + param_size > CSKY_NPARM_REGS)
2065 return (CSKY_NPARM_REGS - reg) * UNITS_PER_WORD;
2067 return 0;
2071 /* Implement TARGET_SETUP_INCOMING_VARARGS.
2072 On C-Sky the copy from the argument registers to the stack is emitted
2073 by the prologue hooks, so here we just have to note how much stack space
2074 to save. */
2076 static void
2077 csky_setup_incoming_varargs (cumulative_args_t pcum_v,
2078 const function_arg_info &arg,
2079 int *pretend_size,
2080 int second_time ATTRIBUTE_UNUSED)
2082 CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v);
2083 CUMULATIVE_ARGS local_cum;
2084 cumulative_args_t local_cum_v = pack_cumulative_args (&local_cum);
2085 int regs_to_push;
2087 cfun->machine->uses_anonymous_args = 1;
2088 local_cum = *pcum;
2089 csky_function_arg_advance (local_cum_v, arg);
2090 regs_to_push = CSKY_NPARM_REGS - local_cum.reg;
2091 if (regs_to_push)
2092 *pretend_size = regs_to_push * UNITS_PER_WORD;
2096 /* Implement TARGET_ASM_OUTPUT_MI_THUNK.
2097 Output code to add DELTA to the first argument, and then jump
2098 to FUNCTION. Used for C++ multiple inheritance. */
2100 static void
2101 csky_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
2102 HOST_WIDE_INT delta,
2103 HOST_WIDE_INT vcall_offset,
2104 tree function)
2106 const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk));
2107 const char *thiz = "a0";
2108 const char *reg0 = "t0";
2109 const char *reg1 = "t1";
2110 int maxoff = 4096; /* Constant range for addi/subi. */
2112 assemble_start_function (thunk, fnname);
2113 final_start_function (emit_barrier (), file, 1);
2115 rtx fnaddr = XEXP (DECL_RTL (function), 0);
2117 if (CSKY_TARGET_ARCH (CK801))
2119 /* CK801 can't use t registers and has only 16-bit addi/subi. */
2120 reg0 = "l0";
2121 reg1 = "l1";
2122 maxoff = 256;
2123 if (vcall_offset > maxoff || vcall_offset < -maxoff)
2124 fprintf (file, "\tpush\tl0, l1\n");
2125 else if (delta > maxoff || delta < -maxoff)
2126 fprintf (file, "\tpush\tl0\n");
2129 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
2130 thiz = "a1";
2132 /* Add delta to this_rtx. */
2133 if (delta != 0)
2135 if (delta > maxoff || delta < -maxoff)
2137 fprintf (file, "\tlrw\t%s, %ld\n", reg0, (long)delta);
2138 fprintf (file, "\taddu\t%s, %s, %s\n", thiz, thiz, reg0);
2140 else
2141 fprintf (file, "\t%s\t%s, %s, %ld\n",
2142 (delta > 0 ? "addi" : "subi"), thiz, thiz,
2143 (long)(delta > 0 ? delta : -delta));
2146 /* If needed, add *(*this_rtx + vcall_offset) to this_rtx. */
2147 if (vcall_offset != 0)
2149 fprintf (file, "\tld.w\t%s, (%s, 0)\n", reg0, thiz);
2151 if (vcall_offset > maxoff || vcall_offset < -maxoff)
2153 fprintf (file, "\tlrw\t%s, %ld\n", reg1, (long)vcall_offset);
2154 fprintf (file, "\taddu\t%s, %s, %s\n", reg0, reg0, reg1);
2156 else
2157 fprintf (file, "\t%s\t%s, %s, %ld\n",
2158 (vcall_offset > 0 ? "addi" : "subi"), reg0, reg0,
2159 (long)(vcall_offset > 0 ? vcall_offset : -vcall_offset));
2161 /* Load the offset and add it to this_rtx */
2162 fprintf (file, "\tld.w\t%s, (%s, 0)\n", reg0, reg0);
2163 fprintf (file, "\taddu\t%s, %s, %s\n", thiz, thiz, reg0);
2166 /* We must pop the scratch regs individually instead of using the
2167 "pop" insn, which also does a return. */
2168 if (CSKY_TARGET_ARCH (CK801))
2170 if (vcall_offset > maxoff || vcall_offset < -maxoff)
2172 fprintf (file, "\tld.w\tl0, (sp, 0)\n");
2173 fprintf (file, "\tld.w\tl1, (sp, 4)\n");
2174 fprintf (file, "\taddi\t sp, sp, 8\n");
2176 else if (delta > maxoff || delta < -maxoff)
2178 fprintf (file, "\tld.w\tl0, (sp, 0)\n");
2179 fprintf (file, "\taddi\tsp, sp, 4\n");
2183 fprintf (file, "\tjbr\t");
2184 output_addr_const (file, fnaddr);
2185 fprintf (file, "\n");
2187 final_end_function ();
2188 assemble_end_function (thunk, fnname);
2192 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE.
2193 Conditionally modify five variables fixed_regs, call_used_regs, global_regs,
2194 reg_names, and reg_class_contents, to take into account any dependence of
2195 these register sets on target flags.
2197 CK801 has registers r0-r8 and r13-r15. CK802 and CK803 have registers
2198 r0-r15 (the "low" registers). Other cpus use registers r0-r31 with
2199 -mhigh-registers, otherwise also only r0-r15.
2201 CK801 only has 16-bit instructions, most of which can only reference
2202 r0-r7 (the "mini" registers). So we mark regs outside that range as
2203 fixed. -msmart can be used on other arch variants to force the same
2204 behavior because it results in smaller code size.
2206 TODO: investigate whether it's beneficial to use r8-r13 as a spill
2207 class when TARGET_MINI_REGISTERS instead of making them unusable by
2208 the register allocator. */
2210 static void
2211 csky_conditional_register_usage (void)
2213 /* Only use mini registers in smart mode or 801. */
2214 if (TARGET_MINI_REGISTERS)
2216 int i;
2218 for (i = (CSKY_LAST_MINI_REGNUM + 1); i < 32; i++)
2220 fixed_regs[i] = 1;
2221 call_used_regs[i] = 1;
2224 /* For some targets, the high registers are not supported.
2225 CPUs other than ck801/ck802/ck803 use high registers
2226 depending on -mhigh-registers option. */
2227 else if (CSKY_TARGET_ARCH (CK802)
2228 || CSKY_TARGET_ARCH (CK803)
2229 || !TARGET_HIGH_REGISTERS)
2231 int i;
2233 for (i = CSKY_FIRST_HIGH_REGNUM; i <= CSKY_LAST_HIGH_REGNUM; i++)
2235 fixed_regs[i] = 1;
2236 call_used_regs[i] = 1;
2240 /* On CK801/CK802 we must mark lr as a fixed register because it is
2241 used to implement far jumps.
2242 FIXME: perhaps there should be a command-line option controlling
2243 use of lr for far jumps on ck802 when !TARGET_MINI_REGS, when
2244 you really want lr to be available to the register allocator and
2245 you know there are no far jumps in the code. */
2246 if (CSKY_TARGET_ARCH (CK801) || CSKY_TARGET_ARCH (CK802))
2248 fixed_regs[CSKY_LR_REGNUM] = 1;
2249 call_used_regs[CSKY_LR_REGNUM] = 0;
2252 /* The hi/lo registers are only supported in dsp mode. */
2253 if (!TARGET_DSP)
2255 fixed_regs[CSKY_HI_REGNUM] = 1;
2256 call_used_regs[CSKY_HI_REGNUM] = 1;
2258 fixed_regs[CSKY_LO_REGNUM] = 1;
2259 call_used_regs[CSKY_LO_REGNUM] = 1;
2262 /* The V_REGS are only supported in hard float mode. */
2263 if (!TARGET_HARD_FLOAT)
2265 int regno;
2267 for (regno = CSKY_FIRST_VFP_REGNUM;
2268 regno <= CSKY_LAST_VFP3_REGNUM; regno++)
2270 fixed_regs[regno] = 1;
2271 call_used_regs[regno] = 1;
2275 if (!TARGET_SUPPORT_FPV3)
2277 int regno;
2279 for (regno = CSKY_FIRST_VFP3_REGNUM;
2280 regno <= CSKY_LAST_VFP3_REGNUM; regno++)
2282 fixed_regs[regno] = 1;
2283 call_used_regs[regno] = 1;
2287 /* In pic mode, the gb register is not available for register
2288 allocation. Since gb is not clobbered by function
2289 calls, set its call_used_regs to 0. */
2290 if (flag_pic)
2292 fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
2293 call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 0;
2297 /* Implement TARGET_HARD_REGNO_NREGS. */
2299 static unsigned int
2300 csky_hard_regno_nregs (unsigned int regno, machine_mode mode)
2302 if (regno >= CSKY_FIRST_VFP_REGNUM && !CSKY_TARGET_ARCH (CK803))
2303 return 1;
2304 else
2305 return CSKY_NUM_REGS (mode);
2308 /* Implement TARGET_HARD_REGNO_MODE_OK. Return true if REGNO is a
2309 valid register for holding a quantity of type MODE. */
2311 static bool
2312 csky_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
2314 int nregs = CSKY_NUM_REGS (mode);
2316 /* We can't handle more than doubleword sizes for any register. */
2317 if (nregs > 2)
2318 return false;
2320 /* For general registers, return true if mode is one word size.
2321 When the size is larger than one word size, there should
2322 be two successive hard registers to put the data. */
2323 if (regno < CSKY_NGPR_REGS)
2325 if (nregs < 2)
2326 return true;
2327 else if (TARGET_MINI_REGISTERS)
2328 return (regno < CSKY_LAST_MINI_REGNUM);
2329 else if (CSKY_TARGET_ARCH (CK802)
2330 || CSKY_TARGET_ARCH (CK803)
2331 || !TARGET_HIGH_REGISTERS)
2332 /* Without high register, r15 cannot hold doubleword data. */
2333 return (regno < (CSKY_SP_REGNUM - 1));
2334 else
2335 return (regno < (CSKY_SP_REGNUM - 1)
2336 || (regno >= CSKY_LR_REGNUM
2337 && regno < CSKY_LAST_HIGH_UNFIXED_REGNUM));
2339 else if (regno == CSKY_CC_REGNUM)
2340 return (mode == CCmode);
2341 else if (regno == CSKY_HI_REGNUM || regno == CSKY_LO_REGNUM)
2343 /* Don't allocate hi,lo register for float data even
2344 if in dsp mode, because it will cause high cost
2345 to reload data from hi,lo register. */
2346 if (!TARGET_DSP || mode == SFmode || mode == DFmode)
2347 return false;
2348 else if (nregs == 2)
2349 return (regno == CSKY_HI_REGNUM);
2350 else
2351 return true;
2353 else if (CSKY_VREG_P (regno) && TARGET_HARD_FLOAT)
2354 return true;
2356 return false;
2359 /* Implement TARGET_MODES_TIEABLE_P. We can't tie DFmode with other modes
2360 when V_REGs might be in use because those registers mess with the stored
2361 bits. */
2363 static bool
2364 csky_modes_tieable_p (machine_mode mode1, machine_mode mode2)
2366 return !(TARGET_HARD_FLOAT
2367 && mode1 != mode2
2368 && (mode1 == DFmode || mode2 == DFmode));
2371 /* Implement TARGET_CLASS_LIKELY_SPILLED_P.
2372 We need to define this for MINI_REGS when we only use r0 - r7.
2373 Otherwise we can end up using r0-r4 for function arguments, and don't
2374 have enough left over to do doubleword arithmetic. */
2376 static bool
2377 csky_class_likely_spilled_p (reg_class_t rclass)
2379 if ((TARGET_MINI_REGISTERS && rclass == MINI_REGS)
2380 || rclass == C_REGS)
2381 return true;
2383 return false;
2387 /* Implement TARGET_PREFERRED_RELOAD_CLASS.
2388 Given an rtx X being reloaded into a reg required to be
2389 in class CLASS, return the class of reg to actually use.
2390 In general this is just CLASS. */
2392 static reg_class_t
2393 csky_preferred_reload_class (rtx x, reg_class_t rclass)
2395 if (TARGET_HARD_FLOAT
2396 && CONST_DOUBLE_P (x)
2397 && (GET_MODE (x) == DFmode || GET_MODE (x) == SFmode)
2398 && rclass == NO_REGS)
2399 return GENERAL_REGS;
2400 return rclass;
2404 /* Implement TARGET_CLASS_MAX_NREGS.
2405 Return the maximum number of consecutive registers of class rclass needed
2406 to hold a value of mode mode.
2407 On the csky, this is the size of MODE in words,
2408 except in the FP regs, where a single reg is always enough. */
2410 static unsigned char
2411 csky_class_max_nregs (reg_class_t rclass, machine_mode mode)
2413 if (rclass == V_REGS)
2414 return 1;
2415 else
2416 return CSKY_NUM_REGS (mode);
2420 /* Implement TARGET_SECONDARY_RELOAD.
2421 If copying a register of RCLASS from/to X requires an intermediate
2422 register, the hook should return the REGISTER_CLASS required for this
2423 intermediate register.
2424 If no intermediate register is required, it should return NO_REGS.
2425 If more than one intermediate register is required, describe the one
2426 that is closest in the copy chain to the reload register. */
2428 reg_class_t
2429 csky_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x,
2430 reg_class_t rclass,
2431 machine_mode mode,
2432 secondary_reload_info *sri ATTRIBUTE_UNUSED)
2434 int regno = -1;
2436 /* Extract the real regno from X. */
2437 if (GET_CODE (x) == SIGN_EXTEND)
2439 int off = 0;
2441 x = XEXP (x, 0);
2443 if (reg_renumber)
2444 regno = true_regnum (x);
2445 else
2447 while (GET_CODE (x) == SUBREG)
2449 off += subreg_regno_offset (REGNO (SUBREG_REG (x)),
2450 GET_MODE (SUBREG_REG (x)),
2451 SUBREG_BYTE (x), GET_MODE (x));
2452 x = SUBREG_REG (x);
2455 if (GET_CODE (x) == REG)
2456 regno = REGNO (x) + off;
2459 else if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
2460 regno = true_regnum (x);
2462 /* We always require a general register when copying anything to
2463 HI/LO_REGNUM, except when copying an SImode value from HI/LO_REGNUM
2464 to a general register, or when copying from register 0. */
2465 if (rclass == HILO_REGS && !CSKY_GENERAL_REGNO_P (regno))
2466 return GENERAL_REGS;
2468 if (rclass == V_REGS && !CSKY_GENERAL_REGNO_P (regno))
2470 /* Reload between vector reg and memory does not need an
2471 intermediate register. */
2472 if (MEM_P (x) && (mode == SFmode || mode == DFmode))
2473 return NO_REGS;
2474 else
2475 return GENERAL_REGS;
2478 return NO_REGS;
2481 /* Implement TARGET_SPILL_CLASS.
2482 Try spilling to a larger register class before spilling to memory. */
2484 static reg_class_t
2485 csky_spill_class (reg_class_t rclass, machine_mode mode ATTRIBUTE_UNUSED)
2487 if ((rclass == MINI_REGS && !TARGET_MINI_REGISTERS)
2488 || (rclass == LOW_REGS && TARGET_HIGH_REGISTERS))
2489 return GENERAL_REGS;
2490 return NO_REGS;
2493 /* Convert a static initializer array of feature bits to sbitmap
2494 representation. */
2496 static void
2497 csky_initialize_isa (sbitmap isa, const enum csky_isa_feature *isa_bits)
2499 bitmap_clear (isa);
2500 while (*isa_bits != CSKY_ISA_FEATURE_GET (none))
2501 bitmap_set_bit (isa, *(isa_bits++));
2505 /* Configure a build target TARGET from the user-specified options OPTS and
2506 OPTS_SET. */
2508 static void
2509 csky_configure_build_target (struct csky_build_target *target,
2510 struct cl_target_option *opts,
2511 struct gcc_options *opts_set)
2513 const struct csky_processors *csky_selected_tune = NULL;
2514 struct csky_processors *csky_selected_cpu = NULL;
2515 struct csky_processors *csky_selected_arch = NULL;
2516 sbitmap all_sbits = sbitmap_alloc (CSKY_ISA_FEATURE_GET (max));
2517 bitmap_clear (all_sbits);
2519 bitmap_clear (target->isa);
2520 target->core_name = NULL;
2521 target->arch_name = NULL;
2523 if (opts_set->x_csky_arch_option)
2524 csky_selected_arch = &all_architectures[opts->x_csky_arch_option];
2526 if (opts_set->x_csky_cpu_option)
2528 csky_selected_cpu = &all_cores[opts->x_csky_cpu_option];
2529 csky_selected_tune = &all_cores[opts->x_csky_cpu_option];
2532 if (csky_selected_cpu)
2534 /* TODO: support combination of features
2535 between different cpu & arch, should based on arch. */
2536 if (csky_selected_arch
2537 && (csky_selected_cpu->base_arch != csky_selected_arch->base_arch))
2538 warning (0, "cpu %s is not based on arch %s, ignoring the arch",
2539 csky_selected_cpu->name, csky_selected_arch->name);
2540 if (!csky_selected_arch)
2541 csky_selected_arch = &all_architectures[csky_selected_cpu->base_arch];
2542 csky_initialize_isa (all_sbits, csky_selected_arch->isa_bits);
2543 target->core_name = csky_selected_cpu->name;
2545 else if (csky_selected_arch)
2547 csky_selected_cpu = csky_selected_arch;
2548 target->arch_name = csky_selected_arch->name;
2550 else /* If the user did not specify a processor, choose one for them. */
2552 csky_selected_cpu = &all_cores[TARGET_CPU_DEFAULT];
2553 csky_selected_arch = &all_architectures[csky_selected_cpu->base_arch];
2554 csky_initialize_isa (all_sbits, csky_selected_arch->isa_bits);
2555 target->core_name = csky_selected_cpu->name;
2558 /* The selected cpu may be an architecture, so lookup tuning by core ID. */
2559 if (!csky_selected_tune)
2560 csky_selected_tune = &all_cores[csky_selected_cpu->core];
2561 gcc_assert (csky_selected_tune);
2563 gcc_assert (csky_selected_arch);
2564 gcc_assert (csky_selected_cpu);
2565 csky_initialize_isa (target->isa, csky_selected_cpu->isa_bits);
2566 bitmap_ior (target->isa, target->isa, all_sbits);
2568 /* Finish initializing the target structure. */
2569 target->arch_pp_name = csky_selected_cpu->arch;
2570 target->base_arch = csky_selected_cpu->base_arch;
2571 target->arch_core = csky_selected_cpu->core;
2573 sbitmap_free (all_sbits);
2577 /* Implement TARGET_OPTION_OVERRIDE. */
2579 static void
2580 csky_option_override (void)
2582 csky_active_target.isa = sbitmap_alloc (CSKY_ISA_FEATURE_GET (max));
2584 /* Create the default target_options structure. We need this early
2585 to configure the overall build target. */
2586 target_option_default_node = target_option_current_node
2587 = build_target_option_node (&global_options, &global_options_set);
2589 csky_configure_build_target (&csky_active_target,
2590 TREE_TARGET_OPTION (target_option_default_node),
2591 &global_options_set);
2593 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2594 SUBTARGET_OVERRIDE_OPTIONS;
2595 #endif
2597 csky_base_arch = csky_active_target.base_arch;
2599 if (flag_pic && !(CSKY_TARGET_ARCH (CK807)
2600 || CSKY_TARGET_ARCH (CK810)
2601 || CSKY_TARGET_ARCH (CK860)))
2603 flag_pic = 0;
2604 warning (0, "%qs is not supported by arch %s",
2605 "-fPIC", csky_active_target.arch_pp_name);
2608 /* Check floating-point options for consistency. */
2609 if (TARGET_HARD_FLOAT)
2611 const struct csky_fpu_desc *csky_selected_fpu = NULL;
2613 if (csky_fpu_index == TARGET_FPU_auto)
2615 const char *target_fpu_name;
2616 bool ok;
2617 int fpu_index;
2619 if (csky_active_target.core_name != NULL
2620 && !strchr (csky_active_target.core_name, 'f'))
2621 target_fpu_name = "auto";
2622 else if (CSKY_TARGET_ARCH (CK803) || !TARGET_DOUBLE_FLOAT)
2623 target_fpu_name = "fpv2_sf";
2624 else if (CSKY_TARGET_ARCH (CK860))
2625 target_fpu_name = "fpv3";
2626 else if (TARGET_DOUBLE_FLOAT && TARGET_FDIVDU)
2627 target_fpu_name = "fpv2_divd";
2628 else
2629 #ifdef CSKY_FPUTYPE_DEFAULT
2630 target_fpu_name = CSKY_FPUTYPE_DEFAULT;
2631 #else
2632 target_fpu_name = "fpv2";
2633 #endif
2635 ok = opt_enum_arg_to_value (OPT_mfpu_, target_fpu_name, &fpu_index,
2636 CL_TARGET);
2637 gcc_assert (ok);
2638 csky_fpu_index = (enum csky_fpu_type) fpu_index;
2641 if (CSKY_TARGET_ARCH (CK801) || CSKY_TARGET_ARCH (CK802))
2642 error ("%qs is not supported by arch %s",
2643 "-mhard-float", csky_active_target.arch_pp_name);
2644 else if (csky_fpu_index == TARGET_FPU_auto)
2645 error ("%<-mhard-float%> is not supported by the selected CPU");
2646 else
2648 csky_selected_fpu = &all_fpus[csky_fpu_index];
2649 sbitmap fpu_bits = sbitmap_alloc (CSKY_ISA_FEATURE_GET (max));
2650 csky_initialize_isa (fpu_bits, csky_selected_fpu->isa_bits);
2652 bitmap_ior (csky_active_target.isa, csky_active_target.isa,
2653 fpu_bits);
2655 sbitmap_free (fpu_bits);
2658 else
2660 if (TARGET_DOUBLE_FLOAT > 0)
2661 warning (0, "%<-mdouble-float%> ignored without %<-mhard-float%>");
2662 TARGET_DOUBLE_FLOAT = 0;
2663 if (TARGET_FDIVDU > 0)
2664 warning (0, "%<-mfdivdu%> ignored without %<-mhard-float%>");
2665 TARGET_FDIVDU = 0;
2668 /* Initialize boolean versions of the architectural flags, for use
2669 in the .md file. */
2671 #undef CSKY_ISA
2672 #define CSKY_ISA(IDENT, DESC) \
2674 csky_arch_isa_features[CSKY_ISA_FEATURE_GET (IDENT)] = \
2675 bitmap_bit_p (csky_active_target.isa, CSKY_ISA_FEATURE_GET (IDENT)); \
2677 #include "csky_isa.def"
2678 #undef CSKY_ISA
2680 /* Extended LRW instructions are enabled by default on CK801, disabled
2681 otherwise. */
2682 if (TARGET_ELRW == -1)
2683 TARGET_ELRW = CSKY_TARGET_ARCH (CK801);
2685 /* DSP is enabled either by the processor feature or -mdsp
2686 command-line option. There is no -mno-dsp option as the assembler
2687 doesn't take one. */
2688 if (!TARGET_DSP)
2689 TARGET_DSP = CSKY_ISA_FEATURE (dsp);
2691 /* There's both -mdiv and -mno-div. Take default from processor if
2692 neither is specified explicitly. */
2693 if (TARGET_DIV == -1)
2694 TARGET_DIV = CSKY_ISA_FEATURE (div);
2696 /* TARGET_CONSTANT_POOL is mandatory for CK801 and CK802 and optional
2697 for other CPUs.
2698 The reason why the compiler has to generate constant pools for CK801/2
2699 instead of deferring to the assembler is that these cores don't have a
2700 long branch instruction other than jbsr, which clobbers lr. So for
2701 the compiler to correctly save/restore lr it has to know whether there
2702 are long branches, which depends on having accurate branch length
2703 counts, which in turn depends on having control over where constant
2704 pools are placed. */
2705 if ((CSKY_TARGET_ARCH (CK801) || CSKY_TARGET_ARCH (CK802))
2706 && !TARGET_CONSTANT_POOL)
2707 error ("%qs is not supported by arch %s",
2708 "-mno-constpool", csky_active_target.arch_pp_name);
2709 else if (TARGET_CONSTANT_POOL == -1)
2710 TARGET_CONSTANT_POOL = (CSKY_TARGET_ARCH (CK801)
2711 || CSKY_TARGET_ARCH (CK802));
2713 /* TARGET_MINI_REGISTERS is mandatory for CK801, the default for CK802,
2714 and optional for other CPUs. TARGET_HIGH_REGISTERS is incompatible
2715 with TARGET_MINI_REGISTERS, is not supported by CK801/802/803,
2716 and is the default for other processors.
2717 See csky_conditional_register_usage. */
2718 if (TARGET_MINI_REGISTERS > 0 && TARGET_HIGH_REGISTERS > 0)
2719 error ("%<-msmart%> is incompatible with %<-mhigh-registers%>");
2720 else if (CSKY_TARGET_ARCH (CK801)
2721 || CSKY_TARGET_ARCH (CK802)
2722 || CSKY_TARGET_ARCH (CK803))
2724 if (CSKY_TARGET_ARCH (CK801)
2725 || (CSKY_TARGET_ARCH (CK802) && TARGET_MINI_REGISTERS == -1))
2726 TARGET_MINI_REGISTERS = 1;
2727 else if (TARGET_MINI_REGISTERS == -1)
2728 TARGET_MINI_REGISTERS = 0;
2729 if (TARGET_HIGH_REGISTERS > 0)
2730 warning (0, "%qs is not supported by arch %s",
2731 "-mhigh-registers", csky_active_target.arch_pp_name);
2732 TARGET_HIGH_REGISTERS = 0;
2734 else
2736 if (TARGET_MINI_REGISTERS == -1)
2737 TARGET_MINI_REGISTERS = 0;
2738 if (TARGET_HIGH_REGISTERS == -1)
2739 TARGET_HIGH_REGISTERS = !TARGET_MINI_REGISTERS;
2742 /* -mmultiple-stld is the default for everything but CK801, which
2743 doesn't support it. */
2744 if (CSKY_TARGET_ARCH (CK801))
2746 if (TARGET_MULTIPLE_STLD > 0)
2747 warning (0, "%qs is not supported by arch %s",
2748 "-mmultiple-stld", csky_active_target.arch_pp_name);
2749 TARGET_MULTIPLE_STLD = 0;
2752 /* TODO */
2754 /* Resynchronize the saved target options. */
2755 cl_target_option_save (TREE_TARGET_OPTION (target_option_default_node),
2756 &global_options, &global_options_set);
2758 #ifdef ENABLE_TPF_DEBUG
2759 /* Don't emit DWARF4 unless specifically selected. The TPF
2760 debuggers do not yet support DWARF 3/4. */
2761 if (!OPTION_SET_P (dwarf_strict))
2762 dwarf_strict = 1;
2763 if (!OPTION_SET_P (dwarf_version))
2764 dwarf_version = 3;
2765 #endif
2767 /* Don't run the scheduler before reload by default,
2768 since it tends to increase register pressure. */
2769 if (!OPTION_SET_P (flag_schedule_insns))
2770 flag_schedule_insns = 0;
2772 csky_add_gc_roots ();
2776 /* Return TRUE if X contains any references to TLS symbols. */
2778 bool
2779 csky_tls_referenced_p (rtx x)
2781 if (!TARGET_TLS)
2782 return false;
2784 subrtx_iterator::array_type array;
2785 FOR_EACH_SUBRTX (iter, array, x, ALL)
2787 const_rtx x = *iter;
2788 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x) != 0)
2789 return true;
2791 /* Don't recurse into UNSPEC_TLS looking for TLS symbols; these are
2792 TLS offsets, not real symbol references. */
2793 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLS)
2794 iter.skip_subrtxes ();
2796 return false;
2800 /* Implement TARGET_CANNOT_FORCE_CONST_MEM.
2801 Determine if it's legal to put X into the constant pool. This
2802 is not possible for the address of thread-local symbols, which
2803 is checked above. */
2805 static bool
2806 csky_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED,
2807 rtx x)
2809 return csky_tls_referenced_p (x);
2813 /* Implement TARGET_LEGITIMATE_CONSTANT_P. Returns nonzero if the
2814 constant value X is a legitimate general operand.
2815 It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
2817 static bool
2818 csky_legitimate_constant_p (machine_mode mode, rtx x)
2820 return (!csky_cannot_force_const_mem (mode, x)
2821 && CONSTANT_P (x));
2825 /* Return true if X is valid as an CSKY addressing register. */
2827 static bool
2828 is_csky_address_register_rtx_p (rtx x, int strict_p)
2830 int regno;
2832 if (!x)
2833 return false;
2834 if (!REG_P (x))
2835 return false;
2837 regno = REGNO (x);
2839 if (strict_p)
2840 return (CSKY_GENERAL_REGNO_P (regno)
2841 || CSKY_GENERAL_REGNO_P (reg_renumber[regno]));
2842 else
2843 return CSKY_GENERAL_REGNO_P (regno) || regno >= FIRST_PSEUDO_REGISTER;
2847 /* Return TRUE if X is a thread-local symbol. */
2849 static bool
2850 csky_tls_symbol_p (rtx x)
2852 if (!TARGET_TLS)
2853 return false;
2855 if (GET_CODE (x) != SYMBOL_REF)
2856 return false;
2858 return SYMBOL_REF_TLS_MODEL (x) != 0;
2862 /* Handle lazy initialization of __tls_get_addr libfunc. */
2863 static GTY(()) rtx tls_get_addr_libfunc;
2865 static rtx
2866 get_tls_get_addr (void)
2868 if (!tls_get_addr_libfunc)
2869 tls_get_addr_libfunc = init_one_libfunc ("__tls_get_addr");
2870 return tls_get_addr_libfunc;
2874 /* Emit a call to __tls_get_addr. */
2876 static rtx_insn *
2877 csky_call_tls_get_addr (rtx x, rtx reg, rtx *valuep, int reloc)
2879 rtx label, labelno, unspec, tmp;
2880 rtx_insn *insns;
2882 start_sequence ();
2884 labelno = GEN_INT (tls_labelno++);
2885 label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_TLS_LABEL);
2886 unspec = gen_rtx_UNSPEC (Pmode,
2887 gen_rtvec (3, x, GEN_INT (reloc), label),
2888 UNSPEC_TLS);
2889 tmp = gen_reg_rtx (SImode);
2890 emit_move_insn (reg, unspec);
2891 emit_move_insn (tmp, label);
2892 emit_insn (gen_addsi3 (reg, reg, tmp));
2893 *valuep = emit_library_call_value (get_tls_get_addr (),
2894 NULL_RTX, LCT_PURE, /* LCT_CONST? */
2895 Pmode, reg, Pmode);
2896 insns = get_insns ();
2897 end_sequence ();
2898 return insns;
2901 /* Helper function for csky_legitimize_address, to handle the TLS cases.
2902 REG is a scratch register and may be null. */
2905 csky_legitimize_tls_address (rtx x, rtx reg)
2907 rtx dest, tp, label, labelno, unspec, ret, eqv, addend, tmp;
2908 rtx_insn *insns;
2909 unsigned int model = SYMBOL_REF_TLS_MODEL (x);
2911 if (!reg)
2912 reg = gen_reg_rtx (SImode);
2914 switch (model)
2916 case TLS_MODEL_GLOBAL_DYNAMIC:
2917 insns = csky_call_tls_get_addr (x, reg, &ret, TLS_GD32);
2918 dest = gen_reg_rtx (Pmode);
2919 emit_libcall_block (insns, dest, ret, x);
2920 return dest;
2922 case TLS_MODEL_LOCAL_DYNAMIC:
2923 insns = csky_call_tls_get_addr (x, reg, &ret, TLS_LDM32);
2925 /* Attach a unique REG_EQUIV, to allow the RTL optimizers to
2926 share the LDM result with other LD model accesses. */
2927 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const1_rtx), UNSPEC_TLS);
2928 dest = gen_reg_rtx (Pmode);
2929 emit_libcall_block (insns, dest, ret, eqv);
2931 /* Load the addend. */
2932 addend = gen_rtx_UNSPEC (Pmode,
2933 gen_rtvec (2, x, GEN_INT (TLS_LDO32)),
2934 UNSPEC_TLS);
2935 addend = force_reg (SImode, addend);
2936 return gen_rtx_PLUS (Pmode, dest, addend);
2938 case TLS_MODEL_INITIAL_EXEC:
2939 labelno = GEN_INT (tls_labelno++);
2940 label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_TLS_LABEL);
2941 unspec = gen_rtx_UNSPEC (Pmode,
2942 gen_rtvec (3, x, GEN_INT (TLS_IE32), label),
2943 UNSPEC_TLS);
2944 tmp = gen_reg_rtx (SImode);
2945 emit_move_insn (reg, unspec);
2946 emit_move_insn (tmp, label);
2947 emit_insn (gen_addsi3 (reg, reg, tmp));
2948 emit_move_insn (reg, gen_const_mem (Pmode, reg));
2949 tp = gen_rtx_REG (SImode, CSKY_TLS_REGNUM);
2950 return gen_rtx_PLUS (Pmode, tp, reg);
2952 case TLS_MODEL_LOCAL_EXEC:
2953 unspec = gen_rtx_UNSPEC (Pmode,
2954 gen_rtvec (2, x, GEN_INT (TLS_LE32)),
2955 UNSPEC_TLS);
2956 emit_move_insn (reg, unspec);
2957 tp = gen_rtx_REG (SImode, CSKY_TLS_REGNUM);
2958 return gen_rtx_PLUS (Pmode, tp, reg);
2960 default:
2961 abort ();
2966 /* Implement TARGET_LEGITIMIZE_ADDRESS. */
2968 static rtx
2969 csky_legitimize_address (rtx x, rtx orig_x ATTRIBUTE_UNUSED,
2970 machine_mode mode)
2972 if (csky_tls_symbol_p (x))
2973 return csky_legitimize_tls_address (x, NULL_RTX);
2975 if (GET_CODE (x) == PLUS)
2977 rtx xop0 = XEXP (x, 0);
2978 rtx xop1 = XEXP (x, 1);
2980 if (is_csky_address_register_rtx_p (xop0, 0)
2981 && CONST_INT_P (xop1))
2983 HOST_WIDE_INT offset = INTVAL (xop1);
2985 /* Try to replace ld32 rx,(ry, offset), to addi16 rz, oimm8
2986 and ld16 rx,(rz, new_ld_offset) to avoid emitting a
2987 32-bit ld, but this addi has a range limitation. */
2988 if (optimize_size
2989 && offset > CSKY_LD16_MAX_OFFSET (mode)
2990 && offset <= (CSKY_ADDI16_MAX_IMM
2991 + CSKY_LD16_MAX_OFFSET (mode)))
2993 HOST_WIDE_INT new_ld_offset
2994 = offset & CSKY_LD16_OFFSET_MASK (mode);
2996 xop0 = force_operand (plus_constant (Pmode, xop0,
2997 offset - new_ld_offset),
2998 NULL_RTX);
2999 x = plus_constant (Pmode, xop0, new_ld_offset);
3001 else if (offset < 0 && offset >= (-CSKY_SUBI16_MAX_IMM))
3002 x = force_operand (x, NULL_RTX);
3003 else if (offset > CSKY_LD16_MAX_OFFSET (mode)
3004 || offset < 0)
3006 /* For the remaining cases, force the constant into a
3007 register. */
3008 xop1 = force_reg (SImode, xop1);
3009 x = gen_rtx_PLUS (SImode, xop0, xop1);
3013 /* If the index is store in register, force the
3014 base to register. */
3015 if (is_csky_address_register_rtx_p (xop1, 0)
3016 && !is_csky_address_register_rtx_p (xop0, 0))
3018 xop0 = force_operand (xop0, NULL_RTX);
3019 x = gen_rtx_PLUS (SImode, xop0, xop1);
3022 /* Make sure to take full advantage of the pre-indexed addressing mode
3023 with absolute addresses which often allows for the base register to
3024 be factorized for multiple adjacent memory references, and it might
3025 even allows for the mini pool to be avoided entirely. */
3026 else if (CONST_INT_P (x) && optimize > 0)
3028 HOST_WIDE_INT mask, base, index;
3029 rtx base_reg;
3031 mask = CSKY_LD16_OFFSET_MASK (mode);
3032 base = INTVAL (x) & ~mask;
3033 index = INTVAL (x) & mask;
3034 base_reg = force_reg (SImode, GEN_INT (base));
3035 x = plus_constant (Pmode, base_reg, index);
3038 return x;
3042 /* Return nonzero if INDEX is valid for an address index operand.
3043 ck801 use 16 bits ld
3044 ck802 use 16 and 32 bits ld
3045 others use ld and ldr. */
3047 static int
3048 ck801_legitimate_index_p (machine_mode mode, rtx index,
3049 int strict_p ATTRIBUTE_UNUSED)
3051 enum rtx_code code = GET_CODE (index);
3053 /* When the mode size is larger than 4, we may use two ld instruction
3054 to get data, the index and (index+1) should be valid. */
3055 if (GET_MODE_SIZE (mode) >= 8)
3056 return (code == CONST_INT
3057 && INTVAL (index) < CSKY_LD16_MAX_OFFSET (SImode)
3058 && INTVAL (index) >= 0 && (INTVAL (index) & 3) == 0);
3060 if (code == CONST_INT && GET_MODE_SIZE (mode) > 0
3061 && INTVAL (index) <= CSKY_LD16_MAX_OFFSET (mode)
3062 && INTVAL (index) >= 0)
3063 return ((INTVAL (index) % GET_MODE_SIZE (mode)) == 0);
3065 return 0;
3069 static int
3070 ck802_legitimate_index_p (machine_mode mode, rtx index,
3071 int strict_p ATTRIBUTE_UNUSED)
3073 enum rtx_code code = GET_CODE (index);
3075 /* When the mode size is larger than 4, we may use two ld instruction
3076 to get data, the index and (index+1) should be valid. */
3077 if (GET_MODE_SIZE (mode) >= 8)
3078 return (code == CONST_INT
3079 && INTVAL (index) < CSKY_LD32_MAX_OFFSET (SImode)
3080 && INTVAL (index) >= 0 && (INTVAL (index) & 3) == 0);
3082 if (code == CONST_INT && GET_MODE_SIZE (mode) > 0
3083 && INTVAL (index) <= CSKY_LD32_MAX_OFFSET (mode)
3084 && INTVAL (index) >= 0)
3085 return ((INTVAL (index) % GET_MODE_SIZE (mode)) == 0);
3087 return 0;
3091 /* The instruction ldr rz, (rx, ry << i), i can be 0,1,2,3.
3092 Check that SHIFT is valid, that the code is MULT, and that
3093 the shift is a power of 2. */
3095 static bool
3096 is_ldr_shift_p (HOST_WIDE_INT shift, enum rtx_code code)
3098 if (code == ASHIFT)
3099 return (shift >= 0 && shift <= 3);
3100 else if (code == MULT)
3101 return (shift == 1
3102 || shift == 2
3103 || shift == 4
3104 || shift == 8);
3105 else
3106 return false;
3110 static int
3111 ck810_legitimate_index_p (machine_mode mode, rtx index, int strict_p)
3113 enum rtx_code code = GET_CODE (index);
3115 if (code == CONST_INT && TARGET_HARD_FLOAT && CSKY_VREG_MODE_P (mode))
3116 return (INTVAL (index) < 1024 && INTVAL (index) >= 0
3117 && (INTVAL (index) & 3) == 0);
3119 if (code == CONST_INT)
3121 /* When the mode size is larger than 4, we may use two ld instruction
3122 to get data, the index and (index+1) should be valid. */
3123 if (GET_MODE_SIZE (mode) >= 8)
3124 return (INTVAL (index) < CSKY_LD32_MAX_OFFSET (SImode)
3125 && INTVAL (index) >= 0 && (INTVAL (index) & 3) == 0);
3127 if (GET_MODE_SIZE (mode) > 0
3128 && INTVAL (index) <= CSKY_LD32_MAX_OFFSET (mode)
3129 && INTVAL (index) >= 0)
3130 return ((INTVAL (index) % GET_MODE_SIZE (mode)) == 0);
3132 /* Allow ld.w rx, (gb, sym@got) when -fpic specially. */
3133 else if (code == UNSPEC)
3134 return (flag_pic == 1
3135 && (XINT (index, 1) == UNSPEC_PIC_SYMBOL_PLT
3136 || XINT (index, 1) == UNSPEC_PIC_SYMBOL_GOT));
3137 /* The follow index is for ldr instruction, the ldr cannot
3138 load dword data, so the mode size should not be larger than
3139 4. */
3140 else if (GET_MODE_SIZE (mode) <= 4
3141 || (TARGET_HARD_FLOAT && CSKY_VREG_MODE_P (mode)))
3143 if (is_csky_address_register_rtx_p (index, strict_p))
3144 return 1;
3145 else if (code == MULT || code == ASHIFT)
3147 rtx xiop0 = XEXP (index, 0);
3148 rtx xiop1 = XEXP (index, 1);
3150 /* FIXME can the xiop1 be the reg and xiop0 be the int when mult? */
3151 return (is_csky_address_register_rtx_p (xiop0, strict_p)
3152 && CONST_INT_P (xiop1)
3153 && is_ldr_shift_p (INTVAL (xiop1), code));
3157 return 0;
3161 static int
3162 csky_legitimate_index_p (machine_mode mode, rtx index, int strict_p)
3164 if (CSKY_TARGET_ARCH (CK801))
3165 return ck801_legitimate_index_p (mode, index, strict_p);
3166 else if (CSKY_TARGET_ARCH (CK802))
3167 return ck802_legitimate_index_p (mode, index, strict_p);
3168 else
3169 return ck810_legitimate_index_p (mode, index, strict_p);
3173 /* Implement TARGET_LEGITIMATE_ADDRESS_P.
3174 Recognizes RTL expressions that are valid memory addresses for an
3175 instruction. The MODE argument is the machine mode for the MEM
3176 expression that wants to use this address.
3178 It only recognizes address in canonical form. LEGITIMIZE_ADDRESS should
3179 convert common non-canonical forms to canonical form so that they will
3180 be recognized. */
3182 static bool
3183 csky_legitimate_address_p (machine_mode mode, rtx addr, bool strict_p)
3185 enum rtx_code code = GET_CODE (addr);
3187 /* Match the RTX form emitted for constant pool references.
3188 After reload constants split into minipools will have addresses
3189 from a LABEL_REF. */
3190 if (reload_completed
3191 && ((code == LABEL_REF)
3192 || (code == CONST
3193 && GET_CODE (XEXP (addr, 0)) == PLUS
3194 && GET_CODE (XEXP (XEXP (addr, 0), 0)) == LABEL_REF
3195 && CONST_INT_P (XEXP (XEXP (addr, 0), 1)))))
3196 return 1;
3198 if (is_csky_address_register_rtx_p (addr, strict_p))
3199 return 1;
3200 /* It is a pc-relative load, may be generated for constpool. */
3201 else if (GET_CODE (addr) == LABEL_REF)
3202 return 1;
3204 if (code == PLUS)
3206 rtx xop0 = XEXP (addr, 0);
3207 rtx xop1 = XEXP (addr, 1);
3209 return ((is_csky_address_register_rtx_p (xop0, strict_p)
3210 && csky_legitimate_index_p (mode, xop1, strict_p))
3211 || (is_csky_address_register_rtx_p (xop1, strict_p)
3212 && csky_legitimate_index_p (mode, xop0, strict_p)));
3215 return 0;
3219 /* Functions to save and restore machine-specific function data. */
3221 static struct machine_function *
3222 csky_init_machine_status (void)
3224 struct machine_function *machine;
3226 machine = ggc_cleared_alloc<machine_function> ();
3228 #if CSKY_FT_UNKNOWN != 0
3229 machine->func_type = CSKY_FT_UNKNOWN;
3230 #endif
3231 return machine;
3235 /* Implement INIT_EXPANDERS. */
3237 void
3238 csky_init_expanders (void)
3240 /* Arrange to initialize and mark the machine per-function status. */
3241 init_machine_status = csky_init_machine_status;
3245 /* Implement TARGET_CANNOT_COPY_INSN_P.
3246 We must not copy any rtx that uses a pc-relative address. */
3248 static bool
3249 csky_cannot_copy_insn_p (rtx_insn *insn)
3251 subrtx_iterator::array_type array;
3252 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), ALL)
3254 const_rtx x = *iter;
3255 if (GET_CODE (x) == UNSPEC
3256 && (XINT (x, 1) == UNSPEC_TLS_LABEL
3257 || XINT (x, 1) == UNSPEC_PIC_SYMBOL_GOTPC_GRS))
3258 return true;
3260 return false;
3264 /* Extract the parts of an RTL expression that is a valid memory address
3265 for an instruction. Return FALSE if it is a invalid memory address. */
3267 struct csky_address
3269 rtx base, index, symbol, label, disp;
3270 HOST_WIDE_INT scale;
3273 static bool
3274 decompose_csky_address (rtx addr, struct csky_address *out)
3276 rtx base = NULL_RTX, index = NULL_RTX, disp = NULL_RTX;
3277 HOST_WIDE_INT scale = 0;
3278 rtx scale_rtx = NULL_RTX;
3279 int i;
3281 out->base = out->index = out->symbol = out->label = out->disp = NULL_RTX;
3282 out->scale = 0;
3284 if (REG_P (addr))
3286 out->base = addr;
3287 return true;
3290 if (GET_CODE (addr) == LABEL_REF)
3292 out->label = addr;
3293 return true;
3296 if (GET_CODE (addr) == CONST)
3297 addr = XEXP (addr, 0);
3299 if (GET_CODE (addr) == PLUS)
3301 rtx addends[2], op;
3303 addends[0] = XEXP (addr, 0);
3304 addends[1] = XEXP (addr, 1);
3306 if (GET_CODE (addends[0]) == LABEL_REF && CONST_INT_P (addends[1]))
3308 out->label = addends[0];
3309 out->disp = addends[1];
3310 return true;
3313 if (!REG_P (addends[0]))
3314 std::swap (addends[0], addends[1]);
3316 for (i = 0; i < 2; ++i)
3318 op = addends[i];
3319 switch (GET_CODE (op))
3321 case REG:
3322 if (!base)
3323 base = op;
3324 else if (!index)
3326 index = op;
3327 scale = 1;
3329 else
3330 return false;
3331 break;
3332 case CONST_INT:
3333 case UNSPEC:
3334 if (disp)
3335 return false;
3336 disp = op;
3337 break;
3338 case MULT:
3339 if (index)
3340 return false;
3341 index = XEXP (op, 0);
3342 scale_rtx = XEXP (op, 1);
3343 if (!CONST_INT_P (index) && !CONST_INT_P (scale_rtx))
3344 return false;
3345 else if (CONST_INT_P (index))
3346 std::swap (index, scale_rtx);
3347 scale = INTVAL (scale_rtx);
3348 break;
3349 case ASHIFT:
3350 if (index)
3351 return false;
3352 index = XEXP (op, 0);
3353 scale_rtx = XEXP (op, 1);
3354 if (!CONST_INT_P (scale_rtx))
3355 return false;
3356 scale = 1 << INTVAL (scale_rtx);
3357 break;
3358 default:
3359 return false;
3364 if (!base)
3365 return false;
3367 out->base = base;
3368 out->index = index;
3369 out->disp = disp;
3370 out->scale = scale;
3372 return true;
3375 /* Helper function for the csky_simple_mem_operand predicate. Returns
3376 true if OP is an address of the form reg + displacement. */
3378 bool
3379 csky_simple_addr_operand_p (rtx op)
3381 struct csky_address addr;
3383 if (!decompose_csky_address (op, &addr))
3384 return false;
3386 /* FIXME The PIC related code.
3387 Check if load the symbol address from got table. */
3388 if (addr.disp && GET_CODE (addr.disp) == UNSPEC)
3389 return false;
3390 if (!addr.index && !addr.symbol)
3391 return true;
3392 return false;
3396 /* Print the UNSPEC operand in X to the STREAM. */
3398 static void
3399 csky_output_pic_addr_const (FILE *stream, rtx x, int code)
3402 if (GET_CODE (x) != UNSPEC)
3403 return;
3405 if (UNSPEC_TLS == XINT (x, 1))
3407 /* FIXME It is not reached */
3408 return;
3411 csky_print_operand (stream, XVECEXP (x, 0, 0), code);
3413 switch (XINT (x, 1))
3415 case UNSPEC_PIC_SYMBOL_GOTOFF:
3416 fputs ("@GOTOFF", stream);
3417 break;
3418 case UNSPEC_PIC_SYMBOL_PLT:
3419 fputs ("@PLT", stream);
3420 break;
3421 case UNSPEC_PIC_SYMBOL_GOT:
3422 fputs ("@GOT", stream);
3423 break;
3424 case UNSPEC_PIC_SYMBOL_GOTPC:
3425 fputs ("@GOTPC", stream);
3426 break;
3427 case UNSPEC_PIC_SYMBOL_BSR:
3428 break;
3429 default:
3430 break;
3435 /* Output the constpool label according to the rtx expression X. */
3437 static void
3438 csky_output_constpool_label (FILE *stream, rtx x)
3440 char buf[15];
3442 gcc_assert (GET_CODE (x) == LABEL_REF);
3443 x = XEXP (x, 0);
3445 if (GET_CODE (x) == UNSPEC_VOLATILE && XINT (x, 1) == VUNSPEC_POOL_LABEL)
3447 ASM_GENERATE_INTERNAL_LABEL (buf, CSKY_CONSTPOOL_LABEL_PREFIX,
3448 INTVAL (XVECEXP (x, 0, 0)));
3449 assemble_name (stream, buf);
3454 /* Implement TARGET_PRINT_OPERAND_ADDRESS. */
3456 static void
3457 csky_print_operand_address (FILE *stream,
3458 machine_mode mode ATTRIBUTE_UNUSED,
3459 rtx x)
3462 struct csky_address addr;
3464 decompose_csky_address (x, &addr);
3466 if (addr.label && addr.disp && GET_CODE (addr.disp) == CONST_INT)
3468 fprintf (stream, "[");
3469 csky_output_constpool_label (stream, addr.label);
3470 fprintf (stream, "+%d]", (int) INTVAL (addr.disp));
3472 else if (addr.label)
3474 fprintf (stream, "[");
3475 csky_output_constpool_label (stream, addr.label);
3476 fprintf (stream, "]");
3478 else if (addr.symbol && addr.disp && GET_CODE (addr.disp) == CONST_INT)
3480 fprintf (stream, "[");
3481 output_addr_const (stream, addr.symbol);
3482 fprintf (stream, "+%d]", (int) INTVAL (addr.disp));
3484 else if (addr.symbol)
3486 fprintf (stream, "[");
3487 output_addr_const (stream, addr.symbol);
3488 fprintf (stream, "]");
3490 else if (addr.disp && GET_CODE (addr.disp) == CONST_INT)
3491 fprintf (stream, "(%s, %d)",
3492 reg_names[REGNO (addr.base)], (int) INTVAL (addr.disp));
3493 else if (addr.disp && GET_CODE (addr.disp) == UNSPEC)
3495 if (REGNO (addr.base) != CSKY_GB_REGNUM)
3496 fprintf (stream, "(%s, ", reg_names[REGNO (addr.base)]);
3497 else
3498 fprintf (stream, "[");
3499 csky_output_pic_addr_const (stream, addr.disp, 0);
3500 fprintf (stream, "%s", (REGNO (addr.base) != CSKY_GB_REGNUM)
3501 ? ")" : "]");
3503 else if (addr.index)
3504 fprintf (stream, "(%s, %s << %d)",
3505 reg_names[REGNO (addr.base)], reg_names[REGNO (addr.index)],
3506 exact_log2 ((int) (addr.scale)));
3507 else
3508 fprintf (stream, "(%s, 0)", reg_names[REGNO (addr.base)]);
3512 /* Implement TARGET_PRINT_OPERAND.
3513 Print operand X (an rtx) in assembler syntax to file STREAM
3514 according to modifier CODE.
3516 'N' print the log2(X+1), mainly used for bmaski
3517 'P' print the log2(X)
3518 'Q' print the log2(~X)
3519 'O' print a decimal number
3520 'M' print a decimal number as its negative
3521 'R' print the next register or memory location along, i.e. the lsw in
3522 a double word value
3523 'H' print the high 16 bits of a constant. */
3525 static void
3526 csky_print_operand (FILE *stream, rtx x, int code)
3528 switch (code)
3530 case 'N':
3531 if ((INTVAL (x) & 0xffffffff) == 0xffffffff)
3532 fprintf (stream, "0");
3533 else
3534 fprintf (stream, "%d",
3535 (int) exact_log2 ((INTVAL (x) & 0xffffffff) + 1) % 32);
3536 break;
3537 case 'P':
3538 fprintf (stream, "%d",
3539 (int) exact_log2 (INTVAL (x) & 0xffffffff));
3540 break;
3541 case 'Q':
3542 fprintf (stream, "%d",
3543 (int) exact_log2 (~INTVAL (x) & 0xffffffff));
3544 break;
3545 case 'O':
3546 fprintf (stream, "%d", (int) INTVAL (x));
3547 break;
3548 case 'M':
3549 fprintf (stream, "%d", (int) (-INTVAL (x)));
3550 break;
3551 case 'R':
3552 /* Next location along in memory or register. */
3553 switch (GET_CODE (x))
3555 case REG:
3556 fputs (reg_names[REGNO (x) + 1], stream);
3557 break;
3558 case MEM:
3559 csky_print_operand_address
3560 (stream, GET_MODE (x), XEXP (adjust_address (x, SImode, 4), 0));
3561 break;
3562 default:
3563 gcc_unreachable ();
3565 break;
3566 case 'H':
3567 fprintf (stream, "%ld", (long)((INTVAL (x) & 0xFFFF0000) >> 16));
3568 break;
3569 default:
3570 switch (GET_CODE (x))
3572 case REG:
3573 fputs (reg_names[REGNO (x)], stream);
3574 break;
3575 case MEM:
3576 output_address (GET_MODE (x), XEXP (x, 0));
3577 break;
3578 case UNSPEC:
3579 csky_output_pic_addr_const (stream, x, code);
3580 break;
3581 case CONST_DOUBLE:
3583 char fpstr[20];
3584 real_to_decimal ( fpstr, CONST_DOUBLE_REAL_VALUE (x),
3585 sizeof (fpstr), 0, 1);
3586 fprintf (stream, "%s", fpstr);
3588 break;
3589 default:
3590 output_addr_const (stream, x);
3591 break;
3593 break;
3599 /* Implement TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS. */
3601 static bool
3602 csky_allocate_stack_slots_for_args (void)
3604 /* Naked functions should not allocate stack slots for arguments. */
3605 return !CSKY_FUNCTION_IS_NAKED (get_csky_current_func_type ());
3609 /* Can we generate a constant with a single instruction, without using
3610 lrw? */
3612 static int
3613 const_ok_for_cskyv2 (HOST_WIDE_INT value)
3615 /* Try exact power of two. It can be generated by bgeni. */
3616 if (CSKY_CONST_OK_FOR_Ub (value))
3617 return 1;
3619 /* Try exact power of two - 1. It can be generated by bmaski. */
3620 if (CSKY_CONST_OK_FOR_Uc (value) && value != -1)
3621 return 1;
3623 /* Try if it can be generated by movi. */
3624 if (CSKY_CONST_OK_FOR_I (value))
3625 return 1;
3627 /* The constant can be generated by movih.
3628 Notice that movih is a 32-bit instruction. */
3629 if (CSKY_CONST_OK_FOR_MOVIH (value))
3630 return 1;
3632 return 0;
3636 /* Tricks for synthesizing constants from values that can be directly
3637 manipulated by machine instructions. */
3639 enum csky_inline_const_type
3641 IC_UNINLINABLE = 0, /* Not inlineable */
3642 IC_SINGLE, /* Single instruction */
3643 IC_APPEND_NOT, /* Single instruction followed by a not */
3644 IC_APPEND_ADDI, /* Single insn followed by an addi */
3645 IC_APPEND_SUBI, /* Single insn followed by a subi */
3646 IC_BGENI_ADDI, /* Single insn(bgeni) followed by an addi */
3647 IC_BGENI_SUBI, /* Single insn(bgeni) followed by a subi */
3648 IC_APPEND_BSETI, /* Single insn followed by bseti */
3649 IC_APPEND_MOVI, /* Single insn followed by movi */
3650 IC_APPEND_BCLRI, /* Single insn followed by bclri */
3651 IC_APPEND_ROTLI, /* Single insn followed by rotli */
3652 IC_APPEND_LSLI, /* Single insn followed by lsli */
3653 IC_APPEND_IXH, /* Single insn followed by ixh */
3654 IC_APPEND_IXW /* Single insn followed by ixw */
3658 /* Try tricks to load a constant inline and return the trick number if
3659 success, or IC_UNINLINABLE. */
3661 static enum csky_inline_const_type
3662 try_csky_constant_tricks (HOST_WIDE_INT value, HOST_WIDE_INT *x,
3663 HOST_WIDE_INT *y)
3665 HOST_WIDE_INT i, value_invert;
3666 unsigned HOST_WIDE_INT bit, shf, rot, lobits, hibits;
3668 value &= 0xffffffff;
3669 value_invert = ~value & 0xffffffff;
3671 if (const_ok_for_cskyv2 (value))
3673 *x = value;
3674 return IC_SINGLE;
3677 /* Since movih is 32 bits, do not use it here, better code may
3678 be generated later. */
3679 if (const_ok_for_cskyv2 (value_invert)
3680 && !CSKY_CONST_OK_FOR_MOVIH (value_invert))
3682 *x = value_invert;
3683 return IC_APPEND_NOT;
3686 /* One immediate generate instruction, and one 16-bit subi or addi. */
3687 for (i = 1; i <= 32; i++)
3689 if (const_ok_for_cskyv2 (value - i)
3690 && !CSKY_CONST_OK_FOR_MOVIH (value - i))
3692 *x = value - i;
3693 *y = i;
3694 return IC_APPEND_ADDI;
3697 if (const_ok_for_cskyv2 (value + i)
3698 && !CSKY_CONST_OK_FOR_MOVIH (value - i))
3700 *x = value + i;
3701 *y = i;
3702 return IC_APPEND_SUBI;
3706 /* Generate bgeni + addi. */
3707 if (CSKY_CONST_OK_FOR_Ub (value & 0xfffff000))
3709 *x = (value & 0xfffff000);
3710 *y = (value & 0xfff);
3711 return IC_BGENI_ADDI;
3714 /* Generate bgeni + subi. */
3715 lobits = value & 0xfff;
3716 hibits = (unsigned HOST_WIDE_INT)(value & 0xfffff000) + (1 << 12);
3717 if (exact_log2 (hibits) >= 1
3718 && exact_log2 (hibits) <= 30
3719 && lobits != 0)
3721 *x = hibits;
3722 *y = (0x1000 - lobits);
3723 return IC_BGENI_SUBI;
3726 /* One immediate generate instruction, and one bseti or bclri. */
3727 bit = 0x80000000ULL;
3728 for (i = 0; i <= 31; i++)
3730 if (const_ok_for_cskyv2 (value & ~bit)
3731 && !CSKY_CONST_OK_FOR_MOVIH (value & ~bit))
3733 *y = bit;
3734 *x = (value & ~bit);
3735 return IC_APPEND_BSETI;
3738 if (const_ok_for_cskyv2 (value | bit)
3739 && !CSKY_CONST_OK_FOR_MOVIH (value | bit))
3741 *y = ~bit & 0xffffffff;
3742 *x = value | bit;
3743 return IC_APPEND_BCLRI;
3746 bit >>= 1;
3749 /* One immediate generate instruction, and one rotli or lsli. */
3750 shf = value;
3751 rot = value;
3752 for (i = 1; i < 31; i++)
3754 int c;
3756 /* Rotate left. */
3757 c = rot << 31;
3758 rot >>= 1;
3759 rot &= 0x7FFFFFFF;
3760 rot |= c;
3762 if (const_ok_for_cskyv2 (rot) && !CSKY_CONST_OK_FOR_MOVIH (rot))
3764 *y = i;
3765 *x = rot;
3766 return IC_APPEND_ROTLI;
3769 /* Can't use logical shift when low order bit is one. */
3770 if (shf & 1)
3771 shf = 0;
3772 else
3773 shf >>= 1;
3775 if (shf != 0 && const_ok_for_cskyv2 (shf)
3776 && !CSKY_CONST_OK_FOR_MOVIH (shf))
3778 *y = i;
3779 *x = shf;
3780 return IC_APPEND_LSLI;
3784 /* One immediate generate instruction, and one ixh. */
3785 if (CSKY_ISA_FEATURE (E2)
3786 && (value % 3) == 0
3787 && const_ok_for_cskyv2 (value / 3)
3788 && !CSKY_CONST_OK_FOR_MOVIH (value / 3))
3790 *x = value / 3;
3791 return IC_APPEND_IXH;
3794 /* One immediate generate instruction, and one ixw. */
3795 if (CSKY_ISA_FEATURE (E2)
3796 && (value % 5) == 0
3797 && const_ok_for_cskyv2 (value / 5)
3798 && !CSKY_CONST_OK_FOR_MOVIH (value / 5))
3800 *x = value / 5;
3801 return IC_APPEND_IXW;
3804 /* Generate movih + bseti. */
3805 if (CSKY_CONST_OK_FOR_Ub (value & 0xffff))
3807 *x = value & 0xffff0000;
3808 *y = value & 0xffff;
3809 return IC_APPEND_BSETI;
3812 /* Generate movih + not. */
3813 if (CSKY_CONST_OK_FOR_MOVIH (value_invert))
3815 *x = value_invert;
3816 return IC_APPEND_NOT;
3819 /* One movih, and one 16bits addi or subi. */
3820 for (i = 1; i <= 32; i++)
3822 if (CSKY_CONST_OK_FOR_MOVIH (value - i))
3824 *x = value - i;
3825 *y = i;
3826 return IC_APPEND_ADDI;
3829 if (CSKY_CONST_OK_FOR_MOVIH (value + i))
3831 *x = value + i;
3832 *y = i;
3833 return IC_APPEND_SUBI;
3837 /* One movih, and one bseti or bclri. */
3838 bit = 0x80000000ULL;
3839 for (i = 0; i <= 31; i++)
3841 if (CSKY_CONST_OK_FOR_MOVIH (value & ~bit))
3843 *y = bit;
3844 *x = value & ~bit;
3845 return IC_APPEND_BSETI;
3848 if (CSKY_CONST_OK_FOR_MOVIH (value | bit))
3850 *y = ~bit & 0xffffffff;
3851 *x = value | bit;
3852 return IC_APPEND_BCLRI;
3855 bit >>= 1;
3858 /* One movih, and one rotli or lsli. */
3859 shf = value;
3860 rot = value;
3861 for (i = 1; i < 31; i++)
3863 int c;
3865 /* Rotate left. */
3866 c = rot << 31;
3867 rot >>= 1;
3868 rot &= 0x7FFFFFFF;
3869 rot |= c;
3871 if (CSKY_CONST_OK_FOR_MOVIH (rot))
3873 *y = i;
3874 *x = rot;
3875 return IC_APPEND_ROTLI;
3878 /* Can't use logical shift when low order bit is one. */
3879 if (shf & 1)
3880 shf = 0;
3881 else
3882 shf >>= 1;
3884 if (shf != 0 && CSKY_CONST_OK_FOR_MOVIH (shf))
3886 *y = i;
3887 *x = shf;
3888 return IC_APPEND_LSLI;
3892 return IC_UNINLINABLE;
3896 /* Actually output a constant using a trick.
3897 FIXME: I think this would be better handled by a splitter than at the
3898 asm output level. */
3900 static const char *
3901 csky_output_inline_const (machine_mode mode, rtx operands[])
3903 HOST_WIDE_INT x = 0, y = 0;
3904 enum csky_inline_const_type trick_type;
3905 rtx out_operands[3];
3906 char buf[256];
3907 char load_op[128];
3908 const char *dst_fmt;
3909 HOST_WIDE_INT value = INTVAL (operands[1]);
3910 int ivalue = (int) value;
3911 unsigned int uvalue = (unsigned int) value;
3913 trick_type = try_csky_constant_tricks (value, &x, &y);
3914 /* lrw's are handled separately: Large inlinable constants never get
3915 turned into lrw's. Our caller uses try_csky_constant_tricks to back
3916 off to an lrw rather than calling this routine. */
3917 gcc_assert (trick_type != IC_UNINLINABLE);
3919 /* Operands: 0 = dst, 1 = load immedate., 2 = adjust immedate. */
3920 out_operands[0] = operands[0];
3921 out_operands[1] = GEN_INT (x);
3922 if (trick_type != IC_SINGLE && trick_type != IC_APPEND_NOT)
3923 out_operands[2] = GEN_INT (y);
3925 /* Select dst format based on mode. */
3926 if (mode == DImode && TARGET_BIG_ENDIAN)
3927 dst_fmt = "%R0";
3928 else
3929 dst_fmt = "%0";
3931 /* Try movi16: 0~31,movi32: 0~65535. */
3932 if (CSKY_CONST_OK_FOR_I (x))
3933 sprintf (load_op, "movi\t%s, %%1", dst_fmt);
3934 /* Try exact power of two - 1. */
3935 else if (CSKY_CONST_OK_FOR_Uc (x))
3936 sprintf (load_op, "bmaski\t%s, %%N1", dst_fmt);
3937 /* Try movih. */
3938 else if (CSKY_CONST_OK_FOR_MOVIH (x))
3939 sprintf (load_op, "movih\t%s, %%H1", dst_fmt);
3940 else
3942 sprintf (load_op, "BADMOVI-inline_const %s, %%1", dst_fmt);
3943 gcc_unreachable ();
3946 switch (trick_type)
3948 case IC_SINGLE:
3949 strcpy (buf, load_op);
3950 break;
3951 /* Add instruction 'not'. */
3952 case IC_APPEND_NOT:
3953 sprintf (buf, "%s\n\tnot\t%s, %s\t// %d 0x%x", load_op, dst_fmt,
3954 dst_fmt, ivalue, uvalue);
3955 break;
3956 /* Add instruction 'addi'. */
3957 case IC_APPEND_ADDI:
3958 sprintf (buf, "%s\n\taddi\t%s, %s, %%2\t// %d 0x%x", load_op,
3959 dst_fmt, dst_fmt, ivalue, uvalue);
3960 break;
3961 /* Add instruction 'subi'. */
3962 case IC_APPEND_SUBI:
3963 sprintf (buf, "%s\n\tsubi\t%s, %s, %%2\t// %d 0x%x", load_op,
3964 dst_fmt, dst_fmt, ivalue, uvalue);
3965 break;
3966 /* Add instruction 'addi', the last instruction is bgeni. */
3967 case IC_BGENI_ADDI:
3968 sprintf (buf, "%s\n\taddi\t%s, %s, %%2\t// %d 0x%x", load_op,
3969 dst_fmt, dst_fmt, ivalue, uvalue);
3970 break;
3971 /* Add instruction 'subi', the last instruction is bgeni. */
3972 case IC_BGENI_SUBI:
3973 sprintf (buf, "%s\n\tsubi\t%s, %s, %%2\t// %d 0x%x", load_op,
3974 dst_fmt, dst_fmt, ivalue, uvalue);
3975 break;
3976 /* Add instruction 'bseti'. */
3977 case IC_APPEND_BSETI:
3978 sprintf (buf, "%s\n\tbseti\t%s, %s, %%P2\t// %d 0x%x", load_op,
3979 dst_fmt, dst_fmt, ivalue, uvalue);
3980 break;
3981 /* Add instruction 'movi'. */
3982 case IC_APPEND_MOVI:
3983 sprintf (buf, "%s\n\tmovi\t%s, %%2\t// %d 0x%x", load_op, dst_fmt,
3984 ivalue, uvalue);
3985 break;
3986 /* Add instruction 'bclri'. */
3987 case IC_APPEND_BCLRI:
3988 sprintf (buf, "%s\n\tbclri\t%s, %s, %%Q2\t// %d 0x%x", load_op,
3989 dst_fmt, dst_fmt, ivalue, uvalue);
3990 break;
3991 /* Add instruction 'rotli'. */
3992 case IC_APPEND_ROTLI:
3993 sprintf (buf, "%s\n\trotli\t%s, %s, %%2\t// %d 0x%x", load_op,
3994 dst_fmt, dst_fmt, ivalue, uvalue);
3995 break;
3996 /* Add instruction 'lsli'. */
3997 case IC_APPEND_LSLI:
3998 sprintf (buf, "%s\n\tlsli\t%s, %s, %%2\t// %d 0x%x", load_op,
3999 dst_fmt, dst_fmt, ivalue, uvalue);
4000 break;
4001 /* Add instruction 'ixh'. */
4002 case IC_APPEND_IXH:
4003 sprintf (buf, "%s\n\tixh\t%s, %s, %s\t// %d 0x%x", load_op,
4004 dst_fmt, dst_fmt, dst_fmt, ivalue, uvalue);
4005 break;
4006 /* Add instruction 'ixw'. */
4007 case IC_APPEND_IXW:
4008 sprintf (buf, "%s\n\tixw\t%s, %s, %s\t// %d 0x%x", load_op,
4009 dst_fmt, dst_fmt, dst_fmt, ivalue, uvalue);
4010 break;
4011 default:
4012 return "";
4015 output_asm_insn (buf, out_operands);
4017 return "";
4020 /* This is a helper function for the Uo constraint for movsi patterns. */
4022 bool
4023 csky_inlinable_constant (HOST_WIDE_INT value)
4025 HOST_WIDE_INT x, y;
4026 return (!(CSKY_TARGET_ARCH (CK802) || CSKY_TARGET_ARCH (CK801))
4027 && try_csky_constant_tricks (value, &x, &y));
4031 /* Return true if the constant VAL can be expressed by an 8-bit constant
4032 with a shift value, filling in *BASE and *SHIFT. */
4034 bool
4035 csky_shifted_imm8_constant (unsigned HOST_WIDE_INT val,
4036 unsigned int *base, unsigned int *shift)
4038 unsigned HOST_WIDE_INT mask = 0xff;
4039 int i;
4040 val = val & (unsigned HOST_WIDE_INT) 0xffffffffu;
4041 if (val == 0)
4042 return 0;
4044 for (i = 0; i < 25; i++)
4045 if ((val & (mask << i)) == val)
4047 if (base)
4048 *base = (unsigned int) (val >> i);
4049 if (shift)
4050 *shift = (unsigned int) i;
4051 return true;
4054 return false;
4058 /* Output a move of a word or less value. */
4060 const char *
4061 csky_output_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
4062 machine_mode mode ATTRIBUTE_UNUSED)
4064 rtx dst = operands[0];
4065 rtx src = operands[1];
4066 struct csky_address op0, op1;
4068 if (REG_P (dst))
4070 /* The situation mov reg to reg. */
4071 if (REG_P (src))
4073 int dstreg = REGNO (dst);
4074 int srcreg = REGNO (src);
4076 /* hilo registers exchange their places,
4077 and their order of Dimode as same as other
4078 general registers in LITTLE_ENDIAN mode. */
4079 if (TARGET_BIG_ENDIAN)
4081 if (dstreg == CSKY_HI_REGNUM)
4082 return "mthi\t%1";
4083 else if (dstreg == CSKY_LO_REGNUM)
4084 return "mtlo\t%1";
4085 else if (srcreg == CSKY_HI_REGNUM)
4086 return "mfhi\t%0";
4087 else if (srcreg == CSKY_LO_REGNUM)
4088 return "mflo\t%0";
4090 else
4092 if (dstreg == CSKY_HI_REGNUM)
4093 return "mtlo\t%1";
4094 else if (dstreg == CSKY_LO_REGNUM)
4095 return "mthi\t%1";
4096 else if (srcreg == CSKY_HI_REGNUM)
4097 return "mflo\t%0";
4098 else if (srcreg == CSKY_LO_REGNUM)
4099 return "mfhi\t%0";
4102 if (CSKY_VREG_P (dstreg) && CSKY_VREG_P (srcreg))
4104 if (CSKY_ISA_FEATURE (fpv2_sf))
4105 return "fmovs\t%0, %1";
4106 else if (CSKY_ISA_FEATURE (fpv3_sf))
4107 return "fmov.32\t%0, %1";
4108 else
4109 gcc_unreachable ();
4111 if (CSKY_VREG_P (dstreg))
4113 if (CSKY_ISA_FEATURE (fpv2_sf))
4114 return "fmtvrl\t%0, %1";
4115 else if (CSKY_ISA_FEATURE (fpv3_sf))
4116 return "fmtvr.32.1\t%0, %1";
4117 else
4118 gcc_unreachable ();
4120 if (CSKY_VREG_P (srcreg))
4122 if (CSKY_ISA_FEATURE (fpv2_sf))
4123 return "fmfvrl\t%0, %1";
4124 else if (CSKY_ISA_FEATURE (fpv3_sf))
4125 return "fmfvr.32.1\t%0, %1";
4126 else
4127 gcc_unreachable ();
4129 if (REGNO (src) == CSKY_CC_REGNUM)
4130 return "mvc\t%0";
4131 else
4132 return "mov\t%0, %1";
4134 /* The situation mov memory to reg. */
4135 else if (GET_CODE (src) == MEM)
4137 decompose_csky_address (XEXP (src, 0), &op1);
4139 if (op1.index)
4140 switch (GET_MODE (src))
4142 case E_HImode:
4143 case E_HFmode:
4144 return "ldr.h\t%0, %1";
4145 case E_QImode:
4146 return "ldr.b\t%0, %1";
4147 case E_SImode:
4148 case E_SFmode:
4149 if (CSKY_VREG_P (REGNO (dst)))
4151 if (CSKY_ISA_FEATURE(fpv2_sf))
4152 return "fldrs\t%0, %1";
4153 else if (CSKY_ISA_FEATURE(fpv3_sf))
4154 return "fldr.32\t%0, %1";
4155 else
4156 gcc_unreachable ();
4158 else
4159 return "ldr.w\t%0, %1";
4160 default:
4161 gcc_unreachable ();
4163 /* Generate lrw rx, [LABEL]. This happens when the compiler
4164 generates constant pool references and uses lrw to get the
4165 constant into memory. */
4166 else if (op1.label)
4167 return "lrw\t%0, %1";
4168 /* Generate lrs.w rx, [symbol@GOT/PLT]. */
4169 else if (flag_pic == 1 && op1.disp && GET_CODE (op1.disp) == UNSPEC)
4170 return "lrs.w\t%0, %1";
4171 else
4172 switch (GET_MODE (src))
4174 case E_HImode:
4175 case E_HFmode:
4176 return "ld.h\t%0, %1";
4177 case E_QImode:
4178 return "ld.b\t%0, %1";
4179 case E_SFmode:
4180 case E_SImode:
4181 if (CSKY_VREG_P (REGNO (dst)))
4183 if (CSKY_ISA_FEATURE(fpv2_sf))
4184 return "flds\t%0, %1";
4185 else if (CSKY_ISA_FEATURE(fpv3_sf))
4186 return "fld.32\t%0, %1";
4187 else
4188 gcc_unreachable ();
4190 else
4191 return "ld.w\t%0, %1";
4192 default:
4193 gcc_unreachable ();
4196 /* The situation mov integer to reg. */
4197 else if (GET_CODE (src) == CONST_INT ||
4198 (GET_CODE (src) == CONST_DOUBLE && GET_MODE (src) == SFmode))
4200 HOST_WIDE_INT x, y;
4201 const REAL_VALUE_TYPE *d;
4202 long l;
4204 if (GET_CODE (src) == CONST_DOUBLE && GET_MODE (src) == SFmode)
4206 d = CONST_DOUBLE_REAL_VALUE (src);
4207 REAL_VALUE_TO_TARGET_SINGLE (*d, l);
4208 operands[1] = GEN_INT (l);
4209 src = operands[1];
4212 if (try_csky_constant_tricks (INTVAL (src), &x, &y))
4213 return csky_output_inline_const (SImode, operands);
4214 /* Return '#' to split it. */
4215 else if (CSKY_CONST_OK_FOR_T (INTVAL (src)))
4216 return "#";
4217 else
4218 return "lrw\t%0, %x1\t";
4220 else if (TARGET_ANCHOR && GET_CODE (src) == SYMBOL_REF)
4222 if (SYMBOL_REF_FUNCTION_P (src))
4223 return "lrw\t%0, %1@BTEXT";
4224 else
4225 return "lrw\t%0, %1@BDATA";
4227 else if (GET_CODE (src) == UNSPEC
4228 && XINT (src, 1) == UNSPEC_PIC_SYMBOL_GRS)
4229 return "grs\t%0, %1";
4230 else
4231 return "lrw\t%0, %1";
4233 else if (GET_CODE (dst) == MEM)
4235 decompose_csky_address (XEXP (dst, 0), &op0);
4237 if (op0.index)
4238 switch (GET_MODE (src))
4240 case E_HImode:
4241 return "str.h\t%1, %0";
4242 case E_QImode:
4243 return "str.b\t%1, %0";
4244 case E_SFmode:
4245 case E_SImode:
4246 if (CSKY_VREG_P (REGNO (src)))
4248 if (CSKY_ISA_FEATURE(fpv2_sf))
4249 return "fstrs\t%1, %0";
4250 else if (CSKY_ISA_FEATURE(fpv3_sf))
4251 return "fstr.32\t%1, %0";
4252 else
4253 gcc_unreachable ();
4255 else
4256 return "str.w\t%1, %0";
4257 default:
4258 gcc_unreachable ();
4260 else
4261 switch (GET_MODE (dst))
4263 case E_HImode:
4264 return "st.h\t%1, %0";
4265 case E_QImode:
4266 return "st.b\t%1, %0";
4267 case E_SImode:
4268 case E_SFmode:
4269 if (CSKY_VREG_P (REGNO (src)))
4271 if (CSKY_ISA_FEATURE(fpv2_sf))
4272 return "fsts\t%1, %0";
4273 else if (CSKY_ISA_FEATURE(fpv3_sf))
4274 return "fst.32\t%1, %0";
4275 else
4276 gcc_unreachable ();
4278 else
4279 return "st.w\t%1, %0";
4280 default:
4281 gcc_unreachable ();
4285 gcc_unreachable ();
4289 /* Output a move of a word or less value. Specific for ck801. */
4291 const char *
4292 csky_output_ck801_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
4293 machine_mode mode ATTRIBUTE_UNUSED)
4295 rtx dst = operands[0];
4296 rtx src = operands[1];
4297 struct csky_address op1;
4299 if (REG_P (dst))
4301 if (REG_P (src))
4302 return "mov\t%0, %1";
4303 else if (GET_CODE (src) == MEM)
4305 decompose_csky_address (XEXP (src, 0), &op1);
4307 /* Generate lrw rx, [LABEL]. This happens when the compiler
4308 generates constant pool references and uses lrw to get the
4309 constant in memory. */
4310 if (op1.label)
4311 return "lrw\t%0, %1";
4312 else
4313 switch (GET_MODE (src))
4315 case E_HImode:
4316 return "ld.h\t%0, %1";
4317 case E_QImode:
4318 return "ld.b\t%0, %1";
4319 case E_SFmode:
4320 case E_SImode:
4321 return "ld.w\t%0, %1";
4322 default:
4323 gcc_unreachable ();
4326 else if (GET_CODE (src) == CONST_INT)
4328 if (REGNO (dst) > 7)
4329 return "lrw\t%0, %x1\t";
4330 else if (CSKY_CONST_OK_FOR_N (INTVAL (src) + 1))
4331 return "movi\t%0, %1";
4332 /* Return '#' to split it. */
4333 else if (CSKY_CONST_OK_FOR_T (INTVAL (src)))
4334 return "#";
4335 else if (csky_shifted_imm8_constant (INTVAL (src), NULL, NULL))
4336 return "#";
4337 else
4338 return "lrw\t%0, %x1\t";
4340 else if (GET_CODE (src) == CONST_DOUBLE && GET_MODE (src) == SFmode)
4342 const REAL_VALUE_TYPE *d;
4343 long l;
4345 d = CONST_DOUBLE_REAL_VALUE (src);
4346 REAL_VALUE_TO_TARGET_SINGLE (*d, l);
4347 operands[1] = GEN_INT (l);
4348 src = operands[1];
4350 if (CSKY_CONST_OK_FOR_N (INTVAL (src) + 1))
4351 return "movi\t%0, %1";
4352 else
4353 return "lrw\t%0, %x1\t";
4355 else if (TARGET_ANCHOR && GET_CODE (src) == SYMBOL_REF)
4357 if (SYMBOL_REF_FUNCTION_P (src))
4358 return "lrw\t%0, %1@BTEXT";
4359 else
4360 return "lrw\t%0, %1@BDATA";
4362 else
4363 return "lrw\t%0, %1";
4365 else if (GET_CODE (dst) == MEM)
4366 switch (GET_MODE (dst))
4368 case E_HImode:
4369 return "st.h\t%1, %0";
4370 case E_QImode:
4371 return "st.b\t%1, %0";
4372 case E_SImode:
4373 case E_SFmode:
4374 return "st.w\t%1, %0";
4375 default:
4376 gcc_unreachable ();
4379 gcc_unreachable ();
4383 /* Return a sequence of instructions to perform DI or DF move.
4384 Since the CSKY cannot move a DI or DF in one instruction, we have
4385 to take care when we see overlapping source and dest registers. */
4387 const char *
4388 csky_output_movedouble (rtx operands[],
4389 machine_mode mode ATTRIBUTE_UNUSED)
4391 rtx dst = operands[0];
4392 rtx src = operands[1];
4394 if (REG_P (dst))
4396 if (REG_P (src))
4398 int dstreg = REGNO (dst);
4399 int srcreg = REGNO (src);
4401 if (CSKY_HILO_REG_P (srcreg))
4403 if (TARGET_BIG_ENDIAN)
4404 return "mfhi\t%0\n\tmflo\t%R0";
4405 else
4406 return "mfhi\t%R0\n\tmflo\t%0";
4408 else if (CSKY_HILO_REG_P (dstreg))
4410 if (TARGET_BIG_ENDIAN)
4411 return "mthi\t%1\n\tmtlo\t%R1";
4412 else
4413 return "mthi\t%R1\n\tmtlo\t%1";
4415 else if (CSKY_VREG_P (srcreg) && CSKY_VREG_P (dstreg))
4417 if (CSKY_ISA_FEATURE(fpv2_df))
4418 return "fmovd\t%0, %1";
4419 else if (CSKY_ISA_FEATURE(fpv3_df))
4420 return "fmov.64\t%0, %1";
4421 else
4422 gcc_unreachable ();
4424 else if (CSKY_VREG_P (srcreg))
4426 /* Since the vector registers in fpuv2_soft processors
4427 like ck803f are 32 bits wide, just one insn is needed
4428 to complete the move operation. */
4429 if (TARGET_SOFT_FPU)
4430 return "fmfvrl\t%0, %1";
4431 else if (TARGET_BIG_ENDIAN)
4433 if (CSKY_ISA_FEATURE(fpv2_df))
4434 return "fmfvrh\t%0, %1\n\tfmfvrl\t%R0, %1";
4435 else if (CSKY_ISA_FEATURE(fpv3_df))
4436 return "fmfvr.64\t%R0, %0, %1";
4437 else
4438 gcc_unreachable ();
4440 else
4442 if (CSKY_ISA_FEATURE(fpv2_df))
4443 return "fmfvrh\t%R0, %1\n\tfmfvrl\t%0, %1";
4444 else if (CSKY_ISA_FEATURE(fpv3_df))
4445 return "fmfvr.64\t%0, %R0, %1";
4446 else
4447 gcc_unreachable ();
4450 else if (CSKY_VREG_P (dstreg))
4452 if (TARGET_SOFT_FPU)
4453 return "fmtvrl\t%0, %1";
4454 else if (TARGET_BIG_ENDIAN)
4456 if (CSKY_ISA_FEATURE(fpv2_df))
4457 return "fmtvrh\t%0, %1\n\tfmtvrl\t%0, %R1";
4458 else if (CSKY_ISA_FEATURE(fpv3_df))
4459 return "fmtvr.64\t%0, %R1, %1";
4460 else
4461 gcc_unreachable ();
4463 else
4465 if (CSKY_ISA_FEATURE(fpv2_df))
4466 return "fmtvrh\t%0, %R1\n\tfmtvrl\t%0, %1";
4467 else if (CSKY_ISA_FEATURE(fpv3_df))
4468 return "fmtvr.64\t%0, %1, %R1";
4469 else
4470 gcc_unreachable ();
4474 /* Ensure the second source not overwritten. */
4475 if (srcreg + 1 == dstreg)
4476 return "mov\t%R0, %R1\n\tmov\t%0, %1";
4477 else
4478 return "mov\t%0, %1\n\tmov\t%R0, %R1";
4480 else if (GET_CODE (src) == MEM)
4482 rtx memexp = XEXP (src, 0);
4483 int dstreg = REGNO (dst);
4484 int basereg = -1;
4485 struct csky_address op0;
4487 decompose_csky_address (XEXP (src, 0), &op0);
4489 if (GET_CODE (memexp) == LABEL_REF
4490 || (GET_CODE (memexp) == CONST
4491 && GET_CODE (XEXP (memexp, 0)) == PLUS
4492 && GET_CODE (XEXP (XEXP (memexp, 0), 0)) == LABEL_REF))
4493 return "lrw\t%0, [%1]\n\tlrw\t%R0, [%R1]";
4494 else if (GET_CODE (memexp) == REG)
4495 basereg = REGNO (memexp);
4496 else if (GET_CODE (memexp) == PLUS)
4498 if (GET_CODE (XEXP (memexp, 0)) == REG)
4499 basereg = REGNO (XEXP (memexp, 0));
4500 else if (GET_CODE (XEXP (memexp, 1)) == REG)
4501 basereg = REGNO (XEXP (memexp, 1));
4502 else
4503 gcc_unreachable ();
4505 else
4506 gcc_unreachable ();
4509 /* When FPUV2. */
4510 if (CSKY_VREG_P (dstreg))
4512 if (op0.index)
4514 if (CSKY_ISA_FEATURE(fpv2_df))
4515 return "fldrd\t%0, %1";
4516 else if (CSKY_ISA_FEATURE(fpv3_df))
4517 return "fldr.64\t%0, %1";
4518 else
4519 gcc_unreachable ();
4521 else
4523 if (CSKY_ISA_FEATURE(fpv2_df))
4524 return "fldd\t%0, %1";
4525 else if (CSKY_ISA_FEATURE(fpv3_df))
4526 return "fld.64\t%0, %1";
4527 else
4528 gcc_unreachable ();
4531 /* FIXME length attribute is wrong here. */
4532 if (dstreg == basereg)
4533 /* Just load them in reverse order. */
4534 return "ld.w\t%R0, %R1\n\tld.w\t%0, %1";
4535 else
4536 return "ld.w\t%0, %1\n\tld.w\t%R0, %R1";
4538 else if (GET_CODE (src) == CONST_INT || GET_CODE (src) == CONST_DOUBLE)
4540 split_double (src, operands + 2, operands + 3);
4542 if (CSKY_CONST_OK_FOR_I (INTVAL (operands[2])))
4543 output_asm_insn ("movi\t%0, %2", operands);
4544 else if (CSKY_CONST_OK_FOR_Uc (INTVAL (operands[2])))
4545 output_asm_insn ("bmaski\t%0, %N2", operands);
4546 else if (CSKY_CONST_OK_FOR_Ub (INTVAL (operands[2])))
4547 output_asm_insn ("bgeni\t%0, %P2", operands);
4548 else
4549 output_asm_insn ("lrw\t%0, %2", operands);
4551 if (CSKY_CONST_OK_FOR_I (INTVAL (operands[3])))
4552 output_asm_insn ("movi\t%R0, %3", operands);
4553 else if (CSKY_CONST_OK_FOR_Uc (INTVAL (operands[3])))
4554 output_asm_insn ("bmaski\t%R0, %N3", operands);
4556 else if (CSKY_CONST_OK_FOR_Ub (INTVAL (operands[3])))
4557 output_asm_insn ("bgeni\t%R0, %P3", operands);
4558 else
4559 output_asm_insn ("lrw\t%R0, %3", operands);
4561 return "";
4563 else
4564 gcc_unreachable ();
4566 else if (GET_CODE (dst) == MEM && GET_CODE (src) == REG)
4568 rtx memexp = XEXP (dst, 0);
4569 int srcreg = REGNO (src);
4570 int basereg = -1;
4571 struct csky_address op0;
4573 decompose_csky_address (XEXP (dst, 0), &op0);
4575 if (GET_CODE (memexp) == REG)
4576 basereg = REGNO (memexp);
4577 else if (GET_CODE (memexp) == PLUS)
4579 if (GET_CODE (XEXP (memexp, 0)) == REG)
4580 basereg = REGNO (XEXP (memexp, 0));
4581 else if (GET_CODE (XEXP (memexp, 1)) == REG)
4582 basereg = REGNO (XEXP (memexp, 1));
4583 else
4584 gcc_unreachable ();
4586 else
4587 gcc_unreachable ();
4589 /* When FPUV2. */
4590 if (CSKY_VREG_P (srcreg))
4592 if (op0.index)
4594 if (CSKY_ISA_FEATURE(fpv2_df))
4595 return "fstrd\t%1, %0";
4596 else if (CSKY_ISA_FEATURE(fpv3_df))
4597 return "fstr.64\t%1, %0";
4598 else
4599 gcc_unreachable ();
4601 else
4603 if (CSKY_ISA_FEATURE(fpv2_df))
4604 return "fstd\t%1, %0";
4605 else if (CSKY_ISA_FEATURE(fpv3_df))
4606 return "fst.64\t%1, %0";
4607 else
4608 gcc_unreachable ();
4611 /* FIXME length attribute is wrong here. */
4612 if (srcreg == basereg)
4613 /* Just load them in reverse order. */
4614 return "st.w\t%R1, %R0\n\tst.w\t%1, %0";
4615 else
4616 return "st.w\t%1, %0\n\tst.w\t%R1, %R0";
4618 else
4619 gcc_unreachable ();
4623 const char *
4624 csky_output_ck801_movedouble (rtx operands[],
4625 machine_mode mode ATTRIBUTE_UNUSED)
4627 rtx dst = operands[0];
4628 rtx src = operands[1];
4630 if (REG_P (dst))
4632 if (REG_P (src))
4634 int dstreg = REGNO (dst);
4635 int srcreg = REGNO (src);
4637 /* Ensure the second source not overwritten. */
4638 if (srcreg + 1 == dstreg)
4639 return "mov\t%R0, %R1\n\tmov\t%0, %1";
4640 else
4641 return "mov\t%0, %1\n\tmov\t%R0, %R1";
4643 else if (GET_CODE (src) == MEM)
4645 rtx memexp = XEXP (src, 0);
4646 int dstreg = REGNO (dst);
4647 int basereg = -1;
4648 struct csky_address op0;
4650 decompose_csky_address (XEXP (src, 0), &op0);
4652 if (GET_CODE (memexp) == LABEL_REF
4653 || (GET_CODE (memexp) == CONST
4654 && GET_CODE (XEXP (memexp, 0)) == PLUS
4655 && GET_CODE (XEXP (XEXP (memexp, 0), 0)) == LABEL_REF))
4656 return "lrw\t%0, [%1]\n\tlrw\t%R0, [%R1]";
4657 else if (GET_CODE (memexp) == REG)
4658 basereg = REGNO (memexp);
4659 else if (GET_CODE (memexp) == PLUS)
4661 if (GET_CODE (XEXP (memexp, 0)) == REG)
4662 basereg = REGNO (XEXP (memexp, 0));
4663 else if (GET_CODE (XEXP (memexp, 1)) == REG)
4664 basereg = REGNO (XEXP (memexp, 1));
4665 else
4666 gcc_unreachable ();
4668 else
4669 gcc_unreachable ();
4671 /* FIXME length attribute is wrong here. */
4672 if (dstreg == basereg)
4673 /* Just load them in reverse order. */
4674 return "ld.w\t%R0, %R1\n\tld.w\t%0, %1";
4675 else
4676 return "ld.w\t%0, %1\n\tld.w\t%R0, %R1";
4678 else if (GET_CODE (src) == CONST_INT || GET_CODE (src) == CONST_DOUBLE)
4680 split_double (src, operands + 2, operands + 3);
4682 if (REGNO (dst) <= 7
4683 && CSKY_CONST_OK_FOR_N (INTVAL (operands[2]) + 1))
4684 output_asm_insn ("movi\t%0, %2", operands);
4685 else
4686 output_asm_insn ("lrw\t%0, %2", operands);
4689 if (REGNO (dst) <= 6
4690 && CSKY_CONST_OK_FOR_N (INTVAL (operands[3]) + 1))
4691 output_asm_insn ("movi\t%R0, %3", operands);
4692 else
4693 output_asm_insn ("lrw\t%R0, %3", operands);
4695 return "";
4699 else
4700 gcc_unreachable ();
4702 else if (GET_CODE (dst) == MEM && GET_CODE (src) == REG)
4704 rtx memexp = XEXP (dst, 0);
4705 int srcreg = REGNO (src);
4706 int basereg = -1;
4707 struct csky_address op0;
4709 decompose_csky_address (XEXP (dst, 0), &op0);
4711 if (GET_CODE (memexp) == REG)
4712 basereg = REGNO (memexp);
4713 else if (GET_CODE (memexp) == PLUS)
4715 if (GET_CODE (XEXP (memexp, 0)) == REG)
4716 basereg = REGNO (XEXP (memexp, 0));
4717 else if (GET_CODE (XEXP (memexp, 1)) == REG)
4718 basereg = REGNO (XEXP (memexp, 1));
4719 else
4720 gcc_unreachable ();
4722 else
4723 gcc_unreachable ();
4725 /* FIXME length attribute is wrong here. */
4726 if (srcreg == basereg)
4727 /* Just load them in reverse order. */
4728 return "st.w\t%R1, %R0\n\tst.w\t%1, %0";
4729 else
4730 return "st.w\t%1, %0\n\tst.w\t%R1, %R0";
4732 else
4733 gcc_unreachable ();
4736 /* Calculate the instruction's length for moving double-word data. */
4739 csky_get_movedouble_length(rtx operands[])
4741 rtx dst = operands[0];
4742 rtx src = operands[1];
4744 if (REG_P (dst))
4746 if (REG_P (src))
4748 int dstreg = REGNO (dst);
4749 int srcreg = REGNO (src);
4751 if (CSKY_VREG_P (srcreg) && CSKY_VREG_P (dstreg))
4752 return 4;
4753 else
4754 return 8;
4756 else if (GET_CODE (src) == MEM)
4758 rtx memexp = XEXP (src, 0);
4759 int dstreg = REGNO (dst);
4760 struct csky_address op0;
4761 decompose_csky_address (XEXP (src, 0), &op0);
4763 if (GET_CODE (memexp) == LABEL_REF)
4764 return 8;
4765 if (CSKY_VREG_P (dstreg))
4766 return 4;
4767 return 8;
4769 else if (GET_CODE (src) == CONST_INT || GET_CODE (src) == CONST_DOUBLE)
4771 split_double (src, operands + 2, operands + 3);
4772 if (CSKY_CONST_OK_FOR_N (INTVAL (operands[2]) + 1)
4773 && CSKY_CONST_OK_FOR_N (INTVAL (operands[3]) + 1)
4774 && REGNO (operands[0]) < 6)
4775 return 4;
4776 else
4777 return 8;
4780 else if (GET_CODE (dst) == MEM && GET_CODE (src) == REG)
4782 rtx memexp = XEXP (dst, 0);
4783 int srcreg = REGNO (src);
4784 int offset = -1;
4785 if (CSKY_VREG_P (srcreg))
4786 return 4;
4788 if (GET_CODE (memexp) == REG)
4789 offset = 0;
4790 else if (GET_CODE (memexp) == PLUS)
4792 if (GET_CODE (XEXP (memexp, 0)) == REG)
4793 offset = INTVAL (XEXP (memexp, 1));
4794 else if (GET_CODE (XEXP (memexp, 1)) == REG)
4795 offset = INTVAL (XEXP (memexp, 0));
4796 else
4797 gcc_unreachable ();
4799 else
4800 gcc_unreachable ();
4802 if (srcreg <= 6 && offset <= 1020)
4803 return 4;
4804 else if ((srcreg == 7 && offset <= 1024) || (srcreg <= 7 && offset == 1024))
4805 return 6;
4806 else
4807 return 8;
4809 else
4810 gcc_unreachable ();
4812 return 0;
4815 /* Output float point load/store instructions for fpuv3. */
4817 const char *
4818 fpuv3_output_move (rtx *operands)
4820 rtx reg, mem, addr, ops[2];
4821 bool isload = REG_P (operands[0]);
4823 const char *templ = "f%s%s.%s\t%%0, %%1";
4824 char buff[50];
4825 machine_mode mode;
4827 reg = operands[isload ? 0 : 1];
4828 mem = operands[isload ? 1 : 0];
4830 gcc_assert (REG_P (reg));
4831 gcc_assert (CSKY_VREG_P (REGNO (reg)));
4832 gcc_assert (MEM_P (mem));
4834 mode = GET_MODE (reg);
4835 const char *type = mode == DFmode ? "64" :
4836 mode == SFmode ? "32" :
4837 mode == HFmode ? "16" :
4838 NULL;
4839 gcc_assert(type != NULL);
4841 addr = XEXP (mem, 0);
4842 struct csky_address caddr;
4843 decompose_csky_address (addr, &caddr);
4845 ops[0] = reg;
4846 ops[1] = mem;
4847 sprintf (buff, templ,
4848 isload ? "ld" : "st",
4849 caddr.index ? "r" : "",
4850 type);
4851 output_asm_insn (buff, ops);
4853 return "";
4856 /* Check if a const_double can be used by a VFP fmovi instruction. */
4859 fpuv3_const_double_rtx (rtx x)
4861 REAL_VALUE_TYPE r, m;
4862 r = *CONST_DOUBLE_REAL_VALUE (x);
4864 /* Fpuv3 doesn't support the following values. */
4865 if (REAL_VALUE_ISINF (r) || REAL_VALUE_ISNAN (r) || REAL_VALUE_MINUS_ZERO (r)
4866 || r.cl == rvc_zero)
4867 return 0;
4869 /* Extract sign, exponent and mantissa. */
4870 int exponent;
4871 r = real_value_abs (&r);
4872 exponent = REAL_EXP (&r);
4874 bool fail;
4875 unsigned HOST_WIDE_INT mantissa, mant_hi;
4876 unsigned HOST_WIDE_INT mask;
4877 int point_pos = 2 * HOST_BITS_PER_WIDE_INT - 1;
4878 real_ldexp (&m, &r, point_pos - exponent);
4879 wide_int w = real_to_integer (&m, &fail, HOST_BITS_PER_WIDE_INT * 2);
4880 mantissa = w.elt (0);
4881 mant_hi = w.elt (1);
4883 exponent -= 1;
4885 if (!IN_RANGE (exponent, -4, 11))
4886 return 0;
4888 /* If there are bits set in the low part of the mantissa, these values are
4889 not supported. */
4890 if (mantissa != 0)
4891 return 0;
4893 /* Now, make the mantissa contain the most-significant bits, and the
4894 point_pos indicates the number of these bits. */
4895 point_pos -= HOST_BITS_PER_WIDE_INT;
4896 mantissa = mant_hi;
4898 /* We can only allow a mantissa of 9 significant digits, top of which is always 1. */
4899 mask = ((unsigned HOST_WIDE_INT)1 << (point_pos - 9)) - 1;
4900 if ((mantissa & mask) != 0)
4901 return 0;
4903 return 1;
4907 /* Split operands for an AND expression when OPERANDS[2] is a constant.
4908 Note operands[0] is marked earlyclobber in this case and can be
4909 overwritten. Return true if "DONE", false otherwise. */
4911 bool
4912 csky_split_and (rtx *operands)
4914 HOST_WIDE_INT mask = INTVAL (operands[2]);
4915 rtx not_value = GEN_INT (~mask);
4916 int i;
4918 /* All zeros or all ones can be handled by a move instruction. */
4919 if (mask == 0)
4921 emit_move_insn (operands[0], const0_rtx);
4922 return true;
4924 if (mask == -1)
4926 emit_move_insn (operands[0], operands[1]);
4927 return true;
4930 /* Check for constants that can be handled directly by the 32-bit andi
4931 instruction. */
4932 if (CSKY_ISA_FEATURE (E2) && csky_arith_O_operand (operands[2], SImode))
4933 return false;
4935 /* Try to transform to andni instruction. */
4936 if (CSKY_ISA_FEATURE (E2) && csky_arith_O_operand (not_value, SImode))
4938 emit_insn (gen_cskyv2_andnsi3 (operands[0], not_value, operands[1]));
4939 return true;
4942 /* If there are only one or two 0 bits in the constant, we can
4943 replace the operation with bclri instructions on those bits.
4944 Note CK801 has only the 16-bit bclri that operates on a single
4945 register, so we must count a move if we are post-reload. */
4946 if (popcount_hwi (~mask & 0xffffffff)
4947 <= (reload_completed && !CSKY_ISA_FEATURE (E2) ? 1 : 2))
4949 rtx input = operands[1];
4951 if (!CSKY_ISA_FEATURE (E2))
4953 emit_move_insn (operands[0], input);
4954 input = operands[0];
4957 for (i = 0; i < 32; i++)
4958 if ((mask & (1 << i)) == 0x0)
4960 emit_insn (gen_bclri (operands[0], input, GEN_INT (i)));
4961 input = operands[0];
4963 return true;
4966 /* If the constant mask is outside the [0, 4095] range for
4967 constraint O, or if constraint O is not allowed (ck801),
4968 maybe the constant is a contiguous bit range that we can
4969 handle by bit extract (low bits) or shifts (high bits). */
4970 for (i = (CSKY_ISA_FEATURE (E2) ? 13 : 1); i < 32; i++)
4972 if ((((HOST_WIDE_INT) 1) << i) - 1 == mask)
4974 if (CSKY_ISA_FEATURE (2E3))
4975 emit_insn (gen_cskyv2_extzv (operands[0], operands[1],
4976 GEN_INT (i), const0_rtx));
4977 else
4979 rtx shift = GEN_INT (32 - i);
4980 rtx reg = (reload_completed
4981 ? operands[0] : gen_reg_rtx (SImode));
4983 emit_insn (gen_ashlsi3 (reg, operands[1], shift));
4984 emit_insn (gen_lshrsi3 (operands[0], reg, shift));
4986 return true;
4988 else if ((((HOST_WIDE_INT) 1) << i) - 1 == ~mask)
4990 rtx shift = GEN_INT (i);
4991 rtx reg = (reload_completed
4992 ? operands[0] : gen_reg_rtx (SImode));
4994 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
4995 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
4996 return true;
5000 /* If the constant is a negative number, it seems better to use
5001 andn and copy the NOT_VALUE to a register instead of the
5002 original value, since the NOT_VALUE is always smaller and thus
5003 more likely to be representable as a small constant.
5004 This transformation can only be done before reload because
5005 it requires a temporary. Hopefully register allocation can get
5006 rid of the extra move required for CK801. */
5007 if (!reload_completed && INTVAL (operands[2]) < 0)
5009 rtx reg = copy_to_mode_reg (SImode, not_value);
5011 if (CSKY_ISA_FEATURE (E2))
5012 emit_insn (gen_cskyv2_andnsi3 (operands[0], reg, operands[1]));
5013 else
5015 emit_move_insn (operands[0], operands[1]);
5016 emit_insn (gen_ck801_andnsi3 (operands[0], reg, operands[0]));
5018 return true;
5021 /* If the above ways are all not working, move the constant
5022 to a register. We can clobber operands[0] as it is
5023 marked earlyclobber in the insn constraints, but then we have to
5024 swap operands 1 and 2 to match the constraints on the 2-operand
5025 16-bit and instruction. */
5026 if (reload_completed)
5028 emit_move_insn (operands[0], operands[2]);
5029 operands[2] = operands[1];
5030 operands[1] = operands[0];
5032 else
5033 operands[2] = copy_to_mode_reg (SImode, operands[2]);
5034 return false;
5037 /* Split operands for an IOR expression when OPERANDS[2] is a constant.
5038 Note operands[0] is marked earlyclobber in this case and can be
5039 overwritten. Return true if "DONE", false otherwise. */
5041 bool
5042 csky_split_ior (rtx *operands)
5044 HOST_WIDE_INT mask = INTVAL (operands[2]);
5045 int i;
5047 /* All zeros or all ones can be handled by a move instruction. */
5048 if (mask == 0)
5050 emit_move_insn (operands[0], operands[1]);
5051 return true;
5053 if (mask == -1)
5055 emit_move_insn (operands[0], gen_int_mode (-1, SImode));
5056 return true;
5059 /* Check for constants that can be handled directly by the 32-bit ori
5060 instruction. */
5061 if (CSKY_ISA_FEATURE (E2) && csky_literal_I_operand (operands[2], SImode))
5062 return false;
5064 /* If there are only one or two 1 bits in the value, we can replace
5065 the operation with bseti instructions to set those bits.
5066 Note CK801 has only the 16-bit bclri that operates on a single
5067 register, so we must count a move if we are post-reload. */
5068 if (popcount_hwi (mask & 0xffffffff)
5069 <= (reload_completed && !CSKY_ISA_FEATURE (E2) ? 1 : 2))
5071 rtx input = operands[1];
5073 if (!CSKY_ISA_FEATURE (E2))
5075 emit_move_insn (operands[0], input);
5076 input = operands[0];
5079 for (i = 0; i < 32; i++)
5080 if (mask & (1 << i))
5082 emit_insn (gen_bseti (operands[0], input, GEN_INT (i)));
5083 input = operands[0];
5085 return true;
5088 /* If the above ways are all not working, move the constant
5089 to a register. We can clobber operands[0] as it is
5090 marked earlyclobber in the insn constraints, but then we have to
5091 swap operands 1 and 2 to match the constraints on the 2-operand
5092 16-bit ior instruction. */
5093 if (reload_completed)
5095 emit_move_insn (operands[0], operands[2]);
5096 operands[2] = operands[1];
5097 operands[1] = operands[0];
5099 else
5100 operands[2] = copy_to_mode_reg (SImode, operands[2]);
5101 return false;
5105 /* Split operands for an XOR expression when OPERANDS[2] is a constant.
5106 Note operands[0] is marked earlyclobber in this case and can be
5107 overwritten. Return true if "DONE", false otherwise. */
5109 bool
5110 csky_split_xor (rtx *operands)
5112 HOST_WIDE_INT mask = INTVAL (operands[2]);
5114 /* All zeros can be turned into move instruction. */
5115 if (mask == 0)
5117 emit_move_insn (operands[0], operands[1]);
5118 return true;
5121 /* All ones can be turned into a bitwise not. */
5122 if (mask == -1)
5124 if (CSKY_ISA_FEATURE (E2))
5125 emit_insn (gen_cskyv2_one_cmplsi2 (operands[0], operands[1]));
5126 else
5128 emit_move_insn (operands[0], operands[1]);
5129 emit_insn (gen_ck801_one_cmplsi2 (operands[0], operands[0]));
5131 return true;
5134 /* Check for constants that can be handled directly by the 32-bit xori
5135 instruction. */
5136 if (CSKY_ISA_FEATURE (E2) && csky_arith_O_operand (operands[2], SImode))
5137 return false;
5139 /* If the above ways are all not working, move the constant
5140 to a register. We can clobber operands[0] as it is
5141 marked earlyclobber in the insn constraints, but then we have to
5142 swap operands 1 and 2 to match the constraints on the 2-operand
5143 16-bit ior instruction. */
5144 if (reload_completed)
5146 emit_move_insn (operands[0], operands[2]);
5147 operands[2] = operands[1];
5148 operands[1] = operands[0];
5150 else
5151 operands[2] = copy_to_mode_reg (SImode, operands[2]);
5152 return false;
5156 /* Return true if X is an address form involving a symbol or label ref. */
5158 bool
5159 csky_symbolic_address_p (rtx x)
5161 switch (GET_CODE (x))
5163 case SYMBOL_REF:
5164 case LABEL_REF:
5165 return 1;
5166 case CONST:
5167 x = XEXP (x, 0);
5168 return ((GET_CODE (XEXP (x, 0)) == SYMBOL_REF
5169 || GET_CODE (XEXP (x, 0)) == LABEL_REF)
5170 && GET_CODE (XEXP (x, 1)) == CONST_INT);
5171 default:
5172 return 0;
5177 /* Emit a comparison instruction.
5178 Return true if an inverted comparison is generated. */
5180 bool
5181 csky_emit_compare (enum rtx_code code, rtx op0, rtx op1)
5183 bool invert;
5184 rtx cc_reg = gen_rtx_REG (CCmode, CSKY_CC_REGNUM);
5186 if (GET_MODE_CLASS(GET_MODE (op0)) == MODE_FLOAT)
5187 return csky_emit_compare_float(code, op0, op1);
5189 if (GET_CODE (op1) == CONST_INT)
5191 HOST_WIDE_INT val = INTVAL (op1);
5193 switch (code)
5195 case GTU:
5196 /* Unsigned (GTU 0) is the same as (NE 0); everything else is
5197 converted below to LEU (reversed cmphs). */
5198 if (val == 0)
5199 code = NE;
5200 /* Check whether (GTU A imm) can become (GEU A imm + 1). */
5201 else if (TARGET_MINI_REGISTERS
5202 ? CSKY_CONST_OK_FOR_J (val + 1)
5203 : CSKY_CONST_OK_FOR_Uk (val + 1))
5205 op1 = GEN_INT (val + 1);
5206 code = GEU;
5208 break;
5209 /* Check whether (LE A imm) can become (LT A imm + 1),
5210 or (GT A imm) can become (GE A imm + 1). */
5211 case GT:
5212 case LE:
5213 if (TARGET_MINI_REGISTERS
5214 ? CSKY_CONST_OK_FOR_J (val + 1)
5215 : CSKY_CONST_OK_FOR_Uk (val + 1))
5217 op1 = GEN_INT (val + 1);
5218 code = code == LE ? LT : GE;
5220 break;
5222 default:
5223 break;
5227 if (CONSTANT_P (op1) && GET_CODE (op1) != CONST_INT)
5228 op1 = force_reg (GET_MODE (op1), op1);
5230 /* cmpnei: 0-31 (K immediate)
5231 ti: 1-32 (J immediate, 0 using btsti x,31). */
5232 invert = false;
5233 switch (code)
5235 /* Use inverted condition, cmpne. */
5236 case EQ:
5237 code = NE;
5238 invert = true;
5239 /* Fall through. */
5240 /* Use normal condition, cmpne. */
5241 case NE:
5242 if (GET_CODE (op1) == CONST_INT
5243 && (TARGET_MINI_REGISTERS
5244 ? !csky_literal_K_operand (op1, SImode)
5245 : !csky_literal_I_operand (op1, SImode)))
5246 op1 = force_reg (SImode, op1);
5247 break;
5249 /* Use inverted condition, reversed cmplt. */
5250 case LE:
5251 code = GT;
5252 invert = true;
5253 /* Fall through. */
5254 /* Use normal condition, reversed cmplt. */
5255 case GT:
5256 if (GET_CODE (op1) == CONST_INT)
5257 op1 = force_reg (SImode, op1);
5258 break;
5260 /* Use inverted condition, cmplt. */
5261 case GE:
5262 code = LT;
5263 invert = true;
5264 /* Fall through. */
5265 /* Use normal condition, cmplt. */
5266 case LT:
5267 /* covered by btsti x,31. */
5268 if (GET_CODE (op1) == CONST_INT && INTVAL (op1) != 0
5269 && (TARGET_MINI_REGISTERS
5270 ? !csky_literal_J_operand (op1, SImode)
5271 : !csky_literal_Uk_operand (op1, SImode)))
5272 op1 = force_reg (SImode, op1);
5273 break;
5275 /* Use inverted condition, cmple. */
5276 case GTU:
5277 /* We coped with unsigned > 0 above. */
5278 gcc_assert (GET_CODE (op1) != CONST_INT || INTVAL (op1) != 0);
5279 code = LEU;
5280 invert = true;
5281 /* Fall through. */
5282 /* Use normal condition, reversed cmphs. */
5283 case LEU:
5284 if (GET_CODE (op1) == CONST_INT && INTVAL (op1) != 0)
5285 op1 = force_reg (SImode, op1);
5286 break;
5288 /* Use inverted condition, cmphs. */
5289 case LTU:
5290 code = GEU;
5291 invert = true;
5292 /* Fall through. */
5293 /* Use normal condition, cmphs. */
5294 case GEU:
5295 if (GET_CODE (op1) == CONST_INT && INTVAL (op1) != 0
5296 && (TARGET_MINI_REGISTERS
5297 ? !csky_literal_J_operand (op1, SImode)
5298 : !csky_literal_Uk_operand (op1, SImode)))
5299 op1 = force_reg (SImode, op1);
5300 break;
5302 default:
5303 break;
5306 emit_insn (gen_rtx_SET (cc_reg,
5307 gen_rtx_fmt_ee (code, CCmode, op0, op1)));
5308 return invert;
5311 /* Return true if push/pop can be used to save/restore all the registers
5312 indicated by MASK. We currently don't attempt to handle situations where
5313 some of the registers could be handled by push/pop and others saved and
5314 restored individually. */
5316 static bool
5317 csky_can_use_pushpop (unsigned int mask)
5319 int i;
5320 int end_reg;
5322 if (!TARGET_PUSHPOP)
5323 return false;
5325 if (mask == 0)
5326 return false;
5328 /* Regs 0-3, 12-14, 18-27, 29-31 cannot be in the mask. */
5329 if (mask & 0xeffc700f)
5330 return false;
5332 /* Regs in the range r4-r11 must be contiguous. */
5333 for (end_reg = 0, i = 11; i >= 4; i--)
5335 if (!end_reg && (mask & (1 << i)))
5336 end_reg = i;
5337 if (end_reg && !(mask & (1 << i)))
5338 return false;
5341 /* Likewise for regs in the range r16-r17. */
5342 for (end_reg = 0, i = 17; i >= 16; i--)
5344 if (!end_reg && (mask & (1 << i)))
5345 end_reg = i;
5346 if (end_reg && !(mask & (1 << i)))
5347 return false;
5350 return true;
5354 /* Return true if store/load multiple instructions can be used to
5355 save/restore at least some of the registers indicated by MASK.
5356 Unlike the push/pop case, this does handle partial ranges.
5357 Set *BR and *ER to the beginning and end (respectively) of the
5358 register range that can be handled. */
5360 static bool
5361 csky_can_use_ldstm (int mask, int *br, int *er)
5363 int regno;
5364 int begin_reg = 0, end_reg = 0;
5365 int count = 0;
5367 if (!TARGET_MULTIPLE_STLD)
5368 return false;
5370 /* We'll only handle registers in the range 4-11, the contiguous range
5371 of caller-saved registers. Higher-numbered registers are handled
5372 individually in addition to this, but we'll give up on doing ldstm
5373 entirely if we need to save/restore the low-numbered EH registers. */
5374 if (mask & 0xf)
5375 return false;
5377 for (regno = 4; regno <= 11; regno++)
5379 if (mask & 1 << regno)
5381 if (!begin_reg)
5382 begin_reg = regno;
5383 end_reg = regno;
5384 count++;
5386 else if (begin_reg)
5387 break;
5390 if (count >= CSKY_MIN_MULTIPLE_STLD && count <= CSKY_MAX_MULTIPLE_STLD)
5392 if (br)
5393 *br = begin_reg;
5394 if (er)
5395 *er = end_reg;
5396 return true;
5398 return false;
5402 const char *
5403 csky_output_return_instruction (void)
5405 unsigned long func_type = get_csky_current_func_type ();
5407 if (CSKY_FUNCTION_IS_NAKED (func_type))
5408 return "";
5409 if (CSKY_FUNCTION_IS_INTERRUPT (func_type))
5410 return "ipop\n\tnir\n";
5411 else
5412 return "rts\n";
5416 /* Adjust the stack pointer by OFFSET bytes. OFFSET is negative if this
5417 is in the prologue, positive if in the epilogue. This may require
5418 multiple instructions and/or use of CSKY_STACKADJUST_REGNUM as
5419 a scratch register. Emit CFA notes as appropriate. */
5420 static void
5421 expand_csky_stack_adjust (int offset)
5423 rtx set;
5424 rtx_insn *insn;
5425 int size = (offset > 0 ? offset : -offset);
5427 if (offset == 0)
5428 return;
5430 /* If OFFSET is too large for addi/subi, load it into
5431 CSKY_STACKADJUST_REGNUM and use a register add/sub instead.
5432 This case is not mentioned in the ABI documentation, but it is
5433 supported by GDB prologue analysis provided that the instruction(s)
5434 to initialize CSKY_STACKADJUST_REGNUM appear directly before
5435 the sub. Depending on the value of OFFSET, this might be a
5436 lrw instruction or the "tricks" used by csky_output_inline_const to
5437 encode special-case integer constants. */
5438 if (size > CSKY_MAX_SP_ADJUST * 2)
5440 rtx tmp, dwarf;
5442 /* We should have reserved the scratch register already in
5443 csky_layout_stack_frame. */
5444 gcc_assert (cfun->machine->reg_size != 0
5445 && (cfun->machine->reg_mask
5446 & (1 << CSKY_STACKADJUST_REGNUM)));
5448 /* Prevent the optimizer from reordering these instructions to
5449 keep GDB happy. */
5450 if (!flag_sched_prolog)
5451 emit_insn (gen_blockage ());
5453 tmp = gen_rtx_REG (SImode, CSKY_STACKADJUST_REGNUM);
5454 emit_move_insn (tmp, GEN_INT (size));
5456 if (offset > 0)
5457 set = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp);
5458 else
5459 set = gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp);
5460 insn = emit_insn (set);
5461 RTX_FRAME_RELATED_P (insn) = 1;
5462 dwarf = gen_rtx_SET (stack_pointer_rtx,
5463 plus_constant (Pmode, stack_pointer_rtx, offset));
5464 add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
5466 /* More make GDB happy. */
5467 if (!flag_sched_prolog)
5468 emit_insn (gen_blockage ());
5471 /* Use one or two addi or subi insns to adjust stack. */
5472 else
5473 while (size)
5475 int delta = (size > CSKY_MAX_SP_ADJUST
5476 ? CSKY_MAX_SP_ADJUST : size);
5478 if (offset > 0)
5479 set = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
5480 GEN_INT (delta));
5481 else
5482 set = gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
5483 GEN_INT (delta));
5484 insn = emit_insn (set);
5485 RTX_FRAME_RELATED_P (insn) = 1;
5486 size -= delta;
5491 /* Generate and emit an insn that we will recognize as a push_multi.
5492 Unfortunately, since this insn does not reflect very well the actual
5493 semantics of the operation, we need to annotate the insn for the benefit
5494 of DWARF2 frame unwind information. DWARF_REGS_MASK is a subset of
5495 MASK for registers that should be annotated for DWARF2 frame unwind
5496 information. */
5498 static rtx
5499 emit_csky_regs_push (unsigned long mask)
5501 int num_regs = 0;
5502 int i, j;
5503 rtx par;
5504 rtx dwarf;
5505 rtx tmp;
5506 int dwarf_par_index;
5508 for (i = 0; i < CSKY_NGPR_REGS; i++)
5510 if (mask & (1 << i))
5511 num_regs++;
5514 /* The reg range for push is:r4-r11,r15-r17,r28. */
5515 gcc_assert (num_regs && num_regs <= 12);
5517 /* For the body of the insn we are going to generate an UNSPEC in
5518 parallel with several USEs. This allows the insn to be recognized
5519 by the push_multi pattern in the csky.md file.
5521 The body of the insn looks something like this:
5523 (parallel [
5524 (set (mem:BLK (pre_modify:SI (reg:SI sp)
5525 (const_int:SI <num>)))
5526 (unspec:BLK [(reg:SI r4)] UNSPEC_PUSHPOP_MULT))
5527 (use (reg:SI XX))
5528 (use (reg:SI YY))
5532 For the frame note however, we try to be more explicit and actually
5533 show each register being stored into the stack frame, plus a (single)
5534 decrement of the stack pointer. We do it this way in order to be
5535 friendly to the stack unwinding code, which only wants to see a single
5536 stack decrement per instruction. The RTL we generate for the note looks
5537 something like this:
5539 (sequence [
5540 (set (reg:SI sp) (plus:SI (reg:SI sp) (const_int -20)))
5541 (set (mem:SI (reg:SI sp)) (reg:SI r4))
5542 (set (mem:SI (plus:SI (reg:SI sp) (const_int 4))) (reg:SI XX))
5543 (set (mem:SI (plus:SI (reg:SI sp) (const_int 8))) (reg:SI YY))
5547 FIXME:: In an ideal world the PRE_MODIFY would not exist and
5548 instead we'd have a parallel expression detailing all
5549 the stores to the various memory addresses so that debug
5550 information is more up-to-date. Remember however while writing
5551 this to take care of the constraints with the push instruction.
5553 Note also that this has to be taken care of for the VFP registers.
5555 For more see PR43399. */
5557 par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num_regs));
5558 dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (num_regs + 1));
5559 dwarf_par_index = 1;
5561 for (i = 0; i < CSKY_NGPR_REGS; i++)
5562 if (mask & (1 << i))
5564 rtx reg = gen_rtx_REG (SImode, i);
5565 rtx addr = plus_constant (Pmode, stack_pointer_rtx, -4 * num_regs);
5566 tmp = gen_frame_mem (BLKmode,
5567 gen_rtx_PRE_MODIFY (Pmode,
5568 stack_pointer_rtx, addr));
5569 XVECEXP (par, 0, 0)
5570 = gen_rtx_SET (tmp,
5571 gen_rtx_UNSPEC (BLKmode,
5572 gen_rtvec (1, reg),
5573 UNSPEC_PUSHPOP_MULT));
5574 tmp = gen_rtx_SET (gen_frame_mem (SImode, stack_pointer_rtx),
5575 reg);
5576 RTX_FRAME_RELATED_P (tmp) = 1;
5577 XVECEXP (dwarf, 0, dwarf_par_index++) = tmp;
5579 break;
5582 for (j = 1, i++; j < num_regs; i++)
5583 if (mask & (1 << i))
5585 rtx reg = gen_rtx_REG (SImode, i);
5586 rtx addr = plus_constant (Pmode, stack_pointer_rtx, 4 * j);
5587 tmp = gen_rtx_SET (gen_frame_mem (SImode, addr), reg);
5588 RTX_FRAME_RELATED_P (tmp) = 1;
5589 XVECEXP (par, 0, j) = gen_rtx_USE (VOIDmode, reg);
5590 XVECEXP (dwarf, 0, dwarf_par_index++) = tmp;
5591 j++;
5594 par = emit_insn (par);
5596 tmp = gen_rtx_SET (stack_pointer_rtx,
5597 plus_constant (Pmode, stack_pointer_rtx, -4 * num_regs));
5598 RTX_FRAME_RELATED_P (tmp) = 1;
5599 XVECEXP (dwarf, 0, 0) = tmp;
5601 add_reg_note (par, REG_FRAME_RELATED_EXPR, dwarf);
5602 RTX_FRAME_RELATED_P (par) = 1;
5604 return par;
5608 /* Generate and emit an insn pattern that we will recognize as a pop_multi.
5609 SAVED_REGS_MASK shows which registers need to be restored.
5611 Unfortunately, since this insn does not reflect very well the actual
5612 semantics of the operation, we need to annotate the insn for the benefit
5613 of DWARF2 frame unwind information. */
5615 static void
5616 emit_csky_regs_pop (unsigned long mask)
5618 int num_regs = 0;
5619 int i, j;
5620 rtx par;
5622 for (i = 0; i < CSKY_NGPR_REGS; i++)
5623 if (mask & (1 << i))
5624 num_regs++;
5626 /* The reg range for push is:r4-r11,r15-r17,r28. */
5627 gcc_assert (num_regs && num_regs <= 12);
5629 /* The first element is (return),
5630 the second element is
5631 (set (reg:SI 'first reg number')
5632 (unspec:SI [(mem)] UNSPEC_PUSHPOP_MULT),
5633 the rest elements is (use (reg:SI 'rest reg number')),
5634 so the length should be number of register to be poped
5635 plus one. */
5636 par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num_regs + 1));
5638 XVECEXP (par, 0, 0) = ret_rtx;
5640 for (i = 0; i < CSKY_NGPR_REGS; i++)
5641 if (mask & (1 << i))
5643 rtx reg = gen_rtx_REG (SImode, i);
5644 rtx addr = plus_constant (Pmode, stack_pointer_rtx, 4 * num_regs);
5645 rtx tmp = gen_frame_mem (SImode,
5646 gen_rtx_POST_MODIFY (Pmode,
5647 stack_pointer_rtx, addr));
5648 XVECEXP (par, 0, 1)
5649 = gen_rtx_SET (reg,
5650 gen_rtx_UNSPEC (SImode,
5651 gen_rtvec (1, tmp),
5652 UNSPEC_PUSHPOP_MULT));
5653 break;
5656 for (j = 2, i++; j < (num_regs + 1); i++)
5657 if (mask & (1 << i))
5659 rtx reg = gen_rtx_REG (SImode, i);
5660 XVECEXP (par, 0, j) = gen_rtx_USE (VOIDmode, reg);
5661 j++;
5664 par = emit_jump_insn (par);
5668 /* Generate the function prologue. */
5670 void
5671 csky_expand_prologue (void)
5673 rtx_insn *insn;
5674 unsigned long func_type = get_csky_current_func_type ();
5675 unsigned int reg_mask;
5676 int reg_size;
5678 if (CSKY_FUNCTION_IS_NAKED (func_type))
5680 if (flag_stack_usage_info)
5681 current_function_static_stack_size = 0;
5682 return;
5685 csky_layout_stack_frame ();
5686 reg_mask = cfun->machine->reg_mask;
5687 reg_size = cfun->machine->reg_size;
5689 /* Adjust stack pointer past argument overflow area. */
5690 if (cfun->machine->arg_size != 0)
5692 int offset = cfun->machine->arg_size;
5693 expand_csky_stack_adjust (- offset);
5695 /* If we have a parameter passed partially in regs and partially
5696 in memory, the registers will have been stored to memory already
5697 in function.cc. So we only need to copy varargs from registers
5698 to stack. */
5699 if (cfun->machine->uses_anonymous_args)
5701 int rn = CSKY_FIRST_PARM_REGNUM + CSKY_NPARM_REGS - 1;
5702 for (offset -= 4; offset >= 0; offset -= 4, rn--)
5704 rtx dst = gen_frame_mem (SImode,
5705 plus_constant (Pmode,
5706 stack_pointer_rtx,
5707 offset));
5708 insn = emit_move_insn (dst, gen_rtx_REG (SImode, rn));
5709 RTX_FRAME_RELATED_P (insn) = 1;
5714 /* Push caller-saved registers to stack. */
5715 if (csky_can_use_pushpop (reg_mask))
5716 emit_csky_regs_push (reg_mask);
5717 else if (reg_size)
5719 int sreg = -1, ereg = -1;
5720 bool stm_p = csky_can_use_ldstm (reg_mask, &sreg, &ereg);
5721 int stm_regs = stm_p ? ereg - sreg + 1 : 0;
5722 int stm_size = stm_regs * 4;
5724 /* First adjust the SP to the low end of the register save area. */
5725 expand_csky_stack_adjust (- reg_size);
5727 /* Emit individual register saves. Even if we are going to emit an
5728 stm, we may need to save individual registers above that too. */
5729 if (reg_size > stm_size)
5731 int offset = reg_size - 4;
5732 int regno = 31;
5733 for ( ; regno > ereg; regno--)
5734 if (reg_mask & (1 << regno))
5736 rtx dst = gen_rtx_MEM (SImode,
5737 plus_constant (Pmode,
5738 stack_pointer_rtx,
5739 offset));
5740 rtx insn = emit_insn (gen_movsi (dst,
5741 gen_rtx_REG (SImode, regno)));
5742 RTX_FRAME_RELATED_P (insn) = 1;
5743 if (offset == stm_size)
5744 break;
5745 offset -= 4;
5749 /* If possible, emit a stm to do a bulk store of sequential
5750 registers to the stack. Note that it is an error in the ABI
5751 documentation that it doesn't list stm as a valid prologue
5752 instruction. */
5753 if (stm_p)
5755 rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (stm_regs));
5756 int regno, slot;
5757 for (regno = sreg, slot = 0; regno <= ereg; regno++, slot++)
5759 rtx reg = gen_rtx_REG (SImode, regno);
5760 rtx addr = plus_constant (Pmode, stack_pointer_rtx, slot * 4);
5761 rtx set = gen_rtx_SET (gen_frame_mem (SImode, addr), reg);
5762 RTX_FRAME_RELATED_P (set) = 1;
5763 XVECEXP (par, 0, slot) = set;
5765 insn = emit_insn (par);
5766 RTX_FRAME_RELATED_P (insn) = 1;
5770 /* Initialize hard frame pointer, if necessary. It points at the base
5771 of the register save area. */
5772 if (frame_pointer_needed)
5774 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx, stack_pointer_rtx));
5775 RTX_FRAME_RELATED_P (insn) = 1;
5778 /* Reserve stack space for locals and outgoing args. */
5779 expand_csky_stack_adjust (- cfun->machine->reg_offset);
5781 /* Put the GOT address in reg_gb for PIC, using R13 as a scratch.
5782 See section 4.7.1 in the ABI documentation,
5783 "Function Prologue for PIC". */
5784 if (flag_pic && (reg_mask & (1 << PIC_OFFSET_TABLE_REGNUM)))
5786 rtx l1 = gen_label_rtx ();
5787 rtx grs_label = gen_rtx_LABEL_REF (SImode, l1);
5788 rtx reg_gb = gen_rtx_REG (SImode, PIC_OFFSET_TABLE_REGNUM);
5789 rtx reg_temp = gen_rtx_REG (SImode, 13);
5791 rtx tmp0_unspec = gen_rtx_UNSPEC (Pmode,
5792 gen_rtvec (1, grs_label),
5793 UNSPEC_PIC_SYMBOL_GOTPC_GRS);
5794 rtx tmp1_unspec = gen_rtx_UNSPEC (Pmode,
5795 gen_rtvec (1, grs_label),
5796 UNSPEC_PIC_SYMBOL_GOTPC);
5798 emit_insn (gen_prologue_get_pc (tmp0_unspec));
5799 emit_move_insn (reg_temp, tmp1_unspec);
5800 emit_insn (gen_addsi3 (reg_gb, reg_gb, reg_temp));
5803 if (flag_stack_usage_info)
5804 current_function_static_stack_size = cfun->machine->frame_size;
5806 if (!flag_sched_prolog)
5807 emit_insn (gen_blockage ());
5810 void
5811 csky_expand_epilogue (void)
5813 unsigned long func_type = get_csky_current_func_type ();
5814 unsigned int reg_mask;
5815 int reg_size;
5816 int adjust;
5817 rtx_insn *insn;
5819 if (!flag_sched_prolog)
5820 emit_insn (gen_blockage ());
5822 if (CSKY_FUNCTION_IS_NAKED (func_type))
5824 emit_jump_insn (gen_simple_return ());
5825 return;
5828 /* Get the frame information. */
5829 csky_layout_stack_frame ();
5830 reg_mask = cfun->machine->reg_mask;
5831 reg_size = cfun->machine->reg_size;
5832 adjust = reg_size + cfun->machine->arg_size;
5834 /* Restore the SP to the base of the register save area. */
5835 if (frame_pointer_needed)
5837 insn = emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
5838 RTX_FRAME_RELATED_P (insn) = 1;
5840 else
5841 expand_csky_stack_adjust (cfun->machine->reg_offset);
5843 /* Restore the callee-saved registers. */
5844 if (csky_can_use_pushpop (reg_mask)
5845 && cfun->machine->arg_size == 0
5846 && !CSKY_FUNCTION_IS_INTERRUPT (func_type)
5847 && !crtl->calls_eh_return)
5849 /* Pop includes an implicit return, so we are done. */
5850 emit_csky_regs_pop (reg_mask);
5851 return;
5853 else if (reg_size)
5855 int sreg = -1, ereg = -1;
5856 bool ldm_p = csky_can_use_ldstm (reg_mask, &sreg, &ereg);
5857 int ldm_regs = ldm_p ? ereg - sreg + 1 : 0;
5858 int ldm_size = ldm_regs * 4;
5860 /* Emit individual register loads. Even if we are going to emit an
5861 ldm, we may need to load individual registers above that too. */
5862 if (reg_size > ldm_size)
5864 int offset = reg_size - 4;
5865 int regno = 31;
5866 for ( ; regno > ereg; regno--)
5867 if (reg_mask & (1 << regno))
5869 rtx src = gen_frame_mem (SImode,
5870 plus_constant (Pmode,
5871 stack_pointer_rtx,
5872 offset));
5873 rtx reg = gen_rtx_REG (SImode, regno);
5874 insn = emit_move_insn (reg, src);
5875 RTX_FRAME_RELATED_P (insn) = 1;
5876 add_reg_note (insn, REG_CFA_RESTORE, reg);
5877 if (offset == ldm_size)
5878 break;
5879 offset -= 4;
5883 /* If possible, emit a ldm to do a bulk load of sequential
5884 registers from the stack. */
5885 if (ldm_p)
5887 rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (ldm_regs));
5888 int regno, slot;
5889 for (regno = sreg, slot = 0; regno <= ereg; regno++, slot++)
5891 rtx reg = gen_rtx_REG (SImode, regno);
5892 rtx addr = plus_constant (Pmode, stack_pointer_rtx, slot * 4);
5893 rtx set = gen_rtx_SET (reg, gen_frame_mem (SImode, addr));
5894 XVECEXP (par, 0, slot) = set;
5896 insn = emit_insn (par);
5897 RTX_FRAME_RELATED_P (insn) = 1;
5898 for (regno = sreg; regno <= ereg; regno++)
5900 rtx reg = gen_rtx_REG (SImode, regno);
5901 add_reg_note (insn, REG_CFA_RESTORE, reg);
5906 /* Emit the final stack pointer adjustment to deallocate the saved
5907 registers and incoming argument area. */
5908 expand_csky_stack_adjust (adjust);
5910 /* Extra stack adjustment for exception handler return. */
5911 if (crtl->calls_eh_return)
5912 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
5913 EH_RETURN_STACKADJ_RTX));
5915 /* Now we can return. */
5916 emit_jump_insn (gen_simple_return ());
5920 static void
5921 csky_output_function_prologue (FILE *f)
5923 unsigned long func_type = get_csky_current_func_type ();
5925 switch ((int) CSKY_FUNCTION_TYPE (func_type))
5927 default:
5928 case CSKY_FT_NORMAL:
5929 break;
5930 case CSKY_FT_INTERRUPT:
5932 asm_fprintf (f, "\t# Interrupt Service Routine.\n");
5933 asm_fprintf (f, "\tnie\n\tipush\n");
5934 break;
5936 case CSKY_FT_FIQ:
5937 asm_fprintf (f, "\t# Fast Interrupt Service Routine.\n");
5938 break;
5939 case CSKY_FT_EXCEPTION:
5940 asm_fprintf (f, "\t# CSKY Exception Handler.\n");
5941 break;
5942 case CSKY_FT_NAKED:
5943 asm_fprintf (f, "\t# Naked Function: prologue and epilogue \
5944 provided by programmer.\n");
5945 return;
5948 csky_layout_stack_frame ();
5950 /* Generate .stack_size function-name, size for callgraph;
5951 the default stack size is 0. */
5952 if (TARGET_STACK_SIZE && cfun->machine->frame_size > 0)
5954 gcc_assert (current_function_decl != NULL);
5955 const char *func_name =
5956 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
5957 if (func_name[0] == '*')
5958 asm_fprintf (f, "\t.stack_size %s, %d\n",
5959 &func_name[1], cfun->machine->frame_size);
5960 else
5961 asm_fprintf (f, "\t.stack_size %s, %d\n",
5962 func_name, cfun->machine->frame_size);
5967 static void
5968 csky_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED)
5974 /* Helper for csky_eh_return splitter: store the call frame exception
5975 handler address in lr. */
5976 void
5977 csky_set_eh_return_address (rtx source, rtx scratch)
5979 HOST_WIDE_INT delta = 0;
5980 rtx basereg, addr;
5981 unsigned int reg_mask;
5983 csky_layout_stack_frame ();
5984 reg_mask = cfun->machine->reg_mask;
5986 if (reg_mask & (1 << CSKY_LR_REGNUM))
5988 /* Find LR in the stack frame. */
5989 int i = 0;
5991 if (frame_pointer_needed)
5993 basereg = hard_frame_pointer_rtx;
5994 delta = 0;
5996 else
5998 basereg = stack_pointer_rtx;
5999 delta = cfun->machine->reg_offset;
6002 /* At this point, (basereg + delta) points at the low end of
6003 the reg save area. Regs are saved sequentially from low
6004 to high from this address. */
6005 for (i = 0; i < CSKY_LR_REGNUM; i++)
6006 if (reg_mask & (1 << i))
6007 delta += 4;
6009 if ((CSKY_TARGET_ARCH (CK801) && delta >= CSKY_LD16_MAX_OFFSET (Pmode))
6010 || delta >= CSKY_LD32_MAX_OFFSET (Pmode))
6012 emit_insn (gen_movsi (scratch, GEN_INT (delta)));
6013 emit_insn (gen_addsi3 (scratch, scratch, basereg));
6014 addr = scratch;
6016 else
6017 addr = plus_constant (Pmode, basereg, delta);
6018 emit_move_insn (gen_frame_mem (Pmode, addr), source);
6020 else
6021 emit_move_insn (gen_rtx_REG (Pmode, CSKY_LR_REGNUM), source);
6024 /* Return TRUE if X references a SYMBOL_REF. */
6026 bool
6027 csky_symbol_mentioned_p (rtx x)
6029 const char *fmt;
6030 int i;
6032 if (GET_CODE (x) == SYMBOL_REF)
6033 return true;
6035 fmt = GET_RTX_FORMAT (GET_CODE (x));
6036 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
6038 if (fmt[i] == 'E')
6040 int j;
6042 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
6043 if (csky_symbol_mentioned_p (XVECEXP (x, i, j)))
6044 return true;
6046 else if (fmt[i] == 'e' && csky_symbol_mentioned_p (XEXP (x, i)))
6047 return true;
6049 return false;
6053 /* Return TRUE if X references a LABEL_REF. */
6055 bool
6056 csky_label_mentioned_p (rtx x)
6058 const char *fmt;
6059 int i;
6061 if (GET_CODE (x) == LABEL_REF)
6062 return true;
6064 fmt = GET_RTX_FORMAT (GET_CODE (x));
6065 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
6067 if (fmt[i] == 'E')
6069 int j;
6071 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
6072 if (csky_label_mentioned_p (XVECEXP (x, i, j)))
6073 return true;
6075 else if (fmt[i] == 'e' && csky_label_mentioned_p (XEXP (x, i)))
6076 return true;
6079 return false;
6083 static bool
6084 tls_unspec_mentioned_p (rtx x)
6086 switch (GET_CODE (x))
6088 case CONST:
6089 return tls_unspec_mentioned_p (XEXP (x, 0));
6091 case UNSPEC:
6092 if (XINT (x, 1) == UNSPEC_TLS)
6093 return true;
6095 /* Fall through. */
6096 default:
6097 return false;
6102 /* Implement LEGITIMATE_PIC_OPERAND_P. */
6104 bool
6105 csky_legitimate_pic_operand_p (rtx x)
6107 if (tls_unspec_mentioned_p (x))
6108 return true;
6109 if (csky_symbol_mentioned_p (x) || csky_label_mentioned_p (x))
6110 return false;
6111 return true;
6115 csky_legitimize_pic_address (rtx orig, rtx reg, bool gotrel_p)
6117 rtx pic_reg = gen_rtx_REG (SImode, PIC_OFFSET_TABLE_REGNUM);
6118 bool optimize_p = false;
6120 if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
6122 rtx pic_ref, address, rtx_tmp;
6123 rtx insn;
6124 rtx pic_reg = gen_rtx_REG (SImode, PIC_OFFSET_TABLE_REGNUM);
6125 int subregs = 0;
6127 if (reg == 0)
6129 gcc_assert (can_create_pseudo_p ());
6130 reg = gen_reg_rtx (Pmode);
6131 subregs = 1;
6134 if (subregs)
6135 address = gen_reg_rtx (Pmode);
6136 else
6137 address = reg;
6139 if (GET_CODE (orig) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (orig))
6141 /* When gotrel_p generate sym@GOT, otherwise generate sym@PLT. */
6142 rtx_tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig),
6143 (gotrel_p
6144 ? UNSPEC_PIC_SYMBOL_GOT
6145 : UNSPEC_PIC_SYMBOL_PLT));
6146 optimize_p = gotrel_p;
6147 if (flag_pic != 1)
6149 emit_move_insn (address, rtx_tmp);
6150 rtx_tmp = gen_rtx_MULT (Pmode, address, GEN_INT (1));
6152 pic_ref = gen_const_mem (Pmode,
6153 gen_rtx_PLUS (Pmode, pic_reg, rtx_tmp));
6155 else
6157 /* bsr symbol */
6158 if (flag_pic == 1 && !gotrel_p)
6160 pic_ref = gen_rtx_UNSPEC (Pmode,
6161 gen_rtvec (1, orig),
6162 UNSPEC_PIC_SYMBOL_BSR);
6163 return pic_ref;
6165 /* grs rx, symbol */
6166 else if (flag_pic == 1 && (GET_CODE (orig) == SYMBOL_REF)
6167 && SYMBOL_REF_FUNCTION_P (orig))
6169 pic_ref = gen_rtx_UNSPEC (Pmode,
6170 gen_rtvec (1, orig),
6171 UNSPEC_PIC_SYMBOL_GRS);
6172 return pic_ref;
6174 /* lrw rx, symbol@GOTOFF; add rx, rx, gb */
6175 else
6177 rtx_tmp = gen_rtx_UNSPEC (Pmode,
6178 gen_rtvec (1, orig),
6179 UNSPEC_PIC_SYMBOL_GOTOFF);
6180 emit_move_insn (address, rtx_tmp);
6181 pic_ref = gen_rtx_PLUS (Pmode, address, pic_reg);
6182 optimize_p = true;
6186 insn = emit_move_insn (reg, pic_ref);
6187 /* Put a REG_EQUAL note on this insn,
6188 so that it can be optimized by loop. */
6189 if (optimize_p)
6190 set_unique_reg_note (insn, REG_EQUAL, orig);
6192 return reg;
6194 else if (GET_CODE (orig) == CONST)
6196 rtx base, offset;
6198 if (GET_CODE (XEXP (orig, 0)) == PLUS
6199 && XEXP (XEXP (orig, 0), 1) == pic_reg)
6200 return orig;
6202 if (reg == 0)
6204 gcc_assert (can_create_pseudo_p ());
6205 reg = gen_reg_rtx (Pmode);
6208 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
6210 base = csky_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
6211 reg, gotrel_p);
6212 offset = csky_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
6213 base == reg ? 0 : reg, gotrel_p);
6215 if (GET_CODE (offset) == CONST_INT)
6216 return plus_constant (Pmode, base, INTVAL (offset));
6218 return gen_rtx_PLUS (Pmode, base, offset);
6221 return orig;
6225 /* Functions to output assembly code for a function call. */
6227 char *
6228 csky_output_call (rtx *operands, int index)
6230 static char buffer[20];
6231 rtx addr = operands[index];
6233 if (REG_P (addr))
6234 sprintf (buffer, "jsr\t%%%d", index);
6235 else if (flag_pic && (GET_CODE (addr) == UNSPEC))
6236 sprintf (buffer, "bsr\t%%%d", index);
6237 else
6238 sprintf (buffer, "jbsr\t%%%d", index);
6240 return buffer;
6244 /* Worker function for TARGET_ASM_TRAMPOLINE_TEMPLATE.
6245 Output assembler code for a block containing the constant parts
6246 of a trampoline, leaving space for the variable parts.
6247 Note that STATIC_CHAIN_REGNUM is t1 (aka r12) on ck801 and
6248 t1 (r13) otherwise. */
6250 static void
6251 csky_asm_trampoline_template (FILE *f)
6253 if (CSKY_ISA_FEATURE (2E3))
6255 fprintf (f, "\tlrw\t%s, [.Lstatic_chain]\n",
6256 reg_names[STATIC_CHAIN_REGNUM]);
6257 fprintf (f, "\tjmpi\t[.Lfunc_address]\n");
6258 /* 2 32-bit insns = 8 bytes. */
6260 else if (CSKY_TARGET_ARCH (CK801))
6262 /* It's hard to provide general support for trampolines on this
6263 core. We need a register other than the one holding the
6264 static chain (r13) to hold the function pointer for the
6265 indirect jump to it. But ck801 has such a limited register set
6266 there is no other call-clobbered scratch register available -- in
6267 particular, this core does not have r12, which we use for the
6268 ck802 case below. If we use a callee-saved register like r4,
6269 saving the old value on the stack screws up the stack frame
6270 if there are overflow arguments pushed on the stack
6271 by the caller. In theory we could test for that and handle
6272 limited cases with parameters that all fit in r0-r3 with no
6273 stack overflow, but punt for now. */
6274 sorry ("Nested function trampolines not supported on CK801.");
6276 else
6278 fprintf (f, "\tlrw\t%s, [.Lfunc_address]\n",
6279 reg_names[CSKY_T1_REGNUM]);
6280 fprintf (f, "\tlrw\t%s, [.Lstatic_chain]\n",
6281 reg_names[STATIC_CHAIN_REGNUM]);
6282 fprintf (f, "\tjmp\t%s\n",
6283 reg_names[CSKY_T1_REGNUM]);
6284 /* To align constant pool on a word boundary. */
6285 fprintf (f, "\t.align 2\n");
6286 /* 2 32-bit lrw insns + 16-bit jump + 16-bit pad = 12 bytes. */
6289 fprintf (f, ".Lstatic_chain:\n");
6290 fprintf (f, "\t.long 0\n");
6291 fprintf (f, ".Lfunc_address:\n");
6292 fprintf (f, "\t.long 0\n");
6293 /* 2 words of constant pool = 8 bytes. */
6296 /* Worker function for TARGET_TRAMPOLINE_INIT. */
6298 static void
6299 csky_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
6301 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
6302 rtx mem, a_tramp;
6303 int pool = TRAMPOLINE_SIZE - 8;
6305 emit_block_move (m_tramp, assemble_trampoline_template (),
6306 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
6308 mem = adjust_address (m_tramp, SImode, pool);
6309 emit_move_insn (mem, chain_value);
6310 mem = adjust_address (m_tramp, SImode, pool + 4);
6311 emit_move_insn (mem, fnaddr);
6313 a_tramp = XEXP (m_tramp, 0);
6314 maybe_emit_call_builtin___clear_cache (a_tramp,
6315 plus_constant (Pmode,
6316 a_tramp,
6317 TRAMPOLINE_SIZE));
6321 /* Emit a comparison insn for float values.
6322 Return true if the comparison is inverted. */
6324 bool
6325 csky_emit_compare_float (enum rtx_code code, rtx op0, rtx op1)
6327 rtx cc_reg = gen_rtx_REG (CCmode, CSKY_CC_REGNUM);
6328 bool invert;
6329 machine_mode mode = GET_MODE (op1);
6331 if (op1 != CONST0_RTX (mode))
6332 op1 = force_reg (mode, op1);
6334 invert = false;
6336 switch (code)
6338 case EQ:
6339 code = NE;
6340 invert = true;
6341 break;
6342 case GT:
6343 case LT:
6344 case LE:
6345 if (op1 == CONST0_RTX (mode) && (CSKY_ISA_FEATURE_GET(fpv2_sf)
6346 || CSKY_ISA_FEATURE_GET(fpv2_df)
6347 || CSKY_ISA_FEATURE_GET(fpv2_divd)))
6348 op1 = force_reg (mode, op1);
6349 break;
6350 case ORDERED:
6351 code = UNORDERED;
6352 invert = true;
6353 break;
6355 default:
6356 break;
6359 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_fmt_ee (code, CCmode, op0, op1)));
6361 return invert;
6364 /* Support for the Q or W memory constraint. Returns true if OP is a MEM
6365 RTX with an address consisting of base + index or base + displacement. */
6367 bool
6368 csky_valid_mem_constraint_operand (rtx op, const char *constraint)
6370 struct csky_address addr;
6372 if (GET_CODE (op) != MEM)
6373 return false;
6375 if (!decompose_csky_address (XEXP (op, 0), &addr))
6376 return false;
6378 /* Verify base register. */
6379 if (!is_csky_address_register_rtx_p (addr.base, 0))
6380 return false;
6382 /* Verify index operand. */
6383 if (addr.index && (constraint[0] == 'Q' || constraint[0] == 'W'))
6385 if (!is_csky_address_register_rtx_p (addr.index, 0))
6386 return false;
6388 if (addr.scale == 1 || addr.scale == 2 || addr.scale == 4
6389 || addr.scale == 8)
6390 return true;
6392 return false;
6394 /* Verify disp operand. */
6395 else if (addr.disp && constraint[0] == 'Q')
6397 rtx disp = addr.disp;
6399 if (!CONST_INT_P (disp))
6400 return false;
6402 if (((unsigned) INTVAL (disp) % 4) == 0
6403 && (unsigned) INTVAL (disp) <= (unsigned) 1020)
6404 return true;
6406 return false;
6408 else if (constraint[0] == 'Q')
6409 /* Single reg is valid for 'Q'. */
6410 return true;
6412 return false;
6416 /* Returns the (interrupt) function type of the current
6417 function, or CSKY_FT_UNKNOWN if the type cannot be determined. */
6419 static unsigned long
6420 csky_isr_value (tree argument)
6422 const isr_attribute_entry *ptr;
6423 const char *arg;
6425 /* No argument - default to IRQ. */
6426 if (argument == NULL_TREE)
6427 return CSKY_FT_ISR;
6429 /* Get the value of the argument. */
6430 if (TREE_VALUE (argument) == NULL_TREE
6431 || TREE_CODE (TREE_VALUE (argument)) != STRING_CST)
6432 return CSKY_FT_UNKNOWN;
6434 arg = TREE_STRING_POINTER (TREE_VALUE (argument));
6436 /* Check it against the list of known arguments. */
6437 for (ptr = isr_attribute_map; ptr->arg != NULL; ptr++)
6438 if (strcmp (arg, ptr->arg) == 0)
6439 return ptr->return_value;
6441 /* An unrecognized interrupt type. */
6442 return CSKY_FT_UNKNOWN;
6445 /* Handle an attribute requiring a FUNCTION_DECL;
6446 arguments as in struct attribute_spec.handler. */
6448 static tree
6449 csky_handle_fndecl_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
6450 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
6452 if (TREE_CODE (*node) != FUNCTION_DECL)
6454 warning (OPT_Wattributes, "%qE attribute only applies to functions",
6455 name);
6456 *no_add_attrs = true;
6459 return NULL_TREE;
6462 /* Handle an "interrupt" or "isr" attribute;
6463 arguments as in struct attribute_spec.handler. */
6465 static tree
6466 csky_handle_isr_attribute (tree *node, tree name, tree args, int flags,
6467 bool *no_add_attrs)
6470 if (!TARGET_ISTACK)
6472 warning (OPT_Wattributes, "%qE attribute ignored without %<-mistack%>",
6473 name);
6474 *no_add_attrs = true;
6475 return NULL_TREE;
6478 if (DECL_P (*node))
6480 if (TREE_CODE (*node) != FUNCTION_DECL)
6482 warning (OPT_Wattributes, "%qE attribute only applies to functions",
6483 name);
6484 *no_add_attrs = true;
6487 else
6489 if (TREE_CODE (*node) == FUNCTION_TYPE
6490 || TREE_CODE (*node) == METHOD_TYPE)
6492 if (csky_isr_value (args) == CSKY_FT_UNKNOWN)
6494 warning (OPT_Wattributes, "%qE attribute ignored", name);
6495 *no_add_attrs = true;
6498 else if (TREE_CODE (*node) == POINTER_TYPE
6499 && (TREE_CODE (TREE_TYPE (*node)) == FUNCTION_TYPE
6500 || TREE_CODE (TREE_TYPE (*node)) == METHOD_TYPE)
6501 && csky_isr_value (args) != CSKY_FT_UNKNOWN)
6503 *node = build_variant_type_copy (*node);
6504 TREE_TYPE (*node) = build_type_attribute_variant (TREE_TYPE (*node),
6505 tree_cons (name, args, TYPE_ATTRIBUTES (TREE_TYPE (*node))));
6506 *no_add_attrs = true;
6508 else if (flags & ((int)ATTR_FLAG_DECL_NEXT
6509 | (int)ATTR_FLAG_FUNCTION_NEXT
6510 | (int)ATTR_FLAG_ARRAY_NEXT))
6512 *no_add_attrs = true;
6513 return tree_cons (name, args, NULL_TREE);
6515 else
6516 warning (OPT_Wattributes, "%qE attribute ignored", name);
6518 return NULL_TREE;
6522 /* Implement TARGET_REGISTER_MOVE_COST: compute extra cost of moving data
6523 between one register class and another. */
6526 csky_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
6527 reg_class_t from, reg_class_t to)
6529 #define GR_REG_CLASS_P(CLASS) \
6530 ((CLASS) == GENERAL_REGS || (CLASS) == MINI_REGS || (CLASS) == SP_REGS \
6531 || (CLASS) == LOW_REGS)
6533 #define HILO_REG_CLASS_P(CLASS) \
6534 ((CLASS) == HILO_REGS)
6536 #define V_REG_CLASS_P(CLASS) \
6537 ((CLASS) == V_REGS)
6539 if (V_REG_CLASS_P (from) && V_REG_CLASS_P (to))
6540 return 2;
6542 if ((V_REG_CLASS_P (from) && GR_REG_CLASS_P (to))
6543 || (GR_REG_CLASS_P (from) && V_REG_CLASS_P (to)))
6544 return 6;
6546 if ((HILO_REG_CLASS_P (from) && GR_REG_CLASS_P (to))
6547 || (GR_REG_CLASS_P (from) && HILO_REG_CLASS_P (to)))
6548 return 16;
6550 if (HILO_REG_CLASS_P (from) && HILO_REG_CLASS_P (to))
6551 return 32;
6553 if ((HILO_REG_CLASS_P (from) && V_REG_CLASS_P (to))
6554 || (V_REG_CLASS_P (from) && HILO_REG_CLASS_P (to)))
6555 return 64;
6557 return 2;
6561 /* Implement TARGET_MEMORY_MOVE_COST: compute the cost of moving data
6562 between registers and memory. */
6565 csky_memory_move_cost (machine_mode mode, reg_class_t rclass,
6566 bool in)
6568 return (4 + memory_move_secondary_cost (mode, rclass, in));
6572 /* TARGET_RTX_COSTS helper for ck801/ck802. */
6574 static bool
6575 ck802_ck801_rtx_costs (rtx x, int code, int outer_code, int *total,
6576 bool speed)
6578 machine_mode mode = GET_MODE (x);
6579 switch (code)
6581 /* Accessing memory costs quite a lot for first word; */
6582 case MEM:
6583 *total = COSTS_N_INSNS (1 + CSKY_NUM_REGS (mode));
6584 return false;
6585 case DIV:
6586 case UDIV:
6587 case MOD:
6588 case UMOD:
6589 *total = 100;
6590 return true;
6592 case ROTATE:
6593 case ROTATERT:
6594 case ASHIFT:
6595 case LSHIFTRT:
6596 case ASHIFTRT:
6597 if (speed)
6598 *total = 2;
6599 else
6600 *total = COSTS_N_INSNS (1);
6601 return false;
6603 case MINUS:
6604 case PLUS:
6605 *total = COSTS_N_INSNS (CSKY_NUM_REGS (mode));
6606 return false;
6608 case AND:
6610 enum rtx_code subcode = GET_CODE (XEXP (x, 1));
6612 /* If subcode is "not", we'll try to combine it into e.g. "andn"
6613 instruction, so give AND itself zero cost. */
6614 if (subcode == NOT)
6616 *total = 0;
6617 return false;
6620 /* Fall through. */
6621 case XOR:
6622 case IOR:
6623 *total = COSTS_N_INSNS (CSKY_NUM_REGS (mode));
6624 return false;
6626 case MULT:
6627 /* FIXME: is ixw supported on ck801/ck802? */
6628 /* We can use "ix.h/w" insn to replace multiply by 2 or 4.
6629 "ix.h/w" is a 32-bit insn, so let its cost be a little less than
6630 "mult" insn. */
6631 if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)))
6633 unsigned HOST_WIDE_INT m
6634 = (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)));
6635 if ((m == 2 || m == 4) && outer_code == PLUS)
6637 *total = 2;
6638 return true;
6640 else
6642 /* Because mult is relatively slower than other operations,
6643 we try to use other insns when optimizing for speed.
6644 When optimizing for size, give it lower cost. */
6645 if (speed)
6647 *total = COSTS_N_INSNS (10 * CSKY_NUM_REGS (mode));
6648 return true;
6650 int cycle = 0;
6651 while (m)
6653 m >>= 2;
6654 cycle++;
6656 *total = COSTS_N_INSNS (1) + cycle;
6657 return false;
6660 if (!speed)
6661 *total = COSTS_N_INSNS (1);
6662 return false;
6664 case NEG:
6665 /* Usually, we use subtract from 0 to substitute for neg, and
6666 it costs 1 extra insn to move 0 to a register. */
6667 *total = COSTS_N_INSNS (2 * CSKY_NUM_REGS (mode));
6668 return false;
6670 case NOT:
6671 *total = COSTS_N_INSNS (CSKY_NUM_REGS (mode));
6672 return false;
6674 case COMPARE:
6675 *total = COSTS_N_INSNS (1);
6676 return false;
6678 case SIGN_EXTEND:
6679 case ZERO_EXTEND:
6680 *total = COSTS_N_INSNS (CSKY_NUM_REGS (mode));
6681 return false;
6683 case SIGN_EXTRACT:
6684 case ZERO_EXTRACT:
6685 if (REG_P (XEXP (x, 0))
6686 && CONST_INT_P (XEXP (x, 1))
6687 && CONST_INT_P (XEXP (x, 2))
6688 && INTVAL (XEXP (x, 1)) == 8
6689 && INTVAL (XEXP (x, 2)) % 8 == 0)
6691 *total = COSTS_N_INSNS (1);
6692 return true;
6694 *total = COSTS_N_INSNS (CSKY_NUM_REGS (mode));
6695 return false;
6697 case CONST_INT:
6699 unsigned HOST_WIDE_INT t = (unsigned HOST_WIDE_INT) (INTVAL (x));
6701 if (outer_code == COMPARE)
6703 if (t < 0x10000)
6704 *total = 0;
6705 else
6706 *total = COSTS_N_INSNS (2);
6708 else if (outer_code == AND || outer_code == IOR || outer_code == XOR)
6710 /* "andi,xori,ori" are 32-bit insns, so let it cost a
6711 little more. */
6712 if (t < 0x1000)
6714 /* Try replacing "andi" by "sextb/h", so let it cost more. */
6715 if (outer_code == AND && (t == 0xff || t == 0xffff))
6717 *total = 8;
6718 return true;
6720 *total = 2;
6722 else if (t < 0x10000)
6723 *total = COSTS_N_INSNS (1);
6724 else
6725 *total = COSTS_N_INSNS (2);
6727 else if (outer_code == PLUS || outer_code == MINUS)
6729 /* "addi/subi rx,ry,imm", if imm<9, it is more often a
6730 16-bit insn. If imm>=9, use "movi" insn; it's probably
6731 less than "addi/subi". */
6732 if (t < 9)
6733 *total = 0;
6734 else if (t < 0x1000)
6735 *total = 2;
6736 else if (t < 0x10000)
6737 *total = COSTS_N_INSNS (1);
6738 else
6739 *total = COSTS_N_INSNS (2);
6741 else if (outer_code == ROTATE || outer_code == ROTATERT
6742 || outer_code == LSHIFTRT || outer_code == ASHIFTRT
6743 || outer_code == ASHIFT)
6745 if (t < 32)
6746 *total = 0;
6747 else
6748 *total = COSTS_N_INSNS (2);
6750 else
6752 if (t < 0x10000)
6753 if (outer_code == SET && t < 256)
6754 *total = 0;
6755 else
6756 *total = COSTS_N_INSNS (1);
6757 else
6758 *total = COSTS_N_INSNS (2);
6761 return true;
6763 case CONST:
6764 case LABEL_REF:
6765 case SYMBOL_REF:
6766 *total = COSTS_N_INSNS (3);
6767 return true;
6768 default:
6769 return false;
6774 /* TARGET_RTX_COSTS helper for ck803. */
6776 static bool
6777 ck803_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
6778 int *total, bool speed ATTRIBUTE_UNUSED)
6780 switch (code)
6782 case SET:
6783 if (MEM_P (XEXP (x, 1)))
6785 struct csky_address op1;
6786 bool address_valid
6787 = decompose_csky_address (XEXP (XEXP (x, 1), 0), &op1);
6788 if (op1.index)
6790 *total = COSTS_N_INSNS (3);
6791 return true;
6793 else if (address_valid)
6795 *total = COSTS_N_INSNS (1);
6796 return true;
6799 if (REG_P (XEXP (x, 0)) && (GET_CODE (XEXP (x, 1)) == PLUS))
6801 rtx sub_exp = XEXP (x, 1);
6802 if (REG_P (XEXP (sub_exp, 0)) && REG_P (XEXP (sub_exp, 1)))
6804 *total = COSTS_N_INSNS (1);
6805 return true;
6808 return false;
6809 case MULT:
6810 if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)))
6812 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6813 if (val % 2 == 0 && val < 0xffffffff && val > 0)
6815 *total = COSTS_N_INSNS (1);
6816 return true;
6819 return false;
6821 case CONST:
6822 case LABEL_REF:
6823 case SYMBOL_REF:
6824 *total = COSTS_N_INSNS (3);
6825 return true;
6826 default:
6827 return false;
6831 /* TARGET_RTX_COSTS helper for ck807/ck810 arches. */
6833 static bool
6834 ck807_ck810_rtx_costs (rtx x, int code,
6835 int outer_code ATTRIBUTE_UNUSED,
6836 int *total, bool speed ATTRIBUTE_UNUSED)
6838 switch (code)
6840 case MULT:
6841 if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)))
6843 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6844 if (val % 2 == 0 && val < 0xffffffff && val > 0)
6846 *total = COSTS_N_INSNS (1);
6847 return true;
6850 return false;
6852 case CONST:
6853 case LABEL_REF:
6854 case SYMBOL_REF:
6855 *total = COSTS_N_INSNS (3);
6856 return true;
6857 default:
6858 return false;
6862 /* TARGET_RTX_COSTS helper for ck860 arches. */
6864 static bool
6865 ck860_rtx_costs (rtx x, int code, machine_mode mode,
6866 int outer_code ATTRIBUTE_UNUSED,
6867 int *total, bool speed ATTRIBUTE_UNUSED)
6869 switch (code)
6871 case PLUS:
6872 /* The costs of mula is 1 more than mult. */
6873 if (GET_CODE (XEXP (x, 0)) == MULT && REG_P (XEXP (x, 1)) && speed)
6875 rtx mul_op0 = XEXP (XEXP (x, 0), 0);
6876 rtx mul_op1 = XEXP (XEXP (x, 0), 1);
6877 if (REG_P (mul_op0) && REG_P (mul_op1))
6879 *total = COSTS_N_INSNS (1);
6880 *total += rtx_cost (XEXP (x, 0), mode,
6881 (enum rtx_code) code, 0, speed);
6882 return true;
6885 return false;
6886 case MULT:
6887 if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)))
6889 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6890 if (val % 2 == 0 && val < 0xffffffff && val > 0)
6892 *total = COSTS_N_INSNS (1);
6893 return true;
6896 return false;
6898 case CONST:
6899 case LABEL_REF:
6900 case SYMBOL_REF:
6901 *total = COSTS_N_INSNS (3);
6902 return true;
6903 default:
6904 return false;
6909 /* Implement TARGET_RTX_COSTS, to compute a (partial) cost for rtx X.
6910 Return true if the complete cost has been computed, and false if
6911 subexpressions should be scanned. In either case, *TOTAL contains
6912 the cost result. */
6914 static bool
6915 csky_rtx_costs (rtx x, machine_mode mode ATTRIBUTE_UNUSED, int outer_code,
6916 int opno ATTRIBUTE_UNUSED, int *total, bool speed)
6918 int code = GET_CODE (x);
6920 if (CSKY_TARGET_ARCH (CK802) || CSKY_TARGET_ARCH (CK801))
6921 return ck802_ck801_rtx_costs (x, code, outer_code, total, speed);
6922 else if (CSKY_TARGET_ARCH (CK803))
6923 return ck803_rtx_costs (x, code, outer_code, total, speed);
6924 else if (CSKY_TARGET_ARCH (CK807) || CSKY_TARGET_ARCH (CK810))
6925 return ck807_ck810_rtx_costs (x, code, outer_code, total, speed);
6926 else if (CSKY_TARGET_ARCH (CK860))
6927 return ck860_rtx_costs (x, code, mode, outer_code, total, speed);
6928 else
6929 gcc_unreachable ();
6932 /* Emit assembly code for CASESI. This is only used on CK801 and CK802
6933 when optimizing for size, and uses helper functions in libgcc instead
6934 of doing the control transfer inline. */
6936 const char *
6937 csky_output_casesi (rtx *operands)
6939 rtx diff_vec = PATTERN (NEXT_INSN (as_a <rtx_insn *> (operands[0])));
6941 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
6943 switch (GET_MODE (diff_vec))
6945 case E_QImode:
6946 return (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned
6947 ? "jbsr\t___gnu_csky_case_uqi"
6948 : "jbsr\t___gnu_csky_case_sqi");
6949 case E_HImode:
6950 return (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned
6951 ? "jbsr\t___gnu_csky_case_uhi"
6952 : "jbsr\t___gnu_csky_case_shi");
6953 case E_SImode:
6954 return "jbsr\t___gnu_csky_case_si";
6955 default:
6956 gcc_unreachable ();
6960 /* Implement TARGET_SCHED_ISSUE_RATE. Lookup the issue rate in the
6961 per-core tuning structs. */
6962 static int
6963 csky_sched_issue_rate (void)
6965 if (CSKY_TARGET_ARCH (CK810))
6966 return 2;
6967 else
6968 return 1;
6972 /* This function implements the target macro TARGET_SCHED_ADJUST_COST.
6973 It corrects the value of COST based on the relationship between
6974 INSN and DEP through the dependence DEP_TYPE. It returns the new
6975 value. */
6977 static int
6978 csky_sched_adjust_cost (rtx_insn *insn,
6979 int dep_type,
6980 rtx_insn *dep,
6981 int cost,
6982 unsigned int dw ATTRIBUTE_UNUSED)
6984 if (dep_type == REG_DEP_ANTI || dep_type == REG_DEP_OUTPUT)
6985 return 0;
6986 /* The REG_DEP_TRUE situation. */
6987 else if (recog_memoized (insn) >= 0 && recog_memoized (dep) >= 0)
6989 enum attr_type insn_type = get_attr_type (insn);
6990 if (CSKY_TARGET_ARCH (CK803))
6992 /* The ld or st's base reg depends on the pre insn,
6993 it will delay 1 cycle. */
6994 if (insn_type == TYPE_LOAD || insn_type == TYPE_STORE)
6996 rtx pattern = PATTERN (insn);
6998 gcc_assert (GET_CODE (pattern) == SET);
6999 rtx addr = (insn_type == TYPE_LOAD
7000 ? SET_SRC (pattern) : SET_DEST (pattern));
7002 enum rtx_code code = GET_CODE (addr);
7003 if (code == ZERO_EXTEND || code == SIGN_EXTEND)
7004 addr = XEXP (addr, 0);
7005 gcc_assert (GET_CODE (addr) == MEM);
7007 rtx base = XEXP (addr, 0);
7008 rtx reg = NULL_RTX;
7009 if (REG_P (base))
7010 reg = base;
7011 if (GET_CODE (base) == PLUS
7012 && GET_CODE (XEXP (base, 0)) == REG)
7013 reg = XEXP (base, 0);
7014 if ((reg != NULL_RTX) && reg_set_p (reg, PATTERN (dep)))
7015 return 2;
7018 else if (CSKY_TARGET_ARCH (CK802))
7020 if ((insn_type == TYPE_CALL_JSR || insn_type == TYPE_BRANCH_JMP)
7021 && get_attr_type (dep) != TYPE_LOAD)
7022 return 1;
7024 if (insn_type == TYPE_LOAD || insn_type == TYPE_STORE)
7026 rtx pattern = PATTERN (insn);
7028 gcc_assert (GET_CODE (pattern) == SET);
7030 rtx addr = (insn_type == TYPE_LOAD
7031 ? SET_SRC (pattern) : SET_DEST (pattern));
7033 enum rtx_code code = GET_CODE (addr);
7034 if (code == ZERO_EXTEND || code == SIGN_EXTEND)
7035 addr = XEXP (addr, 0);
7036 gcc_assert (GET_CODE (addr) == MEM);
7038 rtx base = XEXP (addr, 0);
7039 rtx reg = NULL_RTX;
7040 if (REG_P (base))
7041 reg = base;
7042 if (GET_CODE (base) == PLUS
7043 && GET_CODE (XEXP (base, 0)) == REG)
7044 reg = XEXP (base, 0);
7045 if ((reg != NULL_RTX) && reg_set_p (reg, PATTERN (dep))
7046 && get_attr_type (dep) != TYPE_LOAD)
7047 return 1;
7049 if (insn_type == TYPE_STORE
7050 && reg_referenced_p (SET_SRC (pattern), PATTERN (dep)))
7051 return 1;
7055 return cost;
7058 static bool
7059 csky_warn_func_return (tree decl)
7061 /* Naked functions are implemented entirely in assembly, including the
7062 return sequence, so suppress warnings about this. */
7063 return lookup_attribute ("naked", DECL_ATTRIBUTES (decl)) == NULL_TREE;
7067 /* Implement TARGET_RETURN_IN_MEMORY to decide whether TYPE should be
7068 returned in memory (true) or in a register (false).
7069 FNTYPE is the type of the function making the call. */
7071 static bool
7072 csky_return_in_memory (const_tree type,
7073 const_tree fntype ATTRIBUTE_UNUSED)
7075 const HOST_WIDE_INT size = int_size_in_bytes (type);
7076 return (size == -1 || size > 2 * UNITS_PER_WORD);
7080 /* Implement TARGET_DWARF_REGISTER_SPAN.
7081 Dwarf models VFP registers as 64-bit or 128-bit registers default.
7082 GCC models tham as 32-bit registers, so we need to describe this to
7083 the DWARF generation code. Other registers can use the default. */
7085 static rtx
7086 csky_dwarf_register_span (rtx rtl)
7088 machine_mode mode;
7089 unsigned regno;
7090 rtx parts[16];
7091 int nregs;
7092 int i;
7094 regno = REGNO (rtl);
7095 if (!CSKY_VREG_P (regno))
7096 return NULL_RTX;
7098 if (CSKY_VREG_HI_P (regno))
7099 regno += 16;
7101 mode = GET_MODE (rtl);
7102 if (GET_MODE_SIZE (mode) < 8)
7103 return NULL_RTX;
7106 if (TARGET_SINGLE_FPU)
7108 nregs = GET_MODE_SIZE (mode) / 4;
7109 for (i = 0; i < nregs; i += 2)
7110 if (TARGET_BIG_ENDIAN)
7112 parts[i] = gen_rtx_REG (SImode, regno + i + 1);
7113 parts[i + 1] = gen_rtx_REG (SImode, regno + i);
7115 else
7117 parts[i] = gen_rtx_REG (SImode, regno + i);
7118 parts[i + 1] = gen_rtx_REG (SImode, regno + i + 1);
7121 else
7123 /* FIXME: dwarf2 considers all general registers to be the same
7124 as the CPU bit width. Transform the 64-bit FPU registers to
7125 32 bits here, and we will modify the unwind processing to
7126 fit CSKY architecture later. */
7127 nregs = GET_MODE_SIZE (mode) / 4;
7128 for (i = 0; i < nregs; i += 2)
7129 if (TARGET_BIG_ENDIAN)
7131 parts[i] = gen_rtx_REG (SImode, regno + i - 16);
7132 parts[i + 1] = gen_rtx_REG (SImode, regno + i);
7134 else
7136 parts[i] = gen_rtx_REG (SImode, regno + i);
7137 parts[i + 1] = gen_rtx_REG (SImode, regno + i - 16);
7141 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nregs , parts));
7144 /* Implement TARGET_INIT_LIBFUNCS. */
7146 static void
7147 csky_init_libfuncs (void)
7149 if (TARGET_CSKY_LINUX)
7150 init_sync_libfuncs (UNITS_PER_WORD);
7151 if (!TARGET_LIBCCRT)
7152 return;
7154 #define CSKY_GCC_SYM(sym) "__csky_ccrt_" # sym
7156 /* int */
7158 /* Arithmetic functions */
7159 set_optab_libfunc (ashl_optab, DImode, CSKY_GCC_SYM (ashldi3));
7160 set_optab_libfunc (ashr_optab, DImode, CSKY_GCC_SYM (ashrdi3));
7161 set_optab_libfunc (sdiv_optab, SImode, CSKY_GCC_SYM (divsi3));
7162 set_optab_libfunc (sdiv_optab, DImode, CSKY_GCC_SYM (divdi3));
7163 set_optab_libfunc (lshr_optab, DImode, CSKY_GCC_SYM (lshrdi3));
7164 set_optab_libfunc (smod_optab, SImode, CSKY_GCC_SYM (modsi3));
7165 set_optab_libfunc (smod_optab, DImode, CSKY_GCC_SYM (moddi3));
7166 set_optab_libfunc (smul_optab, DImode, CSKY_GCC_SYM (muldi3));
7167 set_optab_libfunc (neg_optab, DImode, CSKY_GCC_SYM (negdi2));
7168 set_optab_libfunc (udiv_optab, SImode, CSKY_GCC_SYM (udivsi3));
7169 set_optab_libfunc (udiv_optab, DImode, CSKY_GCC_SYM (udivdi3));
7170 set_optab_libfunc (udivmod_optab, DImode, CSKY_GCC_SYM (udivmoddi4));
7171 set_optab_libfunc (umod_optab, SImode, CSKY_GCC_SYM (umodsi3));
7172 set_optab_libfunc (umod_optab, DImode, CSKY_GCC_SYM (umoddi3));
7174 /* Comparison functions */
7175 set_optab_libfunc (cmp_optab, DImode, CSKY_GCC_SYM (cmpdi2));
7176 set_optab_libfunc (ucmp_optab, DImode, CSKY_GCC_SYM (ucmpdi2));
7178 /* Trapping arithmetic functions */
7179 set_optab_libfunc (absv_optab, SImode, CSKY_GCC_SYM (absvsi2));
7180 set_optab_libfunc (absv_optab, DImode, CSKY_GCC_SYM (absvdi2));
7181 set_optab_libfunc (addv_optab, SImode, CSKY_GCC_SYM (addvsi3));
7182 set_optab_libfunc (addv_optab, DImode, CSKY_GCC_SYM (addvdi3));
7183 set_optab_libfunc (smulv_optab, SImode, CSKY_GCC_SYM (mulvsi3));
7184 set_optab_libfunc (smulv_optab, DImode, CSKY_GCC_SYM (mulvdi3));
7185 set_optab_libfunc (negv_optab, SImode, CSKY_GCC_SYM (negvsi2));
7186 set_optab_libfunc (negv_optab, DImode, CSKY_GCC_SYM (negvdi2));
7187 set_optab_libfunc (subv_optab, SImode, CSKY_GCC_SYM (subvsi3));
7188 set_optab_libfunc (subv_optab, DImode, CSKY_GCC_SYM (subvdi3));
7190 /* Bit operations */
7191 set_optab_libfunc (clz_optab, SImode, CSKY_GCC_SYM (clzsi2));
7192 set_optab_libfunc (clz_optab, DImode, CSKY_GCC_SYM (clzdi2));
7193 set_optab_libfunc (ctz_optab, SImode, CSKY_GCC_SYM (ctzsi2));
7194 set_optab_libfunc (ctz_optab, DImode, CSKY_GCC_SYM (ctzdi2));
7195 set_optab_libfunc (ffs_optab, DImode, CSKY_GCC_SYM (ffsdi2));
7196 set_optab_libfunc (parity_optab, SImode, CSKY_GCC_SYM (paritysi2));
7197 set_optab_libfunc (parity_optab, DImode, CSKY_GCC_SYM (paritydi2));
7198 set_optab_libfunc (popcount_optab,SImode, CSKY_GCC_SYM (popcountsi2));
7199 set_optab_libfunc (popcount_optab,DImode, CSKY_GCC_SYM (popcountdi2));
7200 set_optab_libfunc (bswap_optab, SImode, CSKY_GCC_SYM (bswapsi2));
7201 set_optab_libfunc (bswap_optab, DImode, CSKY_GCC_SYM (bswapdi2));
7203 /* float */
7205 /* Arithmetic functions */
7206 set_optab_libfunc (add_optab, SFmode, CSKY_GCC_SYM (addsf3));
7207 set_optab_libfunc (add_optab, DFmode, CSKY_GCC_SYM (adddf3));
7208 set_optab_libfunc (sub_optab, SFmode, CSKY_GCC_SYM (subsf3));
7209 set_optab_libfunc (sub_optab, DFmode, CSKY_GCC_SYM (subdf3));
7210 set_optab_libfunc (smul_optab, SFmode, CSKY_GCC_SYM (mulsf3));
7211 set_optab_libfunc (smul_optab, DFmode, CSKY_GCC_SYM (muldf3));
7212 set_optab_libfunc (sdiv_optab, SFmode, CSKY_GCC_SYM (divsf3));
7213 set_optab_libfunc (sdiv_optab, DFmode, CSKY_GCC_SYM (divdf3));
7214 set_optab_libfunc (neg_optab, SFmode, CSKY_GCC_SYM (negsf2));
7215 set_optab_libfunc (neg_optab, DFmode, CSKY_GCC_SYM (negdf2));
7217 /* Conversion functions */
7218 set_conv_libfunc (sext_optab, DFmode, SFmode, CSKY_GCC_SYM (extendsfdf2));
7219 set_conv_libfunc (trunc_optab, SFmode, DFmode, CSKY_GCC_SYM (truncdfsf2));
7220 set_conv_libfunc (sfix_optab, SImode, SFmode, CSKY_GCC_SYM (fixsfsi));
7221 set_conv_libfunc (sfix_optab, SImode, DFmode, CSKY_GCC_SYM (fixdfsi));
7222 set_conv_libfunc (sfix_optab, DImode, SFmode, CSKY_GCC_SYM (fixsfdi));
7223 set_conv_libfunc (sfix_optab, DImode, DFmode, CSKY_GCC_SYM (fixdfdi));
7224 set_conv_libfunc (ufix_optab, SImode, SFmode, CSKY_GCC_SYM (fixunssfsi));
7225 set_conv_libfunc (ufix_optab, SImode, DFmode, CSKY_GCC_SYM (fixunsdfsi));
7226 set_conv_libfunc (ufix_optab, DImode, SFmode, CSKY_GCC_SYM (fixunssfdi));
7227 set_conv_libfunc (ufix_optab, DImode, DFmode, CSKY_GCC_SYM (fixunsdfdi));
7228 set_conv_libfunc (sfloat_optab, SFmode, SImode, CSKY_GCC_SYM (floatsisf));
7229 set_conv_libfunc (sfloat_optab, DFmode, SImode, CSKY_GCC_SYM (floatsidf));
7230 set_conv_libfunc (sfloat_optab, SFmode, DImode, CSKY_GCC_SYM (floatdisf));
7231 set_conv_libfunc (sfloat_optab, DFmode, DImode, CSKY_GCC_SYM (floatdidf));
7232 set_conv_libfunc (ufloat_optab, SFmode, SImode, CSKY_GCC_SYM (floatunsisf));
7233 set_conv_libfunc (ufloat_optab, DFmode, SImode, CSKY_GCC_SYM (floatunsidf));
7234 set_conv_libfunc (ufloat_optab, SFmode, DImode, CSKY_GCC_SYM (floatundisf));
7235 set_conv_libfunc (ufloat_optab, DFmode, DImode, CSKY_GCC_SYM (floatundidf));
7237 /* Comparison functions */
7238 set_optab_libfunc (cmp_optab, SFmode, CSKY_GCC_SYM (cmpsf2));
7239 set_optab_libfunc (cmp_optab, DFmode, CSKY_GCC_SYM (cmpdf2));
7240 set_optab_libfunc (unord_optab, SFmode, CSKY_GCC_SYM (unordsf2));
7241 set_optab_libfunc (unord_optab, DFmode, CSKY_GCC_SYM (unorddf2));
7242 set_optab_libfunc (eq_optab, SFmode, CSKY_GCC_SYM (eqsf2));
7243 set_optab_libfunc (eq_optab, DFmode, CSKY_GCC_SYM (eqdf2));
7244 set_optab_libfunc (ne_optab, SFmode, CSKY_GCC_SYM (nesf2));
7245 set_optab_libfunc (ne_optab, DFmode, CSKY_GCC_SYM (nedf2));
7246 set_optab_libfunc (ge_optab, SFmode, CSKY_GCC_SYM (gesf2));
7247 set_optab_libfunc (ge_optab, DFmode, CSKY_GCC_SYM (gedf2));
7248 set_optab_libfunc (lt_optab, SFmode, CSKY_GCC_SYM (ltsf2));
7249 set_optab_libfunc (lt_optab, DFmode, CSKY_GCC_SYM (ltdf2));
7250 set_optab_libfunc (le_optab, SFmode, CSKY_GCC_SYM (lesf2));
7251 set_optab_libfunc (le_optab, DFmode, CSKY_GCC_SYM (ledf2));
7252 set_optab_libfunc (gt_optab, SFmode, CSKY_GCC_SYM (gtsf2));
7253 set_optab_libfunc (gt_optab, DFmode, CSKY_GCC_SYM (gtdf2));
7257 /* Implement TARGET_ADDRESS_COST to estimate cost of the memory address X.
7258 For C-SKY, (register) and (register + offset) have the same cost.
7259 Other situations cost more. */
7261 static int
7262 csky_address_cost (rtx x, machine_mode mode ATTRIBUTE_UNUSED,
7263 addr_space_t as ATTRIBUTE_UNUSED,
7264 bool speed ATTRIBUTE_UNUSED)
7266 enum rtx_code code = GET_CODE (x);
7268 if (code == REG)
7269 return COSTS_N_INSNS (1);
7270 if (code == PLUS
7271 && REG_P (XEXP (x, 0))
7272 && CONST_INT_P (XEXP (x, 1)))
7273 return COSTS_N_INSNS (1);
7275 return COSTS_N_INSNS (3);
7279 /* Implement TARGET_FIXED_CONDITION_CODE_REGS. */
7281 static bool
7282 csky_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
7284 *p1 = CSKY_CC_REGNUM;
7285 *p2 = INVALID_REGNUM;
7286 return true;
7289 void
7290 csky_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype,
7291 rtx libname ATTRIBUTE_UNUSED,
7292 tree fndecl ATTRIBUTE_UNUSED)
7294 memset(pcum, 0, sizeof(*pcum));
7295 if (stdarg_p (fntype))
7296 pcum->is_stdarg = true;
7300 /* Implement the TARGET_INIT_BUILTINS target macro. */
7302 void
7303 csky_init_builtins (void)
7305 /* Inint fp16. */
7306 static tree csky_floatHF_type_node = make_node (REAL_TYPE);
7307 TYPE_PRECISION (csky_floatHF_type_node) = GET_MODE_PRECISION (HFmode);
7308 layout_type (csky_floatHF_type_node);
7309 (*lang_hooks.types.register_builtin_type) (csky_floatHF_type_node, "__fp16");
7313 /* Implement TARGET_MANGLE_TYPE. */
7315 static const char *
7316 csky_mangle_type (const_tree type)
7318 if (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
7319 && DECL_NAME (TYPE_NAME (type))
7320 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))), "__fp16"))
7321 return "__fp16";
7323 /* Use the default mangling. */
7324 return NULL;
7327 struct gcc_target targetm = TARGET_INITIALIZER;
7329 #include "gt-csky.h"