1 /* Subroutines used for code generation on the Synopsys DesignWare ARC cpu. 2 Copyright (C) 1994-2019 Free Software Foundation, Inc. 3 4 Sources derived from work done by Sankhya Technologies (www.sankhya.com) on 5 behalf of Synopsys Inc. 6 7 Position Independent Code support added,Code cleaned up, 8 Comments and Support For ARC700 instructions added by 9 Saurabh Verma (saurabh.verma@codito.com) 10 Ramana Radhakrishnan(ramana.radhakrishnan@codito.com) 11 12 Fixing ABI inconsistencies, optimizations for ARC600 / ARC700 pipelines, 13 profiling support added by Joern Rennecke <joern.rennecke@embecosm.com> 14 15 This file is part of GCC. 16 17 GCC is free software; you can redistribute it and/or modify 18 it under the terms of the GNU General Public License as published by 19 the Free Software Foundation; either version 3, or (at your option) 20 any later version. 21 22 GCC is distributed in the hope that it will be useful, 23 but WITHOUT ANY WARRANTY; without even the implied warranty of 24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 GNU General Public License for more details. 26 27 You should have received a copy of the GNU General Public License 28 along with GCC; see the file COPYING3. If not see 29 <http://www.gnu.org/licenses/>. */ 30 31 #define IN_TARGET_CODE 1 32 33 #include "config.h" 34 #include "system.h" 35 #include "coretypes.h" 36 #include "memmodel.h" 37 #include "backend.h" 38 #include "target.h" 39 #include "rtl.h" 40 #include "tree.h" 41 #include "cfghooks.h" 42 #include "df.h" 43 #include "tm_p.h" 44 #include "stringpool.h" 45 #include "attribs.h" 46 #include "optabs.h" 47 #include "regs.h" 48 #include "emit-rtl.h" 49 #include "recog.h" 50 #include "diagnostic.h" 51 #include "fold-const.h" 52 #include "varasm.h" 53 #include "stor-layout.h" 54 #include "calls.h" 55 #include "output.h" 56 #include "insn-attr.h" 57 #include "flags.h" 58 #include "explow.h" 59 #include "expr.h" 60 #include "langhooks.h" 61 #include "tm-constrs.h" 62 #include "reload.h" /* For operands_match_p */ 63 #include "cfgrtl.h" 64 #include "tree-pass.h" 65 #include "context.h" 66 #include "builtins.h" 67 #include "rtl-iter.h" 68 #include "alias.h" 69 #include "opts.h" 70 #include "hw-doloop.h" 71 72 /* Which cpu we're compiling for (ARC600, ARC601, ARC700). */ 73 static char arc_cpu_name[10] = ""; 74 static const char *arc_cpu_string = arc_cpu_name; 75 76 typedef struct GTY (()) _arc_jli_section 77 { 78 const char *name; 79 struct _arc_jli_section *next; 80 } arc_jli_section; 81 82 static arc_jli_section *arc_jli_sections = NULL; 83 84 /* Track which regs are set fixed/call saved/call used from commnad line. */ 85 HARD_REG_SET overrideregs; 86 87 /* Maximum size of a loop. */ 88 #define ARC_MAX_LOOP_LENGTH 4095 89 90 /* Check if an rtx fits in the store instruction format. Loads can 91 handle any constant. */ 92 #define RTX_OK_FOR_OFFSET_P(MODE, X) \ 93 (GET_CODE (X) == CONST_INT \ 94 && SMALL_INT_RANGE (INTVAL (X), (GET_MODE_SIZE (MODE) - 1) & (~0x03), \ 95 (INTVAL (X) & (GET_MODE_SIZE (MODE) - 1) & 3 \ 96 ? 0 \ 97 : -(-GET_MODE_SIZE (MODE) | (~0x03)) >> 1))) 98 99 /* Array of valid operand punctuation characters. */ 100 char arc_punct_chars[256]; 101 102 /* State used by arc_ccfsm_advance to implement conditional execution. */ 103 struct GTY (()) arc_ccfsm 104 { 105 int state; 106 int cc; 107 rtx cond; 108 rtx_insn *target_insn; 109 int target_label; 110 }; 111 112 /* Status of the IRQ_CTRL_AUX register. */ 113 typedef struct irq_ctrl_saved_t 114 { 115 /* Last register number used by IRQ_CTRL_SAVED aux_reg. */ 116 short irq_save_last_reg; 117 /* True if BLINK is automatically saved. */ 118 bool irq_save_blink; 119 /* True if LPCOUNT is automatically saved. */ 120 bool irq_save_lpcount; 121 } irq_ctrl_saved_t; 122 static irq_ctrl_saved_t irq_ctrl_saved; 123 124 #define ARC_AUTOBLINK_IRQ_P(FNTYPE) \ 125 ((ARC_INTERRUPT_P (FNTYPE) \ 126 && irq_ctrl_saved.irq_save_blink) \ 127 || (ARC_FAST_INTERRUPT_P (FNTYPE) \ 128 && rgf_banked_register_count > 8)) 129 130 #define ARC_AUTOFP_IRQ_P(FNTYPE) \ 131 ((ARC_INTERRUPT_P (FNTYPE) \ 132 && (irq_ctrl_saved.irq_save_last_reg > 26)) \ 133 || (ARC_FAST_INTERRUPT_P (FNTYPE) \ 134 && rgf_banked_register_count > 8)) 135 136 #define ARC_AUTO_IRQ_P(FNTYPE) \ 137 (ARC_INTERRUPT_P (FNTYPE) && !ARC_FAST_INTERRUPT_P (FNTYPE) \ 138 && (irq_ctrl_saved.irq_save_blink \ 139 || (irq_ctrl_saved.irq_save_last_reg >= 0))) 140 141 /* Number of registers in second bank for FIRQ support. */ 142 static int rgf_banked_register_count; 143 144 #define arc_ccfsm_current cfun->machine->ccfsm_current 145 146 #define ARC_CCFSM_BRANCH_DELETED_P(STATE) \ 147 ((STATE)->state == 1 || (STATE)->state == 2) 148 149 /* Indicate we're conditionalizing insns now. */ 150 #define ARC_CCFSM_RECORD_BRANCH_DELETED(STATE) \ 151 ((STATE)->state += 2) 152 153 #define ARC_CCFSM_COND_EXEC_P(STATE) \ 154 ((STATE)->state == 3 || (STATE)->state == 4 || (STATE)->state == 5 \ 155 || current_insn_predicate) 156 157 /* Check if INSN has a 16 bit opcode considering struct arc_ccfsm *STATE. */ 158 #define CCFSM_ISCOMPACT(INSN,STATE) \ 159 (ARC_CCFSM_COND_EXEC_P (STATE) \ 160 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \ 161 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \ 162 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE) 163 164 /* Likewise, but also consider that INSN might be in a delay slot of JUMP. */ 165 #define CCFSM_DBR_ISCOMPACT(INSN,JUMP,STATE) \ 166 ((ARC_CCFSM_COND_EXEC_P (STATE) \ 167 || (JUMP_P (JUMP) \ 168 && INSN_ANNULLED_BRANCH_P (JUMP) \ 169 && (TARGET_AT_DBR_CONDEXEC || INSN_FROM_TARGET_P (INSN)))) \ 170 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \ 171 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \ 172 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE) 173 174 /* Start enter/leave register range. */ 175 #define ENTER_LEAVE_START_REG 13 176 177 /* End enter/leave register range. */ 178 #define ENTER_LEAVE_END_REG 26 179 180 /* The maximum number of insns skipped which will be conditionalised if 181 possible. */ 182 /* When optimizing for speed: 183 Let p be the probability that the potentially skipped insns need to 184 be executed, pn the cost of a correctly predicted non-taken branch, 185 mt the cost of a mis/non-predicted taken branch, 186 mn mispredicted non-taken, pt correctly predicted taken ; 187 costs expressed in numbers of instructions like the ones considered 188 skipping. 189 Unfortunately we don't have a measure of predictability - this 190 is linked to probability only in that in the no-eviction-scenario 191 there is a lower bound 1 - 2 * min (p, 1-p), and a somewhat larger 192 value that can be assumed *if* the distribution is perfectly random. 193 A predictability of 1 is perfectly plausible not matter what p is, 194 because the decision could be dependent on an invocation parameter 195 of the program. 196 For large p, we want MAX_INSNS_SKIPPED == pn/(1-p) + mt - pn 197 For small p, we want MAX_INSNS_SKIPPED == pt 198 199 When optimizing for size: 200 We want to skip insn unless we could use 16 opcodes for the 201 non-conditionalized insn to balance the branch length or more. 202 Performance can be tie-breaker. */ 203 /* If the potentially-skipped insns are likely to be executed, we'll 204 generally save one non-taken branch 205 o 206 this to be no less than the 1/p */ 207 #define MAX_INSNS_SKIPPED 3 208 209 /* A nop is needed between a 4 byte insn that sets the condition codes and 210 a branch that uses them (the same isn't true for an 8 byte insn that sets 211 the condition codes). Set by arc_ccfsm_advance. Used by 212 arc_print_operand. */ 213 214 static int get_arc_condition_code (rtx); 215 216 static tree arc_handle_interrupt_attribute (tree *, tree, tree, int, bool *); 217 static tree arc_handle_fndecl_attribute (tree *, tree, tree, int, bool *); 218 static tree arc_handle_jli_attribute (tree *, tree, tree, int, bool *); 219 static tree arc_handle_secure_attribute (tree *, tree, tree, int, bool *); 220 static tree arc_handle_uncached_attribute (tree *, tree, tree, int, bool *); 221 static tree arc_handle_aux_attribute (tree *, tree, tree, int, bool *); 222 223 /* Initialized arc_attribute_table to NULL since arc doesnot have any 224 machine specific supported attributes. */ 225 const struct attribute_spec arc_attribute_table[] = 226 { 227 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, 228 affects_type_identity, handler, exclude } */ 229 { "interrupt", 1, 1, true, false, false, true, 230 arc_handle_interrupt_attribute, NULL }, 231 /* Function calls made to this symbol must be done indirectly, because 232 it may lie outside of the 21/25 bit addressing range of a normal function 233 call. */ 234 { "long_call", 0, 0, false, true, true, false, NULL, NULL }, 235 /* Whereas these functions are always known to reside within the 25 bit 236 addressing range of unconditionalized bl. */ 237 { "medium_call", 0, 0, false, true, true, false, NULL, NULL }, 238 /* And these functions are always known to reside within the 21 bit 239 addressing range of blcc. */ 240 { "short_call", 0, 0, false, true, true, false, NULL, NULL }, 241 /* Function which are not having the prologue and epilogue generated 242 by the compiler. */ 243 { "naked", 0, 0, true, false, false, false, arc_handle_fndecl_attribute, 244 NULL }, 245 /* Functions calls made using jli instruction. The pointer in JLI 246 table is found latter. */ 247 { "jli_always", 0, 0, false, true, true, false, NULL, NULL }, 248 /* Functions calls made using jli instruction. The pointer in JLI 249 table is given as input parameter. */ 250 { "jli_fixed", 1, 1, false, true, true, false, arc_handle_jli_attribute, 251 NULL }, 252 /* Call a function using secure-mode. */ 253 { "secure_call", 1, 1, false, true, true, false, arc_handle_secure_attribute, 254 NULL }, 255 /* Bypass caches using .di flag. */ 256 { "uncached", 0, 0, false, true, false, false, arc_handle_uncached_attribute, 257 NULL }, 258 { "aux", 0, 1, true, false, false, false, arc_handle_aux_attribute, NULL }, 259 { NULL, 0, 0, false, false, false, false, NULL, NULL } 260 }; 261 static int arc_comp_type_attributes (const_tree, const_tree); 262 static void arc_file_start (void); 263 static void arc_internal_label (FILE *, const char *, unsigned long); 264 static void arc_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, 265 tree); 266 static int arc_address_cost (rtx, machine_mode, addr_space_t, bool); 267 static void arc_encode_section_info (tree decl, rtx rtl, int first); 268 269 static void arc_init_builtins (void); 270 static rtx arc_expand_builtin (tree, rtx, rtx, machine_mode, int); 271 272 static int branch_dest (rtx); 273 274 static void arc_output_pic_addr_const (FILE *, rtx, int); 275 static bool arc_function_ok_for_sibcall (tree, tree); 276 static rtx arc_function_value (const_tree, const_tree, bool); 277 const char * output_shift (rtx *); 278 static void arc_reorg (void); 279 static bool arc_in_small_data_p (const_tree); 280 281 static void arc_init_reg_tables (void); 282 static bool arc_return_in_memory (const_tree, const_tree); 283 static bool arc_vector_mode_supported_p (machine_mode); 284 285 static bool arc_can_use_doloop_p (const widest_int &, const widest_int &, 286 unsigned int, bool); 287 static const char *arc_invalid_within_doloop (const rtx_insn *); 288 289 static void output_short_suffix (FILE *file); 290 291 static bool arc_frame_pointer_required (void); 292 293 static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT, 294 unsigned int, 295 enum by_pieces_operation op, 296 bool); 297 298 /* Globally visible information about currently selected cpu. */ 299 const arc_cpu_t *arc_selected_cpu; 300 301 /* Given a symbol RTX (const (symb <+ const_int>), returns its 302 alignment. */ 303 304 static int 305 get_symbol_alignment (rtx x) 306 { 307 tree decl = NULL_TREE; 308 int align = 0; 309 310 switch (GET_CODE (x)) 311 { 312 case SYMBOL_REF: 313 decl = SYMBOL_REF_DECL (x); 314 break; 315 case CONST: 316 return get_symbol_alignment (XEXP (x, 0)); 317 case PLUS: 318 gcc_assert (CONST_INT_P (XEXP (x, 1))); 319 return get_symbol_alignment (XEXP (x, 0)); 320 default: 321 return 0; 322 } 323 324 if (decl) 325 align = DECL_ALIGN (decl); 326 align = align / BITS_PER_UNIT; 327 return align; 328 } 329 330 /* Return true if x is ok to be used as a small data address. */ 331 332 static bool 333 legitimate_small_data_address_p (rtx x) 334 { 335 switch (GET_CODE (x)) 336 { 337 case CONST: 338 return legitimate_small_data_address_p (XEXP (x, 0)); 339 case SYMBOL_REF: 340 return SYMBOL_REF_SMALL_P (x); 341 case PLUS: 342 { 343 bool p0 = (GET_CODE (XEXP (x, 0)) == SYMBOL_REF) 344 && SYMBOL_REF_SMALL_P (XEXP (x, 0)); 345 bool p1 = CONST_INT_P (XEXP (x, 1)) 346 && (INTVAL (XEXP (x, 1)) <= g_switch_value); 347 return p0 && p1; 348 } 349 default: 350 return false; 351 } 352 } 353 354 /* TRUE if op is an scaled address. */ 355 static bool 356 legitimate_scaled_address_p (machine_mode mode, rtx op, bool strict) 357 { 358 if (GET_CODE (op) != PLUS) 359 return false; 360 361 if (GET_CODE (XEXP (op, 0)) != MULT) 362 return false; 363 364 /* Check multiplication operands. */ 365 if (!RTX_OK_FOR_INDEX_P (XEXP (XEXP (op, 0), 0), strict)) 366 return false; 367 368 if (!CONST_INT_P (XEXP (XEXP (op, 0), 1))) 369 return false; 370 371 switch (GET_MODE_SIZE (mode)) 372 { 373 case 2: 374 if (INTVAL (XEXP (XEXP (op, 0), 1)) != 2) 375 return false; 376 break; 377 case 8: 378 if (!TARGET_LL64) 379 return false; 380 /* Fall through. */ 381 case 4: 382 if (INTVAL (XEXP (XEXP (op, 0), 1)) != 4) 383 return false; 384 /* Fall through. */ 385 default: 386 return false; 387 } 388 389 /* Check the base. */ 390 if (RTX_OK_FOR_BASE_P (XEXP (op, 1), (strict))) 391 return true; 392 393 if (flag_pic) 394 { 395 if (CONST_INT_P (XEXP (op, 1))) 396 return true; 397 return false; 398 } 399 400 /* Scalled addresses for sdata is done other places. */ 401 if (legitimate_small_data_address_p (op)) 402 return false; 403 404 if (CONSTANT_P (XEXP (op, 1))) 405 return true; 406 407 return false; 408 } 409 410 /* Check for constructions like REG + OFFS, where OFFS can be a 411 register, an immediate or an long immediate. */ 412 413 static bool 414 legitimate_offset_address_p (machine_mode mode, rtx x, bool index, bool strict) 415 { 416 if (GET_CODE (x) != PLUS) 417 return false; 418 419 if (!RTX_OK_FOR_BASE_P (XEXP (x, 0), (strict))) 420 return false; 421 422 /* Check for: [Rx + small offset] or [Rx + Ry]. */ 423 if (((index && RTX_OK_FOR_INDEX_P (XEXP (x, 1), (strict)) 424 && GET_MODE_SIZE ((mode)) <= 4) 425 || RTX_OK_FOR_OFFSET_P (mode, XEXP (x, 1)))) 426 return true; 427 428 /* Check for [Rx + symbol]. */ 429 if (!flag_pic 430 && (GET_CODE (XEXP (x, 1)) == SYMBOL_REF) 431 /* Avoid this type of address for double or larger modes. */ 432 && (GET_MODE_SIZE (mode) <= 4) 433 /* Avoid small data which ends in something like GP + 434 symb@sda. */ 435 && (!SYMBOL_REF_SMALL_P (XEXP (x, 1)))) 436 return true; 437 438 return false; 439 } 440 441 /* Implements target hook vector_mode_supported_p. */ 442 443 static bool 444 arc_vector_mode_supported_p (machine_mode mode) 445 { 446 switch (mode) 447 { 448 case E_V2HImode: 449 return TARGET_PLUS_DMPY; 450 case E_V4HImode: 451 case E_V2SImode: 452 return TARGET_PLUS_QMACW; 453 case E_V4SImode: 454 case E_V8HImode: 455 return TARGET_SIMD_SET; 456 457 default: 458 return false; 459 } 460 } 461 462 /* Implements target hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */ 463 464 static machine_mode 465 arc_preferred_simd_mode (scalar_mode mode) 466 { 467 switch (mode) 468 { 469 case E_HImode: 470 return TARGET_PLUS_QMACW ? V4HImode : V2HImode; 471 case E_SImode: 472 return V2SImode; 473 474 default: 475 return word_mode; 476 } 477 } 478 479 /* Implements target hook 480 TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES. */ 481 482 static void 483 arc_autovectorize_vector_sizes (vector_sizes *sizes) 484 { 485 if (TARGET_PLUS_QMACW) 486 { 487 sizes->quick_push (8); 488 sizes->quick_push (4); 489 } 490 } 491 492 493 /* Implements target hook TARGET_SCHED_ISSUE_RATE. */ 494 static int 495 arc_sched_issue_rate (void) 496 { 497 switch (arc_tune) 498 { 499 case TUNE_ARCHS4X: 500 case TUNE_ARCHS4XD: 501 return 3; 502 default: 503 break; 504 } 505 return 1; 506 } 507 508 /* TARGET_PRESERVE_RELOAD_P is still awaiting patch re-evaluation / review. */ 509 static bool arc_preserve_reload_p (rtx in) ATTRIBUTE_UNUSED; 510 static rtx arc_delegitimize_address (rtx); 511 static bool arc_can_follow_jump (const rtx_insn *follower, 512 const rtx_insn *followee); 513 514 static rtx frame_insn (rtx); 515 static void arc_function_arg_advance (cumulative_args_t, machine_mode, 516 const_tree, bool); 517 static rtx arc_legitimize_address_0 (rtx, rtx, machine_mode mode); 518 519 /* initialize the GCC target structure. */ 520 #undef TARGET_COMP_TYPE_ATTRIBUTES 521 #define TARGET_COMP_TYPE_ATTRIBUTES arc_comp_type_attributes 522 #undef TARGET_ASM_FILE_START 523 #define TARGET_ASM_FILE_START arc_file_start 524 #undef TARGET_ATTRIBUTE_TABLE 525 #define TARGET_ATTRIBUTE_TABLE arc_attribute_table 526 #undef TARGET_ASM_INTERNAL_LABEL 527 #define TARGET_ASM_INTERNAL_LABEL arc_internal_label 528 #undef TARGET_RTX_COSTS 529 #define TARGET_RTX_COSTS arc_rtx_costs 530 #undef TARGET_ADDRESS_COST 531 #define TARGET_ADDRESS_COST arc_address_cost 532 533 #undef TARGET_ENCODE_SECTION_INFO 534 #define TARGET_ENCODE_SECTION_INFO arc_encode_section_info 535 536 #undef TARGET_CANNOT_FORCE_CONST_MEM 537 #define TARGET_CANNOT_FORCE_CONST_MEM arc_cannot_force_const_mem 538 539 #undef TARGET_INIT_BUILTINS 540 #define TARGET_INIT_BUILTINS arc_init_builtins 541 542 #undef TARGET_EXPAND_BUILTIN 543 #define TARGET_EXPAND_BUILTIN arc_expand_builtin 544 545 #undef TARGET_BUILTIN_DECL 546 #define TARGET_BUILTIN_DECL arc_builtin_decl 547 548 #undef TARGET_ASM_OUTPUT_MI_THUNK 549 #define TARGET_ASM_OUTPUT_MI_THUNK arc_output_mi_thunk 550 551 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK 552 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true 553 554 #undef TARGET_FUNCTION_OK_FOR_SIBCALL 555 #define TARGET_FUNCTION_OK_FOR_SIBCALL arc_function_ok_for_sibcall 556 557 #undef TARGET_MACHINE_DEPENDENT_REORG 558 #define TARGET_MACHINE_DEPENDENT_REORG arc_reorg 559 560 #undef TARGET_IN_SMALL_DATA_P 561 #define TARGET_IN_SMALL_DATA_P arc_in_small_data_p 562 563 #undef TARGET_PROMOTE_FUNCTION_MODE 564 #define TARGET_PROMOTE_FUNCTION_MODE \ 565 default_promote_function_mode_always_promote 566 567 #undef TARGET_PROMOTE_PROTOTYPES 568 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true 569 570 #undef TARGET_RETURN_IN_MEMORY 571 #define TARGET_RETURN_IN_MEMORY arc_return_in_memory 572 #undef TARGET_PASS_BY_REFERENCE 573 #define TARGET_PASS_BY_REFERENCE arc_pass_by_reference 574 575 #undef TARGET_SETUP_INCOMING_VARARGS 576 #define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs 577 578 #undef TARGET_ARG_PARTIAL_BYTES 579 #define TARGET_ARG_PARTIAL_BYTES arc_arg_partial_bytes 580 581 #undef TARGET_MUST_PASS_IN_STACK 582 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size 583 584 #undef TARGET_FUNCTION_VALUE 585 #define TARGET_FUNCTION_VALUE arc_function_value 586 587 #undef TARGET_SCHED_ADJUST_PRIORITY 588 #define TARGET_SCHED_ADJUST_PRIORITY arc_sched_adjust_priority 589 590 #undef TARGET_SCHED_ISSUE_RATE 591 #define TARGET_SCHED_ISSUE_RATE arc_sched_issue_rate 592 593 #undef TARGET_VECTOR_MODE_SUPPORTED_P 594 #define TARGET_VECTOR_MODE_SUPPORTED_P arc_vector_mode_supported_p 595 596 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE 597 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arc_preferred_simd_mode 598 599 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES 600 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES arc_autovectorize_vector_sizes 601 602 #undef TARGET_CAN_USE_DOLOOP_P 603 #define TARGET_CAN_USE_DOLOOP_P arc_can_use_doloop_p 604 605 #undef TARGET_INVALID_WITHIN_DOLOOP 606 #define TARGET_INVALID_WITHIN_DOLOOP arc_invalid_within_doloop 607 608 #undef TARGET_PRESERVE_RELOAD_P 609 #define TARGET_PRESERVE_RELOAD_P arc_preserve_reload_p 610 611 #undef TARGET_CAN_FOLLOW_JUMP 612 #define TARGET_CAN_FOLLOW_JUMP arc_can_follow_jump 613 614 #undef TARGET_DELEGITIMIZE_ADDRESS 615 #define TARGET_DELEGITIMIZE_ADDRESS arc_delegitimize_address 616 617 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P 618 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \ 619 arc_use_by_pieces_infrastructure_p 620 621 /* Usually, we will be able to scale anchor offsets. 622 When this fails, we want LEGITIMIZE_ADDRESS to kick in. */ 623 #undef TARGET_MIN_ANCHOR_OFFSET 624 #define TARGET_MIN_ANCHOR_OFFSET (-1024) 625 #undef TARGET_MAX_ANCHOR_OFFSET 626 #define TARGET_MAX_ANCHOR_OFFSET (1020) 627 628 #undef TARGET_SECONDARY_RELOAD 629 #define TARGET_SECONDARY_RELOAD arc_secondary_reload 630 631 #define TARGET_OPTION_OVERRIDE arc_override_options 632 633 #define TARGET_CONDITIONAL_REGISTER_USAGE arc_conditional_register_usage 634 635 #define TARGET_TRAMPOLINE_INIT arc_initialize_trampoline 636 637 #define TARGET_CAN_ELIMINATE arc_can_eliminate 638 639 #define TARGET_FRAME_POINTER_REQUIRED arc_frame_pointer_required 640 641 #define TARGET_FUNCTION_ARG arc_function_arg 642 643 #define TARGET_FUNCTION_ARG_ADVANCE arc_function_arg_advance 644 645 #define TARGET_LEGITIMATE_CONSTANT_P arc_legitimate_constant_p 646 647 #define TARGET_LEGITIMATE_ADDRESS_P arc_legitimate_address_p 648 649 #define TARGET_MODE_DEPENDENT_ADDRESS_P arc_mode_dependent_address_p 650 651 #define TARGET_LEGITIMIZE_ADDRESS arc_legitimize_address 652 653 #undef TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P 654 #define TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P \ 655 arc_no_speculation_in_delay_slots_p 656 657 #undef TARGET_LRA_P 658 #define TARGET_LRA_P arc_lra_p 659 #define TARGET_REGISTER_PRIORITY arc_register_priority 660 /* Stores with scaled offsets have different displacement ranges. */ 661 #define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P hook_bool_void_true 662 #define TARGET_SPILL_CLASS arc_spill_class 663 664 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS 665 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS arc_allocate_stack_slots_for_args 666 667 #undef TARGET_WARN_FUNC_RETURN 668 #define TARGET_WARN_FUNC_RETURN arc_warn_func_return 669 670 #include "target-def.h" 671 672 #undef TARGET_ASM_ALIGNED_HI_OP 673 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t" 674 #undef TARGET_ASM_ALIGNED_SI_OP 675 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t" 676 677 #ifdef HAVE_AS_TLS 678 #undef TARGET_HAVE_TLS 679 #define TARGET_HAVE_TLS HAVE_AS_TLS 680 #endif 681 682 #undef TARGET_DWARF_REGISTER_SPAN 683 #define TARGET_DWARF_REGISTER_SPAN arc_dwarf_register_span 684 685 #undef TARGET_HARD_REGNO_NREGS 686 #define TARGET_HARD_REGNO_NREGS arc_hard_regno_nregs 687 #undef TARGET_HARD_REGNO_MODE_OK 688 #define TARGET_HARD_REGNO_MODE_OK arc_hard_regno_mode_ok 689 690 #undef TARGET_MODES_TIEABLE_P 691 #define TARGET_MODES_TIEABLE_P arc_modes_tieable_p 692 #undef TARGET_BUILTIN_SETJMP_FRAME_VALUE 693 #define TARGET_BUILTIN_SETJMP_FRAME_VALUE arc_builtin_setjmp_frame_value 694 695 /* Try to keep the (mov:DF _, reg) as early as possible so 696 that the d<add/sub/mul>h-lr insns appear together and can 697 use the peephole2 pattern. */ 698 699 static int 700 arc_sched_adjust_priority (rtx_insn *insn, int priority) 701 { 702 rtx set = single_set (insn); 703 if (set 704 && GET_MODE (SET_SRC(set)) == DFmode 705 && GET_CODE (SET_SRC(set)) == REG) 706 { 707 /* Incrementing priority by 20 (empirically derived). */ 708 return priority + 20; 709 } 710 711 return priority; 712 } 713 714 /* For ARC base register + offset addressing, the validity of the 715 address is mode-dependent for most of the offset range, as the 716 offset can be scaled by the access size. 717 We don't expose these as mode-dependent addresses in the 718 mode_dependent_address_p target hook, because that would disable 719 lots of optimizations, and most uses of these addresses are for 32 720 or 64 bit accesses anyways, which are fine. 721 However, that leaves some addresses for 8 / 16 bit values not 722 properly reloaded by the generic code, which is why we have to 723 schedule secondary reloads for these. */ 724 725 static reg_class_t 726 arc_secondary_reload (bool in_p, 727 rtx x, 728 reg_class_t cl, 729 machine_mode mode, 730 secondary_reload_info *sri) 731 { 732 enum rtx_code code = GET_CODE (x); 733 734 if (cl == DOUBLE_REGS) 735 return GENERAL_REGS; 736 737 /* If we have a subreg (reg), where reg is a pseudo (that will end in 738 a memory location), then we may need a scratch register to handle 739 the fp/sp+largeoffset address. */ 740 if (code == SUBREG) 741 { 742 rtx addr = NULL_RTX; 743 x = SUBREG_REG (x); 744 745 if (REG_P (x)) 746 { 747 int regno = REGNO (x); 748 if (regno >= FIRST_PSEUDO_REGISTER) 749 regno = reg_renumber[regno]; 750 751 if (regno != -1) 752 return NO_REGS; 753 754 /* It is a pseudo that ends in a stack location. This 755 procedure only works with the old reload step. */ 756 if (reg_equiv_mem (REGNO (x)) && !lra_in_progress) 757 { 758 /* Get the equivalent address and check the range of the 759 offset. */ 760 rtx mem = reg_equiv_mem (REGNO (x)); 761 addr = find_replacement (&XEXP (mem, 0)); 762 } 763 } 764 else 765 { 766 gcc_assert (MEM_P (x)); 767 addr = XEXP (x, 0); 768 addr = simplify_rtx (addr); 769 } 770 if (addr && GET_CODE (addr) == PLUS 771 && CONST_INT_P (XEXP (addr, 1)) 772 && (!RTX_OK_FOR_OFFSET_P (mode, XEXP (addr, 1)))) 773 { 774 switch (mode) 775 { 776 case E_QImode: 777 sri->icode = 778 in_p ? CODE_FOR_reload_qi_load : CODE_FOR_reload_qi_store; 779 break; 780 case E_HImode: 781 sri->icode = 782 in_p ? CODE_FOR_reload_hi_load : CODE_FOR_reload_hi_store; 783 break; 784 default: 785 break; 786 } 787 } 788 } 789 return NO_REGS; 790 } 791 792 /* Convert reloads using offsets that are too large to use indirect 793 addressing. */ 794 795 void 796 arc_secondary_reload_conv (rtx reg, rtx mem, rtx scratch, bool store_p) 797 { 798 rtx addr; 799 800 gcc_assert (GET_CODE (mem) == MEM); 801 addr = XEXP (mem, 0); 802 803 /* Large offset: use a move. FIXME: ld ops accepts limms as 804 offsets. Hence, the following move insn is not required. */ 805 emit_move_insn (scratch, addr); 806 mem = replace_equiv_address_nv (mem, scratch); 807 808 /* Now create the move. */ 809 if (store_p) 810 emit_insn (gen_rtx_SET (mem, reg)); 811 else 812 emit_insn (gen_rtx_SET (reg, mem)); 813 814 return; 815 } 816 817 static unsigned arc_ifcvt (void); 818 819 namespace { 820 821 const pass_data pass_data_arc_ifcvt = 822 { 823 RTL_PASS, 824 "arc_ifcvt", /* name */ 825 OPTGROUP_NONE, /* optinfo_flags */ 826 TV_IFCVT2, /* tv_id */ 827 0, /* properties_required */ 828 0, /* properties_provided */ 829 0, /* properties_destroyed */ 830 0, /* todo_flags_start */ 831 TODO_df_finish /* todo_flags_finish */ 832 }; 833 834 class pass_arc_ifcvt : public rtl_opt_pass 835 { 836 public: 837 pass_arc_ifcvt(gcc::context *ctxt) 838 : rtl_opt_pass(pass_data_arc_ifcvt, ctxt) 839 {} 840 841 /* opt_pass methods: */ 842 opt_pass * clone () { return new pass_arc_ifcvt (m_ctxt); } 843 virtual unsigned int execute (function *) { return arc_ifcvt (); } 844 }; 845 846 } // anon namespace 847 848 rtl_opt_pass * 849 make_pass_arc_ifcvt (gcc::context *ctxt) 850 { 851 return new pass_arc_ifcvt (ctxt); 852 } 853 854 static unsigned arc_predicate_delay_insns (void); 855 856 namespace { 857 858 const pass_data pass_data_arc_predicate_delay_insns = 859 { 860 RTL_PASS, 861 "arc_predicate_delay_insns", /* name */ 862 OPTGROUP_NONE, /* optinfo_flags */ 863 TV_IFCVT2, /* tv_id */ 864 0, /* properties_required */ 865 0, /* properties_provided */ 866 0, /* properties_destroyed */ 867 0, /* todo_flags_start */ 868 TODO_df_finish /* todo_flags_finish */ 869 }; 870 871 class pass_arc_predicate_delay_insns : public rtl_opt_pass 872 { 873 public: 874 pass_arc_predicate_delay_insns(gcc::context *ctxt) 875 : rtl_opt_pass(pass_data_arc_predicate_delay_insns, ctxt) 876 {} 877 878 /* opt_pass methods: */ 879 virtual unsigned int execute (function *) 880 { 881 return arc_predicate_delay_insns (); 882 } 883 }; 884 885 } // anon namespace 886 887 rtl_opt_pass * 888 make_pass_arc_predicate_delay_insns (gcc::context *ctxt) 889 { 890 return new pass_arc_predicate_delay_insns (ctxt); 891 } 892 893 /* Called by OVERRIDE_OPTIONS to initialize various things. */ 894 895 static void 896 arc_init (void) 897 { 898 if (TARGET_V2) 899 { 900 /* I have the multiplier, then use it*/ 901 if (TARGET_MPYW || TARGET_MULTI) 902 arc_multcost = COSTS_N_INSNS (1); 903 } 904 /* Note: arc_multcost is only used in rtx_cost if speed is true. */ 905 if (arc_multcost < 0) 906 switch (arc_tune) 907 { 908 case ARC_TUNE_ARC700_4_2_STD: 909 /* latency 7; 910 max throughput (1 multiply + 4 other insns) / 5 cycles. */ 911 arc_multcost = COSTS_N_INSNS (4); 912 if (TARGET_NOMPY_SET) 913 arc_multcost = COSTS_N_INSNS (30); 914 break; 915 case ARC_TUNE_ARC700_4_2_XMAC: 916 /* latency 5; 917 max throughput (1 multiply + 2 other insns) / 3 cycles. */ 918 arc_multcost = COSTS_N_INSNS (3); 919 if (TARGET_NOMPY_SET) 920 arc_multcost = COSTS_N_INSNS (30); 921 break; 922 case ARC_TUNE_ARC600: 923 if (TARGET_MUL64_SET) 924 { 925 arc_multcost = COSTS_N_INSNS (4); 926 break; 927 } 928 /* Fall through. */ 929 default: 930 arc_multcost = COSTS_N_INSNS (30); 931 break; 932 } 933 934 /* MPY instructions valid only for ARC700 or ARCv2. */ 935 if (TARGET_NOMPY_SET && TARGET_ARC600_FAMILY) 936 error ("%<-mno-mpy%> supported only for ARC700 or ARCv2"); 937 938 if (!TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR) 939 error ("%<-mno-dpfp-lrsr%> supported only with %<-mdpfp%>"); 940 941 /* FPX-1. No fast and compact together. */ 942 if ((TARGET_DPFP_FAST_SET && TARGET_DPFP_COMPACT_SET) 943 || (TARGET_SPFP_FAST_SET && TARGET_SPFP_COMPACT_SET)) 944 error ("FPX fast and compact options cannot be specified together"); 945 946 /* FPX-2. No fast-spfp for arc600 or arc601. */ 947 if (TARGET_SPFP_FAST_SET && TARGET_ARC600_FAMILY) 948 error ("%<-mspfp_fast%> not available on ARC600 or ARC601"); 949 950 /* FPX-4. No FPX extensions mixed with FPU extensions. */ 951 if ((TARGET_DPFP_FAST_SET || TARGET_DPFP_COMPACT_SET || TARGET_SPFP) 952 && TARGET_HARD_FLOAT) 953 error ("no FPX/FPU mixing allowed"); 954 955 /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic. */ 956 if (flag_pic && TARGET_ARC600_FAMILY) 957 { 958 warning (0, "PIC is not supported for %qs", 959 arc_cpu_string); 960 flag_pic = 0; 961 } 962 963 arc_init_reg_tables (); 964 965 /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */ 966 memset (arc_punct_chars, 0, sizeof (arc_punct_chars)); 967 arc_punct_chars['#'] = 1; 968 arc_punct_chars['*'] = 1; 969 arc_punct_chars['?'] = 1; 970 arc_punct_chars['!'] = 1; 971 arc_punct_chars['^'] = 1; 972 arc_punct_chars['&'] = 1; 973 arc_punct_chars['+'] = 1; 974 arc_punct_chars['_'] = 1; 975 976 if (optimize > 1 && !TARGET_NO_COND_EXEC) 977 { 978 /* There are two target-independent ifcvt passes, and arc_reorg may do 979 one or more arc_ifcvt calls. */ 980 opt_pass *pass_arc_ifcvt_4 = make_pass_arc_ifcvt (g); 981 struct register_pass_info arc_ifcvt4_info 982 = { pass_arc_ifcvt_4, "dbr", 1, PASS_POS_INSERT_AFTER }; 983 struct register_pass_info arc_ifcvt5_info 984 = { pass_arc_ifcvt_4->clone (), "shorten", 1, PASS_POS_INSERT_BEFORE }; 985 986 register_pass (&arc_ifcvt4_info); 987 register_pass (&arc_ifcvt5_info); 988 } 989 990 if (flag_delayed_branch) 991 { 992 opt_pass *pass_arc_predicate_delay_insns 993 = make_pass_arc_predicate_delay_insns (g); 994 struct register_pass_info arc_predicate_delay_info 995 = { pass_arc_predicate_delay_insns, "dbr", 1, PASS_POS_INSERT_AFTER }; 996 997 register_pass (&arc_predicate_delay_info); 998 } 999 } 1000 1001 /* Parse -mirq-ctrl-saved=RegisterRange, blink, lp_copunt. The 1002 register range is specified as two registers separated by a dash. 1003 It always starts with r0, and its upper limit is fp register. 1004 blink and lp_count registers are optional. */ 1005 1006 static void 1007 irq_range (const char *cstr) 1008 { 1009 int i, first, last, blink, lpcount, xreg; 1010 char *str, *dash, *comma; 1011 1012 i = strlen (cstr); 1013 str = (char *) alloca (i + 1); 1014 memcpy (str, cstr, i + 1); 1015 blink = -1; 1016 lpcount = -1; 1017 1018 dash = strchr (str, '-'); 1019 if (!dash) 1020 { 1021 warning (OPT_mirq_ctrl_saved_, "missing dash"); 1022 return; 1023 } 1024 *dash = '\0'; 1025 1026 comma = strchr (dash + 1, ','); 1027 if (comma) 1028 *comma = '\0'; 1029 1030 first = decode_reg_name (str); 1031 if (first != 0) 1032 { 1033 warning (OPT_mirq_ctrl_saved_, "first register must be R0"); 1034 return; 1035 } 1036 1037 /* At this moment we do not have the register names initialized 1038 accordingly. */ 1039 if (!strcmp (dash + 1, "ilink")) 1040 last = 29; 1041 else 1042 last = decode_reg_name (dash + 1); 1043 1044 if (last < 0) 1045 { 1046 warning (OPT_mirq_ctrl_saved_, "unknown register name: %s", dash + 1); 1047 return; 1048 } 1049 1050 if (!(last & 0x01)) 1051 { 1052 warning (OPT_mirq_ctrl_saved_, 1053 "last register name %s must be an odd register", dash + 1); 1054 return; 1055 } 1056 1057 *dash = '-'; 1058 1059 if (first > last) 1060 { 1061 warning (OPT_mirq_ctrl_saved_, 1062 "%s-%s is an empty range", str, dash + 1); 1063 return; 1064 } 1065 1066 while (comma) 1067 { 1068 *comma = ','; 1069 str = comma + 1; 1070 1071 comma = strchr (str, ','); 1072 if (comma) 1073 *comma = '\0'; 1074 1075 xreg = decode_reg_name (str); 1076 switch (xreg) 1077 { 1078 case 31: 1079 blink = 31; 1080 break; 1081 1082 case 60: 1083 lpcount = 60; 1084 break; 1085 1086 default: 1087 warning (OPT_mirq_ctrl_saved_, 1088 "unknown register name: %s", str); 1089 return; 1090 } 1091 } 1092 1093 irq_ctrl_saved.irq_save_last_reg = last; 1094 irq_ctrl_saved.irq_save_blink = (blink == 31) || (last == 31); 1095 irq_ctrl_saved.irq_save_lpcount = (lpcount == 60); 1096 } 1097 1098 /* Parse -mrgf-banked-regs=NUM option string. Valid values for NUM are 4, 1099 8, 16, or 32. */ 1100 1101 static void 1102 parse_mrgf_banked_regs_option (const char *arg) 1103 { 1104 long int val; 1105 char *end_ptr; 1106 1107 errno = 0; 1108 val = strtol (arg, &end_ptr, 10); 1109 if (errno != 0 || *arg == '\0' || *end_ptr != '\0' 1110 || (val != 0 && val != 4 && val != 8 && val != 16 && val != 32)) 1111 { 1112 error ("invalid number in %<-mrgf-banked-regs=%s%> " 1113 "valid values are 0, 4, 8, 16, or 32", arg); 1114 return; 1115 } 1116 rgf_banked_register_count = (int) val; 1117 } 1118 1119 /* Check ARC options, generate derived target attributes. */ 1120 1121 static void 1122 arc_override_options (void) 1123 { 1124 unsigned int i; 1125 cl_deferred_option *opt; 1126 vec<cl_deferred_option> *vopt 1127 = (vec<cl_deferred_option> *) arc_deferred_options; 1128 1129 if (arc_cpu == PROCESSOR_NONE) 1130 arc_cpu = TARGET_CPU_DEFAULT; 1131 1132 /* Set the default cpu options. */ 1133 arc_selected_cpu = &arc_cpu_types[(int) arc_cpu]; 1134 1135 /* Set the architectures. */ 1136 switch (arc_selected_cpu->arch_info->arch_id) 1137 { 1138 case BASE_ARCH_em: 1139 arc_cpu_string = "EM"; 1140 break; 1141 case BASE_ARCH_hs: 1142 arc_cpu_string = "HS"; 1143 break; 1144 case BASE_ARCH_700: 1145 if (arc_selected_cpu->processor == PROCESSOR_nps400) 1146 arc_cpu_string = "NPS400"; 1147 else 1148 arc_cpu_string = "ARC700"; 1149 break; 1150 case BASE_ARCH_6xx: 1151 arc_cpu_string = "ARC600"; 1152 break; 1153 default: 1154 gcc_unreachable (); 1155 } 1156 1157 irq_ctrl_saved.irq_save_last_reg = -1; 1158 irq_ctrl_saved.irq_save_blink = false; 1159 irq_ctrl_saved.irq_save_lpcount = false; 1160 1161 rgf_banked_register_count = 0; 1162 1163 /* Handle the deferred options. */ 1164 if (vopt) 1165 FOR_EACH_VEC_ELT (*vopt, i, opt) 1166 { 1167 switch (opt->opt_index) 1168 { 1169 case OPT_mirq_ctrl_saved_: 1170 if (TARGET_V2) 1171 irq_range (opt->arg); 1172 else 1173 warning (OPT_mirq_ctrl_saved_, 1174 "option %<-mirq-ctrl-saved%> valid only " 1175 "for ARC v2 processors"); 1176 break; 1177 1178 case OPT_mrgf_banked_regs_: 1179 if (TARGET_V2) 1180 parse_mrgf_banked_regs_option (opt->arg); 1181 else 1182 warning (OPT_mrgf_banked_regs_, 1183 "option %<-mrgf-banked-regs%> valid only for " 1184 "ARC v2 processors"); 1185 break; 1186 1187 default: 1188 gcc_unreachable(); 1189 } 1190 } 1191 1192 CLEAR_HARD_REG_SET (overrideregs); 1193 if (common_deferred_options) 1194 { 1195 vec<cl_deferred_option> v = 1196 *((vec<cl_deferred_option> *) common_deferred_options); 1197 int reg, nregs, j; 1198 1199 FOR_EACH_VEC_ELT (v, i, opt) 1200 { 1201 switch (opt->opt_index) 1202 { 1203 case OPT_ffixed_: 1204 case OPT_fcall_used_: 1205 case OPT_fcall_saved_: 1206 if ((reg = decode_reg_name_and_count (opt->arg, &nregs)) >= 0) 1207 for (j = reg; j < reg + nregs; j++) 1208 SET_HARD_REG_BIT (overrideregs, j); 1209 break; 1210 default: 1211 break; 1212 } 1213 } 1214 } 1215 1216 /* Check options against architecture options. Throw an error if 1217 option is not allowed. Extra, check options against default 1218 architecture/cpu flags and throw an warning if we find a 1219 mismatch. */ 1220 /* TRANSLATORS: the DOC/DOC0/DOC1 are strings which shouldn't be 1221 translated. They are like keywords which one can relate with the 1222 architectural choices taken for an ARC CPU implementation. */ 1223 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC0, DOC1) \ 1224 do { \ 1225 if ((!(arc_selected_cpu->arch_info->flags & CODE)) \ 1226 && (VAR == VAL)) \ 1227 error ("option %<%s=%s%> is not available for %qs CPU", \ 1228 DOC0, DOC1, arc_selected_cpu->name); \ 1229 if ((arc_selected_cpu->arch_info->dflags & CODE) \ 1230 && (VAR != DEFAULT_##VAR) \ 1231 && (VAR != VAL)) \ 1232 warning (0, "option %qs is ignored, the default value %qs" \ 1233 " is considered for %qs CPU", DOC0, DOC1, \ 1234 arc_selected_cpu->name); \ 1235 } while (0); 1236 #define ARC_OPT(NAME, CODE, MASK, DOC) \ 1237 do { \ 1238 if ((!(arc_selected_cpu->arch_info->flags & CODE)) \ 1239 && (target_flags & MASK)) \ 1240 error ("option %qs is not available for %qs CPU", \ 1241 DOC, arc_selected_cpu->name); \ 1242 if ((arc_selected_cpu->arch_info->dflags & CODE) \ 1243 && (target_flags_explicit & MASK) \ 1244 && (!(target_flags & MASK))) \ 1245 warning (0, "unset option %qs is ignored, it is always" \ 1246 " enabled for %qs CPU", DOC, \ 1247 arc_selected_cpu->name); \ 1248 } while (0); 1249 1250 #include "arc-options.def" 1251 1252 #undef ARC_OPTX 1253 #undef ARC_OPT 1254 1255 /* Set cpu flags accordingly to architecture/selected cpu. The cpu 1256 specific flags are set in arc-common.c. The architecture forces 1257 the default hardware configurations in, regardless what command 1258 line options are saying. The CPU optional hw options can be 1259 turned on or off. */ 1260 #define ARC_OPT(NAME, CODE, MASK, DOC) \ 1261 do { \ 1262 if ((arc_selected_cpu->flags & CODE) \ 1263 && ((target_flags_explicit & MASK) == 0)) \ 1264 target_flags |= MASK; \ 1265 if (arc_selected_cpu->arch_info->dflags & CODE) \ 1266 target_flags |= MASK; \ 1267 } while (0); 1268 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC0, DOC1) \ 1269 do { \ 1270 if ((arc_selected_cpu->flags & CODE) \ 1271 && (VAR == DEFAULT_##VAR)) \ 1272 VAR = VAL; \ 1273 if (arc_selected_cpu->arch_info->dflags & CODE) \ 1274 VAR = VAL; \ 1275 } while (0); 1276 1277 #include "arc-options.def" 1278 1279 #undef ARC_OPTX 1280 #undef ARC_OPT 1281 1282 /* Set extras. */ 1283 switch (arc_selected_cpu->extra) 1284 { 1285 case HAS_LPCOUNT_16: 1286 arc_lpcwidth = 16; 1287 break; 1288 default: 1289 break; 1290 } 1291 1292 /* Set Tune option. */ 1293 if (arc_tune == ARC_TUNE_NONE) 1294 arc_tune = (enum arc_tune_attr) arc_selected_cpu->tune; 1295 1296 if (arc_size_opt_level == 3) 1297 optimize_size = 1; 1298 1299 if (TARGET_V2 && optimize_size && (ATTRIBUTE_PCS == 2)) 1300 TARGET_CODE_DENSITY_FRAME = 1; 1301 1302 if (flag_pic) 1303 target_flags |= MASK_NO_SDATA_SET; 1304 1305 if (flag_no_common == 255) 1306 flag_no_common = !TARGET_NO_SDATA_SET; 1307 1308 if (TARGET_MIXED_CODE) 1309 TARGET_Q_CLASS = 1; 1310 1311 /* Check for small data option */ 1312 if (!global_options_set.x_g_switch_value && !TARGET_NO_SDATA_SET) 1313 g_switch_value = TARGET_LL64 ? 8 : 4; 1314 1315 /* A7 has an issue with delay slots. */ 1316 if (TARGET_ARC700 && (arc_tune != ARC_TUNE_ARC7XX)) 1317 flag_delayed_branch = 0; 1318 1319 /* Millicode thunks doesn't work with long calls. */ 1320 if (TARGET_LONG_CALLS_SET) 1321 target_flags &= ~MASK_MILLICODE_THUNK_SET; 1322 1323 /* Set unaligned to all HS cpus. */ 1324 if (!global_options_set.x_unaligned_access && TARGET_HS) 1325 unaligned_access = 1; 1326 1327 /* These need to be done at start up. It's convenient to do them here. */ 1328 arc_init (); 1329 } 1330 1331 /* The condition codes of the ARC, and the inverse function. */ 1332 /* For short branches, the "c" / "nc" names are not defined in the ARC 1333 Programmers manual, so we have to use "lo" / "hs"" instead. */ 1334 static const char *arc_condition_codes[] = 1335 { 1336 "al", 0, "eq", "ne", "p", "n", "lo", "hs", "v", "nv", 1337 "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0 1338 }; 1339 1340 enum arc_cc_code_index 1341 { 1342 ARC_CC_AL, ARC_CC_EQ = ARC_CC_AL+2, ARC_CC_NE, ARC_CC_P, ARC_CC_N, 1343 ARC_CC_C, ARC_CC_NC, ARC_CC_V, ARC_CC_NV, 1344 ARC_CC_GT, ARC_CC_LE, ARC_CC_GE, ARC_CC_LT, ARC_CC_HI, ARC_CC_LS, ARC_CC_PNZ, 1345 ARC_CC_LO = ARC_CC_C, ARC_CC_HS = ARC_CC_NC 1346 }; 1347 1348 #define ARC_INVERSE_CONDITION_CODE(X) ((X) ^ 1) 1349 1350 /* Returns the index of the ARC condition code string in 1351 `arc_condition_codes'. COMPARISON should be an rtx like 1352 `(eq (...) (...))'. */ 1353 1354 static int 1355 get_arc_condition_code (rtx comparison) 1356 { 1357 switch (GET_MODE (XEXP (comparison, 0))) 1358 { 1359 case E_CCmode: 1360 case E_SImode: /* For BRcc. */ 1361 switch (GET_CODE (comparison)) 1362 { 1363 case EQ : return ARC_CC_EQ; 1364 case NE : return ARC_CC_NE; 1365 case GT : return ARC_CC_GT; 1366 case LE : return ARC_CC_LE; 1367 case GE : return ARC_CC_GE; 1368 case LT : return ARC_CC_LT; 1369 case GTU : return ARC_CC_HI; 1370 case LEU : return ARC_CC_LS; 1371 case LTU : return ARC_CC_LO; 1372 case GEU : return ARC_CC_HS; 1373 default : gcc_unreachable (); 1374 } 1375 case E_CC_ZNmode: 1376 switch (GET_CODE (comparison)) 1377 { 1378 case EQ : return ARC_CC_EQ; 1379 case NE : return ARC_CC_NE; 1380 case GE: return ARC_CC_P; 1381 case LT: return ARC_CC_N; 1382 case GT : return ARC_CC_PNZ; 1383 default : gcc_unreachable (); 1384 } 1385 case E_CC_Zmode: 1386 switch (GET_CODE (comparison)) 1387 { 1388 case EQ : return ARC_CC_EQ; 1389 case NE : return ARC_CC_NE; 1390 default : gcc_unreachable (); 1391 } 1392 case E_CC_Cmode: 1393 switch (GET_CODE (comparison)) 1394 { 1395 case LTU : return ARC_CC_C; 1396 case GEU : return ARC_CC_NC; 1397 default : gcc_unreachable (); 1398 } 1399 case E_CC_FP_GTmode: 1400 if (TARGET_ARGONAUT_SET && TARGET_SPFP) 1401 switch (GET_CODE (comparison)) 1402 { 1403 case GT : return ARC_CC_N; 1404 case UNLE: return ARC_CC_P; 1405 default : gcc_unreachable (); 1406 } 1407 else 1408 switch (GET_CODE (comparison)) 1409 { 1410 case GT : return ARC_CC_HI; 1411 case UNLE : return ARC_CC_LS; 1412 default : gcc_unreachable (); 1413 } 1414 case E_CC_FP_GEmode: 1415 /* Same for FPX and non-FPX. */ 1416 switch (GET_CODE (comparison)) 1417 { 1418 case GE : return ARC_CC_HS; 1419 case UNLT : return ARC_CC_LO; 1420 default : gcc_unreachable (); 1421 } 1422 case E_CC_FP_UNEQmode: 1423 switch (GET_CODE (comparison)) 1424 { 1425 case UNEQ : return ARC_CC_EQ; 1426 case LTGT : return ARC_CC_NE; 1427 default : gcc_unreachable (); 1428 } 1429 case E_CC_FP_ORDmode: 1430 switch (GET_CODE (comparison)) 1431 { 1432 case UNORDERED : return ARC_CC_C; 1433 case ORDERED : return ARC_CC_NC; 1434 default : gcc_unreachable (); 1435 } 1436 case E_CC_FPXmode: 1437 switch (GET_CODE (comparison)) 1438 { 1439 case EQ : return ARC_CC_EQ; 1440 case NE : return ARC_CC_NE; 1441 case UNORDERED : return ARC_CC_C; 1442 case ORDERED : return ARC_CC_NC; 1443 case LTGT : return ARC_CC_HI; 1444 case UNEQ : return ARC_CC_LS; 1445 default : gcc_unreachable (); 1446 } 1447 case E_CC_FPUmode: 1448 case E_CC_FPUEmode: 1449 switch (GET_CODE (comparison)) 1450 { 1451 case EQ : return ARC_CC_EQ; 1452 case NE : return ARC_CC_NE; 1453 case GT : return ARC_CC_GT; 1454 case GE : return ARC_CC_GE; 1455 case LT : return ARC_CC_C; 1456 case LE : return ARC_CC_LS; 1457 case UNORDERED : return ARC_CC_V; 1458 case ORDERED : return ARC_CC_NV; 1459 case UNGT : return ARC_CC_HI; 1460 case UNGE : return ARC_CC_HS; 1461 case UNLT : return ARC_CC_LT; 1462 case UNLE : return ARC_CC_LE; 1463 /* UNEQ and LTGT do not have representation. */ 1464 case LTGT : /* Fall through. */ 1465 case UNEQ : /* Fall through. */ 1466 default : gcc_unreachable (); 1467 } 1468 case E_CC_FPU_UNEQmode: 1469 switch (GET_CODE (comparison)) 1470 { 1471 case LTGT : return ARC_CC_NE; 1472 case UNEQ : return ARC_CC_EQ; 1473 default : gcc_unreachable (); 1474 } 1475 default : gcc_unreachable (); 1476 } 1477 /*NOTREACHED*/ 1478 return (42); 1479 } 1480 1481 /* Return true if COMPARISON has a short form that can accomodate OFFSET. */ 1482 1483 bool 1484 arc_short_comparison_p (rtx comparison, int offset) 1485 { 1486 gcc_assert (ARC_CC_NC == ARC_CC_HS); 1487 gcc_assert (ARC_CC_C == ARC_CC_LO); 1488 switch (get_arc_condition_code (comparison)) 1489 { 1490 case ARC_CC_EQ: case ARC_CC_NE: 1491 return offset >= -512 && offset <= 506; 1492 case ARC_CC_GT: case ARC_CC_LE: case ARC_CC_GE: case ARC_CC_LT: 1493 case ARC_CC_HI: case ARC_CC_LS: case ARC_CC_LO: case ARC_CC_HS: 1494 return offset >= -64 && offset <= 58; 1495 default: 1496 return false; 1497 } 1498 } 1499 1500 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE, 1501 return the mode to be used for the comparison. */ 1502 1503 machine_mode 1504 arc_select_cc_mode (enum rtx_code op, rtx x, rtx y) 1505 { 1506 machine_mode mode = GET_MODE (x); 1507 rtx x1; 1508 1509 /* For an operation that sets the condition codes as a side-effect, the 1510 C and V flags is not set as for cmp, so we can only use comparisons where 1511 this doesn't matter. (For LT and GE we can use "mi" and "pl" 1512 instead.) */ 1513 /* ??? We could use "pnz" for greater than zero, however, we could then 1514 get into trouble because the comparison could not be reversed. */ 1515 if (GET_MODE_CLASS (mode) == MODE_INT 1516 && y == const0_rtx 1517 && (op == EQ || op == NE 1518 || ((op == LT || op == GE) && GET_MODE_SIZE (GET_MODE (x)) <= 4))) 1519 return CC_ZNmode; 1520 1521 /* add.f for if (a+b) */ 1522 if (mode == SImode 1523 && GET_CODE (y) == NEG 1524 && (op == EQ || op == NE)) 1525 return CC_ZNmode; 1526 1527 /* Check if this is a test suitable for bxor.f . */ 1528 if (mode == SImode && (op == EQ || op == NE) && CONST_INT_P (y) 1529 && ((INTVAL (y) - 1) & INTVAL (y)) == 0 1530 && INTVAL (y)) 1531 return CC_Zmode; 1532 1533 /* Check if this is a test suitable for add / bmsk.f . */ 1534 if (mode == SImode && (op == EQ || op == NE) && CONST_INT_P (y) 1535 && GET_CODE (x) == AND && CONST_INT_P ((x1 = XEXP (x, 1))) 1536 && ((INTVAL (x1) + 1) & INTVAL (x1)) == 0 1537 && (~INTVAL (x1) | INTVAL (y)) < 0 1538 && (~INTVAL (x1) | INTVAL (y)) > -0x800) 1539 return CC_Zmode; 1540 1541 if (GET_MODE (x) == SImode && (op == LTU || op == GEU) 1542 && GET_CODE (x) == PLUS 1543 && (rtx_equal_p (XEXP (x, 0), y) || rtx_equal_p (XEXP (x, 1), y))) 1544 return CC_Cmode; 1545 1546 if (TARGET_ARGONAUT_SET 1547 && ((mode == SFmode && TARGET_SPFP) || (mode == DFmode && TARGET_DPFP))) 1548 switch (op) 1549 { 1550 case EQ: case NE: case UNEQ: case LTGT: case ORDERED: case UNORDERED: 1551 return CC_FPXmode; 1552 case LT: case UNGE: case GT: case UNLE: 1553 return CC_FP_GTmode; 1554 case LE: case UNGT: case GE: case UNLT: 1555 return CC_FP_GEmode; 1556 default: gcc_unreachable (); 1557 } 1558 else if (TARGET_HARD_FLOAT 1559 && ((mode == SFmode && TARGET_FP_SP_BASE) 1560 || (mode == DFmode && TARGET_FP_DP_BASE))) 1561 switch (op) 1562 { 1563 case EQ: 1564 case NE: 1565 case UNORDERED: 1566 case ORDERED: 1567 case UNLT: 1568 case UNLE: 1569 case UNGT: 1570 case UNGE: 1571 return CC_FPUmode; 1572 1573 case LT: 1574 case LE: 1575 case GT: 1576 case GE: 1577 return CC_FPUEmode; 1578 1579 case LTGT: 1580 case UNEQ: 1581 return CC_FPU_UNEQmode; 1582 1583 default: 1584 gcc_unreachable (); 1585 } 1586 else if (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_OPTFPE) 1587 { 1588 switch (op) 1589 { 1590 case EQ: case NE: return CC_Zmode; 1591 case LT: case UNGE: 1592 case GT: case UNLE: return CC_FP_GTmode; 1593 case LE: case UNGT: 1594 case GE: case UNLT: return CC_FP_GEmode; 1595 case UNEQ: case LTGT: return CC_FP_UNEQmode; 1596 case ORDERED: case UNORDERED: return CC_FP_ORDmode; 1597 default: gcc_unreachable (); 1598 } 1599 } 1600 return CCmode; 1601 } 1602 1603 /* Vectors to keep interesting information about registers where it can easily 1604 be got. We use to use the actual mode value as the bit number, but there 1605 is (or may be) more than 32 modes now. Instead we use two tables: one 1606 indexed by hard register number, and one indexed by mode. */ 1607 1608 /* The purpose of arc_mode_class is to shrink the range of modes so that 1609 they all fit (as bit numbers) in a 32-bit word (again). Each real mode is 1610 mapped into one arc_mode_class mode. */ 1611 1612 enum arc_mode_class { 1613 C_MODE, 1614 S_MODE, D_MODE, T_MODE, O_MODE, 1615 SF_MODE, DF_MODE, TF_MODE, OF_MODE, 1616 V_MODE 1617 }; 1618 1619 /* Modes for condition codes. */ 1620 #define C_MODES (1 << (int) C_MODE) 1621 1622 /* Modes for single-word and smaller quantities. */ 1623 #define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE)) 1624 1625 /* Modes for double-word and smaller quantities. */ 1626 #define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE)) 1627 1628 /* Mode for 8-byte DF values only. */ 1629 #define DF_MODES (1 << DF_MODE) 1630 1631 /* Modes for quad-word and smaller quantities. */ 1632 #define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE)) 1633 1634 /* Modes for 128-bit vectors. */ 1635 #define V_MODES (1 << (int) V_MODE) 1636 1637 /* Value is 1 if register/mode pair is acceptable on arc. */ 1638 1639 static unsigned int arc_hard_regno_modes[] = { 1640 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, 1641 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, 1642 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, D_MODES, 1643 D_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, 1644 1645 /* ??? Leave these as S_MODES for now. */ 1646 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, 1647 DF_MODES, 0, DF_MODES, 0, S_MODES, S_MODES, S_MODES, S_MODES, 1648 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, 1649 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, C_MODES, S_MODES, 1650 1651 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, 1652 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, 1653 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, 1654 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, 1655 1656 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, 1657 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, 1658 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, 1659 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, 1660 1661 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, 1662 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, 1663 S_MODES, S_MODES 1664 }; 1665 1666 static unsigned int arc_mode_class [NUM_MACHINE_MODES]; 1667 1668 enum reg_class arc_regno_reg_class[FIRST_PSEUDO_REGISTER]; 1669 1670 enum reg_class 1671 arc_preferred_reload_class (rtx, enum reg_class cl) 1672 { 1673 return cl; 1674 } 1675 1676 /* Initialize the arc_mode_class array. */ 1677 1678 static void 1679 arc_init_reg_tables (void) 1680 { 1681 int i; 1682 1683 for (i = 0; i < NUM_MACHINE_MODES; i++) 1684 { 1685 machine_mode m = (machine_mode) i; 1686 1687 switch (GET_MODE_CLASS (m)) 1688 { 1689 case MODE_INT: 1690 case MODE_PARTIAL_INT: 1691 case MODE_COMPLEX_INT: 1692 if (GET_MODE_SIZE (m) <= 4) 1693 arc_mode_class[i] = 1 << (int) S_MODE; 1694 else if (GET_MODE_SIZE (m) == 8) 1695 arc_mode_class[i] = 1 << (int) D_MODE; 1696 else if (GET_MODE_SIZE (m) == 16) 1697 arc_mode_class[i] = 1 << (int) T_MODE; 1698 else if (GET_MODE_SIZE (m) == 32) 1699 arc_mode_class[i] = 1 << (int) O_MODE; 1700 else 1701 arc_mode_class[i] = 0; 1702 break; 1703 case MODE_FLOAT: 1704 case MODE_COMPLEX_FLOAT: 1705 if (GET_MODE_SIZE (m) <= 4) 1706 arc_mode_class[i] = 1 << (int) SF_MODE; 1707 else if (GET_MODE_SIZE (m) == 8) 1708 arc_mode_class[i] = 1 << (int) DF_MODE; 1709 else if (GET_MODE_SIZE (m) == 16) 1710 arc_mode_class[i] = 1 << (int) TF_MODE; 1711 else if (GET_MODE_SIZE (m) == 32) 1712 arc_mode_class[i] = 1 << (int) OF_MODE; 1713 else 1714 arc_mode_class[i] = 0; 1715 break; 1716 case MODE_VECTOR_INT: 1717 if (GET_MODE_SIZE (m) == 4) 1718 arc_mode_class[i] = (1 << (int) S_MODE); 1719 else if (GET_MODE_SIZE (m) == 8) 1720 arc_mode_class[i] = (1 << (int) D_MODE); 1721 else 1722 arc_mode_class[i] = (1 << (int) V_MODE); 1723 break; 1724 case MODE_CC: 1725 default: 1726 /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so 1727 we must explicitly check for them here. */ 1728 if (i == (int) CCmode || i == (int) CC_ZNmode || i == (int) CC_Zmode 1729 || i == (int) CC_Cmode 1730 || i == CC_FP_GTmode || i == CC_FP_GEmode || i == CC_FP_ORDmode 1731 || i == CC_FPUmode || i == CC_FPUEmode || i == CC_FPU_UNEQmode) 1732 arc_mode_class[i] = 1 << (int) C_MODE; 1733 else 1734 arc_mode_class[i] = 0; 1735 break; 1736 } 1737 } 1738 } 1739 1740 /* Core registers 56..59 are used for multiply extension options. 1741 The dsp option uses r56 and r57, these are then named acc1 and acc2. 1742 acc1 is the highpart, and acc2 the lowpart, so which register gets which 1743 number depends on endianness. 1744 The mul64 multiplier options use r57 for mlo, r58 for mmid and r59 for mhi. 1745 Because mlo / mhi form a 64 bit value, we use different gcc internal 1746 register numbers to make them form a register pair as the gcc internals 1747 know it. mmid gets number 57, if still available, and mlo / mhi get 1748 number 58 and 59, depending on endianness. We use DBX_REGISTER_NUMBER 1749 to map this back. */ 1750 char rname56[5] = "r56"; 1751 char rname57[5] = "r57"; 1752 char rname58[5] = "r58"; 1753 char rname59[5] = "r59"; 1754 char rname29[7] = "ilink1"; 1755 char rname30[7] = "ilink2"; 1756 1757 static void 1758 arc_conditional_register_usage (void) 1759 { 1760 int regno; 1761 int i; 1762 int fix_start = 60, fix_end = 55; 1763 1764 if (TARGET_V2) 1765 { 1766 /* For ARCv2 the core register set is changed. */ 1767 strcpy (rname29, "ilink"); 1768 strcpy (rname30, "r30"); 1769 1770 if (!TEST_HARD_REG_BIT (overrideregs, R30_REG)) 1771 { 1772 /* No user interference. Set the r30 to be used by the 1773 compiler. */ 1774 call_used_regs[R30_REG] = 1; 1775 fixed_regs[R30_REG] = 0; 1776 1777 arc_regno_reg_class[R30_REG] = GENERAL_REGS; 1778 } 1779 } 1780 1781 if (TARGET_MUL64_SET) 1782 { 1783 fix_start = R57_REG; 1784 fix_end = R59_REG; 1785 1786 /* We don't provide a name for mmed. In rtl / assembly resource lists, 1787 you are supposed to refer to it as mlo & mhi, e.g 1788 (zero_extract:SI (reg:DI 58) (const_int 32) (16)) . 1789 In an actual asm instruction, you are of course use mmed. 1790 The point of avoiding having a separate register for mmed is that 1791 this way, we don't have to carry clobbers of that reg around in every 1792 isntruction that modifies mlo and/or mhi. */ 1793 strcpy (rname57, ""); 1794 strcpy (rname58, TARGET_BIG_ENDIAN ? "mhi" : "mlo"); 1795 strcpy (rname59, TARGET_BIG_ENDIAN ? "mlo" : "mhi"); 1796 } 1797 1798 /* The nature of arc_tp_regno is actually something more like a global 1799 register, however globalize_reg requires a declaration. 1800 We use EPILOGUE_USES to compensate so that sets from 1801 __builtin_set_frame_pointer are not deleted. */ 1802 if (arc_tp_regno != -1) 1803 fixed_regs[arc_tp_regno] = call_used_regs[arc_tp_regno] = 1; 1804 1805 if (TARGET_MULMAC_32BY16_SET) 1806 { 1807 fix_start = MUL32x16_REG; 1808 fix_end = fix_end > R57_REG ? fix_end : R57_REG; 1809 strcpy (rname56, TARGET_BIG_ENDIAN ? "acc1" : "acc2"); 1810 strcpy (rname57, TARGET_BIG_ENDIAN ? "acc2" : "acc1"); 1811 } 1812 for (regno = fix_start; regno <= fix_end; regno++) 1813 { 1814 if (!fixed_regs[regno]) 1815 warning (0, "multiply option implies r%d is fixed", regno); 1816 fixed_regs [regno] = call_used_regs[regno] = 1; 1817 } 1818 1819 /* Reduced configuration: don't use r4-r9, r16-r25. */ 1820 if (TARGET_RF16) 1821 { 1822 for (i = R4_REG; i <= R9_REG; i++) 1823 fixed_regs[i] = call_used_regs[i] = 1; 1824 for (i = R16_REG; i <= R25_REG; i++) 1825 fixed_regs[i] = call_used_regs[i] = 1; 1826 } 1827 1828 /* ARCHS has 64-bit data-path which makes use of the even-odd paired 1829 registers. */ 1830 if (TARGET_HS) 1831 for (regno = R1_REG; regno < R32_REG; regno +=2) 1832 arc_hard_regno_modes[regno] = S_MODES; 1833 1834 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 1835 if (i < ILINK1_REG) 1836 { 1837 if ((TARGET_Q_CLASS || TARGET_RRQ_CLASS) 1838 && ((i <= R3_REG) || ((i >= R12_REG) && (i <= R15_REG)))) 1839 arc_regno_reg_class[i] = ARCOMPACT16_REGS; 1840 else 1841 arc_regno_reg_class[i] = GENERAL_REGS; 1842 } 1843 else if (i < LP_COUNT) 1844 arc_regno_reg_class[i] = GENERAL_REGS; 1845 else 1846 arc_regno_reg_class[i] = NO_REGS; 1847 1848 /* Handle Special Registers. */ 1849 arc_regno_reg_class[CC_REG] = NO_REGS; /* CC_REG: must be NO_REGS. */ 1850 arc_regno_reg_class[FRAME_POINTER_REGNUM] = GENERAL_REGS; 1851 arc_regno_reg_class[ARG_POINTER_REGNUM] = GENERAL_REGS; 1852 1853 if (TARGET_DPFP) 1854 for (i = R40_REG; i < R44_REG; ++i) 1855 { 1856 arc_regno_reg_class[i] = DOUBLE_REGS; 1857 if (!TARGET_ARGONAUT_SET) 1858 CLEAR_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], i); 1859 } 1860 else 1861 { 1862 /* Disable all DOUBLE_REGISTER settings, if not generating DPFP 1863 code. */ 1864 arc_regno_reg_class[R40_REG] = ALL_REGS; 1865 arc_regno_reg_class[R41_REG] = ALL_REGS; 1866 arc_regno_reg_class[R42_REG] = ALL_REGS; 1867 arc_regno_reg_class[R43_REG] = ALL_REGS; 1868 1869 fixed_regs[R40_REG] = 1; 1870 fixed_regs[R41_REG] = 1; 1871 fixed_regs[R42_REG] = 1; 1872 fixed_regs[R43_REG] = 1; 1873 1874 arc_hard_regno_modes[R40_REG] = 0; 1875 arc_hard_regno_modes[R42_REG] = 0; 1876 } 1877 1878 if (TARGET_SIMD_SET) 1879 { 1880 gcc_assert (ARC_FIRST_SIMD_VR_REG == 64); 1881 gcc_assert (ARC_LAST_SIMD_VR_REG == 127); 1882 1883 for (i = ARC_FIRST_SIMD_VR_REG; i <= ARC_LAST_SIMD_VR_REG; i++) 1884 arc_regno_reg_class [i] = SIMD_VR_REGS; 1885 1886 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_REG == 128); 1887 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_IN_REG == 128); 1888 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG == 136); 1889 gcc_assert (ARC_LAST_SIMD_DMA_CONFIG_REG == 143); 1890 1891 for (i = ARC_FIRST_SIMD_DMA_CONFIG_REG; 1892 i <= ARC_LAST_SIMD_DMA_CONFIG_REG; i++) 1893 arc_regno_reg_class [i] = SIMD_DMA_CONFIG_REGS; 1894 } 1895 1896 /* pc : r63 */ 1897 arc_regno_reg_class[PCL_REG] = NO_REGS; 1898 1899 /*ARCV2 Accumulator. */ 1900 if ((TARGET_V2 1901 && (TARGET_FP_DP_FUSED || TARGET_FP_SP_FUSED)) 1902 || TARGET_PLUS_DMPY) 1903 { 1904 arc_regno_reg_class[ACCL_REGNO] = GENERAL_REGS; 1905 arc_regno_reg_class[ACCH_REGNO] = GENERAL_REGS; 1906 1907 /* Allow the compiler to freely use them. */ 1908 if (!TEST_HARD_REG_BIT (overrideregs, ACCL_REGNO)) 1909 fixed_regs[ACCL_REGNO] = 0; 1910 if (!TEST_HARD_REG_BIT (overrideregs, ACCH_REGNO)) 1911 fixed_regs[ACCH_REGNO] = 0; 1912 1913 if (!fixed_regs[ACCH_REGNO] && !fixed_regs[ACCL_REGNO]) 1914 arc_hard_regno_modes[ACC_REG_FIRST] = D_MODES; 1915 } 1916 } 1917 1918 /* Implement TARGET_HARD_REGNO_NREGS. */ 1919 1920 static unsigned int 1921 arc_hard_regno_nregs (unsigned int regno, machine_mode mode) 1922 { 1923 if (GET_MODE_SIZE (mode) == 16 1924 && regno >= ARC_FIRST_SIMD_VR_REG 1925 && regno <= ARC_LAST_SIMD_VR_REG) 1926 return 1; 1927 1928 return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD); 1929 } 1930 1931 /* Implement TARGET_HARD_REGNO_MODE_OK. */ 1932 1933 static bool 1934 arc_hard_regno_mode_ok (unsigned int regno, machine_mode mode) 1935 { 1936 return (arc_hard_regno_modes[regno] & arc_mode_class[mode]) != 0; 1937 } 1938 1939 /* Implement TARGET_MODES_TIEABLE_P. Tie QI/HI/SI modes together. */ 1940 1941 static bool 1942 arc_modes_tieable_p (machine_mode mode1, machine_mode mode2) 1943 { 1944 return (GET_MODE_CLASS (mode1) == MODE_INT 1945 && GET_MODE_CLASS (mode2) == MODE_INT 1946 && GET_MODE_SIZE (mode1) <= UNITS_PER_WORD 1947 && GET_MODE_SIZE (mode2) <= UNITS_PER_WORD); 1948 } 1949 1950 /* Handle an "interrupt" attribute; arguments as in 1951 struct attribute_spec.handler. */ 1952 1953 static tree 1954 arc_handle_interrupt_attribute (tree *, tree name, tree args, int, 1955 bool *no_add_attrs) 1956 { 1957 gcc_assert (args); 1958 1959 tree value = TREE_VALUE (args); 1960 1961 if (TREE_CODE (value) != STRING_CST) 1962 { 1963 warning (OPT_Wattributes, 1964 "argument of %qE attribute is not a string constant", 1965 name); 1966 *no_add_attrs = true; 1967 } 1968 else if (!TARGET_V2 1969 && strcmp (TREE_STRING_POINTER (value), "ilink1") 1970 && strcmp (TREE_STRING_POINTER (value), "ilink2")) 1971 { 1972 warning (OPT_Wattributes, 1973 "argument of %qE attribute is not \"ilink1\" or \"ilink2\"", 1974 name); 1975 *no_add_attrs = true; 1976 } 1977 else if (TARGET_V2 1978 && strcmp (TREE_STRING_POINTER (value), "ilink") 1979 && strcmp (TREE_STRING_POINTER (value), "firq")) 1980 { 1981 warning (OPT_Wattributes, 1982 "argument of %qE attribute is not \"ilink\" or \"firq\"", 1983 name); 1984 *no_add_attrs = true; 1985 } 1986 1987 return NULL_TREE; 1988 } 1989 1990 static tree 1991 arc_handle_fndecl_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED, 1992 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs) 1993 { 1994 if (TREE_CODE (*node) != FUNCTION_DECL) 1995 { 1996 warning (OPT_Wattributes, "%qE attribute only applies to functions", 1997 name); 1998 *no_add_attrs = true; 1999 } 2000 2001 return NULL_TREE; 2002 } 2003 2004 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */ 2005 2006 static bool 2007 arc_allocate_stack_slots_for_args (void) 2008 { 2009 /* Naked functions should not allocate stack slots for arguments. */ 2010 unsigned int fn_type = arc_compute_function_type (cfun); 2011 2012 return !ARC_NAKED_P(fn_type); 2013 } 2014 2015 /* Implement `TARGET_WARN_FUNC_RETURN'. */ 2016 2017 static bool 2018 arc_warn_func_return (tree decl) 2019 { 2020 struct function *func = DECL_STRUCT_FUNCTION (decl); 2021 unsigned int fn_type = arc_compute_function_type (func); 2022 2023 return !ARC_NAKED_P (fn_type); 2024 } 2025 2026 /* Return zero if TYPE1 and TYPE are incompatible, one if they are compatible, 2027 and two if they are nearly compatible (which causes a warning to be 2028 generated). */ 2029 2030 static int 2031 arc_comp_type_attributes (const_tree type1, 2032 const_tree type2) 2033 { 2034 int l1, l2, m1, m2, s1, s2; 2035 2036 /* Check for mismatch of non-default calling convention. */ 2037 if (TREE_CODE (type1) != FUNCTION_TYPE) 2038 return 1; 2039 2040 /* Check for mismatched call attributes. */ 2041 l1 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type1)) != NULL; 2042 l2 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type2)) != NULL; 2043 m1 = lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type1)) != NULL; 2044 m2 = lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type2)) != NULL; 2045 s1 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type1)) != NULL; 2046 s2 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type2)) != NULL; 2047 2048 /* Only bother to check if an attribute is defined. */ 2049 if (l1 | l2 | m1 | m2 | s1 | s2) 2050 { 2051 /* If one type has an attribute, the other must have the same attribute. */ 2052 if ((l1 != l2) || (m1 != m2) || (s1 != s2)) 2053 return 0; 2054 2055 /* Disallow mixed attributes. */ 2056 if (l1 + m1 + s1 > 1) 2057 return 0; 2058 } 2059 2060 2061 return 1; 2062 } 2063 2064 /* Misc. utilities. */ 2065 2066 /* X and Y are two things to compare using CODE. Emit the compare insn and 2067 return the rtx for the cc reg in the proper mode. */ 2068 2069 rtx 2070 gen_compare_reg (rtx comparison, machine_mode omode) 2071 { 2072 enum rtx_code code = GET_CODE (comparison); 2073 rtx x = XEXP (comparison, 0); 2074 rtx y = XEXP (comparison, 1); 2075 rtx tmp, cc_reg; 2076 machine_mode mode, cmode; 2077 2078 2079 cmode = GET_MODE (x); 2080 if (cmode == VOIDmode) 2081 cmode = GET_MODE (y); 2082 gcc_assert (cmode == SImode || cmode == SFmode || cmode == DFmode); 2083 if (cmode == SImode) 2084 { 2085 if (!register_operand (x, SImode)) 2086 { 2087 if (register_operand (y, SImode)) 2088 { 2089 tmp = x; 2090 x = y; 2091 y = tmp; 2092 code = swap_condition (code); 2093 } 2094 else 2095 x = copy_to_mode_reg (SImode, x); 2096 } 2097 if (GET_CODE (y) == SYMBOL_REF && flag_pic) 2098 y = copy_to_mode_reg (SImode, y); 2099 } 2100 else 2101 { 2102 x = force_reg (cmode, x); 2103 y = force_reg (cmode, y); 2104 } 2105 mode = SELECT_CC_MODE (code, x, y); 2106 2107 cc_reg = gen_rtx_REG (mode, CC_REG); 2108 2109 /* ??? FIXME (x-y)==0, as done by both cmpsfpx_raw and 2110 cmpdfpx_raw, is not a correct comparison for floats: 2111 http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm 2112 */ 2113 if (TARGET_ARGONAUT_SET 2114 && ((cmode == SFmode && TARGET_SPFP) || (cmode == DFmode && TARGET_DPFP))) 2115 { 2116 switch (code) 2117 { 2118 case NE: case EQ: case LT: case UNGE: case LE: case UNGT: 2119 case UNEQ: case LTGT: case ORDERED: case UNORDERED: 2120 break; 2121 case GT: case UNLE: case GE: case UNLT: 2122 code = swap_condition (code); 2123 tmp = x; 2124 x = y; 2125 y = tmp; 2126 break; 2127 default: 2128 gcc_unreachable (); 2129 } 2130 if (cmode == SFmode) 2131 { 2132 emit_insn (gen_cmpsfpx_raw (x, y)); 2133 } 2134 else /* DFmode */ 2135 { 2136 /* Accepts Dx regs directly by insns. */ 2137 emit_insn (gen_cmpdfpx_raw (x, y)); 2138 } 2139 2140 if (mode != CC_FPXmode) 2141 emit_insn (gen_rtx_SET (cc_reg, 2142 gen_rtx_COMPARE (mode, 2143 gen_rtx_REG (CC_FPXmode, 61), 2144 const0_rtx))); 2145 } 2146 else if (TARGET_FPX_QUARK && (cmode == SFmode)) 2147 { 2148 switch (code) 2149 { 2150 case NE: case EQ: case GT: case UNLE: case GE: case UNLT: 2151 case UNEQ: case LTGT: case ORDERED: case UNORDERED: 2152 break; 2153 case LT: case UNGE: case LE: case UNGT: 2154 code = swap_condition (code); 2155 tmp = x; 2156 x = y; 2157 y = tmp; 2158 break; 2159 default: 2160 gcc_unreachable (); 2161 } 2162 2163 emit_insn (gen_cmp_quark (cc_reg, 2164 gen_rtx_COMPARE (mode, x, y))); 2165 } 2166 else if (TARGET_HARD_FLOAT 2167 && ((cmode == SFmode && TARGET_FP_SP_BASE) 2168 || (cmode == DFmode && TARGET_FP_DP_BASE))) 2169 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (mode, x, y))); 2170 else if (GET_MODE_CLASS (cmode) == MODE_FLOAT && TARGET_OPTFPE) 2171 { 2172 rtx op0 = gen_rtx_REG (cmode, 0); 2173 rtx op1 = gen_rtx_REG (cmode, GET_MODE_SIZE (cmode) / UNITS_PER_WORD); 2174 bool swap = false; 2175 2176 switch (code) 2177 { 2178 case NE: case EQ: case GT: case UNLE: case GE: case UNLT: 2179 case UNEQ: case LTGT: case ORDERED: case UNORDERED: 2180 break; 2181 case LT: case UNGE: case LE: case UNGT: 2182 code = swap_condition (code); 2183 swap = true; 2184 break; 2185 default: 2186 gcc_unreachable (); 2187 } 2188 if (currently_expanding_to_rtl) 2189 { 2190 if (swap) 2191 { 2192 tmp = x; 2193 x = y; 2194 y = tmp; 2195 } 2196 emit_move_insn (op0, x); 2197 emit_move_insn (op1, y); 2198 } 2199 else 2200 { 2201 gcc_assert (rtx_equal_p (op0, x)); 2202 gcc_assert (rtx_equal_p (op1, y)); 2203 if (swap) 2204 { 2205 op0 = y; 2206 op1 = x; 2207 } 2208 } 2209 emit_insn (gen_cmp_float (cc_reg, gen_rtx_COMPARE (mode, op0, op1))); 2210 } 2211 else 2212 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (mode, x, y))); 2213 return gen_rtx_fmt_ee (code, omode, cc_reg, const0_rtx); 2214 } 2215 2216 /* Return true if VALUE, a const_double, will fit in a limm (4 byte number). 2217 We assume the value can be either signed or unsigned. */ 2218 2219 bool 2220 arc_double_limm_p (rtx value) 2221 { 2222 HOST_WIDE_INT low, high; 2223 2224 gcc_assert (GET_CODE (value) == CONST_DOUBLE); 2225 2226 if (TARGET_DPFP) 2227 return true; 2228 2229 low = CONST_DOUBLE_LOW (value); 2230 high = CONST_DOUBLE_HIGH (value); 2231 2232 if (low & 0x80000000) 2233 { 2234 return (((unsigned HOST_WIDE_INT) low <= 0xffffffff && high == 0) 2235 || (((low & - (unsigned HOST_WIDE_INT) 0x80000000) 2236 == - (unsigned HOST_WIDE_INT) 0x80000000) 2237 && high == -1)); 2238 } 2239 else 2240 { 2241 return (unsigned HOST_WIDE_INT) low <= 0x7fffffff && high == 0; 2242 } 2243 } 2244 2245 /* Do any needed setup for a variadic function. For the ARC, we must 2246 create a register parameter block, and then copy any anonymous arguments 2247 in registers to memory. 2248 2249 CUM has not been updated for the last named argument which has type TYPE 2250 and mode MODE, and we rely on this fact. */ 2251 2252 static void 2253 arc_setup_incoming_varargs (cumulative_args_t args_so_far, 2254 machine_mode mode, tree type, 2255 int *pretend_size, int no_rtl) 2256 { 2257 int first_anon_arg; 2258 CUMULATIVE_ARGS next_cum; 2259 2260 /* We must treat `__builtin_va_alist' as an anonymous arg. */ 2261 2262 next_cum = *get_cumulative_args (args_so_far); 2263 arc_function_arg_advance (pack_cumulative_args (&next_cum), 2264 mode, type, true); 2265 first_anon_arg = next_cum; 2266 2267 if (FUNCTION_ARG_REGNO_P (first_anon_arg)) 2268 { 2269 /* First anonymous (unnamed) argument is in a reg. */ 2270 2271 /* Note that first_reg_offset < MAX_ARC_PARM_REGS. */ 2272 int first_reg_offset = first_anon_arg; 2273 2274 if (!no_rtl) 2275 { 2276 rtx regblock 2277 = gen_rtx_MEM (BLKmode, plus_constant (Pmode, arg_pointer_rtx, 2278 FIRST_PARM_OFFSET (0))); 2279 move_block_from_reg (first_reg_offset, regblock, 2280 MAX_ARC_PARM_REGS - first_reg_offset); 2281 } 2282 2283 *pretend_size 2284 = ((MAX_ARC_PARM_REGS - first_reg_offset ) * UNITS_PER_WORD); 2285 } 2286 } 2287 2288 /* Cost functions. */ 2289 2290 /* Provide the costs of an addressing mode that contains ADDR. 2291 If ADDR is not a valid address, its cost is irrelevant. */ 2292 2293 static int 2294 arc_address_cost (rtx addr, machine_mode, addr_space_t, bool speed) 2295 { 2296 switch (GET_CODE (addr)) 2297 { 2298 case REG : 2299 return speed || satisfies_constraint_Rcq (addr) ? 0 : 1; 2300 case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC: 2301 case PRE_MODIFY: case POST_MODIFY: 2302 return !speed; 2303 2304 case LABEL_REF : 2305 case SYMBOL_REF : 2306 case CONST : 2307 if (TARGET_NPS_CMEM && cmem_address (addr, SImode)) 2308 return 0; 2309 /* Most likely needs a LIMM. */ 2310 return COSTS_N_INSNS (1); 2311 2312 case PLUS : 2313 { 2314 register rtx plus0 = XEXP (addr, 0); 2315 register rtx plus1 = XEXP (addr, 1); 2316 2317 if (GET_CODE (plus0) != REG 2318 && (GET_CODE (plus0) != MULT 2319 || !CONST_INT_P (XEXP (plus0, 1)) 2320 || (INTVAL (XEXP (plus0, 1)) != 2 2321 && INTVAL (XEXP (plus0, 1)) != 4))) 2322 break; 2323 2324 switch (GET_CODE (plus1)) 2325 { 2326 case CONST_INT : 2327 return (!RTX_OK_FOR_OFFSET_P (SImode, plus1) 2328 ? COSTS_N_INSNS (1) 2329 : speed 2330 ? 0 2331 : (satisfies_constraint_Rcq (plus0) 2332 && satisfies_constraint_O (plus1)) 2333 ? 0 2334 : 1); 2335 case REG: 2336 return (speed < 1 ? 0 2337 : (satisfies_constraint_Rcq (plus0) 2338 && satisfies_constraint_Rcq (plus1)) 2339 ? 0 : 1); 2340 case CONST : 2341 case SYMBOL_REF : 2342 case LABEL_REF : 2343 return COSTS_N_INSNS (1); 2344 default: 2345 break; 2346 } 2347 break; 2348 } 2349 default: 2350 break; 2351 } 2352 2353 return 4; 2354 } 2355 2356 /* Emit instruction X with the frame related bit set. */ 2357 2358 static rtx 2359 frame_insn (rtx x) 2360 { 2361 x = emit_insn (x); 2362 RTX_FRAME_RELATED_P (x) = 1; 2363 return x; 2364 } 2365 2366 /* Emit a frame insn to move SRC to DST. */ 2367 2368 static rtx 2369 frame_move (rtx dst, rtx src) 2370 { 2371 rtx tmp = gen_rtx_SET (dst, src); 2372 RTX_FRAME_RELATED_P (tmp) = 1; 2373 return frame_insn (tmp); 2374 } 2375 2376 /* Like frame_move, but add a REG_INC note for REG if ADDR contains an 2377 auto increment address, or is zero. */ 2378 2379 static rtx 2380 frame_move_inc (rtx dst, rtx src, rtx reg, rtx addr) 2381 { 2382 rtx insn = frame_move (dst, src); 2383 2384 if (!addr 2385 || GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == POST_INC 2386 || GET_CODE (addr) == PRE_MODIFY || GET_CODE (addr) == POST_MODIFY) 2387 add_reg_note (insn, REG_INC, reg); 2388 return insn; 2389 } 2390 2391 /* Emit a frame insn which adjusts a frame address register REG by OFFSET. */ 2392 2393 static rtx 2394 frame_add (rtx reg, HOST_WIDE_INT offset) 2395 { 2396 gcc_assert ((offset & 0x3) == 0); 2397 if (!offset) 2398 return NULL_RTX; 2399 return frame_move (reg, plus_constant (Pmode, reg, offset)); 2400 } 2401 2402 /* Emit a frame insn which adjusts stack pointer by OFFSET. */ 2403 2404 static rtx 2405 frame_stack_add (HOST_WIDE_INT offset) 2406 { 2407 return frame_add (stack_pointer_rtx, offset); 2408 } 2409 2410 /* Traditionally, we push saved registers first in the prologue, 2411 then we allocate the rest of the frame - and reverse in the epilogue. 2412 This has still its merits for ease of debugging, or saving code size 2413 or even execution time if the stack frame is so large that some accesses 2414 can't be encoded anymore with offsets in the instruction code when using 2415 a different scheme. 2416 Also, it would be a good starting point if we got instructions to help 2417 with register save/restore. 2418 2419 However, often stack frames are small, and the pushing / popping has 2420 some costs: 2421 - the stack modification prevents a lot of scheduling. 2422 - frame allocation / deallocation needs extra instructions. 2423 - unless we know that we compile ARC700 user code, we need to put 2424 a memory barrier after frame allocation / before deallocation to 2425 prevent interrupts clobbering our data in the frame. 2426 In particular, we don't have any such guarantees for library functions, 2427 which tend to, on the other hand, to have small frames. 2428 2429 Thus, for small frames, we'd like to use a different scheme: 2430 - The frame is allocated in full with the first prologue instruction, 2431 and deallocated in full with the last epilogue instruction. 2432 Thus, the instructions in-betwen can be freely scheduled. 2433 - If the function has no outgoing arguments on the stack, we can allocate 2434 one register save slot at the top of the stack. This register can then 2435 be saved simultanously with frame allocation, and restored with 2436 frame deallocation. 2437 This register can be picked depending on scheduling considerations, 2438 although same though should go into having some set of registers 2439 to be potentially lingering after a call, and others to be available 2440 immediately - i.e. in the absence of interprocedual optimization, we 2441 can use an ABI-like convention for register allocation to reduce 2442 stalls after function return. */ 2443 /* Function prologue/epilogue handlers. */ 2444 2445 /* ARCompact stack frames look like: 2446 2447 Before call After call 2448 high +-----------------------+ +-----------------------+ 2449 mem | reg parm save area | | reg parm save area | 2450 | only created for | | only created for | 2451 | variable arg fns | | variable arg fns | 2452 AP +-----------------------+ +-----------------------+ 2453 | return addr register | | return addr register | 2454 | (if required) | | (if required) | 2455 +-----------------------+ +-----------------------+ 2456 | | | | 2457 | reg save area | | reg save area | 2458 | | | | 2459 +-----------------------+ +-----------------------+ 2460 | frame pointer | | frame pointer | 2461 | (if required) | | (if required) | 2462 FP +-----------------------+ +-----------------------+ 2463 | | | | 2464 | local/temp variables | | local/temp variables | 2465 | | | | 2466 +-----------------------+ +-----------------------+ 2467 | | | | 2468 | arguments on stack | | arguments on stack | 2469 | | | | 2470 SP +-----------------------+ +-----------------------+ 2471 | reg parm save area | 2472 | only created for | 2473 | variable arg fns | 2474 AP +-----------------------+ 2475 | return addr register | 2476 | (if required) | 2477 +-----------------------+ 2478 | | 2479 | reg save area | 2480 | | 2481 +-----------------------+ 2482 | frame pointer | 2483 | (if required) | 2484 FP +-----------------------+ 2485 | | 2486 | local/temp variables | 2487 | | 2488 +-----------------------+ 2489 | | 2490 | arguments on stack | 2491 low | | 2492 mem SP +-----------------------+ 2493 2494 Notes: 2495 1) The "reg parm save area" does not exist for non variable argument fns. 2496 The "reg parm save area" can be eliminated completely if we created our 2497 own va-arc.h, but that has tradeoffs as well (so it's not done). */ 2498 2499 /* Structure to be filled in by arc_compute_frame_size with register 2500 save masks, and offsets for the current function. */ 2501 struct GTY (()) arc_frame_info 2502 { 2503 unsigned int total_size; /* # bytes that the entire frame takes up. */ 2504 unsigned int extra_size; /* # bytes of extra stuff. */ 2505 unsigned int pretend_size; /* # bytes we push and pretend caller did. */ 2506 unsigned int args_size; /* # bytes that outgoing arguments take up. */ 2507 unsigned int reg_size; /* # bytes needed to store regs. */ 2508 unsigned int var_size; /* # bytes that variables take up. */ 2509 unsigned int gmask; /* Mask of saved gp registers. */ 2510 bool initialized; /* FALSE if frame size already calculated. */ 2511 short millicode_start_reg; 2512 short millicode_end_reg; 2513 bool save_return_addr; 2514 }; 2515 2516 /* GMASK bit length -1. */ 2517 #define GMASK_LEN 31 2518 2519 /* Defining data structures for per-function information. */ 2520 2521 typedef struct GTY (()) machine_function 2522 { 2523 unsigned int fn_type; 2524 struct arc_frame_info frame_info; 2525 /* To keep track of unalignment caused by short insns. */ 2526 int unalign; 2527 struct arc_ccfsm ccfsm_current; 2528 /* Map from uid to ccfsm state during branch shortening. */ 2529 rtx ccfsm_current_insn; 2530 char arc_reorg_started; 2531 char prescan_initialized; 2532 } machine_function; 2533 2534 /* Type of function DECL. 2535 2536 The result is cached. To reset the cache at the end of a function, 2537 call with DECL = NULL_TREE. */ 2538 2539 unsigned int 2540 arc_compute_function_type (struct function *fun) 2541 { 2542 tree attr, decl = fun->decl; 2543 unsigned int fn_type = fun->machine->fn_type; 2544 2545 if (fn_type != ARC_FUNCTION_UNKNOWN) 2546 return fn_type; 2547 2548 /* Check if it is a naked function. */ 2549 if (lookup_attribute ("naked", DECL_ATTRIBUTES (decl)) != NULL_TREE) 2550 fn_type |= ARC_FUNCTION_NAKED; 2551 else 2552 fn_type |= ARC_FUNCTION_NORMAL; 2553 2554 /* Now see if this is an interrupt handler. */ 2555 attr = lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl)); 2556 if (attr != NULL_TREE) 2557 { 2558 tree value, args = TREE_VALUE (attr); 2559 2560 gcc_assert (list_length (args) == 1); 2561 value = TREE_VALUE (args); 2562 gcc_assert (TREE_CODE (value) == STRING_CST); 2563 2564 if (!strcmp (TREE_STRING_POINTER (value), "ilink1") 2565 || !strcmp (TREE_STRING_POINTER (value), "ilink")) 2566 fn_type |= ARC_FUNCTION_ILINK1; 2567 else if (!strcmp (TREE_STRING_POINTER (value), "ilink2")) 2568 fn_type |= ARC_FUNCTION_ILINK2; 2569 else if (!strcmp (TREE_STRING_POINTER (value), "firq")) 2570 fn_type |= ARC_FUNCTION_FIRQ; 2571 else 2572 gcc_unreachable (); 2573 } 2574 2575 return fun->machine->fn_type = fn_type; 2576 } 2577 2578 /* Helper function to wrap FRAME_POINTER_NEEDED. We do this as 2579 FRAME_POINTER_NEEDED will not be true until the IRA (Integrated 2580 Register Allocator) pass, while we want to get the frame size 2581 correct earlier than the IRA pass. 2582 2583 When a function uses eh_return we must ensure that the fp register 2584 is saved and then restored so that the unwinder can restore the 2585 correct value for the frame we are going to jump to. 2586 2587 To do this we force all frames that call eh_return to require a 2588 frame pointer (see arc_frame_pointer_required), this 2589 will ensure that the previous frame pointer is stored on entry to 2590 the function, and will then be reloaded at function exit. 2591 2592 As the frame pointer is handled as a special case in our prologue 2593 and epilogue code it must not be saved and restored using the 2594 MUST_SAVE_REGISTER mechanism otherwise we run into issues where GCC 2595 believes that the function is not using a frame pointer and that 2596 the value in the fp register is the frame pointer, while the 2597 prologue and epilogue are busy saving and restoring the fp 2598 register. 2599 2600 During compilation of a function the frame size is evaluated 2601 multiple times, it is not until the reload pass is complete the the 2602 frame size is considered fixed (it is at this point that space for 2603 all spills has been allocated). However the frame_pointer_needed 2604 variable is not set true until the register allocation pass, as a 2605 result in the early stages the frame size does not include space 2606 for the frame pointer to be spilled. 2607 2608 The problem that this causes is that the rtl generated for 2609 EH_RETURN_HANDLER_RTX uses the details of the frame size to compute 2610 the offset from the frame pointer at which the return address 2611 lives. However, in early passes GCC has not yet realised we need a 2612 frame pointer, and so has not included space for the frame pointer 2613 in the frame size, and so gets the offset of the return address 2614 wrong. This should not be an issue as in later passes GCC has 2615 realised that the frame pointer needs to be spilled, and has 2616 increased the frame size. However, the rtl for the 2617 EH_RETURN_HANDLER_RTX is not regenerated to use the newer, larger 2618 offset, and the wrong smaller offset is used. */ 2619 2620 static bool 2621 arc_frame_pointer_needed (void) 2622 { 2623 return (frame_pointer_needed || crtl->calls_eh_return); 2624 } 2625 2626 /* Tell prologue and epilogue if register REGNO should be saved / 2627 restored. The return address, stack pointer and frame pointer are 2628 treated separately. Don't consider them here. Addition for pic: 2629 The gp register needs to be saved if the current function changes 2630 it to access gotoff variables. FIXME: This will not be needed if 2631 we used some arbitrary register instead of r26. */ 2632 2633 static bool 2634 arc_must_save_register (int regno, struct function *func) 2635 { 2636 unsigned int fn_type = arc_compute_function_type (func); 2637 bool irq_auto_save_p = ((irq_ctrl_saved.irq_save_last_reg >= regno) 2638 && ARC_AUTO_IRQ_P (fn_type)); 2639 bool firq_auto_save_p = ARC_FAST_INTERRUPT_P (fn_type); 2640 2641 switch (rgf_banked_register_count) 2642 { 2643 case 4: 2644 firq_auto_save_p &= (regno < 4); 2645 break; 2646 case 8: 2647 firq_auto_save_p &= ((regno < 4) || ((regno > 11) && (regno < 16))); 2648 break; 2649 case 16: 2650 firq_auto_save_p &= ((regno < 4) || ((regno > 9) && (regno < 16)) 2651 || ((regno > 25) && (regno < 29)) 2652 || ((regno > 29) && (regno < 32))); 2653 break; 2654 case 32: 2655 firq_auto_save_p &= (regno != 29) && (regno < 32); 2656 break; 2657 default: 2658 firq_auto_save_p = false; 2659 break; 2660 } 2661 2662 switch (regno) 2663 { 2664 case RETURN_ADDR_REGNUM: 2665 case STACK_POINTER_REGNUM: 2666 return false; 2667 2668 case HARD_FRAME_POINTER_REGNUM: 2669 /* If we need FP reg as a frame pointer then don't save it as a 2670 regular reg. */ 2671 if (arc_frame_pointer_needed ()) 2672 return false; 2673 2674 /* FALLTHRU */ 2675 default: 2676 if (df_regs_ever_live_p (regno) 2677 && (!call_used_regs[regno] 2678 || ARC_INTERRUPT_P (fn_type)) 2679 /* Do not emit code for auto saved regs. */ 2680 && !irq_auto_save_p 2681 && !firq_auto_save_p) 2682 return true; 2683 } 2684 2685 return false; 2686 } 2687 2688 /* Return true if the return address must be saved in the current function, 2689 otherwise return false. */ 2690 2691 static bool 2692 arc_must_save_return_addr (struct function *func) 2693 { 2694 if (func->machine->frame_info.save_return_addr) 2695 return true; 2696 2697 return false; 2698 } 2699 2700 /* Return non-zero if there are registers to be saved or loaded using 2701 millicode thunks. We can only use consecutive sequences starting 2702 with r13, and not going beyond r25. 2703 GMASK is a bitmask of registers to save. This function sets 2704 FRAME->millicod_start_reg .. FRAME->millicode_end_reg to the range 2705 of registers to be saved / restored with a millicode call. */ 2706 2707 static int 2708 arc_compute_millicode_save_restore_regs (unsigned int gmask, 2709 struct arc_frame_info *frame) 2710 { 2711 int regno; 2712 2713 int start_reg = 13, end_reg = 25; 2714 2715 for (regno = start_reg; regno <= end_reg && (gmask & (1L << regno));) 2716 regno++; 2717 end_reg = regno - 1; 2718 /* There is no point in using millicode thunks if we don't save/restore 2719 at least three registers. For non-leaf functions we also have the 2720 blink restore. */ 2721 if (regno - start_reg >= 3 - (crtl->is_leaf == 0)) 2722 { 2723 frame->millicode_start_reg = 13; 2724 frame->millicode_end_reg = regno - 1; 2725 return 1; 2726 } 2727 return 0; 2728 } 2729 2730 /* Return the bytes needed to compute the frame pointer from the 2731 current stack pointer. */ 2732 2733 static unsigned int 2734 arc_compute_frame_size (void) 2735 { 2736 int regno; 2737 unsigned int total_size, var_size, args_size, pretend_size, extra_size; 2738 unsigned int reg_size; 2739 unsigned int gmask; 2740 struct arc_frame_info *frame_info; 2741 int size; 2742 unsigned int extra_plus_reg_size; 2743 unsigned int extra_plus_reg_size_aligned; 2744 2745 /* The answer might already be known. */ 2746 if (cfun->machine->frame_info.initialized) 2747 return cfun->machine->frame_info.total_size; 2748 2749 frame_info = &cfun->machine->frame_info; 2750 size = ARC_STACK_ALIGN (get_frame_size ()); 2751 2752 /* 1) Size of locals and temporaries. */ 2753 var_size = size; 2754 2755 /* 2) Size of outgoing arguments. */ 2756 args_size = crtl->outgoing_args_size; 2757 2758 /* 3) Calculate space needed for saved registers. 2759 ??? We ignore the extension registers for now. */ 2760 2761 /* See if this is an interrupt handler. Call used registers must be saved 2762 for them too. */ 2763 2764 reg_size = 0; 2765 gmask = 0; 2766 2767 for (regno = 0; regno <= 31; regno++) 2768 { 2769 if (arc_must_save_register (regno, cfun)) 2770 { 2771 reg_size += UNITS_PER_WORD; 2772 gmask |= 1L << regno; 2773 } 2774 } 2775 2776 /* In a frame that calls __builtin_eh_return two data registers are 2777 used to pass values back to the exception handler. 2778 2779 Ensure that these registers are spilled to the stack so that the 2780 exception throw code can find them, and update the saved values. 2781 The handling code will then consume these reloaded values to 2782 handle the exception. */ 2783 if (crtl->calls_eh_return) 2784 for (regno = 0; EH_RETURN_DATA_REGNO (regno) != INVALID_REGNUM; regno++) 2785 { 2786 reg_size += UNITS_PER_WORD; 2787 gmask |= 1L << regno; 2788 } 2789 2790 /* Check if we need to save the return address. */ 2791 frame_info->save_return_addr = (!crtl->is_leaf 2792 || df_regs_ever_live_p (RETURN_ADDR_REGNUM) 2793 || crtl->calls_eh_return); 2794 2795 /* Saving blink reg for millicode thunk calls. */ 2796 if (TARGET_MILLICODE_THUNK_SET 2797 && !crtl->calls_eh_return) 2798 { 2799 if (arc_compute_millicode_save_restore_regs (gmask, frame_info)) 2800 frame_info->save_return_addr = true; 2801 } 2802 2803 /* 4) Calculate extra size made up of the blink + fp size. */ 2804 extra_size = 0; 2805 if (arc_must_save_return_addr (cfun)) 2806 extra_size = 4; 2807 if (arc_frame_pointer_needed ()) 2808 extra_size += 4; 2809 2810 /* 5) Space for variable arguments passed in registers */ 2811 pretend_size = crtl->args.pretend_args_size; 2812 2813 /* Ensure everything before the locals is aligned appropriately. */ 2814 extra_plus_reg_size = extra_size + reg_size; 2815 extra_plus_reg_size_aligned = ARC_STACK_ALIGN (extra_plus_reg_size); 2816 reg_size = extra_plus_reg_size_aligned - extra_size; 2817 2818 /* Compute total frame size. */ 2819 total_size = var_size + args_size + extra_size + pretend_size + reg_size; 2820 2821 /* It used to be the case that the alignment was forced at this 2822 point. However, that is dangerous, calculations based on 2823 total_size would be wrong. Given that this has never cropped up 2824 as an issue I've changed this to an assert for now. */ 2825 gcc_assert (total_size == ARC_STACK_ALIGN (total_size)); 2826 2827 /* Save computed information. */ 2828 frame_info->total_size = total_size; 2829 frame_info->extra_size = extra_size; 2830 frame_info->pretend_size = pretend_size; 2831 frame_info->var_size = var_size; 2832 frame_info->args_size = args_size; 2833 frame_info->reg_size = reg_size; 2834 frame_info->gmask = gmask; 2835 frame_info->initialized = reload_completed; 2836 2837 /* Ok, we're done. */ 2838 return total_size; 2839 } 2840 2841 /* Build dwarf information when the context is saved via AUX_IRQ_CTRL 2842 mechanism. */ 2843 2844 static void 2845 arc_dwarf_emit_irq_save_regs (void) 2846 { 2847 rtx tmp, par, insn, reg; 2848 int i, offset, j; 2849 2850 par = gen_rtx_SEQUENCE (VOIDmode, 2851 rtvec_alloc (irq_ctrl_saved.irq_save_last_reg + 1 2852 + irq_ctrl_saved.irq_save_blink 2853 + irq_ctrl_saved.irq_save_lpcount 2854 + 1)); 2855 2856 /* Build the stack adjustment note for unwind info. */ 2857 j = 0; 2858 offset = UNITS_PER_WORD * (irq_ctrl_saved.irq_save_last_reg + 1 2859 + irq_ctrl_saved.irq_save_blink 2860 + irq_ctrl_saved.irq_save_lpcount); 2861 tmp = plus_constant (Pmode, stack_pointer_rtx, -1 * offset); 2862 tmp = gen_rtx_SET (stack_pointer_rtx, tmp); 2863 RTX_FRAME_RELATED_P (tmp) = 1; 2864 XVECEXP (par, 0, j++) = tmp; 2865 2866 offset -= UNITS_PER_WORD; 2867 2868 /* 1st goes LP_COUNT. */ 2869 if (irq_ctrl_saved.irq_save_lpcount) 2870 { 2871 reg = gen_rtx_REG (SImode, 60); 2872 tmp = plus_constant (Pmode, stack_pointer_rtx, offset); 2873 tmp = gen_frame_mem (SImode, tmp); 2874 tmp = gen_rtx_SET (tmp, reg); 2875 RTX_FRAME_RELATED_P (tmp) = 1; 2876 XVECEXP (par, 0, j++) = tmp; 2877 offset -= UNITS_PER_WORD; 2878 } 2879 2880 /* 2nd goes BLINK. */ 2881 if (irq_ctrl_saved.irq_save_blink) 2882 { 2883 reg = gen_rtx_REG (SImode, 31); 2884 tmp = plus_constant (Pmode, stack_pointer_rtx, offset); 2885 tmp = gen_frame_mem (SImode, tmp); 2886 tmp = gen_rtx_SET (tmp, reg); 2887 RTX_FRAME_RELATED_P (tmp) = 1; 2888 XVECEXP (par, 0, j++) = tmp; 2889 offset -= UNITS_PER_WORD; 2890 } 2891 2892 /* Build the parallel of the remaining registers recorded as saved 2893 for unwind. */ 2894 for (i = irq_ctrl_saved.irq_save_last_reg; i >= 0; i--) 2895 { 2896 reg = gen_rtx_REG (SImode, i); 2897 tmp = plus_constant (Pmode, stack_pointer_rtx, offset); 2898 tmp = gen_frame_mem (SImode, tmp); 2899 tmp = gen_rtx_SET (tmp, reg); 2900 RTX_FRAME_RELATED_P (tmp) = 1; 2901 XVECEXP (par, 0, j++) = tmp; 2902 offset -= UNITS_PER_WORD; 2903 } 2904 2905 /* Dummy insn used to anchor the dwarf info. */ 2906 insn = emit_insn (gen_stack_irq_dwarf()); 2907 add_reg_note (insn, REG_FRAME_RELATED_EXPR, par); 2908 RTX_FRAME_RELATED_P (insn) = 1; 2909 } 2910 2911 /* Helper for prologue: emit frame store with pre_modify or pre_dec to 2912 save register REG on stack. An initial offset OFFSET can be passed 2913 to the function. */ 2914 2915 static int 2916 frame_save_reg (rtx reg, HOST_WIDE_INT offset) 2917 { 2918 rtx addr; 2919 2920 if (offset) 2921 { 2922 rtx tmp = plus_constant (Pmode, stack_pointer_rtx, 2923 offset - GET_MODE_SIZE (GET_MODE (reg))); 2924 addr = gen_frame_mem (GET_MODE (reg), 2925 gen_rtx_PRE_MODIFY (Pmode, 2926 stack_pointer_rtx, 2927 tmp)); 2928 } 2929 else 2930 addr = gen_frame_mem (GET_MODE (reg), gen_rtx_PRE_DEC (Pmode, 2931 stack_pointer_rtx)); 2932 frame_move_inc (addr, reg, stack_pointer_rtx, 0); 2933 2934 return GET_MODE_SIZE (GET_MODE (reg)) - offset; 2935 } 2936 2937 /* Helper for epilogue: emit frame load with post_modify or post_inc 2938 to restore register REG from stack. The initial offset is passed 2939 via OFFSET. */ 2940 2941 static int 2942 frame_restore_reg (rtx reg, HOST_WIDE_INT offset) 2943 { 2944 rtx addr, insn; 2945 2946 if (offset) 2947 { 2948 rtx tmp = plus_constant (Pmode, stack_pointer_rtx, 2949 offset + GET_MODE_SIZE (GET_MODE (reg))); 2950 addr = gen_frame_mem (GET_MODE (reg), 2951 gen_rtx_POST_MODIFY (Pmode, 2952 stack_pointer_rtx, 2953 tmp)); 2954 } 2955 else 2956 addr = gen_frame_mem (GET_MODE (reg), gen_rtx_POST_INC (Pmode, 2957 stack_pointer_rtx)); 2958 insn = frame_move_inc (reg, addr, stack_pointer_rtx, 0); 2959 add_reg_note (insn, REG_CFA_RESTORE, reg); 2960 2961 if (reg == hard_frame_pointer_rtx) 2962 add_reg_note (insn, REG_CFA_DEF_CFA, 2963 plus_constant (Pmode, stack_pointer_rtx, 2964 GET_MODE_SIZE (GET_MODE (reg)) + offset)); 2965 else 2966 add_reg_note (insn, REG_CFA_ADJUST_CFA, 2967 gen_rtx_SET (stack_pointer_rtx, 2968 plus_constant (Pmode, stack_pointer_rtx, 2969 GET_MODE_SIZE (GET_MODE (reg)) 2970 + offset))); 2971 2972 return GET_MODE_SIZE (GET_MODE (reg)) + offset; 2973 } 2974 2975 /* Check if we have a continous range to be save/restored with the 2976 help of enter/leave instructions. A vaild register range starts 2977 from $r13 and is up to (including) $r26. */ 2978 2979 static bool 2980 arc_enter_leave_p (unsigned int gmask) 2981 { 2982 int regno; 2983 unsigned int rmask = 0; 2984 2985 if (!gmask) 2986 return false; 2987 2988 for (regno = ENTER_LEAVE_START_REG; 2989 regno <= ENTER_LEAVE_END_REG && (gmask & (1L << regno)); regno++) 2990 rmask |= 1L << regno; 2991 2992 if (rmask ^ gmask) 2993 return false; 2994 2995 return true; 2996 } 2997 2998 /* ARC's prologue, save any needed call-saved regs (and call-used if 2999 this is an interrupt handler) for ARCompact ISA, using ST/STD 3000 instructions. */ 3001 3002 static int 3003 arc_save_callee_saves (unsigned int gmask, 3004 bool save_blink, 3005 bool save_fp, 3006 HOST_WIDE_INT offset) 3007 { 3008 rtx reg; 3009 int frame_allocated = 0; 3010 3011 /* The home-grown ABI says link register is saved first. */ 3012 if (save_blink) 3013 { 3014 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); 3015 frame_allocated += frame_save_reg (reg, offset); 3016 offset = 0; 3017 } 3018 3019 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */ 3020 if (gmask) 3021 for (int i = 31; i >= 0; i--) 3022 { 3023 machine_mode save_mode = SImode; 3024 3025 if (TARGET_LL64 3026 && ((i - 1) % 2 == 0) 3027 && ((gmask & (1L << i)) != 0) 3028 && ((gmask & (1L << (i - 1))) != 0)) 3029 { 3030 save_mode = DImode; 3031 --i; 3032 } 3033 else if ((gmask & (1L << i)) == 0) 3034 continue; 3035 3036 reg = gen_rtx_REG (save_mode, i); 3037 frame_allocated += frame_save_reg (reg, offset); 3038 offset = 0; 3039 } 3040 3041 /* Save frame pointer if needed. First save the FP on stack, if not 3042 autosaved. Unfortunately, I cannot add it to gmask and use the 3043 above loop to save fp because our ABI states fp goes aftert all 3044 registers are saved. */ 3045 if (save_fp) 3046 { 3047 frame_allocated += frame_save_reg (hard_frame_pointer_rtx, offset); 3048 offset = 0; 3049 } 3050 3051 /* Emit mov fp,sp. */ 3052 if (arc_frame_pointer_needed ()) 3053 frame_move (hard_frame_pointer_rtx, stack_pointer_rtx); 3054 3055 return frame_allocated; 3056 } 3057 3058 /* ARC's epilogue, restore any required call-saved regs (and call-used 3059 if it is for an interrupt handler) using LD/LDD instructions. */ 3060 3061 static int 3062 arc_restore_callee_saves (unsigned int gmask, 3063 bool restore_blink, 3064 bool restore_fp, 3065 HOST_WIDE_INT offset, 3066 HOST_WIDE_INT allocated) 3067 { 3068 rtx reg; 3069 int frame_deallocated = 0; 3070 HOST_WIDE_INT offs = cfun->machine->frame_info.reg_size; 3071 bool early_blink_restore; 3072 3073 /* Emit mov fp,sp. */ 3074 if (arc_frame_pointer_needed () && offset) 3075 { 3076 frame_move (stack_pointer_rtx, hard_frame_pointer_rtx); 3077 frame_deallocated += offset; 3078 offset = 0; 3079 } 3080 3081 if (restore_fp) 3082 { 3083 /* Any offset is taken care by previous if-statement. */ 3084 gcc_assert (offset == 0); 3085 frame_deallocated += frame_restore_reg (hard_frame_pointer_rtx, 0); 3086 } 3087 3088 if (offset) 3089 { 3090 /* No $fp involved, we need to do an add to set the $sp to the 3091 location of the first register. */ 3092 frame_stack_add (offset); 3093 frame_deallocated += offset; 3094 offset = 0; 3095 } 3096 3097 /* When we do not optimize for size, restore first blink. */ 3098 early_blink_restore = restore_blink && !optimize_size && offs; 3099 if (early_blink_restore) 3100 { 3101 rtx addr = plus_constant (Pmode, stack_pointer_rtx, offs); 3102 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); 3103 rtx insn = frame_move_inc (reg, gen_frame_mem (Pmode, addr), 3104 stack_pointer_rtx, NULL_RTX); 3105 add_reg_note (insn, REG_CFA_RESTORE, reg); 3106 restore_blink = false; 3107 } 3108 3109 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */ 3110 if (gmask) 3111 for (int i = 0; i <= GMASK_LEN; i++) 3112 { 3113 machine_mode restore_mode = SImode; 3114 3115 if (TARGET_LL64 3116 && ((i % 2) == 0) 3117 && ((gmask & (1L << i)) != 0) 3118 && ((gmask & (1L << (i + 1))) != 0)) 3119 restore_mode = DImode; 3120 else if ((gmask & (1L << i)) == 0) 3121 continue; 3122 3123 reg = gen_rtx_REG (restore_mode, i); 3124 offs = 0; 3125 switch (restore_mode) 3126 { 3127 case E_DImode: 3128 if ((GMASK_LEN - __builtin_clz (gmask)) == (i + 1) 3129 && early_blink_restore) 3130 offs = 4; 3131 break; 3132 case E_SImode: 3133 if ((GMASK_LEN - __builtin_clz (gmask)) == i 3134 && early_blink_restore) 3135 offs = 4; 3136 break; 3137 default: 3138 offs = 0; 3139 } 3140 frame_deallocated += frame_restore_reg (reg, offs); 3141 offset = 0; 3142 3143 if (restore_mode == DImode) 3144 i++; 3145 } 3146 3147 if (restore_blink) 3148 { 3149 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); 3150 frame_deallocated += frame_restore_reg (reg, allocated 3151 - frame_deallocated 3152 /* Consider as well the 3153 current restored 3154 register size. */ 3155 - UNITS_PER_WORD); 3156 } 3157 3158 return frame_deallocated; 3159 } 3160 3161 /* ARC prologue, save the registers using enter instruction. Leave 3162 instruction can also save $blink (SAVE_BLINK) and $fp (SAVE_FP) 3163 register. */ 3164 3165 static int 3166 arc_save_callee_enter (unsigned int gmask, 3167 bool save_blink, 3168 bool save_fp, 3169 HOST_WIDE_INT offset) 3170 { 3171 int start_reg = ENTER_LEAVE_START_REG; 3172 int end_reg = ENTER_LEAVE_END_REG; 3173 int regno, indx, off, nregs; 3174 rtx insn, reg, mem; 3175 int frame_allocated = 0; 3176 3177 for (regno = start_reg; regno <= end_reg && (gmask & (1L << regno));) 3178 regno++; 3179 3180 end_reg = regno - 1; 3181 nregs = end_reg - start_reg + 1; 3182 nregs += save_blink ? 1 : 0; 3183 nregs += save_fp ? 1 : 0; 3184 3185 if (offset) 3186 frame_stack_add (offset); 3187 3188 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs + (save_fp ? 1 : 0) 3189 + 1)); 3190 indx = 0; 3191 3192 reg = gen_rtx_SET (stack_pointer_rtx, 3193 plus_constant (Pmode, 3194 stack_pointer_rtx, 3195 -nregs * UNITS_PER_WORD)); 3196 RTX_FRAME_RELATED_P (reg) = 1; 3197 XVECEXP (insn, 0, indx++) = reg; 3198 off = nregs * UNITS_PER_WORD; 3199 3200 if (save_blink) 3201 { 3202 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); 3203 mem = gen_frame_mem (Pmode, plus_constant (Pmode, 3204 stack_pointer_rtx, 3205 off)); 3206 XVECEXP (insn, 0, indx) = gen_rtx_SET (mem, reg); 3207 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx++)) = 1; 3208 off -= UNITS_PER_WORD; 3209 save_blink = false; 3210 } 3211 3212 for (regno = start_reg; 3213 regno <= end_reg; 3214 regno++, indx++, off -= UNITS_PER_WORD) 3215 { 3216 reg = gen_rtx_REG (SImode, regno); 3217 mem = gen_frame_mem (SImode, plus_constant (Pmode, 3218 stack_pointer_rtx, 3219 off)); 3220 XVECEXP (insn, 0, indx) = gen_rtx_SET (mem, reg); 3221 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx)) = 1; 3222 gmask = gmask & ~(1L << regno); 3223 } 3224 3225 if (save_fp) 3226 { 3227 mem = gen_frame_mem (Pmode, plus_constant (Pmode, 3228 stack_pointer_rtx, 3229 off)); 3230 XVECEXP (insn, 0, indx) = gen_rtx_SET (mem, hard_frame_pointer_rtx); 3231 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx++)) = 1; 3232 off -= UNITS_PER_WORD; 3233 3234 XVECEXP (insn, 0, indx) = gen_rtx_SET (hard_frame_pointer_rtx, 3235 stack_pointer_rtx); 3236 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx++)) = 1; 3237 save_fp = false; 3238 } 3239 3240 gcc_assert (off == 0); 3241 insn = frame_insn (insn); 3242 3243 add_reg_note (insn, REG_INC, stack_pointer_rtx); 3244 3245 frame_allocated = nregs * UNITS_PER_WORD; 3246 3247 /* offset is a negative number, make sure we add it. */ 3248 return frame_allocated - offset; 3249 } 3250 3251 /* ARC epilogue, restore the registers using leave instruction. An 3252 initial offset is passed in OFFSET. Besides restoring an register 3253 range, leave can also restore $blink (RESTORE_BLINK), or $fp 3254 (RESTORE_FP), and can automatic return (RETURN_P). */ 3255 3256 static int 3257 arc_restore_callee_leave (unsigned int gmask, 3258 bool restore_blink, 3259 bool restore_fp, 3260 bool return_p, 3261 HOST_WIDE_INT offset) 3262 { 3263 int start_reg = ENTER_LEAVE_START_REG; 3264 int end_reg = ENTER_LEAVE_END_REG; 3265 int regno, indx, off, nregs; 3266 rtx insn, reg, mem; 3267 int frame_allocated = 0; 3268 3269 for (regno = start_reg; regno <= end_reg && (gmask & (1L << regno));) 3270 regno++; 3271 3272 end_reg = regno - 1; 3273 nregs = end_reg - start_reg + 1; 3274 nregs += restore_blink ? 1 : 0; 3275 nregs += restore_fp ? 1 : 0; 3276 3277 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs + 1 3278 + (return_p ? 1 : 0))); 3279 indx = 0; 3280 3281 if (return_p) 3282 XVECEXP (insn, 0, indx++) = ret_rtx; 3283 3284 if (restore_fp) 3285 { 3286 /* I cannot emit set (sp, fp) here as cselib expects a single sp 3287 set and not two. Thus, use the offset, and change sp adjust 3288 value. */ 3289 frame_allocated += offset; 3290 } 3291 3292 if (offset && !restore_fp) 3293 { 3294 /* This add is only emmited when we do not restore fp with leave 3295 instruction. */ 3296 frame_stack_add (offset); 3297 frame_allocated += offset; 3298 offset = 0; 3299 } 3300 3301 reg = gen_rtx_SET (stack_pointer_rtx, 3302 plus_constant (Pmode, 3303 stack_pointer_rtx, 3304 offset + nregs * UNITS_PER_WORD)); 3305 RTX_FRAME_RELATED_P (reg) = 1; 3306 XVECEXP (insn, 0, indx++) = reg; 3307 off = nregs * UNITS_PER_WORD; 3308 3309 if (restore_blink) 3310 { 3311 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); 3312 mem = gen_frame_mem (Pmode, plus_constant (Pmode, 3313 stack_pointer_rtx, 3314 off)); 3315 XVECEXP (insn, 0, indx) = gen_rtx_SET (reg, mem); 3316 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx++)) = 1; 3317 off -= UNITS_PER_WORD; 3318 } 3319 3320 for (regno = start_reg; 3321 regno <= end_reg; 3322 regno++, indx++, off -= UNITS_PER_WORD) 3323 { 3324 reg = gen_rtx_REG (SImode, regno); 3325 mem = gen_frame_mem (SImode, plus_constant (Pmode, 3326 stack_pointer_rtx, 3327 off)); 3328 XVECEXP (insn, 0, indx) = gen_rtx_SET (reg, mem); 3329 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx)) = 1; 3330 gmask = gmask & ~(1L << regno); 3331 } 3332 3333 if (restore_fp) 3334 { 3335 mem = gen_frame_mem (Pmode, plus_constant (Pmode, 3336 stack_pointer_rtx, 3337 off)); 3338 XVECEXP (insn, 0, indx) = gen_rtx_SET (hard_frame_pointer_rtx, mem); 3339 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx++)) = 1; 3340 off -= UNITS_PER_WORD; 3341 } 3342 3343 gcc_assert (off == 0); 3344 if (return_p) 3345 { 3346 insn = emit_jump_insn (insn); 3347 RTX_FRAME_RELATED_P (insn) = 1; 3348 } 3349 else 3350 insn = frame_insn (insn); 3351 3352 add_reg_note (insn, REG_INC, stack_pointer_rtx); 3353 3354 /* Dwarf related info. */ 3355 if (restore_fp) 3356 { 3357 add_reg_note (insn, REG_CFA_RESTORE, hard_frame_pointer_rtx); 3358 add_reg_note (insn, REG_CFA_DEF_CFA, 3359 plus_constant (Pmode, stack_pointer_rtx, 3360 offset + nregs * UNITS_PER_WORD)); 3361 } 3362 else 3363 { 3364 add_reg_note (insn, REG_CFA_ADJUST_CFA, 3365 gen_rtx_SET (stack_pointer_rtx, 3366 plus_constant (Pmode, stack_pointer_rtx, 3367 nregs * UNITS_PER_WORD))); 3368 } 3369 if (restore_blink) 3370 add_reg_note (insn, REG_CFA_RESTORE, 3371 gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM)); 3372 for (regno = start_reg; regno <= end_reg; regno++) 3373 add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (SImode, regno)); 3374 3375 frame_allocated += nregs * UNITS_PER_WORD; 3376 3377 return frame_allocated; 3378 } 3379 3380 /* Millicode thunks implementation: 3381 Generates calls to millicodes for registers starting from r13 to r25 3382 Present Limitations: 3383 - Only one range supported. The remaining regs will have the ordinary 3384 st and ld instructions for store and loads. Hence a gmask asking 3385 to store r13-14, r16-r25 will only generate calls to store and 3386 load r13 to r14 while store and load insns will be generated for 3387 r16 to r25 in the prologue and epilogue respectively. 3388 3389 - Presently library only supports register ranges starting from r13. 3390 */ 3391 3392 static int 3393 arc_save_callee_milli (unsigned int gmask, 3394 bool save_blink, 3395 bool save_fp, 3396 HOST_WIDE_INT offset, 3397 HOST_WIDE_INT reg_size) 3398 { 3399 int start_reg = 13; 3400 int end_reg = 25; 3401 int regno, indx, off, nregs; 3402 rtx insn, reg, mem; 3403 int frame_allocated = 0; 3404 3405 for (regno = start_reg; regno <= end_reg && (gmask & (1L << regno));) 3406 regno++; 3407 3408 end_reg = regno - 1; 3409 nregs = end_reg - start_reg + 1; 3410 gcc_assert (end_reg > 14); 3411 3412 3413 /* Allocate space on stack for the registers, and take into account 3414 also the initial offset. The registers will be saved using 3415 offsets. N.B. OFFSET is a negative number. */ 3416 if (save_blink) 3417 { 3418 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); 3419 frame_allocated += frame_save_reg (reg, offset); 3420 offset = 0; 3421 } 3422 3423 if (reg_size || offset) 3424 { 3425 frame_stack_add (offset - reg_size); 3426 frame_allocated += nregs * UNITS_PER_WORD - offset; 3427 offset = 0; 3428 } 3429 3430 /* Start generate millicode call. */ 3431 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs + 1)); 3432 indx = 0; 3433 3434 /* This is a call, we clobber blink. */ 3435 XVECEXP (insn, 0, nregs) = 3436 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM)); 3437 3438 for (regno = start_reg, indx = 0, off = 0; 3439 regno <= end_reg; 3440 regno++, indx++, off += UNITS_PER_WORD) 3441 { 3442 reg = gen_rtx_REG (SImode, regno); 3443 mem = gen_frame_mem (SImode, plus_constant (Pmode, 3444 stack_pointer_rtx, 3445 off)); 3446 XVECEXP (insn, 0, indx) = gen_rtx_SET (mem, reg); 3447 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx)) = 1; 3448 gmask = gmask & ~(1L << regno); 3449 } 3450 insn = frame_insn (insn); 3451 3452 /* Add DWARF info. */ 3453 for (regno = start_reg, off = 0; 3454 regno <= end_reg; 3455 regno++, off += UNITS_PER_WORD) 3456 { 3457 reg = gen_rtx_REG (SImode, regno); 3458 mem = gen_rtx_MEM (SImode, plus_constant (Pmode, 3459 stack_pointer_rtx, off)); 3460 add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (mem, reg)); 3461 3462 } 3463 3464 /* In the case of millicode thunk, we need to restore the 3465 clobbered blink register. */ 3466 if (arc_must_save_return_addr (cfun)) 3467 { 3468 emit_insn (gen_rtx_SET (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), 3469 gen_rtx_MEM (Pmode, 3470 plus_constant (Pmode, 3471 stack_pointer_rtx, 3472 reg_size)))); 3473 } 3474 3475 /* Save remaining registers using st instructions. */ 3476 for (regno = 0; regno <= 31; regno++) 3477 { 3478 if ((gmask & (1L << regno)) == 0) 3479 continue; 3480 3481 reg = gen_rtx_REG (SImode, regno); 3482 mem = gen_frame_mem (SImode, plus_constant (Pmode, 3483 stack_pointer_rtx, 3484 off)); 3485 frame_move_inc (mem, reg, stack_pointer_rtx, 0); 3486 frame_allocated += UNITS_PER_WORD; 3487 off += UNITS_PER_WORD; 3488 } 3489 3490 /* Save frame pointer if needed. First save the FP on stack, if not 3491 autosaved. Unfortunately, I cannot add it to gmask and use the 3492 above loop to save fp because our ABI states fp goes aftert all 3493 registers are saved. */ 3494 if (save_fp) 3495 frame_allocated += frame_save_reg (hard_frame_pointer_rtx, offset); 3496 3497 /* Emit mov fp,sp. */ 3498 if (arc_frame_pointer_needed ()) 3499 frame_move (hard_frame_pointer_rtx, stack_pointer_rtx); 3500 3501 return frame_allocated; 3502 } 3503 3504 /* Like the previous function but restore. */ 3505 3506 static int 3507 arc_restore_callee_milli (unsigned int gmask, 3508 bool restore_blink, 3509 bool restore_fp, 3510 bool return_p, 3511 HOST_WIDE_INT offset) 3512 { 3513 int start_reg = 13; 3514 int end_reg = 25; 3515 int regno, indx, off, nregs; 3516 rtx insn, reg, mem; 3517 int frame_allocated = 0; 3518 3519 for (regno = start_reg; regno <= end_reg && (gmask & (1L << regno));) 3520 regno++; 3521 3522 end_reg = regno - 1; 3523 nregs = end_reg - start_reg + 1; 3524 gcc_assert (end_reg > 14); 3525 3526 /* Emit mov fp,sp. */ 3527 if (arc_frame_pointer_needed () && offset) 3528 { 3529 frame_move (stack_pointer_rtx, hard_frame_pointer_rtx); 3530 frame_allocated = offset; 3531 offset = 0; 3532 } 3533 3534 if (restore_fp) 3535 frame_allocated += frame_restore_reg (hard_frame_pointer_rtx, 0); 3536 3537 if (offset) 3538 { 3539 /* No fp involved, hence, we need to adjust the sp via an 3540 add. */ 3541 frame_stack_add (offset); 3542 frame_allocated += offset; 3543 offset = 0; 3544 } 3545 3546 /* Start generate millicode call. */ 3547 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc ((return_p ? 1 : 0) 3548 + nregs + 1)); 3549 indx = 0; 3550 3551 if (return_p) 3552 { 3553 /* sibling call, the blink is restored with the help of the 3554 value held into r12. */ 3555 reg = gen_rtx_REG (Pmode, 12); 3556 XVECEXP (insn, 0, indx++) = ret_rtx; 3557 XVECEXP (insn, 0, indx++) = 3558 gen_rtx_SET (stack_pointer_rtx, 3559 gen_rtx_PLUS (Pmode, stack_pointer_rtx, reg)); 3560 frame_allocated += UNITS_PER_WORD; 3561 } 3562 else 3563 { 3564 /* This is a call, we clobber blink. */ 3565 XVECEXP (insn, 0, nregs) = 3566 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM)); 3567 } 3568 3569 for (regno = start_reg, off = 0; 3570 regno <= end_reg; 3571 regno++, indx++, off += UNITS_PER_WORD) 3572 { 3573 reg = gen_rtx_REG (SImode, regno); 3574 mem = gen_frame_mem (SImode, plus_constant (Pmode, 3575 stack_pointer_rtx, 3576 off)); 3577 XVECEXP (insn, 0, indx) = gen_rtx_SET (reg, mem); 3578 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx)) = 1; 3579 gmask = gmask & ~(1L << regno); 3580 } 3581 3582 /* Restore remaining registers using LD instructions. */ 3583 for (regno = 0; regno <= 31; regno++) 3584 { 3585 if ((gmask & (1L << regno)) == 0) 3586 continue; 3587 3588 reg = gen_rtx_REG (SImode, regno); 3589 mem = gen_frame_mem (SImode, plus_constant (Pmode, 3590 stack_pointer_rtx, 3591 off)); 3592 rtx tmp = frame_move_inc (reg, mem, stack_pointer_rtx, 0); 3593 add_reg_note (tmp, REG_CFA_RESTORE, reg); 3594 off += UNITS_PER_WORD; 3595 } 3596 3597 /* Emit millicode call. */ 3598 if (return_p) 3599 { 3600 reg = gen_rtx_REG (Pmode, 12); 3601 frame_insn (gen_rtx_SET (reg, GEN_INT (off))); 3602 frame_allocated += off; 3603 insn = emit_jump_insn (insn); 3604 RTX_FRAME_RELATED_P (insn) = 1; 3605 } 3606 else 3607 insn = frame_insn (insn); 3608 3609 /* Add DWARF info. */ 3610 for (regno = start_reg; regno <= end_reg; regno++) 3611 { 3612 reg = gen_rtx_REG (SImode, regno); 3613 add_reg_note (insn, REG_CFA_RESTORE, reg); 3614 3615 } 3616 3617 if (restore_blink && !return_p) 3618 { 3619 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); 3620 mem = gen_frame_mem (Pmode, plus_constant (Pmode, stack_pointer_rtx, 3621 off)); 3622 insn = frame_insn (gen_rtx_SET (reg, mem)); 3623 add_reg_note (insn, REG_CFA_RESTORE, reg); 3624 } 3625 3626 return frame_allocated; 3627 } 3628 3629 /* Set up the stack and frame pointer (if desired) for the function. */ 3630 3631 void 3632 arc_expand_prologue (void) 3633 { 3634 int size; 3635 unsigned int gmask = cfun->machine->frame_info.gmask; 3636 struct arc_frame_info *frame = &cfun->machine->frame_info; 3637 unsigned int frame_size_to_allocate; 3638 int first_offset = 0; 3639 unsigned int fn_type = arc_compute_function_type (cfun); 3640 bool save_blink = false; 3641 bool save_fp = false; 3642 3643 /* Naked functions don't have prologue. */ 3644 if (ARC_NAKED_P (fn_type)) 3645 { 3646 if (flag_stack_usage_info) 3647 current_function_static_stack_size = 0; 3648 return; 3649 } 3650 3651 /* Compute total frame size. */ 3652 size = arc_compute_frame_size (); 3653 3654 if (flag_stack_usage_info) 3655 current_function_static_stack_size = size; 3656 3657 /* Keep track of frame size to be allocated. */ 3658 frame_size_to_allocate = size; 3659 3660 /* These cases shouldn't happen. Catch them now. */ 3661 gcc_assert (!(size == 0 && gmask)); 3662 3663 /* Allocate space for register arguments if this is a variadic function. */ 3664 if (frame->pretend_size != 0) 3665 first_offset = -frame->pretend_size; 3666 3667 /* IRQ using automatic save mechanism will save the register before 3668 anything we do. */ 3669 if (ARC_AUTO_IRQ_P (fn_type) 3670 && !ARC_FAST_INTERRUPT_P (fn_type)) 3671 { 3672 frame_stack_add (first_offset); 3673 first_offset = 0; 3674 arc_dwarf_emit_irq_save_regs (); 3675 } 3676 3677 save_blink = arc_must_save_return_addr (cfun) 3678 && !ARC_AUTOBLINK_IRQ_P (fn_type); 3679 save_fp = arc_frame_pointer_needed () && !ARC_AUTOFP_IRQ_P (fn_type); 3680 3681 /* Use enter/leave only for non-interrupt functions. */ 3682 if (TARGET_CODE_DENSITY 3683 && TARGET_CODE_DENSITY_FRAME 3684 && !ARC_AUTOFP_IRQ_P (fn_type) 3685 && !ARC_AUTOBLINK_IRQ_P (fn_type) 3686 && !ARC_INTERRUPT_P (fn_type) 3687 && arc_enter_leave_p (gmask)) 3688 frame_size_to_allocate -= arc_save_callee_enter (gmask, save_blink, 3689 save_fp, 3690 first_offset); 3691 else if (frame->millicode_end_reg > 14) 3692 frame_size_to_allocate -= arc_save_callee_milli (gmask, save_blink, 3693 save_fp, 3694 first_offset, 3695 frame->reg_size); 3696 else 3697 frame_size_to_allocate -= arc_save_callee_saves (gmask, save_blink, save_fp, 3698 first_offset); 3699 3700 /* Allocate the stack frame. */ 3701 if (frame_size_to_allocate > 0) 3702 frame_stack_add ((HOST_WIDE_INT) 0 - frame_size_to_allocate); 3703 3704 /* Emit a blockage to avoid delay slot scheduling. */ 3705 emit_insn (gen_blockage ()); 3706 } 3707 3708 /* Do any necessary cleanup after a function to restore stack, frame, 3709 and regs. */ 3710 3711 void 3712 arc_expand_epilogue (int sibcall_p) 3713 { 3714 int size; 3715 unsigned int fn_type = arc_compute_function_type (cfun); 3716 unsigned int size_to_deallocate; 3717 int restored; 3718 int can_trust_sp_p = !cfun->calls_alloca; 3719 int first_offset; 3720 bool restore_fp = arc_frame_pointer_needed () && !ARC_AUTOFP_IRQ_P (fn_type); 3721 bool restore_blink = arc_must_save_return_addr (cfun) 3722 && !ARC_AUTOBLINK_IRQ_P (fn_type); 3723 unsigned int gmask = cfun->machine->frame_info.gmask; 3724 bool return_p = !sibcall_p && fn_type == ARC_FUNCTION_NORMAL 3725 && !cfun->machine->frame_info.pretend_size; 3726 struct arc_frame_info *frame = &cfun->machine->frame_info; 3727 3728 3729 /* Naked functions don't have epilogue. */ 3730 if (ARC_NAKED_P (fn_type)) 3731 return; 3732 3733 size = arc_compute_frame_size (); 3734 size_to_deallocate = size; 3735 3736 first_offset = size - (frame->pretend_size + frame->reg_size 3737 + frame->extra_size); 3738 3739 if (!can_trust_sp_p) 3740 gcc_assert (arc_frame_pointer_needed ()); 3741 3742 /* Emit a blockage to avoid/flush all pending sp operations. */ 3743 if (size) 3744 emit_insn (gen_blockage ()); 3745 3746 if (TARGET_CODE_DENSITY 3747 && TARGET_CODE_DENSITY_FRAME 3748 && !ARC_AUTOFP_IRQ_P (fn_type) 3749 && !ARC_AUTOBLINK_IRQ_P (fn_type) 3750 && !ARC_INTERRUPT_P (fn_type) 3751 && arc_enter_leave_p (gmask)) 3752 { 3753 /* Using leave instruction. */ 3754 size_to_deallocate -= arc_restore_callee_leave (gmask, restore_blink, 3755 restore_fp, 3756 return_p, 3757 first_offset); 3758 if (return_p) 3759 { 3760 gcc_assert (size_to_deallocate == 0); 3761 return; 3762 } 3763 } 3764 else if (frame->millicode_end_reg > 14) 3765 { 3766 /* Using millicode calls. */ 3767 size_to_deallocate -= arc_restore_callee_milli (gmask, restore_blink, 3768 restore_fp, 3769 return_p, 3770 first_offset); 3771 if (return_p) 3772 { 3773 gcc_assert (size_to_deallocate == 0); 3774 return; 3775 } 3776 } 3777 else 3778 size_to_deallocate -= arc_restore_callee_saves (gmask, restore_blink, 3779 restore_fp, 3780 first_offset, 3781 size_to_deallocate); 3782 3783 /* Keep track of how much of the stack pointer we've restored. It 3784 makes the following a lot more readable. */ 3785 restored = size - size_to_deallocate; 3786 3787 if (size > restored) 3788 frame_stack_add (size - restored); 3789 3790 /* For frames that use __builtin_eh_return, the register defined by 3791 EH_RETURN_STACKADJ_RTX is set to 0 for all standard return paths. 3792 On eh_return paths however, the register is set to the value that 3793 should be added to the stack pointer in order to restore the 3794 correct stack pointer for the exception handling frame. 3795 3796 For ARC we are going to use r2 for EH_RETURN_STACKADJ_RTX, add 3797 this onto the stack for eh_return frames. */ 3798 if (crtl->calls_eh_return) 3799 emit_insn (gen_add2_insn (stack_pointer_rtx, 3800 EH_RETURN_STACKADJ_RTX)); 3801 3802 /* Emit the return instruction. */ 3803 if (sibcall_p == FALSE) 3804 emit_jump_insn (gen_simple_return ()); 3805 } 3806 3807 /* Helper for {push/pop}_multi_operand: check if rtx OP is a suitable 3808 construct to match either enter or leave instruction. Which one 3809 which is selected by PUSH_P argument. */ 3810 3811 bool 3812 arc_check_multi (rtx op, bool push_p) 3813 { 3814 HOST_WIDE_INT len = XVECLEN (op, 0); 3815 unsigned int regno, i, start; 3816 unsigned int memp = push_p ? 0 : 1; 3817 rtx elt; 3818 3819 if (len <= 1) 3820 return false; 3821 3822 start = 1; 3823 elt = XVECEXP (op, 0, 0); 3824 if (!push_p && GET_CODE (elt) == RETURN) 3825 start = 2; 3826 3827 for (i = start, regno = ENTER_LEAVE_START_REG; i < len; i++, regno++) 3828 { 3829 rtx elt = XVECEXP (op, 0, i); 3830 rtx reg, mem, addr; 3831 3832 if (GET_CODE (elt) != SET) 3833 return false; 3834 mem = XEXP (elt, memp); 3835 reg = XEXP (elt, 1 - memp); 3836 3837 if (!REG_P (reg) 3838 || !MEM_P (mem)) 3839 return false; 3840 3841 /* Check for blink. */ 3842 if (REGNO (reg) == RETURN_ADDR_REGNUM 3843 && i == start) 3844 regno = 12; 3845 else if (REGNO (reg) == HARD_FRAME_POINTER_REGNUM) 3846 ++i; 3847 else if (REGNO (reg) != regno) 3848 return false; 3849 3850 addr = XEXP (mem, 0); 3851 if (GET_CODE (addr) == PLUS) 3852 { 3853 if (!rtx_equal_p (stack_pointer_rtx, XEXP (addr, 0)) 3854 || !CONST_INT_P (XEXP (addr, 1))) 3855 return false; 3856 } 3857 else 3858 { 3859 if (!rtx_equal_p (stack_pointer_rtx, addr)) 3860 return false; 3861 } 3862 } 3863 return true; 3864 } 3865 3866 /* Return rtx for the location of the return address on the stack, 3867 suitable for use in __builtin_eh_return. The new return address 3868 will be written to this location in order to redirect the return to 3869 the exception handler. Our ABI says the blink is pushed first on 3870 stack followed by an unknown number of register saves, and finally 3871 by fp. Hence we cannot use the EH_RETURN_ADDRESS macro as the 3872 stack is not finalized. */ 3873 3874 void 3875 arc_eh_return_address_location (rtx source) 3876 { 3877 rtx mem; 3878 int offset; 3879 struct arc_frame_info *afi; 3880 3881 arc_compute_frame_size (); 3882 afi = &cfun->machine->frame_info; 3883 3884 gcc_assert (crtl->calls_eh_return); 3885 gcc_assert (afi->save_return_addr); 3886 gcc_assert (afi->extra_size >= 4); 3887 3888 /* The '-4' removes the size of the return address, which is 3889 included in the 'extra_size' field. */ 3890 offset = afi->reg_size + afi->extra_size - 4; 3891 mem = gen_frame_mem (Pmode, 3892 plus_constant (Pmode, hard_frame_pointer_rtx, offset)); 3893 3894 /* The following should not be needed, and is, really a hack. The 3895 issue being worked around here is that the DSE (Dead Store 3896 Elimination) pass will remove this write to the stack as it sees 3897 a single store and no corresponding read. The read however 3898 occurs in the epilogue code, which is not added into the function 3899 rtl until a later pass. So, at the time of DSE, the decision to 3900 remove this store seems perfectly sensible. Marking the memory 3901 address as volatile obviously has the effect of preventing DSE 3902 from removing the store. */ 3903 MEM_VOLATILE_P (mem) = true; 3904 emit_move_insn (mem, source); 3905 } 3906 3907 /* PIC */ 3908 3909 /* Helper to generate unspec constant. */ 3910 3911 static rtx 3912 arc_unspec_offset (rtx loc, int unspec) 3913 { 3914 return gen_rtx_CONST (Pmode, gen_rtx_UNSPEC (Pmode, gen_rtvec (1, loc), 3915 unspec)); 3916 } 3917 3918 /* !TARGET_BARREL_SHIFTER support. */ 3919 /* Emit a shift insn to set OP0 to OP1 shifted by OP2; CODE specifies what 3920 kind of shift. */ 3921 3922 void 3923 emit_shift (enum rtx_code code, rtx op0, rtx op1, rtx op2) 3924 { 3925 rtx shift = gen_rtx_fmt_ee (code, SImode, op1, op2); 3926 rtx pat 3927 = ((shift4_operator (shift, SImode) ? gen_shift_si3 : gen_shift_si3_loop) 3928 (op0, op1, op2, shift)); 3929 emit_insn (pat); 3930 } 3931 3932 /* Output the assembler code for doing a shift. 3933 We go to a bit of trouble to generate efficient code as the ARC601 only has 3934 single bit shifts. This is taken from the h8300 port. We only have one 3935 mode of shifting and can't access individual bytes like the h8300 can, so 3936 this is greatly simplified (at the expense of not generating hyper- 3937 efficient code). 3938 3939 This function is not used if the variable shift insns are present. */ 3940 3941 /* FIXME: This probably can be done using a define_split in arc.md. 3942 Alternately, generate rtx rather than output instructions. */ 3943 3944 const char * 3945 output_shift (rtx *operands) 3946 { 3947 /* static int loopend_lab;*/ 3948 rtx shift = operands[3]; 3949 machine_mode mode = GET_MODE (shift); 3950 enum rtx_code code = GET_CODE (shift); 3951 const char *shift_one; 3952 3953 gcc_assert (mode == SImode); 3954 3955 switch (code) 3956 { 3957 case ASHIFT: shift_one = "add %0,%1,%1"; break; 3958 case ASHIFTRT: shift_one = "asr %0,%1"; break; 3959 case LSHIFTRT: shift_one = "lsr %0,%1"; break; 3960 default: gcc_unreachable (); 3961 } 3962 3963 if (GET_CODE (operands[2]) != CONST_INT) 3964 { 3965 output_asm_insn ("and.f lp_count,%2, 0x1f", operands); 3966 goto shiftloop; 3967 } 3968 else 3969 { 3970 int n; 3971 3972 n = INTVAL (operands[2]); 3973 3974 /* Only consider the lower 5 bits of the shift count. */ 3975 n = n & 0x1f; 3976 3977 /* First see if we can do them inline. */ 3978 /* ??? We could get better scheduling & shorter code (using short insns) 3979 by using splitters. Alas, that'd be even more verbose. */ 3980 if (code == ASHIFT && n <= 9 && n > 2 3981 && dest_reg_operand (operands[4], SImode)) 3982 { 3983 output_asm_insn ("mov %4,0\n\tadd3 %0,%4,%1", operands); 3984 for (n -=3 ; n >= 3; n -= 3) 3985 output_asm_insn ("add3 %0,%4,%0", operands); 3986 if (n == 2) 3987 output_asm_insn ("add2 %0,%4,%0", operands); 3988 else if (n) 3989 output_asm_insn ("add %0,%0,%0", operands); 3990 } 3991 else if (n <= 4) 3992 { 3993 while (--n >= 0) 3994 { 3995 output_asm_insn (shift_one, operands); 3996 operands[1] = operands[0]; 3997 } 3998 } 3999 /* See if we can use a rotate/and. */ 4000 else if (n == BITS_PER_WORD - 1) 4001 { 4002 switch (code) 4003 { 4004 case ASHIFT : 4005 output_asm_insn ("and %0,%1,1\n\tror %0,%0", operands); 4006 break; 4007 case ASHIFTRT : 4008 /* The ARC doesn't have a rol insn. Use something else. */ 4009 output_asm_insn ("add.f 0,%1,%1\n\tsbc %0,%0,%0", operands); 4010 break; 4011 case LSHIFTRT : 4012 /* The ARC doesn't have a rol insn. Use something else. */ 4013 output_asm_insn ("add.f 0,%1,%1\n\trlc %0,0", operands); 4014 break; 4015 default: 4016 break; 4017 } 4018 } 4019 else if (n == BITS_PER_WORD - 2 && dest_reg_operand (operands[4], SImode)) 4020 { 4021 switch (code) 4022 { 4023 case ASHIFT : 4024 output_asm_insn ("and %0,%1,3\n\tror %0,%0\n\tror %0,%0", operands); 4025 break; 4026 case ASHIFTRT : 4027 #if 1 /* Need some scheduling comparisons. */ 4028 output_asm_insn ("add.f %4,%1,%1\n\tsbc %0,%0,%0\n\t" 4029 "add.f 0,%4,%4\n\trlc %0,%0", operands); 4030 #else 4031 output_asm_insn ("add.f %4,%1,%1\n\tbxor %0,%4,31\n\t" 4032 "sbc.f %0,%0,%4\n\trlc %0,%0", operands); 4033 #endif 4034 break; 4035 case LSHIFTRT : 4036 #if 1 4037 output_asm_insn ("add.f %4,%1,%1\n\trlc %0,0\n\t" 4038 "add.f 0,%4,%4\n\trlc %0,%0", operands); 4039 #else 4040 output_asm_insn ("add.f %0,%1,%1\n\trlc.f %0,0\n\t" 4041 "and %0,%0,1\n\trlc %0,%0", operands); 4042 #endif 4043 break; 4044 default: 4045 break; 4046 } 4047 } 4048 else if (n == BITS_PER_WORD - 3 && code == ASHIFT) 4049 output_asm_insn ("and %0,%1,7\n\tror %0,%0\n\tror %0,%0\n\tror %0,%0", 4050 operands); 4051 /* Must loop. */ 4052 else 4053 { 4054 operands[2] = GEN_INT (n); 4055 output_asm_insn ("mov.f lp_count, %2", operands); 4056 4057 shiftloop: 4058 { 4059 output_asm_insn ("lpnz\t2f", operands); 4060 output_asm_insn (shift_one, operands); 4061 output_asm_insn ("nop", operands); 4062 fprintf (asm_out_file, "2:\t%s end single insn loop\n", 4063 ASM_COMMENT_START); 4064 } 4065 } 4066 } 4067 4068 return ""; 4069 } 4070 4071 /* Nested function support. */ 4072 4073 /* Output assembler code for a block containing the constant parts of 4074 a trampoline, leaving space for variable parts. A trampoline looks 4075 like this: 4076 4077 ld_s r12,[pcl,8] 4078 ld r11,[pcl,12] 4079 j_s [r12] 4080 .word function's address 4081 .word static chain value 4082 4083 */ 4084 4085 static void 4086 arc_asm_trampoline_template (FILE *f) 4087 { 4088 asm_fprintf (f, "\tld_s\t%s,[pcl,8]\n", ARC_TEMP_SCRATCH_REG); 4089 asm_fprintf (f, "\tld\t%s,[pcl,12]\n", reg_names[STATIC_CHAIN_REGNUM]); 4090 asm_fprintf (f, "\tj_s\t[%s]\n", ARC_TEMP_SCRATCH_REG); 4091 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx); 4092 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx); 4093 } 4094 4095 /* Emit RTL insns to initialize the variable parts of a trampoline. 4096 FNADDR is an RTX for the address of the function's pure code. CXT 4097 is an RTX for the static chain value for the function. 4098 4099 The fastest trampoline to execute for trampolines within +-8KB of CTX 4100 would be: 4101 4102 add2 r11,pcl,s12 4103 j [limm] 0x20200f80 limm 4104 4105 and that would also be faster to write to the stack by computing 4106 the offset from CTX to TRAMP at compile time. However, it would 4107 really be better to get rid of the high cost of cache invalidation 4108 when generating trampolines, which requires that the code part of 4109 trampolines stays constant, and additionally either making sure 4110 that no executable code but trampolines is on the stack, no icache 4111 entries linger for the area of the stack from when before the stack 4112 was allocated, and allocating trampolines in trampoline-only cache 4113 lines or allocate trampolines fram a special pool of pre-allocated 4114 trampolines. */ 4115 4116 static void 4117 arc_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt) 4118 { 4119 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0); 4120 4121 emit_block_move (tramp, assemble_trampoline_template (), 4122 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL); 4123 emit_move_insn (adjust_address (tramp, SImode, 8), fnaddr); 4124 emit_move_insn (adjust_address (tramp, SImode, 12), cxt); 4125 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__clear_cache"), 4126 LCT_NORMAL, VOIDmode, XEXP (tramp, 0), Pmode, 4127 plus_constant (Pmode, XEXP (tramp, 0), TRAMPOLINE_SIZE), 4128 Pmode); 4129 } 4130 4131 /* Add the given function declaration to emit code in JLI section. */ 4132 4133 static void 4134 arc_add_jli_section (rtx pat) 4135 { 4136 const char *name; 4137 tree attrs; 4138 arc_jli_section *sec = arc_jli_sections, *new_section; 4139 tree decl = SYMBOL_REF_DECL (pat); 4140 4141 if (!pat) 4142 return; 4143 4144 if (decl) 4145 { 4146 /* For fixed locations do not generate the jli table entry. It 4147 should be provided by the user as an asm file. */ 4148 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl)); 4149 if (lookup_attribute ("jli_fixed", attrs)) 4150 return; 4151 } 4152 4153 name = XSTR (pat, 0); 4154 4155 /* Don't insert the same symbol twice. */ 4156 while (sec != NULL) 4157 { 4158 if(strcmp (name, sec->name) == 0) 4159 return; 4160 sec = sec->next; 4161 } 4162 4163 /* New name, insert it. */ 4164 new_section = (arc_jli_section *) xmalloc (sizeof (arc_jli_section)); 4165 gcc_assert (new_section != NULL); 4166 new_section->name = name; 4167 new_section->next = arc_jli_sections; 4168 arc_jli_sections = new_section; 4169 } 4170 4171 /* This is set briefly to 1 when we output a ".as" address modifer, and then 4172 reset when we output the scaled address. */ 4173 static int output_scaled = 0; 4174 4175 /* Set when we force sdata output. */ 4176 static int output_sdata = 0; 4177 4178 /* Print operand X (an rtx) in assembler syntax to file FILE. 4179 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified. 4180 For `%' followed by punctuation, CODE is the punctuation and X is null. */ 4181 /* In final.c:output_asm_insn: 4182 'l' : label 4183 'a' : address 4184 'c' : constant address if CONSTANT_ADDRESS_P 4185 'n' : negative 4186 Here: 4187 'Z': log2(x+1)-1 4188 'z': log2 4189 'M': log2(~x) 4190 'p': bit Position of lsb 4191 's': size of bit field 4192 '#': condbranch delay slot suffix 4193 '*': jump delay slot suffix 4194 '?' : nonjump-insn suffix for conditional execution or short instruction 4195 '!' : jump / call suffix for conditional execution or short instruction 4196 '`': fold constant inside unary o-perator, re-recognize, and emit. 4197 'd' 4198 'D' 4199 'R': Second word 4200 'S': JLI instruction 4201 'j': used by mov instruction to properly emit jli related labels. 4202 'B': Branch comparison operand - suppress sda reference 4203 'H': Most significant word 4204 'L': Least significant word 4205 'A': ASCII decimal representation of floating point value 4206 'U': Load/store update or scaling indicator 4207 'V': cache bypass indicator for volatile 4208 'P' 4209 'F' 4210 '^' 4211 'O': Operator 4212 'o': original symbol - no @ prepending. */ 4213 4214 void 4215 arc_print_operand (FILE *file, rtx x, int code) 4216 { 4217 switch (code) 4218 { 4219 case 'Z': 4220 if (GET_CODE (x) == CONST_INT) 4221 fprintf (file, "%d",exact_log2(INTVAL (x) + 1) - 1 ); 4222 else 4223 output_operand_lossage ("invalid operand to %%Z code"); 4224 4225 return; 4226 4227 case 'z': 4228 if (GET_CODE (x) == CONST_INT) 4229 fprintf (file, "%d",exact_log2(INTVAL (x)) ); 4230 else 4231 output_operand_lossage ("invalid operand to %%z code"); 4232 4233 return; 4234 4235 case 'c': 4236 if (GET_CODE (x) == CONST_INT) 4237 fprintf (file, "%ld", INTVAL (x) ); 4238 else 4239 output_operand_lossage ("invalid operands to %%c code"); 4240 4241 return; 4242 4243 case 'M': 4244 if (GET_CODE (x) == CONST_INT) 4245 fprintf (file, "%d",exact_log2(~INTVAL (x)) ); 4246 else 4247 output_operand_lossage ("invalid operand to %%M code"); 4248 4249 return; 4250 4251 case 'p': 4252 if (GET_CODE (x) == CONST_INT) 4253 fprintf (file, "%d", exact_log2 (INTVAL (x) & -INTVAL (x))); 4254 else 4255 output_operand_lossage ("invalid operand to %%p code"); 4256 return; 4257 4258 case 's': 4259 if (GET_CODE (x) == CONST_INT) 4260 { 4261 HOST_WIDE_INT i = INTVAL (x); 4262 HOST_WIDE_INT s = exact_log2 (i & -i); 4263 fprintf (file, "%d", exact_log2 (((0xffffffffUL & i) >> s) + 1)); 4264 } 4265 else 4266 output_operand_lossage ("invalid operand to %%s code"); 4267 return; 4268 4269 case '#' : 4270 /* Conditional branches depending on condition codes. 4271 Note that this is only for branches that were known to depend on 4272 condition codes before delay slot scheduling; 4273 out-of-range brcc / bbit expansions should use '*'. 4274 This distinction is important because of the different 4275 allowable delay slot insns and the output of the delay suffix 4276 for TARGET_AT_DBR_COND_EXEC. */ 4277 case '*' : 4278 /* Unconditional branches / branches not depending on condition codes. 4279 This could also be a CALL_INSN. 4280 Output the appropriate delay slot suffix. */ 4281 if (final_sequence && final_sequence->len () != 1) 4282 { 4283 rtx_insn *jump = final_sequence->insn (0); 4284 rtx_insn *delay = final_sequence->insn (1); 4285 4286 /* For TARGET_PAD_RETURN we might have grabbed the delay insn. */ 4287 if (delay->deleted ()) 4288 return; 4289 if (JUMP_P (jump) && INSN_ANNULLED_BRANCH_P (jump)) 4290 fputs (INSN_FROM_TARGET_P (delay) ? ".d" 4291 : TARGET_AT_DBR_CONDEXEC && code == '#' ? ".d" 4292 : get_attr_type (jump) == TYPE_RETURN && code == '#' ? "" 4293 : ".nd", 4294 file); 4295 else 4296 fputs (".d", file); 4297 } 4298 return; 4299 case '?' : /* with leading "." */ 4300 case '!' : /* without leading "." */ 4301 /* This insn can be conditionally executed. See if the ccfsm machinery 4302 says it should be conditionalized. 4303 If it shouldn't, we'll check the compact attribute if this insn 4304 has a short variant, which may be used depending on code size and 4305 alignment considerations. */ 4306 if (current_insn_predicate) 4307 arc_ccfsm_current.cc 4308 = get_arc_condition_code (current_insn_predicate); 4309 if (ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current)) 4310 { 4311 /* Is this insn in a delay slot sequence? */ 4312 if (!final_sequence || XVECLEN (final_sequence, 0) < 2 4313 || current_insn_predicate 4314 || CALL_P (final_sequence->insn (0)) 4315 || simplejump_p (final_sequence->insn (0))) 4316 { 4317 /* This insn isn't in a delay slot sequence, or conditionalized 4318 independently of its position in a delay slot. */ 4319 fprintf (file, "%s%s", 4320 code == '?' ? "." : "", 4321 arc_condition_codes[arc_ccfsm_current.cc]); 4322 /* If this is a jump, there are still short variants. However, 4323 only beq_s / bne_s have the same offset range as b_s, 4324 and the only short conditional returns are jeq_s and jne_s. */ 4325 if (code == '!' 4326 && (arc_ccfsm_current.cc == ARC_CC_EQ 4327 || arc_ccfsm_current.cc == ARC_CC_NE 4328 || 0 /* FIXME: check if branch in 7 bit range. */)) 4329 output_short_suffix (file); 4330 } 4331 else if (code == '!') /* Jump with delay slot. */ 4332 fputs (arc_condition_codes[arc_ccfsm_current.cc], file); 4333 else /* An Instruction in a delay slot of a jump or call. */ 4334 { 4335 rtx jump = XVECEXP (final_sequence, 0, 0); 4336 rtx insn = XVECEXP (final_sequence, 0, 1); 4337 4338 /* If the insn is annulled and is from the target path, we need 4339 to inverse the condition test. */ 4340 if (JUMP_P (jump) && INSN_ANNULLED_BRANCH_P (jump)) 4341 { 4342 if (INSN_FROM_TARGET_P (insn)) 4343 fprintf (file, "%s%s", 4344 code == '?' ? "." : "", 4345 arc_condition_codes[ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current.cc)]); 4346 else 4347 fprintf (file, "%s%s", 4348 code == '?' ? "." : "", 4349 arc_condition_codes[arc_ccfsm_current.cc]); 4350 if (arc_ccfsm_current.state == 5) 4351 arc_ccfsm_current.state = 0; 4352 } 4353 else 4354 /* This insn is executed for either path, so don't 4355 conditionalize it at all. */ 4356 output_short_suffix (file); 4357 4358 } 4359 } 4360 else 4361 output_short_suffix (file); 4362 return; 4363 case'`': 4364 /* FIXME: fold constant inside unary operator, re-recognize, and emit. */ 4365 gcc_unreachable (); 4366 case 'd' : 4367 fputs (arc_condition_codes[get_arc_condition_code (x)], file); 4368 return; 4369 case 'D' : 4370 fputs (arc_condition_codes[ARC_INVERSE_CONDITION_CODE 4371 (get_arc_condition_code (x))], 4372 file); 4373 return; 4374 case 'R' : 4375 /* Write second word of DImode or DFmode reference, 4376 register or memory. */ 4377 if (GET_CODE (x) == REG) 4378 fputs (reg_names[REGNO (x)+1], file); 4379 else if (GET_CODE (x) == MEM) 4380 { 4381 fputc ('[', file); 4382 4383 /* Handle possible auto-increment. For PRE_INC / PRE_DEC / 4384 PRE_MODIFY, we will have handled the first word already; 4385 For POST_INC / POST_DEC / POST_MODIFY, the access to the 4386 first word will be done later. In either case, the access 4387 to the first word will do the modify, and we only have 4388 to add an offset of four here. */ 4389 if (GET_CODE (XEXP (x, 0)) == PRE_INC 4390 || GET_CODE (XEXP (x, 0)) == PRE_DEC 4391 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY 4392 || GET_CODE (XEXP (x, 0)) == POST_INC 4393 || GET_CODE (XEXP (x, 0)) == POST_DEC 4394 || GET_CODE (XEXP (x, 0)) == POST_MODIFY) 4395 output_address (VOIDmode, 4396 plus_constant (Pmode, XEXP (XEXP (x, 0), 0), 4)); 4397 else if (output_scaled) 4398 { 4399 rtx addr = XEXP (x, 0); 4400 int size = GET_MODE_SIZE (GET_MODE (x)); 4401 4402 output_address (VOIDmode, 4403 plus_constant (Pmode, XEXP (addr, 0), 4404 ((INTVAL (XEXP (addr, 1)) + 4) 4405 >> (size == 2 ? 1 : 2)))); 4406 output_scaled = 0; 4407 } 4408 else 4409 output_address (VOIDmode, 4410 plus_constant (Pmode, XEXP (x, 0), 4)); 4411 fputc (']', file); 4412 } 4413 else 4414 output_operand_lossage ("invalid operand to %%R code"); 4415 return; 4416 case 'j': 4417 case 'S' : 4418 if (GET_CODE (x) == SYMBOL_REF 4419 && arc_is_jli_call_p (x)) 4420 { 4421 if (SYMBOL_REF_DECL (x)) 4422 { 4423 tree attrs = (TREE_TYPE (SYMBOL_REF_DECL (x)) != error_mark_node 4424 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x))) 4425 : NULL_TREE); 4426 if (lookup_attribute ("jli_fixed", attrs)) 4427 { 4428 /* No special treatment for jli_fixed functions. */ 4429 if (code == 'j') 4430 break; 4431 fprintf (file, "%ld\t; @", 4432 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs)))); 4433 assemble_name (file, XSTR (x, 0)); 4434 return; 4435 } 4436 } 4437 fprintf (file, "@__jli."); 4438 assemble_name (file, XSTR (x, 0)); 4439 if (code == 'j') 4440 arc_add_jli_section (x); 4441 return; 4442 } 4443 if (GET_CODE (x) == SYMBOL_REF 4444 && arc_is_secure_call_p (x)) 4445 { 4446 /* No special treatment for secure functions. */ 4447 if (code == 'j' ) 4448 break; 4449 tree attrs = (TREE_TYPE (SYMBOL_REF_DECL (x)) != error_mark_node 4450 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x))) 4451 : NULL_TREE); 4452 fprintf (file, "%ld\t; @", 4453 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs)))); 4454 assemble_name (file, XSTR (x, 0)); 4455 return; 4456 } 4457 break; 4458 case 'B' /* Branch or other LIMM ref - must not use sda references. */ : 4459 if (CONSTANT_P (x)) 4460 { 4461 output_addr_const (file, x); 4462 return; 4463 } 4464 break; 4465 case 'H' : 4466 case 'L' : 4467 if (GET_CODE (x) == REG) 4468 { 4469 /* L = least significant word, H = most significant word. */ 4470 if ((WORDS_BIG_ENDIAN != 0) ^ (code == 'L')) 4471 fputs (reg_names[REGNO (x)], file); 4472 else 4473 fputs (reg_names[REGNO (x)+1], file); 4474 } 4475 else if (GET_CODE (x) == CONST_INT 4476 || GET_CODE (x) == CONST_DOUBLE) 4477 { 4478 rtx first, second, word; 4479 4480 split_double (x, &first, &second); 4481 4482 if((WORDS_BIG_ENDIAN) == 0) 4483 word = (code == 'L' ? first : second); 4484 else 4485 word = (code == 'L' ? second : first); 4486 4487 fprintf (file, "0x%08" PRIx32, ((uint32_t) INTVAL (word))); 4488 } 4489 else 4490 output_operand_lossage ("invalid operand to %%H/%%L code"); 4491 return; 4492 case 'A' : 4493 { 4494 char str[30]; 4495 4496 gcc_assert (GET_CODE (x) == CONST_DOUBLE 4497 && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT); 4498 4499 real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (x), sizeof (str), 0, 1); 4500 fprintf (file, "%s", str); 4501 return; 4502 } 4503 case 'U' : 4504 /* Output a load/store with update indicator if appropriate. */ 4505 if (GET_CODE (x) == MEM) 4506 { 4507 rtx addr = XEXP (x, 0); 4508 switch (GET_CODE (addr)) 4509 { 4510 case PRE_INC: case PRE_DEC: case PRE_MODIFY: 4511 fputs (".a", file); break; 4512 case POST_INC: case POST_DEC: case POST_MODIFY: 4513 fputs (".ab", file); break; 4514 case PLUS: 4515 /* Are we using a scaled index? */ 4516 if (GET_CODE (XEXP (addr, 0)) == MULT) 4517 fputs (".as", file); 4518 /* Can we use a scaled offset? */ 4519 else if (CONST_INT_P (XEXP (addr, 1)) 4520 && GET_MODE_SIZE (GET_MODE (x)) > 1 4521 && (!(INTVAL (XEXP (addr, 1)) 4522 & (GET_MODE_SIZE (GET_MODE (x)) - 1) & 3)) 4523 /* Does it make a difference? */ 4524 && !SMALL_INT_RANGE(INTVAL (XEXP (addr, 1)), 4525 GET_MODE_SIZE (GET_MODE (x)) - 2, 0)) 4526 { 4527 fputs (".as", file); 4528 output_scaled = 1; 4529 } 4530 break; 4531 case SYMBOL_REF: 4532 case CONST: 4533 if (legitimate_small_data_address_p (addr) 4534 && GET_MODE_SIZE (GET_MODE (x)) > 1) 4535 { 4536 int align = get_symbol_alignment (addr); 4537 int mask = 0; 4538 switch (GET_MODE (x)) 4539 { 4540 case E_HImode: 4541 mask = 1; 4542 break; 4543 default: 4544 mask = 3; 4545 break; 4546 } 4547 if (align && ((align & mask) == 0)) 4548 fputs (".as", file); 4549 } 4550 break; 4551 case REG: 4552 break; 4553 default: 4554 gcc_assert (CONSTANT_P (addr)); break; 4555 } 4556 } 4557 else 4558 output_operand_lossage ("invalid operand to %%U code"); 4559 return; 4560 case 'V' : 4561 /* Output cache bypass indicator for a load/store insn. Volatile memory 4562 refs are defined to use the cache bypass mechanism. */ 4563 if (GET_CODE (x) == MEM) 4564 { 4565 if ((MEM_VOLATILE_P (x) && !TARGET_VOLATILE_CACHE_SET) 4566 || arc_is_uncached_mem_p (x)) 4567 fputs (".di", file); 4568 } 4569 else 4570 output_operand_lossage ("invalid operand to %%V code"); 4571 return; 4572 /* plt code. */ 4573 case 'P': 4574 case 0 : 4575 /* Do nothing special. */ 4576 break; 4577 case 'F': 4578 fputs (reg_names[REGNO (x)]+1, file); 4579 return; 4580 case '^': 4581 /* This punctuation character is needed because label references are 4582 printed in the output template using %l. This is a front end 4583 character, and when we want to emit a '@' before it, we have to use 4584 this '^'. */ 4585 4586 fputc('@',file); 4587 return; 4588 case 'O': 4589 /* Output an operator. */ 4590 switch (GET_CODE (x)) 4591 { 4592 case PLUS: fputs ("add", file); return; 4593 case SS_PLUS: fputs ("adds", file); return; 4594 case AND: fputs ("and", file); return; 4595 case IOR: fputs ("or", file); return; 4596 case XOR: fputs ("xor", file); return; 4597 case MINUS: fputs ("sub", file); return; 4598 case SS_MINUS: fputs ("subs", file); return; 4599 case ASHIFT: fputs ("asl", file); return; 4600 case ASHIFTRT: fputs ("asr", file); return; 4601 case LSHIFTRT: fputs ("lsr", file); return; 4602 case ROTATERT: fputs ("ror", file); return; 4603 case MULT: fputs ("mpy", file); return; 4604 case ABS: fputs ("abs", file); return; /* Unconditional. */ 4605 case NEG: fputs ("neg", file); return; 4606 case SS_NEG: fputs ("negs", file); return; 4607 case NOT: fputs ("not", file); return; /* Unconditional. */ 4608 case ZERO_EXTEND: 4609 fputs ("ext", file); /* bmsk allows predication. */ 4610 goto size_suffix; 4611 case SIGN_EXTEND: /* Unconditional. */ 4612 fputs ("sex", file); 4613 size_suffix: 4614 switch (GET_MODE (XEXP (x, 0))) 4615 { 4616 case E_QImode: fputs ("b", file); return; 4617 case E_HImode: fputs ("w", file); return; 4618 default: break; 4619 } 4620 break; 4621 case SS_TRUNCATE: 4622 if (GET_MODE (x) != HImode) 4623 break; 4624 fputs ("sat16", file); 4625 default: break; 4626 } 4627 output_operand_lossage ("invalid operand to %%O code"); return; 4628 case 'o': 4629 if (GET_CODE (x) == SYMBOL_REF) 4630 { 4631 assemble_name (file, XSTR (x, 0)); 4632 return; 4633 } 4634 break; 4635 case '&': 4636 if (TARGET_ANNOTATE_ALIGN) 4637 fprintf (file, "; unalign: %d", cfun->machine->unalign); 4638 return; 4639 case '+': 4640 if (TARGET_V2) 4641 fputs ("m", file); 4642 else 4643 fputs ("h", file); 4644 return; 4645 case '_': 4646 if (TARGET_V2) 4647 fputs ("h", file); 4648 else 4649 fputs ("w", file); 4650 return; 4651 default : 4652 /* Unknown flag. */ 4653 output_operand_lossage ("invalid operand output code"); 4654 } 4655 4656 switch (GET_CODE (x)) 4657 { 4658 case REG : 4659 fputs (reg_names[REGNO (x)], file); 4660 break; 4661 case MEM : 4662 { 4663 rtx addr = XEXP (x, 0); 4664 int size = GET_MODE_SIZE (GET_MODE (x)); 4665 4666 if (legitimate_small_data_address_p (addr)) 4667 output_sdata = 1; 4668 4669 fputc ('[', file); 4670 4671 switch (GET_CODE (addr)) 4672 { 4673 case PRE_INC: case POST_INC: 4674 output_address (VOIDmode, 4675 plus_constant (Pmode, XEXP (addr, 0), size)); break; 4676 case PRE_DEC: case POST_DEC: 4677 output_address (VOIDmode, 4678 plus_constant (Pmode, XEXP (addr, 0), -size)); 4679 break; 4680 case PRE_MODIFY: case POST_MODIFY: 4681 output_address (VOIDmode, XEXP (addr, 1)); break; 4682 case PLUS: 4683 if (output_scaled) 4684 { 4685 output_address (VOIDmode, 4686 plus_constant (Pmode, XEXP (addr, 0), 4687 (INTVAL (XEXP (addr, 1)) 4688 >> (size == 2 ? 1 : 2)))); 4689 output_scaled = 0; 4690 } 4691 else 4692 output_address (VOIDmode, addr); 4693 break; 4694 default: 4695 if (flag_pic && CONSTANT_ADDRESS_P (addr)) 4696 arc_output_pic_addr_const (file, addr, code); 4697 else 4698 output_address (VOIDmode, addr); 4699 break; 4700 } 4701 fputc (']', file); 4702 break; 4703 } 4704 case CONST_DOUBLE : 4705 /* We handle SFmode constants here as output_addr_const doesn't. */ 4706 if (GET_MODE (x) == SFmode) 4707 { 4708 long l; 4709 4710 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l); 4711 fprintf (file, "0x%08lx", l); 4712 break; 4713 } 4714 /* FALLTHRU */ 4715 /* Let output_addr_const deal with it. */ 4716 default : 4717 if (flag_pic 4718 || (GET_CODE (x) == CONST 4719 && GET_CODE (XEXP (x, 0)) == UNSPEC 4720 && (XINT (XEXP (x, 0), 1) == UNSPEC_TLS_OFF 4721 || XINT (XEXP (x, 0), 1) == UNSPEC_TLS_GD)) 4722 || (GET_CODE (x) == CONST 4723 && GET_CODE (XEXP (x, 0)) == PLUS 4724 && GET_CODE (XEXP (XEXP (x, 0), 0)) == UNSPEC 4725 && (XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_TLS_OFF 4726 || XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_TLS_GD))) 4727 arc_output_pic_addr_const (file, x, code); 4728 else 4729 output_addr_const (file, x); 4730 break; 4731 } 4732 } 4733 4734 /* Print a memory address as an operand to reference that memory location. */ 4735 4736 void 4737 arc_print_operand_address (FILE *file , rtx addr) 4738 { 4739 register rtx base, index = 0; 4740 4741 switch (GET_CODE (addr)) 4742 { 4743 case REG : 4744 fputs (reg_names[REGNO (addr)], file); 4745 break; 4746 case SYMBOL_REF: 4747 if (output_sdata) 4748 fputs ("gp,", file); 4749 output_addr_const (file, addr); 4750 if (output_sdata) 4751 fputs ("@sda", file); 4752 output_sdata = 0; 4753 break; 4754 case PLUS : 4755 if (GET_CODE (XEXP (addr, 0)) == MULT) 4756 index = XEXP (XEXP (addr, 0), 0), base = XEXP (addr, 1); 4757 else if (CONST_INT_P (XEXP (addr, 0))) 4758 index = XEXP (addr, 0), base = XEXP (addr, 1); 4759 else 4760 base = XEXP (addr, 0), index = XEXP (addr, 1); 4761 4762 gcc_assert (OBJECT_P (base)); 4763 arc_print_operand_address (file, base); 4764 if (CONSTANT_P (base) && CONST_INT_P (index)) 4765 fputc ('+', file); 4766 else 4767 fputc (',', file); 4768 gcc_assert (OBJECT_P (index)); 4769 arc_print_operand_address (file, index); 4770 break; 4771 case CONST: 4772 { 4773 rtx c = XEXP (addr, 0); 4774 4775 if ((GET_CODE (c) == UNSPEC 4776 && (XINT (c, 1) == UNSPEC_TLS_OFF 4777 || XINT (c, 1) == UNSPEC_TLS_IE)) 4778 || (GET_CODE (c) == PLUS 4779 && GET_CODE (XEXP (c, 0)) == UNSPEC 4780 && (XINT (XEXP (c, 0), 1) == UNSPEC_TLS_OFF 4781 || XINT (XEXP (c, 0), 1) == ARC_UNSPEC_GOTOFFPC))) 4782 { 4783 arc_output_pic_addr_const (file, c, 0); 4784 break; 4785 } 4786 gcc_assert (GET_CODE (c) == PLUS); 4787 gcc_assert (GET_CODE (XEXP (c, 0)) == SYMBOL_REF); 4788 gcc_assert (GET_CODE (XEXP (c, 1)) == CONST_INT); 4789 4790 output_address (VOIDmode, XEXP (addr, 0)); 4791 4792 break; 4793 } 4794 case PRE_INC : 4795 case PRE_DEC : 4796 /* We shouldn't get here as we've lost the mode of the memory object 4797 (which says how much to inc/dec by. */ 4798 gcc_unreachable (); 4799 break; 4800 default : 4801 if (flag_pic) 4802 arc_output_pic_addr_const (file, addr, 0); 4803 else 4804 output_addr_const (file, addr); 4805 break; 4806 } 4807 } 4808 4809 /* Conditional execution support. 4810 4811 This is based on the ARM port but for now is much simpler. 4812 4813 A finite state machine takes care of noticing whether or not instructions 4814 can be conditionally executed, and thus decrease execution time and code 4815 size by deleting branch instructions. The fsm is controlled by 4816 arc_ccfsm_advance (called by arc_final_prescan_insn), and controls the 4817 actions of PRINT_OPERAND. The patterns in the .md file for the branch 4818 insns also have a hand in this. */ 4819 /* The way we leave dealing with non-anulled or annull-false delay slot 4820 insns to the consumer is awkward. */ 4821 4822 /* The state of the fsm controlling condition codes are: 4823 0: normal, do nothing special 4824 1: don't output this insn 4825 2: don't output this insn 4826 3: make insns conditional 4827 4: make insns conditional 4828 5: make insn conditional (only for outputting anulled delay slot insns) 4829 4830 special value for cfun->machine->uid_ccfsm_state: 4831 6: return with but one insn before it since function start / call 4832 4833 State transitions (state->state by whom, under what condition): 4834 0 -> 1 arc_ccfsm_advance, if insn is a conditional branch skipping over 4835 some instructions. 4836 0 -> 2 arc_ccfsm_advance, if insn is a conditional branch followed 4837 by zero or more non-jump insns and an unconditional branch with 4838 the same target label as the condbranch. 4839 1 -> 3 branch patterns, after having not output the conditional branch 4840 2 -> 4 branch patterns, after having not output the conditional branch 4841 0 -> 5 branch patterns, for anulled delay slot insn. 4842 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL, if the `target' label is reached 4843 (the target label has CODE_LABEL_NUMBER equal to 4844 arc_ccfsm_target_label). 4845 4 -> 0 arc_ccfsm_advance, if `target' unconditional branch is reached 4846 3 -> 1 arc_ccfsm_advance, finding an 'else' jump skipping over some insns. 4847 5 -> 0 when outputting the delay slot insn 4848 4849 If the jump clobbers the conditions then we use states 2 and 4. 4850 4851 A similar thing can be done with conditional return insns. 4852 4853 We also handle separating branches from sets of the condition code. 4854 This is done here because knowledge of the ccfsm state is required, 4855 we may not be outputting the branch. */ 4856 4857 /* arc_final_prescan_insn calls arc_ccfsm_advance to adjust arc_ccfsm_current, 4858 before letting final output INSN. */ 4859 4860 static void 4861 arc_ccfsm_advance (rtx_insn *insn, struct arc_ccfsm *state) 4862 { 4863 /* BODY will hold the body of INSN. */ 4864 register rtx body; 4865 4866 /* This will be 1 if trying to repeat the trick (ie: do the `else' part of 4867 an if/then/else), and things need to be reversed. */ 4868 int reverse = 0; 4869 4870 /* If we start with a return insn, we only succeed if we find another one. */ 4871 int seeking_return = 0; 4872 4873 /* START_INSN will hold the insn from where we start looking. This is the 4874 first insn after the following code_label if REVERSE is true. */ 4875 rtx_insn *start_insn = insn; 4876 4877 /* Type of the jump_insn. Brcc insns don't affect ccfsm changes, 4878 since they don't rely on a cmp preceding the. */ 4879 enum attr_type jump_insn_type; 4880 4881 /* Allow -mdebug-ccfsm to turn this off so we can see how well it does. 4882 We can't do this in macro FINAL_PRESCAN_INSN because its called from 4883 final_scan_insn which has `optimize' as a local. */ 4884 if (optimize < 2 || TARGET_NO_COND_EXEC) 4885 return; 4886 4887 /* Ignore notes and labels. */ 4888 if (!INSN_P (insn)) 4889 return; 4890 body = PATTERN (insn); 4891 /* If in state 4, check if the target branch is reached, in order to 4892 change back to state 0. */ 4893 if (state->state == 4) 4894 { 4895 if (insn == state->target_insn) 4896 { 4897 state->target_insn = NULL; 4898 state->state = 0; 4899 } 4900 return; 4901 } 4902 4903 /* If in state 3, it is possible to repeat the trick, if this insn is an 4904 unconditional branch to a label, and immediately following this branch 4905 is the previous target label which is only used once, and the label this 4906 branch jumps to is not too far off. Or in other words "we've done the 4907 `then' part, see if we can do the `else' part." */ 4908 if (state->state == 3) 4909 { 4910 if (simplejump_p (insn)) 4911 { 4912 start_insn = next_nonnote_insn (start_insn); 4913 if (GET_CODE (start_insn) == BARRIER) 4914 { 4915 /* ??? Isn't this always a barrier? */ 4916 start_insn = next_nonnote_insn (start_insn); 4917 } 4918 if (GET_CODE (start_insn) == CODE_LABEL 4919 && CODE_LABEL_NUMBER (start_insn) == state->target_label 4920 && LABEL_NUSES (start_insn) == 1) 4921 reverse = TRUE; 4922 else 4923 return; 4924 } 4925 else if (GET_CODE (body) == SIMPLE_RETURN) 4926 { 4927 start_insn = next_nonnote_insn (start_insn); 4928 if (GET_CODE (start_insn) == BARRIER) 4929 start_insn = next_nonnote_insn (start_insn); 4930 if (GET_CODE (start_insn) == CODE_LABEL 4931 && CODE_LABEL_NUMBER (start_insn) == state->target_label 4932 && LABEL_NUSES (start_insn) == 1) 4933 { 4934 reverse = TRUE; 4935 seeking_return = 1; 4936 } 4937 else 4938 return; 4939 } 4940 else 4941 return; 4942 } 4943 4944 if (GET_CODE (insn) != JUMP_INSN 4945 || GET_CODE (PATTERN (insn)) == ADDR_VEC 4946 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC) 4947 return; 4948 4949 /* We can't predicate BRCC or loop ends. 4950 Also, when generating PIC code, and considering a medium range call, 4951 we can't predicate the call. */ 4952 jump_insn_type = get_attr_type (insn); 4953 if (jump_insn_type == TYPE_BRCC 4954 || jump_insn_type == TYPE_BRCC_NO_DELAY_SLOT 4955 || jump_insn_type == TYPE_LOOP_END 4956 || (jump_insn_type == TYPE_CALL && !get_attr_predicable (insn))) 4957 return; 4958 4959 /* This jump might be paralleled with a clobber of the condition codes, 4960 the jump should always come first. */ 4961 if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0) 4962 body = XVECEXP (body, 0, 0); 4963 4964 if (reverse 4965 || (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC 4966 && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE)) 4967 { 4968 int insns_skipped = 0, fail = FALSE, succeed = FALSE; 4969 /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */ 4970 int then_not_else = TRUE; 4971 /* Nonzero if next insn must be the target label. */ 4972 int next_must_be_target_label_p; 4973 rtx_insn *this_insn = start_insn; 4974 rtx label = 0; 4975 4976 /* Register the insn jumped to. */ 4977 if (reverse) 4978 { 4979 if (!seeking_return) 4980 label = XEXP (SET_SRC (body), 0); 4981 } 4982 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == LABEL_REF) 4983 label = XEXP (XEXP (SET_SRC (body), 1), 0); 4984 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == LABEL_REF) 4985 { 4986 label = XEXP (XEXP (SET_SRC (body), 2), 0); 4987 then_not_else = FALSE; 4988 } 4989 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == SIMPLE_RETURN) 4990 seeking_return = 1; 4991 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == SIMPLE_RETURN) 4992 { 4993 seeking_return = 1; 4994 then_not_else = FALSE; 4995 } 4996 else 4997 gcc_unreachable (); 4998 4999 /* If this is a non-annulled branch with a delay slot, there is 5000 no need to conditionalize the delay slot. */ 5001 if ((GET_CODE (PATTERN (NEXT_INSN (PREV_INSN (insn)))) == SEQUENCE) 5002 && state->state == 0 && !INSN_ANNULLED_BRANCH_P (insn)) 5003 { 5004 this_insn = NEXT_INSN (this_insn); 5005 } 5006 /* See how many insns this branch skips, and what kind of insns. If all 5007 insns are okay, and the label or unconditional branch to the same 5008 label is not too far away, succeed. */ 5009 for (insns_skipped = 0, next_must_be_target_label_p = FALSE; 5010 !fail && !succeed && insns_skipped < MAX_INSNS_SKIPPED; 5011 insns_skipped++) 5012 { 5013 rtx scanbody; 5014 5015 this_insn = next_nonnote_insn (this_insn); 5016 if (!this_insn) 5017 break; 5018 5019 if (next_must_be_target_label_p) 5020 { 5021 if (GET_CODE (this_insn) == BARRIER) 5022 continue; 5023 if (GET_CODE (this_insn) == CODE_LABEL 5024 && this_insn == label) 5025 { 5026 state->state = 1; 5027 succeed = TRUE; 5028 } 5029 else 5030 fail = TRUE; 5031 break; 5032 } 5033 5034 switch (GET_CODE (this_insn)) 5035 { 5036 case CODE_LABEL: 5037 /* Succeed if it is the target label, otherwise fail since 5038 control falls in from somewhere else. */ 5039 if (this_insn == label) 5040 { 5041 state->state = 1; 5042 succeed = TRUE; 5043 } 5044 else 5045 fail = TRUE; 5046 break; 5047 5048 case BARRIER: 5049 /* Succeed if the following insn is the target label. 5050 Otherwise fail. 5051 If return insns are used then the last insn in a function 5052 will be a barrier. */ 5053 next_must_be_target_label_p = TRUE; 5054 break; 5055 5056 case CALL_INSN: 5057 /* Can handle a call insn if there are no insns after it. 5058 IE: The next "insn" is the target label. We don't have to 5059 worry about delay slots as such insns are SEQUENCE's inside 5060 INSN's. ??? It is possible to handle such insns though. */ 5061 if (get_attr_cond (this_insn) == COND_CANUSE) 5062 next_must_be_target_label_p = TRUE; 5063 else 5064 fail = TRUE; 5065 break; 5066 5067 case JUMP_INSN: 5068 scanbody = PATTERN (this_insn); 5069 5070 /* If this is an unconditional branch to the same label, succeed. 5071 If it is to another label, do nothing. If it is conditional, 5072 fail. */ 5073 /* ??? Probably, the test for the SET and the PC are 5074 unnecessary. */ 5075 5076 if (GET_CODE (scanbody) == SET 5077 && GET_CODE (SET_DEST (scanbody)) == PC) 5078 { 5079 if (GET_CODE (SET_SRC (scanbody)) == LABEL_REF 5080 && XEXP (SET_SRC (scanbody), 0) == label && !reverse) 5081 { 5082 state->state = 2; 5083 succeed = TRUE; 5084 } 5085 else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE) 5086 fail = TRUE; 5087 else if (get_attr_cond (this_insn) != COND_CANUSE) 5088 fail = TRUE; 5089 } 5090 else if (GET_CODE (scanbody) == SIMPLE_RETURN 5091 && seeking_return) 5092 { 5093 state->state = 2; 5094 succeed = TRUE; 5095 } 5096 else if (GET_CODE (scanbody) == PARALLEL) 5097 { 5098 if (get_attr_cond (this_insn) != COND_CANUSE) 5099 fail = TRUE; 5100 } 5101 break; 5102 5103 case INSN: 5104 scanbody = PATTERN (this_insn); 5105 5106 /* We can only do this with insns that can use the condition 5107 codes (and don't set them). */ 5108 if (GET_CODE (scanbody) == SET 5109 || GET_CODE (scanbody) == PARALLEL) 5110 { 5111 if (get_attr_cond (this_insn) != COND_CANUSE) 5112 fail = TRUE; 5113 } 5114 /* We can't handle other insns like sequences. */ 5115 else 5116 fail = TRUE; 5117 break; 5118 5119 default: 5120 break; 5121 } 5122 } 5123 5124 if (succeed) 5125 { 5126 if ((!seeking_return) && (state->state == 1 || reverse)) 5127 state->target_label = CODE_LABEL_NUMBER (label); 5128 else if (seeking_return || state->state == 2) 5129 { 5130 while (this_insn && GET_CODE (PATTERN (this_insn)) == USE) 5131 { 5132 this_insn = next_nonnote_insn (this_insn); 5133 5134 gcc_assert (!this_insn || 5135 (GET_CODE (this_insn) != BARRIER 5136 && GET_CODE (this_insn) != CODE_LABEL)); 5137 } 5138 if (!this_insn) 5139 { 5140 /* Oh dear! we ran off the end, give up. */ 5141 extract_insn_cached (insn); 5142 state->state = 0; 5143 state->target_insn = NULL; 5144 return; 5145 } 5146 state->target_insn = this_insn; 5147 } 5148 else 5149 gcc_unreachable (); 5150 5151 /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from 5152 what it was. */ 5153 if (!reverse) 5154 { 5155 state->cond = XEXP (SET_SRC (body), 0); 5156 state->cc = get_arc_condition_code (XEXP (SET_SRC (body), 0)); 5157 } 5158 5159 if (reverse || then_not_else) 5160 state->cc = ARC_INVERSE_CONDITION_CODE (state->cc); 5161 } 5162 5163 /* Restore recog_operand. Getting the attributes of other insns can 5164 destroy this array, but final.c assumes that it remains intact 5165 across this call; since the insn has been recognized already we 5166 call insn_extract direct. */ 5167 extract_insn_cached (insn); 5168 } 5169 } 5170 5171 /* Record that we are currently outputting label NUM with prefix PREFIX. 5172 It it's the label we're looking for, reset the ccfsm machinery. 5173 5174 Called from ASM_OUTPUT_INTERNAL_LABEL. */ 5175 5176 static void 5177 arc_ccfsm_at_label (const char *prefix, int num, struct arc_ccfsm *state) 5178 { 5179 if (state->state == 3 && state->target_label == num 5180 && !strcmp (prefix, "L")) 5181 { 5182 state->state = 0; 5183 state->target_insn = NULL; 5184 } 5185 } 5186 5187 /* We are considering a conditional branch with the condition COND. 5188 Check if we want to conditionalize a delay slot insn, and if so modify 5189 the ccfsm state accordingly. 5190 REVERSE says branch will branch when the condition is false. */ 5191 void 5192 arc_ccfsm_record_condition (rtx cond, bool reverse, rtx_insn *jump, 5193 struct arc_ccfsm *state) 5194 { 5195 rtx_insn *seq_insn = NEXT_INSN (PREV_INSN (jump)); 5196 if (!state) 5197 state = &arc_ccfsm_current; 5198 5199 gcc_assert (state->state == 0); 5200 if (seq_insn != jump) 5201 { 5202 rtx insn = XVECEXP (PATTERN (seq_insn), 0, 1); 5203 5204 if (!as_a<rtx_insn *> (insn)->deleted () 5205 && INSN_ANNULLED_BRANCH_P (jump) 5206 && (TARGET_AT_DBR_CONDEXEC || INSN_FROM_TARGET_P (insn))) 5207 { 5208 state->cond = cond; 5209 state->cc = get_arc_condition_code (cond); 5210 if (!reverse) 5211 arc_ccfsm_current.cc 5212 = ARC_INVERSE_CONDITION_CODE (state->cc); 5213 rtx pat = PATTERN (insn); 5214 if (GET_CODE (pat) == COND_EXEC) 5215 gcc_assert ((INSN_FROM_TARGET_P (insn) 5216 ? ARC_INVERSE_CONDITION_CODE (state->cc) : state->cc) 5217 == get_arc_condition_code (XEXP (pat, 0))); 5218 else 5219 state->state = 5; 5220 } 5221 } 5222 } 5223 5224 /* Update *STATE as we would when we emit INSN. */ 5225 5226 static void 5227 arc_ccfsm_post_advance (rtx_insn *insn, struct arc_ccfsm *state) 5228 { 5229 enum attr_type type; 5230 5231 if (LABEL_P (insn)) 5232 arc_ccfsm_at_label ("L", CODE_LABEL_NUMBER (insn), state); 5233 else if (JUMP_P (insn) 5234 && GET_CODE (PATTERN (insn)) != ADDR_VEC 5235 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC 5236 && ((type = get_attr_type (insn)) == TYPE_BRANCH 5237 || ((type == TYPE_UNCOND_BRANCH 5238 || type == TYPE_RETURN) 5239 && ARC_CCFSM_BRANCH_DELETED_P (state)))) 5240 { 5241 if (ARC_CCFSM_BRANCH_DELETED_P (state)) 5242 ARC_CCFSM_RECORD_BRANCH_DELETED (state); 5243 else 5244 { 5245 rtx src = SET_SRC (PATTERN (insn)); 5246 arc_ccfsm_record_condition (XEXP (src, 0), XEXP (src, 1) == pc_rtx, 5247 insn, state); 5248 } 5249 } 5250 else if (arc_ccfsm_current.state == 5) 5251 arc_ccfsm_current.state = 0; 5252 } 5253 5254 /* Return true if the current insn, which is a conditional branch, is to be 5255 deleted. */ 5256 5257 bool 5258 arc_ccfsm_branch_deleted_p (void) 5259 { 5260 return ARC_CCFSM_BRANCH_DELETED_P (&arc_ccfsm_current); 5261 } 5262 5263 /* Record a branch isn't output because subsequent insns can be 5264 conditionalized. */ 5265 5266 void 5267 arc_ccfsm_record_branch_deleted (void) 5268 { 5269 ARC_CCFSM_RECORD_BRANCH_DELETED (&arc_ccfsm_current); 5270 } 5271 5272 /* During insn output, indicate if the current insn is predicated. */ 5273 5274 bool 5275 arc_ccfsm_cond_exec_p (void) 5276 { 5277 return (cfun->machine->prescan_initialized 5278 && ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current)); 5279 } 5280 5281 /* When deciding if an insn should be output short, we want to know something 5282 about the following insns: 5283 - if another insn follows which we know we can output as a short insn 5284 before an alignment-sensitive point, we can output this insn short: 5285 the decision about the eventual alignment can be postponed. 5286 - if a to-be-aligned label comes next, we should output this insn such 5287 as to get / preserve 4-byte alignment. 5288 - if a likely branch without delay slot insn, or a call with an immediately 5289 following short insn comes next, we should out output this insn such as to 5290 get / preserve 2 mod 4 unalignment. 5291 - do the same for a not completely unlikely branch with a short insn 5292 following before any other branch / label. 5293 - in order to decide if we are actually looking at a branch, we need to 5294 call arc_ccfsm_advance. 5295 - in order to decide if we are looking at a short insn, we should know 5296 if it is conditionalized. To a first order of approximation this is 5297 the case if the state from arc_ccfsm_advance from before this insn 5298 indicates the insn is conditionalized. However, a further refinement 5299 could be to not conditionalize an insn if the destination register(s) 5300 is/are dead in the non-executed case. */ 5301 /* Return non-zero if INSN should be output as a short insn. UNALIGN is 5302 zero if the current insn is aligned to a 4-byte-boundary, two otherwise. 5303 If CHECK_ATTR is greater than 0, check the iscompact attribute first. */ 5304 5305 static int 5306 arc_verify_short (rtx_insn *insn, int, int check_attr) 5307 { 5308 enum attr_iscompact iscompact; 5309 5310 if (check_attr > 0) 5311 { 5312 iscompact = get_attr_iscompact (insn); 5313 if (iscompact == ISCOMPACT_FALSE) 5314 return 0; 5315 } 5316 5317 return (get_attr_length (insn) & 2) != 0; 5318 } 5319 5320 /* When outputting an instruction (alternative) that can potentially be short, 5321 output the short suffix if the insn is in fact short, and update 5322 cfun->machine->unalign accordingly. */ 5323 5324 static void 5325 output_short_suffix (FILE *file) 5326 { 5327 rtx_insn *insn = current_output_insn; 5328 5329 if (arc_verify_short (insn, cfun->machine->unalign, 1)) 5330 { 5331 fprintf (file, "_s"); 5332 cfun->machine->unalign ^= 2; 5333 } 5334 /* Restore recog_operand. */ 5335 extract_insn_cached (insn); 5336 } 5337 5338 /* Implement FINAL_PRESCAN_INSN. */ 5339 5340 void 5341 arc_final_prescan_insn (rtx_insn *insn, rtx *opvec ATTRIBUTE_UNUSED, 5342 int noperands ATTRIBUTE_UNUSED) 5343 { 5344 if (TARGET_DUMPISIZE) 5345 fprintf (asm_out_file, "\n; at %04x\n", INSN_ADDRESSES (INSN_UID (insn))); 5346 5347 if (!cfun->machine->prescan_initialized) 5348 { 5349 /* Clear lingering state from branch shortening. */ 5350 memset (&arc_ccfsm_current, 0, sizeof arc_ccfsm_current); 5351 cfun->machine->prescan_initialized = 1; 5352 } 5353 arc_ccfsm_advance (insn, &arc_ccfsm_current); 5354 } 5355 5356 /* Given FROM and TO register numbers, say whether this elimination is allowed. 5357 Frame pointer elimination is automatically handled. 5358 5359 All eliminations are permissible. If we need a frame 5360 pointer, we must eliminate ARG_POINTER_REGNUM into 5361 FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM. */ 5362 5363 static bool 5364 arc_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) 5365 { 5366 return ((to == HARD_FRAME_POINTER_REGNUM) || (to == STACK_POINTER_REGNUM)); 5367 } 5368 5369 /* Define the offset between two registers, one to be eliminated, and 5370 the other its replacement, at the start of a routine. */ 5371 5372 int 5373 arc_initial_elimination_offset (int from, int to) 5374 { 5375 if (!cfun->machine->frame_info.initialized) 5376 arc_compute_frame_size (); 5377 5378 if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM) 5379 { 5380 return (cfun->machine->frame_info.extra_size 5381 + cfun->machine->frame_info.reg_size); 5382 } 5383 5384 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM) 5385 { 5386 return (cfun->machine->frame_info.total_size 5387 - cfun->machine->frame_info.pretend_size); 5388 } 5389 5390 if ((from == FRAME_POINTER_REGNUM) && (to == STACK_POINTER_REGNUM)) 5391 { 5392 return (cfun->machine->frame_info.total_size 5393 - (cfun->machine->frame_info.pretend_size 5394 + cfun->machine->frame_info.extra_size 5395 + cfun->machine->frame_info.reg_size)); 5396 } 5397 if ((from == FRAME_POINTER_REGNUM) && (to == HARD_FRAME_POINTER_REGNUM)) 5398 return 0; 5399 5400 gcc_unreachable (); 5401 } 5402 5403 static bool 5404 arc_frame_pointer_required (void) 5405 { 5406 return cfun->calls_alloca || crtl->calls_eh_return; 5407 } 5408 5409 5410 /* Return the destination address of a branch. */ 5411 5412 static int 5413 branch_dest (rtx branch) 5414 { 5415 rtx pat = PATTERN (branch); 5416 rtx dest = (GET_CODE (pat) == PARALLEL 5417 ? SET_SRC (XVECEXP (pat, 0, 0)) : SET_SRC (pat)); 5418 int dest_uid; 5419 5420 if (GET_CODE (dest) == IF_THEN_ELSE) 5421 dest = XEXP (dest, XEXP (dest, 1) == pc_rtx ? 2 : 1); 5422 5423 dest = XEXP (dest, 0); 5424 dest_uid = INSN_UID (dest); 5425 5426 return INSN_ADDRESSES (dest_uid); 5427 } 5428 5429 5430 /* Implement TARGET_ENCODE_SECTION_INFO hook. */ 5431 5432 static void 5433 arc_encode_section_info (tree decl, rtx rtl, int first) 5434 { 5435 /* For sdata, SYMBOL_FLAG_LOCAL and SYMBOL_FLAG_FUNCTION. 5436 This clears machine specific flags, so has to come first. */ 5437 default_encode_section_info (decl, rtl, first); 5438 5439 /* Check if it is a function, and whether it has the 5440 [long/medium/short]_call attribute specified. */ 5441 if (TREE_CODE (decl) == FUNCTION_DECL) 5442 { 5443 rtx symbol = XEXP (rtl, 0); 5444 int flags = SYMBOL_REF_FLAGS (symbol); 5445 5446 tree attr = (TREE_TYPE (decl) != error_mark_node 5447 ? TYPE_ATTRIBUTES (TREE_TYPE (decl)) : NULL_TREE); 5448 tree long_call_attr = lookup_attribute ("long_call", attr); 5449 tree medium_call_attr = lookup_attribute ("medium_call", attr); 5450 tree short_call_attr = lookup_attribute ("short_call", attr); 5451 5452 if (long_call_attr != NULL_TREE) 5453 flags |= SYMBOL_FLAG_LONG_CALL; 5454 else if (medium_call_attr != NULL_TREE) 5455 flags |= SYMBOL_FLAG_MEDIUM_CALL; 5456 else if (short_call_attr != NULL_TREE) 5457 flags |= SYMBOL_FLAG_SHORT_CALL; 5458 5459 SYMBOL_REF_FLAGS (symbol) = flags; 5460 } 5461 else if (TREE_CODE (decl) == VAR_DECL) 5462 { 5463 rtx symbol = XEXP (rtl, 0); 5464 5465 tree attr = (TREE_TYPE (decl) != error_mark_node 5466 ? DECL_ATTRIBUTES (decl) : NULL_TREE); 5467 5468 tree sec_attr = lookup_attribute ("section", attr); 5469 if (sec_attr) 5470 { 5471 const char *sec_name 5472 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr))); 5473 if (strcmp (sec_name, ".cmem") == 0 5474 || strcmp (sec_name, ".cmem_shared") == 0 5475 || strcmp (sec_name, ".cmem_private") == 0) 5476 SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_CMEM; 5477 } 5478 } 5479 } 5480 5481 /* This is how to output a definition of an internal numbered label where 5482 PREFIX is the class of label and NUM is the number within the class. */ 5483 5484 static void arc_internal_label (FILE *stream, const char *prefix, unsigned long labelno) 5485 { 5486 if (cfun) 5487 arc_ccfsm_at_label (prefix, labelno, &arc_ccfsm_current); 5488 default_internal_label (stream, prefix, labelno); 5489 } 5490 5491 /* Set the cpu type and print out other fancy things, 5492 at the top of the file. */ 5493 5494 static void arc_file_start (void) 5495 { 5496 default_file_start (); 5497 fprintf (asm_out_file, "\t.cpu %s\n", arc_cpu_string); 5498 5499 /* Set some want to have build attributes. */ 5500 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_PCS_config, %d\n", 5501 ATTRIBUTE_PCS); 5502 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_rf16, %d\n", 5503 TARGET_RF16 ? 1 : 0); 5504 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_pic, %d\n", 5505 flag_pic ? 2 : 0); 5506 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_tls, %d\n", 5507 (arc_tp_regno != -1) ? 1 : 0); 5508 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_sda, %d\n", 5509 TARGET_NO_SDATA_SET ? 0 : 2); 5510 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_exceptions, %d\n", 5511 TARGET_OPTFPE ? 1 : 0); 5512 if (TARGET_V2) 5513 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_CPU_variation, %d\n", 5514 (arc_tune < ARC_TUNE_CORE_3) ? 2 : 5515 (arc_tune == ARC_TUNE_CORE_3 ? 3 : 4)); 5516 } 5517 5518 /* Implement `TARGET_ASM_FILE_END'. */ 5519 /* Outputs to the stdio stream FILE jli related text. */ 5520 5521 void arc_file_end (void) 5522 { 5523 arc_jli_section *sec = arc_jli_sections; 5524 5525 while (sec != NULL) 5526 { 5527 fprintf (asm_out_file, "\n"); 5528 fprintf (asm_out_file, "# JLI entry for function "); 5529 assemble_name (asm_out_file, sec->name); 5530 fprintf (asm_out_file, "\n\t.section .jlitab, \"axG\", @progbits, " 5531 ".jlitab."); 5532 assemble_name (asm_out_file, sec->name); 5533 fprintf (asm_out_file,", comdat\n"); 5534 5535 fprintf (asm_out_file, "\t.align\t4\n"); 5536 fprintf (asm_out_file, "__jli."); 5537 assemble_name (asm_out_file, sec->name); 5538 fprintf (asm_out_file, ":\n\t.weak __jli."); 5539 assemble_name (asm_out_file, sec->name); 5540 fprintf (asm_out_file, "\n\tb\t@"); 5541 assemble_name (asm_out_file, sec->name); 5542 fprintf (asm_out_file, "\n"); 5543 sec = sec->next; 5544 } 5545 file_end_indicate_exec_stack (); 5546 } 5547 5548 /* Cost functions. */ 5549 5550 /* Compute a (partial) cost for rtx X. Return true if the complete 5551 cost has been computed, and false if subexpressions should be 5552 scanned. In either case, *TOTAL contains the cost result. */ 5553 5554 static bool 5555 arc_rtx_costs (rtx x, machine_mode mode, int outer_code, 5556 int opno ATTRIBUTE_UNUSED, int *total, bool speed) 5557 { 5558 int code = GET_CODE (x); 5559 5560 switch (code) 5561 { 5562 /* Small integers are as cheap as registers. */ 5563 case CONST_INT: 5564 { 5565 bool nolimm = false; /* Can we do without long immediate? */ 5566 bool fast = false; /* Is the result available immediately? */ 5567 bool condexec = false; /* Does this allow conditiobnal execution? */ 5568 bool compact = false; /* Is a 16 bit opcode available? */ 5569 /* CONDEXEC also implies that we can have an unconditional 5570 3-address operation. */ 5571 5572 nolimm = compact = condexec = false; 5573 if (UNSIGNED_INT6 (INTVAL (x))) 5574 nolimm = condexec = compact = true; 5575 else 5576 { 5577 if (SMALL_INT (INTVAL (x))) 5578 nolimm = fast = true; 5579 switch (outer_code) 5580 { 5581 case AND: /* bclr, bmsk, ext[bw] */ 5582 if (satisfies_constraint_Ccp (x) /* bclr */ 5583 || satisfies_constraint_C1p (x) /* bmsk */) 5584 nolimm = fast = condexec = compact = true; 5585 break; 5586 case IOR: /* bset */ 5587 if (satisfies_constraint_C0p (x)) /* bset */ 5588 nolimm = fast = condexec = compact = true; 5589 break; 5590 case XOR: 5591 if (satisfies_constraint_C0p (x)) /* bxor */ 5592 nolimm = fast = condexec = true; 5593 break; 5594 case SET: 5595 if (satisfies_constraint_Crr (x)) /* ror b,u6 */ 5596 nolimm = true; 5597 default: 5598 break; 5599 } 5600 } 5601 /* FIXME: Add target options to attach a small cost if 5602 condexec / compact is not true. */ 5603 if (nolimm) 5604 { 5605 *total = 0; 5606 return true; 5607 } 5608 } 5609 /* FALLTHRU */ 5610 5611 /* 4 byte values can be fetched as immediate constants - 5612 let's give that the cost of an extra insn. */ 5613 case CONST: 5614 case LABEL_REF: 5615 case SYMBOL_REF: 5616 *total = COSTS_N_INSNS (1); 5617 return true; 5618 5619 case CONST_DOUBLE: 5620 { 5621 rtx first, second; 5622 5623 if (TARGET_DPFP) 5624 { 5625 *total = COSTS_N_INSNS (1); 5626 return true; 5627 } 5628 split_double (x, &first, &second); 5629 *total = COSTS_N_INSNS (!SMALL_INT (INTVAL (first)) 5630 + !SMALL_INT (INTVAL (second))); 5631 return true; 5632 } 5633 5634 /* Encourage synth_mult to find a synthetic multiply when reasonable. 5635 If we need more than 12 insns to do a multiply, then go out-of-line, 5636 since the call overhead will be < 10% of the cost of the multiply. */ 5637 case ASHIFT: 5638 case ASHIFTRT: 5639 case LSHIFTRT: 5640 if (TARGET_BARREL_SHIFTER) 5641 { 5642 /* If we want to shift a constant, we need a LIMM. */ 5643 /* ??? when the optimizers want to know if a constant should be 5644 hoisted, they ask for the cost of the constant. OUTER_CODE is 5645 insufficient context for shifts since we don't know which operand 5646 we are looking at. */ 5647 if (CONSTANT_P (XEXP (x, 0))) 5648 { 5649 *total += (COSTS_N_INSNS (2) 5650 + rtx_cost (XEXP (x, 1), mode, (enum rtx_code) code, 5651 0, speed)); 5652 return true; 5653 } 5654 *total = COSTS_N_INSNS (1); 5655 } 5656 else if (GET_CODE (XEXP (x, 1)) != CONST_INT) 5657 *total = COSTS_N_INSNS (16); 5658 else 5659 { 5660 *total = COSTS_N_INSNS (INTVAL (XEXP ((x), 1))); 5661 /* ??? want_to_gcse_p can throw negative shift counts at us, 5662 and then panics when it gets a negative cost as result. 5663 Seen for gcc.c-torture/compile/20020710-1.c -Os . */ 5664 if (*total < 0) 5665 *total = 0; 5666 } 5667 return false; 5668 5669 case DIV: 5670 case UDIV: 5671 if (speed) 5672 *total = COSTS_N_INSNS(30); 5673 else 5674 *total = COSTS_N_INSNS(1); 5675 return false; 5676 5677 case MULT: 5678 if ((TARGET_DPFP && GET_MODE (x) == DFmode)) 5679 *total = COSTS_N_INSNS (1); 5680 else if (speed) 5681 *total= arc_multcost; 5682 /* We do not want synth_mult sequences when optimizing 5683 for size. */ 5684 else if (TARGET_MUL64_SET || TARGET_ARC700_MPY) 5685 *total = COSTS_N_INSNS (1); 5686 else 5687 *total = COSTS_N_INSNS (2); 5688 return false; 5689 case PLUS: 5690 if ((GET_CODE (XEXP (x, 0)) == ASHIFT 5691 && _1_2_3_operand (XEXP (XEXP (x, 0), 1), VOIDmode)) 5692 || (GET_CODE (XEXP (x, 0)) == MULT 5693 && _2_4_8_operand (XEXP (XEXP (x, 0), 1), VOIDmode))) 5694 { 5695 *total += (rtx_cost (XEXP (x, 1), mode, PLUS, 0, speed) 5696 + rtx_cost (XEXP (XEXP (x, 0), 0), mode, PLUS, 1, speed)); 5697 return true; 5698 } 5699 return false; 5700 case MINUS: 5701 if ((GET_CODE (XEXP (x, 1)) == ASHIFT 5702 && _1_2_3_operand (XEXP (XEXP (x, 1), 1), VOIDmode)) 5703 || (GET_CODE (XEXP (x, 1)) == MULT 5704 && _2_4_8_operand (XEXP (XEXP (x, 1), 1), VOIDmode))) 5705 { 5706 *total += (rtx_cost (XEXP (x, 0), mode, PLUS, 0, speed) 5707 + rtx_cost (XEXP (XEXP (x, 1), 0), mode, PLUS, 1, speed)); 5708 return true; 5709 } 5710 return false; 5711 case COMPARE: 5712 { 5713 rtx op0 = XEXP (x, 0); 5714 rtx op1 = XEXP (x, 1); 5715 5716 if (GET_CODE (op0) == ZERO_EXTRACT && op1 == const0_rtx 5717 && XEXP (op0, 1) == const1_rtx) 5718 { 5719 /* btst / bbit0 / bbit1: 5720 Small integers and registers are free; everything else can 5721 be put in a register. */ 5722 mode = GET_MODE (XEXP (op0, 0)); 5723 *total = (rtx_cost (XEXP (op0, 0), mode, SET, 1, speed) 5724 + rtx_cost (XEXP (op0, 2), mode, SET, 1, speed)); 5725 return true; 5726 } 5727 if (GET_CODE (op0) == AND && op1 == const0_rtx 5728 && satisfies_constraint_C1p (XEXP (op0, 1))) 5729 { 5730 /* bmsk.f */ 5731 *total = rtx_cost (XEXP (op0, 0), VOIDmode, SET, 1, speed); 5732 return true; 5733 } 5734 /* add.f */ 5735 if (GET_CODE (op1) == NEG) 5736 { 5737 /* op0 might be constant, the inside of op1 is rather 5738 unlikely to be so. So swapping the operands might lower 5739 the cost. */ 5740 mode = GET_MODE (op0); 5741 *total = (rtx_cost (op0, mode, PLUS, 1, speed) 5742 + rtx_cost (XEXP (op1, 0), mode, PLUS, 0, speed)); 5743 } 5744 return false; 5745 } 5746 case EQ: case NE: 5747 if (outer_code == IF_THEN_ELSE 5748 && GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT 5749 && XEXP (x, 1) == const0_rtx 5750 && XEXP (XEXP (x, 0), 1) == const1_rtx) 5751 { 5752 /* btst / bbit0 / bbit1: 5753 Small integers and registers are free; everything else can 5754 be put in a register. */ 5755 rtx op0 = XEXP (x, 0); 5756 5757 mode = GET_MODE (XEXP (op0, 0)); 5758 *total = (rtx_cost (XEXP (op0, 0), mode, SET, 1, speed) 5759 + rtx_cost (XEXP (op0, 2), mode, SET, 1, speed)); 5760 return true; 5761 } 5762 /* Fall through. */ 5763 /* scc_insn expands into two insns. */ 5764 case GTU: case GEU: case LEU: 5765 if (mode == SImode) 5766 *total += COSTS_N_INSNS (1); 5767 return false; 5768 case LTU: /* might use adc. */ 5769 if (mode == SImode) 5770 *total += COSTS_N_INSNS (1) - 1; 5771 return false; 5772 default: 5773 return false; 5774 } 5775 } 5776 5777 /* Return true if ADDR is a valid pic address. 5778 A valid pic address on arc should look like 5779 const (unspec (SYMBOL_REF/LABEL) (ARC_UNSPEC_GOTOFF/ARC_UNSPEC_GOT)) */ 5780 5781 bool 5782 arc_legitimate_pic_addr_p (rtx addr) 5783 { 5784 if (GET_CODE (addr) != CONST) 5785 return false; 5786 5787 addr = XEXP (addr, 0); 5788 5789 5790 if (GET_CODE (addr) == PLUS) 5791 { 5792 if (GET_CODE (XEXP (addr, 1)) != CONST_INT) 5793 return false; 5794 addr = XEXP (addr, 0); 5795 } 5796 5797 if (GET_CODE (addr) != UNSPEC 5798 || XVECLEN (addr, 0) != 1) 5799 return false; 5800 5801 /* Must be one of @GOT, @GOTOFF, @GOTOFFPC, @tlsgd, tlsie. */ 5802 if (XINT (addr, 1) != ARC_UNSPEC_GOT 5803 && XINT (addr, 1) != ARC_UNSPEC_GOTOFF 5804 && XINT (addr, 1) != ARC_UNSPEC_GOTOFFPC 5805 && XINT (addr, 1) != UNSPEC_TLS_GD 5806 && XINT (addr, 1) != UNSPEC_TLS_IE) 5807 return false; 5808 5809 if (GET_CODE (XVECEXP (addr, 0, 0)) != SYMBOL_REF 5810 && GET_CODE (XVECEXP (addr, 0, 0)) != LABEL_REF) 5811 return false; 5812 5813 return true; 5814 } 5815 5816 5817 5818 /* Return true if OP contains a symbol reference. */ 5819 5820 static bool 5821 symbolic_reference_mentioned_p (rtx op) 5822 { 5823 register const char *fmt; 5824 register int i; 5825 5826 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF) 5827 return true; 5828 5829 fmt = GET_RTX_FORMAT (GET_CODE (op)); 5830 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--) 5831 { 5832 if (fmt[i] == 'E') 5833 { 5834 register int j; 5835 5836 for (j = XVECLEN (op, i) - 1; j >= 0; j--) 5837 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j))) 5838 return true; 5839 } 5840 5841 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i))) 5842 return true; 5843 } 5844 5845 return false; 5846 } 5847 5848 /* Return true if OP contains a SYMBOL_REF that is not wrapped in an unspec. 5849 If SKIP_LOCAL is true, skip symbols that bind locally. 5850 This is used further down in this file, and, without SKIP_LOCAL, 5851 in the addsi3 / subsi3 expanders when generating PIC code. */ 5852 5853 bool 5854 arc_raw_symbolic_reference_mentioned_p (rtx op, bool skip_local) 5855 { 5856 register const char *fmt; 5857 register int i; 5858 5859 if (GET_CODE(op) == UNSPEC) 5860 return false; 5861 5862 if (GET_CODE (op) == SYMBOL_REF) 5863 { 5864 if (SYMBOL_REF_TLS_MODEL (op)) 5865 return true; 5866 if (!flag_pic) 5867 return false; 5868 tree decl = SYMBOL_REF_DECL (op); 5869 return !skip_local || !decl || !default_binds_local_p (decl); 5870 } 5871 5872 fmt = GET_RTX_FORMAT (GET_CODE (op)); 5873 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--) 5874 { 5875 if (fmt[i] == 'E') 5876 { 5877 register int j; 5878 5879 for (j = XVECLEN (op, i) - 1; j >= 0; j--) 5880 if (arc_raw_symbolic_reference_mentioned_p (XVECEXP (op, i, j), 5881 skip_local)) 5882 return true; 5883 } 5884 5885 else if (fmt[i] == 'e' 5886 && arc_raw_symbolic_reference_mentioned_p (XEXP (op, i), 5887 skip_local)) 5888 return true; 5889 } 5890 5891 return false; 5892 } 5893 5894 /* The __tls_get_attr symbol. */ 5895 static GTY(()) rtx arc_tls_symbol; 5896 5897 /* Emit a call to __tls_get_addr. TI is the argument to this function. 5898 RET is an RTX for the return value location. The entire insn sequence 5899 is returned. */ 5900 5901 static rtx 5902 arc_call_tls_get_addr (rtx ti) 5903 { 5904 rtx arg = gen_rtx_REG (Pmode, R0_REG); 5905 rtx ret = gen_rtx_REG (Pmode, R0_REG); 5906 rtx fn; 5907 rtx_insn *insn; 5908 5909 if (!arc_tls_symbol) 5910 arc_tls_symbol = init_one_libfunc ("__tls_get_addr"); 5911 5912 emit_move_insn (arg, ti); 5913 fn = gen_rtx_MEM (SImode, arc_tls_symbol); 5914 insn = emit_call_insn (gen_call_value (ret, fn, const0_rtx)); 5915 RTL_CONST_CALL_P (insn) = 1; 5916 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), ret); 5917 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), arg); 5918 5919 return ret; 5920 } 5921 5922 #define DTPOFF_ZERO_SYM ".tdata" 5923 5924 /* Return a legitimized address for ADDR, 5925 which is a SYMBOL_REF with tls_model MODEL. */ 5926 5927 static rtx 5928 arc_legitimize_tls_address (rtx addr, enum tls_model model) 5929 { 5930 rtx tmp; 5931 5932 if (!flag_pic && model == TLS_MODEL_LOCAL_DYNAMIC) 5933 model = TLS_MODEL_LOCAL_EXEC; 5934 5935 5936 /* The TP pointer needs to be set. */ 5937 gcc_assert (arc_tp_regno != -1); 5938 5939 switch (model) 5940 { 5941 case TLS_MODEL_GLOBAL_DYNAMIC: 5942 tmp = gen_reg_rtx (Pmode); 5943 emit_move_insn (tmp, arc_unspec_offset (addr, UNSPEC_TLS_GD)); 5944 return arc_call_tls_get_addr (tmp); 5945 5946 case TLS_MODEL_LOCAL_DYNAMIC: 5947 rtx base; 5948 tree decl; 5949 const char *base_name; 5950 5951 decl = SYMBOL_REF_DECL (addr); 5952 base_name = DTPOFF_ZERO_SYM; 5953 if (decl && bss_initializer_p (decl)) 5954 base_name = ".tbss"; 5955 5956 base = gen_rtx_SYMBOL_REF (Pmode, base_name); 5957 tmp = gen_reg_rtx (Pmode); 5958 emit_move_insn (tmp, arc_unspec_offset (base, UNSPEC_TLS_GD)); 5959 base = arc_call_tls_get_addr (tmp); 5960 return gen_rtx_PLUS (Pmode, force_reg (Pmode, base), 5961 arc_unspec_offset (addr, UNSPEC_TLS_OFF)); 5962 5963 case TLS_MODEL_INITIAL_EXEC: 5964 addr = arc_unspec_offset (addr, UNSPEC_TLS_IE); 5965 addr = copy_to_mode_reg (Pmode, gen_const_mem (Pmode, addr)); 5966 return gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, arc_tp_regno), addr); 5967 5968 case TLS_MODEL_LOCAL_EXEC: 5969 addr = arc_unspec_offset (addr, UNSPEC_TLS_OFF); 5970 return gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, arc_tp_regno), addr); 5971 5972 default: 5973 gcc_unreachable (); 5974 } 5975 } 5976 5977 /* Return true if SYMBOL_REF X binds locally. */ 5978 5979 static bool 5980 arc_symbol_binds_local_p (const_rtx x) 5981 { 5982 return (SYMBOL_REF_DECL (x) 5983 ? targetm.binds_local_p (SYMBOL_REF_DECL (x)) 5984 : SYMBOL_REF_LOCAL_P (x)); 5985 } 5986 5987 /* Legitimize a pic address reference in ADDR. The return value is 5988 the legitimated address. */ 5989 5990 static rtx 5991 arc_legitimize_pic_address (rtx addr) 5992 { 5993 if (!flag_pic) 5994 return addr; 5995 5996 switch (GET_CODE (addr)) 5997 { 5998 case UNSPEC: 5999 /* Can be one or our GOT or GOTOFFPC unspecs. This situation 6000 happens when an address is not a legitimate constant and we 6001 need the resolve it via force_reg in 6002 prepare_move_operands. */ 6003 switch (XINT (addr, 1)) 6004 { 6005 case ARC_UNSPEC_GOT: 6006 case ARC_UNSPEC_GOTOFFPC: 6007 /* Recover the symbol ref. */ 6008 addr = XVECEXP (addr, 0, 0); 6009 break; 6010 default: 6011 return addr; 6012 } 6013 /* Fall through. */ 6014 case SYMBOL_REF: 6015 /* TLS symbols are handled in different place. */ 6016 if (SYMBOL_REF_TLS_MODEL (addr)) 6017 return addr; 6018 6019 /* This symbol must be referenced via a load from the Global 6020 Offset Table (@GOTPC). */ 6021 if (!arc_symbol_binds_local_p (addr)) 6022 return gen_const_mem (Pmode, arc_unspec_offset (addr, ARC_UNSPEC_GOT)); 6023 6024 /* Local symb: use @pcl to access it. */ 6025 /* Fall through. */ 6026 case LABEL_REF: 6027 return arc_unspec_offset (addr, ARC_UNSPEC_GOTOFFPC); 6028 6029 default: 6030 break; 6031 } 6032 6033 return addr; 6034 } 6035 6036 /* Output address constant X to FILE, taking PIC into account. */ 6037 6038 static void 6039 arc_output_pic_addr_const (FILE * file, rtx x, int code) 6040 { 6041 char buf[256]; 6042 6043 restart: 6044 switch (GET_CODE (x)) 6045 { 6046 case PC: 6047 if (flag_pic) 6048 putc ('.', file); 6049 else 6050 gcc_unreachable (); 6051 break; 6052 6053 case SYMBOL_REF: 6054 output_addr_const (file, x); 6055 6056 /* Local functions do not get references through the PLT. */ 6057 if (code == 'P' && ! SYMBOL_REF_LOCAL_P (x)) 6058 fputs ("@plt", file); 6059 break; 6060 6061 case LABEL_REF: 6062 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0))); 6063 assemble_name (file, buf); 6064 break; 6065 6066 case CODE_LABEL: 6067 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x)); 6068 assemble_name (file, buf); 6069 break; 6070 6071 case CONST_INT: 6072 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x)); 6073 break; 6074 6075 case CONST: 6076 arc_output_pic_addr_const (file, XEXP (x, 0), code); 6077 break; 6078 6079 case CONST_DOUBLE: 6080 if (GET_MODE (x) == VOIDmode) 6081 { 6082 /* We can use %d if the number is one word and positive. */ 6083 if (CONST_DOUBLE_HIGH (x)) 6084 fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX, 6085 CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x)); 6086 else if (CONST_DOUBLE_LOW (x) < 0) 6087 fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (x)); 6088 else 6089 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x)); 6090 } 6091 else 6092 /* We can't handle floating point constants; 6093 PRINT_OPERAND must handle them. */ 6094 output_operand_lossage ("floating constant misused"); 6095 break; 6096 6097 case PLUS: 6098 /* FIXME: Not needed here. */ 6099 /* Some assemblers need integer constants to appear last (eg masm). */ 6100 if (GET_CODE (XEXP (x, 0)) == CONST_INT) 6101 { 6102 arc_output_pic_addr_const (file, XEXP (x, 1), code); 6103 fprintf (file, "+"); 6104 arc_output_pic_addr_const (file, XEXP (x, 0), code); 6105 } 6106 else if (GET_CODE (XEXP (x, 1)) == CONST_INT) 6107 { 6108 arc_output_pic_addr_const (file, XEXP (x, 0), code); 6109 if (INTVAL (XEXP (x, 1)) >= 0) 6110 fprintf (file, "+"); 6111 arc_output_pic_addr_const (file, XEXP (x, 1), code); 6112 } 6113 else 6114 gcc_unreachable(); 6115 break; 6116 6117 case MINUS: 6118 /* Avoid outputting things like x-x or x+5-x, 6119 since some assemblers can't handle that. */ 6120 x = simplify_subtraction (x); 6121 if (GET_CODE (x) != MINUS) 6122 goto restart; 6123 6124 arc_output_pic_addr_const (file, XEXP (x, 0), code); 6125 fprintf (file, "-"); 6126 if (GET_CODE (XEXP (x, 1)) == CONST_INT 6127 && INTVAL (XEXP (x, 1)) < 0) 6128 { 6129 fprintf (file, "("); 6130 arc_output_pic_addr_const (file, XEXP (x, 1), code); 6131 fprintf (file, ")"); 6132 } 6133 else 6134 arc_output_pic_addr_const (file, XEXP (x, 1), code); 6135 break; 6136 6137 case ZERO_EXTEND: 6138 case SIGN_EXTEND: 6139 arc_output_pic_addr_const (file, XEXP (x, 0), code); 6140 break; 6141 6142 6143 case UNSPEC: 6144 const char *suffix; 6145 bool pcrel; pcrel = false; 6146 rtx base; base = NULL; 6147 gcc_assert (XVECLEN (x, 0) >= 1); 6148 switch (XINT (x, 1)) 6149 { 6150 case ARC_UNSPEC_GOT: 6151 suffix = "@gotpc", pcrel = true; 6152 break; 6153 case ARC_UNSPEC_GOTOFF: 6154 suffix = "@gotoff"; 6155 break; 6156 case ARC_UNSPEC_GOTOFFPC: 6157 suffix = "@pcl", pcrel = true; 6158 break; 6159 case ARC_UNSPEC_PLT: 6160 suffix = "@plt"; 6161 break; 6162 case UNSPEC_TLS_GD: 6163 suffix = "@tlsgd", pcrel = true; 6164 break; 6165 case UNSPEC_TLS_IE: 6166 suffix = "@tlsie", pcrel = true; 6167 break; 6168 case UNSPEC_TLS_OFF: 6169 if (XVECLEN (x, 0) == 2) 6170 base = XVECEXP (x, 0, 1); 6171 if (SYMBOL_REF_TLS_MODEL (XVECEXP (x, 0, 0)) == TLS_MODEL_LOCAL_EXEC 6172 || (!flag_pic && !base)) 6173 suffix = "@tpoff"; 6174 else 6175 suffix = "@dtpoff"; 6176 break; 6177 default: 6178 suffix = "@invalid"; 6179 output_operand_lossage ("invalid UNSPEC as operand: %d", XINT (x,1)); 6180 break; 6181 } 6182 if (pcrel) 6183 fputs ("pcl,", file); 6184 arc_output_pic_addr_const (file, XVECEXP (x, 0, 0), code); 6185 fputs (suffix, file); 6186 if (base) 6187 arc_output_pic_addr_const (file, base, code); 6188 break; 6189 6190 default: 6191 output_operand_lossage ("invalid expression as operand"); 6192 } 6193 } 6194 6195 /* The function returning the number of words, at the beginning of an 6196 argument, must be put in registers. The returned value must be 6197 zero for arguments that are passed entirely in registers or that 6198 are entirely pushed on the stack. 6199 6200 On some machines, certain arguments must be passed partially in 6201 registers and partially in memory. On these machines, typically 6202 the first N words of arguments are passed in registers, and the 6203 rest on the stack. If a multi-word argument (a `double' or a 6204 structure) crosses that boundary, its first few words must be 6205 passed in registers and the rest must be pushed. This function 6206 tells the compiler when this occurs, and how many of the words 6207 should go in registers. 6208 6209 `FUNCTION_ARG' for these arguments should return the first register 6210 to be used by the caller for this argument; likewise 6211 `FUNCTION_INCOMING_ARG', for the called function. 6212 6213 The function is used to implement macro FUNCTION_ARG_PARTIAL_NREGS. */ 6214 6215 /* If REGNO is the least arg reg available then what is the total number of arg 6216 regs available. */ 6217 #define GPR_REST_ARG_REGS(REGNO) \ 6218 ((REGNO) <= MAX_ARC_PARM_REGS ? MAX_ARC_PARM_REGS - (REGNO) : 0 ) 6219 6220 /* Since arc parm regs are contiguous. */ 6221 #define ARC_NEXT_ARG_REG(REGNO) ( (REGNO) + 1 ) 6222 6223 /* Implement TARGET_ARG_PARTIAL_BYTES. */ 6224 6225 static int 6226 arc_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode, 6227 tree type, bool named ATTRIBUTE_UNUSED) 6228 { 6229 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 6230 int bytes = (mode == BLKmode 6231 ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode)); 6232 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD; 6233 int arg_num = *cum; 6234 int ret; 6235 6236 arg_num = ROUND_ADVANCE_CUM (arg_num, mode, type); 6237 ret = GPR_REST_ARG_REGS (arg_num); 6238 6239 /* ICEd at function.c:2361, and ret is copied to data->partial */ 6240 ret = (ret >= words ? 0 : ret * UNITS_PER_WORD); 6241 6242 return ret; 6243 } 6244 6245 /* This function is used to control a function argument is passed in a 6246 register, and which register. 6247 6248 The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes 6249 (in a way defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE) 6250 all of the previous arguments so far passed in registers; MODE, the 6251 machine mode of the argument; TYPE, the data type of the argument 6252 as a tree node or 0 if that is not known (which happens for C 6253 support library functions); and NAMED, which is 1 for an ordinary 6254 argument and 0 for nameless arguments that correspond to `...' in 6255 the called function's prototype. 6256 6257 The returned value should either be a `reg' RTX for the hard 6258 register in which to pass the argument, or zero to pass the 6259 argument on the stack. 6260 6261 For machines like the Vax and 68000, where normally all arguments 6262 are pushed, zero suffices as a definition. 6263 6264 The usual way to make the ANSI library `stdarg.h' work on a machine 6265 where some arguments are usually passed in registers, is to cause 6266 nameless arguments to be passed on the stack instead. This is done 6267 by making the function return 0 whenever NAMED is 0. 6268 6269 You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the 6270 definition of this function to determine if this argument is of a 6271 type that must be passed in the stack. If `REG_PARM_STACK_SPACE' 6272 is not defined and the function returns non-zero for such an 6273 argument, the compiler will abort. If `REG_PARM_STACK_SPACE' is 6274 defined, the argument will be computed in the stack and then loaded 6275 into a register. 6276 6277 The function is used to implement macro FUNCTION_ARG. */ 6278 /* On the ARC the first MAX_ARC_PARM_REGS args are normally in registers 6279 and the rest are pushed. */ 6280 6281 static rtx 6282 arc_function_arg (cumulative_args_t cum_v, 6283 machine_mode mode, 6284 const_tree type ATTRIBUTE_UNUSED, 6285 bool named ATTRIBUTE_UNUSED) 6286 { 6287 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 6288 int arg_num = *cum; 6289 rtx ret; 6290 const char *debstr ATTRIBUTE_UNUSED; 6291 6292 arg_num = ROUND_ADVANCE_CUM (arg_num, mode, type); 6293 /* Return a marker for use in the call instruction. */ 6294 if (mode == VOIDmode) 6295 { 6296 ret = const0_rtx; 6297 debstr = "<0>"; 6298 } 6299 else if (GPR_REST_ARG_REGS (arg_num) > 0) 6300 { 6301 ret = gen_rtx_REG (mode, arg_num); 6302 debstr = reg_names [arg_num]; 6303 } 6304 else 6305 { 6306 ret = NULL_RTX; 6307 debstr = "memory"; 6308 } 6309 return ret; 6310 } 6311 6312 /* The function to update the summarizer variable *CUM to advance past 6313 an argument in the argument list. The values MODE, TYPE and NAMED 6314 describe that argument. Once this is done, the variable *CUM is 6315 suitable for analyzing the *following* argument with 6316 `FUNCTION_ARG', etc. 6317 6318 This function need not do anything if the argument in question was 6319 passed on the stack. The compiler knows how to track the amount of 6320 stack space used for arguments without any special help. 6321 6322 The function is used to implement macro FUNCTION_ARG_ADVANCE. */ 6323 /* For the ARC: the cum set here is passed on to function_arg where we 6324 look at its value and say which reg to use. Strategy: advance the 6325 regnumber here till we run out of arg regs, then set *cum to last 6326 reg. In function_arg, since *cum > last arg reg we would return 0 6327 and thus the arg will end up on the stack. For straddling args of 6328 course function_arg_partial_nregs will come into play. */ 6329 6330 static void 6331 arc_function_arg_advance (cumulative_args_t cum_v, 6332 machine_mode mode, 6333 const_tree type, 6334 bool named ATTRIBUTE_UNUSED) 6335 { 6336 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 6337 int bytes = (mode == BLKmode 6338 ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode)); 6339 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD; 6340 int i; 6341 6342 if (words) 6343 *cum = ROUND_ADVANCE_CUM (*cum, mode, type); 6344 for (i = 0; i < words; i++) 6345 *cum = ARC_NEXT_ARG_REG (*cum); 6346 6347 } 6348 6349 /* Define how to find the value returned by a function. 6350 VALTYPE is the data type of the value (as a tree). 6351 If the precise function being called is known, FN_DECL_OR_TYPE is its 6352 FUNCTION_DECL; otherwise, FN_DECL_OR_TYPE is its type. */ 6353 6354 static rtx 6355 arc_function_value (const_tree valtype, 6356 const_tree fn_decl_or_type ATTRIBUTE_UNUSED, 6357 bool outgoing ATTRIBUTE_UNUSED) 6358 { 6359 machine_mode mode = TYPE_MODE (valtype); 6360 int unsignedp ATTRIBUTE_UNUSED; 6361 6362 unsignedp = TYPE_UNSIGNED (valtype); 6363 if (INTEGRAL_TYPE_P (valtype) || TREE_CODE (valtype) == OFFSET_TYPE) 6364 PROMOTE_MODE (mode, unsignedp, valtype); 6365 return gen_rtx_REG (mode, 0); 6366 } 6367 6368 /* Returns the return address that is used by builtin_return_address. */ 6369 6370 rtx 6371 arc_return_addr_rtx (int count, ATTRIBUTE_UNUSED rtx frame) 6372 { 6373 if (count != 0) 6374 return const0_rtx; 6375 6376 return get_hard_reg_initial_val (Pmode , RETURN_ADDR_REGNUM); 6377 } 6378 6379 /* Determine if a given RTX is a valid constant. We already know this 6380 satisfies CONSTANT_P. */ 6381 6382 bool 6383 arc_legitimate_constant_p (machine_mode mode, rtx x) 6384 { 6385 switch (GET_CODE (x)) 6386 { 6387 case CONST: 6388 if (flag_pic) 6389 { 6390 if (arc_legitimate_pic_addr_p (x)) 6391 return true; 6392 } 6393 return arc_legitimate_constant_p (mode, XEXP (x, 0)); 6394 6395 case SYMBOL_REF: 6396 if (SYMBOL_REF_TLS_MODEL (x)) 6397 return false; 6398 /* Fall through. */ 6399 case LABEL_REF: 6400 if (flag_pic) 6401 return false; 6402 /* Fall through. */ 6403 case CONST_INT: 6404 case CONST_DOUBLE: 6405 return true; 6406 6407 case NEG: 6408 return arc_legitimate_constant_p (mode, XEXP (x, 0)); 6409 6410 case PLUS: 6411 case MINUS: 6412 { 6413 bool t1 = arc_legitimate_constant_p (mode, XEXP (x, 0)); 6414 bool t2 = arc_legitimate_constant_p (mode, XEXP (x, 1)); 6415 6416 return (t1 && t2); 6417 } 6418 6419 case CONST_VECTOR: 6420 switch (mode) 6421 { 6422 case E_V2HImode: 6423 return TARGET_PLUS_DMPY; 6424 case E_V2SImode: 6425 case E_V4HImode: 6426 return TARGET_PLUS_QMACW; 6427 default: 6428 return false; 6429 } 6430 6431 case UNSPEC: 6432 switch (XINT (x, 1)) 6433 { 6434 case UNSPEC_TLS_GD: 6435 case UNSPEC_TLS_OFF: 6436 case UNSPEC_TLS_IE: 6437 return true; 6438 default: 6439 /* Any other unspec ending here are pic related, hence the above 6440 constant pic address checking returned false. */ 6441 return false; 6442 } 6443 /* Fall through. */ 6444 6445 default: 6446 fatal_insn ("unrecognized supposed constant", x); 6447 } 6448 6449 gcc_unreachable (); 6450 } 6451 6452 static bool 6453 arc_legitimate_address_p (machine_mode mode, rtx x, bool strict) 6454 { 6455 if (RTX_OK_FOR_BASE_P (x, strict)) 6456 return true; 6457 if (legitimate_offset_address_p (mode, x, TARGET_INDEXED_LOADS, strict)) 6458 return true; 6459 if (legitimate_scaled_address_p (mode, x, strict)) 6460 return true; 6461 if (legitimate_small_data_address_p (x)) 6462 return true; 6463 if (GET_CODE (x) == CONST_INT && LARGE_INT (INTVAL (x))) 6464 return true; 6465 6466 /* When we compile for size avoid const (@sym + offset) 6467 addresses. */ 6468 if (!flag_pic && optimize_size && !reload_completed 6469 && (GET_CODE (x) == CONST) 6470 && (GET_CODE (XEXP (x, 0)) == PLUS) 6471 && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF) 6472 && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0)) == 0 6473 && !SYMBOL_REF_FUNCTION_P (XEXP (XEXP (x, 0), 0))) 6474 { 6475 rtx addend = XEXP (XEXP (x, 0), 1); 6476 gcc_assert (CONST_INT_P (addend)); 6477 HOST_WIDE_INT offset = INTVAL (addend); 6478 6479 /* Allow addresses having a large offset to pass. Anyhow they 6480 will end in a limm. */ 6481 return !(offset > -1024 && offset < 1020); 6482 } 6483 6484 if ((GET_MODE_SIZE (mode) != 16) && CONSTANT_P (x)) 6485 { 6486 return arc_legitimate_constant_p (mode, x); 6487 } 6488 if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == PRE_INC 6489 || GET_CODE (x) == POST_DEC || GET_CODE (x) == POST_INC) 6490 && RTX_OK_FOR_BASE_P (XEXP (x, 0), strict)) 6491 return true; 6492 /* We're restricted here by the `st' insn. */ 6493 if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY) 6494 && GET_CODE (XEXP ((x), 1)) == PLUS 6495 && rtx_equal_p (XEXP ((x), 0), XEXP (XEXP (x, 1), 0)) 6496 && legitimate_offset_address_p (QImode, XEXP (x, 1), 6497 TARGET_AUTO_MODIFY_REG, strict)) 6498 return true; 6499 return false; 6500 } 6501 6502 /* Return true iff ADDR (a legitimate address expression) 6503 has an effect that depends on the machine mode it is used for. */ 6504 6505 static bool 6506 arc_mode_dependent_address_p (const_rtx addr, addr_space_t) 6507 { 6508 /* SYMBOL_REF is not mode dependent: it is either a small data reference, 6509 which is valid for loads and stores, or a limm offset, which is valid for 6510 loads. Scaled indices are scaled by the access mode. */ 6511 if (GET_CODE (addr) == PLUS 6512 && GET_CODE (XEXP ((addr), 0)) == MULT) 6513 return true; 6514 return false; 6515 } 6516 6517 /* Determine if it's legal to put X into the constant pool. */ 6518 6519 static bool 6520 arc_cannot_force_const_mem (machine_mode mode, rtx x) 6521 { 6522 return !arc_legitimate_constant_p (mode, x); 6523 } 6524 6525 /* IDs for all the ARC builtins. */ 6526 6527 enum arc_builtin_id 6528 { 6529 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \ 6530 ARC_BUILTIN_ ## NAME, 6531 #include "builtins.def" 6532 #undef DEF_BUILTIN 6533 6534 ARC_BUILTIN_COUNT 6535 }; 6536 6537 struct GTY(()) arc_builtin_description 6538 { 6539 enum insn_code icode; 6540 int n_args; 6541 tree fndecl; 6542 }; 6543 6544 static GTY(()) struct arc_builtin_description 6545 arc_bdesc[ARC_BUILTIN_COUNT] = 6546 { 6547 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \ 6548 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE }, 6549 #include "builtins.def" 6550 #undef DEF_BUILTIN 6551 }; 6552 6553 /* Transform UP into lowercase and write the result to LO. 6554 You must provide enough space for LO. Return LO. */ 6555 6556 static char* 6557 arc_tolower (char *lo, const char *up) 6558 { 6559 char *lo0 = lo; 6560 6561 for (; *up; up++, lo++) 6562 *lo = TOLOWER (*up); 6563 6564 *lo = '\0'; 6565 6566 return lo0; 6567 } 6568 6569 /* Implement `TARGET_BUILTIN_DECL'. */ 6570 6571 static tree 6572 arc_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED) 6573 { 6574 if (id < ARC_BUILTIN_COUNT) 6575 return arc_bdesc[id].fndecl; 6576 6577 return error_mark_node; 6578 } 6579 6580 static void 6581 arc_init_builtins (void) 6582 { 6583 tree V4HI_type_node; 6584 tree V2SI_type_node; 6585 tree V2HI_type_node; 6586 6587 /* Vector types based on HS SIMD elements. */ 6588 V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode); 6589 V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode); 6590 V2HI_type_node = build_vector_type_for_mode (intHI_type_node, V2HImode); 6591 6592 tree pcvoid_type_node 6593 = build_pointer_type (build_qualified_type (void_type_node, 6594 TYPE_QUAL_CONST)); 6595 tree V8HI_type_node = build_vector_type_for_mode (intHI_type_node, 6596 V8HImode); 6597 6598 tree void_ftype_void 6599 = build_function_type_list (void_type_node, NULL_TREE); 6600 tree int_ftype_int 6601 = build_function_type_list (integer_type_node, integer_type_node, 6602 NULL_TREE); 6603 tree int_ftype_pcvoid_int 6604 = build_function_type_list (integer_type_node, pcvoid_type_node, 6605 integer_type_node, NULL_TREE); 6606 tree void_ftype_usint_usint 6607 = build_function_type_list (void_type_node, long_unsigned_type_node, 6608 long_unsigned_type_node, NULL_TREE); 6609 tree int_ftype_int_int 6610 = build_function_type_list (integer_type_node, integer_type_node, 6611 integer_type_node, NULL_TREE); 6612 tree usint_ftype_usint 6613 = build_function_type_list (long_unsigned_type_node, 6614 long_unsigned_type_node, NULL_TREE); 6615 tree void_ftype_usint 6616 = build_function_type_list (void_type_node, long_unsigned_type_node, 6617 NULL_TREE); 6618 tree int_ftype_void 6619 = build_function_type_list (integer_type_node, void_type_node, 6620 NULL_TREE); 6621 tree void_ftype_int 6622 = build_function_type_list (void_type_node, integer_type_node, 6623 NULL_TREE); 6624 tree int_ftype_short 6625 = build_function_type_list (integer_type_node, short_integer_type_node, 6626 NULL_TREE); 6627 6628 /* Old ARC SIMD types. */ 6629 tree v8hi_ftype_v8hi_v8hi 6630 = build_function_type_list (V8HI_type_node, V8HI_type_node, 6631 V8HI_type_node, NULL_TREE); 6632 tree v8hi_ftype_v8hi_int 6633 = build_function_type_list (V8HI_type_node, V8HI_type_node, 6634 integer_type_node, NULL_TREE); 6635 tree v8hi_ftype_v8hi_int_int 6636 = build_function_type_list (V8HI_type_node, V8HI_type_node, 6637 integer_type_node, integer_type_node, 6638 NULL_TREE); 6639 tree void_ftype_v8hi_int_int 6640 = build_function_type_list (void_type_node, V8HI_type_node, 6641 integer_type_node, integer_type_node, 6642 NULL_TREE); 6643 tree void_ftype_v8hi_int_int_int 6644 = build_function_type_list (void_type_node, V8HI_type_node, 6645 integer_type_node, integer_type_node, 6646 integer_type_node, NULL_TREE); 6647 tree v8hi_ftype_int_int 6648 = build_function_type_list (V8HI_type_node, integer_type_node, 6649 integer_type_node, NULL_TREE); 6650 tree void_ftype_int_int 6651 = build_function_type_list (void_type_node, integer_type_node, 6652 integer_type_node, NULL_TREE); 6653 tree v8hi_ftype_v8hi 6654 = build_function_type_list (V8HI_type_node, V8HI_type_node, 6655 NULL_TREE); 6656 /* ARCv2 SIMD types. */ 6657 tree long_ftype_v4hi_v4hi 6658 = build_function_type_list (long_long_integer_type_node, 6659 V4HI_type_node, V4HI_type_node, NULL_TREE); 6660 tree int_ftype_v2hi_v2hi 6661 = build_function_type_list (integer_type_node, 6662 V2HI_type_node, V2HI_type_node, NULL_TREE); 6663 tree v2si_ftype_v2hi_v2hi 6664 = build_function_type_list (V2SI_type_node, 6665 V2HI_type_node, V2HI_type_node, NULL_TREE); 6666 tree v2hi_ftype_v2hi_v2hi 6667 = build_function_type_list (V2HI_type_node, 6668 V2HI_type_node, V2HI_type_node, NULL_TREE); 6669 tree v2si_ftype_v2si_v2si 6670 = build_function_type_list (V2SI_type_node, 6671 V2SI_type_node, V2SI_type_node, NULL_TREE); 6672 tree v4hi_ftype_v4hi_v4hi 6673 = build_function_type_list (V4HI_type_node, 6674 V4HI_type_node, V4HI_type_node, NULL_TREE); 6675 tree long_ftype_v2si_v2hi 6676 = build_function_type_list (long_long_integer_type_node, 6677 V2SI_type_node, V2HI_type_node, NULL_TREE); 6678 6679 /* Add the builtins. */ 6680 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \ 6681 { \ 6682 int id = ARC_BUILTIN_ ## NAME; \ 6683 const char *Name = "__builtin_arc_" #NAME; \ 6684 char *name = (char*) alloca (1 + strlen (Name)); \ 6685 \ 6686 gcc_assert (id < ARC_BUILTIN_COUNT); \ 6687 if (MASK) \ 6688 arc_bdesc[id].fndecl \ 6689 = add_builtin_function (arc_tolower(name, Name), TYPE, id, \ 6690 BUILT_IN_MD, NULL, NULL_TREE); \ 6691 } 6692 #include "builtins.def" 6693 #undef DEF_BUILTIN 6694 } 6695 6696 /* Helper to expand __builtin_arc_aligned (void* val, int 6697 alignval). */ 6698 6699 static rtx 6700 arc_expand_builtin_aligned (tree exp) 6701 { 6702 tree arg0 = CALL_EXPR_ARG (exp, 0); 6703 tree arg1 = CALL_EXPR_ARG (exp, 1); 6704 fold (arg1); 6705 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL); 6706 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL); 6707 6708 if (!CONST_INT_P (op1)) 6709 { 6710 /* If we can't fold the alignment to a constant integer 6711 whilst optimizing, this is probably a user error. */ 6712 if (optimize) 6713 warning (0, "%<__builtin_arc_aligned%> with non-constant alignment"); 6714 } 6715 else 6716 { 6717 HOST_WIDE_INT alignTest = INTVAL (op1); 6718 /* Check alignTest is positive, and a power of two. */ 6719 if (alignTest <= 0 || alignTest != (alignTest & -alignTest)) 6720 { 6721 error ("invalid alignment value for %<__builtin_arc_aligned%>"); 6722 return NULL_RTX; 6723 } 6724 6725 if (CONST_INT_P (op0)) 6726 { 6727 HOST_WIDE_INT pnt = INTVAL (op0); 6728 6729 if ((pnt & (alignTest - 1)) == 0) 6730 return const1_rtx; 6731 } 6732 else 6733 { 6734 unsigned align = get_pointer_alignment (arg0); 6735 unsigned numBits = alignTest * BITS_PER_UNIT; 6736 6737 if (align && align >= numBits) 6738 return const1_rtx; 6739 /* Another attempt to ascertain alignment. Check the type 6740 we are pointing to. */ 6741 if (POINTER_TYPE_P (TREE_TYPE (arg0)) 6742 && TYPE_ALIGN (TREE_TYPE (TREE_TYPE (arg0))) >= numBits) 6743 return const1_rtx; 6744 } 6745 } 6746 6747 /* Default to false. */ 6748 return const0_rtx; 6749 } 6750 6751 /* Helper arc_expand_builtin, generates a pattern for the given icode 6752 and arguments. */ 6753 6754 static rtx_insn * 6755 apply_GEN_FCN (enum insn_code icode, rtx *arg) 6756 { 6757 switch (insn_data[icode].n_generator_args) 6758 { 6759 case 0: 6760 return GEN_FCN (icode) (); 6761 case 1: 6762 return GEN_FCN (icode) (arg[0]); 6763 case 2: 6764 return GEN_FCN (icode) (arg[0], arg[1]); 6765 case 3: 6766 return GEN_FCN (icode) (arg[0], arg[1], arg[2]); 6767 case 4: 6768 return GEN_FCN (icode) (arg[0], arg[1], arg[2], arg[3]); 6769 case 5: 6770 return GEN_FCN (icode) (arg[0], arg[1], arg[2], arg[3], arg[4]); 6771 default: 6772 gcc_unreachable (); 6773 } 6774 } 6775 6776 /* Expand an expression EXP that calls a built-in function, 6777 with result going to TARGET if that's convenient 6778 (and in mode MODE if that's convenient). 6779 SUBTARGET may be used as the target for computing one of EXP's operands. 6780 IGNORE is nonzero if the value is to be ignored. */ 6781 6782 static rtx 6783 arc_expand_builtin (tree exp, 6784 rtx target, 6785 rtx subtarget ATTRIBUTE_UNUSED, 6786 machine_mode mode ATTRIBUTE_UNUSED, 6787 int ignore ATTRIBUTE_UNUSED) 6788 { 6789 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 6790 unsigned int id = DECL_FUNCTION_CODE (fndecl); 6791 const struct arc_builtin_description *d = &arc_bdesc[id]; 6792 int i, j, n_args = call_expr_nargs (exp); 6793 rtx pat = NULL_RTX; 6794 rtx xop[5]; 6795 enum insn_code icode = d->icode; 6796 machine_mode tmode = insn_data[icode].operand[0].mode; 6797 int nonvoid; 6798 tree arg0; 6799 tree arg1; 6800 tree arg2; 6801 tree arg3; 6802 rtx op0; 6803 rtx op1; 6804 rtx op2; 6805 rtx op3; 6806 rtx op4; 6807 machine_mode mode0; 6808 machine_mode mode1; 6809 machine_mode mode2; 6810 machine_mode mode3; 6811 machine_mode mode4; 6812 6813 if (id >= ARC_BUILTIN_COUNT) 6814 internal_error ("bad builtin fcode"); 6815 6816 /* 1st part: Expand special builtins. */ 6817 switch (id) 6818 { 6819 case ARC_BUILTIN_NOP: 6820 emit_insn (gen_nopv ()); 6821 return NULL_RTX; 6822 6823 case ARC_BUILTIN_RTIE: 6824 case ARC_BUILTIN_SYNC: 6825 case ARC_BUILTIN_BRK: 6826 case ARC_BUILTIN_SWI: 6827 case ARC_BUILTIN_UNIMP_S: 6828 gcc_assert (icode != 0); 6829 emit_insn (GEN_FCN (icode) (const1_rtx)); 6830 return NULL_RTX; 6831 6832 case ARC_BUILTIN_ALIGNED: 6833 return arc_expand_builtin_aligned (exp); 6834 6835 case ARC_BUILTIN_CLRI: 6836 target = gen_reg_rtx (SImode); 6837 emit_insn (gen_clri (target, const1_rtx)); 6838 return target; 6839 6840 case ARC_BUILTIN_TRAP_S: 6841 case ARC_BUILTIN_SLEEP: 6842 arg0 = CALL_EXPR_ARG (exp, 0); 6843 fold (arg0); 6844 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL); 6845 6846 gcc_assert (icode != 0); 6847 emit_insn (GEN_FCN (icode) (op0)); 6848 return NULL_RTX; 6849 6850 case ARC_BUILTIN_VDORUN: 6851 case ARC_BUILTIN_VDIRUN: 6852 arg0 = CALL_EXPR_ARG (exp, 0); 6853 arg1 = CALL_EXPR_ARG (exp, 1); 6854 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL); 6855 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL); 6856 6857 target = gen_rtx_REG (SImode, (id == ARC_BUILTIN_VDIRUN) ? 131 : 139); 6858 6859 mode0 = insn_data[icode].operand[1].mode; 6860 mode1 = insn_data[icode].operand[2].mode; 6861 6862 if (!insn_data[icode].operand[1].predicate (op0, mode0)) 6863 op0 = copy_to_mode_reg (mode0, op0); 6864 6865 if (!insn_data[icode].operand[2].predicate (op1, mode1)) 6866 op1 = copy_to_mode_reg (mode1, op1); 6867 6868 pat = GEN_FCN (icode) (target, op0, op1); 6869 if (!pat) 6870 return NULL_RTX; 6871 6872 emit_insn (pat); 6873 return NULL_RTX; 6874 6875 case ARC_BUILTIN_VDIWR: 6876 case ARC_BUILTIN_VDOWR: 6877 arg0 = CALL_EXPR_ARG (exp, 0); 6878 arg1 = CALL_EXPR_ARG (exp, 1); 6879 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL); 6880 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL); 6881 6882 if (!CONST_INT_P (op0) 6883 || !(UNSIGNED_INT3 (INTVAL (op0)))) 6884 error ("operand 1 should be an unsigned 3-bit immediate"); 6885 6886 mode1 = insn_data[icode].operand[1].mode; 6887 6888 if (icode == CODE_FOR_vdiwr_insn) 6889 target = gen_rtx_REG (SImode, 6890 ARC_FIRST_SIMD_DMA_CONFIG_IN_REG + INTVAL (op0)); 6891 else if (icode == CODE_FOR_vdowr_insn) 6892 target = gen_rtx_REG (SImode, 6893 ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG + INTVAL (op0)); 6894 else 6895 gcc_unreachable (); 6896 6897 if (!insn_data[icode].operand[2].predicate (op1, mode1)) 6898 op1 = copy_to_mode_reg (mode1, op1); 6899 6900 pat = GEN_FCN (icode) (target, op1); 6901 if (!pat) 6902 return NULL_RTX; 6903 6904 emit_insn (pat); 6905 return NULL_RTX; 6906 6907 case ARC_BUILTIN_VASRW: 6908 case ARC_BUILTIN_VSR8: 6909 case ARC_BUILTIN_VSR8AW: 6910 arg0 = CALL_EXPR_ARG (exp, 0); 6911 arg1 = CALL_EXPR_ARG (exp, 1); 6912 op0 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL); 6913 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL); 6914 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG); 6915 6916 target = gen_reg_rtx (V8HImode); 6917 mode0 = insn_data[icode].operand[1].mode; 6918 mode1 = insn_data[icode].operand[2].mode; 6919 6920 if (!insn_data[icode].operand[1].predicate (op0, mode0)) 6921 op0 = copy_to_mode_reg (mode0, op0); 6922 6923 if ((!insn_data[icode].operand[2].predicate (op1, mode1)) 6924 || !(UNSIGNED_INT3 (INTVAL (op1)))) 6925 error ("operand 2 should be an unsigned 3-bit value (I0-I7)"); 6926 6927 pat = GEN_FCN (icode) (target, op0, op1, op2); 6928 if (!pat) 6929 return NULL_RTX; 6930 6931 emit_insn (pat); 6932 return target; 6933 6934 case ARC_BUILTIN_VLD32WH: 6935 case ARC_BUILTIN_VLD32WL: 6936 case ARC_BUILTIN_VLD64: 6937 case ARC_BUILTIN_VLD32: 6938 rtx src_vreg; 6939 icode = d->icode; 6940 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg. */ 6941 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */ 6942 arg2 = CALL_EXPR_ARG (exp, 2); /* u8. */ 6943 6944 src_vreg = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL); 6945 op0 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL); 6946 op1 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL); 6947 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG); 6948 6949 /* target <- src vreg. */ 6950 emit_insn (gen_move_insn (target, src_vreg)); 6951 6952 /* target <- vec_concat: target, mem (Ib, u8). */ 6953 mode0 = insn_data[icode].operand[3].mode; 6954 mode1 = insn_data[icode].operand[1].mode; 6955 6956 if ((!insn_data[icode].operand[3].predicate (op0, mode0)) 6957 || !(UNSIGNED_INT3 (INTVAL (op0)))) 6958 error ("operand 1 should be an unsigned 3-bit value (I0-I7)"); 6959 6960 if ((!insn_data[icode].operand[1].predicate (op1, mode1)) 6961 || !(UNSIGNED_INT8 (INTVAL (op1)))) 6962 error ("operand 2 should be an unsigned 8-bit value"); 6963 6964 pat = GEN_FCN (icode) (target, op1, op2, op0); 6965 if (!pat) 6966 return NULL_RTX; 6967 6968 emit_insn (pat); 6969 return target; 6970 6971 case ARC_BUILTIN_VLD64W: 6972 case ARC_BUILTIN_VLD128: 6973 arg0 = CALL_EXPR_ARG (exp, 0); /* dest vreg. */ 6974 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */ 6975 6976 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG); 6977 op1 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL); 6978 op2 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL); 6979 6980 /* target <- src vreg. */ 6981 target = gen_reg_rtx (V8HImode); 6982 6983 /* target <- vec_concat: target, mem (Ib, u8). */ 6984 mode0 = insn_data[icode].operand[1].mode; 6985 mode1 = insn_data[icode].operand[2].mode; 6986 mode2 = insn_data[icode].operand[3].mode; 6987 6988 if ((!insn_data[icode].operand[2].predicate (op1, mode1)) 6989 || !(UNSIGNED_INT3 (INTVAL (op1)))) 6990 error ("operand 1 should be an unsigned 3-bit value (I0-I7)"); 6991 6992 if ((!insn_data[icode].operand[3].predicate (op2, mode2)) 6993 || !(UNSIGNED_INT8 (INTVAL (op2)))) 6994 error ("operand 2 should be an unsigned 8-bit value"); 6995 6996 pat = GEN_FCN (icode) (target, op0, op1, op2); 6997 6998 if (!pat) 6999 return NULL_RTX; 7000 7001 emit_insn (pat); 7002 return target; 7003 7004 case ARC_BUILTIN_VST128: 7005 case ARC_BUILTIN_VST64: 7006 arg0 = CALL_EXPR_ARG (exp, 0); /* src vreg. */ 7007 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */ 7008 arg2 = CALL_EXPR_ARG (exp, 2); /* u8. */ 7009 7010 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG); 7011 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL); 7012 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL); 7013 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL); 7014 7015 mode0 = insn_data[icode].operand[0].mode; 7016 mode1 = insn_data[icode].operand[1].mode; 7017 mode2 = insn_data[icode].operand[2].mode; 7018 mode3 = insn_data[icode].operand[3].mode; 7019 7020 if ((!insn_data[icode].operand[1].predicate (op1, mode1)) 7021 || !(UNSIGNED_INT3 (INTVAL (op1)))) 7022 error ("operand 2 should be an unsigned 3-bit value (I0-I7)"); 7023 7024 if ((!insn_data[icode].operand[2].predicate (op2, mode2)) 7025 || !(UNSIGNED_INT8 (INTVAL (op2)))) 7026 error ("operand 3 should be an unsigned 8-bit value"); 7027 7028 if (!insn_data[icode].operand[3].predicate (op3, mode3)) 7029 op3 = copy_to_mode_reg (mode3, op3); 7030 7031 pat = GEN_FCN (icode) (op0, op1, op2, op3); 7032 if (!pat) 7033 return NULL_RTX; 7034 7035 emit_insn (pat); 7036 return NULL_RTX; 7037 7038 case ARC_BUILTIN_VST16_N: 7039 case ARC_BUILTIN_VST32_N: 7040 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg. */ 7041 arg1 = CALL_EXPR_ARG (exp, 1); /* u3. */ 7042 arg2 = CALL_EXPR_ARG (exp, 2); /* [I]0-7. */ 7043 arg3 = CALL_EXPR_ARG (exp, 3); /* u8. */ 7044 7045 op0 = expand_expr (arg3, NULL_RTX, SImode, EXPAND_NORMAL); 7046 op1 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG); 7047 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL); 7048 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL); 7049 op4 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL); 7050 7051 mode0 = insn_data[icode].operand[0].mode; 7052 mode2 = insn_data[icode].operand[2].mode; 7053 mode3 = insn_data[icode].operand[3].mode; 7054 mode4 = insn_data[icode].operand[4].mode; 7055 7056 /* Do some correctness checks for the operands. */ 7057 if ((!insn_data[icode].operand[0].predicate (op0, mode0)) 7058 || !(UNSIGNED_INT8 (INTVAL (op0)))) 7059 error ("operand 4 should be an unsigned 8-bit value (0-255)"); 7060 7061 if ((!insn_data[icode].operand[2].predicate (op2, mode2)) 7062 || !(UNSIGNED_INT3 (INTVAL (op2)))) 7063 error ("operand 3 should be an unsigned 3-bit value (I0-I7)"); 7064 7065 if (!insn_data[icode].operand[3].predicate (op3, mode3)) 7066 op3 = copy_to_mode_reg (mode3, op3); 7067 7068 if ((!insn_data[icode].operand[4].predicate (op4, mode4)) 7069 || !(UNSIGNED_INT3 (INTVAL (op4)))) 7070 error ("operand 2 should be an unsigned 3-bit value (subreg 0-7)"); 7071 else if (icode == CODE_FOR_vst32_n_insn 7072 && ((INTVAL (op4) % 2) != 0)) 7073 error ("operand 2 should be an even 3-bit value (subreg 0,2,4,6)"); 7074 7075 pat = GEN_FCN (icode) (op0, op1, op2, op3, op4); 7076 if (!pat) 7077 return NULL_RTX; 7078 7079 emit_insn (pat); 7080 return NULL_RTX; 7081 7082 default: 7083 break; 7084 } 7085 7086 /* 2nd part: Expand regular builtins. */ 7087 if (icode == 0) 7088 internal_error ("bad builtin fcode"); 7089 7090 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node; 7091 j = 0; 7092 7093 if (nonvoid) 7094 { 7095 if (target == NULL_RTX 7096 || GET_MODE (target) != tmode 7097 || !insn_data[icode].operand[0].predicate (target, tmode)) 7098 { 7099 target = gen_reg_rtx (tmode); 7100 } 7101 xop[j++] = target; 7102 } 7103 7104 gcc_assert (n_args <= 4); 7105 for (i = 0; i < n_args; i++, j++) 7106 { 7107 tree arg = CALL_EXPR_ARG (exp, i); 7108 machine_mode mode = insn_data[icode].operand[j].mode; 7109 rtx op = expand_expr (arg, NULL_RTX, mode, EXPAND_NORMAL); 7110 machine_mode opmode = GET_MODE (op); 7111 char c = insn_data[icode].operand[j].constraint[0]; 7112 7113 /* SIMD extension requires exact immediate operand match. */ 7114 if ((id > ARC_BUILTIN_SIMD_BEGIN) 7115 && (id < ARC_BUILTIN_SIMD_END) 7116 && (c != 'v') 7117 && (c != 'r')) 7118 { 7119 if (!CONST_INT_P (op)) 7120 error ("builtin requires an immediate for operand %d", j); 7121 switch (c) 7122 { 7123 case 'L': 7124 if (!satisfies_constraint_L (op)) 7125 error ("operand %d should be a 6 bit unsigned immediate", j); 7126 break; 7127 case 'P': 7128 if (!satisfies_constraint_P (op)) 7129 error ("operand %d should be a 8 bit unsigned immediate", j); 7130 break; 7131 case 'K': 7132 if (!satisfies_constraint_K (op)) 7133 error ("operand %d should be a 3 bit unsigned immediate", j); 7134 break; 7135 default: 7136 error ("unknown builtin immediate operand type for operand %d", 7137 j); 7138 } 7139 } 7140 7141 if (CONST_INT_P (op)) 7142 opmode = mode; 7143 7144 if ((opmode == SImode) && (mode == HImode)) 7145 { 7146 opmode = HImode; 7147 op = gen_lowpart (HImode, op); 7148 } 7149 7150 /* In case the insn wants input operands in modes different from 7151 the result, abort. */ 7152 gcc_assert (opmode == mode || opmode == VOIDmode); 7153 7154 if (!insn_data[icode].operand[i + nonvoid].predicate (op, mode)) 7155 op = copy_to_mode_reg (mode, op); 7156 7157 xop[j] = op; 7158 } 7159 7160 pat = apply_GEN_FCN (icode, xop); 7161 if (pat == NULL_RTX) 7162 return NULL_RTX; 7163 7164 emit_insn (pat); 7165 7166 if (nonvoid) 7167 return target; 7168 else 7169 return const0_rtx; 7170 } 7171 7172 /* Returns true if the operands[opno] is a valid compile-time constant to be 7173 used as register number in the code for builtins. Else it flags an error 7174 and returns false. */ 7175 7176 bool 7177 check_if_valid_regno_const (rtx *operands, int opno) 7178 { 7179 7180 switch (GET_CODE (operands[opno])) 7181 { 7182 case SYMBOL_REF : 7183 case CONST : 7184 case CONST_INT : 7185 return true; 7186 default: 7187 error ("register number must be a compile-time constant. " 7188 "Try giving higher optimization levels"); 7189 break; 7190 } 7191 return false; 7192 } 7193 7194 /* Return true if it is ok to make a tail-call to DECL. */ 7195 7196 static bool 7197 arc_function_ok_for_sibcall (tree decl, 7198 tree exp ATTRIBUTE_UNUSED) 7199 { 7200 tree attrs = NULL_TREE; 7201 7202 /* Never tailcall from an ISR routine - it needs a special exit sequence. */ 7203 if (ARC_INTERRUPT_P (arc_compute_function_type (cfun))) 7204 return false; 7205 7206 if (decl) 7207 { 7208 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl)); 7209 7210 if (lookup_attribute ("jli_always", attrs)) 7211 return false; 7212 if (lookup_attribute ("jli_fixed", attrs)) 7213 return false; 7214 if (lookup_attribute ("secure_call", attrs)) 7215 return false; 7216 } 7217 7218 /* Everything else is ok. */ 7219 return true; 7220 } 7221 7222 /* Output code to add DELTA to the first argument, and then jump 7223 to FUNCTION. Used for C++ multiple inheritance. */ 7224 7225 static void 7226 arc_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, 7227 HOST_WIDE_INT delta, 7228 HOST_WIDE_INT vcall_offset, 7229 tree function) 7230 { 7231 int mi_delta = delta; 7232 const char *const mi_op = mi_delta < 0 ? "sub" : "add"; 7233 int shift = 0; 7234 int this_regno 7235 = aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function) ? 1 : 0; 7236 rtx fnaddr; 7237 7238 if (mi_delta < 0) 7239 mi_delta = - mi_delta; 7240 7241 /* Add DELTA. When possible use a plain add, otherwise load it into 7242 a register first. */ 7243 7244 while (mi_delta != 0) 7245 { 7246 if ((mi_delta & (3 << shift)) == 0) 7247 shift += 2; 7248 else 7249 { 7250 asm_fprintf (file, "\t%s\t%s, %s, %d\n", 7251 mi_op, reg_names[this_regno], reg_names[this_regno], 7252 mi_delta & (0xff << shift)); 7253 mi_delta &= ~(0xff << shift); 7254 shift += 8; 7255 } 7256 } 7257 7258 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */ 7259 if (vcall_offset != 0) 7260 { 7261 /* ld r12,[this] --> temp = *this 7262 add r12,r12,vcall_offset --> temp = *(*this + vcall_offset) 7263 ld r12,[r12] 7264 add this,this,r12 --> this+ = *(*this + vcall_offset) */ 7265 asm_fprintf (file, "\tld\t%s, [%s]\n", 7266 ARC_TEMP_SCRATCH_REG, reg_names[this_regno]); 7267 asm_fprintf (file, "\tadd\t%s, %s, " HOST_WIDE_INT_PRINT_DEC "\n", 7268 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG, vcall_offset); 7269 asm_fprintf (file, "\tld\t%s, [%s]\n", 7270 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG); 7271 asm_fprintf (file, "\tadd\t%s, %s, %s\n", reg_names[this_regno], 7272 reg_names[this_regno], ARC_TEMP_SCRATCH_REG); 7273 } 7274 7275 fnaddr = XEXP (DECL_RTL (function), 0); 7276 7277 if (arc_is_longcall_p (fnaddr)) 7278 { 7279 if (flag_pic) 7280 { 7281 asm_fprintf (file, "\tld\t%s, [pcl, @", 7282 ARC_TEMP_SCRATCH_REG); 7283 assemble_name (file, XSTR (fnaddr, 0)); 7284 fputs ("@gotpc]\n", file); 7285 asm_fprintf (file, "\tj\t[%s]", ARC_TEMP_SCRATCH_REG); 7286 } 7287 else 7288 { 7289 fputs ("\tj\t@", file); 7290 assemble_name (file, XSTR (fnaddr, 0)); 7291 } 7292 } 7293 else 7294 { 7295 fputs ("\tb\t@", file); 7296 assemble_name (file, XSTR (fnaddr, 0)); 7297 if (flag_pic) 7298 fputs ("@plt\n", file); 7299 } 7300 fputc ('\n', file); 7301 } 7302 7303 /* Return true if a 32 bit "long_call" should be generated for 7304 this calling SYM_REF. We generate a long_call if the function: 7305 7306 a. has an __attribute__((long call)) 7307 or b. the -mlong-calls command line switch has been specified 7308 7309 However we do not generate a long call if the function has an 7310 __attribute__ ((short_call)) or __attribute__ ((medium_call)) 7311 7312 This function will be called by C fragments contained in the machine 7313 description file. */ 7314 7315 bool 7316 arc_is_longcall_p (rtx sym_ref) 7317 { 7318 if (GET_CODE (sym_ref) != SYMBOL_REF) 7319 return false; 7320 7321 return (SYMBOL_REF_LONG_CALL_P (sym_ref) 7322 || (TARGET_LONG_CALLS_SET 7323 && !SYMBOL_REF_SHORT_CALL_P (sym_ref) 7324 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref))); 7325 7326 } 7327 7328 /* Likewise for short calls. */ 7329 7330 bool 7331 arc_is_shortcall_p (rtx sym_ref) 7332 { 7333 if (GET_CODE (sym_ref) != SYMBOL_REF) 7334 return false; 7335 7336 return (SYMBOL_REF_SHORT_CALL_P (sym_ref) 7337 || (!TARGET_LONG_CALLS_SET && !TARGET_MEDIUM_CALLS 7338 && !SYMBOL_REF_LONG_CALL_P (sym_ref) 7339 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref))); 7340 7341 } 7342 7343 /* Worker function for TARGET_RETURN_IN_MEMORY. */ 7344 7345 static bool 7346 arc_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) 7347 { 7348 if (AGGREGATE_TYPE_P (type) || TREE_ADDRESSABLE (type)) 7349 return true; 7350 else 7351 { 7352 HOST_WIDE_INT size = int_size_in_bytes (type); 7353 return (size == -1 || size > (TARGET_V2 ? 16 : 8)); 7354 } 7355 } 7356 7357 static bool 7358 arc_pass_by_reference (cumulative_args_t ca_v ATTRIBUTE_UNUSED, 7359 machine_mode mode ATTRIBUTE_UNUSED, 7360 const_tree type, 7361 bool named ATTRIBUTE_UNUSED) 7362 { 7363 return (type != 0 7364 && (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST 7365 || TREE_ADDRESSABLE (type))); 7366 } 7367 7368 /* Implement TARGET_CAN_USE_DOLOOP_P. */ 7369 7370 static bool 7371 arc_can_use_doloop_p (const widest_int &, 7372 const widest_int &iterations_max, 7373 unsigned int loop_depth, bool entered_at_top) 7374 { 7375 /* Considering limitations in the hardware, only use doloop 7376 for innermost loops which must be entered from the top. */ 7377 if (loop_depth > 1 || !entered_at_top) 7378 return false; 7379 7380 /* Check for lp_count width boundary. */ 7381 if (arc_lpcwidth != 32 7382 && (wi::gtu_p (iterations_max, ((1 << arc_lpcwidth) - 1)) 7383 || wi::eq_p (iterations_max, 0))) 7384 return false; 7385 return true; 7386 } 7387 7388 /* NULL if INSN insn is valid within a low-overhead loop. Otherwise 7389 return why doloop cannot be applied. */ 7390 7391 static const char * 7392 arc_invalid_within_doloop (const rtx_insn *insn) 7393 { 7394 if (CALL_P (insn)) 7395 return "Function call in the loop."; 7396 7397 /* FIXME! add here all the ZOL exceptions. */ 7398 return NULL; 7399 } 7400 7401 /* Return the next active insn, skiping the inline assembly code. */ 7402 7403 static rtx_insn * 7404 arc_active_insn (rtx_insn *insn) 7405 { 7406 rtx_insn *nxt = next_active_insn (insn); 7407 7408 if (nxt && GET_CODE (PATTERN (nxt)) == ASM_INPUT) 7409 nxt = next_active_insn (nxt); 7410 return nxt; 7411 } 7412 7413 /* Search for a sequence made out of two stores and a given number of 7414 loads, insert a nop if required. */ 7415 7416 static void 7417 check_store_cacheline_hazard (void) 7418 { 7419 rtx_insn *insn, *succ0, *insn1; 7420 bool found = false; 7421 7422 for (insn = get_insns (); insn; insn = arc_active_insn (insn)) 7423 { 7424 succ0 = arc_active_insn (insn); 7425 7426 if (!succ0) 7427 return; 7428 7429 if (!single_set (insn) || !single_set (succ0)) 7430 continue; 7431 7432 if ((get_attr_type (insn) != TYPE_STORE) 7433 || (get_attr_type (succ0) != TYPE_STORE)) 7434 continue; 7435 7436 /* Found at least two consecutive stores. Goto the end of the 7437 store sequence. */ 7438 for (insn1 = succ0; insn1; insn1 = arc_active_insn (insn1)) 7439 if (!single_set (insn1) || get_attr_type (insn1) != TYPE_STORE) 7440 break; 7441 7442 /* Now, check the next two instructions for the following cases: 7443 1. next instruction is a LD => insert 2 nops between store 7444 sequence and load. 7445 2. next-next instruction is a LD => inset 1 nop after the store 7446 sequence. */ 7447 if (insn1 && single_set (insn1) 7448 && (get_attr_type (insn1) == TYPE_LOAD)) 7449 { 7450 found = true; 7451 emit_insn_before (gen_nopv (), insn1); 7452 emit_insn_before (gen_nopv (), insn1); 7453 } 7454 else 7455 { 7456 if (insn1 && (get_attr_type (insn1) == TYPE_COMPARE)) 7457 { 7458 /* REG_SAVE_NOTE is used by Haifa scheduler, we are in 7459 reorg, so it is safe to reuse it for avoiding the 7460 current compare insn to be part of a BRcc 7461 optimization. */ 7462 add_reg_note (insn1, REG_SAVE_NOTE, GEN_INT (3)); 7463 } 7464 insn1 = arc_active_insn (insn1); 7465 if (insn1 && single_set (insn1) 7466 && (get_attr_type (insn1) == TYPE_LOAD)) 7467 { 7468 found = true; 7469 emit_insn_before (gen_nopv (), insn1); 7470 } 7471 } 7472 7473 insn = insn1; 7474 if (found) 7475 found = false; 7476 } 7477 } 7478 7479 /* Return true if a load instruction (CONSUMER) uses the same address as a 7480 store instruction (PRODUCER). This function is used to avoid st/ld 7481 address hazard in ARC700 cores. */ 7482 7483 static bool 7484 arc_store_addr_hazard_internal_p (rtx_insn* producer, rtx_insn* consumer) 7485 { 7486 rtx in_set, out_set; 7487 rtx out_addr, in_addr; 7488 7489 if (!producer) 7490 return false; 7491 7492 if (!consumer) 7493 return false; 7494 7495 /* Peel the producer and the consumer for the address. */ 7496 out_set = single_set (producer); 7497 if (out_set) 7498 { 7499 out_addr = SET_DEST (out_set); 7500 if (!out_addr) 7501 return false; 7502 if (GET_CODE (out_addr) == ZERO_EXTEND 7503 || GET_CODE (out_addr) == SIGN_EXTEND) 7504 out_addr = XEXP (out_addr, 0); 7505 7506 if (!MEM_P (out_addr)) 7507 return false; 7508 7509 in_set = single_set (consumer); 7510 if (in_set) 7511 { 7512 in_addr = SET_SRC (in_set); 7513 if (!in_addr) 7514 return false; 7515 if (GET_CODE (in_addr) == ZERO_EXTEND 7516 || GET_CODE (in_addr) == SIGN_EXTEND) 7517 in_addr = XEXP (in_addr, 0); 7518 7519 if (!MEM_P (in_addr)) 7520 return false; 7521 /* Get rid of the MEM and check if the addresses are 7522 equivalent. */ 7523 in_addr = XEXP (in_addr, 0); 7524 out_addr = XEXP (out_addr, 0); 7525 7526 return exp_equiv_p (in_addr, out_addr, 0, true); 7527 } 7528 } 7529 return false; 7530 } 7531 7532 /* Return TRUE is we have an store address hazard. */ 7533 7534 bool 7535 arc_store_addr_hazard_p (rtx_insn* producer, rtx_insn* consumer) 7536 { 7537 if (TARGET_ARC700 && (arc_tune != ARC_TUNE_ARC7XX)) 7538 return true; 7539 return arc_store_addr_hazard_internal_p (producer, consumer); 7540 } 7541 7542 /* The same functionality as arc_hazard. It is called in machine 7543 reorg before any other optimization. Hence, the NOP size is taken 7544 into account when doing branch shortening. */ 7545 7546 static void 7547 workaround_arc_anomaly (void) 7548 { 7549 rtx_insn *insn, *succ0; 7550 rtx_insn *succ1; 7551 7552 /* For any architecture: call arc_hazard here. */ 7553 for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 7554 { 7555 succ0 = next_real_insn (insn); 7556 if (arc_hazard (insn, succ0)) 7557 { 7558 emit_insn_before (gen_nopv (), succ0); 7559 } 7560 } 7561 7562 if (!TARGET_ARC700) 7563 return; 7564 7565 /* Old A7 are suffering of a cache hazard, and we need to insert two 7566 nops between any sequence of stores and a load. */ 7567 if (arc_tune != ARC_TUNE_ARC7XX) 7568 check_store_cacheline_hazard (); 7569 7570 for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 7571 { 7572 succ0 = next_real_insn (insn); 7573 if (arc_store_addr_hazard_internal_p (insn, succ0)) 7574 { 7575 emit_insn_after (gen_nopv (), insn); 7576 emit_insn_after (gen_nopv (), insn); 7577 continue; 7578 } 7579 7580 /* Avoid adding nops if the instruction between the ST and LD is 7581 a call or jump. */ 7582 succ1 = next_real_insn (succ0); 7583 if (succ0 && !JUMP_P (succ0) && !CALL_P (succ0) 7584 && arc_store_addr_hazard_internal_p (insn, succ1)) 7585 emit_insn_after (gen_nopv (), insn); 7586 } 7587 } 7588 7589 /* A callback for the hw-doloop pass. Called when a loop we have discovered 7590 turns out not to be optimizable; we have to split the loop_end pattern into 7591 a subtract and a test. */ 7592 7593 static void 7594 hwloop_fail (hwloop_info loop) 7595 { 7596 rtx test; 7597 rtx insn = loop->loop_end; 7598 7599 if (TARGET_DBNZ 7600 && (loop->length && (loop->length <= ARC_MAX_LOOP_LENGTH)) 7601 && REG_P (loop->iter_reg)) 7602 { 7603 /* TARGET_V2 core3 has dbnz instructions. */ 7604 test = gen_dbnz (loop->iter_reg, loop->start_label); 7605 insn = emit_jump_insn_before (test, loop->loop_end); 7606 } 7607 else if (REG_P (loop->iter_reg) && (REGNO (loop->iter_reg) == LP_COUNT)) 7608 { 7609 /* We have the lp_count as loop iterator, try to use it. */ 7610 emit_insn_before (gen_loop_fail (), loop->loop_end); 7611 test = gen_rtx_NE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), 7612 const0_rtx); 7613 test = gen_rtx_IF_THEN_ELSE (VOIDmode, test, 7614 gen_rtx_LABEL_REF (Pmode, loop->start_label), 7615 pc_rtx); 7616 insn = emit_jump_insn_before (gen_rtx_SET (pc_rtx, test), 7617 loop->loop_end); 7618 } 7619 else 7620 { 7621 emit_insn_before (gen_addsi3 (loop->iter_reg, 7622 loop->iter_reg, 7623 constm1_rtx), 7624 loop->loop_end); 7625 test = gen_rtx_NE (VOIDmode, loop->iter_reg, const0_rtx); 7626 insn = emit_jump_insn_before (gen_cbranchsi4 (test, 7627 loop->iter_reg, 7628 const0_rtx, 7629 loop->start_label), 7630 loop->loop_end); 7631 } 7632 JUMP_LABEL (insn) = loop->start_label; 7633 LABEL_NUSES (loop->start_label)++; 7634 delete_insn (loop->loop_end); 7635 } 7636 7637 /* Return the next insn after INSN that is not a NOTE, but stop the 7638 search before we enter another basic block. This routine does not 7639 look inside SEQUENCEs. */ 7640 7641 static rtx_insn * 7642 next_nonnote_insn_bb (rtx_insn *insn) 7643 { 7644 while (insn) 7645 { 7646 insn = NEXT_INSN (insn); 7647 if (insn == 0 || !NOTE_P (insn)) 7648 break; 7649 if (NOTE_INSN_BASIC_BLOCK_P (insn)) 7650 return NULL; 7651 } 7652 7653 return insn; 7654 } 7655 7656 /* Optimize LOOP. */ 7657 7658 static bool 7659 hwloop_optimize (hwloop_info loop) 7660 { 7661 int i; 7662 edge entry_edge; 7663 basic_block entry_bb, bb; 7664 rtx iter_reg; 7665 rtx_insn *insn, *seq, *entry_after, *last_insn, *end_label; 7666 unsigned int length; 7667 bool need_fix = false; 7668 rtx lp_reg = gen_rtx_REG (SImode, LP_COUNT); 7669 7670 if (loop->depth > 1) 7671 { 7672 if (dump_file) 7673 fprintf (dump_file, ";; loop %d is not innermost\n", 7674 loop->loop_no); 7675 return false; 7676 } 7677 7678 if (!loop->incoming_dest) 7679 { 7680 if (dump_file) 7681 fprintf (dump_file, ";; loop %d has more than one entry\n", 7682 loop->loop_no); 7683 return false; 7684 } 7685 7686 if (loop->incoming_dest != loop->head) 7687 { 7688 if (dump_file) 7689 fprintf (dump_file, ";; loop %d is not entered from head\n", 7690 loop->loop_no); 7691 return false; 7692 } 7693 7694 if (loop->has_call || loop->has_asm) 7695 { 7696 if (dump_file) 7697 fprintf (dump_file, ";; loop %d has invalid insn\n", 7698 loop->loop_no); 7699 return false; 7700 } 7701 7702 /* Scan all the blocks to make sure they don't use iter_reg. */ 7703 if (loop->iter_reg_used || loop->iter_reg_used_outside) 7704 { 7705 if (dump_file) 7706 fprintf (dump_file, ";; loop %d uses iterator\n", 7707 loop->loop_no); 7708 return false; 7709 } 7710 7711 /* Check if start_label appears before doloop_end. */ 7712 length = 0; 7713 for (insn = loop->start_label; 7714 insn && insn != loop->loop_end; 7715 insn = NEXT_INSN (insn)) 7716 { 7717 length += NONDEBUG_INSN_P (insn) ? get_attr_length (insn) : 0; 7718 if (JUMP_TABLES_IN_TEXT_SECTION 7719 && JUMP_TABLE_DATA_P (insn)) 7720 { 7721 if (dump_file) 7722 fprintf (dump_file, ";; loop %d has a jump table\n", 7723 loop->loop_no); 7724 return false; 7725 } 7726 } 7727 7728 if (!insn) 7729 { 7730 if (dump_file) 7731 fprintf (dump_file, ";; loop %d start_label not before loop_end\n", 7732 loop->loop_no); 7733 return false; 7734 } 7735 7736 loop->length = length; 7737 if (loop->length > ARC_MAX_LOOP_LENGTH) 7738 { 7739 if (dump_file) 7740 fprintf (dump_file, ";; loop %d too long\n", loop->loop_no); 7741 return false; 7742 } 7743 else if (!loop->length) 7744 { 7745 if (dump_file) 7746 fprintf (dump_file, ";; loop %d is empty\n", loop->loop_no); 7747 return false; 7748 } 7749 7750 /* Check if we use a register or not. */ 7751 if (!REG_P (loop->iter_reg)) 7752 { 7753 if (dump_file) 7754 fprintf (dump_file, ";; loop %d iterator is MEM\n", 7755 loop->loop_no); 7756 return false; 7757 } 7758 7759 /* Check if we use a register or not. */ 7760 if (!REG_P (loop->iter_reg)) 7761 { 7762 if (dump_file) 7763 fprintf (dump_file, ";; loop %d iterator is MEM\n", 7764 loop->loop_no); 7765 return false; 7766 } 7767 7768 /* Check if loop register is lpcount. */ 7769 if (REG_P (loop->iter_reg) && (REGNO (loop->iter_reg)) != LP_COUNT) 7770 { 7771 if (dump_file) 7772 fprintf (dump_file, ";; loop %d doesn't use lp_count as loop" 7773 " iterator\n", 7774 loop->loop_no); 7775 /* This loop doesn't use the lp_count, check though if we can 7776 fix it. */ 7777 if (TEST_HARD_REG_BIT (loop->regs_set_in_loop, LP_COUNT) 7778 /* In very unique cases we may have LP_COUNT alive. */ 7779 || (loop->incoming_src 7780 && REGNO_REG_SET_P (df_get_live_out (loop->incoming_src), 7781 LP_COUNT))) 7782 { 7783 if (dump_file) 7784 fprintf (dump_file, ";; loop %d, lp_count is alive", loop->loop_no); 7785 return false; 7786 } 7787 else 7788 need_fix = true; 7789 } 7790 7791 /* Check for control like instruction as the last instruction of a 7792 ZOL. */ 7793 bb = loop->tail; 7794 last_insn = PREV_INSN (loop->loop_end); 7795 7796 while (1) 7797 { 7798 for (; last_insn != BB_HEAD (bb); 7799 last_insn = PREV_INSN (last_insn)) 7800 if (NONDEBUG_INSN_P (last_insn)) 7801 break; 7802 7803 if (last_insn != BB_HEAD (bb)) 7804 break; 7805 7806 if (single_pred_p (bb) 7807 && single_pred_edge (bb)->flags & EDGE_FALLTHRU 7808 && single_pred (bb) != ENTRY_BLOCK_PTR_FOR_FN (cfun)) 7809 { 7810 bb = single_pred (bb); 7811 last_insn = BB_END (bb); 7812 continue; 7813 } 7814 else 7815 { 7816 last_insn = NULL; 7817 break; 7818 } 7819 } 7820 7821 if (!last_insn) 7822 { 7823 if (dump_file) 7824 fprintf (dump_file, ";; loop %d has no last instruction\n", 7825 loop->loop_no); 7826 return false; 7827 } 7828 7829 if ((TARGET_ARC600_FAMILY || TARGET_HS) 7830 && INSN_P (last_insn) 7831 && (JUMP_P (last_insn) || CALL_P (last_insn) 7832 || GET_CODE (PATTERN (last_insn)) == SEQUENCE 7833 /* At this stage we can have (insn (clobber (mem:BLK 7834 (reg)))) instructions, ignore them. */ 7835 || (GET_CODE (PATTERN (last_insn)) != CLOBBER 7836 && (get_attr_type (last_insn) == TYPE_BRCC 7837 || get_attr_type (last_insn) == TYPE_BRCC_NO_DELAY_SLOT)))) 7838 { 7839 if (loop->length + 2 > ARC_MAX_LOOP_LENGTH) 7840 { 7841 if (dump_file) 7842 fprintf (dump_file, ";; loop %d too long\n", loop->loop_no); 7843 return false; 7844 } 7845 if (dump_file) 7846 fprintf (dump_file, ";; loop %d has a control like last insn;" 7847 "add a nop\n", 7848 loop->loop_no); 7849 7850 last_insn = emit_insn_after (gen_nopv (), last_insn); 7851 } 7852 7853 if (LABEL_P (last_insn)) 7854 { 7855 if (dump_file) 7856 fprintf (dump_file, ";; loop %d has a label as last insn;" 7857 "add a nop\n", 7858 loop->loop_no); 7859 last_insn = emit_insn_after (gen_nopv (), last_insn); 7860 } 7861 7862 /* SAVE_NOTE is used by haifa scheduler. However, we are after it 7863 and we can use it to indicate the last ZOL instruction cannot be 7864 part of a delay slot. */ 7865 add_reg_note (last_insn, REG_SAVE_NOTE, GEN_INT (2)); 7866 7867 loop->last_insn = last_insn; 7868 7869 /* Get the loop iteration register. */ 7870 iter_reg = loop->iter_reg; 7871 7872 gcc_assert (REG_P (iter_reg)); 7873 7874 entry_edge = NULL; 7875 7876 FOR_EACH_VEC_SAFE_ELT (loop->incoming, i, entry_edge) 7877 if (entry_edge->flags & EDGE_FALLTHRU) 7878 break; 7879 7880 if (entry_edge == NULL) 7881 { 7882 if (dump_file) 7883 fprintf (dump_file, ";; loop %d has no fallthru edge jumping" 7884 "into the loop\n", 7885 loop->loop_no); 7886 return false; 7887 } 7888 /* The loop is good. */ 7889 end_label = gen_label_rtx (); 7890 loop->end_label = end_label; 7891 7892 /* Place the zero_cost_loop_start instruction before the loop. */ 7893 entry_bb = entry_edge->src; 7894 7895 start_sequence (); 7896 7897 if (need_fix) 7898 { 7899 /* The loop uses a R-register, but the lp_count is free, thus 7900 use lp_count. */ 7901 emit_insn (gen_rtx_SET (lp_reg, iter_reg)); 7902 SET_HARD_REG_BIT (loop->regs_set_in_loop, LP_COUNT); 7903 iter_reg = lp_reg; 7904 if (dump_file) 7905 { 7906 fprintf (dump_file, ";; fix loop %d to use lp_count\n", 7907 loop->loop_no); 7908 } 7909 } 7910 7911 insn = emit_insn (gen_arc_lp (loop->start_label, 7912 loop->end_label)); 7913 7914 seq = get_insns (); 7915 end_sequence (); 7916 7917 entry_after = BB_END (entry_bb); 7918 if (!single_succ_p (entry_bb) || vec_safe_length (loop->incoming) > 1 7919 || !entry_after) 7920 { 7921 basic_block new_bb; 7922 edge e; 7923 edge_iterator ei; 7924 7925 emit_insn_before (seq, BB_HEAD (loop->head)); 7926 seq = emit_label_before (gen_label_rtx (), seq); 7927 new_bb = create_basic_block (seq, insn, entry_bb); 7928 FOR_EACH_EDGE (e, ei, loop->incoming) 7929 { 7930 if (!(e->flags & EDGE_FALLTHRU)) 7931 redirect_edge_and_branch_force (e, new_bb); 7932 else 7933 redirect_edge_succ (e, new_bb); 7934 } 7935 7936 make_edge (new_bb, loop->head, 0); 7937 } 7938 else 7939 { 7940 #if 0 7941 while (DEBUG_INSN_P (entry_after) 7942 || (NOTE_P (entry_after) 7943 && NOTE_KIND (entry_after) != NOTE_INSN_BASIC_BLOCK 7944 /* Make sure we don't split a call and its corresponding 7945 CALL_ARG_LOCATION note. */ 7946 && NOTE_KIND (entry_after) != NOTE_INSN_CALL_ARG_LOCATION)) 7947 entry_after = NEXT_INSN (entry_after); 7948 #endif 7949 entry_after = next_nonnote_insn_bb (entry_after); 7950 7951 gcc_assert (entry_after); 7952 emit_insn_before (seq, entry_after); 7953 } 7954 7955 /* Insert the loop end label before the last instruction of the 7956 loop. */ 7957 emit_label_after (end_label, loop->last_insn); 7958 /* Make sure we mark the begining and end label as used. */ 7959 LABEL_NUSES (loop->end_label)++; 7960 LABEL_NUSES (loop->start_label)++; 7961 7962 return true; 7963 } 7964 7965 /* A callback for the hw-doloop pass. This function examines INSN; if 7966 it is a loop_end pattern we recognize, return the reg rtx for the 7967 loop counter. Otherwise, return NULL_RTX. */ 7968 7969 static rtx 7970 hwloop_pattern_reg (rtx_insn *insn) 7971 { 7972 rtx reg; 7973 7974 if (!JUMP_P (insn) || recog_memoized (insn) != CODE_FOR_loop_end) 7975 return NULL_RTX; 7976 7977 reg = SET_DEST (XVECEXP (PATTERN (insn), 0, 1)); 7978 if (!REG_P (reg)) 7979 return NULL_RTX; 7980 return reg; 7981 } 7982 7983 static struct hw_doloop_hooks arc_doloop_hooks = 7984 { 7985 hwloop_pattern_reg, 7986 hwloop_optimize, 7987 hwloop_fail 7988 }; 7989 7990 /* Run from machine_dependent_reorg, this pass looks for doloop_end insns 7991 and tries to rewrite the RTL of these loops so that proper Blackfin 7992 hardware loops are generated. */ 7993 7994 static void 7995 arc_reorg_loops (void) 7996 { 7997 reorg_loops (true, &arc_doloop_hooks); 7998 } 7999 8000 /* Scan all calls and add symbols to be emitted in the jli section if 8001 needed. */ 8002 8003 static void 8004 jli_call_scan (void) 8005 { 8006 rtx_insn *insn; 8007 8008 for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 8009 { 8010 if (!CALL_P (insn)) 8011 continue; 8012 8013 rtx pat = PATTERN (insn); 8014 if (GET_CODE (pat) == COND_EXEC) 8015 pat = COND_EXEC_CODE (pat); 8016 pat = XVECEXP (pat, 0, 0); 8017 if (GET_CODE (pat) == SET) 8018 pat = SET_SRC (pat); 8019 8020 pat = XEXP (XEXP (pat, 0), 0); 8021 if (GET_CODE (pat) == SYMBOL_REF 8022 && arc_is_jli_call_p (pat)) 8023 arc_add_jli_section (pat); 8024 } 8025 } 8026 8027 /* Add padding if necessary to avoid a mispredict. A return could 8028 happen immediately after the function start. A call/return and 8029 return/return must be 6 bytes apart to avoid mispredict. */ 8030 8031 static void 8032 pad_return (void) 8033 { 8034 rtx_insn *insn; 8035 long offset; 8036 8037 if (!TARGET_PAD_RETURN) 8038 return; 8039 8040 for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 8041 { 8042 rtx_insn *prev0 = prev_active_insn (insn); 8043 bool wantlong = false; 8044 8045 if (!INSN_P (insn) || GET_CODE (PATTERN (insn)) != SIMPLE_RETURN) 8046 continue; 8047 8048 if (!prev0) 8049 { 8050 prev0 = emit_insn_before (gen_nopv (), insn); 8051 /* REG_SAVE_NOTE is used by Haifa scheduler, we are in reorg 8052 so it is safe to reuse it for forcing a particular length 8053 for an instruction. */ 8054 add_reg_note (prev0, REG_SAVE_NOTE, GEN_INT (1)); 8055 emit_insn_before (gen_nopv (), insn); 8056 continue; 8057 } 8058 offset = get_attr_length (prev0); 8059 8060 if (get_attr_length (prev0) == 2 8061 && get_attr_iscompact (prev0) != ISCOMPACT_TRUE) 8062 { 8063 /* Force long version of the insn. */ 8064 wantlong = true; 8065 offset += 2; 8066 } 8067 8068 rtx_insn *prev = prev_active_insn (prev0); 8069 if (prev) 8070 offset += get_attr_length (prev); 8071 8072 prev = prev_active_insn (prev); 8073 if (prev) 8074 offset += get_attr_length (prev); 8075 8076 switch (offset) 8077 { 8078 case 2: 8079 prev = emit_insn_before (gen_nopv (), insn); 8080 add_reg_note (prev, REG_SAVE_NOTE, GEN_INT (1)); 8081 break; 8082 case 4: 8083 emit_insn_before (gen_nopv (), insn); 8084 break; 8085 default: 8086 continue; 8087 } 8088 8089 if (wantlong) 8090 add_reg_note (prev0, REG_SAVE_NOTE, GEN_INT (1)); 8091 8092 /* Emit a blockage to avoid delay slot scheduling. */ 8093 emit_insn_before (gen_blockage (), insn); 8094 } 8095 } 8096 8097 static int arc_reorg_in_progress = 0; 8098 8099 /* ARC's machince specific reorg function. */ 8100 8101 static void 8102 arc_reorg (void) 8103 { 8104 rtx_insn *insn; 8105 rtx pattern; 8106 rtx pc_target; 8107 long offset; 8108 int changed; 8109 8110 cfun->machine->arc_reorg_started = 1; 8111 arc_reorg_in_progress = 1; 8112 8113 compute_bb_for_insn (); 8114 8115 df_analyze (); 8116 8117 /* Doloop optimization. */ 8118 arc_reorg_loops (); 8119 8120 workaround_arc_anomaly (); 8121 jli_call_scan (); 8122 pad_return (); 8123 8124 /* FIXME: should anticipate ccfsm action, generate special patterns for 8125 to-be-deleted branches that have no delay slot and have at least the 8126 length of the size increase forced on other insns that are conditionalized. 8127 This can also have an insn_list inside that enumerates insns which are 8128 not actually conditionalized because the destinations are dead in the 8129 not-execute case. 8130 Could also tag branches that we want to be unaligned if they get no delay 8131 slot, or even ones that we don't want to do delay slot sheduling for 8132 because we can unalign them. 8133 8134 However, there are cases when conditional execution is only possible after 8135 delay slot scheduling: 8136 8137 - If a delay slot is filled with a nocond/set insn from above, the previous 8138 basic block can become elegible for conditional execution. 8139 - If a delay slot is filled with a nocond insn from the fall-through path, 8140 the branch with that delay slot can become eligble for conditional 8141 execution (however, with the same sort of data flow analysis that dbr 8142 does, we could have figured out before that we don't need to 8143 conditionalize this insn.) 8144 - If a delay slot insn is filled with an insn from the target, the 8145 target label gets its uses decremented (even deleted if falling to zero), 8146 thus possibly creating more condexec opportunities there. 8147 Therefore, we should still be prepared to apply condexec optimization on 8148 non-prepared branches if the size increase of conditionalized insns is no 8149 more than the size saved from eliminating the branch. An invocation option 8150 could also be used to reserve a bit of extra size for condbranches so that 8151 this'll work more often (could also test in arc_reorg if the block is 8152 'close enough' to be eligible for condexec to make this likely, and 8153 estimate required size increase). */ 8154 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */ 8155 if (TARGET_NO_BRCC_SET) 8156 return; 8157 8158 do 8159 { 8160 init_insn_lengths(); 8161 changed = 0; 8162 8163 if (optimize > 1 && !TARGET_NO_COND_EXEC) 8164 { 8165 arc_ifcvt (); 8166 unsigned int flags = pass_data_arc_ifcvt.todo_flags_finish; 8167 df_finish_pass ((flags & TODO_df_verify) != 0); 8168 8169 if (dump_file) 8170 { 8171 fprintf (dump_file, ";; After if conversion:\n\n"); 8172 print_rtl (dump_file, get_insns ()); 8173 } 8174 } 8175 8176 /* Call shorten_branches to calculate the insn lengths. */ 8177 shorten_branches (get_insns()); 8178 cfun->machine->ccfsm_current_insn = NULL_RTX; 8179 8180 if (!INSN_ADDRESSES_SET_P()) 8181 fatal_error (input_location, 8182 "insn addresses not set after shorten_branches"); 8183 8184 for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 8185 { 8186 rtx label; 8187 enum attr_type insn_type; 8188 8189 /* If a non-jump insn (or a casesi jump table), continue. */ 8190 if (GET_CODE (insn) != JUMP_INSN || 8191 GET_CODE (PATTERN (insn)) == ADDR_VEC 8192 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC) 8193 continue; 8194 8195 /* If we already have a brcc, note if it is suitable for brcc_s. 8196 Be a bit generous with the brcc_s range so that we can take 8197 advantage of any code shortening from delay slot scheduling. */ 8198 if (recog_memoized (insn) == CODE_FOR_cbranchsi4_scratch) 8199 { 8200 rtx pat = PATTERN (insn); 8201 rtx op = XEXP (SET_SRC (XVECEXP (pat, 0, 0)), 0); 8202 rtx *ccp = &XEXP (XVECEXP (pat, 0, 1), 0); 8203 8204 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn)); 8205 if ((offset >= -140 && offset < 140) 8206 && rtx_equal_p (XEXP (op, 1), const0_rtx) 8207 && compact_register_operand (XEXP (op, 0), VOIDmode) 8208 && equality_comparison_operator (op, VOIDmode)) 8209 PUT_MODE (*ccp, CC_Zmode); 8210 else if (GET_MODE (*ccp) == CC_Zmode) 8211 PUT_MODE (*ccp, CC_ZNmode); 8212 continue; 8213 } 8214 if ((insn_type = get_attr_type (insn)) == TYPE_BRCC 8215 || insn_type == TYPE_BRCC_NO_DELAY_SLOT) 8216 continue; 8217 8218 /* OK. so we have a jump insn. */ 8219 /* We need to check that it is a bcc. */ 8220 /* Bcc => set (pc) (if_then_else ) */ 8221 pattern = PATTERN (insn); 8222 if (GET_CODE (pattern) != SET 8223 || GET_CODE (SET_SRC (pattern)) != IF_THEN_ELSE 8224 || ANY_RETURN_P (XEXP (SET_SRC (pattern), 1))) 8225 continue; 8226 8227 /* Now check if the jump is beyond the s9 range. */ 8228 if (CROSSING_JUMP_P (insn)) 8229 continue; 8230 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn)); 8231 8232 if(offset > 253 || offset < -254) 8233 continue; 8234 8235 pc_target = SET_SRC (pattern); 8236 8237 /* Avoid FPU instructions. */ 8238 if ((GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPUmode) 8239 || (GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPUEmode) 8240 || (GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPU_UNEQmode)) 8241 continue; 8242 8243 /* Now go back and search for the set cc insn. */ 8244 8245 label = XEXP (pc_target, 1); 8246 8247 { 8248 rtx pat; 8249 rtx_insn *scan, *link_insn = NULL; 8250 8251 for (scan = PREV_INSN (insn); 8252 scan && GET_CODE (scan) != CODE_LABEL; 8253 scan = PREV_INSN (scan)) 8254 { 8255 if (! INSN_P (scan)) 8256 continue; 8257 pat = PATTERN (scan); 8258 if (GET_CODE (pat) == SET 8259 && cc_register (SET_DEST (pat), VOIDmode)) 8260 { 8261 link_insn = scan; 8262 break; 8263 } 8264 } 8265 if (!link_insn) 8266 continue; 8267 else 8268 { 8269 /* Check if this is a data dependency. */ 8270 rtx op, cc_clob_rtx, op0, op1, brcc_insn, note; 8271 rtx cmp0, cmp1; 8272 8273 /* Make sure we can use it for brcc insns. */ 8274 if (find_reg_note (link_insn, REG_SAVE_NOTE, GEN_INT (3))) 8275 continue; 8276 8277 /* Ok this is the set cc. copy args here. */ 8278 op = XEXP (pc_target, 0); 8279 8280 op0 = cmp0 = XEXP (SET_SRC (pat), 0); 8281 op1 = cmp1 = XEXP (SET_SRC (pat), 1); 8282 if (GET_CODE (op0) == ZERO_EXTRACT 8283 && XEXP (op0, 1) == const1_rtx 8284 && (GET_CODE (op) == EQ 8285 || GET_CODE (op) == NE)) 8286 { 8287 /* btst / b{eq,ne} -> bbit{0,1} */ 8288 op0 = XEXP (cmp0, 0); 8289 op1 = XEXP (cmp0, 2); 8290 } 8291 else if (!register_operand (op0, VOIDmode) 8292 || !general_operand (op1, VOIDmode)) 8293 continue; 8294 /* Be careful not to break what cmpsfpx_raw is 8295 trying to create for checking equality of 8296 single-precision floats. */ 8297 else if (TARGET_SPFP 8298 && GET_MODE (op0) == SFmode 8299 && GET_MODE (op1) == SFmode) 8300 continue; 8301 8302 /* None of the two cmp operands should be set between the 8303 cmp and the branch. */ 8304 if (reg_set_between_p (op0, link_insn, insn)) 8305 continue; 8306 8307 if (reg_set_between_p (op1, link_insn, insn)) 8308 continue; 8309 8310 /* Since the MODE check does not work, check that this is 8311 CC reg's last set location before insn, and also no 8312 instruction between the cmp and branch uses the 8313 condition codes. */ 8314 if ((reg_set_between_p (SET_DEST (pat), link_insn, insn)) 8315 || (reg_used_between_p (SET_DEST (pat), link_insn, insn))) 8316 continue; 8317 8318 /* CC reg should be dead after insn. */ 8319 if (!find_regno_note (insn, REG_DEAD, CC_REG)) 8320 continue; 8321 8322 op = gen_rtx_fmt_ee (GET_CODE (op), 8323 GET_MODE (op), cmp0, cmp1); 8324 /* If we create a LIMM where there was none before, 8325 we only benefit if we can avoid a scheduling bubble 8326 for the ARC600. Otherwise, we'd only forgo chances 8327 at short insn generation, and risk out-of-range 8328 branches. */ 8329 if (!brcc_nolimm_operator (op, VOIDmode) 8330 && !long_immediate_operand (op1, VOIDmode) 8331 && (TARGET_ARC700 8332 || next_active_insn (link_insn) != insn)) 8333 continue; 8334 8335 /* Emit bbit / brcc (or brcc_s if possible). 8336 CC_Zmode indicates that brcc_s is possible. */ 8337 8338 if (op0 != cmp0) 8339 cc_clob_rtx = gen_rtx_REG (CC_ZNmode, CC_REG); 8340 else if ((offset >= -140 && offset < 140) 8341 && rtx_equal_p (op1, const0_rtx) 8342 && compact_register_operand (op0, VOIDmode) 8343 && (GET_CODE (op) == EQ 8344 || GET_CODE (op) == NE)) 8345 cc_clob_rtx = gen_rtx_REG (CC_Zmode, CC_REG); 8346 else 8347 cc_clob_rtx = gen_rtx_REG (CCmode, CC_REG); 8348 8349 brcc_insn 8350 = gen_rtx_IF_THEN_ELSE (VOIDmode, op, label, pc_rtx); 8351 brcc_insn = gen_rtx_SET (pc_rtx, brcc_insn); 8352 cc_clob_rtx = gen_rtx_CLOBBER (VOIDmode, cc_clob_rtx); 8353 brcc_insn 8354 = gen_rtx_PARALLEL 8355 (VOIDmode, gen_rtvec (2, brcc_insn, cc_clob_rtx)); 8356 brcc_insn = emit_jump_insn_before (brcc_insn, insn); 8357 8358 JUMP_LABEL (brcc_insn) = JUMP_LABEL (insn); 8359 note = find_reg_note (insn, REG_BR_PROB, 0); 8360 if (note) 8361 { 8362 XEXP (note, 1) = REG_NOTES (brcc_insn); 8363 REG_NOTES (brcc_insn) = note; 8364 } 8365 note = find_reg_note (link_insn, REG_DEAD, op0); 8366 if (note) 8367 { 8368 remove_note (link_insn, note); 8369 XEXP (note, 1) = REG_NOTES (brcc_insn); 8370 REG_NOTES (brcc_insn) = note; 8371 } 8372 note = find_reg_note (link_insn, REG_DEAD, op1); 8373 if (note) 8374 { 8375 XEXP (note, 1) = REG_NOTES (brcc_insn); 8376 REG_NOTES (brcc_insn) = note; 8377 } 8378 8379 changed = 1; 8380 8381 /* Delete the bcc insn. */ 8382 set_insn_deleted (insn); 8383 8384 /* Delete the cmp insn. */ 8385 set_insn_deleted (link_insn); 8386 8387 } 8388 } 8389 } 8390 /* Clear out insn_addresses. */ 8391 INSN_ADDRESSES_FREE (); 8392 8393 } while (changed); 8394 8395 if (INSN_ADDRESSES_SET_P()) 8396 fatal_error (input_location, "insn addresses not freed"); 8397 8398 arc_reorg_in_progress = 0; 8399 } 8400 8401 /* Check if the operands are valid for BRcc.d generation 8402 Valid Brcc.d patterns are 8403 Brcc.d b, c, s9 8404 Brcc.d b, u6, s9 8405 8406 For cc={GT, LE, GTU, LEU}, u6=63 cannot be allowed, 8407 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which 8408 does not have a delay slot 8409 8410 Assumed precondition: Second operand is either a register or a u6 value. */ 8411 8412 bool 8413 valid_brcc_with_delay_p (rtx *operands) 8414 { 8415 if (optimize_size && GET_MODE (operands[4]) == CC_Zmode) 8416 return false; 8417 return brcc_nolimm_operator (operands[0], VOIDmode); 8418 } 8419 8420 /* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to 8421 access DECL using %gp_rel(...)($gp). */ 8422 8423 static bool 8424 arc_in_small_data_p (const_tree decl) 8425 { 8426 HOST_WIDE_INT size; 8427 tree attr; 8428 8429 /* Only variables are going into small data area. */ 8430 if (TREE_CODE (decl) != VAR_DECL) 8431 return false; 8432 8433 if (TARGET_NO_SDATA_SET) 8434 return false; 8435 8436 /* Disable sdata references to weak variables. */ 8437 if (DECL_WEAK (decl)) 8438 return false; 8439 8440 /* Don't put constants into the small data section: we want them to 8441 be in ROM rather than RAM. */ 8442 if (TREE_READONLY (decl)) 8443 return false; 8444 8445 /* To ensure -mvolatile-cache works ld.di does not have a 8446 gp-relative variant. */ 8447 if (!TARGET_VOLATILE_CACHE_SET 8448 && TREE_THIS_VOLATILE (decl)) 8449 return false; 8450 8451 /* Likewise for uncached data. */ 8452 attr = TYPE_ATTRIBUTES (TREE_TYPE (decl)); 8453 if (lookup_attribute ("uncached", attr)) 8454 return false; 8455 8456 /* and for aux regs. */ 8457 attr = DECL_ATTRIBUTES (decl); 8458 if (lookup_attribute ("aux", attr)) 8459 return false; 8460 8461 if (DECL_SECTION_NAME (decl) != 0) 8462 { 8463 const char *name = DECL_SECTION_NAME (decl); 8464 if (strcmp (name, ".sdata") == 0 8465 || strcmp (name, ".sbss") == 0) 8466 return true; 8467 } 8468 /* If it's not public, there's no need to put it in the small data 8469 section. */ 8470 else if (TREE_PUBLIC (decl)) 8471 { 8472 size = int_size_in_bytes (TREE_TYPE (decl)); 8473 return (size > 0 && size <= g_switch_value); 8474 } 8475 return false; 8476 } 8477 8478 /* Return true if OP is an acceptable memory operand for ARCompact 8479 16-bit gp-relative load instructions. 8480 */ 8481 /* volatile cache option still to be handled. */ 8482 8483 bool 8484 compact_sda_memory_operand (rtx op, machine_mode mode, bool short_p) 8485 { 8486 rtx addr; 8487 int size; 8488 int align = 0; 8489 int mask = 0; 8490 8491 /* Eliminate non-memory operations. */ 8492 if (GET_CODE (op) != MEM) 8493 return false; 8494 8495 if (mode == VOIDmode) 8496 mode = GET_MODE (op); 8497 8498 size = GET_MODE_SIZE (mode); 8499 8500 /* dword operations really put out 2 instructions, so eliminate them. */ 8501 if (size > UNITS_PER_WORD) 8502 return false; 8503 8504 /* Decode the address now. */ 8505 addr = XEXP (op, 0); 8506 8507 if (!legitimate_small_data_address_p (addr)) 8508 return false; 8509 8510 if (!short_p || size == 1) 8511 return true; 8512 8513 /* Now check for the alignment, the short loads using gp require the 8514 addresses to be aligned. */ 8515 align = get_symbol_alignment (addr); 8516 switch (mode) 8517 { 8518 case E_HImode: 8519 mask = 1; 8520 break; 8521 default: 8522 mask = 3; 8523 break; 8524 } 8525 8526 if (align && ((align & mask) == 0)) 8527 return true; 8528 return false; 8529 } 8530 8531 /* Return TRUE if PAT is accessing an aux-reg. */ 8532 8533 static bool 8534 arc_is_aux_reg_p (rtx pat) 8535 { 8536 tree attrs = NULL_TREE; 8537 tree addr; 8538 8539 if (!MEM_P (pat)) 8540 return false; 8541 8542 /* Get the memory attributes. */ 8543 addr = MEM_EXPR (pat); 8544 if (!addr) 8545 return false; 8546 8547 /* Get the attributes. */ 8548 if (TREE_CODE (addr) == VAR_DECL) 8549 attrs = DECL_ATTRIBUTES (addr); 8550 else if (TREE_CODE (addr) == MEM_REF) 8551 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 0))); 8552 else 8553 return false; 8554 8555 if (lookup_attribute ("aux", attrs)) 8556 return true; 8557 return false; 8558 } 8559 8560 /* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */ 8561 8562 void 8563 arc_asm_output_aligned_decl_local (FILE * stream, tree decl, const char * name, 8564 unsigned HOST_WIDE_INT size, 8565 unsigned HOST_WIDE_INT align, 8566 unsigned HOST_WIDE_INT globalize_p) 8567 { 8568 int in_small_data = arc_in_small_data_p (decl); 8569 rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl); 8570 8571 /* Don't output aux-reg symbols. */ 8572 if (mem != NULL_RTX && MEM_P (mem) 8573 && SYMBOL_REF_P (XEXP (mem, 0)) 8574 && arc_is_aux_reg_p (mem)) 8575 return; 8576 8577 if (in_small_data) 8578 switch_to_section (get_named_section (NULL, ".sbss", 0)); 8579 /* named_section (0,".sbss",0); */ 8580 else 8581 switch_to_section (bss_section); 8582 8583 if (globalize_p) 8584 (*targetm.asm_out.globalize_label) (stream, name); 8585 8586 ASM_OUTPUT_ALIGN (stream, floor_log2 ((align) / BITS_PER_UNIT)); 8587 ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object"); 8588 ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size); 8589 ASM_OUTPUT_LABEL (stream, name); 8590 8591 if (size != 0) 8592 ASM_OUTPUT_SKIP (stream, size); 8593 } 8594 8595 static bool 8596 arc_preserve_reload_p (rtx in) 8597 { 8598 return (GET_CODE (in) == PLUS 8599 && RTX_OK_FOR_BASE_P (XEXP (in, 0), true) 8600 && CONST_INT_P (XEXP (in, 1)) 8601 && !((INTVAL (XEXP (in, 1)) & 511))); 8602 } 8603 8604 /* Implement TARGET_REGISTER_MOVE_COST. */ 8605 8606 static int 8607 arc_register_move_cost (machine_mode, 8608 reg_class_t from_class, reg_class_t to_class) 8609 { 8610 /* Force an attempt to 'mov Dy,Dx' to spill. */ 8611 if ((TARGET_ARC700 || TARGET_EM) && TARGET_DPFP 8612 && from_class == DOUBLE_REGS && to_class == DOUBLE_REGS) 8613 return 100; 8614 8615 return 2; 8616 } 8617 8618 /* Emit code for an addsi3 instruction with OPERANDS. 8619 COND_P indicates if this will use conditional execution. 8620 Return the length of the instruction. 8621 If OUTPUT_P is false, don't actually output the instruction, just return 8622 its length. */ 8623 int 8624 arc_output_addsi (rtx *operands, bool cond_p, bool output_p) 8625 { 8626 char format[35]; 8627 8628 int match = operands_match_p (operands[0], operands[1]); 8629 int match2 = operands_match_p (operands[0], operands[2]); 8630 int intval = (REG_P (operands[2]) ? 1 8631 : CONST_INT_P (operands[2]) ? INTVAL (operands[2]) : 0xbadc057); 8632 int neg_intval = -intval; 8633 int short_0 = satisfies_constraint_Rcq (operands[0]); 8634 int short_p = (!cond_p && short_0 && satisfies_constraint_Rcq (operands[1])); 8635 int ret = 0; 8636 8637 #define REG_H_P(OP) (REG_P (OP) && ((TARGET_V2 && REGNO (OP) <= 31 \ 8638 && REGNO (OP) != 30) \ 8639 || !TARGET_V2)) 8640 8641 #define ADDSI_OUTPUT1(FORMAT) do {\ 8642 if (output_p) \ 8643 output_asm_insn (FORMAT, operands);\ 8644 return ret; \ 8645 } while (0) 8646 #define ADDSI_OUTPUT(LIST) do {\ 8647 if (output_p) \ 8648 sprintf LIST;\ 8649 ADDSI_OUTPUT1 (format);\ 8650 return ret; \ 8651 } while (0) 8652 8653 /* First try to emit a 16 bit insn. */ 8654 ret = 2; 8655 if (!cond_p 8656 /* If we are actually about to output this insn, don't try a 16 bit 8657 variant if we already decided that we don't want that 8658 (I.e. we upsized this insn to align some following insn.) 8659 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM - 8660 but add1 r0,sp,35 doesn't. */ 8661 && (!output_p || (get_attr_length (current_output_insn) & 2))) 8662 { 8663 /* Generate add_s a,b,c; add_s b,b,u7; add_s c,b,u3; add_s b,b,h 8664 patterns. */ 8665 if (short_p 8666 && ((REG_H_P (operands[2]) 8667 && (match || satisfies_constraint_Rcq (operands[2]))) 8668 || (CONST_INT_P (operands[2]) 8669 && ((unsigned) intval <= (match ? 127 : 7))))) 8670 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;1"); 8671 8672 /* Generate add_s b,b,h patterns. */ 8673 if (short_0 && match2 && REG_H_P (operands[1])) 8674 ADDSI_OUTPUT1 ("add%? %0,%2,%1 ;2"); 8675 8676 /* Generate add_s b,sp,u7; add_s sp,sp,u7 patterns. */ 8677 if ((short_0 || REGNO (operands[0]) == STACK_POINTER_REGNUM) 8678 && REGNO (operands[1]) == STACK_POINTER_REGNUM && !(intval & ~124)) 8679 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;3"); 8680 8681 if ((short_p && (unsigned) neg_intval <= (match ? 31 : 7)) 8682 || (REGNO (operands[0]) == STACK_POINTER_REGNUM 8683 && match && !(neg_intval & ~124))) 8684 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2 ;4"); 8685 8686 /* Generate add_s h,h,s3 patterns. */ 8687 if (REG_H_P (operands[0]) && match && TARGET_V2 8688 && CONST_INT_P (operands[2]) && ((intval>= -1) && (intval <= 6))) 8689 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;5"); 8690 8691 /* Generate add_s r0,b,u6; add_s r1,b,u6 patterns. */ 8692 if (TARGET_CODE_DENSITY && REG_P (operands[0]) && REG_P (operands[1]) 8693 && ((REGNO (operands[0]) == 0) || (REGNO (operands[0]) == 1)) 8694 && satisfies_constraint_Rcq (operands[1]) 8695 && satisfies_constraint_L (operands[2])) 8696 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;6"); 8697 } 8698 8699 /* Now try to emit a 32 bit insn without long immediate. */ 8700 ret = 4; 8701 if (!match && match2 && REG_P (operands[1])) 8702 ADDSI_OUTPUT1 ("add%? %0,%2,%1"); 8703 if (match || !cond_p) 8704 { 8705 int limit = (match && !cond_p) ? 0x7ff : 0x3f; 8706 int range_factor = neg_intval & intval; 8707 int shift; 8708 8709 if (intval == (HOST_WIDE_INT) (HOST_WIDE_INT_M1U << 31)) 8710 ADDSI_OUTPUT1 ("bxor%? %0,%1,31"); 8711 8712 /* If we can use a straight add / sub instead of a {add,sub}[123] of 8713 same size, do, so - the insn latency is lower. */ 8714 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but 8715 0x800 is not. */ 8716 if ((intval >= 0 && intval <= limit) 8717 || (intval == -0x800 && limit == 0x7ff)) 8718 ADDSI_OUTPUT1 ("add%? %0,%1,%2"); 8719 else if ((intval < 0 && neg_intval <= limit) 8720 || (intval == 0x800 && limit == 0x7ff)) 8721 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2"); 8722 shift = range_factor >= 8 ? 3 : (range_factor >> 1); 8723 gcc_assert (shift == 0 || shift == 1 || shift == 2 || shift == 3); 8724 gcc_assert ((((1 << shift) - 1) & intval) == 0); 8725 if (((intval < 0 && intval != -0x4000) 8726 /* sub[123] is slower than add_s / sub, only use it if it 8727 avoids a long immediate. */ 8728 && neg_intval <= limit << shift) 8729 || (intval == 0x4000 && limit == 0x7ff)) 8730 ADDSI_OUTPUT ((format, "sub%d%%? %%0,%%1,%d", 8731 shift, neg_intval >> shift)); 8732 else if ((intval >= 0 && intval <= limit << shift) 8733 || (intval == -0x4000 && limit == 0x7ff)) 8734 ADDSI_OUTPUT ((format, "add%d%%? %%0,%%1,%d", shift, intval >> shift)); 8735 } 8736 /* Try to emit a 16 bit opcode with long immediate. */ 8737 ret = 6; 8738 if (short_p && match) 8739 ADDSI_OUTPUT1 ("add%? %0,%1,%2"); 8740 8741 /* We have to use a 32 bit opcode, and with a long immediate. */ 8742 ret = 8; 8743 ADDSI_OUTPUT1 (intval < 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%2"); 8744 } 8745 8746 /* Emit code for an commutative_cond_exec instruction with OPERANDS. 8747 Return the length of the instruction. 8748 If OUTPUT_P is false, don't actually output the instruction, just return 8749 its length. */ 8750 int 8751 arc_output_commutative_cond_exec (rtx *operands, bool output_p) 8752 { 8753 enum rtx_code commutative_op = GET_CODE (operands[3]); 8754 const char *pat = NULL; 8755 8756 /* Canonical rtl should not have a constant in the first operand position. */ 8757 gcc_assert (!CONSTANT_P (operands[1])); 8758 8759 switch (commutative_op) 8760 { 8761 case AND: 8762 if (satisfies_constraint_C1p (operands[2])) 8763 pat = "bmsk%? %0,%1,%Z2"; 8764 else if (satisfies_constraint_C2p (operands[2])) 8765 { 8766 operands[2] = GEN_INT ((~INTVAL (operands[2]))); 8767 pat = "bmskn%? %0,%1,%Z2"; 8768 } 8769 else if (satisfies_constraint_Ccp (operands[2])) 8770 pat = "bclr%? %0,%1,%M2"; 8771 else if (satisfies_constraint_CnL (operands[2])) 8772 pat = "bic%? %0,%1,%n2-1"; 8773 break; 8774 case IOR: 8775 if (satisfies_constraint_C0p (operands[2])) 8776 pat = "bset%? %0,%1,%z2"; 8777 break; 8778 case XOR: 8779 if (satisfies_constraint_C0p (operands[2])) 8780 pat = "bxor%? %0,%1,%z2"; 8781 break; 8782 case PLUS: 8783 return arc_output_addsi (operands, true, output_p); 8784 default: break; 8785 } 8786 if (output_p) 8787 output_asm_insn (pat ? pat : "%O3.%d5 %0,%1,%2", operands); 8788 if (pat || REG_P (operands[2]) || satisfies_constraint_L (operands[2])) 8789 return 4; 8790 return 8; 8791 } 8792 8793 /* Helper function of arc_expand_movmem. ADDR points to a chunk of memory. 8794 Emit code and return an potentially modified address such that offsets 8795 up to SIZE are can be added to yield a legitimate address. 8796 if REUSE is set, ADDR is a register that may be modified. */ 8797 8798 static rtx 8799 force_offsettable (rtx addr, HOST_WIDE_INT size, bool reuse) 8800 { 8801 rtx base = addr; 8802 rtx offs = const0_rtx; 8803 8804 if (GET_CODE (base) == PLUS) 8805 { 8806 offs = XEXP (base, 1); 8807 base = XEXP (base, 0); 8808 } 8809 if (!REG_P (base) 8810 || (REGNO (base) != STACK_POINTER_REGNUM 8811 && REGNO_PTR_FRAME_P (REGNO (base))) 8812 || !CONST_INT_P (offs) || !SMALL_INT (INTVAL (offs)) 8813 || !SMALL_INT (INTVAL (offs) + size)) 8814 { 8815 if (reuse) 8816 emit_insn (gen_add2_insn (addr, offs)); 8817 else 8818 addr = copy_to_mode_reg (Pmode, addr); 8819 } 8820 return addr; 8821 } 8822 8823 /* Like move_by_pieces, but take account of load latency, and actual 8824 offset ranges. Return true on success. */ 8825 8826 bool 8827 arc_expand_movmem (rtx *operands) 8828 { 8829 rtx dst = operands[0]; 8830 rtx src = operands[1]; 8831 rtx dst_addr, src_addr; 8832 HOST_WIDE_INT size; 8833 int align = INTVAL (operands[3]); 8834 unsigned n_pieces; 8835 int piece = align; 8836 rtx store[2]; 8837 rtx tmpx[2]; 8838 int i; 8839 8840 if (!CONST_INT_P (operands[2])) 8841 return false; 8842 size = INTVAL (operands[2]); 8843 /* move_by_pieces_ninsns is static, so we can't use it. */ 8844 if (align >= 4) 8845 { 8846 if (TARGET_LL64) 8847 n_pieces = (size + 4) / 8U + ((size >> 1) & 1) + (size & 1); 8848 else 8849 n_pieces = (size + 2) / 4U + (size & 1); 8850 } 8851 else if (align == 2) 8852 n_pieces = (size + 1) / 2U; 8853 else 8854 n_pieces = size; 8855 if (n_pieces >= (unsigned int) (optimize_size ? 3 : 15)) 8856 return false; 8857 /* Force 32 bit aligned and larger datum to use 64 bit transfers, if 8858 possible. */ 8859 if (TARGET_LL64 && (piece >= 4) && (size >= 8)) 8860 piece = 8; 8861 else if (piece > 4) 8862 piece = 4; 8863 dst_addr = force_offsettable (XEXP (operands[0], 0), size, 0); 8864 src_addr = force_offsettable (XEXP (operands[1], 0), size, 0); 8865 store[0] = store[1] = NULL_RTX; 8866 tmpx[0] = tmpx[1] = NULL_RTX; 8867 for (i = 0; size > 0; i ^= 1, size -= piece) 8868 { 8869 rtx tmp; 8870 machine_mode mode; 8871 8872 while (piece > size) 8873 piece >>= 1; 8874 mode = smallest_int_mode_for_size (piece * BITS_PER_UNIT); 8875 /* If we don't re-use temporaries, the scheduler gets carried away, 8876 and the register pressure gets unnecessarily high. */ 8877 if (0 && tmpx[i] && GET_MODE (tmpx[i]) == mode) 8878 tmp = tmpx[i]; 8879 else 8880 tmpx[i] = tmp = gen_reg_rtx (mode); 8881 dst_addr = force_offsettable (dst_addr, piece, 1); 8882 src_addr = force_offsettable (src_addr, piece, 1); 8883 if (store[i]) 8884 emit_insn (store[i]); 8885 emit_move_insn (tmp, change_address (src, mode, src_addr)); 8886 store[i] = gen_move_insn (change_address (dst, mode, dst_addr), tmp); 8887 dst_addr = plus_constant (Pmode, dst_addr, piece); 8888 src_addr = plus_constant (Pmode, src_addr, piece); 8889 } 8890 if (store[i]) 8891 emit_insn (store[i]); 8892 if (store[i^1]) 8893 emit_insn (store[i^1]); 8894 return true; 8895 } 8896 8897 static bool 8898 arc_get_aux_arg (rtx pat, int *auxr) 8899 { 8900 tree attr, addr = MEM_EXPR (pat); 8901 if (TREE_CODE (addr) != VAR_DECL) 8902 return false; 8903 8904 attr = DECL_ATTRIBUTES (addr); 8905 if (lookup_attribute ("aux", attr)) 8906 { 8907 tree arg = TREE_VALUE (attr); 8908 if (arg) 8909 { 8910 *auxr = TREE_INT_CST_LOW (TREE_VALUE (arg)); 8911 return true; 8912 } 8913 } 8914 8915 return false; 8916 } 8917 8918 /* Prepare operands for move in MODE. Return true iff the move has 8919 been emitted. */ 8920 8921 bool 8922 prepare_move_operands (rtx *operands, machine_mode mode) 8923 { 8924 /* First handle aux attribute. */ 8925 if (mode == SImode 8926 && (MEM_P (operands[0]) || MEM_P (operands[1]))) 8927 { 8928 rtx tmp; 8929 int auxr = 0; 8930 if (MEM_P (operands[0]) && arc_is_aux_reg_p (operands[0])) 8931 { 8932 /* Save operation. */ 8933 if (arc_get_aux_arg (operands[0], &auxr)) 8934 { 8935 tmp = gen_reg_rtx (SImode); 8936 emit_move_insn (tmp, GEN_INT (auxr)); 8937 } 8938 else 8939 { 8940 tmp = XEXP (operands[0], 0); 8941 } 8942 8943 operands[1] = force_reg (SImode, operands[1]); 8944 emit_insn (gen_rtx_UNSPEC_VOLATILE 8945 (VOIDmode, gen_rtvec (2, operands[1], tmp), 8946 VUNSPEC_ARC_SR)); 8947 return true; 8948 } 8949 if (MEM_P (operands[1]) && arc_is_aux_reg_p (operands[1])) 8950 { 8951 if (arc_get_aux_arg (operands[1], &auxr)) 8952 { 8953 tmp = gen_reg_rtx (SImode); 8954 emit_move_insn (tmp, GEN_INT (auxr)); 8955 } 8956 else 8957 { 8958 tmp = XEXP (operands[1], 0); 8959 gcc_assert (GET_CODE (tmp) == SYMBOL_REF); 8960 } 8961 /* Load operation. */ 8962 gcc_assert (REG_P (operands[0])); 8963 emit_insn (gen_rtx_SET (operands[0], 8964 gen_rtx_UNSPEC_VOLATILE 8965 (SImode, gen_rtvec (1, tmp), 8966 VUNSPEC_ARC_LR))); 8967 return true; 8968 } 8969 } 8970 8971 if (GET_CODE (operands[1]) == SYMBOL_REF) 8972 { 8973 enum tls_model model = SYMBOL_REF_TLS_MODEL (operands[1]); 8974 if (MEM_P (operands[0])) 8975 operands[1] = force_reg (mode, operands[1]); 8976 else if (model) 8977 operands[1] = arc_legitimize_tls_address (operands[1], model); 8978 } 8979 8980 operands[1] = arc_legitimize_pic_address (operands[1]); 8981 8982 /* Store instructions are limited, they only accept as address an 8983 immediate, a register or a register plus a small immediate. */ 8984 if (MEM_P (operands[0]) 8985 && !move_dest_operand (operands[0], mode)) 8986 { 8987 rtx tmp0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); 8988 rtx tmp1 = change_address (operands[0], mode, tmp0); 8989 MEM_COPY_ATTRIBUTES (tmp1, operands[0]); 8990 operands[0] = tmp1; 8991 } 8992 8993 /* Check if it is constant but it is not legitimized. */ 8994 if (CONSTANT_P (operands[1]) 8995 && !arc_legitimate_constant_p (mode, operands[1])) 8996 operands[1] = force_reg (mode, XEXP (operands[1], 0)); 8997 else if (MEM_P (operands[0]) 8998 && ((CONSTANT_P (operands[1]) 8999 && !satisfies_constraint_Cm3 (operands[1])) 9000 || MEM_P (operands[1]))) 9001 operands[1] = force_reg (mode, operands[1]); 9002 9003 return false; 9004 } 9005 9006 /* Output a library call to a function called FNAME that has been arranged 9007 to be local to any dso. */ 9008 9009 const char * 9010 arc_output_libcall (const char *fname) 9011 { 9012 unsigned len = strlen (fname); 9013 static char buf[64]; 9014 9015 gcc_assert (len < sizeof buf - 35); 9016 if (TARGET_LONG_CALLS_SET 9017 || (TARGET_MEDIUM_CALLS && arc_ccfsm_cond_exec_p ())) 9018 { 9019 if (flag_pic) 9020 sprintf (buf, "add r12,pcl,@%s@pcl\n\tjl%%!%%* [r12]", fname); 9021 else 9022 sprintf (buf, "jl%%! @%s", fname); 9023 } 9024 else 9025 sprintf (buf, "bl%%!%%* @%s", fname); 9026 return buf; 9027 } 9028 9029 /* Return the SImode highpart of the DImode value IN. */ 9030 9031 rtx 9032 disi_highpart (rtx in) 9033 { 9034 return simplify_gen_subreg (SImode, in, DImode, TARGET_BIG_ENDIAN ? 0 : 4); 9035 } 9036 9037 /* Return length adjustment for INSN. 9038 For ARC600: 9039 A write to a core reg greater or equal to 32 must not be immediately 9040 followed by a use. Anticipate the length requirement to insert a nop 9041 between PRED and SUCC to prevent a hazard. */ 9042 9043 static int 9044 arc600_corereg_hazard (rtx_insn *pred, rtx_insn *succ) 9045 { 9046 if (!TARGET_ARC600) 9047 return 0; 9048 if (GET_CODE (PATTERN (pred)) == SEQUENCE) 9049 pred = as_a <rtx_sequence *> (PATTERN (pred))->insn (1); 9050 if (GET_CODE (PATTERN (succ)) == SEQUENCE) 9051 succ = as_a <rtx_sequence *> (PATTERN (succ))->insn (0); 9052 if (recog_memoized (pred) == CODE_FOR_mulsi_600 9053 || recog_memoized (pred) == CODE_FOR_umul_600 9054 || recog_memoized (pred) == CODE_FOR_mac_600 9055 || recog_memoized (pred) == CODE_FOR_mul64_600 9056 || recog_memoized (pred) == CODE_FOR_mac64_600 9057 || recog_memoized (pred) == CODE_FOR_umul64_600 9058 || recog_memoized (pred) == CODE_FOR_umac64_600) 9059 return 0; 9060 subrtx_iterator::array_type array; 9061 FOR_EACH_SUBRTX (iter, array, PATTERN (pred), NONCONST) 9062 { 9063 const_rtx x = *iter; 9064 switch (GET_CODE (x)) 9065 { 9066 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC: 9067 break; 9068 default: 9069 /* This is also fine for PRE/POST_MODIFY, because they 9070 contain a SET. */ 9071 continue; 9072 } 9073 rtx dest = XEXP (x, 0); 9074 /* Check if this sets a an extension register. N.B. we use 61 for the 9075 condition codes, which is definitely not an extension register. */ 9076 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61 9077 /* Check if the same register is used by the PAT. */ 9078 && (refers_to_regno_p 9079 (REGNO (dest), 9080 REGNO (dest) + (GET_MODE_SIZE (GET_MODE (dest)) + 3) / 4U, 9081 PATTERN (succ), 0))) 9082 return 4; 9083 } 9084 return 0; 9085 } 9086 9087 /* Given a rtx, check if it is an assembly instruction or not. */ 9088 9089 static int 9090 arc_asm_insn_p (rtx x) 9091 { 9092 int i, j; 9093 9094 if (x == 0) 9095 return 0; 9096 9097 switch (GET_CODE (x)) 9098 { 9099 case ASM_OPERANDS: 9100 case ASM_INPUT: 9101 return 1; 9102 9103 case SET: 9104 return arc_asm_insn_p (SET_SRC (x)); 9105 9106 case PARALLEL: 9107 j = 0; 9108 for (i = XVECLEN (x, 0) - 1; i >= 0; i--) 9109 j += arc_asm_insn_p (XVECEXP (x, 0, i)); 9110 if ( j > 0) 9111 return 1; 9112 break; 9113 9114 default: 9115 break; 9116 } 9117 9118 return 0; 9119 } 9120 9121 /* For ARC600: 9122 A write to a core reg greater or equal to 32 must not be immediately 9123 followed by a use. Anticipate the length requirement to insert a nop 9124 between PRED and SUCC to prevent a hazard. */ 9125 9126 int 9127 arc_hazard (rtx_insn *pred, rtx_insn *succ) 9128 { 9129 if (!pred || !INSN_P (pred) || !succ || !INSN_P (succ)) 9130 return 0; 9131 9132 if (TARGET_ARC600) 9133 return arc600_corereg_hazard (pred, succ); 9134 9135 return 0; 9136 } 9137 9138 /* Return length adjustment for INSN. */ 9139 9140 int 9141 arc_adjust_insn_length (rtx_insn *insn, int len, bool) 9142 { 9143 if (!INSN_P (insn)) 9144 return len; 9145 /* We already handle sequences by ignoring the delay sequence flag. */ 9146 if (GET_CODE (PATTERN (insn)) == SEQUENCE) 9147 return len; 9148 9149 /* Check for return with but one preceding insn since function 9150 start / call. */ 9151 if (TARGET_PAD_RETURN 9152 && JUMP_P (insn) 9153 && GET_CODE (PATTERN (insn)) != ADDR_VEC 9154 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC 9155 && get_attr_type (insn) == TYPE_RETURN) 9156 { 9157 rtx_insn *prev = prev_active_insn (insn); 9158 9159 if (!prev || !(prev = prev_active_insn (prev)) 9160 || ((NONJUMP_INSN_P (prev) 9161 && GET_CODE (PATTERN (prev)) == SEQUENCE) 9162 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0), 9163 NON_SIBCALL) 9164 : CALL_ATTR (prev, NON_SIBCALL))) 9165 return len + 4; 9166 } 9167 if (TARGET_ARC600) 9168 { 9169 rtx_insn *succ = next_real_insn (insn); 9170 9171 /* One the ARC600, a write to an extension register must be separated 9172 from a read. */ 9173 if (succ && INSN_P (succ)) 9174 len += arc600_corereg_hazard (insn, succ); 9175 } 9176 9177 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one 9178 can go awry. */ 9179 extract_constrain_insn_cached (insn); 9180 9181 return len; 9182 } 9183 9184 /* Return a copy of COND from *STATEP, inverted if that is indicated by the 9185 CC field of *STATEP. */ 9186 9187 static rtx 9188 arc_get_ccfsm_cond (struct arc_ccfsm *statep, bool reverse) 9189 { 9190 rtx cond = statep->cond; 9191 int raw_cc = get_arc_condition_code (cond); 9192 if (reverse) 9193 raw_cc = ARC_INVERSE_CONDITION_CODE (raw_cc); 9194 9195 if (statep->cc == raw_cc) 9196 return copy_rtx (cond); 9197 9198 gcc_assert (ARC_INVERSE_CONDITION_CODE (raw_cc) == statep->cc); 9199 9200 machine_mode ccm = GET_MODE (XEXP (cond, 0)); 9201 enum rtx_code code = reverse_condition (GET_CODE (cond)); 9202 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode) 9203 code = reverse_condition_maybe_unordered (GET_CODE (cond)); 9204 9205 return gen_rtx_fmt_ee (code, GET_MODE (cond), 9206 copy_rtx (XEXP (cond, 0)), copy_rtx (XEXP (cond, 1))); 9207 } 9208 9209 /* Return version of PAT conditionalized with COND, which is part of INSN. 9210 ANNULLED indicates if INSN is an annulled delay-slot insn. 9211 Register further changes if necessary. */ 9212 static rtx 9213 conditionalize_nonjump (rtx pat, rtx cond, rtx insn, bool annulled) 9214 { 9215 /* For commutative operators, we generally prefer to have 9216 the first source match the destination. */ 9217 if (GET_CODE (pat) == SET) 9218 { 9219 rtx src = SET_SRC (pat); 9220 9221 if (COMMUTATIVE_P (src)) 9222 { 9223 rtx src0 = XEXP (src, 0); 9224 rtx src1 = XEXP (src, 1); 9225 rtx dst = SET_DEST (pat); 9226 9227 if (rtx_equal_p (src1, dst) && !rtx_equal_p (src0, dst) 9228 /* Leave add_n alone - the canonical form is to 9229 have the complex summand first. */ 9230 && REG_P (src0)) 9231 pat = gen_rtx_SET (dst, 9232 gen_rtx_fmt_ee (GET_CODE (src), GET_MODE (src), 9233 src1, src0)); 9234 } 9235 } 9236 9237 /* dwarf2out.c:dwarf2out_frame_debug_expr doesn't know 9238 what to do with COND_EXEC. */ 9239 if (RTX_FRAME_RELATED_P (insn)) 9240 { 9241 /* If this is the delay slot insn of an anulled branch, 9242 dwarf2out.c:scan_trace understands the anulling semantics 9243 without the COND_EXEC. */ 9244 gcc_assert (annulled); 9245 rtx note = alloc_reg_note (REG_FRAME_RELATED_EXPR, pat, 9246 REG_NOTES (insn)); 9247 validate_change (insn, ®_NOTES (insn), note, 1); 9248 } 9249 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat); 9250 return pat; 9251 } 9252 9253 /* Use the ccfsm machinery to do if conversion. */ 9254 9255 static unsigned 9256 arc_ifcvt (void) 9257 { 9258 struct arc_ccfsm *statep = &cfun->machine->ccfsm_current; 9259 9260 memset (statep, 0, sizeof *statep); 9261 for (rtx_insn *insn = get_insns (); insn; insn = next_insn (insn)) 9262 { 9263 arc_ccfsm_advance (insn, statep); 9264 9265 switch (statep->state) 9266 { 9267 case 0: 9268 break; 9269 case 1: case 2: 9270 { 9271 /* Deleted branch. */ 9272 arc_ccfsm_post_advance (insn, statep); 9273 gcc_assert (!IN_RANGE (statep->state, 1, 2)); 9274 rtx_insn *seq = NEXT_INSN (PREV_INSN (insn)); 9275 if (GET_CODE (PATTERN (seq)) == SEQUENCE) 9276 { 9277 rtx slot = XVECEXP (PATTERN (seq), 0, 1); 9278 rtx pat = PATTERN (slot); 9279 if (INSN_ANNULLED_BRANCH_P (insn)) 9280 { 9281 rtx cond 9282 = arc_get_ccfsm_cond (statep, INSN_FROM_TARGET_P (slot)); 9283 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat); 9284 } 9285 if (!validate_change (seq, &PATTERN (seq), pat, 0)) 9286 gcc_unreachable (); 9287 PUT_CODE (slot, NOTE); 9288 NOTE_KIND (slot) = NOTE_INSN_DELETED; 9289 } 9290 else 9291 { 9292 set_insn_deleted (insn); 9293 } 9294 continue; 9295 } 9296 case 3: 9297 if (LABEL_P (insn) 9298 && statep->target_label == CODE_LABEL_NUMBER (insn)) 9299 { 9300 arc_ccfsm_post_advance (insn, statep); 9301 if (--LABEL_NUSES (insn) == 0) 9302 delete_insn (insn); 9303 continue; 9304 } 9305 /* Fall through. */ 9306 case 4: case 5: 9307 if (!NONDEBUG_INSN_P (insn)) 9308 break; 9309 9310 /* Conditionalized insn. */ 9311 9312 rtx_insn *prev, *pprev; 9313 rtx *patp, pat, cond; 9314 bool annulled; annulled = false; 9315 9316 /* If this is a delay slot insn in a non-annulled branch, 9317 don't conditionalize it. N.B., this should be fine for 9318 conditional return too. However, don't do this for 9319 unconditional branches, as these would be encountered when 9320 processing an 'else' part. */ 9321 prev = PREV_INSN (insn); 9322 pprev = PREV_INSN (prev); 9323 if (pprev && NEXT_INSN (NEXT_INSN (pprev)) == NEXT_INSN (insn) 9324 && JUMP_P (prev) && get_attr_cond (prev) == COND_USE) 9325 { 9326 if (!INSN_ANNULLED_BRANCH_P (prev)) 9327 break; 9328 annulled = true; 9329 } 9330 9331 patp = &PATTERN (insn); 9332 pat = *patp; 9333 cond = arc_get_ccfsm_cond (statep, INSN_FROM_TARGET_P (insn)); 9334 if (NONJUMP_INSN_P (insn) || CALL_P (insn)) 9335 { 9336 /* ??? don't conditionalize if all side effects are dead 9337 in the not-execute case. */ 9338 9339 pat = conditionalize_nonjump (pat, cond, insn, annulled); 9340 } 9341 else if (simplejump_p (insn)) 9342 { 9343 patp = &SET_SRC (pat); 9344 pat = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, *patp, pc_rtx); 9345 } 9346 else if (JUMP_P (insn) && ANY_RETURN_P (PATTERN (insn))) 9347 { 9348 pat = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, pat, pc_rtx); 9349 pat = gen_rtx_SET (pc_rtx, pat); 9350 } 9351 else 9352 gcc_unreachable (); 9353 validate_change (insn, patp, pat, 1); 9354 if (!apply_change_group ()) 9355 gcc_unreachable (); 9356 if (JUMP_P (insn)) 9357 { 9358 rtx_insn *next = next_nonnote_insn (insn); 9359 if (GET_CODE (next) == BARRIER) 9360 delete_insn (next); 9361 if (statep->state == 3) 9362 continue; 9363 } 9364 break; 9365 default: 9366 gcc_unreachable (); 9367 } 9368 arc_ccfsm_post_advance (insn, statep); 9369 } 9370 return 0; 9371 } 9372 9373 /* Find annulled delay insns and convert them to use the appropriate predicate. 9374 This allows branch shortening to size up these insns properly. */ 9375 9376 static unsigned 9377 arc_predicate_delay_insns (void) 9378 { 9379 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn)) 9380 { 9381 rtx pat, jump, dlay, src, cond, *patp; 9382 int reverse; 9383 9384 if (!NONJUMP_INSN_P (insn) 9385 || GET_CODE (pat = PATTERN (insn)) != SEQUENCE) 9386 continue; 9387 jump = XVECEXP (pat, 0, 0); 9388 dlay = XVECEXP (pat, 0, 1); 9389 if (!JUMP_P (jump) || !INSN_ANNULLED_BRANCH_P (jump)) 9390 continue; 9391 /* If the branch insn does the annulling, leave the delay insn alone. */ 9392 if (!TARGET_AT_DBR_CONDEXEC && !INSN_FROM_TARGET_P (dlay)) 9393 continue; 9394 /* ??? Could also leave DLAY un-conditionalized if its target is dead 9395 on the other path. */ 9396 gcc_assert (GET_CODE (PATTERN (jump)) == SET); 9397 gcc_assert (SET_DEST (PATTERN (jump)) == pc_rtx); 9398 src = SET_SRC (PATTERN (jump)); 9399 gcc_assert (GET_CODE (src) == IF_THEN_ELSE); 9400 cond = XEXP (src, 0); 9401 if (XEXP (src, 2) == pc_rtx) 9402 reverse = 0; 9403 else if (XEXP (src, 1) == pc_rtx) 9404 reverse = 1; 9405 else 9406 gcc_unreachable (); 9407 if (reverse != !INSN_FROM_TARGET_P (dlay)) 9408 { 9409 machine_mode ccm = GET_MODE (XEXP (cond, 0)); 9410 enum rtx_code code = reverse_condition (GET_CODE (cond)); 9411 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode) 9412 code = reverse_condition_maybe_unordered (GET_CODE (cond)); 9413 9414 cond = gen_rtx_fmt_ee (code, GET_MODE (cond), 9415 copy_rtx (XEXP (cond, 0)), 9416 copy_rtx (XEXP (cond, 1))); 9417 } 9418 else 9419 cond = copy_rtx (cond); 9420 patp = &PATTERN (dlay); 9421 pat = *patp; 9422 pat = conditionalize_nonjump (pat, cond, dlay, true); 9423 validate_change (dlay, patp, pat, 1); 9424 if (!apply_change_group ()) 9425 gcc_unreachable (); 9426 } 9427 return 0; 9428 } 9429 9430 /* For ARC600: If a write to a core reg >=32 appears in a delay slot 9431 (other than of a forward brcc), it creates a hazard when there is a read 9432 of the same register at the branch target. We can't know what is at the 9433 branch target of calls, and for branches, we don't really know before the 9434 end of delay slot scheduling, either. Not only can individual instruction 9435 be hoisted out into a delay slot, a basic block can also be emptied this 9436 way, and branch and/or fall through targets be redirected. Hence we don't 9437 want such writes in a delay slot. */ 9438 9439 /* Return nonzreo iff INSN writes to an extension core register. */ 9440 9441 int 9442 arc_write_ext_corereg (rtx insn) 9443 { 9444 subrtx_iterator::array_type array; 9445 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST) 9446 { 9447 const_rtx x = *iter; 9448 switch (GET_CODE (x)) 9449 { 9450 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC: 9451 break; 9452 default: 9453 /* This is also fine for PRE/POST_MODIFY, because they 9454 contain a SET. */ 9455 continue; 9456 } 9457 const_rtx dest = XEXP (x, 0); 9458 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61) 9459 return 1; 9460 } 9461 return 0; 9462 } 9463 9464 /* This is like the hook, but returns NULL when it can't / won't generate 9465 a legitimate address. */ 9466 9467 static rtx 9468 arc_legitimize_address_0 (rtx x, rtx oldx ATTRIBUTE_UNUSED, 9469 machine_mode mode) 9470 { 9471 rtx addr, inner; 9472 9473 addr = x; 9474 if (GET_CODE (addr) == CONST) 9475 addr = XEXP (addr, 0); 9476 9477 if (GET_CODE (addr) == PLUS 9478 && CONST_INT_P (XEXP (addr, 1)) 9479 && ((GET_CODE (XEXP (addr, 0)) == SYMBOL_REF 9480 && !SYMBOL_REF_FUNCTION_P (XEXP (addr, 0))) 9481 || (REG_P (XEXP (addr, 0)) 9482 && (INTVAL (XEXP (addr, 1)) & 252)))) 9483 { 9484 HOST_WIDE_INT offs, upper; 9485 int size = GET_MODE_SIZE (mode); 9486 9487 offs = INTVAL (XEXP (addr, 1)); 9488 upper = (offs + 256 * size) & ~511 * size; 9489 inner = plus_constant (Pmode, XEXP (addr, 0), upper); 9490 #if 0 /* ??? this produces worse code for EEMBC idctrn01 */ 9491 if (GET_CODE (x) == CONST) 9492 inner = gen_rtx_CONST (Pmode, inner); 9493 #endif 9494 addr = plus_constant (Pmode, force_reg (Pmode, inner), offs - upper); 9495 x = addr; 9496 } 9497 else if (GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FUNCTION_P (addr)) 9498 x = force_reg (Pmode, x); 9499 if (memory_address_p ((machine_mode) mode, x)) 9500 return x; 9501 return NULL_RTX; 9502 } 9503 9504 static rtx 9505 arc_legitimize_address (rtx orig_x, rtx oldx, machine_mode mode) 9506 { 9507 rtx new_x = arc_legitimize_address_0 (orig_x, oldx, mode); 9508 9509 if (new_x) 9510 return new_x; 9511 return orig_x; 9512 } 9513 9514 static rtx 9515 arc_delegitimize_address_0 (rtx op) 9516 { 9517 switch (GET_CODE (op)) 9518 { 9519 case CONST: 9520 return arc_delegitimize_address_0 (XEXP (op, 0)); 9521 9522 case UNSPEC: 9523 switch (XINT (op, 1)) 9524 { 9525 case ARC_UNSPEC_GOT: 9526 case ARC_UNSPEC_GOTOFFPC: 9527 return XVECEXP (op, 0, 0); 9528 default: 9529 break; 9530 } 9531 break; 9532 9533 case PLUS: 9534 { 9535 rtx t1 = arc_delegitimize_address_0 (XEXP (op, 0)); 9536 rtx t2 = XEXP (op, 1); 9537 9538 if (t1 && t2) 9539 return gen_rtx_PLUS (GET_MODE (op), t1, t2); 9540 break; 9541 } 9542 9543 default: 9544 break; 9545 } 9546 return NULL_RTX; 9547 } 9548 9549 static rtx 9550 arc_delegitimize_address (rtx orig_x) 9551 { 9552 rtx x = orig_x; 9553 9554 if (MEM_P (x)) 9555 x = XEXP (x, 0); 9556 9557 x = arc_delegitimize_address_0 (x); 9558 if (!x) 9559 return orig_x; 9560 9561 if (MEM_P (orig_x)) 9562 x = replace_equiv_address_nv (orig_x, x); 9563 return x; 9564 } 9565 9566 /* Return a REG rtx for acc1. N.B. the gcc-internal representation may 9567 differ from the hardware register number in order to allow the generic 9568 code to correctly split the concatenation of acc1 and acc2. */ 9569 9570 rtx 9571 gen_acc1 (void) 9572 { 9573 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 56: 57); 9574 } 9575 9576 /* Return a REG rtx for acc2. N.B. the gcc-internal representation may 9577 differ from the hardware register number in order to allow the generic 9578 code to correctly split the concatenation of acc1 and acc2. */ 9579 9580 rtx 9581 gen_acc2 (void) 9582 { 9583 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 57: 56); 9584 } 9585 9586 /* Return a REG rtx for mlo. N.B. the gcc-internal representation may 9587 differ from the hardware register number in order to allow the generic 9588 code to correctly split the concatenation of mhi and mlo. */ 9589 9590 rtx 9591 gen_mlo (void) 9592 { 9593 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 59: 58); 9594 } 9595 9596 /* Return a REG rtx for mhi. N.B. the gcc-internal representation may 9597 differ from the hardware register number in order to allow the generic 9598 code to correctly split the concatenation of mhi and mlo. */ 9599 9600 rtx 9601 gen_mhi (void) 9602 { 9603 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 58: 59); 9604 } 9605 9606 /* FIXME: a parameter should be added, and code added to final.c, 9607 to reproduce this functionality in shorten_branches. */ 9608 #if 0 9609 /* Return nonzero iff BRANCH should be unaligned if possible by upsizing 9610 a previous instruction. */ 9611 int 9612 arc_unalign_branch_p (rtx branch) 9613 { 9614 rtx note; 9615 9616 if (!TARGET_UNALIGN_BRANCH) 9617 return 0; 9618 /* Do not do this if we have a filled delay slot. */ 9619 if (get_attr_delay_slot_filled (branch) == DELAY_SLOT_FILLED_YES 9620 && !NEXT_INSN (branch)->deleted ()) 9621 return 0; 9622 note = find_reg_note (branch, REG_BR_PROB, 0); 9623 return (!note 9624 || (arc_unalign_prob_threshold && !br_prob_note_reliable_p (note)) 9625 || INTVAL (XEXP (note, 0)) < arc_unalign_prob_threshold); 9626 } 9627 #endif 9628 9629 /* When estimating sizes during arc_reorg, when optimizing for speed, there 9630 are three reasons why we need to consider branches to be length 6: 9631 - annull-false delay slot insns are implemented using conditional execution, 9632 thus preventing short insn formation where used. 9633 - for ARC600: annul-true delay slot insns are implemented where possible 9634 using conditional execution, preventing short insn formation where used. 9635 - for ARC700: likely or somewhat likely taken branches are made long and 9636 unaligned if possible to avoid branch penalty. */ 9637 9638 bool 9639 arc_branch_size_unknown_p (void) 9640 { 9641 return !optimize_size && arc_reorg_in_progress; 9642 } 9643 9644 /* The usual; we set up our machine_function data. */ 9645 9646 static struct machine_function * 9647 arc_init_machine_status (void) 9648 { 9649 struct machine_function *machine; 9650 machine = ggc_cleared_alloc<machine_function> (); 9651 machine->fn_type = ARC_FUNCTION_UNKNOWN; 9652 9653 return machine; 9654 } 9655 9656 /* Implements INIT_EXPANDERS. We just set up to call the above 9657 function. */ 9658 9659 void 9660 arc_init_expanders (void) 9661 { 9662 init_machine_status = arc_init_machine_status; 9663 } 9664 9665 /* Check if OP is a proper parallel of a millicode call pattern. OFFSET 9666 indicates a number of elements to ignore - that allows to have a 9667 sibcall pattern that starts with (return). LOAD_P is zero for store 9668 multiple (for prologues), and one for load multiples (for epilogues), 9669 and two for load multiples where no final clobber of blink is required. 9670 We also skip the first load / store element since this is supposed to 9671 be checked in the instruction pattern. */ 9672 9673 int 9674 arc_check_millicode (rtx op, int offset, int load_p) 9675 { 9676 int len = XVECLEN (op, 0) - offset; 9677 int i; 9678 9679 if (load_p == 2) 9680 { 9681 if (len < 2 || len > 13) 9682 return 0; 9683 load_p = 1; 9684 } 9685 else 9686 { 9687 rtx elt = XVECEXP (op, 0, --len); 9688 9689 if (GET_CODE (elt) != CLOBBER 9690 || !REG_P (XEXP (elt, 0)) 9691 || REGNO (XEXP (elt, 0)) != RETURN_ADDR_REGNUM 9692 || len < 3 || len > 13) 9693 return 0; 9694 } 9695 for (i = 1; i < len; i++) 9696 { 9697 rtx elt = XVECEXP (op, 0, i + offset); 9698 rtx reg, mem, addr; 9699 9700 if (GET_CODE (elt) != SET) 9701 return 0; 9702 mem = XEXP (elt, load_p); 9703 reg = XEXP (elt, 1-load_p); 9704 if (!REG_P (reg) || REGNO (reg) != 13U+i || !MEM_P (mem)) 9705 return 0; 9706 addr = XEXP (mem, 0); 9707 if (GET_CODE (addr) != PLUS 9708 || !rtx_equal_p (stack_pointer_rtx, XEXP (addr, 0)) 9709 || !CONST_INT_P (XEXP (addr, 1)) || INTVAL (XEXP (addr, 1)) != i*4) 9710 return 0; 9711 } 9712 return 1; 9713 } 9714 9715 /* Accessor functions for cfun->machine->unalign. */ 9716 9717 int 9718 arc_get_unalign (void) 9719 { 9720 return cfun->machine->unalign; 9721 } 9722 9723 void 9724 arc_clear_unalign (void) 9725 { 9726 if (cfun) 9727 cfun->machine->unalign = 0; 9728 } 9729 9730 void 9731 arc_toggle_unalign (void) 9732 { 9733 cfun->machine->unalign ^= 2; 9734 } 9735 9736 /* Operands 0..2 are the operands of a addsi which uses a 12 bit 9737 constant in operand 2, but which would require a LIMM because of 9738 operand mismatch. 9739 operands 3 and 4 are new SET_SRCs for operands 0. */ 9740 9741 void 9742 split_addsi (rtx *operands) 9743 { 9744 int val = INTVAL (operands[2]); 9745 9746 /* Try for two short insns first. Lengths being equal, we prefer 9747 expansions with shorter register lifetimes. */ 9748 if (val > 127 && val <= 255 9749 && satisfies_constraint_Rcq (operands[0])) 9750 { 9751 operands[3] = operands[2]; 9752 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]); 9753 } 9754 else 9755 { 9756 operands[3] = operands[1]; 9757 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[2]); 9758 } 9759 } 9760 9761 /* Operands 0..2 are the operands of a subsi which uses a 12 bit 9762 constant in operand 1, but which would require a LIMM because of 9763 operand mismatch. 9764 operands 3 and 4 are new SET_SRCs for operands 0. */ 9765 9766 void 9767 split_subsi (rtx *operands) 9768 { 9769 int val = INTVAL (operands[1]); 9770 9771 /* Try for two short insns first. Lengths being equal, we prefer 9772 expansions with shorter register lifetimes. */ 9773 if (satisfies_constraint_Rcq (operands[0]) 9774 && satisfies_constraint_Rcq (operands[2])) 9775 { 9776 if (val >= -31 && val <= 127) 9777 { 9778 operands[3] = gen_rtx_NEG (SImode, operands[2]); 9779 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]); 9780 return; 9781 } 9782 else if (val >= 0 && val < 255) 9783 { 9784 operands[3] = operands[1]; 9785 operands[4] = gen_rtx_MINUS (SImode, operands[0], operands[2]); 9786 return; 9787 } 9788 } 9789 /* If the destination is not an ARCompact16 register, we might 9790 still have a chance to make a short insn if the source is; 9791 we need to start with a reg-reg move for this. */ 9792 operands[3] = operands[2]; 9793 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[0]); 9794 } 9795 9796 /* Handle DOUBLE_REGS uses. 9797 Operand 0: destination register 9798 Operand 1: source register */ 9799 9800 static bool 9801 arc_process_double_reg_moves (rtx *operands) 9802 { 9803 enum usesDxState { none, srcDx, destDx, maxDx }; 9804 enum usesDxState state = none; 9805 rtx dest = operands[0]; 9806 rtx src = operands[1]; 9807 9808 if (refers_to_regno_p (40, 44, src, 0)) 9809 { 9810 state = srcDx; 9811 gcc_assert (REG_P (dest)); 9812 } 9813 if (refers_to_regno_p (40, 44, dest, 0)) 9814 { 9815 /* Via arc_register_move_cost, we should never see D,D moves. */ 9816 gcc_assert (REG_P (src)); 9817 gcc_assert (state == none); 9818 state = destDx; 9819 } 9820 9821 if (state == none) 9822 return false; 9823 9824 if (state == srcDx) 9825 { 9826 /* Without the LR insn, we need to split this into a 9827 sequence of insns which will use the DEXCLx and DADDHxy 9828 insns to be able to read the Dx register in question. */ 9829 if (TARGET_DPFP_DISABLE_LRSR) 9830 { 9831 /* gen *movdf_insn_nolrsr */ 9832 rtx set = gen_rtx_SET (dest, src); 9833 rtx use1 = gen_rtx_USE (VOIDmode, const1_rtx); 9834 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, use1))); 9835 } 9836 else 9837 { 9838 /* When we have 'mov D, r' or 'mov D, D' then get the target 9839 register pair for use with LR insn. */ 9840 rtx destHigh = simplify_gen_subreg (SImode, dest, DFmode, 9841 TARGET_BIG_ENDIAN ? 0 : 4); 9842 rtx destLow = simplify_gen_subreg (SImode, dest, DFmode, 9843 TARGET_BIG_ENDIAN ? 4 : 0); 9844 9845 /* Produce the two LR insns to get the high and low parts. */ 9846 emit_insn (gen_rtx_SET (destHigh, 9847 gen_rtx_UNSPEC_VOLATILE (Pmode, 9848 gen_rtvec (1, src), 9849 VUNSPEC_ARC_LR_HIGH))); 9850 emit_insn (gen_rtx_SET (destLow, 9851 gen_rtx_UNSPEC_VOLATILE (Pmode, 9852 gen_rtvec (1, src), 9853 VUNSPEC_ARC_LR))); 9854 } 9855 } 9856 else if (state == destDx) 9857 { 9858 /* When we have 'mov r, D' or 'mov D, D' and we have access to the 9859 LR insn get the target register pair. */ 9860 rtx srcHigh = simplify_gen_subreg (SImode, src, DFmode, 9861 TARGET_BIG_ENDIAN ? 0 : 4); 9862 rtx srcLow = simplify_gen_subreg (SImode, src, DFmode, 9863 TARGET_BIG_ENDIAN ? 4 : 0); 9864 9865 emit_insn (gen_dexcl_2op (dest, srcHigh, srcLow)); 9866 } 9867 else 9868 gcc_unreachable (); 9869 9870 return true; 9871 } 9872 9873 /* operands 0..1 are the operands of a 64 bit move instruction. 9874 split it into two moves with operands 2/3 and 4/5. */ 9875 9876 void 9877 arc_split_move (rtx *operands) 9878 { 9879 machine_mode mode = GET_MODE (operands[0]); 9880 int i; 9881 int swap = 0; 9882 rtx xop[4]; 9883 9884 if (TARGET_DPFP) 9885 { 9886 if (arc_process_double_reg_moves (operands)) 9887 return; 9888 } 9889 9890 if (TARGET_LL64 9891 && ((memory_operand (operands[0], mode) 9892 && (even_register_operand (operands[1], mode) 9893 || satisfies_constraint_Cm3 (operands[1]))) 9894 || (memory_operand (operands[1], mode) 9895 && even_register_operand (operands[0], mode)))) 9896 { 9897 emit_move_insn (operands[0], operands[1]); 9898 return; 9899 } 9900 9901 if (TARGET_PLUS_QMACW 9902 && GET_CODE (operands[1]) == CONST_VECTOR) 9903 { 9904 HOST_WIDE_INT intval0, intval1; 9905 if (GET_MODE (operands[1]) == V2SImode) 9906 { 9907 intval0 = INTVAL (XVECEXP (operands[1], 0, 0)); 9908 intval1 = INTVAL (XVECEXP (operands[1], 0, 1)); 9909 } 9910 else 9911 { 9912 intval1 = INTVAL (XVECEXP (operands[1], 0, 3)) << 16; 9913 intval1 |= INTVAL (XVECEXP (operands[1], 0, 2)) & 0xFFFF; 9914 intval0 = INTVAL (XVECEXP (operands[1], 0, 1)) << 16; 9915 intval0 |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF; 9916 } 9917 xop[0] = gen_rtx_REG (SImode, REGNO (operands[0])); 9918 xop[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); 9919 xop[2] = GEN_INT (trunc_int_for_mode (intval0, SImode)); 9920 xop[1] = GEN_INT (trunc_int_for_mode (intval1, SImode)); 9921 emit_move_insn (xop[0], xop[2]); 9922 emit_move_insn (xop[3], xop[1]); 9923 return; 9924 } 9925 9926 for (i = 0; i < 2; i++) 9927 { 9928 if (MEM_P (operands[i]) && auto_inc_p (XEXP (operands[i], 0))) 9929 { 9930 rtx addr = XEXP (operands[i], 0); 9931 rtx r, o; 9932 enum rtx_code code; 9933 9934 gcc_assert (!reg_overlap_mentioned_p (operands[0], addr)); 9935 switch (GET_CODE (addr)) 9936 { 9937 case PRE_DEC: o = GEN_INT (-8); goto pre_modify; 9938 case PRE_INC: o = GEN_INT (8); goto pre_modify; 9939 case PRE_MODIFY: o = XEXP (XEXP (addr, 1), 1); 9940 pre_modify: 9941 code = PRE_MODIFY; 9942 break; 9943 case POST_DEC: o = GEN_INT (-8); goto post_modify; 9944 case POST_INC: o = GEN_INT (8); goto post_modify; 9945 case POST_MODIFY: o = XEXP (XEXP (addr, 1), 1); 9946 post_modify: 9947 code = POST_MODIFY; 9948 swap = 2; 9949 break; 9950 default: 9951 gcc_unreachable (); 9952 } 9953 r = XEXP (addr, 0); 9954 xop[0+i] = adjust_automodify_address_nv 9955 (operands[i], SImode, 9956 gen_rtx_fmt_ee (code, Pmode, r, 9957 gen_rtx_PLUS (Pmode, r, o)), 9958 0); 9959 xop[2+i] = adjust_automodify_address_nv 9960 (operands[i], SImode, plus_constant (Pmode, r, 4), 4); 9961 } 9962 else 9963 { 9964 xop[0+i] = operand_subword (operands[i], 0, 0, mode); 9965 xop[2+i] = operand_subword (operands[i], 1, 0, mode); 9966 } 9967 } 9968 if (reg_overlap_mentioned_p (xop[0], xop[3])) 9969 { 9970 swap = 2; 9971 gcc_assert (!reg_overlap_mentioned_p (xop[2], xop[1])); 9972 } 9973 9974 emit_move_insn (xop[0 + swap], xop[1 + swap]); 9975 emit_move_insn (xop[2 - swap], xop[3 - swap]); 9976 9977 } 9978 9979 /* Select between the instruction output templates s_tmpl (for short INSNs) 9980 and l_tmpl (for long INSNs). */ 9981 9982 const char * 9983 arc_short_long (rtx_insn *insn, const char *s_tmpl, const char *l_tmpl) 9984 { 9985 int is_short = arc_verify_short (insn, cfun->machine->unalign, -1); 9986 9987 extract_constrain_insn_cached (insn); 9988 return is_short ? s_tmpl : l_tmpl; 9989 } 9990 9991 /* Searches X for any reference to REGNO, returning the rtx of the 9992 reference found if any. Otherwise, returns NULL_RTX. */ 9993 9994 rtx 9995 arc_regno_use_in (unsigned int regno, rtx x) 9996 { 9997 const char *fmt; 9998 int i, j; 9999 rtx tem; 10000 10001 if (REG_P (x) && refers_to_regno_p (regno, x)) 10002 return x; 10003 10004 fmt = GET_RTX_FORMAT (GET_CODE (x)); 10005 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--) 10006 { 10007 if (fmt[i] == 'e') 10008 { 10009 if ((tem = regno_use_in (regno, XEXP (x, i)))) 10010 return tem; 10011 } 10012 else if (fmt[i] == 'E') 10013 for (j = XVECLEN (x, i) - 1; j >= 0; j--) 10014 if ((tem = regno_use_in (regno , XVECEXP (x, i, j)))) 10015 return tem; 10016 } 10017 10018 return NULL_RTX; 10019 } 10020 10021 /* Return the integer value of the "type" attribute for INSN, or -1 if 10022 INSN can't have attributes. */ 10023 10024 static int 10025 arc_attr_type (rtx_insn *insn) 10026 { 10027 if (NONJUMP_INSN_P (insn) 10028 ? (GET_CODE (PATTERN (insn)) == USE 10029 || GET_CODE (PATTERN (insn)) == CLOBBER) 10030 : JUMP_P (insn) 10031 ? (GET_CODE (PATTERN (insn)) == ADDR_VEC 10032 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC) 10033 : !CALL_P (insn)) 10034 return -1; 10035 return get_attr_type (insn); 10036 } 10037 10038 /* Return true if insn sets the condition codes. */ 10039 10040 bool 10041 arc_sets_cc_p (rtx_insn *insn) 10042 { 10043 if (NONJUMP_INSN_P (insn)) 10044 if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (insn))) 10045 insn = seq->insn (seq->len () - 1); 10046 return arc_attr_type (insn) == TYPE_COMPARE; 10047 } 10048 10049 /* Return true if INSN is an instruction with a delay slot we may want 10050 to fill. */ 10051 10052 bool 10053 arc_need_delay (rtx_insn *insn) 10054 { 10055 rtx_insn *next; 10056 10057 if (!flag_delayed_branch) 10058 return false; 10059 /* The return at the end of a function needs a delay slot. */ 10060 if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == USE 10061 && (!(next = next_active_insn (insn)) 10062 || ((!NONJUMP_INSN_P (next) || GET_CODE (PATTERN (next)) != SEQUENCE) 10063 && arc_attr_type (next) == TYPE_RETURN)) 10064 && (!TARGET_PAD_RETURN 10065 || (prev_active_insn (insn) 10066 && prev_active_insn (prev_active_insn (insn)) 10067 && prev_active_insn (prev_active_insn (prev_active_insn (insn)))))) 10068 return true; 10069 if (NONJUMP_INSN_P (insn) 10070 ? (GET_CODE (PATTERN (insn)) == USE 10071 || GET_CODE (PATTERN (insn)) == CLOBBER 10072 || GET_CODE (PATTERN (insn)) == SEQUENCE) 10073 : JUMP_P (insn) 10074 ? (GET_CODE (PATTERN (insn)) == ADDR_VEC 10075 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC) 10076 : !CALL_P (insn)) 10077 return false; 10078 return num_delay_slots (insn) != 0; 10079 } 10080 10081 /* Return true if the scheduling pass(es) has/have already run, 10082 i.e. where possible, we should try to mitigate high latencies 10083 by different instruction selection. */ 10084 10085 bool 10086 arc_scheduling_not_expected (void) 10087 { 10088 return cfun->machine->arc_reorg_started; 10089 } 10090 10091 /* Code has a minimum p2 alignment of 1, which we must restore after 10092 an ADDR_DIFF_VEC. */ 10093 10094 int 10095 arc_label_align (rtx_insn *label) 10096 { 10097 if (align_labels.levels[0].log < 1) 10098 { 10099 rtx_insn *next = next_nonnote_nondebug_insn (label); 10100 if (INSN_P (next) && recog_memoized (next) >= 0) 10101 return 1; 10102 } 10103 return align_labels.levels[0].log; 10104 } 10105 10106 /* Return true if LABEL is in executable code. */ 10107 10108 bool 10109 arc_text_label (rtx_insn *label) 10110 { 10111 rtx_insn *next; 10112 10113 /* ??? We use deleted labels like they were still there, see 10114 gcc.c-torture/compile/20000326-2.c . */ 10115 gcc_assert (GET_CODE (label) == CODE_LABEL 10116 || (GET_CODE (label) == NOTE 10117 && NOTE_KIND (label) == NOTE_INSN_DELETED_LABEL)); 10118 next = next_nonnote_insn (label); 10119 if (next) 10120 return (!JUMP_TABLE_DATA_P (next) 10121 || GET_CODE (PATTERN (next)) != ADDR_VEC); 10122 else if (!PREV_INSN (label)) 10123 /* ??? sometimes text labels get inserted very late, see 10124 gcc.dg/torture/stackalign/comp-goto-1.c */ 10125 return true; 10126 return false; 10127 } 10128 10129 /* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble 10130 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use 10131 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump 10132 to redirect two breqs. */ 10133 10134 static bool 10135 arc_can_follow_jump (const rtx_insn *follower, const rtx_insn *followee) 10136 { 10137 /* ??? get_attr_type is declared to take an rtx. */ 10138 union { const rtx_insn *c; rtx_insn *r; } u; 10139 10140 u.c = follower; 10141 if (CROSSING_JUMP_P (followee)) 10142 switch (get_attr_type (u.r)) 10143 { 10144 case TYPE_BRANCH: 10145 if (get_attr_length (u.r) != 2) 10146 break; 10147 /* Fall through. */ 10148 case TYPE_BRCC: 10149 case TYPE_BRCC_NO_DELAY_SLOT: 10150 return false; 10151 default: 10152 return true; 10153 } 10154 return true; 10155 } 10156 10157 /* Return the register number of the register holding the return address 10158 for a function of type TYPE. */ 10159 10160 int 10161 arc_return_address_register (unsigned int fn_type) 10162 { 10163 int regno = 0; 10164 10165 if (ARC_INTERRUPT_P (fn_type)) 10166 { 10167 if ((fn_type & (ARC_FUNCTION_ILINK1 | ARC_FUNCTION_FIRQ)) != 0) 10168 regno = ILINK1_REG; 10169 else if ((fn_type & ARC_FUNCTION_ILINK2) != 0) 10170 regno = ILINK2_REG; 10171 else 10172 gcc_unreachable (); 10173 } 10174 else if (ARC_NORMAL_P (fn_type) || ARC_NAKED_P (fn_type)) 10175 regno = RETURN_ADDR_REGNUM; 10176 10177 gcc_assert (regno != 0); 10178 return regno; 10179 } 10180 10181 /* Implement EPILOGUE_USES. 10182 Return true if REGNO should be added to the deemed uses of the epilogue. 10183 10184 We have to make sure all the register restore instructions are 10185 known to be live in interrupt functions, plus the blink register if 10186 it is clobbered by the isr. */ 10187 10188 bool 10189 arc_epilogue_uses (int regno) 10190 { 10191 unsigned int fn_type; 10192 10193 if (regno == arc_tp_regno) 10194 return true; 10195 10196 fn_type = arc_compute_function_type (cfun); 10197 if (reload_completed) 10198 { 10199 if (ARC_INTERRUPT_P (cfun->machine->fn_type)) 10200 { 10201 if (!fixed_regs[regno]) 10202 return true; 10203 return ((regno == arc_return_address_register (fn_type)) 10204 || (regno == RETURN_ADDR_REGNUM)); 10205 } 10206 else 10207 return regno == RETURN_ADDR_REGNUM; 10208 } 10209 else 10210 return regno == arc_return_address_register (fn_type); 10211 } 10212 10213 /* Helper for EH_USES macro. */ 10214 10215 bool 10216 arc_eh_uses (int regno) 10217 { 10218 if (regno == arc_tp_regno) 10219 return true; 10220 return false; 10221 } 10222 10223 /* Return true if we use LRA instead of reload pass. */ 10224 10225 bool 10226 arc_lra_p (void) 10227 { 10228 return arc_lra_flag; 10229 } 10230 10231 /* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to use 10232 Rcq registers, because some insn are shorter with them. OTOH we already 10233 have separate alternatives for this purpose, and other insns don't 10234 mind, so maybe we should rather prefer the other registers? 10235 We need more data, and we can only get that if we allow people to 10236 try all options. */ 10237 static int 10238 arc_register_priority (int r) 10239 { 10240 switch (arc_lra_priority_tag) 10241 { 10242 case ARC_LRA_PRIORITY_NONE: 10243 return 0; 10244 case ARC_LRA_PRIORITY_NONCOMPACT: 10245 return ((((r & 7) ^ 4) - 4) & 15) != r; 10246 case ARC_LRA_PRIORITY_COMPACT: 10247 return ((((r & 7) ^ 4) - 4) & 15) == r; 10248 default: 10249 gcc_unreachable (); 10250 } 10251 } 10252 10253 static reg_class_t 10254 arc_spill_class (reg_class_t /* orig_class */, machine_mode) 10255 { 10256 return GENERAL_REGS; 10257 } 10258 10259 bool 10260 arc_legitimize_reload_address (rtx *p, machine_mode mode, int opnum, 10261 int itype) 10262 { 10263 rtx x = *p; 10264 enum reload_type type = (enum reload_type) itype; 10265 10266 if (GET_CODE (x) == PLUS 10267 && CONST_INT_P (XEXP (x, 1)) 10268 && (RTX_OK_FOR_BASE_P (XEXP (x, 0), true) 10269 || (REG_P (XEXP (x, 0)) 10270 && reg_equiv_constant (REGNO (XEXP (x, 0)))))) 10271 { 10272 int scale = GET_MODE_SIZE (mode); 10273 int shift; 10274 rtx index_rtx = XEXP (x, 1); 10275 HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base; 10276 rtx reg, sum, sum2; 10277 10278 if (scale > 4) 10279 scale = 4; 10280 if ((scale-1) & offset) 10281 scale = 1; 10282 shift = scale >> 1; 10283 offset_base 10284 = ((offset + (256 << shift)) 10285 & ((HOST_WIDE_INT)((unsigned HOST_WIDE_INT) -512 << shift))); 10286 /* Sometimes the normal form does not suit DImode. We 10287 could avoid that by using smaller ranges, but that 10288 would give less optimized code when SImode is 10289 prevalent. */ 10290 if (GET_MODE_SIZE (mode) + offset - offset_base <= (256 << shift)) 10291 { 10292 int regno; 10293 10294 reg = XEXP (x, 0); 10295 regno = REGNO (reg); 10296 sum2 = sum = plus_constant (Pmode, reg, offset_base); 10297 10298 if (reg_equiv_constant (regno)) 10299 { 10300 sum2 = plus_constant (Pmode, reg_equiv_constant (regno), 10301 offset_base); 10302 if (GET_CODE (sum2) == PLUS) 10303 sum2 = gen_rtx_CONST (Pmode, sum2); 10304 } 10305 *p = gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - offset_base)); 10306 push_reload (sum2, NULL_RTX, &XEXP (*p, 0), NULL, 10307 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, 10308 type); 10309 return true; 10310 } 10311 } 10312 /* We must re-recognize what we created before. */ 10313 else if (GET_CODE (x) == PLUS 10314 && GET_CODE (XEXP (x, 0)) == PLUS 10315 && CONST_INT_P (XEXP (XEXP (x, 0), 1)) 10316 && REG_P (XEXP (XEXP (x, 0), 0)) 10317 && CONST_INT_P (XEXP (x, 1))) 10318 { 10319 /* Because this address is so complex, we know it must have 10320 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus, 10321 it is already unshared, and needs no further unsharing. */ 10322 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, 10323 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type); 10324 return true; 10325 } 10326 return false; 10327 } 10328 10329 /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */ 10330 10331 static bool 10332 arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size, 10333 unsigned int align, 10334 enum by_pieces_operation op, 10335 bool speed_p) 10336 { 10337 /* Let the movmem expander handle small block moves. */ 10338 if (op == MOVE_BY_PIECES) 10339 return false; 10340 10341 return default_use_by_pieces_infrastructure_p (size, align, op, speed_p); 10342 } 10343 10344 /* Emit a (pre) memory barrier around an atomic sequence according to 10345 MODEL. */ 10346 10347 static void 10348 arc_pre_atomic_barrier (enum memmodel model) 10349 { 10350 if (need_atomic_barrier_p (model, true)) 10351 emit_insn (gen_memory_barrier ()); 10352 } 10353 10354 /* Emit a (post) memory barrier around an atomic sequence according to 10355 MODEL. */ 10356 10357 static void 10358 arc_post_atomic_barrier (enum memmodel model) 10359 { 10360 if (need_atomic_barrier_p (model, false)) 10361 emit_insn (gen_memory_barrier ()); 10362 } 10363 10364 /* Expand a compare and swap pattern. */ 10365 10366 static void 10367 emit_unlikely_jump (rtx insn) 10368 { 10369 rtx_insn *jump = emit_jump_insn (insn); 10370 add_reg_br_prob_note (jump, profile_probability::very_unlikely ()); 10371 } 10372 10373 /* Expand code to perform a 8 or 16-bit compare and swap by doing 10374 32-bit compare and swap on the word containing the byte or 10375 half-word. The difference between a weak and a strong CAS is that 10376 the weak version may simply fail. The strong version relies on two 10377 loops, one checks if the SCOND op is succsfully or not, the other 10378 checks if the 32 bit accessed location which contains the 8 or 16 10379 bit datum is not changed by other thread. The first loop is 10380 implemented by the atomic_compare_and_swapsi_1 pattern. The second 10381 loops is implemented by this routine. */ 10382 10383 static void 10384 arc_expand_compare_and_swap_qh (rtx bool_result, rtx result, rtx mem, 10385 rtx oldval, rtx newval, rtx weak, 10386 rtx mod_s, rtx mod_f) 10387 { 10388 rtx addr1 = force_reg (Pmode, XEXP (mem, 0)); 10389 rtx addr = gen_reg_rtx (Pmode); 10390 rtx off = gen_reg_rtx (SImode); 10391 rtx oldv = gen_reg_rtx (SImode); 10392 rtx newv = gen_reg_rtx (SImode); 10393 rtx oldvalue = gen_reg_rtx (SImode); 10394 rtx newvalue = gen_reg_rtx (SImode); 10395 rtx res = gen_reg_rtx (SImode); 10396 rtx resv = gen_reg_rtx (SImode); 10397 rtx memsi, val, mask, end_label, loop_label, cc, x; 10398 machine_mode mode; 10399 bool is_weak = (weak != const0_rtx); 10400 10401 /* Truncate the address. */ 10402 emit_insn (gen_rtx_SET (addr, 10403 gen_rtx_AND (Pmode, addr1, GEN_INT (-4)))); 10404 10405 /* Compute the datum offset. */ 10406 emit_insn (gen_rtx_SET (off, 10407 gen_rtx_AND (SImode, addr1, GEN_INT (3)))); 10408 if (TARGET_BIG_ENDIAN) 10409 emit_insn (gen_rtx_SET (off, 10410 gen_rtx_MINUS (SImode, 10411 (GET_MODE (mem) == QImode) ? 10412 GEN_INT (3) : GEN_INT (2), off))); 10413 10414 /* Normal read from truncated address. */ 10415 memsi = gen_rtx_MEM (SImode, addr); 10416 set_mem_alias_set (memsi, ALIAS_SET_MEMORY_BARRIER); 10417 MEM_VOLATILE_P (memsi) = MEM_VOLATILE_P (mem); 10418 10419 val = copy_to_reg (memsi); 10420 10421 /* Convert the offset in bits. */ 10422 emit_insn (gen_rtx_SET (off, 10423 gen_rtx_ASHIFT (SImode, off, GEN_INT (3)))); 10424 10425 /* Get the proper mask. */ 10426 if (GET_MODE (mem) == QImode) 10427 mask = force_reg (SImode, GEN_INT (0xff)); 10428 else 10429 mask = force_reg (SImode, GEN_INT (0xffff)); 10430 10431 emit_insn (gen_rtx_SET (mask, 10432 gen_rtx_ASHIFT (SImode, mask, off))); 10433 10434 /* Prepare the old and new values. */ 10435 emit_insn (gen_rtx_SET (val, 10436 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask), 10437 val))); 10438 10439 oldval = gen_lowpart (SImode, oldval); 10440 emit_insn (gen_rtx_SET (oldv, 10441 gen_rtx_ASHIFT (SImode, oldval, off))); 10442 10443 newval = gen_lowpart_common (SImode, newval); 10444 emit_insn (gen_rtx_SET (newv, 10445 gen_rtx_ASHIFT (SImode, newval, off))); 10446 10447 emit_insn (gen_rtx_SET (oldv, 10448 gen_rtx_AND (SImode, oldv, mask))); 10449 10450 emit_insn (gen_rtx_SET (newv, 10451 gen_rtx_AND (SImode, newv, mask))); 10452 10453 if (!is_weak) 10454 { 10455 end_label = gen_label_rtx (); 10456 loop_label = gen_label_rtx (); 10457 emit_label (loop_label); 10458 } 10459 10460 /* Make the old and new values. */ 10461 emit_insn (gen_rtx_SET (oldvalue, 10462 gen_rtx_IOR (SImode, oldv, val))); 10463 10464 emit_insn (gen_rtx_SET (newvalue, 10465 gen_rtx_IOR (SImode, newv, val))); 10466 10467 /* Try an 32bit atomic compare and swap. It clobbers the CC 10468 register. */ 10469 emit_insn (gen_atomic_compare_and_swapsi_1 (res, memsi, oldvalue, newvalue, 10470 weak, mod_s, mod_f)); 10471 10472 /* Regardless of the weakness of the operation, a proper boolean 10473 result needs to be provided. */ 10474 x = gen_rtx_REG (CC_Zmode, CC_REG); 10475 x = gen_rtx_EQ (SImode, x, const0_rtx); 10476 emit_insn (gen_rtx_SET (bool_result, x)); 10477 10478 if (!is_weak) 10479 { 10480 /* Check the results: if the atomic op is successfully the goto 10481 to end label. */ 10482 x = gen_rtx_REG (CC_Zmode, CC_REG); 10483 x = gen_rtx_EQ (VOIDmode, x, const0_rtx); 10484 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, 10485 gen_rtx_LABEL_REF (Pmode, end_label), pc_rtx); 10486 emit_jump_insn (gen_rtx_SET (pc_rtx, x)); 10487 10488 /* Wait for the right moment when the accessed 32-bit location 10489 is stable. */ 10490 emit_insn (gen_rtx_SET (resv, 10491 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask), 10492 res))); 10493 mode = SELECT_CC_MODE (NE, resv, val); 10494 cc = gen_rtx_REG (mode, CC_REG); 10495 emit_insn (gen_rtx_SET (cc, gen_rtx_COMPARE (mode, resv, val))); 10496 10497 /* Set the new value of the 32 bit location, proper masked. */ 10498 emit_insn (gen_rtx_SET (val, resv)); 10499 10500 /* Try again if location is unstable. Fall through if only 10501 scond op failed. */ 10502 x = gen_rtx_NE (VOIDmode, cc, const0_rtx); 10503 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, 10504 gen_rtx_LABEL_REF (Pmode, loop_label), pc_rtx); 10505 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x)); 10506 10507 emit_label (end_label); 10508 } 10509 10510 /* End: proper return the result for the given mode. */ 10511 emit_insn (gen_rtx_SET (res, 10512 gen_rtx_AND (SImode, res, mask))); 10513 10514 emit_insn (gen_rtx_SET (res, 10515 gen_rtx_LSHIFTRT (SImode, res, off))); 10516 10517 emit_move_insn (result, gen_lowpart (GET_MODE (result), res)); 10518 } 10519 10520 /* Helper function used by "atomic_compare_and_swap" expand 10521 pattern. */ 10522 10523 void 10524 arc_expand_compare_and_swap (rtx operands[]) 10525 { 10526 rtx bval, rval, mem, oldval, newval, is_weak, mod_s, mod_f, x; 10527 machine_mode mode; 10528 10529 bval = operands[0]; 10530 rval = operands[1]; 10531 mem = operands[2]; 10532 oldval = operands[3]; 10533 newval = operands[4]; 10534 is_weak = operands[5]; 10535 mod_s = operands[6]; 10536 mod_f = operands[7]; 10537 mode = GET_MODE (mem); 10538 10539 if (reg_overlap_mentioned_p (rval, oldval)) 10540 oldval = copy_to_reg (oldval); 10541 10542 if (mode == SImode) 10543 { 10544 emit_insn (gen_atomic_compare_and_swapsi_1 (rval, mem, oldval, newval, 10545 is_weak, mod_s, mod_f)); 10546 x = gen_rtx_REG (CC_Zmode, CC_REG); 10547 x = gen_rtx_EQ (SImode, x, const0_rtx); 10548 emit_insn (gen_rtx_SET (bval, x)); 10549 } 10550 else 10551 { 10552 arc_expand_compare_and_swap_qh (bval, rval, mem, oldval, newval, 10553 is_weak, mod_s, mod_f); 10554 } 10555 } 10556 10557 /* Helper function used by the "atomic_compare_and_swapsi_1" 10558 pattern. */ 10559 10560 void 10561 arc_split_compare_and_swap (rtx operands[]) 10562 { 10563 rtx rval, mem, oldval, newval; 10564 machine_mode mode; 10565 enum memmodel mod_s, mod_f; 10566 bool is_weak; 10567 rtx label1, label2, x, cond; 10568 10569 rval = operands[0]; 10570 mem = operands[1]; 10571 oldval = operands[2]; 10572 newval = operands[3]; 10573 is_weak = (operands[4] != const0_rtx); 10574 mod_s = (enum memmodel) INTVAL (operands[5]); 10575 mod_f = (enum memmodel) INTVAL (operands[6]); 10576 mode = GET_MODE (mem); 10577 10578 /* ARC atomic ops work only with 32-bit aligned memories. */ 10579 gcc_assert (mode == SImode); 10580 10581 arc_pre_atomic_barrier (mod_s); 10582 10583 label1 = NULL_RTX; 10584 if (!is_weak) 10585 { 10586 label1 = gen_label_rtx (); 10587 emit_label (label1); 10588 } 10589 label2 = gen_label_rtx (); 10590 10591 /* Load exclusive. */ 10592 emit_insn (gen_arc_load_exclusivesi (rval, mem)); 10593 10594 /* Check if it is oldval. */ 10595 mode = SELECT_CC_MODE (NE, rval, oldval); 10596 cond = gen_rtx_REG (mode, CC_REG); 10597 emit_insn (gen_rtx_SET (cond, gen_rtx_COMPARE (mode, rval, oldval))); 10598 10599 x = gen_rtx_NE (VOIDmode, cond, const0_rtx); 10600 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, 10601 gen_rtx_LABEL_REF (Pmode, label2), pc_rtx); 10602 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x)); 10603 10604 /* Exclusively store new item. Store clobbers CC reg. */ 10605 emit_insn (gen_arc_store_exclusivesi (mem, newval)); 10606 10607 if (!is_weak) 10608 { 10609 /* Check the result of the store. */ 10610 cond = gen_rtx_REG (CC_Zmode, CC_REG); 10611 x = gen_rtx_NE (VOIDmode, cond, const0_rtx); 10612 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, 10613 gen_rtx_LABEL_REF (Pmode, label1), pc_rtx); 10614 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x)); 10615 } 10616 10617 if (mod_f != MEMMODEL_RELAXED) 10618 emit_label (label2); 10619 10620 arc_post_atomic_barrier (mod_s); 10621 10622 if (mod_f == MEMMODEL_RELAXED) 10623 emit_label (label2); 10624 } 10625 10626 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation 10627 to perform. MEM is the memory on which to operate. VAL is the second 10628 operand of the binary operator. BEFORE and AFTER are optional locations to 10629 return the value of MEM either before of after the operation. MODEL_RTX 10630 is a CONST_INT containing the memory model to use. */ 10631 10632 void 10633 arc_expand_atomic_op (enum rtx_code code, rtx mem, rtx val, 10634 rtx orig_before, rtx orig_after, rtx model_rtx) 10635 { 10636 enum memmodel model = (enum memmodel) INTVAL (model_rtx); 10637 machine_mode mode = GET_MODE (mem); 10638 rtx label, x, cond; 10639 rtx before = orig_before, after = orig_after; 10640 10641 /* ARC atomic ops work only with 32-bit aligned memories. */ 10642 gcc_assert (mode == SImode); 10643 10644 arc_pre_atomic_barrier (model); 10645 10646 label = gen_label_rtx (); 10647 emit_label (label); 10648 label = gen_rtx_LABEL_REF (VOIDmode, label); 10649 10650 if (before == NULL_RTX) 10651 before = gen_reg_rtx (mode); 10652 10653 if (after == NULL_RTX) 10654 after = gen_reg_rtx (mode); 10655 10656 /* Load exclusive. */ 10657 emit_insn (gen_arc_load_exclusivesi (before, mem)); 10658 10659 switch (code) 10660 { 10661 case NOT: 10662 x = gen_rtx_AND (mode, before, val); 10663 emit_insn (gen_rtx_SET (after, x)); 10664 x = gen_rtx_NOT (mode, after); 10665 emit_insn (gen_rtx_SET (after, x)); 10666 break; 10667 10668 case MINUS: 10669 if (CONST_INT_P (val)) 10670 { 10671 val = GEN_INT (-INTVAL (val)); 10672 code = PLUS; 10673 } 10674 10675 /* FALLTHRU. */ 10676 default: 10677 x = gen_rtx_fmt_ee (code, mode, before, val); 10678 emit_insn (gen_rtx_SET (after, x)); 10679 break; 10680 } 10681 10682 /* Exclusively store new item. Store clobbers CC reg. */ 10683 emit_insn (gen_arc_store_exclusivesi (mem, after)); 10684 10685 /* Check the result of the store. */ 10686 cond = gen_rtx_REG (CC_Zmode, CC_REG); 10687 x = gen_rtx_NE (VOIDmode, cond, const0_rtx); 10688 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, 10689 label, pc_rtx); 10690 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x)); 10691 10692 arc_post_atomic_barrier (model); 10693 } 10694 10695 /* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */ 10696 10697 static bool 10698 arc_no_speculation_in_delay_slots_p () 10699 { 10700 return true; 10701 } 10702 10703 /* Return a parallel of registers to represent where to find the 10704 register pieces if required, otherwise NULL_RTX. */ 10705 10706 static rtx 10707 arc_dwarf_register_span (rtx rtl) 10708 { 10709 machine_mode mode = GET_MODE (rtl); 10710 unsigned regno; 10711 rtx p; 10712 10713 if (GET_MODE_SIZE (mode) != 8) 10714 return NULL_RTX; 10715 10716 p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2)); 10717 regno = REGNO (rtl); 10718 XVECEXP (p, 0, 0) = gen_rtx_REG (SImode, regno); 10719 XVECEXP (p, 0, 1) = gen_rtx_REG (SImode, regno + 1); 10720 10721 return p; 10722 } 10723 10724 /* Return true if OP is an acceptable memory operand for ARCompact 10725 16-bit load instructions of MODE. 10726 10727 AV2SHORT: TRUE if address needs to fit into the new ARCv2 short 10728 non scaled instructions. 10729 10730 SCALED: TRUE if address can be scaled. */ 10731 10732 bool 10733 compact_memory_operand_p (rtx op, machine_mode mode, 10734 bool av2short, bool scaled) 10735 { 10736 rtx addr, plus0, plus1; 10737 int size, off; 10738 10739 /* Eliminate non-memory operations. */ 10740 if (GET_CODE (op) != MEM) 10741 return 0; 10742 10743 /* .di instructions have no 16-bit form. */ 10744 if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET) 10745 return false; 10746 10747 /* likewise for uncached types. */ 10748 if (arc_is_uncached_mem_p (op)) 10749 return false; 10750 10751 if (mode == VOIDmode) 10752 mode = GET_MODE (op); 10753 10754 size = GET_MODE_SIZE (mode); 10755 10756 /* dword operations really put out 2 instructions, so eliminate 10757 them. */ 10758 if (size > UNITS_PER_WORD) 10759 return false; 10760 10761 /* Decode the address now. */ 10762 addr = XEXP (op, 0); 10763 switch (GET_CODE (addr)) 10764 { 10765 case REG: 10766 return (REGNO (addr) >= FIRST_PSEUDO_REGISTER 10767 || COMPACT_GP_REG_P (REGNO (addr)) 10768 || (SP_REG_P (REGNO (addr)) && (size != 2))); 10769 case PLUS: 10770 plus0 = XEXP (addr, 0); 10771 plus1 = XEXP (addr, 1); 10772 10773 if ((GET_CODE (plus0) == REG) 10774 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER) 10775 || COMPACT_GP_REG_P (REGNO (plus0))) 10776 && ((GET_CODE (plus1) == REG) 10777 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER) 10778 || COMPACT_GP_REG_P (REGNO (plus1))))) 10779 { 10780 return !av2short; 10781 } 10782 10783 if ((GET_CODE (plus0) == REG) 10784 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER) 10785 || (COMPACT_GP_REG_P (REGNO (plus0)) && !av2short) 10786 || (IN_RANGE (REGNO (plus0), 0, 31) && av2short)) 10787 && (GET_CODE (plus1) == CONST_INT)) 10788 { 10789 bool valid = false; 10790 10791 off = INTVAL (plus1); 10792 10793 /* Negative offset is not supported in 16-bit load/store insns. */ 10794 if (off < 0) 10795 return 0; 10796 10797 /* Only u5 immediates allowed in code density instructions. */ 10798 if (av2short) 10799 { 10800 switch (size) 10801 { 10802 case 1: 10803 return false; 10804 case 2: 10805 /* This is an ldh_s.x instruction, check the u6 10806 immediate. */ 10807 if (COMPACT_GP_REG_P (REGNO (plus0))) 10808 valid = true; 10809 break; 10810 case 4: 10811 /* Only u5 immediates allowed in 32bit access code 10812 density instructions. */ 10813 if (REGNO (plus0) <= 31) 10814 return ((off < 32) && (off % 4 == 0)); 10815 break; 10816 default: 10817 return false; 10818 } 10819 } 10820 else 10821 if (COMPACT_GP_REG_P (REGNO (plus0))) 10822 valid = true; 10823 10824 if (valid) 10825 { 10826 10827 switch (size) 10828 { 10829 case 1: 10830 return (off < 32); 10831 case 2: 10832 /* The 6-bit constant get shifted to fit the real 10833 5-bits field. Check also for the alignment. */ 10834 return ((off < 64) && (off % 2 == 0)); 10835 case 4: 10836 return ((off < 128) && (off % 4 == 0)); 10837 default: 10838 return false; 10839 } 10840 } 10841 } 10842 10843 if (REG_P (plus0) && CONST_INT_P (plus1) 10844 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER) 10845 || SP_REG_P (REGNO (plus0))) 10846 && !av2short) 10847 { 10848 off = INTVAL (plus1); 10849 return ((size != 2) && (off >= 0 && off < 128) && (off % 4 == 0)); 10850 } 10851 10852 if ((GET_CODE (plus0) == MULT) 10853 && (GET_CODE (XEXP (plus0, 0)) == REG) 10854 && ((REGNO (XEXP (plus0, 0)) >= FIRST_PSEUDO_REGISTER) 10855 || COMPACT_GP_REG_P (REGNO (XEXP (plus0, 0)))) 10856 && (GET_CODE (plus1) == REG) 10857 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER) 10858 || COMPACT_GP_REG_P (REGNO (plus1)))) 10859 return scaled; 10860 default: 10861 break ; 10862 /* TODO: 'gp' and 'pcl' are to supported as base address operand 10863 for 16-bit load instructions. */ 10864 } 10865 return false; 10866 } 10867 10868 /* Return the frame pointer value to be backed up in the setjmp buffer. */ 10869 10870 static rtx 10871 arc_builtin_setjmp_frame_value (void) 10872 { 10873 /* We always want to preserve whatever value is currently in the frame 10874 pointer register. For frames that are using the frame pointer the new 10875 value of the frame pointer register will have already been computed 10876 (as part of the prologue). For frames that are not using the frame 10877 pointer it is important that we backup whatever value is in the frame 10878 pointer register, as earlier (more outer) frames may have placed a 10879 value into the frame pointer register. It might be tempting to try 10880 and use `frame_pointer_rtx` here, however, this is not what we want. 10881 For frames that are using the frame pointer this will give the 10882 correct value. However, for frames that are not using the frame 10883 pointer this will still give the value that _would_ have been the 10884 frame pointer value for this frame (if the use of the frame pointer 10885 had not been removed). We really do want the raw frame pointer 10886 register value. */ 10887 return gen_raw_REG (Pmode, HARD_FRAME_POINTER_REGNUM); 10888 } 10889 10890 /* Return nonzero if a jli call should be generated for a call from 10891 the current function to DECL. */ 10892 10893 bool 10894 arc_is_jli_call_p (rtx pat) 10895 { 10896 tree attrs; 10897 tree decl = SYMBOL_REF_DECL (pat); 10898 10899 /* If it is not a well defined public function then return false. */ 10900 if (!decl || !SYMBOL_REF_FUNCTION_P (pat) || !TREE_PUBLIC (decl)) 10901 return false; 10902 10903 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl)); 10904 if (lookup_attribute ("jli_always", attrs)) 10905 return true; 10906 10907 if (lookup_attribute ("jli_fixed", attrs)) 10908 return true; 10909 10910 return TARGET_JLI_ALWAYS; 10911 } 10912 10913 /* Handle and "jli" attribute; arguments as in struct 10914 attribute_spec.handler. */ 10915 10916 static tree 10917 arc_handle_jli_attribute (tree *node ATTRIBUTE_UNUSED, 10918 tree name, tree args, int, 10919 bool *no_add_attrs) 10920 { 10921 if (!TARGET_V2) 10922 { 10923 warning (OPT_Wattributes, 10924 "%qE attribute only valid for ARCv2 architecture", 10925 name); 10926 *no_add_attrs = true; 10927 } 10928 10929 if (args == NULL_TREE) 10930 { 10931 warning (OPT_Wattributes, 10932 "argument of %qE attribute is missing", 10933 name); 10934 *no_add_attrs = true; 10935 } 10936 else 10937 { 10938 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR) 10939 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0); 10940 tree arg = TREE_VALUE (args); 10941 if (TREE_CODE (arg) != INTEGER_CST) 10942 { 10943 warning (0, "%qE attribute allows only an integer constant argument", 10944 name); 10945 *no_add_attrs = true; 10946 } 10947 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */ 10948 } 10949 return NULL_TREE; 10950 } 10951 10952 /* Handle and "scure" attribute; arguments as in struct 10953 attribute_spec.handler. */ 10954 10955 static tree 10956 arc_handle_secure_attribute (tree *node ATTRIBUTE_UNUSED, 10957 tree name, tree args, int, 10958 bool *no_add_attrs) 10959 { 10960 if (!TARGET_EM) 10961 { 10962 warning (OPT_Wattributes, 10963 "%qE attribute only valid for ARC EM architecture", 10964 name); 10965 *no_add_attrs = true; 10966 } 10967 10968 if (args == NULL_TREE) 10969 { 10970 warning (OPT_Wattributes, 10971 "argument of %qE attribute is missing", 10972 name); 10973 *no_add_attrs = true; 10974 } 10975 else 10976 { 10977 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR) 10978 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0); 10979 tree arg = TREE_VALUE (args); 10980 if (TREE_CODE (arg) != INTEGER_CST) 10981 { 10982 warning (0, "%qE attribute allows only an integer constant argument", 10983 name); 10984 *no_add_attrs = true; 10985 } 10986 } 10987 return NULL_TREE; 10988 } 10989 10990 /* Return nonzero if the symbol is a secure function. */ 10991 10992 bool 10993 arc_is_secure_call_p (rtx pat) 10994 { 10995 tree attrs; 10996 tree decl = SYMBOL_REF_DECL (pat); 10997 10998 if (!decl) 10999 return false; 11000 11001 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl)); 11002 if (lookup_attribute ("secure_call", attrs)) 11003 return true; 11004 11005 return false; 11006 } 11007 11008 /* Handle "uncached" qualifier. */ 11009 11010 static tree 11011 arc_handle_uncached_attribute (tree *node, 11012 tree name, tree args, 11013 int flags ATTRIBUTE_UNUSED, 11014 bool *no_add_attrs) 11015 { 11016 if (DECL_P (*node) && TREE_CODE (*node) != TYPE_DECL) 11017 { 11018 error ("%qE attribute only applies to types", 11019 name); 11020 *no_add_attrs = true; 11021 } 11022 else if (args) 11023 { 11024 warning (OPT_Wattributes, "argument of %qE attribute ignored", name); 11025 } 11026 return NULL_TREE; 11027 } 11028 11029 /* Return TRUE if PAT is a memory addressing an uncached data. */ 11030 11031 bool 11032 arc_is_uncached_mem_p (rtx pat) 11033 { 11034 tree attrs = NULL_TREE; 11035 tree addr; 11036 11037 if (!MEM_P (pat)) 11038 return false; 11039 11040 /* Get the memory attributes. */ 11041 addr = MEM_EXPR (pat); 11042 if (!addr) 11043 return false; 11044 11045 /* Get the attributes. */ 11046 if (TREE_CODE (addr) == MEM_REF) 11047 { 11048 attrs = TYPE_ATTRIBUTES (TREE_TYPE (addr)); 11049 if (lookup_attribute ("uncached", attrs)) 11050 return true; 11051 11052 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 0))); 11053 if (lookup_attribute ("uncached", attrs)) 11054 return true; 11055 } 11056 11057 /* For COMPONENT_REF, use the FIELD_DECL from tree operand 1. */ 11058 if (TREE_CODE (addr) == COMPONENT_REF) 11059 { 11060 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 1))); 11061 if (lookup_attribute ("uncached", attrs)) 11062 return true; 11063 } 11064 return false; 11065 } 11066 11067 /* Handle aux attribute. The auxiliary registers are addressed using 11068 special instructions lr and sr. The attribute 'aux' indicates if a 11069 variable refers to the aux-regs and what is the register number 11070 desired. */ 11071 11072 static tree 11073 arc_handle_aux_attribute (tree *node, 11074 tree name, tree args, int, 11075 bool *no_add_attrs) 11076 { 11077 /* Isn't it better to use address spaces for the aux-regs? */ 11078 if (DECL_P (*node)) 11079 { 11080 if (TREE_CODE (*node) != VAR_DECL) 11081 { 11082 error ("%qE attribute only applies to variables", name); 11083 *no_add_attrs = true; 11084 } 11085 else if (args) 11086 { 11087 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR) 11088 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0); 11089 tree arg = TREE_VALUE (args); 11090 if (TREE_CODE (arg) != INTEGER_CST) 11091 { 11092 warning (OPT_Wattributes, "%qE attribute allows only an integer " 11093 "constant argument", name); 11094 *no_add_attrs = true; 11095 } 11096 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */ 11097 } 11098 11099 if (TREE_CODE (*node) == VAR_DECL) 11100 { 11101 tree fntype = TREE_TYPE (*node); 11102 if (fntype && TREE_CODE (fntype) == POINTER_TYPE) 11103 { 11104 tree attrs = tree_cons (get_identifier ("aux"), NULL_TREE, 11105 TYPE_ATTRIBUTES (fntype)); 11106 TYPE_ATTRIBUTES (fntype) = attrs; 11107 } 11108 } 11109 } 11110 return NULL_TREE; 11111 } 11112 11113 /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P. We don't want to use 11114 anchors for small data: the GP register acts as an anchor in that 11115 case. We also don't want to use them for PC-relative accesses, 11116 where the PC acts as an anchor. Prohibit also TLS symbols to use 11117 anchors. */ 11118 11119 static bool 11120 arc_use_anchors_for_symbol_p (const_rtx symbol) 11121 { 11122 if (SYMBOL_REF_TLS_MODEL (symbol)) 11123 return false; 11124 11125 if (flag_pic) 11126 return false; 11127 11128 if (SYMBOL_REF_SMALL_P (symbol)) 11129 return false; 11130 11131 return default_use_anchors_for_symbol_p (symbol); 11132 } 11133 11134 /* Return true if SUBST can't safely replace its equivalent during RA. */ 11135 static bool 11136 arc_cannot_substitute_mem_equiv_p (rtx) 11137 { 11138 /* If SUBST is mem[base+index], the address may not fit ISA, 11139 thus return true. */ 11140 return true; 11141 } 11142 11143 /* Checks whether the operands are valid for use in an LDD/STD 11144 instruction. Assumes that RT, and RT2 are REG. This is guaranteed 11145 by the patterns. Assumes that the address in the base register RN 11146 is word aligned. Pattern guarantees that both memory accesses use 11147 the same base register, the offsets are constants within the range, 11148 and the gap between the offsets is 4. If reload complete then 11149 check that registers are legal. */ 11150 11151 static bool 11152 operands_ok_ldd_std (rtx rt, rtx rt2, HOST_WIDE_INT offset) 11153 { 11154 unsigned int t, t2; 11155 11156 if (!reload_completed) 11157 return true; 11158 11159 if (!(SMALL_INT_RANGE (offset, (GET_MODE_SIZE (DImode) - 1) & (~0x03), 11160 (offset & (GET_MODE_SIZE (DImode) - 1) & 3 11161 ? 0 : -(-GET_MODE_SIZE (DImode) | (~0x03)) >> 1)))) 11162 return false; 11163 11164 t = REGNO (rt); 11165 t2 = REGNO (rt2); 11166 11167 if ((t2 == PCL_REG) 11168 || (t % 2 != 0) /* First destination register is not even. */ 11169 || (t2 != t + 1)) 11170 return false; 11171 11172 return true; 11173 } 11174 11175 /* Helper for gen_operands_ldd_std. Returns true iff the memory 11176 operand MEM's address contains an immediate offset from the base 11177 register and has no side effects, in which case it sets BASE and 11178 OFFSET accordingly. */ 11179 11180 static bool 11181 mem_ok_for_ldd_std (rtx mem, rtx *base, rtx *offset) 11182 { 11183 rtx addr; 11184 11185 gcc_assert (base != NULL && offset != NULL); 11186 11187 /* TODO: Handle more general memory operand patterns, such as 11188 PRE_DEC and PRE_INC. */ 11189 11190 if (side_effects_p (mem)) 11191 return false; 11192 11193 /* Can't deal with subregs. */ 11194 if (GET_CODE (mem) == SUBREG) 11195 return false; 11196 11197 gcc_assert (MEM_P (mem)); 11198 11199 *offset = const0_rtx; 11200 11201 addr = XEXP (mem, 0); 11202 11203 /* If addr isn't valid for DImode, then we can't handle it. */ 11204 if (!arc_legitimate_address_p (DImode, addr, 11205 reload_in_progress || reload_completed)) 11206 return false; 11207 11208 if (REG_P (addr)) 11209 { 11210 *base = addr; 11211 return true; 11212 } 11213 else if (GET_CODE (addr) == PLUS || GET_CODE (addr) == MINUS) 11214 { 11215 *base = XEXP (addr, 0); 11216 *offset = XEXP (addr, 1); 11217 return (REG_P (*base) && CONST_INT_P (*offset)); 11218 } 11219 11220 return false; 11221 } 11222 11223 /* Called from peephole2 to replace two word-size accesses with a 11224 single LDD/STD instruction. Returns true iff we can generate a new 11225 instruction sequence. That is, both accesses use the same base 11226 register and the gap between constant offsets is 4. OPERANDS are 11227 the operands found by the peephole matcher; OPERANDS[0,1] are 11228 register operands, and OPERANDS[2,3] are the corresponding memory 11229 operands. LOAD indicates whether the access is load or store. */ 11230 11231 bool 11232 gen_operands_ldd_std (rtx *operands, bool load, bool commute) 11233 { 11234 int i, gap; 11235 HOST_WIDE_INT offsets[2], offset; 11236 int nops = 2; 11237 rtx cur_base, cur_offset, tmp; 11238 rtx base = NULL_RTX; 11239 11240 /* Check that the memory references are immediate offsets from the 11241 same base register. Extract the base register, the destination 11242 registers, and the corresponding memory offsets. */ 11243 for (i = 0; i < nops; i++) 11244 { 11245 if (!mem_ok_for_ldd_std (operands[nops+i], &cur_base, &cur_offset)) 11246 return false; 11247 11248 if (i == 0) 11249 base = cur_base; 11250 else if (REGNO (base) != REGNO (cur_base)) 11251 return false; 11252 11253 offsets[i] = INTVAL (cur_offset); 11254 if (GET_CODE (operands[i]) == SUBREG) 11255 { 11256 tmp = SUBREG_REG (operands[i]); 11257 gcc_assert (GET_MODE (operands[i]) == GET_MODE (tmp)); 11258 operands[i] = tmp; 11259 } 11260 } 11261 11262 /* Make sure there is no dependency between the individual loads. */ 11263 if (load && REGNO (operands[0]) == REGNO (base)) 11264 return false; /* RAW. */ 11265 11266 if (load && REGNO (operands[0]) == REGNO (operands[1])) 11267 return false; /* WAW. */ 11268 11269 /* Make sure the instructions are ordered with lower memory access first. */ 11270 if (offsets[0] > offsets[1]) 11271 { 11272 gap = offsets[0] - offsets[1]; 11273 offset = offsets[1]; 11274 11275 /* Swap the instructions such that lower memory is accessed first. */ 11276 std::swap (operands[0], operands[1]); 11277 std::swap (operands[2], operands[3]); 11278 } 11279 else 11280 { 11281 gap = offsets[1] - offsets[0]; 11282 offset = offsets[0]; 11283 } 11284 11285 /* Make sure accesses are to consecutive memory locations. */ 11286 if (gap != 4) 11287 return false; 11288 11289 /* Make sure we generate legal instructions. */ 11290 if (operands_ok_ldd_std (operands[0], operands[1], offset)) 11291 return true; 11292 11293 if (load && commute) 11294 { 11295 /* Try reordering registers. */ 11296 std::swap (operands[0], operands[1]); 11297 if (operands_ok_ldd_std (operands[0], operands[1], offset)) 11298 return true; 11299 } 11300 11301 return false; 11302 } 11303 11304 /* This order of allocation is used when we compile for size. It 11305 allocates first the registers which are most probably to end up in 11306 a short instruction. */ 11307 static const int size_alloc_order[] = 11308 { 11309 0, 1, 2, 3, 12, 13, 14, 15, 11310 4, 5, 6, 7, 8, 9, 10, 11 11311 }; 11312 11313 /* Adjust register allocation order when compiling for size. */ 11314 void 11315 arc_adjust_reg_alloc_order (void) 11316 { 11317 const int arc_default_alloc_order[] = REG_ALLOC_ORDER; 11318 memcpy (reg_alloc_order, arc_default_alloc_order, sizeof (reg_alloc_order)); 11319 if (optimize_size) 11320 memcpy (reg_alloc_order, size_alloc_order, sizeof (size_alloc_order)); 11321 } 11322 11323 /* Implement TARGET_MEMORY_MOVE_COST. */ 11324 11325 static int 11326 arc_memory_move_cost (machine_mode mode, 11327 reg_class_t rclass ATTRIBUTE_UNUSED, 11328 bool in ATTRIBUTE_UNUSED) 11329 { 11330 if ((GET_MODE_SIZE (mode) <= UNITS_PER_WORD) 11331 || ((GET_MODE_SIZE (mode) <= UNITS_PER_WORD * 2) && TARGET_LL64)) 11332 return 6; 11333 11334 return (2 * GET_MODE_SIZE (mode)); 11335 } 11336 11337 #undef TARGET_USE_ANCHORS_FOR_SYMBOL_P 11338 #define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p 11339 11340 #undef TARGET_CONSTANT_ALIGNMENT 11341 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings 11342 11343 #undef TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P 11344 #define TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P arc_cannot_substitute_mem_equiv_p 11345 11346 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE 11347 #define TARGET_ASM_TRAMPOLINE_TEMPLATE arc_asm_trampoline_template 11348 11349 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE 11350 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed 11351 11352 #undef TARGET_REGISTER_MOVE_COST 11353 #define TARGET_REGISTER_MOVE_COST arc_register_move_cost 11354 11355 #undef TARGET_MEMORY_MOVE_COST 11356 #define TARGET_MEMORY_MOVE_COST arc_memory_move_cost 11357 11358 struct gcc_target targetm = TARGET_INITIALIZER; 11359 11360 #include "gt-arc.h" 11361