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