1/* Subroutines used for code generation on Renesas RX processors. 2 Copyright (C) 2008-2020 Free Software Foundation, Inc. 3 Contributed by Red Hat. 4 5 This file is part of GCC. 6 7 GCC is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3, or (at your option) 10 any later version. 11 12 GCC is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GCC; see the file COPYING3. If not see 19 <http://www.gnu.org/licenses/>. */ 20 21/* To Do: 22 23 * Re-enable memory-to-memory copies and fix up reload. */ 24 25#define IN_TARGET_CODE 1 26 27#include "config.h" 28#include "system.h" 29#include "coretypes.h" 30#include "backend.h" 31#include "target.h" 32#include "rtl.h" 33#include "tree.h" 34#include "stringpool.h" 35#include "attribs.h" 36#include "cfghooks.h" 37#include "df.h" 38#include "memmodel.h" 39#include "tm_p.h" 40#include "regs.h" 41#include "emit-rtl.h" 42#include "diagnostic-core.h" 43#include "varasm.h" 44#include "stor-layout.h" 45#include "calls.h" 46#include "output.h" 47#include "flags.h" 48#include "explow.h" 49#include "expr.h" 50#include "toplev.h" 51#include "langhooks.h" 52#include "opts.h" 53#include "builtins.h" 54 55/* This file should be included last. */ 56#include "target-def.h" 57 58static unsigned int rx_gp_base_regnum_val = INVALID_REGNUM; 59static unsigned int rx_pid_base_regnum_val = INVALID_REGNUM; 60static unsigned int rx_num_interrupt_regs; 61 62static unsigned int 63rx_gp_base_regnum (void) 64{ 65 if (rx_gp_base_regnum_val == INVALID_REGNUM) 66 gcc_unreachable (); 67 return rx_gp_base_regnum_val; 68} 69 70static unsigned int 71rx_pid_base_regnum (void) 72{ 73 if (rx_pid_base_regnum_val == INVALID_REGNUM) 74 gcc_unreachable (); 75 return rx_pid_base_regnum_val; 76} 77 78/* Find a SYMBOL_REF in a "standard" MEM address and return its decl. */ 79 80static tree 81rx_decl_for_addr (rtx op) 82{ 83 if (GET_CODE (op) == MEM) 84 op = XEXP (op, 0); 85 if (GET_CODE (op) == CONST) 86 op = XEXP (op, 0); 87 while (GET_CODE (op) == PLUS) 88 op = XEXP (op, 0); 89 if (GET_CODE (op) == SYMBOL_REF) 90 return SYMBOL_REF_DECL (op); 91 return NULL_TREE; 92} 93 94static void rx_print_operand (FILE *, rtx, int); 95 96#define CC_FLAG_S (1 << 0) 97#define CC_FLAG_Z (1 << 1) 98#define CC_FLAG_O (1 << 2) 99#define CC_FLAG_C (1 << 3) 100#define CC_FLAG_FP (1 << 4) /* Fake, to differentiate CC_Fmode. */ 101 102static unsigned int flags_from_mode (machine_mode mode); 103static unsigned int flags_from_code (enum rtx_code code); 104 105/* Return true if OP is a reference to an object in a PID data area. */ 106 107enum pid_type 108{ 109 PID_NOT_PID = 0, /* The object is not in the PID data area. */ 110 PID_ENCODED, /* The object is in the PID data area. */ 111 PID_UNENCODED /* The object will be placed in the PID data area, but it has not been placed there yet. */ 112}; 113 114static enum pid_type 115rx_pid_data_operand (rtx op) 116{ 117 tree op_decl; 118 119 if (!TARGET_PID) 120 return PID_NOT_PID; 121 122 if (GET_CODE (op) == PLUS 123 && GET_CODE (XEXP (op, 0)) == REG 124 && GET_CODE (XEXP (op, 1)) == CONST 125 && GET_CODE (XEXP (XEXP (op, 1), 0)) == UNSPEC) 126 return PID_ENCODED; 127 128 op_decl = rx_decl_for_addr (op); 129 130 if (op_decl) 131 { 132 if (TREE_READONLY (op_decl)) 133 return PID_UNENCODED; 134 } 135 else 136 { 137 /* Sigh, some special cases. */ 138 if (GET_CODE (op) == SYMBOL_REF 139 || GET_CODE (op) == LABEL_REF) 140 return PID_UNENCODED; 141 } 142 143 return PID_NOT_PID; 144} 145 146static rtx 147rx_legitimize_address (rtx x, 148 rtx oldx ATTRIBUTE_UNUSED, 149 machine_mode mode ATTRIBUTE_UNUSED) 150{ 151 if (rx_pid_data_operand (x) == PID_UNENCODED) 152 { 153 rtx rv = gen_pid_addr (gen_rtx_REG (SImode, rx_pid_base_regnum ()), x); 154 return rv; 155 } 156 157 if (GET_CODE (x) == PLUS 158 && GET_CODE (XEXP (x, 0)) == PLUS 159 && REG_P (XEXP (XEXP (x, 0), 0)) 160 && REG_P (XEXP (x, 1))) 161 return force_reg (SImode, x); 162 163 return x; 164} 165 166/* Return true if OP is a reference to an object in a small data area. */ 167 168static bool 169rx_small_data_operand (rtx op) 170{ 171 if (rx_small_data_limit == 0) 172 return false; 173 174 if (GET_CODE (op) == SYMBOL_REF) 175 return SYMBOL_REF_SMALL_P (op); 176 177 return false; 178} 179 180static bool 181rx_is_legitimate_address (machine_mode mode, rtx x, 182 bool strict ATTRIBUTE_UNUSED) 183{ 184 if (RTX_OK_FOR_BASE (x, strict)) 185 /* Register Indirect. */ 186 return true; 187 188 if ((GET_MODE_SIZE (mode) == 4 189 || GET_MODE_SIZE (mode) == 2 190 || GET_MODE_SIZE (mode) == 1) 191 && (GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)) 192 /* Pre-decrement Register Indirect or 193 Post-increment Register Indirect. */ 194 return RTX_OK_FOR_BASE (XEXP (x, 0), strict); 195 196 switch (rx_pid_data_operand (x)) 197 { 198 case PID_UNENCODED: 199 return false; 200 case PID_ENCODED: 201 return true; 202 default: 203 break; 204 } 205 206 if (GET_CODE (x) == PLUS) 207 { 208 rtx arg1 = XEXP (x, 0); 209 rtx arg2 = XEXP (x, 1); 210 rtx index = NULL_RTX; 211 212 if (REG_P (arg1) && RTX_OK_FOR_BASE (arg1, strict)) 213 index = arg2; 214 else if (REG_P (arg2) && RTX_OK_FOR_BASE (arg2, strict)) 215 index = arg1; 216 else 217 return false; 218 219 switch (GET_CODE (index)) 220 { 221 case CONST_INT: 222 { 223 /* Register Relative: REG + INT. 224 Only positive, mode-aligned, mode-sized 225 displacements are allowed. */ 226 HOST_WIDE_INT val = INTVAL (index); 227 int factor; 228 229 if (val < 0) 230 return false; 231 232 switch (GET_MODE_SIZE (mode)) 233 { 234 default: 235 case 4: factor = 4; break; 236 case 2: factor = 2; break; 237 case 1: factor = 1; break; 238 } 239 240 if (val > (65535 * factor)) 241 return false; 242 return (val % factor) == 0; 243 } 244 245 case REG: 246 /* Unscaled Indexed Register Indirect: REG + REG 247 Size has to be "QI", REG has to be valid. */ 248 return GET_MODE_SIZE (mode) == 1 && RTX_OK_FOR_BASE (index, strict); 249 250 case MULT: 251 { 252 /* Scaled Indexed Register Indirect: REG + (REG * FACTOR) 253 Factor has to equal the mode size, REG has to be valid. */ 254 rtx factor; 255 256 factor = XEXP (index, 1); 257 index = XEXP (index, 0); 258 259 return REG_P (index) 260 && RTX_OK_FOR_BASE (index, strict) 261 && CONST_INT_P (factor) 262 && GET_MODE_SIZE (mode) == INTVAL (factor); 263 } 264 265 default: 266 return false; 267 } 268 } 269 270 /* Small data area accesses turn into register relative offsets. */ 271 return rx_small_data_operand (x); 272} 273 274/* Returns TRUE for simple memory addresses, ie ones 275 that do not involve register indirect addressing 276 or pre/post increment/decrement. */ 277 278bool 279rx_is_restricted_memory_address (rtx mem, machine_mode mode) 280{ 281 if (! rx_is_legitimate_address 282 (mode, mem, reload_in_progress || reload_completed)) 283 return false; 284 285 switch (GET_CODE (mem)) 286 { 287 case REG: 288 /* Simple memory addresses are OK. */ 289 return true; 290 291 case SUBREG: 292 return RX_REG_P (SUBREG_REG (mem)); 293 294 case PRE_DEC: 295 case POST_INC: 296 return false; 297 298 case PLUS: 299 { 300 rtx base, index; 301 302 /* Only allow REG+INT addressing. */ 303 base = XEXP (mem, 0); 304 index = XEXP (mem, 1); 305 306 if (! RX_REG_P (base) || ! CONST_INT_P (index)) 307 return false; 308 309 return IN_RANGE (INTVAL (index), 0, (0x10000 * GET_MODE_SIZE (mode)) - 1); 310 } 311 312 case SYMBOL_REF: 313 /* Can happen when small data is being supported. 314 Assume that it will be resolved into GP+INT. */ 315 return true; 316 317 default: 318 gcc_unreachable (); 319 } 320} 321 322/* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */ 323 324static bool 325rx_mode_dependent_address_p (const_rtx addr, addr_space_t as ATTRIBUTE_UNUSED) 326{ 327 if (GET_CODE (addr) == CONST) 328 addr = XEXP (addr, 0); 329 330 switch (GET_CODE (addr)) 331 { 332 /* --REG and REG++ only work in SImode. */ 333 case PRE_DEC: 334 case POST_INC: 335 return true; 336 337 case MINUS: 338 case PLUS: 339 if (! REG_P (XEXP (addr, 0))) 340 return true; 341 342 addr = XEXP (addr, 1); 343 344 switch (GET_CODE (addr)) 345 { 346 case REG: 347 /* REG+REG only works in SImode. */ 348 return true; 349 350 case CONST_INT: 351 /* REG+INT is only mode independent if INT is a 352 multiple of 4, positive and will fit into 16-bits. */ 353 if (((INTVAL (addr) & 3) == 0) 354 && IN_RANGE (INTVAL (addr), 4, 0xfffc)) 355 return false; 356 return true; 357 358 case SYMBOL_REF: 359 case LABEL_REF: 360 return true; 361 362 case MULT: 363 /* REG+REG*SCALE is always mode dependent. */ 364 return true; 365 366 default: 367 /* Not recognized, so treat as mode dependent. */ 368 return true; 369 } 370 371 case CONST_INT: 372 case SYMBOL_REF: 373 case LABEL_REF: 374 case REG: 375 /* These are all mode independent. */ 376 return false; 377 378 default: 379 /* Everything else is unrecognized, 380 so treat as mode dependent. */ 381 return true; 382 } 383} 384 385/* A C compound statement to output to stdio stream FILE the 386 assembler syntax for an instruction operand that is a memory 387 reference whose address is ADDR. */ 388 389static void 390rx_print_operand_address (FILE * file, machine_mode /*mode*/, rtx addr) 391{ 392 switch (GET_CODE (addr)) 393 { 394 case REG: 395 fprintf (file, "["); 396 rx_print_operand (file, addr, 0); 397 fprintf (file, "]"); 398 break; 399 400 case PRE_DEC: 401 fprintf (file, "[-"); 402 rx_print_operand (file, XEXP (addr, 0), 0); 403 fprintf (file, "]"); 404 break; 405 406 case POST_INC: 407 fprintf (file, "["); 408 rx_print_operand (file, XEXP (addr, 0), 0); 409 fprintf (file, "+]"); 410 break; 411 412 case PLUS: 413 { 414 rtx arg1 = XEXP (addr, 0); 415 rtx arg2 = XEXP (addr, 1); 416 rtx base, index; 417 418 if (REG_P (arg1) && RTX_OK_FOR_BASE (arg1, true)) 419 base = arg1, index = arg2; 420 else if (REG_P (arg2) && RTX_OK_FOR_BASE (arg2, true)) 421 base = arg2, index = arg1; 422 else 423 { 424 rx_print_operand (file, arg1, 0); 425 fprintf (file, " + "); 426 rx_print_operand (file, arg2, 0); 427 break; 428 } 429 430 if (REG_P (index) || GET_CODE (index) == MULT) 431 { 432 fprintf (file, "["); 433 rx_print_operand (file, index, 'A'); 434 fprintf (file, ","); 435 } 436 else /* GET_CODE (index) == CONST_INT */ 437 { 438 rx_print_operand (file, index, 'A'); 439 fprintf (file, "["); 440 } 441 rx_print_operand (file, base, 0); 442 fprintf (file, "]"); 443 break; 444 } 445 446 case CONST: 447 if (GET_CODE (XEXP (addr, 0)) == UNSPEC) 448 { 449 addr = XEXP (addr, 0); 450 gcc_assert (XINT (addr, 1) == UNSPEC_CONST); 451 452 addr = XVECEXP (addr, 0, 0); 453 gcc_assert (CONST_INT_P (addr)); 454 fprintf (file, "#"); 455 output_addr_const (file, addr); 456 break; 457 } 458 fprintf (file, "#"); 459 output_addr_const (file, XEXP (addr, 0)); 460 break; 461 462 case UNSPEC: 463 addr = XVECEXP (addr, 0, 0); 464 /* Fall through. */ 465 case LABEL_REF: 466 case SYMBOL_REF: 467 fprintf (file, "#"); 468 /* Fall through. */ 469 default: 470 output_addr_const (file, addr); 471 break; 472 } 473} 474 475static void 476rx_print_integer (FILE * file, HOST_WIDE_INT val) 477{ 478 if (val < 64) 479 fprintf (file, HOST_WIDE_INT_PRINT_DEC, val); 480 else 481 fprintf (file, 482 TARGET_AS100_SYNTAX 483 ? "0%" HOST_WIDE_INT_PRINT "xH" : HOST_WIDE_INT_PRINT_HEX, 484 val); 485} 486 487static bool 488rx_assemble_integer (rtx x, unsigned int size, int is_aligned) 489{ 490 const char * op = integer_asm_op (size, is_aligned); 491 492 if (! CONST_INT_P (x)) 493 return default_assemble_integer (x, size, is_aligned); 494 495 if (op == NULL) 496 return false; 497 fputs (op, asm_out_file); 498 499 rx_print_integer (asm_out_file, INTVAL (x)); 500 fputc ('\n', asm_out_file); 501 return true; 502} 503 504 505/* Handles the insertion of a single operand into the assembler output. 506 The %<letter> directives supported are: 507 508 %A Print an operand without a leading # character. 509 %B Print an integer comparison name. 510 %C Print a control register name. 511 %F Print a condition code flag name. 512 %G Register used for small-data-area addressing 513 %H Print high part of a DImode register, integer or address. 514 %L Print low part of a DImode register, integer or address. 515 %N Print the negation of the immediate value. 516 %P Register used for PID addressing 517 %Q If the operand is a MEM, then correctly generate 518 register indirect or register relative addressing. 519 %R Like %Q but for zero-extending loads. */ 520 521static void 522rx_print_operand (FILE * file, rtx op, int letter) 523{ 524 bool unsigned_load = false; 525 bool print_hash = true; 526 527 if (letter == 'A' 528 && ((GET_CODE (op) == CONST 529 && GET_CODE (XEXP (op, 0)) == UNSPEC) 530 || GET_CODE (op) == UNSPEC)) 531 { 532 print_hash = false; 533 letter = 0; 534 } 535 536 switch (letter) 537 { 538 case 'A': 539 /* Print an operand without a leading #. */ 540 if (MEM_P (op)) 541 op = XEXP (op, 0); 542 543 switch (GET_CODE (op)) 544 { 545 case LABEL_REF: 546 case SYMBOL_REF: 547 output_addr_const (file, op); 548 break; 549 case CONST_INT: 550 fprintf (file, "%ld", (long) INTVAL (op)); 551 break; 552 default: 553 rx_print_operand (file, op, 0); 554 break; 555 } 556 break; 557 558 case 'B': 559 { 560 enum rtx_code code = GET_CODE (op); 561 machine_mode mode = GET_MODE (XEXP (op, 0)); 562 const char *ret; 563 564 if (mode == CC_Fmode) 565 { 566 /* C flag is undefined, and O flag carries unordered. None of the 567 branch combinations that include O use it helpfully. */ 568 switch (code) 569 { 570 case ORDERED: 571 ret = "no"; 572 break; 573 case UNORDERED: 574 ret = "o"; 575 break; 576 case LT: 577 ret = "n"; 578 break; 579 case GE: 580 ret = "pz"; 581 break; 582 case EQ: 583 ret = "eq"; 584 break; 585 case NE: 586 ret = "ne"; 587 break; 588 default: 589 gcc_unreachable (); 590 } 591 } 592 else 593 { 594 unsigned int flags = flags_from_mode (mode); 595 596 switch (code) 597 { 598 case LT: 599 ret = (flags & CC_FLAG_O ? "lt" : "n"); 600 break; 601 case GE: 602 ret = (flags & CC_FLAG_O ? "ge" : "pz"); 603 break; 604 case GT: 605 ret = "gt"; 606 break; 607 case LE: 608 ret = "le"; 609 break; 610 case GEU: 611 ret = "geu"; 612 break; 613 case LTU: 614 ret = "ltu"; 615 break; 616 case GTU: 617 ret = "gtu"; 618 break; 619 case LEU: 620 ret = "leu"; 621 break; 622 case EQ: 623 ret = "eq"; 624 break; 625 case NE: 626 ret = "ne"; 627 break; 628 default: 629 gcc_unreachable (); 630 } 631 gcc_checking_assert ((flags_from_code (code) & ~flags) == 0); 632 } 633 fputs (ret, file); 634 break; 635 } 636 637 case 'C': 638 gcc_assert (CONST_INT_P (op)); 639 switch (INTVAL (op)) 640 { 641 case CTRLREG_PSW: fprintf (file, "psw"); break; 642 case CTRLREG_USP: fprintf (file, "usp"); break; 643 case CTRLREG_FPSW: fprintf (file, "fpsw"); break; 644 case CTRLREG_BPSW: fprintf (file, "bpsw"); break; 645 case CTRLREG_BPC: fprintf (file, "bpc"); break; 646 case CTRLREG_ISP: fprintf (file, "isp"); break; 647 case CTRLREG_FINTV: fprintf (file, "fintv"); break; 648 case CTRLREG_INTB: fprintf (file, "intb"); break; 649 default: 650 warning (0, "unrecognized control register number: %d" 651 " - using %<psw%>", (int) INTVAL (op)); 652 fprintf (file, "psw"); 653 break; 654 } 655 break; 656 657 case 'F': 658 gcc_assert (CONST_INT_P (op)); 659 switch (INTVAL (op)) 660 { 661 case 0: case 'c': case 'C': fprintf (file, "C"); break; 662 case 1: case 'z': case 'Z': fprintf (file, "Z"); break; 663 case 2: case 's': case 'S': fprintf (file, "S"); break; 664 case 3: case 'o': case 'O': fprintf (file, "O"); break; 665 case 8: case 'i': case 'I': fprintf (file, "I"); break; 666 case 9: case 'u': case 'U': fprintf (file, "U"); break; 667 default: 668 gcc_unreachable (); 669 } 670 break; 671 672 case 'G': 673 fprintf (file, "%s", reg_names [rx_gp_base_regnum ()]); 674 break; 675 676 case 'H': 677 switch (GET_CODE (op)) 678 { 679 case REG: 680 fprintf (file, "%s", reg_names [REGNO (op) + (WORDS_BIG_ENDIAN ? 0 : 1)]); 681 break; 682 case CONST_INT: 683 { 684 HOST_WIDE_INT v = INTVAL (op); 685 686 fprintf (file, "#"); 687 /* Trickery to avoid problems with shifting 32 bits at a time. */ 688 v = v >> 16; 689 v = v >> 16; 690 rx_print_integer (file, v); 691 break; 692 } 693 case CONST_DOUBLE: 694 fprintf (file, "#"); 695 rx_print_integer (file, CONST_DOUBLE_HIGH (op)); 696 break; 697 case MEM: 698 if (! WORDS_BIG_ENDIAN) 699 op = adjust_address (op, SImode, 4); 700 output_address (GET_MODE (op), XEXP (op, 0)); 701 break; 702 default: 703 gcc_unreachable (); 704 } 705 break; 706 707 case 'L': 708 switch (GET_CODE (op)) 709 { 710 case REG: 711 fprintf (file, "%s", reg_names [REGNO (op) + (WORDS_BIG_ENDIAN ? 1 : 0)]); 712 break; 713 case CONST_INT: 714 fprintf (file, "#"); 715 rx_print_integer (file, INTVAL (op) & 0xffffffff); 716 break; 717 case CONST_DOUBLE: 718 fprintf (file, "#"); 719 rx_print_integer (file, CONST_DOUBLE_LOW (op)); 720 break; 721 case MEM: 722 if (WORDS_BIG_ENDIAN) 723 op = adjust_address (op, SImode, 4); 724 output_address (GET_MODE (op), XEXP (op, 0)); 725 break; 726 default: 727 gcc_unreachable (); 728 } 729 break; 730 731 case 'N': 732 gcc_assert (CONST_INT_P (op)); 733 fprintf (file, "#"); 734 rx_print_integer (file, - INTVAL (op)); 735 break; 736 737 case 'P': 738 fprintf (file, "%s", reg_names [rx_pid_base_regnum ()]); 739 break; 740 741 case 'R': 742 gcc_assert (GET_MODE_SIZE (GET_MODE (op)) <= 4); 743 unsigned_load = true; 744 /* Fall through. */ 745 case 'Q': 746 if (MEM_P (op)) 747 { 748 HOST_WIDE_INT offset; 749 rtx mem = op; 750 751 op = XEXP (op, 0); 752 753 if (REG_P (op)) 754 offset = 0; 755 else if (GET_CODE (op) == PLUS) 756 { 757 rtx displacement; 758 759 if (REG_P (XEXP (op, 0))) 760 { 761 displacement = XEXP (op, 1); 762 op = XEXP (op, 0); 763 } 764 else 765 { 766 displacement = XEXP (op, 0); 767 op = XEXP (op, 1); 768 gcc_assert (REG_P (op)); 769 } 770 771 gcc_assert (CONST_INT_P (displacement)); 772 offset = INTVAL (displacement); 773 gcc_assert (offset >= 0); 774 775 fprintf (file, "%ld", offset); 776 } 777 else 778 gcc_unreachable (); 779 780 fprintf (file, "["); 781 rx_print_operand (file, op, 0); 782 fprintf (file, "]."); 783 784 switch (GET_MODE_SIZE (GET_MODE (mem))) 785 { 786 case 1: 787 gcc_assert (offset <= 65535 * 1); 788 fprintf (file, unsigned_load ? "UB" : "B"); 789 break; 790 case 2: 791 gcc_assert (offset % 2 == 0); 792 gcc_assert (offset <= 65535 * 2); 793 fprintf (file, unsigned_load ? "UW" : "W"); 794 break; 795 case 4: 796 gcc_assert (offset % 4 == 0); 797 gcc_assert (offset <= 65535 * 4); 798 fprintf (file, "L"); 799 break; 800 default: 801 gcc_unreachable (); 802 } 803 break; 804 } 805 806 /* Fall through. */ 807 808 default: 809 if (GET_CODE (op) == CONST 810 && GET_CODE (XEXP (op, 0)) == UNSPEC) 811 op = XEXP (op, 0); 812 else if (GET_CODE (op) == CONST 813 && GET_CODE (XEXP (op, 0)) == PLUS 814 && GET_CODE (XEXP (XEXP (op, 0), 0)) == UNSPEC 815 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT) 816 { 817 if (print_hash) 818 fprintf (file, "#"); 819 fprintf (file, "("); 820 rx_print_operand (file, XEXP (XEXP (op, 0), 0), 'A'); 821 fprintf (file, " + "); 822 output_addr_const (file, XEXP (XEXP (op, 0), 1)); 823 fprintf (file, ")"); 824 return; 825 } 826 827 switch (GET_CODE (op)) 828 { 829 case MULT: 830 /* Should be the scaled part of an 831 indexed register indirect address. */ 832 { 833 rtx base = XEXP (op, 0); 834 rtx index = XEXP (op, 1); 835 836 /* Check for a swaped index register and scaling factor. 837 Not sure if this can happen, but be prepared to handle it. */ 838 if (CONST_INT_P (base) && REG_P (index)) 839 { 840 rtx tmp = base; 841 base = index; 842 index = tmp; 843 } 844 845 gcc_assert (REG_P (base)); 846 gcc_assert (REGNO (base) < FIRST_PSEUDO_REGISTER); 847 gcc_assert (CONST_INT_P (index)); 848 /* Do not try to verify the value of the scalar as it is based 849 on the mode of the MEM not the mode of the MULT. (Which 850 will always be SImode). */ 851 fprintf (file, "%s", reg_names [REGNO (base)]); 852 break; 853 } 854 855 case MEM: 856 output_address (GET_MODE (op), XEXP (op, 0)); 857 break; 858 859 case PLUS: 860 output_address (VOIDmode, op); 861 break; 862 863 case REG: 864 gcc_assert (REGNO (op) < FIRST_PSEUDO_REGISTER); 865 fprintf (file, "%s", reg_names [REGNO (op)]); 866 break; 867 868 case SUBREG: 869 gcc_assert (subreg_regno (op) < FIRST_PSEUDO_REGISTER); 870 fprintf (file, "%s", reg_names [subreg_regno (op)]); 871 break; 872 873 /* This will only be single precision.... */ 874 case CONST_DOUBLE: 875 { 876 unsigned long val; 877 878 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (op), val); 879 if (print_hash) 880 fprintf (file, "#"); 881 fprintf (file, TARGET_AS100_SYNTAX ? "0%lxH" : "0x%lx", val); 882 break; 883 } 884 885 case CONST_INT: 886 if (print_hash) 887 fprintf (file, "#"); 888 rx_print_integer (file, INTVAL (op)); 889 break; 890 891 case UNSPEC: 892 switch (XINT (op, 1)) 893 { 894 case UNSPEC_PID_ADDR: 895 { 896 rtx sym, add; 897 898 if (print_hash) 899 fprintf (file, "#"); 900 sym = XVECEXP (op, 0, 0); 901 add = NULL_RTX; 902 fprintf (file, "("); 903 if (GET_CODE (sym) == PLUS) 904 { 905 add = XEXP (sym, 1); 906 sym = XEXP (sym, 0); 907 } 908 output_addr_const (file, sym); 909 if (add != NULL_RTX) 910 { 911 fprintf (file, "+"); 912 output_addr_const (file, add); 913 } 914 fprintf (file, "-__pid_base"); 915 fprintf (file, ")"); 916 return; 917 } 918 } 919 /* Fall through */ 920 921 case CONST: 922 case SYMBOL_REF: 923 case LABEL_REF: 924 case CODE_LABEL: 925 rx_print_operand_address (file, VOIDmode, op); 926 break; 927 928 default: 929 gcc_unreachable (); 930 } 931 break; 932 } 933} 934 935/* Maybe convert an operand into its PID format. */ 936 937rtx 938rx_maybe_pidify_operand (rtx op, int copy_to_reg) 939{ 940 if (rx_pid_data_operand (op) == PID_UNENCODED) 941 { 942 if (GET_CODE (op) == MEM) 943 { 944 rtx a = gen_pid_addr (gen_rtx_REG (SImode, rx_pid_base_regnum ()), XEXP (op, 0)); 945 op = replace_equiv_address (op, a); 946 } 947 else 948 { 949 op = gen_pid_addr (gen_rtx_REG (SImode, rx_pid_base_regnum ()), op); 950 } 951 952 if (copy_to_reg) 953 op = copy_to_mode_reg (GET_MODE (op), op); 954 } 955 return op; 956} 957 958/* Returns an assembler template for a move instruction. */ 959 960char * 961rx_gen_move_template (rtx * operands, bool is_movu) 962{ 963 static char out_template [64]; 964 const char * extension = TARGET_AS100_SYNTAX ? ".L" : ""; 965 const char * src_template; 966 const char * dst_template; 967 rtx dest = operands[0]; 968 rtx src = operands[1]; 969 970 /* Decide which extension, if any, should be given to the move instruction. */ 971 switch (CONST_INT_P (src) ? GET_MODE (dest) : GET_MODE (src)) 972 { 973 case E_QImode: 974 /* The .B extension is not valid when 975 loading an immediate into a register. */ 976 if (! REG_P (dest) || ! CONST_INT_P (src)) 977 extension = ".B"; 978 break; 979 case E_HImode: 980 if (! REG_P (dest) || ! CONST_INT_P (src)) 981 /* The .W extension is not valid when 982 loading an immediate into a register. */ 983 extension = ".W"; 984 break; 985 case E_DFmode: 986 case E_DImode: 987 case E_SFmode: 988 case E_SImode: 989 extension = ".L"; 990 break; 991 case E_VOIDmode: 992 /* This mode is used by constants. */ 993 break; 994 default: 995 debug_rtx (src); 996 gcc_unreachable (); 997 } 998 999 if (MEM_P (src) && rx_pid_data_operand (XEXP (src, 0)) == PID_UNENCODED) 1000 { 1001 gcc_assert (GET_MODE (src) != DImode); 1002 gcc_assert (GET_MODE (src) != DFmode); 1003 1004 src_template = "(%A1 - __pid_base)[%P1]"; 1005 } 1006 else if (MEM_P (src) && rx_small_data_operand (XEXP (src, 0))) 1007 { 1008 gcc_assert (GET_MODE (src) != DImode); 1009 gcc_assert (GET_MODE (src) != DFmode); 1010 1011 src_template = "%%gp(%A1)[%G1]"; 1012 } 1013 else 1014 src_template = "%1"; 1015 1016 if (MEM_P (dest) && rx_small_data_operand (XEXP (dest, 0))) 1017 { 1018 gcc_assert (GET_MODE (dest) != DImode); 1019 gcc_assert (GET_MODE (dest) != DFmode); 1020 1021 dst_template = "%%gp(%A0)[%G0]"; 1022 } 1023 else 1024 dst_template = "%0"; 1025 1026 if (GET_MODE (dest) == DImode || GET_MODE (dest) == DFmode) 1027 { 1028 gcc_assert (! is_movu); 1029 1030 if (REG_P (src) && REG_P (dest) && (REGNO (dest) == REGNO (src) + 1)) 1031 sprintf (out_template, "mov.L\t%%H1, %%H0 ! mov.L\t%%1, %%0"); 1032 else 1033 sprintf (out_template, "mov.L\t%%1, %%0 ! mov.L\t%%H1, %%H0"); 1034 } 1035 else 1036 sprintf (out_template, "%s%s\t%s, %s", is_movu ? "movu" : "mov", 1037 extension, src_template, dst_template); 1038 return out_template; 1039} 1040 1041/* Return VALUE rounded up to the next ALIGNMENT boundary. */ 1042 1043static inline unsigned int 1044rx_round_up (unsigned int value, unsigned int alignment) 1045{ 1046 alignment -= 1; 1047 return (value + alignment) & (~ alignment); 1048} 1049 1050/* Return the number of bytes in the argument registers 1051 occupied by an argument of type TYPE and mode MODE. */ 1052 1053static unsigned int 1054rx_function_arg_size (machine_mode mode, const_tree type) 1055{ 1056 unsigned int num_bytes; 1057 1058 num_bytes = (mode == BLKmode) 1059 ? int_size_in_bytes (type) : GET_MODE_SIZE (mode); 1060 return rx_round_up (num_bytes, UNITS_PER_WORD); 1061} 1062 1063#define NUM_ARG_REGS 4 1064#define MAX_NUM_ARG_BYTES (NUM_ARG_REGS * UNITS_PER_WORD) 1065 1066/* Return an RTL expression describing the register holding function 1067 argument ARG or NULL_RTX if the parameter should be passed on the 1068 stack. CUM describes the previous parameters to the function. */ 1069 1070static rtx 1071rx_function_arg (cumulative_args_t cum, const function_arg_info &arg) 1072{ 1073 unsigned int next_reg; 1074 unsigned int bytes_so_far = *get_cumulative_args (cum); 1075 unsigned int size; 1076 unsigned int rounded_size; 1077 1078 size = arg.promoted_size_in_bytes (); 1079 /* If the size is not known it cannot be passed in registers. */ 1080 if (size < 1) 1081 return NULL_RTX; 1082 1083 rounded_size = rx_round_up (size, UNITS_PER_WORD); 1084 1085 /* Don't pass this arg via registers if there 1086 are insufficient registers to hold all of it. */ 1087 if (rounded_size + bytes_so_far > MAX_NUM_ARG_BYTES) 1088 return NULL_RTX; 1089 1090 /* Unnamed arguments and the last named argument in a 1091 variadic function are always passed on the stack. */ 1092 if (!arg.named) 1093 return NULL_RTX; 1094 1095 /* Structures must occupy an exact number of registers, 1096 otherwise they are passed on the stack. */ 1097 if ((arg.type == NULL || AGGREGATE_TYPE_P (arg.type)) 1098 && (size % UNITS_PER_WORD) != 0) 1099 return NULL_RTX; 1100 1101 next_reg = (bytes_so_far / UNITS_PER_WORD) + 1; 1102 1103 return gen_rtx_REG (arg.mode, next_reg); 1104} 1105 1106static void 1107rx_function_arg_advance (cumulative_args_t cum, 1108 const function_arg_info &arg) 1109{ 1110 *get_cumulative_args (cum) += rx_function_arg_size (arg.mode, arg.type); 1111} 1112 1113static unsigned int 1114rx_function_arg_boundary (machine_mode mode ATTRIBUTE_UNUSED, 1115 const_tree type ATTRIBUTE_UNUSED) 1116{ 1117 /* Older versions of the RX backend aligned all on-stack arguments 1118 to 32-bits. The RX C ABI however says that they should be 1119 aligned to their natural alignment. (See section 5.2.2 of the ABI). */ 1120 if (TARGET_GCC_ABI) 1121 return STACK_BOUNDARY; 1122 1123 if (type) 1124 { 1125 if (DECL_P (type)) 1126 return DECL_ALIGN (type); 1127 return TYPE_ALIGN (type); 1128 } 1129 1130 return PARM_BOUNDARY; 1131} 1132 1133/* Return an RTL describing where a function return value of type RET_TYPE 1134 is held. */ 1135 1136static rtx 1137rx_function_value (const_tree ret_type, 1138 const_tree fn_decl_or_type ATTRIBUTE_UNUSED, 1139 bool outgoing ATTRIBUTE_UNUSED) 1140{ 1141 machine_mode mode = TYPE_MODE (ret_type); 1142 1143 /* RX ABI specifies that small integer types are 1144 promoted to int when returned by a function. */ 1145 if (GET_MODE_SIZE (mode) > 0 1146 && GET_MODE_SIZE (mode) < 4 1147 && ! COMPLEX_MODE_P (mode) 1148 && ! VECTOR_TYPE_P (ret_type) 1149 && ! VECTOR_MODE_P (mode) 1150 ) 1151 return gen_rtx_REG (SImode, FUNC_RETURN_REGNUM); 1152 1153 return gen_rtx_REG (mode, FUNC_RETURN_REGNUM); 1154} 1155 1156/* TARGET_PROMOTE_FUNCTION_MODE must behave in the same way with 1157 regard to function returns as does TARGET_FUNCTION_VALUE. */ 1158 1159static machine_mode 1160rx_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, 1161 machine_mode mode, 1162 int * punsignedp ATTRIBUTE_UNUSED, 1163 const_tree funtype ATTRIBUTE_UNUSED, 1164 int for_return) 1165{ 1166 if (for_return != 1 1167 || GET_MODE_SIZE (mode) >= 4 1168 || COMPLEX_MODE_P (mode) 1169 || VECTOR_MODE_P (mode) 1170 || VECTOR_TYPE_P (type) 1171 || GET_MODE_SIZE (mode) < 1) 1172 return mode; 1173 1174 return SImode; 1175} 1176 1177static bool 1178rx_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) 1179{ 1180 HOST_WIDE_INT size; 1181 1182 if (TYPE_MODE (type) != BLKmode 1183 && ! AGGREGATE_TYPE_P (type)) 1184 return false; 1185 1186 size = int_size_in_bytes (type); 1187 /* Large structs and those whose size is not an 1188 exact multiple of 4 are returned in memory. */ 1189 return size < 1 1190 || size > 16 1191 || (size % UNITS_PER_WORD) != 0; 1192} 1193 1194static rtx 1195rx_struct_value_rtx (tree fndecl ATTRIBUTE_UNUSED, 1196 int incoming ATTRIBUTE_UNUSED) 1197{ 1198 return gen_rtx_REG (Pmode, STRUCT_VAL_REGNUM); 1199} 1200 1201static bool 1202rx_return_in_msb (const_tree valtype) 1203{ 1204 return TARGET_BIG_ENDIAN_DATA 1205 && (AGGREGATE_TYPE_P (valtype) || TREE_CODE (valtype) == COMPLEX_TYPE); 1206} 1207 1208/* Returns true if the provided function has the specified attribute. */ 1209 1210static inline bool 1211has_func_attr (const_tree decl, const char * func_attr) 1212{ 1213 if (decl == NULL_TREE) 1214 decl = current_function_decl; 1215 1216 return lookup_attribute (func_attr, DECL_ATTRIBUTES (decl)) != NULL_TREE; 1217} 1218 1219/* Returns true if the provided function has the "fast_interrupt" attribute. */ 1220 1221bool 1222is_fast_interrupt_func (const_tree decl) 1223{ 1224 return has_func_attr (decl, "fast_interrupt"); 1225} 1226 1227/* Returns true if the provided function has the "interrupt" attribute. */ 1228 1229bool 1230is_interrupt_func (const_tree decl) 1231{ 1232 return has_func_attr (decl, "interrupt"); 1233} 1234 1235/* Returns true if the provided function has the "naked" attribute. */ 1236 1237static inline bool 1238is_naked_func (const_tree decl) 1239{ 1240 return has_func_attr (decl, "naked"); 1241} 1242 1243static bool use_fixed_regs = false; 1244 1245static void 1246rx_conditional_register_usage (void) 1247{ 1248 static bool using_fixed_regs = false; 1249 1250 if (TARGET_PID) 1251 { 1252 rx_pid_base_regnum_val = GP_BASE_REGNUM - rx_num_interrupt_regs; 1253 fixed_regs[rx_pid_base_regnum_val] = call_used_regs [rx_pid_base_regnum_val] = 1; 1254 } 1255 1256 if (rx_small_data_limit > 0) 1257 { 1258 if (TARGET_PID) 1259 rx_gp_base_regnum_val = rx_pid_base_regnum_val - 1; 1260 else 1261 rx_gp_base_regnum_val = GP_BASE_REGNUM - rx_num_interrupt_regs; 1262 1263 fixed_regs[rx_gp_base_regnum_val] = call_used_regs [rx_gp_base_regnum_val] = 1; 1264 } 1265 1266 if (use_fixed_regs != using_fixed_regs) 1267 { 1268 static char saved_fixed_regs[FIRST_PSEUDO_REGISTER]; 1269 static char saved_call_used_regs[FIRST_PSEUDO_REGISTER]; 1270 1271 if (use_fixed_regs) 1272 { 1273 unsigned int r; 1274 1275 memcpy (saved_fixed_regs, fixed_regs, sizeof fixed_regs); 1276 memcpy (saved_call_used_regs, call_used_regs, sizeof call_used_regs); 1277 1278 /* This is for fast interrupt handlers. Any register in 1279 the range r10 to r13 (inclusive) that is currently 1280 marked as fixed is now a viable, call-used register. */ 1281 for (r = 10; r <= 13; r++) 1282 if (fixed_regs[r]) 1283 { 1284 fixed_regs[r] = 0; 1285 call_used_regs[r] = 1; 1286 } 1287 1288 /* Mark r7 as fixed. This is just a hack to avoid 1289 altering the reg_alloc_order array so that the newly 1290 freed r10-r13 registers are the preferred registers. */ 1291 fixed_regs[7] = call_used_regs[7] = 1; 1292 } 1293 else 1294 { 1295 /* Restore the normal register masks. */ 1296 memcpy (fixed_regs, saved_fixed_regs, sizeof fixed_regs); 1297 memcpy (call_used_regs, saved_call_used_regs, sizeof call_used_regs); 1298 } 1299 1300 using_fixed_regs = use_fixed_regs; 1301 } 1302} 1303 1304struct decl_chain 1305{ 1306 tree fndecl; 1307 struct decl_chain * next; 1308}; 1309 1310/* Stack of decls for which we have issued warnings. */ 1311static struct decl_chain * warned_decls = NULL; 1312 1313static void 1314add_warned_decl (tree fndecl) 1315{ 1316 struct decl_chain * warned = (struct decl_chain *) xmalloc (sizeof * warned); 1317 1318 warned->fndecl = fndecl; 1319 warned->next = warned_decls; 1320 warned_decls = warned; 1321} 1322 1323/* Returns TRUE if FNDECL is on our list of warned about decls. */ 1324 1325static bool 1326already_warned (tree fndecl) 1327{ 1328 struct decl_chain * warned; 1329 1330 for (warned = warned_decls; 1331 warned != NULL; 1332 warned = warned->next) 1333 if (warned->fndecl == fndecl) 1334 return true; 1335 1336 return false; 1337} 1338 1339/* Perform any actions necessary before starting to compile FNDECL. 1340 For the RX we use this to make sure that we have the correct 1341 set of register masks selected. If FNDECL is NULL then we are 1342 compiling top level things. */ 1343 1344static void 1345rx_set_current_function (tree fndecl) 1346{ 1347 /* Remember the last target of rx_set_current_function. */ 1348 static tree rx_previous_fndecl; 1349 bool prev_was_fast_interrupt; 1350 bool current_is_fast_interrupt; 1351 1352 /* Only change the context if the function changes. This hook is called 1353 several times in the course of compiling a function, and we don't want 1354 to slow things down too much or call target_reinit when it isn't safe. */ 1355 if (fndecl == rx_previous_fndecl) 1356 return; 1357 1358 prev_was_fast_interrupt 1359 = rx_previous_fndecl 1360 ? is_fast_interrupt_func (rx_previous_fndecl) : false; 1361 1362 current_is_fast_interrupt 1363 = fndecl ? is_fast_interrupt_func (fndecl) : false; 1364 1365 if (prev_was_fast_interrupt != current_is_fast_interrupt) 1366 { 1367 use_fixed_regs = current_is_fast_interrupt; 1368 target_reinit (); 1369 } 1370 1371 if (current_is_fast_interrupt && rx_warn_multiple_fast_interrupts) 1372 { 1373 /* We do not warn about the first fast interrupt routine that 1374 we see. Instead we just push it onto the stack. */ 1375 if (warned_decls == NULL) 1376 add_warned_decl (fndecl); 1377 1378 /* Otherwise if this fast interrupt is one for which we have 1379 not already issued a warning, generate one and then push 1380 it onto the stack as well. */ 1381 else if (! already_warned (fndecl)) 1382 { 1383 warning (0, "multiple fast interrupt routines seen: %qE and %qE", 1384 fndecl, warned_decls->fndecl); 1385 add_warned_decl (fndecl); 1386 } 1387 } 1388 1389 rx_previous_fndecl = fndecl; 1390} 1391 1392/* Typical stack layout should looks like this after the function's prologue: 1393 1394 | | 1395 -- ^ 1396 | | \ | 1397 | | arguments saved | Increasing 1398 | | on the stack | addresses 1399 PARENT arg pointer -> | | / 1400 -------------------------- ---- ------------------- 1401 CHILD |ret | return address 1402 -- 1403 | | \ 1404 | | call saved 1405 | | registers 1406 | | / 1407 -- 1408 | | \ 1409 | | local 1410 | | variables 1411 frame pointer -> | | / 1412 -- 1413 | | \ 1414 | | outgoing | Decreasing 1415 | | arguments | addresses 1416 current stack pointer -> | | / | 1417 -------------------------- ---- ------------------ V 1418 | | */ 1419 1420static unsigned int 1421bit_count (unsigned int x) 1422{ 1423 const unsigned int m1 = 0x55555555; 1424 const unsigned int m2 = 0x33333333; 1425 const unsigned int m4 = 0x0f0f0f0f; 1426 1427 x -= (x >> 1) & m1; 1428 x = (x & m2) + ((x >> 2) & m2); 1429 x = (x + (x >> 4)) & m4; 1430 x += x >> 8; 1431 1432 return (x + (x >> 16)) & 0x3f; 1433} 1434 1435#if defined(TARGET_SAVE_ACC_REGISTER) 1436#define MUST_SAVE_ACC_REGISTER \ 1437 (TARGET_SAVE_ACC_REGISTER \ 1438 && (is_interrupt_func (NULL_TREE) \ 1439 || is_fast_interrupt_func (NULL_TREE))) 1440#else 1441#define MUST_SAVE_ACC_REGISTER 0 1442#endif 1443 1444/* Returns either the lowest numbered and highest numbered registers that 1445 occupy the call-saved area of the stack frame, if the registers are 1446 stored as a contiguous block, or else a bitmask of the individual 1447 registers if they are stored piecemeal. 1448 1449 Also computes the size of the frame and the size of the outgoing 1450 arguments block (in bytes). */ 1451 1452static void 1453rx_get_stack_layout (unsigned int * lowest, 1454 unsigned int * highest, 1455 unsigned int * register_mask, 1456 unsigned int * frame_size, 1457 unsigned int * stack_size) 1458{ 1459 unsigned int reg; 1460 unsigned int low; 1461 unsigned int high; 1462 unsigned int fixed_reg = 0; 1463 unsigned int save_mask; 1464 unsigned int pushed_mask; 1465 unsigned int unneeded_pushes; 1466 1467 if (is_naked_func (NULL_TREE)) 1468 { 1469 /* Naked functions do not create their own stack frame. 1470 Instead the programmer must do that for us. */ 1471 * lowest = 0; 1472 * highest = 0; 1473 * register_mask = 0; 1474 * frame_size = 0; 1475 * stack_size = 0; 1476 return; 1477 } 1478 1479 for (save_mask = high = low = 0, reg = 1; reg < CC_REGNUM; reg++) 1480 { 1481 if ((df_regs_ever_live_p (reg) 1482 /* Always save all call clobbered registers inside non-leaf 1483 interrupt handlers, even if they are not live - they may 1484 be used in (non-interrupt aware) routines called from this one. */ 1485 || (call_used_or_fixed_reg_p (reg) 1486 && is_interrupt_func (NULL_TREE) 1487 && ! crtl->is_leaf)) 1488 && (! call_used_or_fixed_reg_p (reg) 1489 /* Even call clobbered registered must 1490 be pushed inside interrupt handlers. */ 1491 || is_interrupt_func (NULL_TREE) 1492 /* Likewise for fast interrupt handlers, except registers r10 - 1493 r13. These are normally call-saved, but may have been set 1494 to call-used by rx_conditional_register_usage. If so then 1495 they can be used in the fast interrupt handler without 1496 saving them on the stack. */ 1497 || (is_fast_interrupt_func (NULL_TREE) 1498 && ! IN_RANGE (reg, 10, 13)))) 1499 { 1500 if (low == 0) 1501 low = reg; 1502 high = reg; 1503 1504 save_mask |= 1 << reg; 1505 } 1506 1507 /* Remember if we see a fixed register 1508 after having found the low register. */ 1509 if (low != 0 && fixed_reg == 0 && fixed_regs [reg]) 1510 fixed_reg = reg; 1511 } 1512 1513 /* If we have to save the accumulator register, make sure 1514 that at least two registers are pushed into the frame. */ 1515 if (MUST_SAVE_ACC_REGISTER 1516 && bit_count (save_mask) < 2) 1517 { 1518 save_mask |= (1 << 13) | (1 << 14); 1519 if (low == 0) 1520 low = 13; 1521 if (high == 0 || low == high) 1522 high = low + 1; 1523 } 1524 1525 /* Decide if it would be faster fill in the call-saved area of the stack 1526 frame using multiple PUSH instructions instead of a single PUSHM 1527 instruction. 1528 1529 SAVE_MASK is a bitmask of the registers that must be stored in the 1530 call-save area. PUSHED_MASK is a bitmask of the registers that would 1531 be pushed into the area if we used a PUSHM instruction. UNNEEDED_PUSHES 1532 is a bitmask of those registers in pushed_mask that are not in 1533 save_mask. 1534 1535 We use a simple heuristic that says that it is better to use 1536 multiple PUSH instructions if the number of unnecessary pushes is 1537 greater than the number of necessary pushes. 1538 1539 We also use multiple PUSH instructions if there are any fixed registers 1540 between LOW and HIGH. The only way that this can happen is if the user 1541 has specified --fixed-<reg-name> on the command line and in such 1542 circumstances we do not want to touch the fixed registers at all. 1543 1544 Note also that the code in the prologue/epilogue handlers will 1545 automatically merge multiple PUSHes of adjacent registers into a single 1546 PUSHM. 1547 1548 FIXME: Is it worth improving this heuristic ? */ 1549 pushed_mask = (HOST_WIDE_INT_M1U << low) & ~(HOST_WIDE_INT_M1U << (high + 1)); 1550 unneeded_pushes = (pushed_mask & (~ save_mask)) & pushed_mask; 1551 1552 if ((fixed_reg && fixed_reg <= high) 1553 || (optimize_function_for_speed_p (cfun) 1554 && bit_count (save_mask) < bit_count (unneeded_pushes))) 1555 { 1556 /* Use multiple pushes. */ 1557 * lowest = 0; 1558 * highest = 0; 1559 * register_mask = save_mask; 1560 } 1561 else 1562 { 1563 /* Use one push multiple instruction. */ 1564 * lowest = low; 1565 * highest = high; 1566 * register_mask = 0; 1567 } 1568 1569 * frame_size = rx_round_up 1570 (get_frame_size (), STACK_BOUNDARY / BITS_PER_UNIT); 1571 1572 if (crtl->args.size > 0) 1573 * frame_size += rx_round_up 1574 (crtl->args.size, STACK_BOUNDARY / BITS_PER_UNIT); 1575 1576 * stack_size = rx_round_up 1577 (crtl->outgoing_args_size, STACK_BOUNDARY / BITS_PER_UNIT); 1578} 1579 1580/* Generate a PUSHM instruction that matches the given operands. */ 1581 1582void 1583rx_emit_stack_pushm (rtx * operands) 1584{ 1585 HOST_WIDE_INT last_reg; 1586 rtx first_push; 1587 1588 gcc_assert (CONST_INT_P (operands[0])); 1589 last_reg = (INTVAL (operands[0]) / UNITS_PER_WORD) - 1; 1590 1591 gcc_assert (GET_CODE (operands[1]) == PARALLEL); 1592 first_push = XVECEXP (operands[1], 0, 1); 1593 gcc_assert (SET_P (first_push)); 1594 first_push = SET_SRC (first_push); 1595 gcc_assert (REG_P (first_push)); 1596 1597 asm_fprintf (asm_out_file, "\tpushm\t%s-%s\n", 1598 reg_names [REGNO (first_push) - last_reg], 1599 reg_names [REGNO (first_push)]); 1600} 1601 1602/* Generate a PARALLEL that will pass the rx_store_multiple_vector predicate. */ 1603 1604static rtx 1605gen_rx_store_vector (unsigned int low, unsigned int high) 1606{ 1607 unsigned int i; 1608 unsigned int count = (high - low) + 2; 1609 rtx vector; 1610 1611 vector = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count)); 1612 1613 XVECEXP (vector, 0, 0) = 1614 gen_rtx_SET (stack_pointer_rtx, 1615 gen_rtx_MINUS (SImode, stack_pointer_rtx, 1616 GEN_INT ((count - 1) * UNITS_PER_WORD))); 1617 1618 for (i = 0; i < count - 1; i++) 1619 XVECEXP (vector, 0, i + 1) = 1620 gen_rtx_SET (gen_rtx_MEM (SImode, 1621 gen_rtx_MINUS (SImode, stack_pointer_rtx, 1622 GEN_INT ((i + 1) * UNITS_PER_WORD))), 1623 gen_rtx_REG (SImode, high - i)); 1624 return vector; 1625} 1626 1627/* Mark INSN as being frame related. If it is a PARALLEL 1628 then mark each element as being frame related as well. */ 1629 1630static void 1631mark_frame_related (rtx insn) 1632{ 1633 RTX_FRAME_RELATED_P (insn) = 1; 1634 insn = PATTERN (insn); 1635 1636 if (GET_CODE (insn) == PARALLEL) 1637 { 1638 unsigned int i; 1639 1640 for (i = 0; i < (unsigned) XVECLEN (insn, 0); i++) 1641 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, i)) = 1; 1642 } 1643} 1644 1645/* Create CFI notes for register pops. */ 1646static void 1647add_pop_cfi_notes (rtx_insn *insn, unsigned int high, unsigned int low) 1648{ 1649 rtx t = plus_constant (Pmode, stack_pointer_rtx, 1650 (high - low + 1) * UNITS_PER_WORD); 1651 t = gen_rtx_SET (stack_pointer_rtx, t); 1652 add_reg_note (insn, REG_CFA_ADJUST_CFA, t); 1653 RTX_FRAME_RELATED_P (insn) = 1; 1654 for (unsigned int i = low; i <= high; i++) 1655 add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (word_mode, i)); 1656} 1657 1658 1659static bool 1660ok_for_max_constant (HOST_WIDE_INT val) 1661{ 1662 if (rx_max_constant_size == 0 || rx_max_constant_size == 4) 1663 /* If there is no constraint on the size of constants 1664 used as operands, then any value is legitimate. */ 1665 return true; 1666 1667 /* rx_max_constant_size specifies the maximum number 1668 of bytes that can be used to hold a signed value. */ 1669 return IN_RANGE (val, (HOST_WIDE_INT_M1U << (rx_max_constant_size * 8)), 1670 ( 1 << (rx_max_constant_size * 8))); 1671} 1672 1673/* Generate an ADD of SRC plus VAL into DEST. 1674 Handles the case where VAL is too big for max_constant_value. 1675 Sets FRAME_RELATED_P on the insn if IS_FRAME_RELATED is true. */ 1676 1677static void 1678gen_safe_add (rtx dest, rtx src, rtx val, bool is_frame_related) 1679{ 1680 rtx insn; 1681 1682 if (val == NULL_RTX || INTVAL (val) == 0) 1683 { 1684 gcc_assert (dest != src); 1685 1686 insn = emit_move_insn (dest, src); 1687 } 1688 else if (ok_for_max_constant (INTVAL (val))) 1689 insn = emit_insn (gen_addsi3 (dest, src, val)); 1690 else 1691 { 1692 /* Wrap VAL in an UNSPEC so that rx_is_legitimate_constant 1693 will not reject it. */ 1694 val = gen_rtx_CONST (SImode, gen_rtx_UNSPEC (SImode, gen_rtvec (1, val), UNSPEC_CONST)); 1695 insn = emit_insn (gen_addsi3 (dest, src, val)); 1696 1697 if (is_frame_related) 1698 /* We have to provide our own frame related note here 1699 as the dwarf2out code cannot be expected to grok 1700 our unspec. */ 1701 add_reg_note (insn, REG_FRAME_RELATED_EXPR, 1702 gen_rtx_SET (dest, gen_rtx_PLUS (SImode, src, val))); 1703 return; 1704 } 1705 1706 if (is_frame_related) 1707 RTX_FRAME_RELATED_P (insn) = 1; 1708} 1709 1710static void 1711push_regs (unsigned int high, unsigned int low) 1712{ 1713 rtx insn; 1714 1715 if (low == high) 1716 insn = emit_insn (gen_stack_push (gen_rtx_REG (SImode, low))); 1717 else 1718 insn = emit_insn (gen_stack_pushm (GEN_INT (((high - low) + 1) * UNITS_PER_WORD), 1719 gen_rx_store_vector (low, high))); 1720 mark_frame_related (insn); 1721} 1722 1723void 1724rx_expand_prologue (void) 1725{ 1726 unsigned int stack_size; 1727 unsigned int frame_size; 1728 unsigned int mask; 1729 unsigned int low; 1730 unsigned int high; 1731 unsigned int reg; 1732 1733 /* Naked functions use their own, programmer provided prologues. */ 1734 if (is_naked_func (NULL_TREE)) 1735 return; 1736 1737 rx_get_stack_layout (& low, & high, & mask, & frame_size, & stack_size); 1738 1739 if (flag_stack_usage_info) 1740 current_function_static_stack_size = frame_size + stack_size; 1741 1742 /* If we use any of the callee-saved registers, save them now. */ 1743 if (mask) 1744 { 1745 /* Push registers in reverse order. */ 1746 for (reg = CC_REGNUM; reg --;) 1747 if (mask & (1 << reg)) 1748 { 1749 low = high = reg; 1750 1751 /* Look for a span of registers. 1752 Note - we do not have to worry about -Os and whether 1753 it is better to use a single, longer PUSHM as 1754 rx_get_stack_layout has already done that for us. */ 1755 while (reg-- > 0) 1756 if ((mask & (1 << reg)) == 0) 1757 break; 1758 else 1759 --low; 1760 1761 push_regs (high, low); 1762 if (reg == (unsigned) -1) 1763 break; 1764 } 1765 } 1766 else if (low) 1767 push_regs (high, low); 1768 1769 if (MUST_SAVE_ACC_REGISTER) 1770 { 1771 unsigned int acc_high, acc_low; 1772 1773 /* Interrupt handlers have to preserve the accumulator 1774 register if so requested by the user. Use the first 1775 two pushed registers as intermediaries. */ 1776 if (mask) 1777 { 1778 acc_low = acc_high = 0; 1779 1780 for (reg = 1; reg < CC_REGNUM; reg ++) 1781 if (mask & (1 << reg)) 1782 { 1783 if (acc_low == 0) 1784 acc_low = reg; 1785 else 1786 { 1787 acc_high = reg; 1788 break; 1789 } 1790 } 1791 1792 /* We have assumed that there are at least two registers pushed... */ 1793 gcc_assert (acc_high != 0); 1794 1795 /* Note - the bottom 16 bits of the accumulator are inaccessible. 1796 We just assume that they are zero. */ 1797 emit_insn (gen_mvfacmi (gen_rtx_REG (SImode, acc_low))); 1798 emit_insn (gen_mvfachi (gen_rtx_REG (SImode, acc_high))); 1799 emit_insn (gen_stack_push (gen_rtx_REG (SImode, acc_low))); 1800 emit_insn (gen_stack_push (gen_rtx_REG (SImode, acc_high))); 1801 } 1802 else 1803 { 1804 acc_low = low; 1805 acc_high = low + 1; 1806 1807 /* We have assumed that there are at least two registers pushed... */ 1808 gcc_assert (acc_high <= high); 1809 1810 emit_insn (gen_mvfacmi (gen_rtx_REG (SImode, acc_low))); 1811 emit_insn (gen_mvfachi (gen_rtx_REG (SImode, acc_high))); 1812 emit_insn (gen_stack_pushm (GEN_INT (2 * UNITS_PER_WORD), 1813 gen_rx_store_vector (acc_low, acc_high))); 1814 } 1815 } 1816 1817 /* If needed, set up the frame pointer. */ 1818 if (frame_pointer_needed) 1819 gen_safe_add (frame_pointer_rtx, stack_pointer_rtx, 1820 GEN_INT (- (HOST_WIDE_INT) frame_size), true); 1821 1822 /* Allocate space for the outgoing args. 1823 If the stack frame has not already been set up then handle this as well. */ 1824 if (stack_size) 1825 { 1826 if (frame_size) 1827 { 1828 if (frame_pointer_needed) 1829 gen_safe_add (stack_pointer_rtx, frame_pointer_rtx, 1830 GEN_INT (- (HOST_WIDE_INT) stack_size), true); 1831 else 1832 gen_safe_add (stack_pointer_rtx, stack_pointer_rtx, 1833 GEN_INT (- (HOST_WIDE_INT) (frame_size + stack_size)), 1834 true); 1835 } 1836 else 1837 gen_safe_add (stack_pointer_rtx, stack_pointer_rtx, 1838 GEN_INT (- (HOST_WIDE_INT) stack_size), true); 1839 } 1840 else if (frame_size) 1841 { 1842 if (! frame_pointer_needed) 1843 gen_safe_add (stack_pointer_rtx, stack_pointer_rtx, 1844 GEN_INT (- (HOST_WIDE_INT) frame_size), true); 1845 else 1846 gen_safe_add (stack_pointer_rtx, frame_pointer_rtx, NULL_RTX, 1847 false /* False because the epilogue will use the FP not the SP. */); 1848 } 1849} 1850 1851static void 1852add_vector_labels (FILE *file, const char *aname) 1853{ 1854 tree vec_attr; 1855 tree val_attr; 1856 const char *vname = "vect"; 1857 const char *s; 1858 int vnum; 1859 1860 /* This node is for the vector/interrupt tag itself */ 1861 vec_attr = lookup_attribute (aname, DECL_ATTRIBUTES (current_function_decl)); 1862 if (!vec_attr) 1863 return; 1864 1865 /* Now point it at the first argument */ 1866 vec_attr = TREE_VALUE (vec_attr); 1867 1868 /* Iterate through the arguments. */ 1869 while (vec_attr) 1870 { 1871 val_attr = TREE_VALUE (vec_attr); 1872 switch (TREE_CODE (val_attr)) 1873 { 1874 case STRING_CST: 1875 s = TREE_STRING_POINTER (val_attr); 1876 goto string_id_common; 1877 1878 case IDENTIFIER_NODE: 1879 s = IDENTIFIER_POINTER (val_attr); 1880 1881 string_id_common: 1882 if (strcmp (s, "$default") == 0) 1883 { 1884 fprintf (file, "\t.global\t$tableentry$default$%s\n", vname); 1885 fprintf (file, "$tableentry$default$%s:\n", vname); 1886 } 1887 else 1888 vname = s; 1889 break; 1890 1891 case INTEGER_CST: 1892 vnum = TREE_INT_CST_LOW (val_attr); 1893 1894 fprintf (file, "\t.global\t$tableentry$%d$%s\n", vnum, vname); 1895 fprintf (file, "$tableentry$%d$%s:\n", vnum, vname); 1896 break; 1897 1898 default: 1899 ; 1900 } 1901 1902 vec_attr = TREE_CHAIN (vec_attr); 1903 } 1904 1905} 1906 1907static void 1908rx_output_function_prologue (FILE * file) 1909{ 1910 add_vector_labels (file, "interrupt"); 1911 add_vector_labels (file, "vector"); 1912 1913 if (is_fast_interrupt_func (NULL_TREE)) 1914 asm_fprintf (file, "\t; Note: Fast Interrupt Handler\n"); 1915 1916 if (is_interrupt_func (NULL_TREE)) 1917 asm_fprintf (file, "\t; Note: Interrupt Handler\n"); 1918 1919 if (is_naked_func (NULL_TREE)) 1920 asm_fprintf (file, "\t; Note: Naked Function\n"); 1921 1922 if (cfun->static_chain_decl != NULL) 1923 asm_fprintf (file, "\t; Note: Nested function declared " 1924 "inside another function.\n"); 1925 1926 if (crtl->calls_eh_return) 1927 asm_fprintf (file, "\t; Note: Calls __builtin_eh_return.\n"); 1928} 1929 1930/* Generate a POPM or RTSD instruction that matches the given operands. */ 1931 1932void 1933rx_emit_stack_popm (rtx * operands, bool is_popm) 1934{ 1935 HOST_WIDE_INT stack_adjust; 1936 HOST_WIDE_INT last_reg; 1937 rtx first_push; 1938 1939 gcc_assert (CONST_INT_P (operands[0])); 1940 stack_adjust = INTVAL (operands[0]); 1941 1942 gcc_assert (GET_CODE (operands[1]) == PARALLEL); 1943 last_reg = XVECLEN (operands[1], 0) - (is_popm ? 2 : 3); 1944 1945 first_push = XVECEXP (operands[1], 0, 1); 1946 gcc_assert (SET_P (first_push)); 1947 first_push = SET_DEST (first_push); 1948 gcc_assert (REG_P (first_push)); 1949 1950 if (is_popm) 1951 asm_fprintf (asm_out_file, "\tpopm\t%s-%s\n", 1952 reg_names [REGNO (first_push)], 1953 reg_names [REGNO (first_push) + last_reg]); 1954 else 1955 asm_fprintf (asm_out_file, "\trtsd\t#%d, %s-%s\n", 1956 (int) stack_adjust, 1957 reg_names [REGNO (first_push)], 1958 reg_names [REGNO (first_push) + last_reg]); 1959} 1960 1961/* Generate a PARALLEL which will satisfy the rx_rtsd_vector predicate. */ 1962 1963static rtx 1964gen_rx_rtsd_vector (unsigned int adjust, unsigned int low, unsigned int high) 1965{ 1966 unsigned int i; 1967 unsigned int bias = 3; 1968 unsigned int count = (high - low) + bias; 1969 rtx vector; 1970 1971 vector = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count)); 1972 1973 XVECEXP (vector, 0, 0) = 1974 gen_rtx_SET (stack_pointer_rtx, 1975 plus_constant (Pmode, stack_pointer_rtx, adjust)); 1976 1977 for (i = 0; i < count - 2; i++) 1978 XVECEXP (vector, 0, i + 1) = 1979 gen_rtx_SET (gen_rtx_REG (SImode, low + i), 1980 gen_rtx_MEM (SImode, 1981 i == 0 ? stack_pointer_rtx 1982 : plus_constant (Pmode, stack_pointer_rtx, 1983 i * UNITS_PER_WORD))); 1984 1985 XVECEXP (vector, 0, count - 1) = ret_rtx; 1986 1987 return vector; 1988} 1989 1990/* Generate a PARALLEL which will satisfy the rx_load_multiple_vector predicate. */ 1991 1992static rtx 1993gen_rx_popm_vector (unsigned int low, unsigned int high) 1994{ 1995 unsigned int i; 1996 unsigned int count = (high - low) + 2; 1997 rtx vector; 1998 1999 vector = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count)); 2000 2001 XVECEXP (vector, 0, 0) = 2002 gen_rtx_SET (stack_pointer_rtx, 2003 plus_constant (Pmode, stack_pointer_rtx, 2004 (count - 1) * UNITS_PER_WORD)); 2005 2006 for (i = 0; i < count - 1; i++) 2007 XVECEXP (vector, 0, i + 1) = 2008 gen_rtx_SET (gen_rtx_REG (SImode, low + i), 2009 gen_rtx_MEM (SImode, 2010 i == 0 ? stack_pointer_rtx 2011 : plus_constant (Pmode, stack_pointer_rtx, 2012 i * UNITS_PER_WORD))); 2013 2014 return vector; 2015} 2016 2017/* Returns true if a simple return insn can be used. */ 2018 2019bool 2020rx_can_use_simple_return (void) 2021{ 2022 unsigned int low; 2023 unsigned int high; 2024 unsigned int frame_size; 2025 unsigned int stack_size; 2026 unsigned int register_mask; 2027 2028 if (is_naked_func (NULL_TREE) 2029 || is_fast_interrupt_func (NULL_TREE) 2030 || is_interrupt_func (NULL_TREE)) 2031 return false; 2032 2033 rx_get_stack_layout (& low, & high, & register_mask, 2034 & frame_size, & stack_size); 2035 2036 return (register_mask == 0 2037 && (frame_size + stack_size) == 0 2038 && low == 0); 2039} 2040 2041static void 2042pop_regs (unsigned int high, unsigned int low) 2043{ 2044 rtx_insn *insn; 2045 if (high == low) 2046 insn = emit_insn (gen_stack_pop (gen_rtx_REG (SImode, low))); 2047 else 2048 insn = emit_insn (gen_stack_popm (GEN_INT (((high - low) + 1) 2049 * UNITS_PER_WORD), 2050 gen_rx_popm_vector (low, high))); 2051 add_pop_cfi_notes (insn, high, low); 2052} 2053 2054void 2055rx_expand_epilogue (bool is_sibcall) 2056{ 2057 unsigned int low; 2058 unsigned int high; 2059 unsigned int frame_size; 2060 unsigned int stack_size; 2061 unsigned int register_mask; 2062 unsigned int regs_size; 2063 unsigned int reg; 2064 unsigned HOST_WIDE_INT total_size; 2065 2066 /* FIXME: We do not support indirect sibcalls at the moment becaause we 2067 cannot guarantee that the register holding the function address is a 2068 call-used register. If it is a call-saved register then the stack 2069 pop instructions generated in the epilogue will corrupt the address 2070 before it is used. 2071 2072 Creating a new call-used-only register class works but then the 2073 reload pass gets stuck because it cannot always find a call-used 2074 register for spilling sibcalls. 2075 2076 The other possible solution is for this pass to scan forward for the 2077 sibcall instruction (if it has been generated) and work out if it 2078 is an indirect sibcall using a call-saved register. If it is then 2079 the address can copied into a call-used register in this epilogue 2080 code and the sibcall instruction modified to use that register. */ 2081 2082 if (is_naked_func (NULL_TREE)) 2083 { 2084 gcc_assert (! is_sibcall); 2085 2086 /* Naked functions use their own, programmer provided epilogues. 2087 But, in order to keep gcc happy we have to generate some kind of 2088 epilogue RTL. */ 2089 emit_jump_insn (gen_naked_return ()); 2090 return; 2091 } 2092 2093 rx_get_stack_layout (& low, & high, & register_mask, 2094 & frame_size, & stack_size); 2095 2096 total_size = frame_size + stack_size; 2097 regs_size = ((high - low) + 1) * UNITS_PER_WORD; 2098 2099 /* See if we are unable to use the special stack frame deconstruct and 2100 return instructions. In most cases we can use them, but the exceptions 2101 are: 2102 2103 - Sibling calling functions deconstruct the frame but do not return to 2104 their caller. Instead they branch to their sibling and allow their 2105 return instruction to return to this function's parent. 2106 2107 - Fast and normal interrupt handling functions have to use special 2108 return instructions. 2109 2110 - Functions where we have pushed a fragmented set of registers into the 2111 call-save area must have the same set of registers popped. */ 2112 if (is_sibcall 2113 || is_fast_interrupt_func (NULL_TREE) 2114 || is_interrupt_func (NULL_TREE) 2115 || register_mask) 2116 { 2117 /* Cannot use the special instructions - deconstruct by hand. */ 2118 if (total_size) 2119 gen_safe_add (stack_pointer_rtx, stack_pointer_rtx, 2120 GEN_INT (total_size), false); 2121 2122 if (MUST_SAVE_ACC_REGISTER) 2123 { 2124 unsigned int acc_low, acc_high; 2125 2126 /* Reverse the saving of the accumulator register onto the stack. 2127 Note we must adjust the saved "low" accumulator value as it 2128 is really the middle 32-bits of the accumulator. */ 2129 if (register_mask) 2130 { 2131 acc_low = acc_high = 0; 2132 2133 for (reg = 1; reg < CC_REGNUM; reg ++) 2134 if (register_mask & (1 << reg)) 2135 { 2136 if (acc_low == 0) 2137 acc_low = reg; 2138 else 2139 { 2140 acc_high = reg; 2141 break; 2142 } 2143 } 2144 emit_insn (gen_stack_pop (gen_rtx_REG (SImode, acc_high))); 2145 emit_insn (gen_stack_pop (gen_rtx_REG (SImode, acc_low))); 2146 } 2147 else 2148 { 2149 acc_low = low; 2150 acc_high = low + 1; 2151 emit_insn (gen_stack_popm (GEN_INT (2 * UNITS_PER_WORD), 2152 gen_rx_popm_vector (acc_low, acc_high))); 2153 } 2154 2155 emit_insn (gen_ashlsi3 (gen_rtx_REG (SImode, acc_low), 2156 gen_rtx_REG (SImode, acc_low), 2157 GEN_INT (16))); 2158 emit_insn (gen_mvtaclo (gen_rtx_REG (SImode, acc_low))); 2159 emit_insn (gen_mvtachi (gen_rtx_REG (SImode, acc_high))); 2160 } 2161 2162 if (register_mask) 2163 { 2164 for (reg = 0; reg < CC_REGNUM; reg ++) 2165 if (register_mask & (1 << reg)) 2166 { 2167 low = high = reg; 2168 while (register_mask & (1 << high)) 2169 high ++; 2170 pop_regs (high - 1, low); 2171 reg = high; 2172 } 2173 } 2174 else if (low) 2175 pop_regs (high, low); 2176 2177 if (is_fast_interrupt_func (NULL_TREE)) 2178 { 2179 gcc_assert (! is_sibcall); 2180 emit_jump_insn (gen_fast_interrupt_return ()); 2181 } 2182 else if (is_interrupt_func (NULL_TREE)) 2183 { 2184 gcc_assert (! is_sibcall); 2185 emit_jump_insn (gen_exception_return ()); 2186 } 2187 else if (! is_sibcall) 2188 emit_jump_insn (gen_simple_return ()); 2189 2190 return; 2191 } 2192 2193 /* If we allocated space on the stack, free it now. */ 2194 if (total_size) 2195 { 2196 unsigned HOST_WIDE_INT rtsd_size; 2197 2198 /* See if we can use the RTSD instruction. */ 2199 rtsd_size = total_size + regs_size; 2200 if (rtsd_size < 1024 && (rtsd_size % 4) == 0) 2201 { 2202 if (low) 2203 emit_jump_insn (gen_pop_and_return 2204 (GEN_INT (rtsd_size), 2205 gen_rx_rtsd_vector (rtsd_size, low, high))); 2206 else 2207 emit_jump_insn (gen_deallocate_and_return (GEN_INT (total_size))); 2208 2209 return; 2210 } 2211 2212 gen_safe_add (stack_pointer_rtx, stack_pointer_rtx, 2213 GEN_INT (total_size), false); 2214 } 2215 2216 if (low) 2217 emit_jump_insn (gen_pop_and_return (GEN_INT (regs_size), 2218 gen_rx_rtsd_vector (regs_size, 2219 low, high))); 2220 else 2221 emit_jump_insn (gen_simple_return ()); 2222} 2223 2224 2225/* Compute the offset (in words) between FROM (arg pointer 2226 or frame pointer) and TO (frame pointer or stack pointer). 2227 See ASCII art comment at the start of rx_expand_prologue 2228 for more information. */ 2229 2230int 2231rx_initial_elimination_offset (int from, int to) 2232{ 2233 unsigned int low; 2234 unsigned int high; 2235 unsigned int frame_size; 2236 unsigned int stack_size; 2237 unsigned int mask; 2238 2239 rx_get_stack_layout (& low, & high, & mask, & frame_size, & stack_size); 2240 2241 if (from == ARG_POINTER_REGNUM) 2242 { 2243 /* Extend the computed size of the stack frame to 2244 include the registers pushed in the prologue. */ 2245 if (low) 2246 frame_size += ((high - low) + 1) * UNITS_PER_WORD; 2247 else 2248 frame_size += bit_count (mask) * UNITS_PER_WORD; 2249 2250 /* Remember to include the return address. */ 2251 frame_size += 1 * UNITS_PER_WORD; 2252 2253 if (to == FRAME_POINTER_REGNUM) 2254 return frame_size; 2255 2256 gcc_assert (to == STACK_POINTER_REGNUM); 2257 return frame_size + stack_size; 2258 } 2259 2260 gcc_assert (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM); 2261 return stack_size; 2262} 2263 2264/* Decide if a variable should go into one of the small data sections. */ 2265 2266static bool 2267rx_in_small_data (const_tree decl) 2268{ 2269 int size; 2270 const char * section; 2271 2272 if (rx_small_data_limit == 0) 2273 return false; 2274 2275 if (TREE_CODE (decl) != VAR_DECL) 2276 return false; 2277 2278 /* We do not put read-only variables into a small data area because 2279 they would be placed with the other read-only sections, far away 2280 from the read-write data sections, and we only have one small 2281 data area pointer. 2282 Similarly commons are placed in the .bss section which might be 2283 far away (and out of alignment with respect to) the .data section. */ 2284 if (TREE_READONLY (decl) || DECL_COMMON (decl)) 2285 return false; 2286 2287 section = DECL_SECTION_NAME (decl); 2288 if (section) 2289 return (strcmp (section, "D_2") == 0) || (strcmp (section, "B_2") == 0); 2290 2291 size = int_size_in_bytes (TREE_TYPE (decl)); 2292 2293 return (size > 0) && (size <= rx_small_data_limit); 2294} 2295 2296/* Return a section for X. 2297 The only special thing we do here is to honor small data. */ 2298 2299static section * 2300rx_select_rtx_section (machine_mode mode, 2301 rtx x, 2302 unsigned HOST_WIDE_INT align) 2303{ 2304 if (rx_small_data_limit > 0 2305 && GET_MODE_SIZE (mode) <= rx_small_data_limit 2306 && align <= (unsigned HOST_WIDE_INT) rx_small_data_limit * BITS_PER_UNIT) 2307 return sdata_section; 2308 2309 return default_elf_select_rtx_section (mode, x, align); 2310} 2311 2312static section * 2313rx_select_section (tree decl, 2314 int reloc, 2315 unsigned HOST_WIDE_INT align) 2316{ 2317 if (rx_small_data_limit > 0) 2318 { 2319 switch (categorize_decl_for_section (decl, reloc)) 2320 { 2321 case SECCAT_SDATA: return sdata_section; 2322 case SECCAT_SBSS: return sbss_section; 2323 case SECCAT_SRODATA: 2324 /* Fall through. We do not put small, read only 2325 data into the C_2 section because we are not 2326 using the C_2 section. We do not use the C_2 2327 section because it is located with the other 2328 read-only data sections, far away from the read-write 2329 data sections and we only have one small data 2330 pointer (r13). */ 2331 default: 2332 break; 2333 } 2334 } 2335 2336 /* If we are supporting the Renesas assembler 2337 we cannot use mergeable sections. */ 2338 if (TARGET_AS100_SYNTAX) 2339 switch (categorize_decl_for_section (decl, reloc)) 2340 { 2341 case SECCAT_RODATA_MERGE_CONST: 2342 case SECCAT_RODATA_MERGE_STR_INIT: 2343 case SECCAT_RODATA_MERGE_STR: 2344 return readonly_data_section; 2345 2346 default: 2347 break; 2348 } 2349 2350 return default_elf_select_section (decl, reloc, align); 2351} 2352 2353enum rx_builtin 2354{ 2355 RX_BUILTIN_BRK, 2356 RX_BUILTIN_CLRPSW, 2357 RX_BUILTIN_INT, 2358 RX_BUILTIN_MACHI, 2359 RX_BUILTIN_MACLO, 2360 RX_BUILTIN_MULHI, 2361 RX_BUILTIN_MULLO, 2362 RX_BUILTIN_MVFACHI, 2363 RX_BUILTIN_MVFACMI, 2364 RX_BUILTIN_MVFC, 2365 RX_BUILTIN_MVTACHI, 2366 RX_BUILTIN_MVTACLO, 2367 RX_BUILTIN_MVTC, 2368 RX_BUILTIN_MVTIPL, 2369 RX_BUILTIN_RACW, 2370 RX_BUILTIN_REVW, 2371 RX_BUILTIN_RMPA, 2372 RX_BUILTIN_ROUND, 2373 RX_BUILTIN_SETPSW, 2374 RX_BUILTIN_WAIT, 2375 RX_BUILTIN_max 2376}; 2377 2378static GTY(()) tree rx_builtins[(int) RX_BUILTIN_max]; 2379 2380static void 2381rx_init_builtins (void) 2382{ 2383#define ADD_RX_BUILTIN0(UC_NAME, LC_NAME, RET_TYPE) \ 2384 rx_builtins[RX_BUILTIN_##UC_NAME] = \ 2385 add_builtin_function ("__builtin_rx_" LC_NAME, \ 2386 build_function_type_list (RET_TYPE##_type_node, \ 2387 NULL_TREE), \ 2388 RX_BUILTIN_##UC_NAME, \ 2389 BUILT_IN_MD, NULL, NULL_TREE) 2390 2391#define ADD_RX_BUILTIN1(UC_NAME, LC_NAME, RET_TYPE, ARG_TYPE) \ 2392 rx_builtins[RX_BUILTIN_##UC_NAME] = \ 2393 add_builtin_function ("__builtin_rx_" LC_NAME, \ 2394 build_function_type_list (RET_TYPE##_type_node, \ 2395 ARG_TYPE##_type_node, \ 2396 NULL_TREE), \ 2397 RX_BUILTIN_##UC_NAME, \ 2398 BUILT_IN_MD, NULL, NULL_TREE) 2399 2400#define ADD_RX_BUILTIN2(UC_NAME, LC_NAME, RET_TYPE, ARG_TYPE1, ARG_TYPE2) \ 2401 rx_builtins[RX_BUILTIN_##UC_NAME] = \ 2402 add_builtin_function ("__builtin_rx_" LC_NAME, \ 2403 build_function_type_list (RET_TYPE##_type_node, \ 2404 ARG_TYPE1##_type_node,\ 2405 ARG_TYPE2##_type_node,\ 2406 NULL_TREE), \ 2407 RX_BUILTIN_##UC_NAME, \ 2408 BUILT_IN_MD, NULL, NULL_TREE) 2409 2410#define ADD_RX_BUILTIN3(UC_NAME,LC_NAME,RET_TYPE,ARG_TYPE1,ARG_TYPE2,ARG_TYPE3) \ 2411 rx_builtins[RX_BUILTIN_##UC_NAME] = \ 2412 add_builtin_function ("__builtin_rx_" LC_NAME, \ 2413 build_function_type_list (RET_TYPE##_type_node, \ 2414 ARG_TYPE1##_type_node,\ 2415 ARG_TYPE2##_type_node,\ 2416 ARG_TYPE3##_type_node,\ 2417 NULL_TREE), \ 2418 RX_BUILTIN_##UC_NAME, \ 2419 BUILT_IN_MD, NULL, NULL_TREE) 2420 2421 ADD_RX_BUILTIN0 (BRK, "brk", void); 2422 ADD_RX_BUILTIN1 (CLRPSW, "clrpsw", void, integer); 2423 ADD_RX_BUILTIN1 (SETPSW, "setpsw", void, integer); 2424 ADD_RX_BUILTIN1 (INT, "int", void, integer); 2425 ADD_RX_BUILTIN2 (MACHI, "machi", void, intSI, intSI); 2426 ADD_RX_BUILTIN2 (MACLO, "maclo", void, intSI, intSI); 2427 ADD_RX_BUILTIN2 (MULHI, "mulhi", void, intSI, intSI); 2428 ADD_RX_BUILTIN2 (MULLO, "mullo", void, intSI, intSI); 2429 ADD_RX_BUILTIN0 (MVFACHI, "mvfachi", intSI); 2430 ADD_RX_BUILTIN0 (MVFACMI, "mvfacmi", intSI); 2431 ADD_RX_BUILTIN1 (MVTACHI, "mvtachi", void, intSI); 2432 ADD_RX_BUILTIN1 (MVTACLO, "mvtaclo", void, intSI); 2433 ADD_RX_BUILTIN0 (RMPA, "rmpa", void); 2434 ADD_RX_BUILTIN1 (MVFC, "mvfc", intSI, integer); 2435 ADD_RX_BUILTIN2 (MVTC, "mvtc", void, integer, integer); 2436 ADD_RX_BUILTIN1 (MVTIPL, "mvtipl", void, integer); 2437 ADD_RX_BUILTIN1 (RACW, "racw", void, integer); 2438 ADD_RX_BUILTIN1 (ROUND, "round", intSI, float); 2439 ADD_RX_BUILTIN1 (REVW, "revw", intSI, intSI); 2440 ADD_RX_BUILTIN0 (WAIT, "wait", void); 2441} 2442 2443/* Return the RX builtin for CODE. */ 2444 2445static tree 2446rx_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED) 2447{ 2448 if (code >= RX_BUILTIN_max) 2449 return error_mark_node; 2450 2451 return rx_builtins[code]; 2452} 2453 2454static rtx 2455rx_expand_void_builtin_1_arg (rtx arg, rtx (* gen_func)(rtx), bool reg) 2456{ 2457 if (reg && ! REG_P (arg)) 2458 arg = force_reg (SImode, arg); 2459 2460 emit_insn (gen_func (arg)); 2461 2462 return NULL_RTX; 2463} 2464 2465static rtx 2466rx_expand_builtin_mvtc (tree exp) 2467{ 2468 rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0)); 2469 rtx arg2 = expand_normal (CALL_EXPR_ARG (exp, 1)); 2470 2471 if (! CONST_INT_P (arg1)) 2472 return NULL_RTX; 2473 2474 if (! REG_P (arg2)) 2475 arg2 = force_reg (SImode, arg2); 2476 2477 emit_insn (gen_mvtc (arg1, arg2)); 2478 2479 return NULL_RTX; 2480} 2481 2482static rtx 2483rx_expand_builtin_mvfc (tree t_arg, rtx target) 2484{ 2485 rtx arg = expand_normal (t_arg); 2486 2487 if (! CONST_INT_P (arg)) 2488 return NULL_RTX; 2489 2490 if (target == NULL_RTX) 2491 return NULL_RTX; 2492 2493 if (! REG_P (target)) 2494 target = force_reg (SImode, target); 2495 2496 emit_insn (gen_mvfc (target, arg)); 2497 2498 return target; 2499} 2500 2501static rtx 2502rx_expand_builtin_mvtipl (rtx arg) 2503{ 2504 /* The RX610 does not support the MVTIPL instruction. */ 2505 if (rx_cpu_type == RX610) 2506 return NULL_RTX; 2507 2508 if (! CONST_INT_P (arg) || ! IN_RANGE (INTVAL (arg), 0, (1 << 4) - 1)) 2509 return NULL_RTX; 2510 2511 emit_insn (gen_mvtipl (arg)); 2512 2513 return NULL_RTX; 2514} 2515 2516static rtx 2517rx_expand_builtin_mac (tree exp, rtx (* gen_func)(rtx, rtx)) 2518{ 2519 rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0)); 2520 rtx arg2 = expand_normal (CALL_EXPR_ARG (exp, 1)); 2521 2522 if (! REG_P (arg1)) 2523 arg1 = force_reg (SImode, arg1); 2524 2525 if (! REG_P (arg2)) 2526 arg2 = force_reg (SImode, arg2); 2527 2528 emit_insn (gen_func (arg1, arg2)); 2529 2530 return NULL_RTX; 2531} 2532 2533static rtx 2534rx_expand_int_builtin_1_arg (rtx arg, 2535 rtx target, 2536 rtx (* gen_func)(rtx, rtx), 2537 bool mem_ok) 2538{ 2539 if (! REG_P (arg)) 2540 if (!mem_ok || ! MEM_P (arg)) 2541 arg = force_reg (SImode, arg); 2542 2543 if (target == NULL_RTX || ! REG_P (target)) 2544 target = gen_reg_rtx (SImode); 2545 2546 emit_insn (gen_func (target, arg)); 2547 2548 return target; 2549} 2550 2551static rtx 2552rx_expand_int_builtin_0_arg (rtx target, rtx (* gen_func)(rtx)) 2553{ 2554 if (target == NULL_RTX || ! REG_P (target)) 2555 target = gen_reg_rtx (SImode); 2556 2557 emit_insn (gen_func (target)); 2558 2559 return target; 2560} 2561 2562static rtx 2563rx_expand_builtin_round (rtx arg, rtx target) 2564{ 2565 if ((! REG_P (arg) && ! MEM_P (arg)) 2566 || GET_MODE (arg) != SFmode) 2567 arg = force_reg (SFmode, arg); 2568 2569 if (target == NULL_RTX || ! REG_P (target)) 2570 target = gen_reg_rtx (SImode); 2571 2572 emit_insn (gen_lrintsf2 (target, arg)); 2573 2574 return target; 2575} 2576 2577static int 2578valid_psw_flag (rtx op, const char *which) 2579{ 2580 static int mvtc_inform_done = 0; 2581 2582 if (GET_CODE (op) == CONST_INT) 2583 switch (INTVAL (op)) 2584 { 2585 case 0: case 'c': case 'C': 2586 case 1: case 'z': case 'Z': 2587 case 2: case 's': case 'S': 2588 case 3: case 'o': case 'O': 2589 case 8: case 'i': case 'I': 2590 case 9: case 'u': case 'U': 2591 return 1; 2592 } 2593 2594 error ("%<__builtin_rx_%s%> takes %<C%>, %<Z%>, %<S%>, %<O%>, %<I%>, " 2595 "or %<U%>", which); 2596 if (!mvtc_inform_done) 2597 error ("use %<__builtin_rx_mvtc%> (0, ... ) to write arbitrary values to PSW"); 2598 mvtc_inform_done = 1; 2599 2600 return 0; 2601} 2602 2603static rtx 2604rx_expand_builtin (tree exp, 2605 rtx target, 2606 rtx subtarget ATTRIBUTE_UNUSED, 2607 machine_mode mode ATTRIBUTE_UNUSED, 2608 int ignore ATTRIBUTE_UNUSED) 2609{ 2610 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 2611 tree arg = call_expr_nargs (exp) >= 1 ? CALL_EXPR_ARG (exp, 0) : NULL_TREE; 2612 rtx op = arg ? expand_normal (arg) : NULL_RTX; 2613 unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl); 2614 2615 switch (fcode) 2616 { 2617 case RX_BUILTIN_BRK: emit_insn (gen_brk ()); return NULL_RTX; 2618 case RX_BUILTIN_CLRPSW: 2619 if (!valid_psw_flag (op, "clrpsw")) 2620 return NULL_RTX; 2621 return rx_expand_void_builtin_1_arg (op, gen_clrpsw, false); 2622 case RX_BUILTIN_SETPSW: 2623 if (!valid_psw_flag (op, "setpsw")) 2624 return NULL_RTX; 2625 return rx_expand_void_builtin_1_arg (op, gen_setpsw, false); 2626 case RX_BUILTIN_INT: return rx_expand_void_builtin_1_arg 2627 (op, gen_int, false); 2628 case RX_BUILTIN_MACHI: return rx_expand_builtin_mac (exp, gen_machi); 2629 case RX_BUILTIN_MACLO: return rx_expand_builtin_mac (exp, gen_maclo); 2630 case RX_BUILTIN_MULHI: return rx_expand_builtin_mac (exp, gen_mulhi); 2631 case RX_BUILTIN_MULLO: return rx_expand_builtin_mac (exp, gen_mullo); 2632 case RX_BUILTIN_MVFACHI: return rx_expand_int_builtin_0_arg 2633 (target, gen_mvfachi); 2634 case RX_BUILTIN_MVFACMI: return rx_expand_int_builtin_0_arg 2635 (target, gen_mvfacmi); 2636 case RX_BUILTIN_MVTACHI: return rx_expand_void_builtin_1_arg 2637 (op, gen_mvtachi, true); 2638 case RX_BUILTIN_MVTACLO: return rx_expand_void_builtin_1_arg 2639 (op, gen_mvtaclo, true); 2640 case RX_BUILTIN_RMPA: 2641 if (rx_allow_string_insns) 2642 emit_insn (gen_rmpa ()); 2643 else 2644 error ("%<-mno-allow-string-insns%> forbids the generation " 2645 "of the RMPA instruction"); 2646 return NULL_RTX; 2647 case RX_BUILTIN_MVFC: return rx_expand_builtin_mvfc (arg, target); 2648 case RX_BUILTIN_MVTC: return rx_expand_builtin_mvtc (exp); 2649 case RX_BUILTIN_MVTIPL: return rx_expand_builtin_mvtipl (op); 2650 case RX_BUILTIN_RACW: return rx_expand_void_builtin_1_arg 2651 (op, gen_racw, false); 2652 case RX_BUILTIN_ROUND: return rx_expand_builtin_round (op, target); 2653 case RX_BUILTIN_REVW: return rx_expand_int_builtin_1_arg 2654 (op, target, gen_revw, false); 2655 case RX_BUILTIN_WAIT: emit_insn (gen_wait ()); return NULL_RTX; 2656 2657 default: 2658 internal_error ("bad builtin code"); 2659 break; 2660 } 2661 2662 return NULL_RTX; 2663} 2664 2665/* Place an element into a constructor or destructor section. 2666 Like default_ctor_section_asm_out_constructor in varasm.c 2667 except that it uses .init_array (or .fini_array) and it 2668 handles constructor priorities. */ 2669 2670static void 2671rx_elf_asm_cdtor (rtx symbol, int priority, bool is_ctor) 2672{ 2673 section * s; 2674 2675 if (priority != DEFAULT_INIT_PRIORITY) 2676 { 2677 char buf[18]; 2678 2679 sprintf (buf, "%s.%.5u", 2680 is_ctor ? ".init_array" : ".fini_array", 2681 priority); 2682 s = get_section (buf, SECTION_WRITE, NULL_TREE); 2683 } 2684 else if (is_ctor) 2685 s = ctors_section; 2686 else 2687 s = dtors_section; 2688 2689 switch_to_section (s); 2690 assemble_align (POINTER_SIZE); 2691 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1); 2692} 2693 2694static void 2695rx_elf_asm_constructor (rtx symbol, int priority) 2696{ 2697 rx_elf_asm_cdtor (symbol, priority, /* is_ctor= */true); 2698} 2699 2700static void 2701rx_elf_asm_destructor (rtx symbol, int priority) 2702{ 2703 rx_elf_asm_cdtor (symbol, priority, /* is_ctor= */false); 2704} 2705 2706/* Check "fast_interrupt", "interrupt" and "naked" attributes. */ 2707 2708static tree 2709rx_handle_func_attribute (tree * node, 2710 tree name, 2711 tree args ATTRIBUTE_UNUSED, 2712 int flags ATTRIBUTE_UNUSED, 2713 bool * no_add_attrs) 2714{ 2715 gcc_assert (DECL_P (* node)); 2716 2717 if (TREE_CODE (* node) != FUNCTION_DECL) 2718 { 2719 warning (OPT_Wattributes, "%qE attribute only applies to functions", 2720 name); 2721 * no_add_attrs = true; 2722 } 2723 2724 /* FIXME: We ought to check for conflicting attributes. */ 2725 2726 /* FIXME: We ought to check that the interrupt and exception 2727 handler attributes have been applied to void functions. */ 2728 return NULL_TREE; 2729} 2730 2731/* Check "vector" attribute. */ 2732 2733static tree 2734rx_handle_vector_attribute (tree * node, 2735 tree name, 2736 tree args, 2737 int flags ATTRIBUTE_UNUSED, 2738 bool * no_add_attrs) 2739{ 2740 gcc_assert (DECL_P (* node)); 2741 gcc_assert (args != NULL_TREE); 2742 2743 if (TREE_CODE (* node) != FUNCTION_DECL) 2744 { 2745 warning (OPT_Wattributes, "%qE attribute only applies to functions", 2746 name); 2747 * no_add_attrs = true; 2748 } 2749 2750 return NULL_TREE; 2751} 2752 2753/* Table of RX specific attributes. */ 2754const struct attribute_spec rx_attribute_table[] = 2755{ 2756 /* Name, min_len, max_len, decl_req, type_req, fn_type_req, 2757 affects_type_identity, handler, exclude. */ 2758 { "fast_interrupt", 0, 0, true, false, false, false, 2759 rx_handle_func_attribute, NULL }, 2760 { "interrupt", 0, -1, true, false, false, false, 2761 rx_handle_func_attribute, NULL }, 2762 { "naked", 0, 0, true, false, false, false, 2763 rx_handle_func_attribute, NULL }, 2764 { "vector", 1, -1, true, false, false, false, 2765 rx_handle_vector_attribute, NULL }, 2766 { NULL, 0, 0, false, false, false, false, NULL, NULL } 2767}; 2768 2769/* Implement TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE. */ 2770 2771static void 2772rx_override_options_after_change (void) 2773{ 2774 static bool first_time = TRUE; 2775 2776 if (first_time) 2777 { 2778 /* If this is the first time through and the user has not disabled 2779 the use of RX FPU hardware then enable -ffinite-math-only, 2780 since the FPU instructions do not support NaNs and infinities. */ 2781 if (TARGET_USE_FPU) 2782 flag_finite_math_only = 1; 2783 2784 first_time = FALSE; 2785 } 2786 else 2787 { 2788 /* Alert the user if they are changing the optimization options 2789 to use IEEE compliant floating point arithmetic with RX FPU insns. */ 2790 if (TARGET_USE_FPU 2791 && !flag_finite_math_only) 2792 warning (0, "RX FPU instructions do not support NaNs and infinities"); 2793 } 2794} 2795 2796static void 2797rx_option_override (void) 2798{ 2799 unsigned int i; 2800 cl_deferred_option *opt; 2801 vec<cl_deferred_option> *v = (vec<cl_deferred_option> *) rx_deferred_options; 2802 2803 if (v) 2804 FOR_EACH_VEC_ELT (*v, i, opt) 2805 { 2806 switch (opt->opt_index) 2807 { 2808 case OPT_mint_register_: 2809 switch (opt->value) 2810 { 2811 case 4: 2812 fixed_regs[10] = call_used_regs [10] = 1; 2813 /* Fall through. */ 2814 case 3: 2815 fixed_regs[11] = call_used_regs [11] = 1; 2816 /* Fall through. */ 2817 case 2: 2818 fixed_regs[12] = call_used_regs [12] = 1; 2819 /* Fall through. */ 2820 case 1: 2821 fixed_regs[13] = call_used_regs [13] = 1; 2822 /* Fall through. */ 2823 case 0: 2824 rx_num_interrupt_regs = opt->value; 2825 break; 2826 default: 2827 rx_num_interrupt_regs = 0; 2828 /* Error message already given because rx_handle_option 2829 returned false. */ 2830 break; 2831 } 2832 break; 2833 2834 default: 2835 gcc_unreachable (); 2836 } 2837 } 2838 2839 /* This target defaults to strict volatile bitfields. */ 2840 if (flag_strict_volatile_bitfields < 0 && abi_version_at_least(2)) 2841 flag_strict_volatile_bitfields = 1; 2842 2843 rx_override_options_after_change (); 2844 2845 /* These values are bytes, not log. */ 2846 if (! optimize_size) 2847 { 2848 if (flag_align_jumps && !str_align_jumps) 2849 str_align_jumps = ((rx_cpu_type == RX100 2850 || rx_cpu_type == RX200) ? "4" : "8"); 2851 if (flag_align_loops && !str_align_loops) 2852 str_align_loops = ((rx_cpu_type == RX100 2853 || rx_cpu_type == RX200) ? "4" : "8"); 2854 if (flag_align_labels && !str_align_labels) 2855 str_align_labels = ((rx_cpu_type == RX100 2856 || rx_cpu_type == RX200) ? "4" : "8"); 2857 } 2858} 2859 2860 2861static bool 2862rx_allocate_stack_slots_for_args (void) 2863{ 2864 /* Naked functions should not allocate stack slots for arguments. */ 2865 return ! is_naked_func (NULL_TREE); 2866} 2867 2868static bool 2869rx_func_attr_inlinable (const_tree decl) 2870{ 2871 return ! is_fast_interrupt_func (decl) 2872 && ! is_interrupt_func (decl) 2873 && ! is_naked_func (decl); 2874} 2875 2876static bool 2877rx_warn_func_return (tree decl) 2878{ 2879 /* Naked functions are implemented entirely in assembly, including the 2880 return sequence, so suppress warnings about this. */ 2881 return !is_naked_func (decl); 2882} 2883 2884/* Return nonzero if it is ok to make a tail-call to DECL, 2885 a function_decl or NULL if this is an indirect call, using EXP */ 2886 2887static bool 2888rx_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED) 2889{ 2890 if (TARGET_JSR) 2891 return false; 2892 2893 /* Do not allow indirect tailcalls. The 2894 sibcall patterns do not support them. */ 2895 if (decl == NULL) 2896 return false; 2897 2898 /* Never tailcall from inside interrupt handlers or naked functions. */ 2899 if (is_fast_interrupt_func (NULL_TREE) 2900 || is_interrupt_func (NULL_TREE) 2901 || is_naked_func (NULL_TREE)) 2902 return false; 2903 2904 return true; 2905} 2906 2907static void 2908rx_file_start (void) 2909{ 2910 if (! TARGET_AS100_SYNTAX) 2911 default_file_start (); 2912} 2913 2914static bool 2915rx_is_ms_bitfield_layout (const_tree record_type ATTRIBUTE_UNUSED) 2916{ 2917 /* The packed attribute overrides the MS behavior. */ 2918 return ! TYPE_PACKED (record_type); 2919} 2920 2921/* Returns true if X a legitimate constant for an immediate 2922 operand on the RX. X is already known to satisfy CONSTANT_P. */ 2923 2924bool 2925rx_is_legitimate_constant (machine_mode mode ATTRIBUTE_UNUSED, rtx x) 2926{ 2927 switch (GET_CODE (x)) 2928 { 2929 case CONST: 2930 x = XEXP (x, 0); 2931 2932 if (GET_CODE (x) == PLUS) 2933 { 2934 if (! CONST_INT_P (XEXP (x, 1))) 2935 return false; 2936 2937 /* GCC would not pass us CONST_INT + CONST_INT so we 2938 know that we have {SYMBOL|LABEL} + CONST_INT. */ 2939 x = XEXP (x, 0); 2940 gcc_assert (! CONST_INT_P (x)); 2941 } 2942 2943 switch (GET_CODE (x)) 2944 { 2945 case LABEL_REF: 2946 case SYMBOL_REF: 2947 return true; 2948 2949 case UNSPEC: 2950 return XINT (x, 1) == UNSPEC_CONST || XINT (x, 1) == UNSPEC_PID_ADDR; 2951 2952 default: 2953 /* FIXME: Can this ever happen ? */ 2954 gcc_unreachable (); 2955 } 2956 break; 2957 2958 case LABEL_REF: 2959 case SYMBOL_REF: 2960 return true; 2961 case CONST_DOUBLE: 2962 return (rx_max_constant_size == 0 || rx_max_constant_size == 4); 2963 case CONST_VECTOR: 2964 return false; 2965 default: 2966 gcc_assert (CONST_INT_P (x)); 2967 break; 2968 } 2969 2970 return ok_for_max_constant (INTVAL (x)); 2971} 2972 2973static int 2974rx_address_cost (rtx addr, machine_mode mode ATTRIBUTE_UNUSED, 2975 addr_space_t as ATTRIBUTE_UNUSED, bool speed) 2976{ 2977 rtx a, b; 2978 2979 if (GET_CODE (addr) != PLUS) 2980 return COSTS_N_INSNS (1); 2981 2982 a = XEXP (addr, 0); 2983 b = XEXP (addr, 1); 2984 2985 if (REG_P (a) && REG_P (b)) 2986 /* Try to discourage REG+REG addressing as it keeps two registers live. */ 2987 return COSTS_N_INSNS (4); 2988 2989 if (speed) 2990 /* [REG+OFF] is just as fast as [REG]. */ 2991 return COSTS_N_INSNS (1); 2992 2993 if (CONST_INT_P (b) 2994 && ((INTVAL (b) > 128) || INTVAL (b) < -127)) 2995 /* Try to discourage REG + <large OFF> when optimizing for size. */ 2996 return COSTS_N_INSNS (2); 2997 2998 return COSTS_N_INSNS (1); 2999} 3000 3001static bool 3002rx_rtx_costs (rtx x, machine_mode mode, int outer_code ATTRIBUTE_UNUSED, 3003 int opno ATTRIBUTE_UNUSED, int* total, bool speed) 3004{ 3005 if (x == const0_rtx) 3006 { 3007 *total = 0; 3008 return true; 3009 } 3010 3011 switch (GET_CODE (x)) 3012 { 3013 case MULT: 3014 if (mode == DImode) 3015 { 3016 *total = COSTS_N_INSNS (2); 3017 return true; 3018 } 3019 /* fall through */ 3020 3021 case PLUS: 3022 case MINUS: 3023 case AND: 3024 case COMPARE: 3025 case IOR: 3026 case XOR: 3027 *total = COSTS_N_INSNS (1); 3028 return true; 3029 3030 case DIV: 3031 if (speed) 3032 /* This is the worst case for a division. Pessimize divisions when 3033 not optimizing for size and allow reciprocal optimizations which 3034 produce bigger code. */ 3035 *total = COSTS_N_INSNS (20); 3036 else 3037 *total = COSTS_N_INSNS (3); 3038 return true; 3039 3040 case UDIV: 3041 if (speed) 3042 /* This is the worst case for a division. Pessimize divisions when 3043 not optimizing for size and allow reciprocal optimizations which 3044 produce bigger code. */ 3045 *total = COSTS_N_INSNS (18); 3046 else 3047 *total = COSTS_N_INSNS (3); 3048 return true; 3049 3050 default: 3051 break; 3052 } 3053 3054 return false; 3055} 3056 3057static bool 3058rx_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) 3059{ 3060 /* We can always eliminate to the frame pointer. 3061 We can eliminate to the stack pointer unless a frame 3062 pointer is needed. */ 3063 3064 return to == FRAME_POINTER_REGNUM 3065 || ( to == STACK_POINTER_REGNUM && ! frame_pointer_needed); 3066} 3067 3068 3069static void 3070rx_trampoline_template (FILE * file) 3071{ 3072 /* Output assembler code for a block containing the constant 3073 part of a trampoline, leaving space for the variable parts. 3074 3075 On the RX, (where r8 is the static chain regnum) the trampoline 3076 looks like: 3077 3078 mov #<static chain value>, r8 3079 mov #<function's address>, r9 3080 jmp r9 3081 3082 In big-endian-data-mode however instructions are read into the CPU 3083 4 bytes at a time. These bytes are then swapped around before being 3084 passed to the decoder. So...we must partition our trampoline into 3085 4 byte packets and swap these packets around so that the instruction 3086 reader will reverse the process. But, in order to avoid splitting 3087 the 32-bit constants across these packet boundaries, (making inserting 3088 them into the constructed trampoline very difficult) we have to pad the 3089 instruction sequence with NOP insns. ie: 3090 3091 nop 3092 nop 3093 mov.l #<...>, r8 3094 nop 3095 nop 3096 mov.l #<...>, r9 3097 jmp r9 3098 nop 3099 nop */ 3100 3101 if (! TARGET_BIG_ENDIAN_DATA) 3102 { 3103 asm_fprintf (file, "\tmov.L\t#0deadbeefH, r%d\n", STATIC_CHAIN_REGNUM); 3104 asm_fprintf (file, "\tmov.L\t#0deadbeefH, r%d\n", TRAMPOLINE_TEMP_REGNUM); 3105 asm_fprintf (file, "\tjmp\tr%d\n", TRAMPOLINE_TEMP_REGNUM); 3106 } 3107 else 3108 { 3109 char r8 = '0' + STATIC_CHAIN_REGNUM; 3110 char r9 = '0' + TRAMPOLINE_TEMP_REGNUM; 3111 3112 if (TARGET_AS100_SYNTAX) 3113 { 3114 asm_fprintf (file, "\t.BYTE 0%c2H, 0fbH, 003H, 003H\n", r8); 3115 asm_fprintf (file, "\t.BYTE 0deH, 0adH, 0beH, 0efH\n"); 3116 asm_fprintf (file, "\t.BYTE 0%c2H, 0fbH, 003H, 003H\n", r9); 3117 asm_fprintf (file, "\t.BYTE 0deH, 0adH, 0beH, 0efH\n"); 3118 asm_fprintf (file, "\t.BYTE 003H, 003H, 00%cH, 07fH\n", r9); 3119 } 3120 else 3121 { 3122 asm_fprintf (file, "\t.byte 0x%c2, 0xfb, 0x03, 0x03\n", r8); 3123 asm_fprintf (file, "\t.byte 0xde, 0xad, 0xbe, 0xef\n"); 3124 asm_fprintf (file, "\t.byte 0x%c2, 0xfb, 0x03, 0x03\n", r9); 3125 asm_fprintf (file, "\t.byte 0xde, 0xad, 0xbe, 0xef\n"); 3126 asm_fprintf (file, "\t.byte 0x03, 0x03, 0x0%c, 0x7f\n", r9); 3127 } 3128 } 3129} 3130 3131static void 3132rx_trampoline_init (rtx tramp, tree fndecl, rtx chain) 3133{ 3134 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0); 3135 3136 emit_block_move (tramp, assemble_trampoline_template (), 3137 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL); 3138 3139 if (TARGET_BIG_ENDIAN_DATA) 3140 { 3141 emit_move_insn (adjust_address (tramp, SImode, 4), chain); 3142 emit_move_insn (adjust_address (tramp, SImode, 12), fnaddr); 3143 } 3144 else 3145 { 3146 emit_move_insn (adjust_address (tramp, SImode, 2), chain); 3147 emit_move_insn (adjust_address (tramp, SImode, 6 + 2), fnaddr); 3148 } 3149} 3150 3151static int 3152rx_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED, 3153 reg_class_t regclass ATTRIBUTE_UNUSED, 3154 bool in) 3155{ 3156 return (in ? 2 : 0) + REGISTER_MOVE_COST (mode, regclass, regclass); 3157} 3158 3159/* Convert a CC_MODE to the set of flags that it represents. */ 3160 3161static unsigned int 3162flags_from_mode (machine_mode mode) 3163{ 3164 switch (mode) 3165 { 3166 case E_CC_ZSmode: 3167 return CC_FLAG_S | CC_FLAG_Z; 3168 case E_CC_ZSOmode: 3169 return CC_FLAG_S | CC_FLAG_Z | CC_FLAG_O; 3170 case E_CC_ZSCmode: 3171 return CC_FLAG_S | CC_FLAG_Z | CC_FLAG_C; 3172 case E_CCmode: 3173 return CC_FLAG_S | CC_FLAG_Z | CC_FLAG_O | CC_FLAG_C; 3174 case E_CC_Fmode: 3175 return CC_FLAG_FP; 3176 default: 3177 gcc_unreachable (); 3178 } 3179} 3180 3181/* Convert a set of flags to a CC_MODE that can implement it. */ 3182 3183static machine_mode 3184mode_from_flags (unsigned int f) 3185{ 3186 if (f & CC_FLAG_FP) 3187 return CC_Fmode; 3188 if (f & CC_FLAG_O) 3189 { 3190 if (f & CC_FLAG_C) 3191 return CCmode; 3192 else 3193 return CC_ZSOmode; 3194 } 3195 else if (f & CC_FLAG_C) 3196 return CC_ZSCmode; 3197 else 3198 return CC_ZSmode; 3199} 3200 3201/* Convert an RTX_CODE to the set of flags needed to implement it. 3202 This assumes an integer comparison. */ 3203 3204static unsigned int 3205flags_from_code (enum rtx_code code) 3206{ 3207 switch (code) 3208 { 3209 case LT: 3210 case GE: 3211 return CC_FLAG_S; 3212 case GT: 3213 case LE: 3214 return CC_FLAG_S | CC_FLAG_O | CC_FLAG_Z; 3215 case GEU: 3216 case LTU: 3217 return CC_FLAG_C; 3218 case GTU: 3219 case LEU: 3220 return CC_FLAG_C | CC_FLAG_Z; 3221 case EQ: 3222 case NE: 3223 return CC_FLAG_Z; 3224 default: 3225 gcc_unreachable (); 3226 } 3227} 3228 3229/* Return a CC_MODE of which both M1 and M2 are subsets. */ 3230 3231static machine_mode 3232rx_cc_modes_compatible (machine_mode m1, machine_mode m2) 3233{ 3234 unsigned f; 3235 3236 /* Early out for identical modes. */ 3237 if (m1 == m2) 3238 return m1; 3239 3240 /* There's no valid combination for FP vs non-FP. */ 3241 f = flags_from_mode (m1) | flags_from_mode (m2); 3242 if (f & CC_FLAG_FP) 3243 return VOIDmode; 3244 3245 /* Otherwise, see what mode can implement all the flags. */ 3246 return mode_from_flags (f); 3247} 3248 3249/* Return the minimal CC mode needed to implement (CMP_CODE X Y). */ 3250 3251machine_mode 3252rx_select_cc_mode (enum rtx_code cmp_code, rtx x, rtx y) 3253{ 3254 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) 3255 return CC_Fmode; 3256 3257 if (y != const0_rtx) 3258 return CCmode; 3259 3260 return mode_from_flags (flags_from_code (cmp_code)); 3261} 3262 3263/* Split the conditional branch. Emit (COMPARE C1 C2) into CC_REG with 3264 CC_MODE, and use that in branches based on that compare. */ 3265 3266void 3267rx_split_cbranch (machine_mode cc_mode, enum rtx_code cmp1, 3268 rtx c1, rtx c2, rtx label) 3269{ 3270 rtx flags, x; 3271 3272 flags = gen_rtx_REG (cc_mode, CC_REG); 3273 x = gen_rtx_COMPARE (cc_mode, c1, c2); 3274 x = gen_rtx_SET (flags, x); 3275 emit_insn (x); 3276 3277 x = gen_rtx_fmt_ee (cmp1, VOIDmode, flags, const0_rtx); 3278 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, label, pc_rtx); 3279 x = gen_rtx_SET (pc_rtx, x); 3280 emit_jump_insn (x); 3281} 3282 3283/* A helper function for matching parallels that set the flags. */ 3284 3285bool 3286rx_match_ccmode (rtx insn, machine_mode cc_mode) 3287{ 3288 rtx op1, flags; 3289 machine_mode flags_mode; 3290 3291 gcc_checking_assert (XVECLEN (PATTERN (insn), 0) == 2); 3292 3293 op1 = XVECEXP (PATTERN (insn), 0, 0); 3294 gcc_checking_assert (GET_CODE (SET_SRC (op1)) == COMPARE); 3295 3296 flags = SET_DEST (op1); 3297 flags_mode = GET_MODE (flags); 3298 3299 if (GET_MODE (SET_SRC (op1)) != flags_mode) 3300 return false; 3301 if (GET_MODE_CLASS (flags_mode) != MODE_CC) 3302 return false; 3303 3304 /* Ensure that the mode of FLAGS is compatible with CC_MODE. */ 3305 if (flags_from_mode (flags_mode) & ~flags_from_mode (cc_mode)) 3306 return false; 3307 3308 return true; 3309} 3310 3311 3312static int 3313rx_max_skip_for_label (rtx_insn *lab) 3314{ 3315 int opsize; 3316 rtx_insn *op; 3317 3318 if (optimize_size) 3319 return 0; 3320 3321 if (lab == NULL) 3322 return 0; 3323 3324 op = lab; 3325 do 3326 { 3327 op = next_nonnote_nondebug_insn (op); 3328 } 3329 while (op && (LABEL_P (op) 3330 || (INSN_P (op) && GET_CODE (PATTERN (op)) == USE))); 3331 if (!op) 3332 return 0; 3333 3334 opsize = get_attr_length (op); 3335 if (opsize >= 0 && opsize < 8) 3336 return MAX (0, opsize - 1); 3337 return 0; 3338} 3339 3340static int 3341rx_align_log_for_label (rtx_insn *lab, int uses_threshold) 3342{ 3343 /* This is a simple heuristic to guess when an alignment would not be useful 3344 because the delay due to the inserted NOPs would be greater than the delay 3345 due to the misaligned branch. If uses_threshold is zero then the alignment 3346 is always useful. */ 3347 if (LABEL_P (lab) && LABEL_NUSES (lab) < uses_threshold) 3348 return 0; 3349 3350 if (optimize_size) 3351 return 0; 3352 3353 /* Return zero if max_skip not a positive number. */ 3354 int max_skip = rx_max_skip_for_label (lab); 3355 if (max_skip <= 0) 3356 return 0; 3357 3358 /* These values are log, not bytes. */ 3359 if (rx_cpu_type == RX100 || rx_cpu_type == RX200) 3360 return 2; /* 4 bytes */ 3361 return 3; /* 8 bytes */ 3362} 3363 3364align_flags 3365rx_align_for_label (rtx_insn *lab, int uses_threshold) 3366{ 3367 return align_flags (rx_align_log_for_label (lab, uses_threshold), 3368 rx_max_skip_for_label (lab)); 3369} 3370 3371/* Compute the real length of the extending load-and-op instructions. */ 3372 3373int 3374rx_adjust_insn_length (rtx_insn *insn, int current_length) 3375{ 3376 rtx extend, mem, offset; 3377 bool zero; 3378 int factor; 3379 3380 if (!INSN_P (insn)) 3381 return current_length; 3382 3383 switch (INSN_CODE (insn)) 3384 { 3385 default: 3386 return current_length; 3387 3388 case CODE_FOR_plussi3_zero_extendhi: 3389 case CODE_FOR_andsi3_zero_extendhi: 3390 case CODE_FOR_iorsi3_zero_extendhi: 3391 case CODE_FOR_xorsi3_zero_extendhi: 3392 case CODE_FOR_divsi3_zero_extendhi: 3393 case CODE_FOR_udivsi3_zero_extendhi: 3394 case CODE_FOR_minussi3_zero_extendhi: 3395 case CODE_FOR_smaxsi3_zero_extendhi: 3396 case CODE_FOR_sminsi3_zero_extendhi: 3397 case CODE_FOR_multsi3_zero_extendhi: 3398 case CODE_FOR_comparesi3_zero_extendhi: 3399 zero = true; 3400 factor = 2; 3401 break; 3402 3403 case CODE_FOR_plussi3_sign_extendhi: 3404 case CODE_FOR_andsi3_sign_extendhi: 3405 case CODE_FOR_iorsi3_sign_extendhi: 3406 case CODE_FOR_xorsi3_sign_extendhi: 3407 case CODE_FOR_divsi3_sign_extendhi: 3408 case CODE_FOR_udivsi3_sign_extendhi: 3409 case CODE_FOR_minussi3_sign_extendhi: 3410 case CODE_FOR_smaxsi3_sign_extendhi: 3411 case CODE_FOR_sminsi3_sign_extendhi: 3412 case CODE_FOR_multsi3_sign_extendhi: 3413 case CODE_FOR_comparesi3_sign_extendhi: 3414 zero = false; 3415 factor = 2; 3416 break; 3417 3418 case CODE_FOR_plussi3_zero_extendqi: 3419 case CODE_FOR_andsi3_zero_extendqi: 3420 case CODE_FOR_iorsi3_zero_extendqi: 3421 case CODE_FOR_xorsi3_zero_extendqi: 3422 case CODE_FOR_divsi3_zero_extendqi: 3423 case CODE_FOR_udivsi3_zero_extendqi: 3424 case CODE_FOR_minussi3_zero_extendqi: 3425 case CODE_FOR_smaxsi3_zero_extendqi: 3426 case CODE_FOR_sminsi3_zero_extendqi: 3427 case CODE_FOR_multsi3_zero_extendqi: 3428 case CODE_FOR_comparesi3_zero_extendqi: 3429 zero = true; 3430 factor = 1; 3431 break; 3432 3433 case CODE_FOR_plussi3_sign_extendqi: 3434 case CODE_FOR_andsi3_sign_extendqi: 3435 case CODE_FOR_iorsi3_sign_extendqi: 3436 case CODE_FOR_xorsi3_sign_extendqi: 3437 case CODE_FOR_divsi3_sign_extendqi: 3438 case CODE_FOR_udivsi3_sign_extendqi: 3439 case CODE_FOR_minussi3_sign_extendqi: 3440 case CODE_FOR_smaxsi3_sign_extendqi: 3441 case CODE_FOR_sminsi3_sign_extendqi: 3442 case CODE_FOR_multsi3_sign_extendqi: 3443 case CODE_FOR_comparesi3_sign_extendqi: 3444 zero = false; 3445 factor = 1; 3446 break; 3447 } 3448 3449 /* We are expecting: (SET (REG) (<OP> (REG) (<EXTEND> (MEM)))). */ 3450 extend = single_set (insn); 3451 gcc_assert (extend != NULL_RTX); 3452 3453 extend = SET_SRC (extend); 3454 if (GET_CODE (XEXP (extend, 0)) == ZERO_EXTEND 3455 || GET_CODE (XEXP (extend, 0)) == SIGN_EXTEND) 3456 extend = XEXP (extend, 0); 3457 else 3458 extend = XEXP (extend, 1); 3459 3460 gcc_assert ((zero && (GET_CODE (extend) == ZERO_EXTEND)) 3461 || (! zero && (GET_CODE (extend) == SIGN_EXTEND))); 3462 3463 mem = XEXP (extend, 0); 3464 gcc_checking_assert (MEM_P (mem)); 3465 if (REG_P (XEXP (mem, 0))) 3466 return (zero && factor == 1) ? 2 : 3; 3467 3468 /* We are expecting: (MEM (PLUS (REG) (CONST_INT))). */ 3469 gcc_checking_assert (GET_CODE (XEXP (mem, 0)) == PLUS); 3470 gcc_checking_assert (REG_P (XEXP (XEXP (mem, 0), 0))); 3471 3472 offset = XEXP (XEXP (mem, 0), 1); 3473 gcc_checking_assert (GET_CODE (offset) == CONST_INT); 3474 3475 if (IN_RANGE (INTVAL (offset), 0, 255 * factor)) 3476 return (zero && factor == 1) ? 3 : 4; 3477 3478 return (zero && factor == 1) ? 4 : 5; 3479} 3480 3481static bool 3482rx_narrow_volatile_bitfield (void) 3483{ 3484 return true; 3485} 3486 3487static bool 3488rx_ok_to_inline (tree caller, tree callee) 3489{ 3490 /* Do not inline functions with local variables 3491 into a naked CALLER - naked function have no stack frame and 3492 locals need a frame in order to have somewhere to live. 3493 3494 Unfortunately we have no way to determine the presence of 3495 local variables in CALLEE, so we have to be cautious and 3496 assume that there might be some there. 3497 3498 We do allow inlining when CALLEE has the "inline" type 3499 modifier or the "always_inline" or "gnu_inline" attributes. */ 3500 return lookup_attribute ("naked", DECL_ATTRIBUTES (caller)) == NULL_TREE 3501 || DECL_DECLARED_INLINE_P (callee) 3502 || lookup_attribute ("always_inline", DECL_ATTRIBUTES (callee)) != NULL_TREE 3503 || lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (callee)) != NULL_TREE; 3504} 3505 3506static bool 3507rx_enable_lra (void) 3508{ 3509 return TARGET_ENABLE_LRA; 3510} 3511 3512rx_atomic_sequence::rx_atomic_sequence (const_tree fun_decl) 3513{ 3514 if (is_fast_interrupt_func (fun_decl) || is_interrupt_func (fun_decl)) 3515 { 3516 /* If we are inside an interrupt handler, assume that interrupts are 3517 off -- which is the default hardware behavior. In this case, there 3518 is no need to disable the interrupts. */ 3519 m_prev_psw_reg = NULL; 3520 } 3521 else 3522 { 3523 m_prev_psw_reg = gen_reg_rtx (SImode); 3524 emit_insn (gen_mvfc (m_prev_psw_reg, GEN_INT (CTRLREG_PSW))); 3525 emit_insn (gen_clrpsw (GEN_INT ('I'))); 3526 } 3527} 3528 3529rx_atomic_sequence::~rx_atomic_sequence (void) 3530{ 3531 if (m_prev_psw_reg != NULL) 3532 emit_insn (gen_mvtc (GEN_INT (CTRLREG_PSW), m_prev_psw_reg)); 3533} 3534 3535/* Given an insn and a reg number, tell whether the reg dies or is unused 3536 after the insn. */ 3537bool 3538rx_reg_dead_or_unused_after_insn (const rtx_insn* i, int regno) 3539{ 3540 return find_regno_note (i, REG_DEAD, regno) != NULL 3541 || find_regno_note (i, REG_UNUSED, regno) != NULL; 3542} 3543 3544/* Copy dead and unused notes from SRC to DST for the specified REGNO. */ 3545void 3546rx_copy_reg_dead_or_unused_notes (rtx reg, const rtx_insn* src, rtx_insn* dst) 3547{ 3548 int regno = REGNO (SUBREG_P (reg) ? SUBREG_REG (reg) : reg); 3549 3550 if (rtx note = find_regno_note (src, REG_DEAD, regno)) 3551 add_shallow_copy_of_reg_note (dst, note); 3552 3553 if (rtx note = find_regno_note (src, REG_UNUSED, regno)) 3554 add_shallow_copy_of_reg_note (dst, note); 3555} 3556 3557/* Try to fuse the current bit-operation insn with the surrounding memory load 3558 and store. */ 3559bool 3560rx_fuse_in_memory_bitop (rtx* operands, rtx_insn* curr_insn, 3561 rtx (*gen_insn)(rtx, rtx)) 3562{ 3563 rtx op2_reg = SUBREG_P (operands[2]) ? SUBREG_REG (operands[2]) : operands[2]; 3564 3565 set_of_reg op2_def = rx_find_set_of_reg (op2_reg, curr_insn, 3566 prev_nonnote_nondebug_insn_bb); 3567 if (op2_def.set_src == NULL_RTX 3568 || !MEM_P (op2_def.set_src) 3569 || GET_MODE (op2_def.set_src) != QImode 3570 || !rx_is_restricted_memory_address (XEXP (op2_def.set_src, 0), 3571 GET_MODE (op2_def.set_src)) 3572 || reg_used_between_p (operands[2], op2_def.insn, curr_insn) 3573 || !rx_reg_dead_or_unused_after_insn (curr_insn, REGNO (op2_reg)) 3574 ) 3575 return false; 3576 3577 /* The register operand originates from a memory load and the memory load 3578 could be fused with the bitop insn. 3579 Look for the following memory store with the same memory operand. */ 3580 rtx mem = op2_def.set_src; 3581 3582 /* If the memory is an auto-mod address, it can't be fused. */ 3583 if (GET_CODE (XEXP (mem, 0)) == POST_INC 3584 || GET_CODE (XEXP (mem, 0)) == PRE_INC 3585 || GET_CODE (XEXP (mem, 0)) == POST_DEC 3586 || GET_CODE (XEXP (mem, 0)) == PRE_DEC) 3587 return false; 3588 3589 rtx_insn* op0_use = rx_find_use_of_reg (operands[0], curr_insn, 3590 next_nonnote_nondebug_insn_bb); 3591 if (op0_use == NULL 3592 || !(GET_CODE (PATTERN (op0_use)) == SET 3593 && RX_REG_P (XEXP (PATTERN (op0_use), 1)) 3594 && reg_overlap_mentioned_p (operands[0], XEXP (PATTERN (op0_use), 1)) 3595 && rtx_equal_p (mem, XEXP (PATTERN (op0_use), 0))) 3596 || !rx_reg_dead_or_unused_after_insn (op0_use, REGNO (operands[0])) 3597 || reg_set_between_p (operands[2], curr_insn, op0_use)) 3598 return false; 3599 3600 /* If the load-modify-store operation is fused it could potentially modify 3601 load/store ordering if there are other memory accesses between the load 3602 and the store for this insn. If there are volatile mems between the load 3603 and store it's better not to change the ordering. If there is a call 3604 between the load and store, it's also not safe to fuse it. */ 3605 for (rtx_insn* i = next_nonnote_nondebug_insn_bb (op2_def.insn); 3606 i != NULL && i != op0_use; 3607 i = next_nonnote_nondebug_insn_bb (i)) 3608 if (volatile_insn_p (PATTERN (i)) || CALL_P (i)) 3609 return false; 3610 3611 emit_insn (gen_insn (mem, gen_lowpart (QImode, operands[1]))); 3612 set_insn_deleted (op2_def.insn); 3613 set_insn_deleted (op0_use); 3614 return true; 3615} 3616 3617/* Implement TARGET_HARD_REGNO_NREGS. */ 3618 3619static unsigned int 3620rx_hard_regno_nregs (unsigned int, machine_mode mode) 3621{ 3622 return CLASS_MAX_NREGS (0, mode); 3623} 3624 3625/* Implement TARGET_HARD_REGNO_MODE_OK. */ 3626 3627static bool 3628rx_hard_regno_mode_ok (unsigned int regno, machine_mode) 3629{ 3630 return REGNO_REG_CLASS (regno) == GR_REGS; 3631} 3632 3633/* Implement TARGET_MODES_TIEABLE_P. */ 3634 3635static bool 3636rx_modes_tieable_p (machine_mode mode1, machine_mode mode2) 3637{ 3638 return ((GET_MODE_CLASS (mode1) == MODE_FLOAT 3639 || GET_MODE_CLASS (mode1) == MODE_COMPLEX_FLOAT) 3640 == (GET_MODE_CLASS (mode2) == MODE_FLOAT 3641 || GET_MODE_CLASS (mode2) == MODE_COMPLEX_FLOAT)); 3642} 3643 3644#undef TARGET_NARROW_VOLATILE_BITFIELD 3645#define TARGET_NARROW_VOLATILE_BITFIELD rx_narrow_volatile_bitfield 3646 3647#undef TARGET_CAN_INLINE_P 3648#define TARGET_CAN_INLINE_P rx_ok_to_inline 3649 3650#undef TARGET_FUNCTION_VALUE 3651#define TARGET_FUNCTION_VALUE rx_function_value 3652 3653#undef TARGET_RETURN_IN_MSB 3654#define TARGET_RETURN_IN_MSB rx_return_in_msb 3655 3656#undef TARGET_IN_SMALL_DATA_P 3657#define TARGET_IN_SMALL_DATA_P rx_in_small_data 3658 3659#undef TARGET_RETURN_IN_MEMORY 3660#define TARGET_RETURN_IN_MEMORY rx_return_in_memory 3661 3662#undef TARGET_HAVE_SRODATA_SECTION 3663#define TARGET_HAVE_SRODATA_SECTION true 3664 3665#undef TARGET_ASM_SELECT_RTX_SECTION 3666#define TARGET_ASM_SELECT_RTX_SECTION rx_select_rtx_section 3667 3668#undef TARGET_ASM_SELECT_SECTION 3669#define TARGET_ASM_SELECT_SECTION rx_select_section 3670 3671#undef TARGET_INIT_BUILTINS 3672#define TARGET_INIT_BUILTINS rx_init_builtins 3673 3674#undef TARGET_BUILTIN_DECL 3675#define TARGET_BUILTIN_DECL rx_builtin_decl 3676 3677#undef TARGET_EXPAND_BUILTIN 3678#define TARGET_EXPAND_BUILTIN rx_expand_builtin 3679 3680#undef TARGET_ASM_CONSTRUCTOR 3681#define TARGET_ASM_CONSTRUCTOR rx_elf_asm_constructor 3682 3683#undef TARGET_ASM_DESTRUCTOR 3684#define TARGET_ASM_DESTRUCTOR rx_elf_asm_destructor 3685 3686#undef TARGET_STRUCT_VALUE_RTX 3687#define TARGET_STRUCT_VALUE_RTX rx_struct_value_rtx 3688 3689#undef TARGET_ATTRIBUTE_TABLE 3690#define TARGET_ATTRIBUTE_TABLE rx_attribute_table 3691 3692#undef TARGET_ASM_FILE_START 3693#define TARGET_ASM_FILE_START rx_file_start 3694 3695#undef TARGET_MS_BITFIELD_LAYOUT_P 3696#define TARGET_MS_BITFIELD_LAYOUT_P rx_is_ms_bitfield_layout 3697 3698#undef TARGET_LEGITIMATE_ADDRESS_P 3699#define TARGET_LEGITIMATE_ADDRESS_P rx_is_legitimate_address 3700 3701#undef TARGET_MODE_DEPENDENT_ADDRESS_P 3702#define TARGET_MODE_DEPENDENT_ADDRESS_P rx_mode_dependent_address_p 3703 3704#undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS 3705#define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS rx_allocate_stack_slots_for_args 3706 3707#undef TARGET_ASM_FUNCTION_PROLOGUE 3708#define TARGET_ASM_FUNCTION_PROLOGUE rx_output_function_prologue 3709 3710#undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P 3711#define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P rx_func_attr_inlinable 3712 3713#undef TARGET_FUNCTION_OK_FOR_SIBCALL 3714#define TARGET_FUNCTION_OK_FOR_SIBCALL rx_function_ok_for_sibcall 3715 3716#undef TARGET_FUNCTION_ARG 3717#define TARGET_FUNCTION_ARG rx_function_arg 3718 3719#undef TARGET_FUNCTION_ARG_ADVANCE 3720#define TARGET_FUNCTION_ARG_ADVANCE rx_function_arg_advance 3721 3722#undef TARGET_FUNCTION_ARG_BOUNDARY 3723#define TARGET_FUNCTION_ARG_BOUNDARY rx_function_arg_boundary 3724 3725#undef TARGET_SET_CURRENT_FUNCTION 3726#define TARGET_SET_CURRENT_FUNCTION rx_set_current_function 3727 3728#undef TARGET_ASM_INTEGER 3729#define TARGET_ASM_INTEGER rx_assemble_integer 3730 3731#undef TARGET_USE_BLOCKS_FOR_CONSTANT_P 3732#define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true 3733 3734#undef TARGET_MAX_ANCHOR_OFFSET 3735#define TARGET_MAX_ANCHOR_OFFSET 32 3736 3737#undef TARGET_ADDRESS_COST 3738#define TARGET_ADDRESS_COST rx_address_cost 3739 3740#undef TARGET_CAN_ELIMINATE 3741#define TARGET_CAN_ELIMINATE rx_can_eliminate 3742 3743#undef TARGET_CONDITIONAL_REGISTER_USAGE 3744#define TARGET_CONDITIONAL_REGISTER_USAGE rx_conditional_register_usage 3745 3746#undef TARGET_ASM_TRAMPOLINE_TEMPLATE 3747#define TARGET_ASM_TRAMPOLINE_TEMPLATE rx_trampoline_template 3748 3749#undef TARGET_TRAMPOLINE_INIT 3750#define TARGET_TRAMPOLINE_INIT rx_trampoline_init 3751 3752#undef TARGET_PRINT_OPERAND 3753#define TARGET_PRINT_OPERAND rx_print_operand 3754 3755#undef TARGET_PRINT_OPERAND_ADDRESS 3756#define TARGET_PRINT_OPERAND_ADDRESS rx_print_operand_address 3757 3758#undef TARGET_CC_MODES_COMPATIBLE 3759#define TARGET_CC_MODES_COMPATIBLE rx_cc_modes_compatible 3760 3761#undef TARGET_MEMORY_MOVE_COST 3762#define TARGET_MEMORY_MOVE_COST rx_memory_move_cost 3763 3764#undef TARGET_OPTION_OVERRIDE 3765#define TARGET_OPTION_OVERRIDE rx_option_override 3766 3767#undef TARGET_PROMOTE_FUNCTION_MODE 3768#define TARGET_PROMOTE_FUNCTION_MODE rx_promote_function_mode 3769 3770#undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE 3771#define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE rx_override_options_after_change 3772 3773#undef TARGET_FLAGS_REGNUM 3774#define TARGET_FLAGS_REGNUM CC_REG 3775 3776#undef TARGET_LEGITIMATE_CONSTANT_P 3777#define TARGET_LEGITIMATE_CONSTANT_P rx_is_legitimate_constant 3778 3779#undef TARGET_LEGITIMIZE_ADDRESS 3780#define TARGET_LEGITIMIZE_ADDRESS rx_legitimize_address 3781 3782#undef TARGET_WARN_FUNC_RETURN 3783#define TARGET_WARN_FUNC_RETURN rx_warn_func_return 3784 3785#undef TARGET_LRA_P 3786#define TARGET_LRA_P rx_enable_lra 3787 3788#undef TARGET_HARD_REGNO_NREGS 3789#define TARGET_HARD_REGNO_NREGS rx_hard_regno_nregs 3790#undef TARGET_HARD_REGNO_MODE_OK 3791#define TARGET_HARD_REGNO_MODE_OK rx_hard_regno_mode_ok 3792 3793#undef TARGET_MODES_TIEABLE_P 3794#define TARGET_MODES_TIEABLE_P rx_modes_tieable_p 3795 3796#undef TARGET_RTX_COSTS 3797#define TARGET_RTX_COSTS rx_rtx_costs 3798 3799#undef TARGET_HAVE_SPECULATION_SAFE_VALUE 3800#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed 3801 3802struct gcc_target targetm = TARGET_INITIALIZER; 3803 3804#include "gt-rx.h" 3805