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