1/* Subroutines for insn-output.c for Tensilica's Xtensa architecture. 2 Copyright (C) 2001-2020 Free Software Foundation, Inc. 3 Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica. 4 5This file is part of GCC. 6 7GCC is free software; you can redistribute it and/or modify it under 8the terms of the GNU General Public License as published by the Free 9Software Foundation; either version 3, or (at your option) any later 10version. 11 12GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13WARRANTY; without even the implied warranty of MERCHANTABILITY or 14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15for more details. 16 17You should have received a copy of the GNU General Public License 18along with GCC; see the file COPYING3. If not see 19<http://www.gnu.org/licenses/>. */ 20 21#define IN_TARGET_CODE 1 22 23#include "config.h" 24#include "system.h" 25#include "coretypes.h" 26#include "backend.h" 27#include "target.h" 28#include "rtl.h" 29#include "tree.h" 30#include "gimple.h" 31#include "cfghooks.h" 32#include "df.h" 33#include "memmodel.h" 34#include "tm_p.h" 35#include "stringpool.h" 36#include "attribs.h" 37#include "optabs.h" 38#include "regs.h" 39#include "emit-rtl.h" 40#include "recog.h" 41#include "diagnostic-core.h" 42#include "cfgrtl.h" 43#include "output.h" 44#include "fold-const.h" 45#include "stor-layout.h" 46#include "calls.h" 47#include "varasm.h" 48#include "alias.h" 49#include "explow.h" 50#include "expr.h" 51#include "reload.h" 52#include "langhooks.h" 53#include "gimplify.h" 54#include "builtins.h" 55#include "dumpfile.h" 56#include "hw-doloop.h" 57#include "rtl-iter.h" 58 59/* This file should be included last. */ 60#include "target-def.h" 61 62/* Enumeration for all of the relational tests, so that we can build 63 arrays indexed by the test type, and not worry about the order 64 of EQ, NE, etc. */ 65 66enum internal_test 67{ 68 ITEST_EQ, 69 ITEST_NE, 70 ITEST_GT, 71 ITEST_GE, 72 ITEST_LT, 73 ITEST_LE, 74 ITEST_GTU, 75 ITEST_GEU, 76 ITEST_LTU, 77 ITEST_LEU, 78 ITEST_MAX 79}; 80 81/* Array giving truth value on whether or not a given hard register 82 can support a given mode. */ 83static char xtensa_hard_regno_mode_ok_p 84 [(int) MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER]; 85 86/* Largest block move to handle in-line. */ 87#define LARGEST_MOVE_RATIO 15 88 89/* Define the structure for the machine field in struct function. */ 90struct GTY(()) machine_function 91{ 92 int accesses_prev_frame; 93 bool need_a7_copy; 94 bool vararg_a7; 95 rtx vararg_a7_copy; 96 rtx_insn *set_frame_ptr_insn; 97 /* Current frame size calculated by compute_frame_size. */ 98 unsigned current_frame_size; 99 /* Callee-save area size in the current frame calculated by 100 compute_frame_size. */ 101 int callee_save_size; 102 bool frame_laid_out; 103 bool epilogue_done; 104}; 105 106/* Vector, indexed by hard register number, which contains 1 for a 107 register that is allowable in a candidate for leaf function 108 treatment. */ 109 110const char xtensa_leaf_regs[FIRST_PSEUDO_REGISTER] = 111{ 112 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 113 1, 1, 1, 114 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 115 1 116}; 117 118static void xtensa_option_override (void); 119static enum internal_test map_test_to_internal_test (enum rtx_code); 120static rtx gen_int_relational (enum rtx_code, rtx, rtx, int *); 121static rtx gen_float_relational (enum rtx_code, rtx, rtx); 122static rtx gen_conditional_move (enum rtx_code, machine_mode, rtx, rtx); 123static rtx fixup_subreg_mem (rtx); 124static struct machine_function * xtensa_init_machine_status (void); 125static rtx xtensa_legitimize_tls_address (rtx); 126static rtx xtensa_legitimize_address (rtx, rtx, machine_mode); 127static bool xtensa_mode_dependent_address_p (const_rtx, addr_space_t); 128static bool xtensa_return_in_msb (const_tree); 129static void printx (FILE *, signed int); 130static rtx xtensa_builtin_saveregs (void); 131static bool xtensa_legitimate_address_p (machine_mode, rtx, bool); 132static unsigned int xtensa_multibss_section_type_flags (tree, const char *, 133 int) ATTRIBUTE_UNUSED; 134static section *xtensa_select_rtx_section (machine_mode, rtx, 135 unsigned HOST_WIDE_INT); 136static bool xtensa_rtx_costs (rtx, machine_mode, int, int, int *, bool); 137static int xtensa_register_move_cost (machine_mode, reg_class_t, 138 reg_class_t); 139static int xtensa_memory_move_cost (machine_mode, reg_class_t, bool); 140static tree xtensa_build_builtin_va_list (void); 141static bool xtensa_return_in_memory (const_tree, const_tree); 142static tree xtensa_gimplify_va_arg_expr (tree, tree, gimple_seq *, 143 gimple_seq *); 144static void xtensa_function_arg_advance (cumulative_args_t, 145 const function_arg_info &); 146static rtx xtensa_function_arg (cumulative_args_t, const function_arg_info &); 147static rtx xtensa_function_incoming_arg (cumulative_args_t, 148 const function_arg_info &); 149static rtx xtensa_function_value (const_tree, const_tree, bool); 150static rtx xtensa_libcall_value (machine_mode, const_rtx); 151static bool xtensa_function_value_regno_p (const unsigned int); 152static unsigned int xtensa_function_arg_boundary (machine_mode, 153 const_tree); 154static void xtensa_init_builtins (void); 155static tree xtensa_fold_builtin (tree, int, tree *, bool); 156static rtx xtensa_expand_builtin (tree, rtx, rtx, machine_mode, int); 157static void xtensa_va_start (tree, rtx); 158static bool xtensa_frame_pointer_required (void); 159static rtx xtensa_static_chain (const_tree, bool); 160static void xtensa_asm_trampoline_template (FILE *); 161static void xtensa_trampoline_init (rtx, tree, rtx); 162static bool xtensa_output_addr_const_extra (FILE *, rtx); 163static bool xtensa_cannot_force_const_mem (machine_mode, rtx); 164 165static reg_class_t xtensa_preferred_reload_class (rtx, reg_class_t); 166static reg_class_t xtensa_preferred_output_reload_class (rtx, reg_class_t); 167static reg_class_t xtensa_secondary_reload (bool, rtx, reg_class_t, 168 machine_mode, 169 struct secondary_reload_info *); 170 171static bool constantpool_address_p (const_rtx addr); 172static bool xtensa_legitimate_constant_p (machine_mode, rtx); 173static void xtensa_reorg (void); 174static bool xtensa_can_use_doloop_p (const widest_int &, const widest_int &, 175 unsigned int, bool); 176static const char *xtensa_invalid_within_doloop (const rtx_insn *); 177 178static bool xtensa_member_type_forces_blk (const_tree, 179 machine_mode mode); 180 181static void xtensa_conditional_register_usage (void); 182static unsigned int xtensa_hard_regno_nregs (unsigned int, machine_mode); 183static bool xtensa_hard_regno_mode_ok (unsigned int, machine_mode); 184static bool xtensa_modes_tieable_p (machine_mode, machine_mode); 185static HOST_WIDE_INT xtensa_constant_alignment (const_tree, HOST_WIDE_INT); 186static HOST_WIDE_INT xtensa_starting_frame_offset (void); 187static unsigned HOST_WIDE_INT xtensa_asan_shadow_offset (void); 188 189 190 191/* These hooks specify assembly directives for creating certain kinds 192 of integer object. */ 193 194#undef TARGET_ASM_ALIGNED_SI_OP 195#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t" 196 197#undef TARGET_ASM_SELECT_RTX_SECTION 198#define TARGET_ASM_SELECT_RTX_SECTION xtensa_select_rtx_section 199 200#undef TARGET_LEGITIMIZE_ADDRESS 201#define TARGET_LEGITIMIZE_ADDRESS xtensa_legitimize_address 202#undef TARGET_MODE_DEPENDENT_ADDRESS_P 203#define TARGET_MODE_DEPENDENT_ADDRESS_P xtensa_mode_dependent_address_p 204 205#undef TARGET_REGISTER_MOVE_COST 206#define TARGET_REGISTER_MOVE_COST xtensa_register_move_cost 207#undef TARGET_MEMORY_MOVE_COST 208#define TARGET_MEMORY_MOVE_COST xtensa_memory_move_cost 209#undef TARGET_RTX_COSTS 210#define TARGET_RTX_COSTS xtensa_rtx_costs 211#undef TARGET_ADDRESS_COST 212#define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0 213 214#undef TARGET_MEMBER_TYPE_FORCES_BLK 215#define TARGET_MEMBER_TYPE_FORCES_BLK xtensa_member_type_forces_blk 216 217#undef TARGET_BUILD_BUILTIN_VA_LIST 218#define TARGET_BUILD_BUILTIN_VA_LIST xtensa_build_builtin_va_list 219 220#undef TARGET_EXPAND_BUILTIN_VA_START 221#define TARGET_EXPAND_BUILTIN_VA_START xtensa_va_start 222 223#undef TARGET_PROMOTE_FUNCTION_MODE 224#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote 225#undef TARGET_PROMOTE_PROTOTYPES 226#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true 227 228#undef TARGET_RETURN_IN_MEMORY 229#define TARGET_RETURN_IN_MEMORY xtensa_return_in_memory 230#undef TARGET_FUNCTION_VALUE 231#define TARGET_FUNCTION_VALUE xtensa_function_value 232#undef TARGET_LIBCALL_VALUE 233#define TARGET_LIBCALL_VALUE xtensa_libcall_value 234#undef TARGET_FUNCTION_VALUE_REGNO_P 235#define TARGET_FUNCTION_VALUE_REGNO_P xtensa_function_value_regno_p 236 237#undef TARGET_SPLIT_COMPLEX_ARG 238#define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true 239#undef TARGET_MUST_PASS_IN_STACK 240#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size 241#undef TARGET_FUNCTION_ARG_ADVANCE 242#define TARGET_FUNCTION_ARG_ADVANCE xtensa_function_arg_advance 243#undef TARGET_FUNCTION_ARG 244#define TARGET_FUNCTION_ARG xtensa_function_arg 245#undef TARGET_FUNCTION_INCOMING_ARG 246#define TARGET_FUNCTION_INCOMING_ARG xtensa_function_incoming_arg 247#undef TARGET_FUNCTION_ARG_BOUNDARY 248#define TARGET_FUNCTION_ARG_BOUNDARY xtensa_function_arg_boundary 249 250#undef TARGET_EXPAND_BUILTIN_SAVEREGS 251#define TARGET_EXPAND_BUILTIN_SAVEREGS xtensa_builtin_saveregs 252#undef TARGET_GIMPLIFY_VA_ARG_EXPR 253#define TARGET_GIMPLIFY_VA_ARG_EXPR xtensa_gimplify_va_arg_expr 254 255#undef TARGET_RETURN_IN_MSB 256#define TARGET_RETURN_IN_MSB xtensa_return_in_msb 257 258#undef TARGET_INIT_BUILTINS 259#define TARGET_INIT_BUILTINS xtensa_init_builtins 260#undef TARGET_FOLD_BUILTIN 261#define TARGET_FOLD_BUILTIN xtensa_fold_builtin 262#undef TARGET_EXPAND_BUILTIN 263#define TARGET_EXPAND_BUILTIN xtensa_expand_builtin 264 265#undef TARGET_PREFERRED_RELOAD_CLASS 266#define TARGET_PREFERRED_RELOAD_CLASS xtensa_preferred_reload_class 267#undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS 268#define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS xtensa_preferred_output_reload_class 269 270#undef TARGET_SECONDARY_RELOAD 271#define TARGET_SECONDARY_RELOAD xtensa_secondary_reload 272 273#undef TARGET_HAVE_TLS 274#define TARGET_HAVE_TLS (TARGET_THREADPTR && HAVE_AS_TLS) 275 276#undef TARGET_CANNOT_FORCE_CONST_MEM 277#define TARGET_CANNOT_FORCE_CONST_MEM xtensa_cannot_force_const_mem 278 279#undef TARGET_LRA_P 280#define TARGET_LRA_P hook_bool_void_false 281 282#undef TARGET_LEGITIMATE_ADDRESS_P 283#define TARGET_LEGITIMATE_ADDRESS_P xtensa_legitimate_address_p 284 285#undef TARGET_FRAME_POINTER_REQUIRED 286#define TARGET_FRAME_POINTER_REQUIRED xtensa_frame_pointer_required 287 288#undef TARGET_STATIC_CHAIN 289#define TARGET_STATIC_CHAIN xtensa_static_chain 290#undef TARGET_ASM_TRAMPOLINE_TEMPLATE 291#define TARGET_ASM_TRAMPOLINE_TEMPLATE xtensa_asm_trampoline_template 292#undef TARGET_TRAMPOLINE_INIT 293#define TARGET_TRAMPOLINE_INIT xtensa_trampoline_init 294 295#undef TARGET_OPTION_OVERRIDE 296#define TARGET_OPTION_OVERRIDE xtensa_option_override 297 298#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA 299#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA xtensa_output_addr_const_extra 300 301#undef TARGET_LEGITIMATE_CONSTANT_P 302#define TARGET_LEGITIMATE_CONSTANT_P xtensa_legitimate_constant_p 303 304#undef TARGET_MACHINE_DEPENDENT_REORG 305#define TARGET_MACHINE_DEPENDENT_REORG xtensa_reorg 306 307#undef TARGET_CAN_USE_DOLOOP_P 308#define TARGET_CAN_USE_DOLOOP_P xtensa_can_use_doloop_p 309 310#undef TARGET_INVALID_WITHIN_DOLOOP 311#define TARGET_INVALID_WITHIN_DOLOOP xtensa_invalid_within_doloop 312 313#undef TARGET_CONDITIONAL_REGISTER_USAGE 314#define TARGET_CONDITIONAL_REGISTER_USAGE xtensa_conditional_register_usage 315 316#undef TARGET_HARD_REGNO_NREGS 317#define TARGET_HARD_REGNO_NREGS xtensa_hard_regno_nregs 318#undef TARGET_HARD_REGNO_MODE_OK 319#define TARGET_HARD_REGNO_MODE_OK xtensa_hard_regno_mode_ok 320 321#undef TARGET_MODES_TIEABLE_P 322#define TARGET_MODES_TIEABLE_P xtensa_modes_tieable_p 323 324#undef TARGET_CONSTANT_ALIGNMENT 325#define TARGET_CONSTANT_ALIGNMENT xtensa_constant_alignment 326 327#undef TARGET_STARTING_FRAME_OFFSET 328#define TARGET_STARTING_FRAME_OFFSET xtensa_starting_frame_offset 329 330#undef TARGET_ASAN_SHADOW_OFFSET 331#define TARGET_ASAN_SHADOW_OFFSET xtensa_asan_shadow_offset 332 333#undef TARGET_HAVE_SPECULATION_SAFE_VALUE 334#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed 335 336struct gcc_target targetm = TARGET_INITIALIZER; 337 338 339/* Functions to test Xtensa immediate operand validity. */ 340 341bool 342xtensa_simm8 (HOST_WIDE_INT v) 343{ 344 return v >= -128 && v <= 127; 345} 346 347 348bool 349xtensa_simm8x256 (HOST_WIDE_INT v) 350{ 351 return (v & 255) == 0 && (v >= -32768 && v <= 32512); 352} 353 354 355bool 356xtensa_simm12b (HOST_WIDE_INT v) 357{ 358 return v >= -2048 && v <= 2047; 359} 360 361 362static bool 363xtensa_uimm8 (HOST_WIDE_INT v) 364{ 365 return v >= 0 && v <= 255; 366} 367 368 369static bool 370xtensa_uimm8x2 (HOST_WIDE_INT v) 371{ 372 return (v & 1) == 0 && (v >= 0 && v <= 510); 373} 374 375 376static bool 377xtensa_uimm8x4 (HOST_WIDE_INT v) 378{ 379 return (v & 3) == 0 && (v >= 0 && v <= 1020); 380} 381 382 383static bool 384xtensa_b4const (HOST_WIDE_INT v) 385{ 386 switch (v) 387 { 388 case -1: 389 case 1: 390 case 2: 391 case 3: 392 case 4: 393 case 5: 394 case 6: 395 case 7: 396 case 8: 397 case 10: 398 case 12: 399 case 16: 400 case 32: 401 case 64: 402 case 128: 403 case 256: 404 return true; 405 } 406 return false; 407} 408 409 410bool 411xtensa_b4const_or_zero (HOST_WIDE_INT v) 412{ 413 if (v == 0) 414 return true; 415 return xtensa_b4const (v); 416} 417 418 419bool 420xtensa_b4constu (HOST_WIDE_INT v) 421{ 422 switch (v) 423 { 424 case 32768: 425 case 65536: 426 case 2: 427 case 3: 428 case 4: 429 case 5: 430 case 6: 431 case 7: 432 case 8: 433 case 10: 434 case 12: 435 case 16: 436 case 32: 437 case 64: 438 case 128: 439 case 256: 440 return true; 441 } 442 return false; 443} 444 445 446bool 447xtensa_mask_immediate (HOST_WIDE_INT v) 448{ 449#define MAX_MASK_SIZE 16 450 int mask_size; 451 452 for (mask_size = 1; mask_size <= MAX_MASK_SIZE; mask_size++) 453 { 454 if ((v & 1) == 0) 455 return false; 456 v = v >> 1; 457 if (v == 0) 458 return true; 459 } 460 461 return false; 462} 463 464 465/* This is just like the standard true_regnum() function except that it 466 works even when reg_renumber is not initialized. */ 467 468int 469xt_true_regnum (rtx x) 470{ 471 if (GET_CODE (x) == REG) 472 { 473 if (reg_renumber 474 && REGNO (x) >= FIRST_PSEUDO_REGISTER 475 && reg_renumber[REGNO (x)] >= 0) 476 return reg_renumber[REGNO (x)]; 477 return REGNO (x); 478 } 479 if (GET_CODE (x) == SUBREG) 480 { 481 int base = xt_true_regnum (SUBREG_REG (x)); 482 if (base >= 0 && base < FIRST_PSEUDO_REGISTER) 483 return base + subreg_regno_offset (REGNO (SUBREG_REG (x)), 484 GET_MODE (SUBREG_REG (x)), 485 SUBREG_BYTE (x), GET_MODE (x)); 486 } 487 return -1; 488} 489 490 491int 492xtensa_valid_move (machine_mode mode, rtx *operands) 493{ 494 /* Either the destination or source must be a register, and the 495 MAC16 accumulator doesn't count. */ 496 497 if (register_operand (operands[0], mode)) 498 { 499 int dst_regnum = xt_true_regnum (operands[0]); 500 501 if (xtensa_tls_referenced_p (operands[1])) 502 return FALSE; 503 504 /* The stack pointer can only be assigned with a MOVSP opcode. */ 505 if (dst_regnum == STACK_POINTER_REGNUM) 506 return !TARGET_WINDOWED_ABI 507 || (mode == SImode 508 && register_operand (operands[1], mode) 509 && !ACC_REG_P (xt_true_regnum (operands[1]))); 510 511 if (!ACC_REG_P (dst_regnum)) 512 return true; 513 } 514 if (register_operand (operands[1], mode)) 515 { 516 int src_regnum = xt_true_regnum (operands[1]); 517 if (!ACC_REG_P (src_regnum)) 518 return true; 519 } 520 return FALSE; 521} 522 523 524int 525smalloffset_mem_p (rtx op) 526{ 527 if (GET_CODE (op) == MEM) 528 { 529 rtx addr = XEXP (op, 0); 530 if (GET_CODE (addr) == REG) 531 return BASE_REG_P (addr, 0); 532 if (GET_CODE (addr) == PLUS) 533 { 534 rtx offset = XEXP (addr, 0); 535 HOST_WIDE_INT val; 536 if (GET_CODE (offset) != CONST_INT) 537 offset = XEXP (addr, 1); 538 if (GET_CODE (offset) != CONST_INT) 539 return FALSE; 540 541 val = INTVAL (offset); 542 return (val & 3) == 0 && (val >= 0 && val <= 60); 543 } 544 } 545 return FALSE; 546} 547 548 549static bool 550constantpool_address_p (const_rtx addr) 551{ 552 const_rtx sym = addr; 553 554 if (GET_CODE (addr) == CONST) 555 { 556 rtx offset; 557 558 /* Only handle (PLUS (SYM, OFFSET)) form. */ 559 addr = XEXP (addr, 0); 560 if (GET_CODE (addr) != PLUS) 561 return false; 562 563 /* Make sure the address is word aligned. */ 564 offset = XEXP (addr, 1); 565 if ((!CONST_INT_P (offset)) 566 || ((INTVAL (offset) & 3) != 0)) 567 return false; 568 569 sym = XEXP (addr, 0); 570 } 571 572 if ((GET_CODE (sym) == SYMBOL_REF) 573 && CONSTANT_POOL_ADDRESS_P (sym)) 574 return true; 575 return false; 576} 577 578 579int 580constantpool_mem_p (rtx op) 581{ 582 if (GET_CODE (op) == SUBREG) 583 op = SUBREG_REG (op); 584 if (GET_CODE (op) == MEM) 585 return constantpool_address_p (XEXP (op, 0)); 586 return FALSE; 587} 588 589 590/* Return TRUE if X is a thread-local symbol. */ 591 592static bool 593xtensa_tls_symbol_p (rtx x) 594{ 595 if (! TARGET_HAVE_TLS) 596 return false; 597 598 return GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x) != 0; 599} 600 601 602void 603xtensa_extend_reg (rtx dst, rtx src) 604{ 605 rtx temp = gen_reg_rtx (SImode); 606 rtx shift = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (GET_MODE (src))); 607 608 /* Generate paradoxical subregs as needed so that the modes match. */ 609 src = simplify_gen_subreg (SImode, src, GET_MODE (src), 0); 610 dst = simplify_gen_subreg (SImode, dst, GET_MODE (dst), 0); 611 612 emit_insn (gen_ashlsi3 (temp, src, shift)); 613 emit_insn (gen_ashrsi3 (dst, temp, shift)); 614} 615 616 617bool 618xtensa_mem_offset (unsigned v, machine_mode mode) 619{ 620 switch (mode) 621 { 622 case E_BLKmode: 623 /* Handle the worst case for block moves. See xtensa_expand_block_move 624 where we emit an optimized block move operation if the block can be 625 moved in < "move_ratio" pieces. The worst case is when the block is 626 aligned but has a size of (3 mod 4) (does this happen?) so that the 627 last piece requires a byte load/store. */ 628 return (xtensa_uimm8 (v) 629 && xtensa_uimm8 (v + MOVE_MAX * LARGEST_MOVE_RATIO)); 630 631 case E_QImode: 632 return xtensa_uimm8 (v); 633 634 case E_HImode: 635 return xtensa_uimm8x2 (v); 636 637 case E_DImode: 638 case E_DFmode: 639 return (xtensa_uimm8x4 (v) && xtensa_uimm8x4 (v + 4)); 640 641 default: 642 break; 643 } 644 645 return xtensa_uimm8x4 (v); 646} 647 648 649/* Make normal rtx_code into something we can index from an array. */ 650 651static enum internal_test 652map_test_to_internal_test (enum rtx_code test_code) 653{ 654 enum internal_test test = ITEST_MAX; 655 656 switch (test_code) 657 { 658 default: break; 659 case EQ: test = ITEST_EQ; break; 660 case NE: test = ITEST_NE; break; 661 case GT: test = ITEST_GT; break; 662 case GE: test = ITEST_GE; break; 663 case LT: test = ITEST_LT; break; 664 case LE: test = ITEST_LE; break; 665 case GTU: test = ITEST_GTU; break; 666 case GEU: test = ITEST_GEU; break; 667 case LTU: test = ITEST_LTU; break; 668 case LEU: test = ITEST_LEU; break; 669 } 670 671 return test; 672} 673 674 675/* Generate the code to compare two integer values. The return value is 676 the comparison expression. */ 677 678static rtx 679gen_int_relational (enum rtx_code test_code, /* relational test (EQ, etc) */ 680 rtx cmp0, /* first operand to compare */ 681 rtx cmp1, /* second operand to compare */ 682 int *p_invert /* whether branch needs to reverse test */) 683{ 684 struct cmp_info 685 { 686 enum rtx_code test_code; /* test code to use in insn */ 687 bool (*const_range_p) (HOST_WIDE_INT); /* range check function */ 688 int const_add; /* constant to add (convert LE -> LT) */ 689 int reverse_regs; /* reverse registers in test */ 690 int invert_const; /* != 0 if invert value if cmp1 is constant */ 691 int invert_reg; /* != 0 if invert value if cmp1 is register */ 692 int unsignedp; /* != 0 for unsigned comparisons. */ 693 }; 694 695 static struct cmp_info info[ (int)ITEST_MAX ] = { 696 697 { EQ, xtensa_b4const_or_zero, 0, 0, 0, 0, 0 }, /* EQ */ 698 { NE, xtensa_b4const_or_zero, 0, 0, 0, 0, 0 }, /* NE */ 699 700 { LT, xtensa_b4const_or_zero, 1, 1, 1, 0, 0 }, /* GT */ 701 { GE, xtensa_b4const_or_zero, 0, 0, 0, 0, 0 }, /* GE */ 702 { LT, xtensa_b4const_or_zero, 0, 0, 0, 0, 0 }, /* LT */ 703 { GE, xtensa_b4const_or_zero, 1, 1, 1, 0, 0 }, /* LE */ 704 705 { LTU, xtensa_b4constu, 1, 1, 1, 0, 1 }, /* GTU */ 706 { GEU, xtensa_b4constu, 0, 0, 0, 0, 1 }, /* GEU */ 707 { LTU, xtensa_b4constu, 0, 0, 0, 0, 1 }, /* LTU */ 708 { GEU, xtensa_b4constu, 1, 1, 1, 0, 1 }, /* LEU */ 709 }; 710 711 enum internal_test test; 712 machine_mode mode; 713 struct cmp_info *p_info; 714 715 test = map_test_to_internal_test (test_code); 716 gcc_assert (test != ITEST_MAX); 717 718 p_info = &info[ (int)test ]; 719 720 mode = GET_MODE (cmp0); 721 if (mode == VOIDmode) 722 mode = GET_MODE (cmp1); 723 724 /* Make sure we can handle any constants given to us. */ 725 if (GET_CODE (cmp1) == CONST_INT) 726 { 727 HOST_WIDE_INT value = INTVAL (cmp1); 728 unsigned HOST_WIDE_INT uvalue = (unsigned HOST_WIDE_INT)value; 729 730 /* if the immediate overflows or does not fit in the immediate field, 731 spill it to a register */ 732 733 if ((p_info->unsignedp ? 734 (uvalue + p_info->const_add > uvalue) : 735 (value + p_info->const_add > value)) != (p_info->const_add > 0)) 736 { 737 cmp1 = force_reg (mode, cmp1); 738 } 739 else if (!(p_info->const_range_p) (value + p_info->const_add)) 740 { 741 cmp1 = force_reg (mode, cmp1); 742 } 743 } 744 else if ((GET_CODE (cmp1) != REG) && (GET_CODE (cmp1) != SUBREG)) 745 { 746 cmp1 = force_reg (mode, cmp1); 747 } 748 749 /* See if we need to invert the result. */ 750 *p_invert = ((GET_CODE (cmp1) == CONST_INT) 751 ? p_info->invert_const 752 : p_info->invert_reg); 753 754 /* Comparison to constants, may involve adding 1 to change a LT into LE. 755 Comparison between two registers, may involve switching operands. */ 756 if (GET_CODE (cmp1) == CONST_INT) 757 { 758 if (p_info->const_add != 0) 759 cmp1 = GEN_INT (INTVAL (cmp1) + p_info->const_add); 760 761 } 762 else if (p_info->reverse_regs) 763 { 764 rtx temp = cmp0; 765 cmp0 = cmp1; 766 cmp1 = temp; 767 } 768 769 return gen_rtx_fmt_ee (p_info->test_code, VOIDmode, cmp0, cmp1); 770} 771 772 773/* Generate the code to compare two float values. The return value is 774 the comparison expression. */ 775 776static rtx 777gen_float_relational (enum rtx_code test_code, /* relational test (EQ, etc) */ 778 rtx cmp0, /* first operand to compare */ 779 rtx cmp1 /* second operand to compare */) 780{ 781 rtx (*gen_fn) (rtx, rtx, rtx); 782 rtx brtmp; 783 int reverse_regs, invert; 784 785 switch (test_code) 786 { 787 case EQ: reverse_regs = 0; invert = 0; gen_fn = gen_seq_sf; break; 788 case NE: reverse_regs = 0; invert = 1; gen_fn = gen_seq_sf; break; 789 case LE: reverse_regs = 0; invert = 0; gen_fn = gen_sle_sf; break; 790 case GT: reverse_regs = 1; invert = 0; gen_fn = gen_slt_sf; break; 791 case LT: reverse_regs = 0; invert = 0; gen_fn = gen_slt_sf; break; 792 case GE: reverse_regs = 1; invert = 0; gen_fn = gen_sle_sf; break; 793 case UNEQ: reverse_regs = 0; invert = 0; gen_fn = gen_suneq_sf; break; 794 case LTGT: reverse_regs = 0; invert = 1; gen_fn = gen_suneq_sf; break; 795 case UNLE: reverse_regs = 0; invert = 0; gen_fn = gen_sunle_sf; break; 796 case UNGT: reverse_regs = 1; invert = 0; gen_fn = gen_sunlt_sf; break; 797 case UNLT: reverse_regs = 0; invert = 0; gen_fn = gen_sunlt_sf; break; 798 case UNGE: reverse_regs = 1; invert = 0; gen_fn = gen_sunle_sf; break; 799 case UNORDERED: 800 reverse_regs = 0; invert = 0; gen_fn = gen_sunordered_sf; break; 801 case ORDERED: 802 reverse_regs = 0; invert = 1; gen_fn = gen_sunordered_sf; break; 803 default: 804 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1)); 805 reverse_regs = 0; invert = 0; gen_fn = 0; /* avoid compiler warnings */ 806 } 807 808 if (reverse_regs) 809 { 810 rtx temp = cmp0; 811 cmp0 = cmp1; 812 cmp1 = temp; 813 } 814 815 brtmp = gen_rtx_REG (CCmode, FPCC_REGNUM); 816 emit_insn (gen_fn (brtmp, cmp0, cmp1)); 817 818 return gen_rtx_fmt_ee (invert ? EQ : NE, VOIDmode, brtmp, const0_rtx); 819} 820 821 822void 823xtensa_expand_conditional_branch (rtx *operands, machine_mode mode) 824{ 825 enum rtx_code test_code = GET_CODE (operands[0]); 826 rtx cmp0 = operands[1]; 827 rtx cmp1 = operands[2]; 828 rtx cmp; 829 int invert; 830 rtx label1, label2; 831 832 switch (mode) 833 { 834 case E_DFmode: 835 default: 836 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1)); 837 838 case E_SImode: 839 invert = FALSE; 840 cmp = gen_int_relational (test_code, cmp0, cmp1, &invert); 841 break; 842 843 case E_SFmode: 844 if (!TARGET_HARD_FLOAT) 845 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, 846 cmp0, cmp1)); 847 invert = FALSE; 848 cmp = gen_float_relational (test_code, cmp0, cmp1); 849 break; 850 } 851 852 /* Generate the branch. */ 853 854 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[3]); 855 label2 = pc_rtx; 856 857 if (invert) 858 { 859 label2 = label1; 860 label1 = pc_rtx; 861 } 862 863 emit_jump_insn (gen_rtx_SET (pc_rtx, 864 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp, 865 label1, 866 label2))); 867} 868 869 870static rtx 871gen_conditional_move (enum rtx_code code, machine_mode mode, 872 rtx op0, rtx op1) 873{ 874 if (mode == SImode) 875 { 876 rtx cmp; 877 878 /* Jump optimization calls get_condition() which canonicalizes 879 comparisons like (GE x <const>) to (GT x <const-1>). 880 Transform those comparisons back to GE, since that is the 881 comparison supported in Xtensa. We shouldn't have to 882 transform <LE x const> comparisons, because neither 883 xtensa_expand_conditional_branch() nor get_condition() will 884 produce them. */ 885 886 if ((code == GT) && (op1 == constm1_rtx)) 887 { 888 code = GE; 889 op1 = const0_rtx; 890 } 891 cmp = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx); 892 893 if (boolean_operator (cmp, VOIDmode)) 894 { 895 /* Swap the operands to make const0 second. */ 896 if (op0 == const0_rtx) 897 { 898 op0 = op1; 899 op1 = const0_rtx; 900 } 901 902 /* If not comparing against zero, emit a comparison (subtract). */ 903 if (op1 != const0_rtx) 904 { 905 op0 = expand_binop (SImode, sub_optab, op0, op1, 906 0, 0, OPTAB_LIB_WIDEN); 907 op1 = const0_rtx; 908 } 909 } 910 else if (branch_operator (cmp, VOIDmode)) 911 { 912 /* Swap the operands to make const0 second. */ 913 if (op0 == const0_rtx) 914 { 915 op0 = op1; 916 op1 = const0_rtx; 917 918 switch (code) 919 { 920 case LT: code = GE; break; 921 case GE: code = LT; break; 922 default: gcc_unreachable (); 923 } 924 } 925 926 if (op1 != const0_rtx) 927 return 0; 928 } 929 else 930 return 0; 931 932 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1); 933 } 934 935 if (TARGET_HARD_FLOAT && mode == SFmode) 936 return gen_float_relational (code, op0, op1); 937 938 return 0; 939} 940 941 942int 943xtensa_expand_conditional_move (rtx *operands, int isflt) 944{ 945 rtx dest = operands[0]; 946 rtx cmp = operands[1]; 947 machine_mode cmp_mode = GET_MODE (XEXP (cmp, 0)); 948 rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx); 949 950 if (!(cmp = gen_conditional_move (GET_CODE (cmp), cmp_mode, 951 XEXP (cmp, 0), XEXP (cmp, 1)))) 952 return 0; 953 954 if (isflt) 955 gen_fn = (cmp_mode == SImode 956 ? gen_movsfcc_internal0 957 : gen_movsfcc_internal1); 958 else 959 gen_fn = (cmp_mode == SImode 960 ? gen_movsicc_internal0 961 : gen_movsicc_internal1); 962 963 emit_insn (gen_fn (dest, XEXP (cmp, 0), operands[2], operands[3], cmp)); 964 return 1; 965} 966 967 968int 969xtensa_expand_scc (rtx operands[4], machine_mode cmp_mode) 970{ 971 rtx dest = operands[0]; 972 rtx cmp; 973 rtx one_tmp, zero_tmp; 974 rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx); 975 976 if (!(cmp = gen_conditional_move (GET_CODE (operands[1]), cmp_mode, 977 operands[2], operands[3]))) 978 return 0; 979 980 one_tmp = gen_reg_rtx (SImode); 981 zero_tmp = gen_reg_rtx (SImode); 982 emit_insn (gen_movsi (one_tmp, const_true_rtx)); 983 emit_insn (gen_movsi (zero_tmp, const0_rtx)); 984 985 gen_fn = (cmp_mode == SImode 986 ? gen_movsicc_internal0 987 : gen_movsicc_internal1); 988 emit_insn (gen_fn (dest, XEXP (cmp, 0), one_tmp, zero_tmp, cmp)); 989 return 1; 990} 991 992 993/* Split OP[1] into OP[2,3] and likewise for OP[0] into OP[0,1]. MODE is 994 for the output, i.e., the input operands are twice as big as MODE. */ 995 996void 997xtensa_split_operand_pair (rtx operands[4], machine_mode mode) 998{ 999 switch (GET_CODE (operands[1])) 1000 { 1001 case REG: 1002 operands[3] = gen_rtx_REG (mode, REGNO (operands[1]) + 1); 1003 operands[2] = gen_rtx_REG (mode, REGNO (operands[1])); 1004 break; 1005 1006 case MEM: 1007 operands[3] = adjust_address (operands[1], mode, GET_MODE_SIZE (mode)); 1008 operands[2] = adjust_address (operands[1], mode, 0); 1009 break; 1010 1011 case CONST_INT: 1012 case CONST_DOUBLE: 1013 split_double (operands[1], &operands[2], &operands[3]); 1014 break; 1015 1016 default: 1017 gcc_unreachable (); 1018 } 1019 1020 switch (GET_CODE (operands[0])) 1021 { 1022 case REG: 1023 operands[1] = gen_rtx_REG (mode, REGNO (operands[0]) + 1); 1024 operands[0] = gen_rtx_REG (mode, REGNO (operands[0])); 1025 break; 1026 1027 case MEM: 1028 operands[1] = adjust_address (operands[0], mode, GET_MODE_SIZE (mode)); 1029 operands[0] = adjust_address (operands[0], mode, 0); 1030 break; 1031 1032 default: 1033 gcc_unreachable (); 1034 } 1035} 1036 1037 1038/* Emit insns to move operands[1] into operands[0]. 1039 Return 1 if we have written out everything that needs to be done to 1040 do the move. Otherwise, return 0 and the caller will emit the move 1041 normally. */ 1042 1043int 1044xtensa_emit_move_sequence (rtx *operands, machine_mode mode) 1045{ 1046 rtx src = operands[1]; 1047 1048 if (CONSTANT_P (src) 1049 && (GET_CODE (src) != CONST_INT || ! xtensa_simm12b (INTVAL (src)))) 1050 { 1051 rtx dst = operands[0]; 1052 1053 if (xtensa_tls_referenced_p (src)) 1054 { 1055 rtx addend = NULL; 1056 1057 if (GET_CODE (src) == CONST && GET_CODE (XEXP (src, 0)) == PLUS) 1058 { 1059 addend = XEXP (XEXP (src, 0), 1); 1060 src = XEXP (XEXP (src, 0), 0); 1061 } 1062 1063 src = xtensa_legitimize_tls_address (src); 1064 if (addend) 1065 { 1066 src = gen_rtx_PLUS (mode, src, addend); 1067 src = force_operand (src, dst); 1068 } 1069 emit_move_insn (dst, src); 1070 return 1; 1071 } 1072 1073 if (! TARGET_AUTO_LITPOOLS && ! TARGET_CONST16) 1074 { 1075 src = force_const_mem (SImode, src); 1076 operands[1] = src; 1077 } 1078 1079 /* PC-relative loads are always SImode, and CONST16 is only 1080 supported in the movsi pattern, so add a SUBREG for any other 1081 (smaller) mode. */ 1082 1083 if (mode != SImode) 1084 { 1085 if (register_operand (dst, mode)) 1086 { 1087 emit_move_insn (simplify_gen_subreg (SImode, dst, mode, 0), src); 1088 return 1; 1089 } 1090 else 1091 { 1092 src = force_reg (SImode, src); 1093 src = gen_lowpart_SUBREG (mode, src); 1094 operands[1] = src; 1095 } 1096 } 1097 } 1098 1099 if (!(reload_in_progress | reload_completed) 1100 && !xtensa_valid_move (mode, operands)) 1101 operands[1] = force_reg (mode, operands[1]); 1102 1103 operands[1] = xtensa_copy_incoming_a7 (operands[1]); 1104 1105 /* During reload we don't want to emit (subreg:X (mem:Y)) since that 1106 instruction won't be recognized after reload, so we remove the 1107 subreg and adjust mem accordingly. */ 1108 if (reload_in_progress) 1109 { 1110 operands[0] = fixup_subreg_mem (operands[0]); 1111 operands[1] = fixup_subreg_mem (operands[1]); 1112 } 1113 return 0; 1114} 1115 1116 1117static rtx 1118fixup_subreg_mem (rtx x) 1119{ 1120 if (GET_CODE (x) == SUBREG 1121 && GET_CODE (SUBREG_REG (x)) == REG 1122 && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER) 1123 { 1124 rtx temp = 1125 gen_rtx_SUBREG (GET_MODE (x), 1126 reg_equiv_mem (REGNO (SUBREG_REG (x))), 1127 SUBREG_BYTE (x)); 1128 x = alter_subreg (&temp, true); 1129 } 1130 return x; 1131} 1132 1133 1134/* Check if an incoming argument in a7 is expected to be used soon and 1135 if OPND is a register or register pair that includes a7. If so, 1136 create a new pseudo and copy a7 into that pseudo at the very 1137 beginning of the function, followed by the special "set_frame_ptr" 1138 unspec_volatile insn. The return value is either the original 1139 operand, if it is not a7, or the new pseudo containing a copy of 1140 the incoming argument. This is necessary because the register 1141 allocator will ignore conflicts with a7 and may either assign some 1142 other pseudo to a7 or use a7 as the hard_frame_pointer, clobbering 1143 the incoming argument in a7. By copying the argument out of a7 as 1144 the very first thing, and then immediately following that with an 1145 unspec_volatile to keep the scheduler away, we should avoid any 1146 problems. Putting the set_frame_ptr insn at the beginning, with 1147 only the a7 copy before it, also makes it easier for the prologue 1148 expander to initialize the frame pointer after the a7 copy and to 1149 fix up the a7 copy to use the stack pointer instead of the frame 1150 pointer. */ 1151 1152rtx 1153xtensa_copy_incoming_a7 (rtx opnd) 1154{ 1155 rtx entry_insns = 0; 1156 rtx reg, tmp; 1157 machine_mode mode; 1158 1159 if (!cfun->machine->need_a7_copy) 1160 return opnd; 1161 1162 /* This function should never be called again once a7 has been copied. */ 1163 gcc_assert (!cfun->machine->set_frame_ptr_insn); 1164 1165 mode = GET_MODE (opnd); 1166 1167 /* The operand using a7 may come in a later instruction, so just return 1168 the original operand if it doesn't use a7. */ 1169 reg = opnd; 1170 if (GET_CODE (reg) == SUBREG) 1171 { 1172 gcc_assert (SUBREG_BYTE (reg) == 0); 1173 reg = SUBREG_REG (reg); 1174 } 1175 if (GET_CODE (reg) != REG 1176 || REGNO (reg) > A7_REG 1177 || REGNO (reg) + hard_regno_nregs (A7_REG, mode) <= A7_REG) 1178 return opnd; 1179 1180 /* 1-word args will always be in a7; 2-word args in a6/a7. */ 1181 gcc_assert (REGNO (reg) + hard_regno_nregs (A7_REG, mode) - 1 == A7_REG); 1182 1183 cfun->machine->need_a7_copy = false; 1184 1185 /* Copy a7 to a new pseudo at the function entry. Use gen_raw_REG to 1186 create the REG for a7 so that hard_frame_pointer_rtx is not used. */ 1187 1188 start_sequence (); 1189 tmp = gen_reg_rtx (mode); 1190 1191 switch (mode) 1192 { 1193 case E_DFmode: 1194 case E_DImode: 1195 /* Copy the value out of A7 here but keep the first word in A6 until 1196 after the set_frame_ptr insn. Otherwise, the register allocator 1197 may decide to put "subreg (tmp, 0)" in A7 and clobber the incoming 1198 value. */ 1199 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode, tmp, 4), 1200 gen_raw_REG (SImode, A7_REG))); 1201 break; 1202 case E_SFmode: 1203 emit_insn (gen_movsf_internal (tmp, gen_raw_REG (mode, A7_REG))); 1204 break; 1205 case E_SImode: 1206 emit_insn (gen_movsi_internal (tmp, gen_raw_REG (mode, A7_REG))); 1207 break; 1208 case E_HImode: 1209 emit_insn (gen_movhi_internal (tmp, gen_raw_REG (mode, A7_REG))); 1210 break; 1211 case E_QImode: 1212 emit_insn (gen_movqi_internal (tmp, gen_raw_REG (mode, A7_REG))); 1213 break; 1214 default: 1215 gcc_unreachable (); 1216 } 1217 1218 cfun->machine->set_frame_ptr_insn = emit_insn (gen_set_frame_ptr ()); 1219 1220 /* For DF and DI mode arguments, copy the incoming value in A6 now. */ 1221 if (mode == DFmode || mode == DImode) 1222 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode, tmp, 0), 1223 gen_rtx_REG (SImode, A7_REG - 1))); 1224 entry_insns = get_insns (); 1225 end_sequence (); 1226 1227 if (cfun->machine->vararg_a7) 1228 { 1229 /* This is called from within builtin_saveregs, which will insert the 1230 saveregs code at the function entry, ahead of anything placed at 1231 the function entry now. Instead, save the sequence to be inserted 1232 at the beginning of the saveregs code. */ 1233 cfun->machine->vararg_a7_copy = entry_insns; 1234 } 1235 else 1236 { 1237 /* Put entry_insns after the NOTE that starts the function. If 1238 this is inside a start_sequence, make the outer-level insn 1239 chain current, so the code is placed at the start of the 1240 function. */ 1241 push_topmost_sequence (); 1242 /* Do not use entry_of_function() here. This is called from within 1243 expand_function_start, when the CFG still holds GIMPLE. */ 1244 emit_insn_after (entry_insns, get_insns ()); 1245 pop_topmost_sequence (); 1246 } 1247 1248 return tmp; 1249} 1250 1251 1252/* Try to expand a block move operation to a sequence of RTL move 1253 instructions. If not optimizing, or if the block size is not a 1254 constant, or if the block is too large, the expansion fails and GCC 1255 falls back to calling memcpy(). 1256 1257 operands[0] is the destination 1258 operands[1] is the source 1259 operands[2] is the length 1260 operands[3] is the alignment */ 1261 1262int 1263xtensa_expand_block_move (rtx *operands) 1264{ 1265 static const machine_mode mode_from_align[] = 1266 { 1267 VOIDmode, QImode, HImode, VOIDmode, SImode, 1268 }; 1269 1270 rtx dst_mem = operands[0]; 1271 rtx src_mem = operands[1]; 1272 HOST_WIDE_INT bytes, align; 1273 int num_pieces, move_ratio; 1274 rtx temp[2]; 1275 machine_mode mode[2]; 1276 int amount[2]; 1277 bool active[2]; 1278 int phase = 0; 1279 int next; 1280 int offset_ld = 0; 1281 int offset_st = 0; 1282 rtx x; 1283 1284 /* If this is not a fixed size move, just call memcpy. */ 1285 if (!optimize || (GET_CODE (operands[2]) != CONST_INT)) 1286 return 0; 1287 1288 bytes = INTVAL (operands[2]); 1289 align = INTVAL (operands[3]); 1290 1291 /* Anything to move? */ 1292 if (bytes <= 0) 1293 return 0; 1294 1295 if (align > MOVE_MAX) 1296 align = MOVE_MAX; 1297 1298 /* Decide whether to expand inline based on the optimization level. */ 1299 move_ratio = 4; 1300 if (optimize > 2) 1301 move_ratio = LARGEST_MOVE_RATIO; 1302 num_pieces = (bytes / align) + (bytes % align); /* Close enough anyway. */ 1303 if (num_pieces > move_ratio) 1304 return 0; 1305 1306 x = XEXP (dst_mem, 0); 1307 if (!REG_P (x)) 1308 { 1309 x = force_reg (Pmode, x); 1310 dst_mem = replace_equiv_address (dst_mem, x); 1311 } 1312 1313 x = XEXP (src_mem, 0); 1314 if (!REG_P (x)) 1315 { 1316 x = force_reg (Pmode, x); 1317 src_mem = replace_equiv_address (src_mem, x); 1318 } 1319 1320 active[0] = active[1] = false; 1321 1322 do 1323 { 1324 next = phase; 1325 phase ^= 1; 1326 1327 if (bytes > 0) 1328 { 1329 int next_amount; 1330 1331 next_amount = (bytes >= 4 ? 4 : (bytes >= 2 ? 2 : 1)); 1332 next_amount = MIN (next_amount, align); 1333 1334 amount[next] = next_amount; 1335 mode[next] = mode_from_align[next_amount]; 1336 temp[next] = gen_reg_rtx (mode[next]); 1337 1338 x = adjust_address (src_mem, mode[next], offset_ld); 1339 emit_insn (gen_rtx_SET (temp[next], x)); 1340 1341 offset_ld += next_amount; 1342 bytes -= next_amount; 1343 active[next] = true; 1344 } 1345 1346 if (active[phase]) 1347 { 1348 active[phase] = false; 1349 1350 x = adjust_address (dst_mem, mode[phase], offset_st); 1351 emit_insn (gen_rtx_SET (x, temp[phase])); 1352 1353 offset_st += amount[phase]; 1354 } 1355 } 1356 while (active[next]); 1357 1358 return 1; 1359} 1360 1361 1362void 1363xtensa_expand_nonlocal_goto (rtx *operands) 1364{ 1365 rtx goto_handler = operands[1]; 1366 rtx containing_fp = operands[3]; 1367 1368 /* Generate a call to "__xtensa_nonlocal_goto" (in libgcc); the code 1369 is too big to generate in-line. */ 1370 1371 if (GET_CODE (containing_fp) != REG) 1372 containing_fp = force_reg (Pmode, containing_fp); 1373 1374 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_nonlocal_goto"), 1375 LCT_NORMAL, VOIDmode, 1376 containing_fp, Pmode, 1377 goto_handler, Pmode); 1378} 1379 1380 1381static struct machine_function * 1382xtensa_init_machine_status (void) 1383{ 1384 return ggc_cleared_alloc<machine_function> (); 1385} 1386 1387 1388/* Shift VAL of mode MODE left by COUNT bits. */ 1389 1390static inline rtx 1391xtensa_expand_mask_and_shift (rtx val, machine_mode mode, rtx count) 1392{ 1393 val = expand_simple_binop (SImode, AND, val, GEN_INT (GET_MODE_MASK (mode)), 1394 NULL_RTX, 1, OPTAB_DIRECT); 1395 return expand_simple_binop (SImode, ASHIFT, val, count, 1396 NULL_RTX, 1, OPTAB_DIRECT); 1397} 1398 1399 1400/* Structure to hold the initial parameters for a compare_and_swap operation 1401 in HImode and QImode. */ 1402 1403struct alignment_context 1404{ 1405 rtx memsi; /* SI aligned memory location. */ 1406 rtx shift; /* Bit offset with regard to lsb. */ 1407 rtx modemask; /* Mask of the HQImode shifted by SHIFT bits. */ 1408 rtx modemaski; /* ~modemask */ 1409}; 1410 1411 1412/* Initialize structure AC for word access to HI and QI mode memory. */ 1413 1414static void 1415init_alignment_context (struct alignment_context *ac, rtx mem) 1416{ 1417 machine_mode mode = GET_MODE (mem); 1418 rtx byteoffset = NULL_RTX; 1419 bool aligned = (MEM_ALIGN (mem) >= GET_MODE_BITSIZE (SImode)); 1420 1421 if (aligned) 1422 ac->memsi = adjust_address (mem, SImode, 0); /* Memory is aligned. */ 1423 else 1424 { 1425 /* Alignment is unknown. */ 1426 rtx addr, align; 1427 1428 /* Force the address into a register. */ 1429 addr = force_reg (Pmode, XEXP (mem, 0)); 1430 1431 /* Align it to SImode. */ 1432 align = expand_simple_binop (Pmode, AND, addr, 1433 GEN_INT (-GET_MODE_SIZE (SImode)), 1434 NULL_RTX, 1, OPTAB_DIRECT); 1435 /* Generate MEM. */ 1436 ac->memsi = gen_rtx_MEM (SImode, align); 1437 MEM_VOLATILE_P (ac->memsi) = MEM_VOLATILE_P (mem); 1438 set_mem_alias_set (ac->memsi, ALIAS_SET_MEMORY_BARRIER); 1439 set_mem_align (ac->memsi, GET_MODE_BITSIZE (SImode)); 1440 1441 byteoffset = expand_simple_binop (Pmode, AND, addr, 1442 GEN_INT (GET_MODE_SIZE (SImode) - 1), 1443 NULL_RTX, 1, OPTAB_DIRECT); 1444 } 1445 1446 /* Calculate shiftcount. */ 1447 if (TARGET_BIG_ENDIAN) 1448 { 1449 ac->shift = GEN_INT (GET_MODE_SIZE (SImode) - GET_MODE_SIZE (mode)); 1450 if (!aligned) 1451 ac->shift = expand_simple_binop (SImode, MINUS, ac->shift, byteoffset, 1452 NULL_RTX, 1, OPTAB_DIRECT); 1453 } 1454 else 1455 { 1456 if (aligned) 1457 ac->shift = NULL_RTX; 1458 else 1459 ac->shift = byteoffset; 1460 } 1461 1462 if (ac->shift != NULL_RTX) 1463 { 1464 /* Shift is the byte count, but we need the bitcount. */ 1465 gcc_assert (exact_log2 (BITS_PER_UNIT) >= 0); 1466 ac->shift = expand_simple_binop (SImode, ASHIFT, ac->shift, 1467 GEN_INT (exact_log2 (BITS_PER_UNIT)), 1468 NULL_RTX, 1, OPTAB_DIRECT); 1469 ac->modemask = expand_simple_binop (SImode, ASHIFT, 1470 GEN_INT (GET_MODE_MASK (mode)), 1471 ac->shift, 1472 NULL_RTX, 1, OPTAB_DIRECT); 1473 } 1474 else 1475 ac->modemask = GEN_INT (GET_MODE_MASK (mode)); 1476 1477 ac->modemaski = expand_simple_unop (SImode, NOT, ac->modemask, NULL_RTX, 1); 1478} 1479 1480 1481/* Expand an atomic compare and swap operation for HImode and QImode. 1482 MEM is the memory location, CMP the old value to compare MEM with 1483 and NEW_RTX the value to set if CMP == MEM. */ 1484 1485void 1486xtensa_expand_compare_and_swap (rtx target, rtx mem, rtx cmp, rtx new_rtx) 1487{ 1488 machine_mode mode = GET_MODE (mem); 1489 struct alignment_context ac; 1490 rtx tmp, cmpv, newv, val; 1491 rtx oldval = gen_reg_rtx (SImode); 1492 rtx res = gen_reg_rtx (SImode); 1493 rtx_code_label *csloop = gen_label_rtx (); 1494 rtx_code_label *csend = gen_label_rtx (); 1495 1496 init_alignment_context (&ac, mem); 1497 1498 if (ac.shift != NULL_RTX) 1499 { 1500 cmp = xtensa_expand_mask_and_shift (cmp, mode, ac.shift); 1501 new_rtx = xtensa_expand_mask_and_shift (new_rtx, mode, ac.shift); 1502 } 1503 1504 /* Load the surrounding word into VAL with the MEM value masked out. */ 1505 val = force_reg (SImode, expand_simple_binop (SImode, AND, ac.memsi, 1506 ac.modemaski, NULL_RTX, 1, 1507 OPTAB_DIRECT)); 1508 emit_label (csloop); 1509 1510 /* Patch CMP and NEW_RTX into VAL at correct position. */ 1511 cmpv = force_reg (SImode, expand_simple_binop (SImode, IOR, cmp, val, 1512 NULL_RTX, 1, OPTAB_DIRECT)); 1513 newv = force_reg (SImode, expand_simple_binop (SImode, IOR, new_rtx, val, 1514 NULL_RTX, 1, OPTAB_DIRECT)); 1515 1516 /* Jump to end if we're done. */ 1517 emit_insn (gen_sync_compare_and_swapsi (res, ac.memsi, cmpv, newv)); 1518 emit_cmp_and_jump_insns (res, cmpv, EQ, const0_rtx, SImode, true, csend); 1519 1520 /* Check for changes outside mode. */ 1521 emit_move_insn (oldval, val); 1522 tmp = expand_simple_binop (SImode, AND, res, ac.modemaski, 1523 val, 1, OPTAB_DIRECT); 1524 if (tmp != val) 1525 emit_move_insn (val, tmp); 1526 1527 /* Loop internal if so. */ 1528 emit_cmp_and_jump_insns (oldval, val, NE, const0_rtx, SImode, true, csloop); 1529 1530 emit_label (csend); 1531 1532 /* Return the correct part of the bitfield. */ 1533 convert_move (target, 1534 (ac.shift == NULL_RTX ? res 1535 : expand_simple_binop (SImode, LSHIFTRT, res, ac.shift, 1536 NULL_RTX, 1, OPTAB_DIRECT)), 1537 1); 1538} 1539 1540 1541/* Expand an atomic operation CODE of mode MODE (either HImode or QImode -- 1542 the default expansion works fine for SImode). MEM is the memory location 1543 and VAL the value to play with. If AFTER is true then store the value 1544 MEM holds after the operation, if AFTER is false then store the value MEM 1545 holds before the operation. If TARGET is zero then discard that value, else 1546 store it to TARGET. */ 1547 1548void 1549xtensa_expand_atomic (enum rtx_code code, rtx target, rtx mem, rtx val, 1550 bool after) 1551{ 1552 machine_mode mode = GET_MODE (mem); 1553 struct alignment_context ac; 1554 rtx_code_label *csloop = gen_label_rtx (); 1555 rtx cmp, tmp; 1556 rtx old = gen_reg_rtx (SImode); 1557 rtx new_rtx = gen_reg_rtx (SImode); 1558 rtx orig = NULL_RTX; 1559 1560 init_alignment_context (&ac, mem); 1561 1562 /* Prepare values before the compare-and-swap loop. */ 1563 if (ac.shift != NULL_RTX) 1564 val = xtensa_expand_mask_and_shift (val, mode, ac.shift); 1565 switch (code) 1566 { 1567 case PLUS: 1568 case MINUS: 1569 orig = gen_reg_rtx (SImode); 1570 convert_move (orig, val, 1); 1571 break; 1572 1573 case SET: 1574 case IOR: 1575 case XOR: 1576 break; 1577 1578 case MULT: /* NAND */ 1579 case AND: 1580 /* val = "11..1<val>11..1" */ 1581 val = expand_simple_binop (SImode, XOR, val, ac.modemaski, 1582 NULL_RTX, 1, OPTAB_DIRECT); 1583 break; 1584 1585 default: 1586 gcc_unreachable (); 1587 } 1588 1589 /* Load full word. Subsequent loads are performed by S32C1I. */ 1590 cmp = force_reg (SImode, ac.memsi); 1591 1592 emit_label (csloop); 1593 emit_move_insn (old, cmp); 1594 1595 switch (code) 1596 { 1597 case PLUS: 1598 case MINUS: 1599 val = expand_simple_binop (SImode, code, old, orig, 1600 NULL_RTX, 1, OPTAB_DIRECT); 1601 val = expand_simple_binop (SImode, AND, val, ac.modemask, 1602 NULL_RTX, 1, OPTAB_DIRECT); 1603 /* FALLTHRU */ 1604 case SET: 1605 tmp = expand_simple_binop (SImode, AND, old, ac.modemaski, 1606 NULL_RTX, 1, OPTAB_DIRECT); 1607 tmp = expand_simple_binop (SImode, IOR, tmp, val, 1608 new_rtx, 1, OPTAB_DIRECT); 1609 break; 1610 1611 case AND: 1612 case IOR: 1613 case XOR: 1614 tmp = expand_simple_binop (SImode, code, old, val, 1615 new_rtx, 1, OPTAB_DIRECT); 1616 break; 1617 1618 case MULT: /* NAND */ 1619 tmp = expand_simple_binop (SImode, AND, old, val, 1620 NULL_RTX, 1, OPTAB_DIRECT); 1621 tmp = expand_simple_binop (SImode, XOR, tmp, ac.modemask, 1622 new_rtx, 1, OPTAB_DIRECT); 1623 break; 1624 1625 default: 1626 gcc_unreachable (); 1627 } 1628 1629 if (tmp != new_rtx) 1630 emit_move_insn (new_rtx, tmp); 1631 emit_insn (gen_sync_compare_and_swapsi (cmp, ac.memsi, old, new_rtx)); 1632 emit_cmp_and_jump_insns (cmp, old, NE, const0_rtx, SImode, true, csloop); 1633 1634 if (target) 1635 { 1636 tmp = (after ? new_rtx : cmp); 1637 convert_move (target, 1638 (ac.shift == NULL_RTX ? tmp 1639 : expand_simple_binop (SImode, LSHIFTRT, tmp, ac.shift, 1640 NULL_RTX, 1, OPTAB_DIRECT)), 1641 1); 1642 } 1643} 1644 1645 1646void 1647xtensa_setup_frame_addresses (void) 1648{ 1649 /* Set flag to cause TARGET_FRAME_POINTER_REQUIRED to return true. */ 1650 cfun->machine->accesses_prev_frame = 1; 1651 1652 if (TARGET_WINDOWED_ABI) 1653 emit_library_call 1654 (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_libgcc_window_spill"), 1655 LCT_NORMAL, VOIDmode); 1656} 1657 1658 1659/* Emit the assembly for the end of a zero-cost loop. Normally we just emit 1660 a comment showing where the end of the loop is. However, if there is a 1661 label or a branch at the end of the loop then we need to place a nop 1662 there. If the loop ends with a label we need the nop so that branches 1663 targeting that label will target the nop (and thus remain in the loop), 1664 instead of targeting the instruction after the loop (and thus exiting 1665 the loop). If the loop ends with a branch, we need the nop in case the 1666 branch is targeting a location inside the loop. When the branch 1667 executes it will cause the loop count to be decremented even if it is 1668 taken (because it is the last instruction in the loop), so we need to 1669 nop after the branch to prevent the loop count from being decremented 1670 when the branch is taken. */ 1671 1672void 1673xtensa_emit_loop_end (rtx_insn *insn, rtx *operands) 1674{ 1675 char done = 0; 1676 1677 for (insn = PREV_INSN (insn); insn && !done; insn = PREV_INSN (insn)) 1678 { 1679 switch (GET_CODE (insn)) 1680 { 1681 case NOTE: 1682 case BARRIER: 1683 break; 1684 1685 case CODE_LABEL: 1686 output_asm_insn (TARGET_DENSITY ? "nop.n" : "nop", operands); 1687 done = 1; 1688 break; 1689 1690 default: 1691 { 1692 rtx body = PATTERN (insn); 1693 1694 if (JUMP_P (body)) 1695 { 1696 output_asm_insn (TARGET_DENSITY ? "nop.n" : "nop", operands); 1697 done = 1; 1698 } 1699 else if ((GET_CODE (body) != USE) 1700 && (GET_CODE (body) != CLOBBER)) 1701 done = 1; 1702 } 1703 break; 1704 } 1705 } 1706 1707 output_asm_insn ("%1_LEND:", operands); 1708} 1709 1710 1711char * 1712xtensa_emit_branch (bool inverted, bool immed, rtx *operands) 1713{ 1714 static char result[64]; 1715 enum rtx_code code; 1716 const char *op; 1717 1718 code = GET_CODE (operands[3]); 1719 switch (code) 1720 { 1721 case EQ: op = inverted ? "ne" : "eq"; break; 1722 case NE: op = inverted ? "eq" : "ne"; break; 1723 case LT: op = inverted ? "ge" : "lt"; break; 1724 case GE: op = inverted ? "lt" : "ge"; break; 1725 case LTU: op = inverted ? "geu" : "ltu"; break; 1726 case GEU: op = inverted ? "ltu" : "geu"; break; 1727 default: gcc_unreachable (); 1728 } 1729 1730 if (immed) 1731 { 1732 if (INTVAL (operands[1]) == 0) 1733 sprintf (result, "b%sz%s\t%%0, %%2", op, 1734 (TARGET_DENSITY && (code == EQ || code == NE)) ? ".n" : ""); 1735 else 1736 sprintf (result, "b%si\t%%0, %%d1, %%2", op); 1737 } 1738 else 1739 sprintf (result, "b%s\t%%0, %%1, %%2", op); 1740 1741 return result; 1742} 1743 1744 1745char * 1746xtensa_emit_bit_branch (bool inverted, bool immed, rtx *operands) 1747{ 1748 static char result[64]; 1749 const char *op; 1750 1751 switch (GET_CODE (operands[3])) 1752 { 1753 case EQ: op = inverted ? "bs" : "bc"; break; 1754 case NE: op = inverted ? "bc" : "bs"; break; 1755 default: gcc_unreachable (); 1756 } 1757 1758 if (immed) 1759 { 1760 unsigned bitnum = INTVAL (operands[1]) & 0x1f; 1761 operands[1] = GEN_INT (bitnum); 1762 sprintf (result, "b%si\t%%0, %%d1, %%2", op); 1763 } 1764 else 1765 sprintf (result, "b%s\t%%0, %%1, %%2", op); 1766 1767 return result; 1768} 1769 1770 1771char * 1772xtensa_emit_movcc (bool inverted, bool isfp, bool isbool, rtx *operands) 1773{ 1774 static char result[64]; 1775 enum rtx_code code; 1776 const char *op; 1777 1778 code = GET_CODE (operands[4]); 1779 if (isbool) 1780 { 1781 switch (code) 1782 { 1783 case EQ: op = inverted ? "t" : "f"; break; 1784 case NE: op = inverted ? "f" : "t"; break; 1785 default: gcc_unreachable (); 1786 } 1787 } 1788 else 1789 { 1790 switch (code) 1791 { 1792 case EQ: op = inverted ? "nez" : "eqz"; break; 1793 case NE: op = inverted ? "eqz" : "nez"; break; 1794 case LT: op = inverted ? "gez" : "ltz"; break; 1795 case GE: op = inverted ? "ltz" : "gez"; break; 1796 default: gcc_unreachable (); 1797 } 1798 } 1799 1800 sprintf (result, "mov%s%s\t%%0, %%%d, %%1", 1801 op, isfp ? ".s" : "", inverted ? 3 : 2); 1802 return result; 1803} 1804 1805 1806char * 1807xtensa_emit_call (int callop, rtx *operands) 1808{ 1809 static char result[64]; 1810 rtx tgt = operands[callop]; 1811 1812 if (GET_CODE (tgt) == CONST_INT) 1813 sprintf (result, "call%d\t" HOST_WIDE_INT_PRINT_HEX, 1814 WINDOW_SIZE, INTVAL (tgt)); 1815 else if (register_operand (tgt, VOIDmode)) 1816 sprintf (result, "callx%d\t%%%d", WINDOW_SIZE, callop); 1817 else 1818 sprintf (result, "call%d\t%%%d", WINDOW_SIZE, callop); 1819 1820 return result; 1821} 1822 1823 1824bool 1825xtensa_legitimate_address_p (machine_mode mode, rtx addr, bool strict) 1826{ 1827 /* Allow constant pool addresses. */ 1828 if (mode != BLKmode && GET_MODE_SIZE (mode) >= UNITS_PER_WORD 1829 && ! TARGET_CONST16 && constantpool_address_p (addr) 1830 && ! xtensa_tls_referenced_p (addr)) 1831 return true; 1832 1833 while (GET_CODE (addr) == SUBREG) 1834 addr = SUBREG_REG (addr); 1835 1836 /* Allow base registers. */ 1837 if (GET_CODE (addr) == REG && BASE_REG_P (addr, strict)) 1838 return true; 1839 1840 /* Check for "register + offset" addressing. */ 1841 if (GET_CODE (addr) == PLUS) 1842 { 1843 rtx xplus0 = XEXP (addr, 0); 1844 rtx xplus1 = XEXP (addr, 1); 1845 enum rtx_code code0; 1846 enum rtx_code code1; 1847 1848 while (GET_CODE (xplus0) == SUBREG) 1849 xplus0 = SUBREG_REG (xplus0); 1850 code0 = GET_CODE (xplus0); 1851 1852 while (GET_CODE (xplus1) == SUBREG) 1853 xplus1 = SUBREG_REG (xplus1); 1854 code1 = GET_CODE (xplus1); 1855 1856 /* Swap operands if necessary so the register is first. */ 1857 if (code0 != REG && code1 == REG) 1858 { 1859 xplus0 = XEXP (addr, 1); 1860 xplus1 = XEXP (addr, 0); 1861 code0 = GET_CODE (xplus0); 1862 code1 = GET_CODE (xplus1); 1863 } 1864 1865 if (code0 == REG && BASE_REG_P (xplus0, strict) 1866 && code1 == CONST_INT 1867 && xtensa_mem_offset (INTVAL (xplus1), mode)) 1868 return true; 1869 } 1870 1871 return false; 1872} 1873 1874 1875/* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol. */ 1876 1877static GTY(()) rtx xtensa_tls_module_base_symbol; 1878 1879static rtx 1880xtensa_tls_module_base (void) 1881{ 1882 if (! xtensa_tls_module_base_symbol) 1883 { 1884 xtensa_tls_module_base_symbol = 1885 gen_rtx_SYMBOL_REF (Pmode, "_TLS_MODULE_BASE_"); 1886 SYMBOL_REF_FLAGS (xtensa_tls_module_base_symbol) 1887 |= TLS_MODEL_GLOBAL_DYNAMIC << SYMBOL_FLAG_TLS_SHIFT; 1888 } 1889 1890 return xtensa_tls_module_base_symbol; 1891} 1892 1893 1894static rtx_insn * 1895xtensa_call_tls_desc (rtx sym, rtx *retp) 1896{ 1897 rtx fn, arg, a_io; 1898 rtx_insn *call_insn, *insns; 1899 1900 start_sequence (); 1901 fn = gen_reg_rtx (Pmode); 1902 arg = gen_reg_rtx (Pmode); 1903 a_io = gen_rtx_REG (Pmode, WINDOW_SIZE + 2); 1904 1905 emit_insn (gen_tls_func (fn, sym)); 1906 emit_insn (gen_tls_arg (arg, sym)); 1907 emit_move_insn (a_io, arg); 1908 call_insn = emit_call_insn (gen_tls_call (a_io, fn, sym, const1_rtx)); 1909 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), a_io); 1910 insns = get_insns (); 1911 end_sequence (); 1912 1913 *retp = a_io; 1914 return insns; 1915} 1916 1917 1918static rtx 1919xtensa_legitimize_tls_address (rtx x) 1920{ 1921 unsigned int model = SYMBOL_REF_TLS_MODEL (x); 1922 rtx dest, tp, ret, modbase, base, addend; 1923 rtx_insn *insns; 1924 1925 dest = gen_reg_rtx (Pmode); 1926 switch (model) 1927 { 1928 case TLS_MODEL_GLOBAL_DYNAMIC: 1929 insns = xtensa_call_tls_desc (x, &ret); 1930 emit_libcall_block (insns, dest, ret, x); 1931 break; 1932 1933 case TLS_MODEL_LOCAL_DYNAMIC: 1934 base = gen_reg_rtx (Pmode); 1935 modbase = xtensa_tls_module_base (); 1936 insns = xtensa_call_tls_desc (modbase, &ret); 1937 emit_libcall_block (insns, base, ret, modbase); 1938 addend = force_reg (SImode, gen_sym_DTPOFF (x)); 1939 emit_insn (gen_addsi3 (dest, base, addend)); 1940 break; 1941 1942 case TLS_MODEL_INITIAL_EXEC: 1943 case TLS_MODEL_LOCAL_EXEC: 1944 tp = gen_reg_rtx (SImode); 1945 emit_insn (gen_get_thread_pointersi (tp)); 1946 addend = force_reg (SImode, gen_sym_TPOFF (x)); 1947 emit_insn (gen_addsi3 (dest, tp, addend)); 1948 break; 1949 1950 default: 1951 gcc_unreachable (); 1952 } 1953 1954 return dest; 1955} 1956 1957 1958rtx 1959xtensa_legitimize_address (rtx x, 1960 rtx oldx ATTRIBUTE_UNUSED, 1961 machine_mode mode) 1962{ 1963 if (xtensa_tls_symbol_p (x)) 1964 return xtensa_legitimize_tls_address (x); 1965 1966 if (GET_CODE (x) == PLUS) 1967 { 1968 rtx plus0 = XEXP (x, 0); 1969 rtx plus1 = XEXP (x, 1); 1970 1971 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG) 1972 { 1973 plus0 = XEXP (x, 1); 1974 plus1 = XEXP (x, 0); 1975 } 1976 1977 /* Try to split up the offset to use an ADDMI instruction. */ 1978 if (GET_CODE (plus0) == REG 1979 && GET_CODE (plus1) == CONST_INT 1980 && !xtensa_mem_offset (INTVAL (plus1), mode) 1981 && !xtensa_simm8 (INTVAL (plus1)) 1982 && xtensa_mem_offset (INTVAL (plus1) & 0xff, mode) 1983 && xtensa_simm8x256 (INTVAL (plus1) & ~0xff)) 1984 { 1985 rtx temp = gen_reg_rtx (Pmode); 1986 rtx addmi_offset = GEN_INT (INTVAL (plus1) & ~0xff); 1987 emit_insn (gen_rtx_SET (temp, gen_rtx_PLUS (Pmode, plus0, 1988 addmi_offset))); 1989 return gen_rtx_PLUS (Pmode, temp, GEN_INT (INTVAL (plus1) & 0xff)); 1990 } 1991 } 1992 1993 return x; 1994} 1995 1996/* Worker function for TARGET_MODE_DEPENDENT_ADDRESS_P. 1997 1998 Treat constant-pool references as "mode dependent" since they can 1999 only be accessed with SImode loads. This works around a bug in the 2000 combiner where a constant pool reference is temporarily converted 2001 to an HImode load, which is then assumed to zero-extend based on 2002 our definition of LOAD_EXTEND_OP. This is wrong because the high 2003 bits of a 16-bit value in the constant pool are now sign-extended 2004 by default. */ 2005 2006static bool 2007xtensa_mode_dependent_address_p (const_rtx addr, 2008 addr_space_t as ATTRIBUTE_UNUSED) 2009{ 2010 return constantpool_address_p (addr); 2011} 2012 2013/* Return TRUE if X contains any TLS symbol references. */ 2014 2015bool 2016xtensa_tls_referenced_p (rtx x) 2017{ 2018 if (! TARGET_HAVE_TLS) 2019 return false; 2020 2021 subrtx_iterator::array_type array; 2022 FOR_EACH_SUBRTX (iter, array, x, ALL) 2023 { 2024 const_rtx x = *iter; 2025 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x) != 0) 2026 return true; 2027 2028 /* Ignore TLS references that have already been legitimized. */ 2029 if (GET_CODE (x) == UNSPEC) 2030 switch (XINT (x, 1)) 2031 { 2032 case UNSPEC_TPOFF: 2033 case UNSPEC_DTPOFF: 2034 case UNSPEC_TLS_FUNC: 2035 case UNSPEC_TLS_ARG: 2036 case UNSPEC_TLS_CALL: 2037 iter.skip_subrtxes (); 2038 break; 2039 default: 2040 break; 2041 } 2042 } 2043 return false; 2044} 2045 2046 2047/* Implement TARGET_CANNOT_FORCE_CONST_MEM. */ 2048 2049static bool 2050xtensa_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x) 2051{ 2052 return xtensa_tls_referenced_p (x); 2053} 2054 2055 2056/* Return the debugger register number to use for 'regno'. */ 2057 2058int 2059xtensa_dbx_register_number (int regno) 2060{ 2061 int first = -1; 2062 2063 if (GP_REG_P (regno)) 2064 { 2065 regno -= GP_REG_FIRST; 2066 first = 0; 2067 } 2068 else if (BR_REG_P (regno)) 2069 { 2070 regno -= BR_REG_FIRST; 2071 first = 16; 2072 } 2073 else if (FP_REG_P (regno)) 2074 { 2075 regno -= FP_REG_FIRST; 2076 first = 48; 2077 } 2078 else if (ACC_REG_P (regno)) 2079 { 2080 first = 0x200; /* Start of Xtensa special registers. */ 2081 regno = 16; /* ACCLO is special register 16. */ 2082 } 2083 2084 /* When optimizing, we sometimes get asked about pseudo-registers 2085 that don't represent hard registers. Return 0 for these. */ 2086 if (first == -1) 2087 return 0; 2088 2089 return first + regno; 2090} 2091 2092 2093/* Argument support functions. */ 2094 2095/* Initialize CUMULATIVE_ARGS for a function. */ 2096 2097void 2098init_cumulative_args (CUMULATIVE_ARGS *cum, int incoming) 2099{ 2100 cum->arg_words = 0; 2101 cum->incoming = incoming; 2102} 2103 2104 2105/* Advance the argument to the next argument position. */ 2106 2107static void 2108xtensa_function_arg_advance (cumulative_args_t cum, 2109 const function_arg_info &arg) 2110{ 2111 int words, max; 2112 int *arg_words; 2113 2114 arg_words = &get_cumulative_args (cum)->arg_words; 2115 max = MAX_ARGS_IN_REGISTERS; 2116 2117 words = ((arg.promoted_size_in_bytes () + UNITS_PER_WORD - 1) 2118 / UNITS_PER_WORD); 2119 2120 if (*arg_words < max 2121 && (targetm.calls.must_pass_in_stack (arg) 2122 || *arg_words + words > max)) 2123 *arg_words = max; 2124 2125 *arg_words += words; 2126} 2127 2128 2129/* Return an RTL expression containing the register for the given argument, 2130 or 0 if the argument is to be passed on the stack. INCOMING_P is nonzero 2131 if this is an incoming argument to the current function. */ 2132 2133static rtx 2134xtensa_function_arg_1 (cumulative_args_t cum_v, const function_arg_info &arg, 2135 bool incoming_p) 2136{ 2137 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 2138 int regbase, words, max; 2139 int *arg_words; 2140 int regno; 2141 2142 arg_words = &cum->arg_words; 2143 regbase = (incoming_p ? GP_ARG_FIRST : GP_OUTGOING_ARG_FIRST); 2144 max = MAX_ARGS_IN_REGISTERS; 2145 2146 words = ((arg.promoted_size_in_bytes () + UNITS_PER_WORD - 1) 2147 / UNITS_PER_WORD); 2148 2149 if (arg.type && (TYPE_ALIGN (arg.type) > BITS_PER_WORD)) 2150 { 2151 int align = MIN (TYPE_ALIGN (arg.type), STACK_BOUNDARY) / BITS_PER_WORD; 2152 *arg_words = (*arg_words + align - 1) & -align; 2153 } 2154 2155 if (*arg_words + words > max) 2156 return (rtx)0; 2157 2158 regno = regbase + *arg_words; 2159 2160 if (cum->incoming && regno <= A7_REG && regno + words > A7_REG) 2161 cfun->machine->need_a7_copy = TARGET_WINDOWED_ABI; 2162 2163 return gen_rtx_REG (arg.mode, regno); 2164} 2165 2166/* Implement TARGET_FUNCTION_ARG. */ 2167 2168static rtx 2169xtensa_function_arg (cumulative_args_t cum, const function_arg_info &arg) 2170{ 2171 return xtensa_function_arg_1 (cum, arg, false); 2172} 2173 2174/* Implement TARGET_FUNCTION_INCOMING_ARG. */ 2175 2176static rtx 2177xtensa_function_incoming_arg (cumulative_args_t cum, 2178 const function_arg_info &arg) 2179{ 2180 return xtensa_function_arg_1 (cum, arg, true); 2181} 2182 2183static unsigned int 2184xtensa_function_arg_boundary (machine_mode mode, const_tree type) 2185{ 2186 unsigned int alignment; 2187 2188 alignment = type ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode); 2189 if (alignment < PARM_BOUNDARY) 2190 alignment = PARM_BOUNDARY; 2191 if (alignment > STACK_BOUNDARY) 2192 alignment = STACK_BOUNDARY; 2193 return alignment; 2194} 2195 2196 2197static bool 2198xtensa_return_in_msb (const_tree valtype) 2199{ 2200 return (TARGET_BIG_ENDIAN 2201 && AGGREGATE_TYPE_P (valtype) 2202 && int_size_in_bytes (valtype) >= UNITS_PER_WORD); 2203} 2204 2205 2206static void 2207xtensa_option_override (void) 2208{ 2209 int regno; 2210 machine_mode mode; 2211 2212 /* Use CONST16 in the absence of L32R. 2213 Set it in the TARGET_OPTION_OVERRIDE to avoid dependency on xtensa 2214 configuration in the xtensa-common.c */ 2215 2216 if (!TARGET_L32R) 2217 target_flags |= MASK_CONST16; 2218 2219 if (!TARGET_BOOLEANS && TARGET_HARD_FLOAT) 2220 error ("boolean registers required for the floating-point option"); 2221 2222 /* Set up array giving whether a given register can hold a given mode. */ 2223 for (mode = VOIDmode; 2224 mode != MAX_MACHINE_MODE; 2225 mode = (machine_mode) ((int) mode + 1)) 2226 { 2227 int size = GET_MODE_SIZE (mode); 2228 enum mode_class mclass = GET_MODE_CLASS (mode); 2229 2230 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 2231 { 2232 int temp; 2233 2234 if (ACC_REG_P (regno)) 2235 temp = (TARGET_MAC16 2236 && (mclass == MODE_INT) && (size <= UNITS_PER_WORD)); 2237 else if (GP_REG_P (regno)) 2238 temp = ((regno & 1) == 0 || (size <= UNITS_PER_WORD)); 2239 else if (FP_REG_P (regno)) 2240 temp = (TARGET_HARD_FLOAT && (mode == SFmode)); 2241 else if (BR_REG_P (regno)) 2242 temp = (TARGET_BOOLEANS && (mode == CCmode)); 2243 else 2244 temp = FALSE; 2245 2246 xtensa_hard_regno_mode_ok_p[(int) mode][regno] = temp; 2247 } 2248 } 2249 2250 init_machine_status = xtensa_init_machine_status; 2251 2252 /* Check PIC settings. PIC is only supported when using L32R 2253 instructions, and some targets need to always use PIC. */ 2254 if (flag_pic && TARGET_CONST16) 2255 error ("%<-f%s%> is not supported with CONST16 instructions", 2256 (flag_pic > 1 ? "PIC" : "pic")); 2257 else if (TARGET_FORCE_NO_PIC) 2258 flag_pic = 0; 2259 else if (XTENSA_ALWAYS_PIC) 2260 { 2261 if (TARGET_CONST16) 2262 error ("PIC is required but not supported with CONST16 instructions"); 2263 flag_pic = 1; 2264 } 2265 /* There's no need for -fPIC (as opposed to -fpic) on Xtensa. */ 2266 if (flag_pic > 1) 2267 flag_pic = 1; 2268 if (flag_pic && !flag_pie) 2269 flag_shlib = 1; 2270 2271 /* Hot/cold partitioning does not work on this architecture, because of 2272 constant pools (the load instruction cannot necessarily reach that far). 2273 Therefore disable it on this architecture. */ 2274 if (flag_reorder_blocks_and_partition) 2275 { 2276 flag_reorder_blocks_and_partition = 0; 2277 flag_reorder_blocks = 1; 2278 } 2279} 2280 2281/* Implement TARGET_HARD_REGNO_NREGS. */ 2282 2283static unsigned int 2284xtensa_hard_regno_nregs (unsigned int regno, machine_mode mode) 2285{ 2286 if (FP_REG_P (regno)) 2287 return CEIL (GET_MODE_SIZE (mode), UNITS_PER_FPREG); 2288 return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD); 2289} 2290 2291/* Implement TARGET_HARD_REGNO_MODE_OK. */ 2292 2293static bool 2294xtensa_hard_regno_mode_ok (unsigned int regno, machine_mode mode) 2295{ 2296 return xtensa_hard_regno_mode_ok_p[mode][regno]; 2297} 2298 2299/* Implement TARGET_MODES_TIEABLE_P. */ 2300 2301static bool 2302xtensa_modes_tieable_p (machine_mode mode1, machine_mode mode2) 2303{ 2304 return ((GET_MODE_CLASS (mode1) == MODE_FLOAT 2305 || GET_MODE_CLASS (mode1) == MODE_COMPLEX_FLOAT) 2306 == (GET_MODE_CLASS (mode2) == MODE_FLOAT 2307 || GET_MODE_CLASS (mode2) == MODE_COMPLEX_FLOAT)); 2308} 2309 2310/* A C compound statement to output to stdio stream STREAM the 2311 assembler syntax for an instruction operand X. X is an RTL 2312 expression. 2313 2314 CODE is a value that can be used to specify one of several ways 2315 of printing the operand. It is used when identical operands 2316 must be printed differently depending on the context. CODE 2317 comes from the '%' specification that was used to request 2318 printing of the operand. If the specification was just '%DIGIT' 2319 then CODE is 0; if the specification was '%LTR DIGIT' then CODE 2320 is the ASCII code for LTR. 2321 2322 If X is a register, this macro should print the register's name. 2323 The names can be found in an array 'reg_names' whose type is 2324 'char *[]'. 'reg_names' is initialized from 'REGISTER_NAMES'. 2325 2326 When the machine description has a specification '%PUNCT' (a '%' 2327 followed by a punctuation character), this macro is called with 2328 a null pointer for X and the punctuation character for CODE. 2329 2330 'a', 'c', 'l', and 'n' are reserved. 2331 2332 The Xtensa specific codes are: 2333 2334 'd' CONST_INT, print as signed decimal 2335 'x' CONST_INT, print as signed hexadecimal 2336 'K' CONST_INT, print number of bits in mask for EXTUI 2337 'R' CONST_INT, print (X & 0x1f) 2338 'L' CONST_INT, print ((32 - X) & 0x1f) 2339 'D' REG, print second register of double-word register operand 2340 'N' MEM, print address of next word following a memory operand 2341 'v' MEM, if memory reference is volatile, output a MEMW before it 2342 't' any constant, add "@h" suffix for top 16 bits 2343 'b' any constant, add "@l" suffix for bottom 16 bits 2344*/ 2345 2346static void 2347printx (FILE *file, signed int val) 2348{ 2349 /* Print a hexadecimal value in a nice way. */ 2350 if ((val > -0xa) && (val < 0xa)) 2351 fprintf (file, "%d", val); 2352 else if (val < 0) 2353 fprintf (file, "-0x%x", -val); 2354 else 2355 fprintf (file, "0x%x", val); 2356} 2357 2358 2359void 2360print_operand (FILE *file, rtx x, int letter) 2361{ 2362 if (!x) 2363 error ("PRINT_OPERAND null pointer"); 2364 2365 switch (letter) 2366 { 2367 case 'D': 2368 if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG) 2369 fprintf (file, "%s", reg_names[xt_true_regnum (x) + 1]); 2370 else 2371 output_operand_lossage ("invalid %%D value"); 2372 break; 2373 2374 case 'v': 2375 if (GET_CODE (x) == MEM) 2376 { 2377 /* For a volatile memory reference, emit a MEMW before the 2378 load or store. */ 2379 if (MEM_VOLATILE_P (x) && TARGET_SERIALIZE_VOLATILE) 2380 fprintf (file, "memw\n\t"); 2381 } 2382 else 2383 output_operand_lossage ("invalid %%v value"); 2384 break; 2385 2386 case 'N': 2387 if (GET_CODE (x) == MEM 2388 && (GET_MODE (x) == DFmode || GET_MODE (x) == DImode)) 2389 { 2390 x = adjust_address (x, GET_MODE (x) == DFmode ? E_SFmode : E_SImode, 2391 4); 2392 output_address (GET_MODE (x), XEXP (x, 0)); 2393 } 2394 else 2395 output_operand_lossage ("invalid %%N value"); 2396 break; 2397 2398 case 'K': 2399 if (GET_CODE (x) == CONST_INT) 2400 { 2401 int num_bits = 0; 2402 unsigned val = INTVAL (x); 2403 while (val & 1) 2404 { 2405 num_bits += 1; 2406 val = val >> 1; 2407 } 2408 if ((val != 0) || (num_bits == 0) || (num_bits > 16)) 2409 fatal_insn ("invalid mask", x); 2410 2411 fprintf (file, "%d", num_bits); 2412 } 2413 else 2414 output_operand_lossage ("invalid %%K value"); 2415 break; 2416 2417 case 'L': 2418 if (GET_CODE (x) == CONST_INT) 2419 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INTVAL (x)) & 0x1f); 2420 else 2421 output_operand_lossage ("invalid %%L value"); 2422 break; 2423 2424 case 'R': 2425 if (GET_CODE (x) == CONST_INT) 2426 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0x1f); 2427 else 2428 output_operand_lossage ("invalid %%R value"); 2429 break; 2430 2431 case 'x': 2432 if (GET_CODE (x) == CONST_INT) 2433 printx (file, INTVAL (x)); 2434 else 2435 output_operand_lossage ("invalid %%x value"); 2436 break; 2437 2438 case 'd': 2439 if (GET_CODE (x) == CONST_INT) 2440 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x)); 2441 else 2442 output_operand_lossage ("invalid %%d value"); 2443 break; 2444 2445 case 't': 2446 case 'b': 2447 if (GET_CODE (x) == CONST_INT) 2448 { 2449 printx (file, INTVAL (x)); 2450 fputs (letter == 't' ? "@h" : "@l", file); 2451 } 2452 else if (GET_CODE (x) == CONST_DOUBLE) 2453 { 2454 if (GET_MODE (x) == SFmode) 2455 { 2456 long l; 2457 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l); 2458 fprintf (file, "0x%08lx@%c", l, letter == 't' ? 'h' : 'l'); 2459 } 2460 else 2461 output_operand_lossage ("invalid %%t/%%b value"); 2462 } 2463 else if (GET_CODE (x) == CONST) 2464 { 2465 /* X must be a symbolic constant on ELF. Write an expression 2466 suitable for 'const16' that sets the high or low 16 bits. */ 2467 if (GET_CODE (XEXP (x, 0)) != PLUS 2468 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF 2469 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF) 2470 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT) 2471 output_operand_lossage ("invalid %%t/%%b value"); 2472 print_operand (file, XEXP (XEXP (x, 0), 0), 0); 2473 fputs (letter == 't' ? "@h" : "@l", file); 2474 /* There must be a non-alphanumeric character between 'h' or 'l' 2475 and the number. The '-' is added by print_operand() already. */ 2476 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0) 2477 fputs ("+", file); 2478 print_operand (file, XEXP (XEXP (x, 0), 1), 0); 2479 } 2480 else 2481 { 2482 output_addr_const (file, x); 2483 fputs (letter == 't' ? "@h" : "@l", file); 2484 } 2485 break; 2486 2487 case 'y': 2488 if (GET_CODE (x) == CONST_DOUBLE && 2489 GET_MODE (x) == SFmode) 2490 { 2491 long l; 2492 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l); 2493 fprintf (file, "0x%08lx", l); 2494 break; 2495 } 2496 2497 /* fall through */ 2498 2499 default: 2500 if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG) 2501 fprintf (file, "%s", reg_names[xt_true_regnum (x)]); 2502 else if (GET_CODE (x) == MEM) 2503 output_address (GET_MODE (x), XEXP (x, 0)); 2504 else if (GET_CODE (x) == CONST_INT) 2505 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x)); 2506 else 2507 output_addr_const (file, x); 2508 } 2509} 2510 2511 2512/* A C compound statement to output to stdio stream STREAM the 2513 assembler syntax for an instruction operand that is a memory 2514 reference whose address is ADDR. ADDR is an RTL expression. */ 2515 2516void 2517print_operand_address (FILE *file, rtx addr) 2518{ 2519 if (!addr) 2520 error ("PRINT_OPERAND_ADDRESS, null pointer"); 2521 2522 switch (GET_CODE (addr)) 2523 { 2524 default: 2525 fatal_insn ("invalid address", addr); 2526 break; 2527 2528 case REG: 2529 fprintf (file, "%s, 0", reg_names [REGNO (addr)]); 2530 break; 2531 2532 case PLUS: 2533 { 2534 rtx reg = (rtx)0; 2535 rtx offset = (rtx)0; 2536 rtx arg0 = XEXP (addr, 0); 2537 rtx arg1 = XEXP (addr, 1); 2538 2539 if (GET_CODE (arg0) == REG) 2540 { 2541 reg = arg0; 2542 offset = arg1; 2543 } 2544 else if (GET_CODE (arg1) == REG) 2545 { 2546 reg = arg1; 2547 offset = arg0; 2548 } 2549 else 2550 fatal_insn ("no register in address", addr); 2551 2552 if (CONSTANT_P (offset)) 2553 { 2554 fprintf (file, "%s, ", reg_names [REGNO (reg)]); 2555 output_addr_const (file, offset); 2556 } 2557 else 2558 fatal_insn ("address offset not a constant", addr); 2559 } 2560 break; 2561 2562 case LABEL_REF: 2563 case SYMBOL_REF: 2564 case CONST_INT: 2565 case CONST: 2566 output_addr_const (file, addr); 2567 break; 2568 } 2569} 2570 2571/* Implement TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */ 2572 2573static bool 2574xtensa_output_addr_const_extra (FILE *fp, rtx x) 2575{ 2576 if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 1) 2577 { 2578 switch (XINT (x, 1)) 2579 { 2580 case UNSPEC_TPOFF: 2581 output_addr_const (fp, XVECEXP (x, 0, 0)); 2582 fputs ("@TPOFF", fp); 2583 return true; 2584 case UNSPEC_DTPOFF: 2585 output_addr_const (fp, XVECEXP (x, 0, 0)); 2586 fputs ("@DTPOFF", fp); 2587 return true; 2588 case UNSPEC_PLT: 2589 if (flag_pic) 2590 { 2591 output_addr_const (fp, XVECEXP (x, 0, 0)); 2592 fputs ("@PLT", fp); 2593 return true; 2594 } 2595 break; 2596 default: 2597 break; 2598 } 2599 } 2600 return false; 2601} 2602 2603static void 2604xtensa_output_integer_literal_parts (FILE *file, rtx x, int size) 2605{ 2606 if (size > 4 && !(size & (size - 1))) 2607 { 2608 rtx first, second; 2609 2610 split_double (x, &first, &second); 2611 xtensa_output_integer_literal_parts (file, first, size / 2); 2612 fputs (", ", file); 2613 xtensa_output_integer_literal_parts (file, second, size / 2); 2614 } 2615 else if (size == 4) 2616 { 2617 output_addr_const (file, x); 2618 } 2619 else 2620 { 2621 gcc_unreachable(); 2622 } 2623} 2624 2625void 2626xtensa_output_literal (FILE *file, rtx x, machine_mode mode, int labelno) 2627{ 2628 long value_long[2]; 2629 2630 fprintf (file, "\t.literal .LC%u, ", (unsigned) labelno); 2631 2632 switch (GET_MODE_CLASS (mode)) 2633 { 2634 case MODE_FLOAT: 2635 gcc_assert (GET_CODE (x) == CONST_DOUBLE); 2636 2637 switch (mode) 2638 { 2639 case E_SFmode: 2640 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), 2641 value_long[0]); 2642 if (HOST_BITS_PER_LONG > 32) 2643 value_long[0] &= 0xffffffff; 2644 fprintf (file, "0x%08lx\n", value_long[0]); 2645 break; 2646 2647 case E_DFmode: 2648 REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x), 2649 value_long); 2650 if (HOST_BITS_PER_LONG > 32) 2651 { 2652 value_long[0] &= 0xffffffff; 2653 value_long[1] &= 0xffffffff; 2654 } 2655 fprintf (file, "0x%08lx, 0x%08lx\n", 2656 value_long[0], value_long[1]); 2657 break; 2658 2659 default: 2660 gcc_unreachable (); 2661 } 2662 2663 break; 2664 2665 case MODE_INT: 2666 case MODE_PARTIAL_INT: 2667 xtensa_output_integer_literal_parts (file, x, GET_MODE_SIZE (mode)); 2668 fputs ("\n", file); 2669 break; 2670 2671 default: 2672 gcc_unreachable (); 2673 } 2674} 2675 2676static bool 2677xtensa_call_save_reg(int regno) 2678{ 2679 if (TARGET_WINDOWED_ABI) 2680 return false; 2681 2682 if (regno == A0_REG) 2683 return crtl->profile || !crtl->is_leaf || crtl->calls_eh_return || 2684 df_regs_ever_live_p (regno); 2685 2686 if (crtl->calls_eh_return && regno >= 2 && regno < 4) 2687 return true; 2688 2689 return !call_used_or_fixed_reg_p (regno) && df_regs_ever_live_p (regno); 2690} 2691 2692/* Return the bytes needed to compute the frame pointer from the current 2693 stack pointer. */ 2694 2695#define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT) 2696#define XTENSA_STACK_ALIGN(LOC) (((LOC) + STACK_BYTES-1) & ~(STACK_BYTES-1)) 2697 2698long 2699compute_frame_size (poly_int64 size) 2700{ 2701 int regno; 2702 2703 if (reload_completed && cfun->machine->frame_laid_out) 2704 return cfun->machine->current_frame_size; 2705 2706 /* Add space for the incoming static chain value. */ 2707 if (cfun->static_chain_decl != NULL) 2708 size += (1 * UNITS_PER_WORD); 2709 2710 cfun->machine->callee_save_size = 0; 2711 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno) 2712 { 2713 if (xtensa_call_save_reg(regno)) 2714 cfun->machine->callee_save_size += UNITS_PER_WORD; 2715 } 2716 2717 cfun->machine->current_frame_size = 2718 XTENSA_STACK_ALIGN (size 2719 + cfun->machine->callee_save_size 2720 + crtl->outgoing_args_size 2721 + (WINDOW_SIZE * UNITS_PER_WORD)); 2722 cfun->machine->callee_save_size = 2723 XTENSA_STACK_ALIGN (cfun->machine->callee_save_size); 2724 cfun->machine->frame_laid_out = true; 2725 return cfun->machine->current_frame_size; 2726} 2727 2728 2729bool 2730xtensa_frame_pointer_required (void) 2731{ 2732 /* The code to expand builtin_frame_addr and builtin_return_addr 2733 currently uses the hard_frame_pointer instead of frame_pointer. 2734 This seems wrong but maybe it's necessary for other architectures. 2735 This function is derived from the i386 code. */ 2736 2737 if (cfun->machine->accesses_prev_frame || cfun->has_nonlocal_label) 2738 return true; 2739 2740 return false; 2741} 2742 2743HOST_WIDE_INT 2744xtensa_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED) 2745{ 2746 long frame_size = compute_frame_size (get_frame_size ()); 2747 HOST_WIDE_INT offset; 2748 2749 switch (from) 2750 { 2751 case FRAME_POINTER_REGNUM: 2752 if (FRAME_GROWS_DOWNWARD) 2753 offset = frame_size - (WINDOW_SIZE * UNITS_PER_WORD) 2754 - cfun->machine->callee_save_size; 2755 else 2756 offset = 0; 2757 break; 2758 case ARG_POINTER_REGNUM: 2759 offset = frame_size; 2760 break; 2761 default: 2762 gcc_unreachable (); 2763 } 2764 2765 return offset; 2766} 2767 2768/* minimum frame = reg save area (4 words) plus static chain (1 word) 2769 and the total number of words must be a multiple of 128 bits. */ 2770#define MIN_FRAME_SIZE (8 * UNITS_PER_WORD) 2771 2772void 2773xtensa_expand_prologue (void) 2774{ 2775 HOST_WIDE_INT total_size; 2776 rtx_insn *insn = NULL; 2777 rtx note_rtx; 2778 2779 2780 total_size = compute_frame_size (get_frame_size ()); 2781 2782 if (flag_stack_usage_info) 2783 current_function_static_stack_size = total_size; 2784 2785 if (TARGET_WINDOWED_ABI) 2786 { 2787 if (total_size < (1 << (12+3))) 2788 insn = emit_insn (gen_entry (GEN_INT (total_size))); 2789 else 2790 { 2791 /* Use a8 as a temporary since a0-a7 may be live. */ 2792 rtx tmp_reg = gen_rtx_REG (Pmode, A8_REG); 2793 emit_insn (gen_entry (GEN_INT (MIN_FRAME_SIZE))); 2794 emit_move_insn (tmp_reg, GEN_INT (total_size - MIN_FRAME_SIZE)); 2795 emit_insn (gen_subsi3 (tmp_reg, stack_pointer_rtx, tmp_reg)); 2796 insn = emit_insn (gen_movsi (stack_pointer_rtx, tmp_reg)); 2797 } 2798 } 2799 else 2800 { 2801 int regno; 2802 HOST_WIDE_INT offset = 0; 2803 int callee_save_size = cfun->machine->callee_save_size; 2804 2805 /* -128 is a limit of single addi instruction. */ 2806 if (total_size > 0 && total_size <= 128) 2807 { 2808 insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, 2809 GEN_INT (-total_size))); 2810 RTX_FRAME_RELATED_P (insn) = 1; 2811 note_rtx = gen_rtx_SET (stack_pointer_rtx, 2812 plus_constant (Pmode, stack_pointer_rtx, 2813 -total_size)); 2814 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx); 2815 offset = total_size - UNITS_PER_WORD; 2816 } 2817 else if (callee_save_size) 2818 { 2819 /* 1020 is maximal s32i offset, if the frame is bigger than that 2820 * we move sp to the end of callee-saved save area, save and then 2821 * move it to its final location. */ 2822 if (total_size > 1024) 2823 { 2824 insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, 2825 GEN_INT (-callee_save_size))); 2826 RTX_FRAME_RELATED_P (insn) = 1; 2827 note_rtx = gen_rtx_SET (stack_pointer_rtx, 2828 plus_constant (Pmode, stack_pointer_rtx, 2829 -callee_save_size)); 2830 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx); 2831 offset = callee_save_size - UNITS_PER_WORD; 2832 } 2833 else 2834 { 2835 rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG); 2836 emit_move_insn (tmp_reg, GEN_INT (total_size)); 2837 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, 2838 stack_pointer_rtx, tmp_reg)); 2839 RTX_FRAME_RELATED_P (insn) = 1; 2840 note_rtx = gen_rtx_SET (stack_pointer_rtx, 2841 plus_constant (Pmode, stack_pointer_rtx, 2842 -total_size)); 2843 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx); 2844 offset = total_size - UNITS_PER_WORD; 2845 } 2846 } 2847 2848 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno) 2849 { 2850 if (xtensa_call_save_reg(regno)) 2851 { 2852 rtx x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset)); 2853 rtx mem = gen_frame_mem (SImode, x); 2854 rtx reg = gen_rtx_REG (SImode, regno); 2855 2856 offset -= UNITS_PER_WORD; 2857 insn = emit_move_insn (mem, reg); 2858 RTX_FRAME_RELATED_P (insn) = 1; 2859 add_reg_note (insn, REG_FRAME_RELATED_EXPR, 2860 gen_rtx_SET (mem, reg)); 2861 } 2862 } 2863 if (total_size > 1024 2864 || (!callee_save_size && total_size > 128)) 2865 { 2866 rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG); 2867 emit_move_insn (tmp_reg, GEN_INT (total_size - 2868 callee_save_size)); 2869 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, 2870 stack_pointer_rtx, tmp_reg)); 2871 RTX_FRAME_RELATED_P (insn) = 1; 2872 note_rtx = gen_rtx_SET (stack_pointer_rtx, 2873 plus_constant (Pmode, stack_pointer_rtx, 2874 callee_save_size - 2875 total_size)); 2876 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx); 2877 } 2878 } 2879 2880 if (frame_pointer_needed) 2881 { 2882 if (cfun->machine->set_frame_ptr_insn) 2883 { 2884 rtx_insn *first; 2885 2886 push_topmost_sequence (); 2887 first = get_insns (); 2888 pop_topmost_sequence (); 2889 2890 /* For all instructions prior to set_frame_ptr_insn, replace 2891 hard_frame_pointer references with stack_pointer. */ 2892 for (insn = first; 2893 insn != cfun->machine->set_frame_ptr_insn; 2894 insn = NEXT_INSN (insn)) 2895 { 2896 if (INSN_P (insn)) 2897 { 2898 PATTERN (insn) = replace_rtx (copy_rtx (PATTERN (insn)), 2899 hard_frame_pointer_rtx, 2900 stack_pointer_rtx); 2901 df_insn_rescan (insn); 2902 } 2903 } 2904 } 2905 else 2906 { 2907 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx, 2908 stack_pointer_rtx)); 2909 if (!TARGET_WINDOWED_ABI) 2910 { 2911 note_rtx = gen_rtx_SET (hard_frame_pointer_rtx, 2912 stack_pointer_rtx); 2913 RTX_FRAME_RELATED_P (insn) = 1; 2914 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx); 2915 } 2916 } 2917 } 2918 2919 if (TARGET_WINDOWED_ABI) 2920 { 2921 /* Create a note to describe the CFA. Because this is only used to set 2922 DW_AT_frame_base for debug info, don't bother tracking changes through 2923 each instruction in the prologue. It just takes up space. */ 2924 note_rtx = gen_rtx_SET ((frame_pointer_needed 2925 ? hard_frame_pointer_rtx 2926 : stack_pointer_rtx), 2927 plus_constant (Pmode, stack_pointer_rtx, 2928 -total_size)); 2929 RTX_FRAME_RELATED_P (insn) = 1; 2930 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx); 2931 } 2932} 2933 2934void 2935xtensa_expand_epilogue (void) 2936{ 2937 if (!TARGET_WINDOWED_ABI) 2938 { 2939 int regno; 2940 HOST_WIDE_INT offset; 2941 2942 if (cfun->machine->current_frame_size > (frame_pointer_needed ? 127 : 1024)) 2943 { 2944 rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG); 2945 emit_move_insn (tmp_reg, GEN_INT (cfun->machine->current_frame_size - 2946 cfun->machine->callee_save_size)); 2947 emit_insn (gen_addsi3 (stack_pointer_rtx, frame_pointer_needed ? 2948 hard_frame_pointer_rtx : stack_pointer_rtx, 2949 tmp_reg)); 2950 offset = cfun->machine->callee_save_size - UNITS_PER_WORD; 2951 } 2952 else 2953 { 2954 if (frame_pointer_needed) 2955 emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx); 2956 offset = cfun->machine->current_frame_size - UNITS_PER_WORD; 2957 } 2958 2959 /* Prevent reordering of saved a0 update and loading it back from 2960 the save area. */ 2961 if (crtl->calls_eh_return) 2962 emit_insn (gen_blockage ()); 2963 2964 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno) 2965 { 2966 if (xtensa_call_save_reg(regno)) 2967 { 2968 rtx x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset)); 2969 2970 offset -= UNITS_PER_WORD; 2971 emit_move_insn (gen_rtx_REG (SImode, regno), 2972 gen_frame_mem (SImode, x)); 2973 } 2974 } 2975 2976 if (cfun->machine->current_frame_size > 0) 2977 { 2978 if (frame_pointer_needed || /* always reachable with addi */ 2979 cfun->machine->current_frame_size > 1024 || 2980 cfun->machine->current_frame_size <= 127) 2981 { 2982 if (cfun->machine->current_frame_size <= 127) 2983 offset = cfun->machine->current_frame_size; 2984 else 2985 offset = cfun->machine->callee_save_size; 2986 2987 emit_insn (gen_addsi3 (stack_pointer_rtx, 2988 stack_pointer_rtx, 2989 GEN_INT (offset))); 2990 } 2991 else 2992 { 2993 rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG); 2994 emit_move_insn (tmp_reg, 2995 GEN_INT (cfun->machine->current_frame_size)); 2996 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, 2997 tmp_reg)); 2998 } 2999 } 3000 3001 if (crtl->calls_eh_return) 3002 emit_insn (gen_add3_insn (stack_pointer_rtx, 3003 stack_pointer_rtx, 3004 EH_RETURN_STACKADJ_RTX)); 3005 } 3006 cfun->machine->epilogue_done = true; 3007 emit_jump_insn (gen_return ()); 3008} 3009 3010bool 3011xtensa_use_return_instruction_p (void) 3012{ 3013 if (!reload_completed) 3014 return false; 3015 if (TARGET_WINDOWED_ABI) 3016 return true; 3017 if (compute_frame_size (get_frame_size ()) == 0) 3018 return true; 3019 return cfun->machine->epilogue_done; 3020} 3021 3022void 3023xtensa_set_return_address (rtx address, rtx scratch) 3024{ 3025 HOST_WIDE_INT total_size = compute_frame_size (get_frame_size ()); 3026 rtx frame = frame_pointer_needed ? 3027 hard_frame_pointer_rtx : stack_pointer_rtx; 3028 rtx a0_addr = plus_constant (Pmode, frame, 3029 total_size - UNITS_PER_WORD); 3030 rtx note = gen_rtx_SET (gen_frame_mem (SImode, a0_addr), 3031 gen_rtx_REG (SImode, A0_REG)); 3032 rtx insn; 3033 3034 if (total_size > 1024) { 3035 emit_move_insn (scratch, GEN_INT (total_size - UNITS_PER_WORD)); 3036 emit_insn (gen_addsi3 (scratch, frame, scratch)); 3037 a0_addr = scratch; 3038 } 3039 3040 insn = emit_move_insn (gen_frame_mem (SImode, a0_addr), address); 3041 RTX_FRAME_RELATED_P (insn) = 1; 3042 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note); 3043} 3044 3045rtx 3046xtensa_return_addr (int count, rtx frame) 3047{ 3048 rtx result, retaddr, curaddr, label; 3049 3050 if (!TARGET_WINDOWED_ABI) 3051 { 3052 if (count != 0) 3053 return const0_rtx; 3054 3055 return get_hard_reg_initial_val (Pmode, A0_REG); 3056 } 3057 3058 if (count == -1) 3059 retaddr = gen_rtx_REG (Pmode, A0_REG); 3060 else 3061 { 3062 rtx addr = plus_constant (Pmode, frame, -4 * UNITS_PER_WORD); 3063 addr = memory_address (Pmode, addr); 3064 retaddr = gen_reg_rtx (Pmode); 3065 emit_move_insn (retaddr, gen_rtx_MEM (Pmode, addr)); 3066 } 3067 3068 /* The 2 most-significant bits of the return address on Xtensa hold 3069 the register window size. To get the real return address, these 3070 bits must be replaced with the high bits from some address in the 3071 code. */ 3072 3073 /* Get the 2 high bits of a local label in the code. */ 3074 curaddr = gen_reg_rtx (Pmode); 3075 label = gen_label_rtx (); 3076 emit_label (label); 3077 LABEL_PRESERVE_P (label) = 1; 3078 emit_move_insn (curaddr, gen_rtx_LABEL_REF (Pmode, label)); 3079 emit_insn (gen_lshrsi3 (curaddr, curaddr, GEN_INT (30))); 3080 emit_insn (gen_ashlsi3 (curaddr, curaddr, GEN_INT (30))); 3081 3082 /* Clear the 2 high bits of the return address. */ 3083 result = gen_reg_rtx (Pmode); 3084 emit_insn (gen_ashlsi3 (result, retaddr, GEN_INT (2))); 3085 emit_insn (gen_lshrsi3 (result, result, GEN_INT (2))); 3086 3087 /* Combine them to get the result. */ 3088 emit_insn (gen_iorsi3 (result, result, curaddr)); 3089 return result; 3090} 3091 3092/* Disable the use of word-sized or smaller complex modes for structures, 3093 and for function arguments in particular, where they cause problems with 3094 register a7. The xtensa_copy_incoming_a7 function assumes that there is 3095 a single reference to an argument in a7, but with small complex modes the 3096 real and imaginary components may be extracted separately, leading to two 3097 uses of the register, only one of which would be replaced. */ 3098 3099static bool 3100xtensa_member_type_forces_blk (const_tree, machine_mode mode) 3101{ 3102 return mode == CQImode || mode == CHImode; 3103} 3104 3105/* Create the va_list data type. 3106 3107 This structure is set up by __builtin_saveregs. The __va_reg field 3108 points to a stack-allocated region holding the contents of the 3109 incoming argument registers. The __va_ndx field is an index 3110 initialized to the position of the first unnamed (variable) 3111 argument. This same index is also used to address the arguments 3112 passed in memory. Thus, the __va_stk field is initialized to point 3113 to the position of the first argument in memory offset to account 3114 for the arguments passed in registers and to account for the size 3115 of the argument registers not being 16-byte aligned. E.G., there 3116 are 6 argument registers of 4 bytes each, but we want the __va_ndx 3117 for the first stack argument to have the maximal alignment of 16 3118 bytes, so we offset the __va_stk address by 32 bytes so that 3119 __va_stk[32] references the first argument on the stack. */ 3120 3121static tree 3122xtensa_build_builtin_va_list (void) 3123{ 3124 tree f_stk, f_reg, f_ndx, record, type_decl; 3125 3126 record = (*lang_hooks.types.make_type) (RECORD_TYPE); 3127 type_decl = build_decl (BUILTINS_LOCATION, 3128 TYPE_DECL, get_identifier ("__va_list_tag"), record); 3129 3130 f_stk = build_decl (BUILTINS_LOCATION, 3131 FIELD_DECL, get_identifier ("__va_stk"), 3132 ptr_type_node); 3133 f_reg = build_decl (BUILTINS_LOCATION, 3134 FIELD_DECL, get_identifier ("__va_reg"), 3135 ptr_type_node); 3136 f_ndx = build_decl (BUILTINS_LOCATION, 3137 FIELD_DECL, get_identifier ("__va_ndx"), 3138 integer_type_node); 3139 3140 DECL_FIELD_CONTEXT (f_stk) = record; 3141 DECL_FIELD_CONTEXT (f_reg) = record; 3142 DECL_FIELD_CONTEXT (f_ndx) = record; 3143 3144 TYPE_STUB_DECL (record) = type_decl; 3145 TYPE_NAME (record) = type_decl; 3146 TYPE_FIELDS (record) = f_stk; 3147 DECL_CHAIN (f_stk) = f_reg; 3148 DECL_CHAIN (f_reg) = f_ndx; 3149 3150 layout_type (record); 3151 return record; 3152} 3153 3154 3155/* Save the incoming argument registers on the stack. Returns the 3156 address of the saved registers. */ 3157 3158static rtx 3159xtensa_builtin_saveregs (void) 3160{ 3161 rtx gp_regs; 3162 int arg_words = crtl->args.info.arg_words; 3163 int gp_left = MAX_ARGS_IN_REGISTERS - arg_words; 3164 3165 if (gp_left <= 0) 3166 return const0_rtx; 3167 3168 /* Allocate the general-purpose register space. */ 3169 gp_regs = assign_stack_local 3170 (BLKmode, MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD, -1); 3171 set_mem_alias_set (gp_regs, get_varargs_alias_set ()); 3172 3173 /* Now store the incoming registers. */ 3174 cfun->machine->need_a7_copy = TARGET_WINDOWED_ABI; 3175 cfun->machine->vararg_a7 = true; 3176 move_block_from_reg (GP_ARG_FIRST + arg_words, 3177 adjust_address (gp_regs, BLKmode, 3178 arg_words * UNITS_PER_WORD), 3179 gp_left); 3180 if (cfun->machine->vararg_a7_copy != 0) 3181 emit_insn_before (cfun->machine->vararg_a7_copy, get_insns ()); 3182 3183 return XEXP (gp_regs, 0); 3184} 3185 3186 3187/* Implement `va_start' for varargs and stdarg. We look at the 3188 current function to fill in an initial va_list. */ 3189 3190static void 3191xtensa_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED) 3192{ 3193 tree f_stk, stk; 3194 tree f_reg, reg; 3195 tree f_ndx, ndx; 3196 tree t, u; 3197 int arg_words; 3198 3199 arg_words = crtl->args.info.arg_words; 3200 3201 f_stk = TYPE_FIELDS (va_list_type_node); 3202 f_reg = DECL_CHAIN (f_stk); 3203 f_ndx = DECL_CHAIN (f_reg); 3204 3205 stk = build3 (COMPONENT_REF, TREE_TYPE (f_stk), valist, f_stk, NULL_TREE); 3206 reg = build3 (COMPONENT_REF, TREE_TYPE (f_reg), unshare_expr (valist), 3207 f_reg, NULL_TREE); 3208 ndx = build3 (COMPONENT_REF, TREE_TYPE (f_ndx), unshare_expr (valist), 3209 f_ndx, NULL_TREE); 3210 3211 /* Call __builtin_saveregs; save the result in __va_reg */ 3212 u = make_tree (sizetype, expand_builtin_saveregs ()); 3213 u = fold_convert (ptr_type_node, u); 3214 t = build2 (MODIFY_EXPR, ptr_type_node, reg, u); 3215 TREE_SIDE_EFFECTS (t) = 1; 3216 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 3217 3218 /* Set the __va_stk member to ($arg_ptr - 32). */ 3219 u = make_tree (ptr_type_node, virtual_incoming_args_rtx); 3220 u = fold_build_pointer_plus_hwi (u, -32); 3221 t = build2 (MODIFY_EXPR, ptr_type_node, stk, u); 3222 TREE_SIDE_EFFECTS (t) = 1; 3223 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 3224 3225 /* Set the __va_ndx member. If the first variable argument is on 3226 the stack, adjust __va_ndx by 2 words to account for the extra 3227 alignment offset for __va_stk. */ 3228 if (arg_words >= MAX_ARGS_IN_REGISTERS) 3229 arg_words += 2; 3230 t = build2 (MODIFY_EXPR, integer_type_node, ndx, 3231 build_int_cst (integer_type_node, arg_words * UNITS_PER_WORD)); 3232 TREE_SIDE_EFFECTS (t) = 1; 3233 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 3234} 3235 3236 3237/* Implement `va_arg'. */ 3238 3239static tree 3240xtensa_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, 3241 gimple_seq *post_p ATTRIBUTE_UNUSED) 3242{ 3243 tree f_stk, stk; 3244 tree f_reg, reg; 3245 tree f_ndx, ndx; 3246 tree type_size, array, orig_ndx, addr, size, va_size, t; 3247 tree lab_false, lab_over, lab_false2; 3248 bool indirect; 3249 3250 indirect = pass_va_arg_by_reference (type); 3251 if (indirect) 3252 type = build_pointer_type (type); 3253 3254 /* Handle complex values as separate real and imaginary parts. */ 3255 if (TREE_CODE (type) == COMPLEX_TYPE) 3256 { 3257 tree real_part, imag_part; 3258 3259 real_part = xtensa_gimplify_va_arg_expr (valist, TREE_TYPE (type), 3260 pre_p, NULL); 3261 real_part = get_initialized_tmp_var (real_part, pre_p, NULL); 3262 3263 imag_part = xtensa_gimplify_va_arg_expr (unshare_expr (valist), 3264 TREE_TYPE (type), 3265 pre_p, NULL); 3266 imag_part = get_initialized_tmp_var (imag_part, pre_p, NULL); 3267 3268 return build2 (COMPLEX_EXPR, type, real_part, imag_part); 3269 } 3270 3271 f_stk = TYPE_FIELDS (va_list_type_node); 3272 f_reg = DECL_CHAIN (f_stk); 3273 f_ndx = DECL_CHAIN (f_reg); 3274 3275 stk = build3 (COMPONENT_REF, TREE_TYPE (f_stk), valist, 3276 f_stk, NULL_TREE); 3277 reg = build3 (COMPONENT_REF, TREE_TYPE (f_reg), unshare_expr (valist), 3278 f_reg, NULL_TREE); 3279 ndx = build3 (COMPONENT_REF, TREE_TYPE (f_ndx), unshare_expr (valist), 3280 f_ndx, NULL_TREE); 3281 3282 type_size = size_in_bytes (type); 3283 va_size = round_up (type_size, UNITS_PER_WORD); 3284 gimplify_expr (&va_size, pre_p, NULL, is_gimple_val, fb_rvalue); 3285 3286 3287 /* First align __va_ndx if necessary for this arg: 3288 3289 orig_ndx = (AP).__va_ndx; 3290 if (__alignof__ (TYPE) > 4 ) 3291 orig_ndx = ((orig_ndx + __alignof__ (TYPE) - 1) 3292 & -__alignof__ (TYPE)); */ 3293 3294 orig_ndx = get_initialized_tmp_var (ndx, pre_p, NULL); 3295 3296 if (TYPE_ALIGN (type) > BITS_PER_WORD) 3297 { 3298 int align = MIN (TYPE_ALIGN (type), STACK_BOUNDARY) / BITS_PER_UNIT; 3299 3300 t = build2 (PLUS_EXPR, integer_type_node, unshare_expr (orig_ndx), 3301 build_int_cst (integer_type_node, align - 1)); 3302 t = build2 (BIT_AND_EXPR, integer_type_node, t, 3303 build_int_cst (integer_type_node, -align)); 3304 gimplify_assign (unshare_expr (orig_ndx), t, pre_p); 3305 } 3306 3307 3308 /* Increment __va_ndx to point past the argument: 3309 3310 (AP).__va_ndx = orig_ndx + __va_size (TYPE); */ 3311 3312 t = fold_convert (integer_type_node, va_size); 3313 t = build2 (PLUS_EXPR, integer_type_node, orig_ndx, t); 3314 gimplify_assign (unshare_expr (ndx), t, pre_p); 3315 3316 3317 /* Check if the argument is in registers: 3318 3319 if ((AP).__va_ndx <= __MAX_ARGS_IN_REGISTERS * 4 3320 && !must_pass_in_stack (type)) 3321 __array = (AP).__va_reg; */ 3322 3323 array = create_tmp_var (ptr_type_node); 3324 3325 lab_over = NULL; 3326 if (!must_pass_va_arg_in_stack (type)) 3327 { 3328 lab_false = create_artificial_label (UNKNOWN_LOCATION); 3329 lab_over = create_artificial_label (UNKNOWN_LOCATION); 3330 3331 t = build2 (GT_EXPR, boolean_type_node, unshare_expr (ndx), 3332 build_int_cst (integer_type_node, 3333 MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD)); 3334 t = build3 (COND_EXPR, void_type_node, t, 3335 build1 (GOTO_EXPR, void_type_node, lab_false), 3336 NULL_TREE); 3337 gimplify_and_add (t, pre_p); 3338 3339 gimplify_assign (unshare_expr (array), reg, pre_p); 3340 3341 t = build1 (GOTO_EXPR, void_type_node, lab_over); 3342 gimplify_and_add (t, pre_p); 3343 3344 t = build1 (LABEL_EXPR, void_type_node, lab_false); 3345 gimplify_and_add (t, pre_p); 3346 } 3347 3348 3349 /* ...otherwise, the argument is on the stack (never split between 3350 registers and the stack -- change __va_ndx if necessary): 3351 3352 else 3353 { 3354 if (orig_ndx <= __MAX_ARGS_IN_REGISTERS * 4) 3355 (AP).__va_ndx = 32 + __va_size (TYPE); 3356 __array = (AP).__va_stk; 3357 } */ 3358 3359 lab_false2 = create_artificial_label (UNKNOWN_LOCATION); 3360 3361 t = build2 (GT_EXPR, boolean_type_node, unshare_expr (orig_ndx), 3362 build_int_cst (integer_type_node, 3363 MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD)); 3364 t = build3 (COND_EXPR, void_type_node, t, 3365 build1 (GOTO_EXPR, void_type_node, lab_false2), 3366 NULL_TREE); 3367 gimplify_and_add (t, pre_p); 3368 3369 t = size_binop (PLUS_EXPR, unshare_expr (va_size), size_int (32)); 3370 t = fold_convert (integer_type_node, t); 3371 gimplify_assign (unshare_expr (ndx), t, pre_p); 3372 3373 t = build1 (LABEL_EXPR, void_type_node, lab_false2); 3374 gimplify_and_add (t, pre_p); 3375 3376 gimplify_assign (array, stk, pre_p); 3377 3378 if (lab_over) 3379 { 3380 t = build1 (LABEL_EXPR, void_type_node, lab_over); 3381 gimplify_and_add (t, pre_p); 3382 } 3383 3384 3385 /* Given the base array pointer (__array) and index to the subsequent 3386 argument (__va_ndx), find the address: 3387 3388 __array + (AP).__va_ndx - (BYTES_BIG_ENDIAN && sizeof (TYPE) < 4 3389 ? sizeof (TYPE) 3390 : __va_size (TYPE)) 3391 3392 The results are endian-dependent because values smaller than one word 3393 are aligned differently. */ 3394 3395 3396 if (BYTES_BIG_ENDIAN && TREE_CODE (type_size) == INTEGER_CST) 3397 { 3398 t = fold_build2 (GE_EXPR, boolean_type_node, unshare_expr (type_size), 3399 size_int (PARM_BOUNDARY / BITS_PER_UNIT)); 3400 t = fold_build3 (COND_EXPR, sizetype, t, unshare_expr (va_size), 3401 unshare_expr (type_size)); 3402 size = t; 3403 } 3404 else 3405 size = unshare_expr (va_size); 3406 3407 t = fold_convert (sizetype, unshare_expr (ndx)); 3408 t = build2 (MINUS_EXPR, sizetype, t, size); 3409 addr = fold_build_pointer_plus (unshare_expr (array), t); 3410 3411 addr = fold_convert (build_pointer_type (type), addr); 3412 if (indirect) 3413 addr = build_va_arg_indirect_ref (addr); 3414 return build_va_arg_indirect_ref (addr); 3415} 3416 3417 3418/* Builtins. */ 3419 3420enum xtensa_builtin 3421{ 3422 XTENSA_BUILTIN_UMULSIDI3, 3423 XTENSA_BUILTIN_max 3424}; 3425 3426 3427static void 3428xtensa_init_builtins (void) 3429{ 3430 tree ftype, decl; 3431 3432 ftype = build_function_type_list (unsigned_intDI_type_node, 3433 unsigned_intSI_type_node, 3434 unsigned_intSI_type_node, NULL_TREE); 3435 3436 decl = add_builtin_function ("__builtin_umulsidi3", ftype, 3437 XTENSA_BUILTIN_UMULSIDI3, BUILT_IN_MD, 3438 "__umulsidi3", NULL_TREE); 3439 TREE_NOTHROW (decl) = 1; 3440 TREE_READONLY (decl) = 1; 3441} 3442 3443 3444static tree 3445xtensa_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *args, 3446 bool ignore ATTRIBUTE_UNUSED) 3447{ 3448 unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl); 3449 tree arg0, arg1; 3450 3451 switch (fcode) 3452 { 3453 case XTENSA_BUILTIN_UMULSIDI3: 3454 arg0 = args[0]; 3455 arg1 = args[1]; 3456 if ((TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST) 3457 || TARGET_MUL32_HIGH) 3458 return fold_build2 (MULT_EXPR, unsigned_intDI_type_node, 3459 fold_convert (unsigned_intDI_type_node, arg0), 3460 fold_convert (unsigned_intDI_type_node, arg1)); 3461 break; 3462 3463 default: 3464 internal_error ("bad builtin code"); 3465 break; 3466 } 3467 3468 return NULL; 3469} 3470 3471 3472static rtx 3473xtensa_expand_builtin (tree exp, rtx target, 3474 rtx subtarget ATTRIBUTE_UNUSED, 3475 machine_mode mode ATTRIBUTE_UNUSED, 3476 int ignore) 3477{ 3478 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 3479 unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl); 3480 3481 switch (fcode) 3482 { 3483 case XTENSA_BUILTIN_UMULSIDI3: 3484 /* The umulsidi3 builtin is just a mechanism to avoid calling the real 3485 __umulsidi3 function when the Xtensa configuration can directly 3486 implement it. If not, just call the function. */ 3487 return expand_call (exp, target, ignore); 3488 3489 default: 3490 internal_error ("bad builtin code"); 3491 } 3492 return NULL_RTX; 3493} 3494 3495/* Worker function for TARGET_PREFERRED_RELOAD_CLASS. */ 3496 3497static reg_class_t 3498xtensa_preferred_reload_class (rtx x, reg_class_t rclass) 3499{ 3500 if (CONSTANT_P (x) && CONST_DOUBLE_P (x)) 3501 return NO_REGS; 3502 3503 /* Don't use the stack pointer or hard frame pointer for reloads! 3504 The hard frame pointer would normally be OK except that it may 3505 briefly hold an incoming argument in the prologue, and reload 3506 won't know that it is live because the hard frame pointer is 3507 treated specially. */ 3508 3509 if (rclass == AR_REGS || rclass == GR_REGS) 3510 return RL_REGS; 3511 3512 return rclass; 3513} 3514 3515/* Worker function for TARGET_PREFERRED_OUTPUT_RELOAD_CLASS. */ 3516 3517static reg_class_t 3518xtensa_preferred_output_reload_class (rtx x ATTRIBUTE_UNUSED, 3519 reg_class_t rclass) 3520{ 3521 /* Don't use the stack pointer or hard frame pointer for reloads! 3522 The hard frame pointer would normally be OK except that it may 3523 briefly hold an incoming argument in the prologue, and reload 3524 won't know that it is live because the hard frame pointer is 3525 treated specially. */ 3526 3527 if (rclass == AR_REGS || rclass == GR_REGS) 3528 return RL_REGS; 3529 3530 return rclass; 3531} 3532 3533/* Worker function for TARGET_SECONDARY_RELOAD. */ 3534 3535static reg_class_t 3536xtensa_secondary_reload (bool in_p, rtx x, reg_class_t rclass, 3537 machine_mode mode, secondary_reload_info *sri) 3538{ 3539 int regno; 3540 3541 if (in_p && constantpool_mem_p (x)) 3542 { 3543 if (rclass == FP_REGS) 3544 return RL_REGS; 3545 3546 if (mode == QImode) 3547 sri->icode = CODE_FOR_reloadqi_literal; 3548 else if (mode == HImode) 3549 sri->icode = CODE_FOR_reloadhi_literal; 3550 } 3551 3552 regno = xt_true_regnum (x); 3553 if (ACC_REG_P (regno)) 3554 return ((rclass == GR_REGS || rclass == RL_REGS) ? NO_REGS : RL_REGS); 3555 if (rclass == ACC_REG) 3556 return (GP_REG_P (regno) ? NO_REGS : RL_REGS); 3557 3558 return NO_REGS; 3559} 3560 3561 3562void 3563order_regs_for_local_alloc (void) 3564{ 3565 if (!leaf_function_p ()) 3566 { 3567 static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] = 3568 REG_ALLOC_ORDER; 3569 static const int reg_nonleaf_alloc_order_call0[FIRST_PSEUDO_REGISTER] = 3570 { 3571 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 12, 13, 14, 15, 3572 18, 3573 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 3574 0, 1, 16, 17, 3575 35, 3576 }; 3577 3578 memcpy (reg_alloc_order, TARGET_WINDOWED_ABI ? 3579 reg_nonleaf_alloc_order : reg_nonleaf_alloc_order_call0, 3580 FIRST_PSEUDO_REGISTER * sizeof (int)); 3581 } 3582 else 3583 { 3584 int i, num_arg_regs; 3585 int nxt = 0; 3586 3587 /* Use the AR registers in increasing order (skipping a0 and a1) 3588 but save the incoming argument registers for a last resort. */ 3589 num_arg_regs = crtl->args.info.arg_words; 3590 if (num_arg_regs > MAX_ARGS_IN_REGISTERS) 3591 num_arg_regs = MAX_ARGS_IN_REGISTERS; 3592 for (i = GP_ARG_FIRST; i < 16 - num_arg_regs; i++) 3593 reg_alloc_order[nxt++] = i + num_arg_regs; 3594 for (i = 0; i < num_arg_regs; i++) 3595 reg_alloc_order[nxt++] = GP_ARG_FIRST + i; 3596 3597 /* List the coprocessor registers in order. */ 3598 for (i = 0; i < BR_REG_NUM; i++) 3599 reg_alloc_order[nxt++] = BR_REG_FIRST + i; 3600 3601 /* List the FP registers in order for now. */ 3602 for (i = 0; i < 16; i++) 3603 reg_alloc_order[nxt++] = FP_REG_FIRST + i; 3604 3605 /* GCC requires that we list *all* the registers.... */ 3606 reg_alloc_order[nxt++] = 0; /* a0 = return address */ 3607 reg_alloc_order[nxt++] = 1; /* a1 = stack pointer */ 3608 reg_alloc_order[nxt++] = 16; /* pseudo frame pointer */ 3609 reg_alloc_order[nxt++] = 17; /* pseudo arg pointer */ 3610 3611 reg_alloc_order[nxt++] = ACC_REG_FIRST; /* MAC16 accumulator */ 3612 } 3613} 3614 3615 3616/* Some Xtensa targets support multiple bss sections. If the section 3617 name ends with ".bss", add SECTION_BSS to the flags. */ 3618 3619static unsigned int 3620xtensa_multibss_section_type_flags (tree decl, const char *name, int reloc) 3621{ 3622 unsigned int flags = default_section_type_flags (decl, name, reloc); 3623 const char *suffix; 3624 3625 suffix = strrchr (name, '.'); 3626 if (suffix && strcmp (suffix, ".bss") == 0) 3627 { 3628 if (!decl || (TREE_CODE (decl) == VAR_DECL 3629 && DECL_INITIAL (decl) == NULL_TREE)) 3630 flags |= SECTION_BSS; /* @nobits */ 3631 else 3632 warning (0, "only uninitialized variables can be placed in a " 3633 ".bss section"); 3634 } 3635 3636 return flags; 3637} 3638 3639 3640/* The literal pool stays with the function. */ 3641 3642static section * 3643xtensa_select_rtx_section (machine_mode mode ATTRIBUTE_UNUSED, 3644 rtx x ATTRIBUTE_UNUSED, 3645 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED) 3646{ 3647 return function_section (current_function_decl); 3648} 3649 3650/* Worker function for TARGET_REGISTER_MOVE_COST. */ 3651 3652static int 3653xtensa_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED, 3654 reg_class_t from, reg_class_t to) 3655{ 3656 if (from == to && from != BR_REGS && to != BR_REGS) 3657 return 2; 3658 else if (reg_class_subset_p (from, AR_REGS) 3659 && reg_class_subset_p (to, AR_REGS)) 3660 return 2; 3661 else if (reg_class_subset_p (from, AR_REGS) && to == ACC_REG) 3662 return 3; 3663 else if (from == ACC_REG && reg_class_subset_p (to, AR_REGS)) 3664 return 3; 3665 else 3666 return 10; 3667} 3668 3669/* Worker function for TARGET_MEMORY_MOVE_COST. */ 3670 3671static int 3672xtensa_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED, 3673 reg_class_t rclass ATTRIBUTE_UNUSED, 3674 bool in ATTRIBUTE_UNUSED) 3675{ 3676 return 4; 3677} 3678 3679/* Compute a (partial) cost for rtx X. Return true if the complete 3680 cost has been computed, and false if subexpressions should be 3681 scanned. In either case, *TOTAL contains the cost result. */ 3682 3683static bool 3684xtensa_rtx_costs (rtx x, machine_mode mode, int outer_code, 3685 int opno ATTRIBUTE_UNUSED, 3686 int *total, bool speed ATTRIBUTE_UNUSED) 3687{ 3688 int code = GET_CODE (x); 3689 3690 switch (code) 3691 { 3692 case CONST_INT: 3693 switch (outer_code) 3694 { 3695 case SET: 3696 if (xtensa_simm12b (INTVAL (x))) 3697 { 3698 *total = 4; 3699 return true; 3700 } 3701 break; 3702 case PLUS: 3703 if (xtensa_simm8 (INTVAL (x)) 3704 || xtensa_simm8x256 (INTVAL (x))) 3705 { 3706 *total = 0; 3707 return true; 3708 } 3709 break; 3710 case AND: 3711 if (xtensa_mask_immediate (INTVAL (x))) 3712 { 3713 *total = 0; 3714 return true; 3715 } 3716 break; 3717 case COMPARE: 3718 if ((INTVAL (x) == 0) || xtensa_b4const (INTVAL (x))) 3719 { 3720 *total = 0; 3721 return true; 3722 } 3723 break; 3724 case ASHIFT: 3725 case ASHIFTRT: 3726 case LSHIFTRT: 3727 case ROTATE: 3728 case ROTATERT: 3729 /* No way to tell if X is the 2nd operand so be conservative. */ 3730 default: break; 3731 } 3732 if (xtensa_simm12b (INTVAL (x))) 3733 *total = 5; 3734 else if (TARGET_CONST16) 3735 *total = COSTS_N_INSNS (2); 3736 else 3737 *total = 6; 3738 return true; 3739 3740 case CONST: 3741 case LABEL_REF: 3742 case SYMBOL_REF: 3743 if (TARGET_CONST16) 3744 *total = COSTS_N_INSNS (2); 3745 else 3746 *total = 5; 3747 return true; 3748 3749 case CONST_DOUBLE: 3750 if (TARGET_CONST16) 3751 *total = COSTS_N_INSNS (4); 3752 else 3753 *total = 7; 3754 return true; 3755 3756 case MEM: 3757 { 3758 int num_words = 3759 (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1; 3760 3761 if (memory_address_p (mode, XEXP ((x), 0))) 3762 *total = COSTS_N_INSNS (num_words); 3763 else 3764 *total = COSTS_N_INSNS (2*num_words); 3765 return true; 3766 } 3767 3768 case FFS: 3769 case CTZ: 3770 *total = COSTS_N_INSNS (TARGET_NSA ? 5 : 50); 3771 return true; 3772 3773 case CLZ: 3774 *total = COSTS_N_INSNS (TARGET_NSA ? 1 : 50); 3775 return true; 3776 3777 case NOT: 3778 *total = COSTS_N_INSNS (mode == DImode ? 3 : 2); 3779 return true; 3780 3781 case AND: 3782 case IOR: 3783 case XOR: 3784 if (mode == DImode) 3785 *total = COSTS_N_INSNS (2); 3786 else 3787 *total = COSTS_N_INSNS (1); 3788 return true; 3789 3790 case ASHIFT: 3791 case ASHIFTRT: 3792 case LSHIFTRT: 3793 if (mode == DImode) 3794 *total = COSTS_N_INSNS (50); 3795 else 3796 *total = COSTS_N_INSNS (1); 3797 return true; 3798 3799 case ABS: 3800 { 3801 if (mode == SFmode) 3802 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50); 3803 else if (mode == DFmode) 3804 *total = COSTS_N_INSNS (50); 3805 else 3806 *total = COSTS_N_INSNS (4); 3807 return true; 3808 } 3809 3810 case PLUS: 3811 case MINUS: 3812 { 3813 if (mode == SFmode) 3814 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50); 3815 else if (mode == DFmode || mode == DImode) 3816 *total = COSTS_N_INSNS (50); 3817 else 3818 *total = COSTS_N_INSNS (1); 3819 return true; 3820 } 3821 3822 case NEG: 3823 *total = COSTS_N_INSNS (mode == DImode ? 4 : 2); 3824 return true; 3825 3826 case MULT: 3827 { 3828 if (mode == SFmode) 3829 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 4 : 50); 3830 else if (mode == DFmode) 3831 *total = COSTS_N_INSNS (50); 3832 else if (mode == DImode) 3833 *total = COSTS_N_INSNS (TARGET_MUL32_HIGH ? 10 : 50); 3834 else if (TARGET_MUL32) 3835 *total = COSTS_N_INSNS (4); 3836 else if (TARGET_MAC16) 3837 *total = COSTS_N_INSNS (16); 3838 else if (TARGET_MUL16) 3839 *total = COSTS_N_INSNS (12); 3840 else 3841 *total = COSTS_N_INSNS (50); 3842 return true; 3843 } 3844 3845 case DIV: 3846 case MOD: 3847 { 3848 if (mode == SFmode) 3849 { 3850 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT_DIV ? 8 : 50); 3851 return true; 3852 } 3853 else if (mode == DFmode) 3854 { 3855 *total = COSTS_N_INSNS (50); 3856 return true; 3857 } 3858 } 3859 /* Fall through. */ 3860 3861 case UDIV: 3862 case UMOD: 3863 { 3864 if (mode == DImode) 3865 *total = COSTS_N_INSNS (50); 3866 else if (TARGET_DIV32) 3867 *total = COSTS_N_INSNS (32); 3868 else 3869 *total = COSTS_N_INSNS (50); 3870 return true; 3871 } 3872 3873 case SQRT: 3874 if (mode == SFmode) 3875 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT_SQRT ? 8 : 50); 3876 else 3877 *total = COSTS_N_INSNS (50); 3878 return true; 3879 3880 case SMIN: 3881 case UMIN: 3882 case SMAX: 3883 case UMAX: 3884 *total = COSTS_N_INSNS (TARGET_MINMAX ? 1 : 50); 3885 return true; 3886 3887 case SIGN_EXTRACT: 3888 case SIGN_EXTEND: 3889 *total = COSTS_N_INSNS (TARGET_SEXT ? 1 : 2); 3890 return true; 3891 3892 case ZERO_EXTRACT: 3893 case ZERO_EXTEND: 3894 *total = COSTS_N_INSNS (1); 3895 return true; 3896 3897 default: 3898 return false; 3899 } 3900} 3901 3902/* Worker function for TARGET_RETURN_IN_MEMORY. */ 3903 3904static bool 3905xtensa_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) 3906{ 3907 return ((unsigned HOST_WIDE_INT) int_size_in_bytes (type) 3908 > 4 * UNITS_PER_WORD); 3909} 3910 3911/* Worker function for TARGET_FUNCTION_VALUE. */ 3912 3913rtx 3914xtensa_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED, 3915 bool outgoing) 3916{ 3917 return gen_rtx_REG ((INTEGRAL_TYPE_P (valtype) 3918 && TYPE_PRECISION (valtype) < BITS_PER_WORD) 3919 ? SImode : TYPE_MODE (valtype), 3920 outgoing ? GP_OUTGOING_RETURN : GP_RETURN); 3921} 3922 3923/* Worker function for TARGET_LIBCALL_VALUE. */ 3924 3925static rtx 3926xtensa_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED) 3927{ 3928 return gen_rtx_REG ((GET_MODE_CLASS (mode) == MODE_INT 3929 && GET_MODE_SIZE (mode) < UNITS_PER_WORD) 3930 ? SImode : mode, GP_RETURN); 3931} 3932 3933/* Worker function TARGET_FUNCTION_VALUE_REGNO_P. */ 3934 3935static bool 3936xtensa_function_value_regno_p (const unsigned int regno) 3937{ 3938 return (regno == GP_RETURN); 3939} 3940 3941/* The static chain is passed in memory. Provide rtx giving 'mem' 3942 expressions that denote where they are stored. */ 3943 3944static rtx 3945xtensa_static_chain (const_tree ARG_UNUSED (fndecl_or_type), bool incoming_p) 3946{ 3947 if (TARGET_WINDOWED_ABI) 3948 { 3949 rtx base = incoming_p ? arg_pointer_rtx : stack_pointer_rtx; 3950 return gen_frame_mem (Pmode, plus_constant (Pmode, base, 3951 -5 * UNITS_PER_WORD)); 3952 } 3953 else 3954 return gen_rtx_REG (Pmode, A8_REG); 3955} 3956 3957 3958/* TRAMPOLINE_TEMPLATE: For Xtensa, the trampoline must perform an ENTRY 3959 instruction with a minimal stack frame in order to get some free 3960 registers. Once the actual call target is known, the proper stack frame 3961 size is extracted from the ENTRY instruction at the target and the 3962 current frame is adjusted to match. The trampoline then transfers 3963 control to the instruction following the ENTRY at the target. Note: 3964 this assumes that the target begins with an ENTRY instruction. */ 3965 3966static void 3967xtensa_asm_trampoline_template (FILE *stream) 3968{ 3969 bool use_call0 = (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS); 3970 3971 fprintf (stream, "\t.begin no-transform\n"); 3972 3973 if (TARGET_WINDOWED_ABI) 3974 { 3975 fprintf (stream, "\tentry\tsp, %d\n", MIN_FRAME_SIZE); 3976 3977 if (use_call0) 3978 { 3979 /* Save the return address. */ 3980 fprintf (stream, "\tmov\ta10, a0\n"); 3981 3982 /* Use a CALL0 instruction to skip past the constants and in the 3983 process get the PC into A0. This allows PC-relative access to 3984 the constants without relying on L32R. */ 3985 fprintf (stream, "\tcall0\t.Lskipconsts\n"); 3986 } 3987 else 3988 fprintf (stream, "\tj\t.Lskipconsts\n"); 3989 3990 fprintf (stream, "\t.align\t4\n"); 3991 fprintf (stream, ".Lchainval:%s0\n", integer_asm_op (4, TRUE)); 3992 fprintf (stream, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE)); 3993 fprintf (stream, ".Lskipconsts:\n"); 3994 3995 /* Load the static chain and function address from the trampoline. */ 3996 if (use_call0) 3997 { 3998 fprintf (stream, "\taddi\ta0, a0, 3\n"); 3999 fprintf (stream, "\tl32i\ta9, a0, 0\n"); 4000 fprintf (stream, "\tl32i\ta8, a0, 4\n"); 4001 } 4002 else 4003 { 4004 fprintf (stream, "\tl32r\ta9, .Lchainval\n"); 4005 fprintf (stream, "\tl32r\ta8, .Lfnaddr\n"); 4006 } 4007 4008 /* Store the static chain. */ 4009 fprintf (stream, "\ts32i\ta9, sp, %d\n", MIN_FRAME_SIZE - 20); 4010 4011 /* Set the proper stack pointer value. */ 4012 fprintf (stream, "\tl32i\ta9, a8, 0\n"); 4013 fprintf (stream, "\textui\ta9, a9, %d, 12\n", 4014 TARGET_BIG_ENDIAN ? 8 : 12); 4015 fprintf (stream, "\tslli\ta9, a9, 3\n"); 4016 fprintf (stream, "\taddi\ta9, a9, %d\n", -MIN_FRAME_SIZE); 4017 fprintf (stream, "\tsub\ta9, sp, a9\n"); 4018 fprintf (stream, "\tmovsp\tsp, a9\n"); 4019 4020 if (use_call0) 4021 /* Restore the return address. */ 4022 fprintf (stream, "\tmov\ta0, a10\n"); 4023 4024 /* Jump to the instruction following the ENTRY. */ 4025 fprintf (stream, "\taddi\ta8, a8, 3\n"); 4026 fprintf (stream, "\tjx\ta8\n"); 4027 4028 /* Pad size to a multiple of TRAMPOLINE_ALIGNMENT. */ 4029 if (use_call0) 4030 fprintf (stream, "\t.byte\t0\n"); 4031 else 4032 fprintf (stream, "\tnop\n"); 4033 } 4034 else 4035 { 4036 if (use_call0) 4037 { 4038 /* Save the return address. */ 4039 fprintf (stream, "\tmov\ta10, a0\n"); 4040 4041 /* Use a CALL0 instruction to skip past the constants and in the 4042 process get the PC into A0. This allows PC-relative access to 4043 the constants without relying on L32R. */ 4044 fprintf (stream, "\tcall0\t.Lskipconsts\n"); 4045 } 4046 else 4047 fprintf (stream, "\tj\t.Lskipconsts\n"); 4048 4049 fprintf (stream, "\t.align\t4\n"); 4050 fprintf (stream, ".Lchainval:%s0\n", integer_asm_op (4, TRUE)); 4051 fprintf (stream, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE)); 4052 fprintf (stream, ".Lskipconsts:\n"); 4053 4054 /* Load the static chain and function address from the trampoline. */ 4055 if (use_call0) 4056 { 4057 fprintf (stream, "\taddi\ta0, a0, 3\n"); 4058 fprintf (stream, "\tl32i\ta8, a0, 0\n"); 4059 fprintf (stream, "\tl32i\ta9, a0, 4\n"); 4060 fprintf (stream, "\tmov\ta0, a10\n"); 4061 } 4062 else 4063 { 4064 fprintf (stream, "\tl32r\ta8, .Lchainval\n"); 4065 fprintf (stream, "\tl32r\ta9, .Lfnaddr\n"); 4066 } 4067 fprintf (stream, "\tjx\ta9\n"); 4068 4069 /* Pad size to a multiple of TRAMPOLINE_ALIGNMENT. */ 4070 if (use_call0) 4071 fprintf (stream, "\t.byte\t0\n"); 4072 else 4073 fprintf (stream, "\tnop\n"); 4074 } 4075 fprintf (stream, "\t.end no-transform\n"); 4076} 4077 4078static void 4079xtensa_trampoline_init (rtx m_tramp, tree fndecl, rtx chain) 4080{ 4081 rtx func = XEXP (DECL_RTL (fndecl), 0); 4082 bool use_call0 = (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS); 4083 int chain_off; 4084 int func_off; 4085 4086 if (TARGET_WINDOWED_ABI) 4087 { 4088 chain_off = use_call0 ? 12 : 8; 4089 func_off = use_call0 ? 16 : 12; 4090 } 4091 else 4092 { 4093 chain_off = use_call0 ? 8 : 4; 4094 func_off = use_call0 ? 12 : 8; 4095 } 4096 4097 emit_block_move (m_tramp, assemble_trampoline_template (), 4098 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL); 4099 4100 emit_move_insn (adjust_address (m_tramp, SImode, chain_off), chain); 4101 emit_move_insn (adjust_address (m_tramp, SImode, func_off), func); 4102 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_sync_caches"), 4103 LCT_NORMAL, VOIDmode, XEXP (m_tramp, 0), Pmode); 4104} 4105 4106/* Implement TARGET_LEGITIMATE_CONSTANT_P. */ 4107 4108static bool 4109xtensa_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x) 4110{ 4111 return !xtensa_tls_referenced_p (x); 4112} 4113 4114/* Implement TARGET_CAN_USE_DOLOOP_P. */ 4115 4116static bool 4117xtensa_can_use_doloop_p (const widest_int &, const widest_int &, 4118 unsigned int loop_depth, bool entered_at_top) 4119{ 4120 /* Considering limitations in the hardware, only use doloop 4121 for innermost loops which must be entered from the top. */ 4122 if (loop_depth > 1 || !entered_at_top) 4123 return false; 4124 4125 return true; 4126} 4127 4128/* NULL if INSN insn is valid within a low-overhead loop. 4129 Otherwise return why doloop cannot be applied. */ 4130 4131static const char * 4132xtensa_invalid_within_doloop (const rtx_insn *insn) 4133{ 4134 if (CALL_P (insn)) 4135 return "Function call in the loop."; 4136 4137 if (JUMP_P (insn) && INSN_CODE (insn) == CODE_FOR_return) 4138 return "Return from a call instruction in the loop."; 4139 4140 return NULL; 4141} 4142 4143/* Optimize LOOP. */ 4144 4145static bool 4146hwloop_optimize (hwloop_info loop) 4147{ 4148 int i; 4149 edge entry_edge; 4150 basic_block entry_bb; 4151 rtx iter_reg; 4152 rtx_insn *insn, *seq, *entry_after; 4153 4154 if (loop->depth > 1) 4155 { 4156 if (dump_file) 4157 fprintf (dump_file, ";; loop %d is not innermost\n", 4158 loop->loop_no); 4159 return false; 4160 } 4161 4162 if (!loop->incoming_dest) 4163 { 4164 if (dump_file) 4165 fprintf (dump_file, ";; loop %d has more than one entry\n", 4166 loop->loop_no); 4167 return false; 4168 } 4169 4170 if (loop->incoming_dest != loop->head) 4171 { 4172 if (dump_file) 4173 fprintf (dump_file, ";; loop %d is not entered from head\n", 4174 loop->loop_no); 4175 return false; 4176 } 4177 4178 if (loop->has_call || loop->has_asm) 4179 { 4180 if (dump_file) 4181 fprintf (dump_file, ";; loop %d has invalid insn\n", 4182 loop->loop_no); 4183 return false; 4184 } 4185 4186 /* Scan all the blocks to make sure they don't use iter_reg. */ 4187 if (loop->iter_reg_used || loop->iter_reg_used_outside) 4188 { 4189 if (dump_file) 4190 fprintf (dump_file, ";; loop %d uses iterator\n", 4191 loop->loop_no); 4192 return false; 4193 } 4194 4195 /* Check if start_label appears before doloop_end. */ 4196 insn = loop->start_label; 4197 while (insn && insn != loop->loop_end) 4198 insn = NEXT_INSN (insn); 4199 4200 if (!insn) 4201 { 4202 if (dump_file) 4203 fprintf (dump_file, ";; loop %d start_label not before loop_end\n", 4204 loop->loop_no); 4205 return false; 4206 } 4207 4208 /* Get the loop iteration register. */ 4209 iter_reg = loop->iter_reg; 4210 4211 gcc_assert (REG_P (iter_reg)); 4212 4213 entry_edge = NULL; 4214 4215 FOR_EACH_VEC_SAFE_ELT (loop->incoming, i, entry_edge) 4216 if (entry_edge->flags & EDGE_FALLTHRU) 4217 break; 4218 4219 if (entry_edge == NULL) 4220 return false; 4221 4222 /* Place the zero_cost_loop_start instruction before the loop. */ 4223 entry_bb = entry_edge->src; 4224 4225 start_sequence (); 4226 4227 insn = emit_insn (gen_zero_cost_loop_start (loop->iter_reg, 4228 loop->start_label, 4229 loop->iter_reg)); 4230 4231 seq = get_insns (); 4232 4233 entry_after = BB_END (entry_bb); 4234 if (!single_succ_p (entry_bb) || vec_safe_length (loop->incoming) > 1 4235 || !entry_after) 4236 { 4237 basic_block new_bb; 4238 edge e; 4239 edge_iterator ei; 4240 4241 emit_insn_before (seq, BB_HEAD (loop->head)); 4242 seq = emit_label_before (gen_label_rtx (), seq); 4243 new_bb = create_basic_block (seq, insn, entry_bb); 4244 FOR_EACH_EDGE (e, ei, loop->incoming) 4245 { 4246 if (!(e->flags & EDGE_FALLTHRU)) 4247 redirect_edge_and_branch_force (e, new_bb); 4248 else 4249 redirect_edge_succ (e, new_bb); 4250 } 4251 4252 make_edge (new_bb, loop->head, 0); 4253 } 4254 else 4255 { 4256 while (DEBUG_INSN_P (entry_after) 4257 || (NOTE_P (entry_after) 4258 && NOTE_KIND (entry_after) != NOTE_INSN_BASIC_BLOCK)) 4259 entry_after = PREV_INSN (entry_after); 4260 4261 emit_insn_after (seq, entry_after); 4262 } 4263 4264 end_sequence (); 4265 4266 return true; 4267} 4268 4269/* A callback for the hw-doloop pass. Called when a loop we have discovered 4270 turns out not to be optimizable; we have to split the loop_end pattern into 4271 a subtract and a test. */ 4272 4273static void 4274hwloop_fail (hwloop_info loop) 4275{ 4276 rtx test; 4277 rtx_insn *insn = loop->loop_end; 4278 4279 emit_insn_before (gen_addsi3 (loop->iter_reg, 4280 loop->iter_reg, 4281 constm1_rtx), 4282 loop->loop_end); 4283 4284 test = gen_rtx_NE (VOIDmode, loop->iter_reg, const0_rtx); 4285 insn = emit_jump_insn_before (gen_cbranchsi4 (test, 4286 loop->iter_reg, const0_rtx, 4287 loop->start_label), 4288 loop->loop_end); 4289 4290 JUMP_LABEL (insn) = loop->start_label; 4291 LABEL_NUSES (loop->start_label)++; 4292 delete_insn (loop->loop_end); 4293} 4294 4295/* A callback for the hw-doloop pass. This function examines INSN; if 4296 it is a doloop_end pattern we recognize, return the reg rtx for the 4297 loop counter. Otherwise, return NULL_RTX. */ 4298 4299static rtx 4300hwloop_pattern_reg (rtx_insn *insn) 4301{ 4302 rtx reg; 4303 4304 if (!JUMP_P (insn) || recog_memoized (insn) != CODE_FOR_loop_end) 4305 return NULL_RTX; 4306 4307 reg = SET_DEST (XVECEXP (PATTERN (insn), 0, 1)); 4308 if (!REG_P (reg)) 4309 return NULL_RTX; 4310 4311 return reg; 4312} 4313 4314 4315static struct hw_doloop_hooks xtensa_doloop_hooks = 4316{ 4317 hwloop_pattern_reg, 4318 hwloop_optimize, 4319 hwloop_fail 4320}; 4321 4322/* Run from machine_dependent_reorg, this pass looks for doloop_end insns 4323 and tries to rewrite the RTL of these loops so that proper Xtensa 4324 hardware loops are generated. */ 4325 4326static void 4327xtensa_reorg_loops (void) 4328{ 4329 if (TARGET_LOOPS) 4330 reorg_loops (false, &xtensa_doloop_hooks); 4331} 4332 4333/* Implement the TARGET_MACHINE_DEPENDENT_REORG pass. */ 4334 4335static void 4336xtensa_reorg (void) 4337{ 4338 /* We are freeing block_for_insn in the toplev to keep compatibility 4339 with old MDEP_REORGS that are not CFG based. Recompute it now. */ 4340 compute_bb_for_insn (); 4341 4342 df_analyze (); 4343 4344 /* Doloop optimization. */ 4345 xtensa_reorg_loops (); 4346} 4347 4348/* Update register usage after having seen the compiler flags. */ 4349 4350static void 4351xtensa_conditional_register_usage (void) 4352{ 4353 unsigned i, c_mask; 4354 4355 c_mask = TARGET_WINDOWED_ABI ? (1 << 1) : (1 << 2); 4356 4357 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 4358 { 4359 /* Set/reset conditionally defined registers from 4360 CALL_USED_REGISTERS initializer. */ 4361 if (call_used_regs[i] > 1) 4362 call_used_regs[i] = !!(call_used_regs[i] & c_mask); 4363 } 4364 4365 /* Remove hard FP register from the preferred reload registers set. */ 4366 CLEAR_HARD_REG_BIT (reg_class_contents[(int)RL_REGS], 4367 HARD_FRAME_POINTER_REGNUM); 4368} 4369 4370/* Map hard register number to register class */ 4371 4372enum reg_class xtensa_regno_to_class (int regno) 4373{ 4374 static const enum reg_class regno_to_class[FIRST_PSEUDO_REGISTER] = 4375 { 4376 RL_REGS, SP_REG, RL_REGS, RL_REGS, 4377 RL_REGS, RL_REGS, RL_REGS, RL_REGS, 4378 RL_REGS, RL_REGS, RL_REGS, RL_REGS, 4379 RL_REGS, RL_REGS, RL_REGS, RL_REGS, 4380 AR_REGS, AR_REGS, BR_REGS, 4381 FP_REGS, FP_REGS, FP_REGS, FP_REGS, 4382 FP_REGS, FP_REGS, FP_REGS, FP_REGS, 4383 FP_REGS, FP_REGS, FP_REGS, FP_REGS, 4384 FP_REGS, FP_REGS, FP_REGS, FP_REGS, 4385 ACC_REG, 4386 }; 4387 4388 if (regno == HARD_FRAME_POINTER_REGNUM) 4389 return GR_REGS; 4390 else 4391 return regno_to_class[regno]; 4392} 4393 4394/* Implement TARGET_CONSTANT_ALIGNMENT. Align string constants and 4395 constructors to at least a word boundary. The typical use of this 4396 macro is to increase alignment for string constants to be word 4397 aligned so that 'strcpy' calls that copy constants can be done 4398 inline. */ 4399 4400static HOST_WIDE_INT 4401xtensa_constant_alignment (const_tree exp, HOST_WIDE_INT align) 4402{ 4403 if ((TREE_CODE (exp) == STRING_CST || TREE_CODE (exp) == CONSTRUCTOR) 4404 && !optimize_size) 4405 return MAX (align, BITS_PER_WORD); 4406 return align; 4407} 4408 4409/* Implement TARGET_STARTING_FRAME_OFFSET. */ 4410 4411static HOST_WIDE_INT 4412xtensa_starting_frame_offset (void) 4413{ 4414 if (FRAME_GROWS_DOWNWARD) 4415 return 0; 4416 return crtl->outgoing_args_size; 4417} 4418 4419/* Implement TARGET_ASAN_SHADOW_OFFSET. */ 4420 4421static unsigned HOST_WIDE_INT 4422xtensa_asan_shadow_offset (void) 4423{ 4424 return HOST_WIDE_INT_UC (0x10000000); 4425} 4426 4427#include "gt-xtensa.h" 4428