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