1/* Subroutines used for code generation on Vitesse IQ2000 processors 2 Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. 3 4This file is part of GCC. 5 6GCC is free software; you can redistribute it and/or modify 7it under the terms of the GNU General Public License as published by 8the Free Software Foundation; either version 2, or (at your option) 9any later version. 10 11GCC is distributed in the hope that it will be useful, 12but WITHOUT ANY WARRANTY; without even the implied warranty of 13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14GNU General Public License for more details. 15 16You should have received a copy of the GNU General Public License 17along with GCC; see the file COPYING. If not, write to 18the Free Software Foundation, 51 Franklin Street, Fifth Floor, 19Boston, MA 02110-1301, USA. */ 20 21#include "config.h" 22#include "system.h" 23#include "coretypes.h" 24#include <signal.h> 25#include "tm.h" 26#include "tree.h" 27#include "rtl.h" 28#include "regs.h" 29#include "hard-reg-set.h" 30#include "real.h" 31#include "insn-config.h" 32#include "conditions.h" 33#include "output.h" 34#include "insn-attr.h" 35#include "flags.h" 36#include "function.h" 37#include "expr.h" 38#include "optabs.h" 39#include "libfuncs.h" 40#include "recog.h" 41#include "toplev.h" 42#include "reload.h" 43#include "ggc.h" 44#include "tm_p.h" 45#include "debug.h" 46#include "target.h" 47#include "target-def.h" 48#include "langhooks.h" 49 50/* Enumeration for all of the relational tests, so that we can build 51 arrays indexed by the test type, and not worry about the order 52 of EQ, NE, etc. */ 53 54enum internal_test 55 { 56 ITEST_EQ, 57 ITEST_NE, 58 ITEST_GT, 59 ITEST_GE, 60 ITEST_LT, 61 ITEST_LE, 62 ITEST_GTU, 63 ITEST_GEU, 64 ITEST_LTU, 65 ITEST_LEU, 66 ITEST_MAX 67 }; 68 69struct constant; 70 71 72/* Structure to be filled in by compute_frame_size with register 73 save masks, and offsets for the current function. */ 74 75struct iq2000_frame_info 76{ 77 long total_size; /* # bytes that the entire frame takes up. */ 78 long var_size; /* # bytes that variables take up. */ 79 long args_size; /* # bytes that outgoing arguments take up. */ 80 long extra_size; /* # bytes of extra gunk. */ 81 int gp_reg_size; /* # bytes needed to store gp regs. */ 82 int fp_reg_size; /* # bytes needed to store fp regs. */ 83 long mask; /* Mask of saved gp registers. */ 84 long gp_save_offset; /* Offset from vfp to store gp registers. */ 85 long fp_save_offset; /* Offset from vfp to store fp registers. */ 86 long gp_sp_offset; /* Offset from new sp to store gp registers. */ 87 long fp_sp_offset; /* Offset from new sp to store fp registers. */ 88 int initialized; /* != 0 if frame size already calculated. */ 89 int num_gp; /* Number of gp registers saved. */ 90} iq2000_frame_info; 91 92struct machine_function GTY(()) 93{ 94 /* Current frame information, calculated by compute_frame_size. */ 95 long total_size; /* # bytes that the entire frame takes up. */ 96 long var_size; /* # bytes that variables take up. */ 97 long args_size; /* # bytes that outgoing arguments take up. */ 98 long extra_size; /* # bytes of extra gunk. */ 99 int gp_reg_size; /* # bytes needed to store gp regs. */ 100 int fp_reg_size; /* # bytes needed to store fp regs. */ 101 long mask; /* Mask of saved gp registers. */ 102 long gp_save_offset; /* Offset from vfp to store gp registers. */ 103 long fp_save_offset; /* Offset from vfp to store fp registers. */ 104 long gp_sp_offset; /* Offset from new sp to store gp registers. */ 105 long fp_sp_offset; /* Offset from new sp to store fp registers. */ 106 int initialized; /* != 0 if frame size already calculated. */ 107 int num_gp; /* Number of gp registers saved. */ 108}; 109 110/* Global variables for machine-dependent things. */ 111 112/* List of all IQ2000 punctuation characters used by print_operand. */ 113char iq2000_print_operand_punct[256]; 114 115/* The target cpu for optimization and scheduling. */ 116enum processor_type iq2000_tune; 117 118/* Which instruction set architecture to use. */ 119int iq2000_isa; 120 121/* Cached operands, and operator to compare for use in set/branch/trap 122 on condition codes. */ 123rtx branch_cmp[2]; 124 125/* What type of branch to use. */ 126enum cmp_type branch_type; 127 128/* Local variables. */ 129 130/* The next branch instruction is a branch likely, not branch normal. */ 131static int iq2000_branch_likely; 132 133/* Count of delay slots and how many are filled. */ 134static int dslots_load_total; 135static int dslots_load_filled; 136static int dslots_jump_total; 137 138/* # of nops needed by previous insn. */ 139static int dslots_number_nops; 140 141/* Number of 1/2/3 word references to data items (i.e., not jal's). */ 142static int num_refs[3]; 143 144/* Registers to check for load delay. */ 145static rtx iq2000_load_reg; 146static rtx iq2000_load_reg2; 147static rtx iq2000_load_reg3; 148static rtx iq2000_load_reg4; 149 150/* Mode used for saving/restoring general purpose registers. */ 151static enum machine_mode gpr_mode; 152 153 154/* Initialize the GCC target structure. */ 155static struct machine_function* iq2000_init_machine_status (void); 156static bool iq2000_handle_option (size_t, const char *, int); 157static section *iq2000_select_rtx_section (enum machine_mode, rtx, 158 unsigned HOST_WIDE_INT); 159static void iq2000_init_builtins (void); 160static rtx iq2000_expand_builtin (tree, rtx, rtx, enum machine_mode, int); 161static bool iq2000_return_in_memory (tree, tree); 162static void iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *, 163 enum machine_mode, tree, int *, 164 int); 165static bool iq2000_rtx_costs (rtx, int, int, int *); 166static int iq2000_address_cost (rtx); 167static section *iq2000_select_section (tree, int, unsigned HOST_WIDE_INT); 168static bool iq2000_return_in_memory (tree, tree); 169static bool iq2000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, 170 tree, bool); 171static int iq2000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, 172 tree, bool); 173 174#undef TARGET_INIT_BUILTINS 175#define TARGET_INIT_BUILTINS iq2000_init_builtins 176#undef TARGET_EXPAND_BUILTIN 177#define TARGET_EXPAND_BUILTIN iq2000_expand_builtin 178#undef TARGET_ASM_SELECT_RTX_SECTION 179#define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section 180#undef TARGET_HANDLE_OPTION 181#define TARGET_HANDLE_OPTION iq2000_handle_option 182#undef TARGET_RTX_COSTS 183#define TARGET_RTX_COSTS iq2000_rtx_costs 184#undef TARGET_ADDRESS_COST 185#define TARGET_ADDRESS_COST iq2000_address_cost 186#undef TARGET_ASM_SELECT_SECTION 187#define TARGET_ASM_SELECT_SECTION iq2000_select_section 188 189/* The assembler supports switchable .bss sections, but 190 iq2000_select_section doesn't yet make use of them. */ 191#undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS 192#define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS false 193 194#undef TARGET_PROMOTE_FUNCTION_ARGS 195#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true 196#undef TARGET_PROMOTE_FUNCTION_RETURN 197#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true 198#undef TARGET_PROMOTE_PROTOTYPES 199#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true 200 201#undef TARGET_RETURN_IN_MEMORY 202#define TARGET_RETURN_IN_MEMORY iq2000_return_in_memory 203#undef TARGET_PASS_BY_REFERENCE 204#define TARGET_PASS_BY_REFERENCE iq2000_pass_by_reference 205#undef TARGET_CALLEE_COPIES 206#define TARGET_CALLEE_COPIES hook_callee_copies_named 207#undef TARGET_ARG_PARTIAL_BYTES 208#define TARGET_ARG_PARTIAL_BYTES iq2000_arg_partial_bytes 209 210#undef TARGET_SETUP_INCOMING_VARARGS 211#define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs 212#undef TARGET_STRICT_ARGUMENT_NAMING 213#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true 214 215struct gcc_target targetm = TARGET_INITIALIZER; 216 217/* Return nonzero if we split the address into high and low parts. */ 218 219int 220iq2000_check_split (rtx address, enum machine_mode mode) 221{ 222 /* This is the same check used in simple_memory_operand. 223 We use it here because LO_SUM is not offsettable. */ 224 if (GET_MODE_SIZE (mode) > (unsigned) UNITS_PER_WORD) 225 return 0; 226 227 if ((GET_CODE (address) == SYMBOL_REF) 228 || (GET_CODE (address) == CONST 229 && GET_CODE (XEXP (XEXP (address, 0), 0)) == SYMBOL_REF) 230 || GET_CODE (address) == LABEL_REF) 231 return 1; 232 233 return 0; 234} 235 236/* Return nonzero if REG is valid for MODE. */ 237 238int 239iq2000_reg_mode_ok_for_base_p (rtx reg, 240 enum machine_mode mode ATTRIBUTE_UNUSED, 241 int strict) 242{ 243 return (strict 244 ? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg), mode) 245 : GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg), mode)); 246} 247 248/* Return a nonzero value if XINSN is a legitimate address for a 249 memory operand of the indicated MODE. STRICT is nonzero if this 250 function is called during reload. */ 251 252int 253iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, int strict) 254{ 255 if (TARGET_DEBUG_A_MODE) 256 { 257 GO_PRINTF2 ("\n========== GO_IF_LEGITIMATE_ADDRESS, %sstrict\n", 258 strict ? "" : "not "); 259 GO_DEBUG_RTX (xinsn); 260 } 261 262 /* Check for constant before stripping off SUBREG, so that we don't 263 accept (subreg (const_int)) which will fail to reload. */ 264 if (CONSTANT_ADDRESS_P (xinsn) 265 && ! (iq2000_check_split (xinsn, mode)) 266 && ! (GET_CODE (xinsn) == CONST_INT && ! SMALL_INT (xinsn))) 267 return 1; 268 269 while (GET_CODE (xinsn) == SUBREG) 270 xinsn = SUBREG_REG (xinsn); 271 272 if (GET_CODE (xinsn) == REG 273 && iq2000_reg_mode_ok_for_base_p (xinsn, mode, strict)) 274 return 1; 275 276 if (GET_CODE (xinsn) == LO_SUM) 277 { 278 rtx xlow0 = XEXP (xinsn, 0); 279 rtx xlow1 = XEXP (xinsn, 1); 280 281 while (GET_CODE (xlow0) == SUBREG) 282 xlow0 = SUBREG_REG (xlow0); 283 if (GET_CODE (xlow0) == REG 284 && iq2000_reg_mode_ok_for_base_p (xlow0, mode, strict) 285 && iq2000_check_split (xlow1, mode)) 286 return 1; 287 } 288 289 if (GET_CODE (xinsn) == PLUS) 290 { 291 rtx xplus0 = XEXP (xinsn, 0); 292 rtx xplus1 = XEXP (xinsn, 1); 293 enum rtx_code code0; 294 enum rtx_code code1; 295 296 while (GET_CODE (xplus0) == SUBREG) 297 xplus0 = SUBREG_REG (xplus0); 298 code0 = GET_CODE (xplus0); 299 300 while (GET_CODE (xplus1) == SUBREG) 301 xplus1 = SUBREG_REG (xplus1); 302 code1 = GET_CODE (xplus1); 303 304 if (code0 == REG 305 && iq2000_reg_mode_ok_for_base_p (xplus0, mode, strict)) 306 { 307 if (code1 == CONST_INT && SMALL_INT (xplus1) 308 && SMALL_INT_UNSIGNED (xplus1) /* No negative offsets */) 309 return 1; 310 } 311 } 312 313 if (TARGET_DEBUG_A_MODE) 314 GO_PRINTF ("Not a legitimate address\n"); 315 316 /* The address was not legitimate. */ 317 return 0; 318} 319 320/* Returns an operand string for the given instruction's delay slot, 321 after updating filled delay slot statistics. 322 323 We assume that operands[0] is the target register that is set. 324 325 In order to check the next insn, most of this functionality is moved 326 to FINAL_PRESCAN_INSN, and we just set the global variables that 327 it needs. */ 328 329const char * 330iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[], 331 rtx cur_insn) 332{ 333 rtx set_reg; 334 enum machine_mode mode; 335 rtx next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL_RTX; 336 int num_nops; 337 338 if (type == DELAY_LOAD || type == DELAY_FCMP) 339 num_nops = 1; 340 341 else 342 num_nops = 0; 343 344 /* Make sure that we don't put nop's after labels. */ 345 next_insn = NEXT_INSN (cur_insn); 346 while (next_insn != 0 347 && (GET_CODE (next_insn) == NOTE 348 || GET_CODE (next_insn) == CODE_LABEL)) 349 next_insn = NEXT_INSN (next_insn); 350 351 dslots_load_total += num_nops; 352 if (TARGET_DEBUG_C_MODE 353 || type == DELAY_NONE 354 || operands == 0 355 || cur_insn == 0 356 || next_insn == 0 357 || GET_CODE (next_insn) == CODE_LABEL 358 || (set_reg = operands[0]) == 0) 359 { 360 dslots_number_nops = 0; 361 iq2000_load_reg = 0; 362 iq2000_load_reg2 = 0; 363 iq2000_load_reg3 = 0; 364 iq2000_load_reg4 = 0; 365 366 return ret; 367 } 368 369 set_reg = operands[0]; 370 if (set_reg == 0) 371 return ret; 372 373 while (GET_CODE (set_reg) == SUBREG) 374 set_reg = SUBREG_REG (set_reg); 375 376 mode = GET_MODE (set_reg); 377 dslots_number_nops = num_nops; 378 iq2000_load_reg = set_reg; 379 if (GET_MODE_SIZE (mode) 380 > (unsigned) (UNITS_PER_WORD)) 381 iq2000_load_reg2 = gen_rtx_REG (SImode, REGNO (set_reg) + 1); 382 else 383 iq2000_load_reg2 = 0; 384 385 return ret; 386} 387 388/* Determine whether a memory reference takes one (based off of the GP 389 pointer), two (normal), or three (label + reg) instructions, and bump the 390 appropriate counter for -mstats. */ 391 392static void 393iq2000_count_memory_refs (rtx op, int num) 394{ 395 int additional = 0; 396 int n_words = 0; 397 rtx addr, plus0, plus1; 398 enum rtx_code code0, code1; 399 int looping; 400 401 if (TARGET_DEBUG_B_MODE) 402 { 403 fprintf (stderr, "\n========== iq2000_count_memory_refs:\n"); 404 debug_rtx (op); 405 } 406 407 /* Skip MEM if passed, otherwise handle movsi of address. */ 408 addr = (GET_CODE (op) != MEM) ? op : XEXP (op, 0); 409 410 /* Loop, going through the address RTL. */ 411 do 412 { 413 looping = FALSE; 414 switch (GET_CODE (addr)) 415 { 416 case REG: 417 case CONST_INT: 418 case LO_SUM: 419 break; 420 421 case PLUS: 422 plus0 = XEXP (addr, 0); 423 plus1 = XEXP (addr, 1); 424 code0 = GET_CODE (plus0); 425 code1 = GET_CODE (plus1); 426 427 if (code0 == REG) 428 { 429 additional++; 430 addr = plus1; 431 looping = 1; 432 continue; 433 } 434 435 if (code0 == CONST_INT) 436 { 437 addr = plus1; 438 looping = 1; 439 continue; 440 } 441 442 if (code1 == REG) 443 { 444 additional++; 445 addr = plus0; 446 looping = 1; 447 continue; 448 } 449 450 if (code1 == CONST_INT) 451 { 452 addr = plus0; 453 looping = 1; 454 continue; 455 } 456 457 if (code0 == SYMBOL_REF || code0 == LABEL_REF || code0 == CONST) 458 { 459 addr = plus0; 460 looping = 1; 461 continue; 462 } 463 464 if (code1 == SYMBOL_REF || code1 == LABEL_REF || code1 == CONST) 465 { 466 addr = plus1; 467 looping = 1; 468 continue; 469 } 470 471 break; 472 473 case LABEL_REF: 474 n_words = 2; /* Always 2 words. */ 475 break; 476 477 case CONST: 478 addr = XEXP (addr, 0); 479 looping = 1; 480 continue; 481 482 case SYMBOL_REF: 483 n_words = SYMBOL_REF_FLAG (addr) ? 1 : 2; 484 break; 485 486 default: 487 break; 488 } 489 } 490 while (looping); 491 492 if (n_words == 0) 493 return; 494 495 n_words += additional; 496 if (n_words > 3) 497 n_words = 3; 498 499 num_refs[n_words-1] += num; 500} 501 502/* Abort after printing out a specific insn. */ 503 504static void 505abort_with_insn (rtx insn, const char * reason) 506{ 507 error (reason); 508 debug_rtx (insn); 509 fancy_abort (__FILE__, __LINE__, __FUNCTION__); 510} 511 512/* Return the appropriate instructions to move one operand to another. */ 513 514const char * 515iq2000_move_1word (rtx operands[], rtx insn, int unsignedp) 516{ 517 const char *ret = 0; 518 rtx op0 = operands[0]; 519 rtx op1 = operands[1]; 520 enum rtx_code code0 = GET_CODE (op0); 521 enum rtx_code code1 = GET_CODE (op1); 522 enum machine_mode mode = GET_MODE (op0); 523 int subreg_offset0 = 0; 524 int subreg_offset1 = 0; 525 enum delay_type delay = DELAY_NONE; 526 527 while (code0 == SUBREG) 528 { 529 subreg_offset0 += subreg_regno_offset (REGNO (SUBREG_REG (op0)), 530 GET_MODE (SUBREG_REG (op0)), 531 SUBREG_BYTE (op0), 532 GET_MODE (op0)); 533 op0 = SUBREG_REG (op0); 534 code0 = GET_CODE (op0); 535 } 536 537 while (code1 == SUBREG) 538 { 539 subreg_offset1 += subreg_regno_offset (REGNO (SUBREG_REG (op1)), 540 GET_MODE (SUBREG_REG (op1)), 541 SUBREG_BYTE (op1), 542 GET_MODE (op1)); 543 op1 = SUBREG_REG (op1); 544 code1 = GET_CODE (op1); 545 } 546 547 /* For our purposes, a condition code mode is the same as SImode. */ 548 if (mode == CCmode) 549 mode = SImode; 550 551 if (code0 == REG) 552 { 553 int regno0 = REGNO (op0) + subreg_offset0; 554 555 if (code1 == REG) 556 { 557 int regno1 = REGNO (op1) + subreg_offset1; 558 559 /* Do not do anything for assigning a register to itself */ 560 if (regno0 == regno1) 561 ret = ""; 562 563 else if (GP_REG_P (regno0)) 564 { 565 if (GP_REG_P (regno1)) 566 ret = "or\t%0,%%0,%1"; 567 } 568 569 } 570 571 else if (code1 == MEM) 572 { 573 delay = DELAY_LOAD; 574 575 if (TARGET_STATS) 576 iq2000_count_memory_refs (op1, 1); 577 578 if (GP_REG_P (regno0)) 579 { 580 /* For loads, use the mode of the memory item, instead of the 581 target, so zero/sign extend can use this code as well. */ 582 switch (GET_MODE (op1)) 583 { 584 default: 585 break; 586 case SFmode: 587 ret = "lw\t%0,%1"; 588 break; 589 case SImode: 590 case CCmode: 591 ret = "lw\t%0,%1"; 592 break; 593 case HImode: 594 ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1"; 595 break; 596 case QImode: 597 ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1"; 598 break; 599 } 600 } 601 } 602 603 else if (code1 == CONST_INT 604 || (code1 == CONST_DOUBLE 605 && GET_MODE (op1) == VOIDmode)) 606 { 607 if (code1 == CONST_DOUBLE) 608 { 609 /* This can happen when storing constants into long long 610 bitfields. Just store the least significant word of 611 the value. */ 612 operands[1] = op1 = GEN_INT (CONST_DOUBLE_LOW (op1)); 613 } 614 615 if (INTVAL (op1) == 0) 616 { 617 if (GP_REG_P (regno0)) 618 ret = "or\t%0,%%0,%z1"; 619 } 620 else if (GP_REG_P (regno0)) 621 { 622 if (SMALL_INT_UNSIGNED (op1)) 623 ret = "ori\t%0,%%0,%x1\t\t\t# %1"; 624 else if (SMALL_INT (op1)) 625 ret = "addiu\t%0,%%0,%1\t\t\t# %1"; 626 else 627 ret = "lui\t%0,%X1\t\t\t# %1\n\tori\t%0,%0,%x1"; 628 } 629 } 630 631 else if (code1 == CONST_DOUBLE && mode == SFmode) 632 { 633 if (op1 == CONST0_RTX (SFmode)) 634 { 635 if (GP_REG_P (regno0)) 636 ret = "or\t%0,%%0,%."; 637 } 638 639 else 640 { 641 delay = DELAY_LOAD; 642 ret = "li.s\t%0,%1"; 643 } 644 } 645 646 else if (code1 == LABEL_REF) 647 { 648 if (TARGET_STATS) 649 iq2000_count_memory_refs (op1, 1); 650 651 ret = "la\t%0,%a1"; 652 } 653 654 else if (code1 == SYMBOL_REF || code1 == CONST) 655 { 656 if (TARGET_STATS) 657 iq2000_count_memory_refs (op1, 1); 658 659 ret = "la\t%0,%a1"; 660 } 661 662 else if (code1 == PLUS) 663 { 664 rtx add_op0 = XEXP (op1, 0); 665 rtx add_op1 = XEXP (op1, 1); 666 667 if (GET_CODE (XEXP (op1, 1)) == REG 668 && GET_CODE (XEXP (op1, 0)) == CONST_INT) 669 add_op0 = XEXP (op1, 1), add_op1 = XEXP (op1, 0); 670 671 operands[2] = add_op0; 672 operands[3] = add_op1; 673 ret = "add%:\t%0,%2,%3"; 674 } 675 676 else if (code1 == HIGH) 677 { 678 operands[1] = XEXP (op1, 0); 679 ret = "lui\t%0,%%hi(%1)"; 680 } 681 } 682 683 else if (code0 == MEM) 684 { 685 if (TARGET_STATS) 686 iq2000_count_memory_refs (op0, 1); 687 688 if (code1 == REG) 689 { 690 int regno1 = REGNO (op1) + subreg_offset1; 691 692 if (GP_REG_P (regno1)) 693 { 694 switch (mode) 695 { 696 case SFmode: ret = "sw\t%1,%0"; break; 697 case SImode: ret = "sw\t%1,%0"; break; 698 case HImode: ret = "sh\t%1,%0"; break; 699 case QImode: ret = "sb\t%1,%0"; break; 700 default: break; 701 } 702 } 703 } 704 705 else if (code1 == CONST_INT && INTVAL (op1) == 0) 706 { 707 switch (mode) 708 { 709 case SFmode: ret = "sw\t%z1,%0"; break; 710 case SImode: ret = "sw\t%z1,%0"; break; 711 case HImode: ret = "sh\t%z1,%0"; break; 712 case QImode: ret = "sb\t%z1,%0"; break; 713 default: break; 714 } 715 } 716 717 else if (code1 == CONST_DOUBLE && op1 == CONST0_RTX (mode)) 718 { 719 switch (mode) 720 { 721 case SFmode: ret = "sw\t%.,%0"; break; 722 case SImode: ret = "sw\t%.,%0"; break; 723 case HImode: ret = "sh\t%.,%0"; break; 724 case QImode: ret = "sb\t%.,%0"; break; 725 default: break; 726 } 727 } 728 } 729 730 if (ret == 0) 731 { 732 abort_with_insn (insn, "Bad move"); 733 return 0; 734 } 735 736 if (delay != DELAY_NONE) 737 return iq2000_fill_delay_slot (ret, delay, operands, insn); 738 739 return ret; 740} 741 742/* Provide the costs of an addressing mode that contains ADDR. */ 743 744static int 745iq2000_address_cost (rtx addr) 746{ 747 switch (GET_CODE (addr)) 748 { 749 case LO_SUM: 750 return 1; 751 752 case LABEL_REF: 753 return 2; 754 755 case CONST: 756 { 757 rtx offset = const0_rtx; 758 759 addr = eliminate_constant_term (XEXP (addr, 0), & offset); 760 if (GET_CODE (addr) == LABEL_REF) 761 return 2; 762 763 if (GET_CODE (addr) != SYMBOL_REF) 764 return 4; 765 766 if (! SMALL_INT (offset)) 767 return 2; 768 } 769 770 /* Fall through. */ 771 772 case SYMBOL_REF: 773 return SYMBOL_REF_FLAG (addr) ? 1 : 2; 774 775 case PLUS: 776 { 777 rtx plus0 = XEXP (addr, 0); 778 rtx plus1 = XEXP (addr, 1); 779 780 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG) 781 plus0 = XEXP (addr, 1), plus1 = XEXP (addr, 0); 782 783 if (GET_CODE (plus0) != REG) 784 break; 785 786 switch (GET_CODE (plus1)) 787 { 788 case CONST_INT: 789 return SMALL_INT (plus1) ? 1 : 2; 790 791 case CONST: 792 case SYMBOL_REF: 793 case LABEL_REF: 794 case HIGH: 795 case LO_SUM: 796 return iq2000_address_cost (plus1) + 1; 797 798 default: 799 break; 800 } 801 } 802 803 default: 804 break; 805 } 806 807 return 4; 808} 809 810/* Make normal rtx_code into something we can index from an array. */ 811 812static enum internal_test 813map_test_to_internal_test (enum rtx_code test_code) 814{ 815 enum internal_test test = ITEST_MAX; 816 817 switch (test_code) 818 { 819 case EQ: test = ITEST_EQ; break; 820 case NE: test = ITEST_NE; break; 821 case GT: test = ITEST_GT; break; 822 case GE: test = ITEST_GE; break; 823 case LT: test = ITEST_LT; break; 824 case LE: test = ITEST_LE; break; 825 case GTU: test = ITEST_GTU; break; 826 case GEU: test = ITEST_GEU; break; 827 case LTU: test = ITEST_LTU; break; 828 case LEU: test = ITEST_LEU; break; 829 default: break; 830 } 831 832 return test; 833} 834 835/* Generate the code to do a TEST_CODE comparison on two integer values CMP0 836 and CMP1. P_INVERT is NULL or ptr if branch needs to reverse its test. 837 The return value RESULT is: 838 (reg:SI xx) The pseudo register the comparison is in 839 0 No register, generate a simple branch. */ 840 841rtx 842gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1, 843 int *p_invert) 844{ 845 struct cmp_info 846 { 847 enum rtx_code test_code; /* Code to use in instruction (LT vs. LTU). */ 848 int const_low; /* Low bound of constant we can accept. */ 849 int const_high; /* High bound of constant we can accept. */ 850 int const_add; /* Constant to add (convert LE -> LT). */ 851 int reverse_regs; /* Reverse registers in test. */ 852 int invert_const; /* != 0 if invert value if cmp1 is constant. */ 853 int invert_reg; /* != 0 if invert value if cmp1 is register. */ 854 int unsignedp; /* != 0 for unsigned comparisons. */ 855 }; 856 857 static struct cmp_info info[ (int)ITEST_MAX ] = 858 { 859 { XOR, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */ 860 { XOR, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */ 861 { LT, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */ 862 { LT, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */ 863 { LT, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */ 864 { LT, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */ 865 { LTU, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */ 866 { LTU, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */ 867 { LTU, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */ 868 { LTU, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */ 869 }; 870 871 enum internal_test test; 872 enum machine_mode mode; 873 struct cmp_info *p_info; 874 int branch_p; 875 int eqne_p; 876 int invert; 877 rtx reg; 878 rtx reg2; 879 880 test = map_test_to_internal_test (test_code); 881 gcc_assert (test != ITEST_MAX); 882 883 p_info = &info[(int) test]; 884 eqne_p = (p_info->test_code == XOR); 885 886 mode = GET_MODE (cmp0); 887 if (mode == VOIDmode) 888 mode = GET_MODE (cmp1); 889 890 /* Eliminate simple branches. */ 891 branch_p = (result == 0); 892 if (branch_p) 893 { 894 if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG) 895 { 896 /* Comparisons against zero are simple branches. */ 897 if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0) 898 return 0; 899 900 /* Test for beq/bne. */ 901 if (eqne_p) 902 return 0; 903 } 904 905 /* Allocate a pseudo to calculate the value in. */ 906 result = gen_reg_rtx (mode); 907 } 908 909 /* Make sure we can handle any constants given to us. */ 910 if (GET_CODE (cmp0) == CONST_INT) 911 cmp0 = force_reg (mode, cmp0); 912 913 if (GET_CODE (cmp1) == CONST_INT) 914 { 915 HOST_WIDE_INT value = INTVAL (cmp1); 916 917 if (value < p_info->const_low 918 || value > p_info->const_high) 919 cmp1 = force_reg (mode, cmp1); 920 } 921 922 /* See if we need to invert the result. */ 923 invert = (GET_CODE (cmp1) == CONST_INT 924 ? p_info->invert_const : p_info->invert_reg); 925 926 if (p_invert != (int *)0) 927 { 928 *p_invert = invert; 929 invert = 0; 930 } 931 932 /* Comparison to constants, may involve adding 1 to change a LT into LE. 933 Comparison between two registers, may involve switching operands. */ 934 if (GET_CODE (cmp1) == CONST_INT) 935 { 936 if (p_info->const_add != 0) 937 { 938 HOST_WIDE_INT new = INTVAL (cmp1) + p_info->const_add; 939 940 /* If modification of cmp1 caused overflow, 941 we would get the wrong answer if we follow the usual path; 942 thus, x > 0xffffffffU would turn into x > 0U. */ 943 if ((p_info->unsignedp 944 ? (unsigned HOST_WIDE_INT) new > 945 (unsigned HOST_WIDE_INT) INTVAL (cmp1) 946 : new > INTVAL (cmp1)) 947 != (p_info->const_add > 0)) 948 { 949 /* This test is always true, but if INVERT is true then 950 the result of the test needs to be inverted so 0 should 951 be returned instead. */ 952 emit_move_insn (result, invert ? const0_rtx : const_true_rtx); 953 return result; 954 } 955 else 956 cmp1 = GEN_INT (new); 957 } 958 } 959 960 else if (p_info->reverse_regs) 961 { 962 rtx temp = cmp0; 963 cmp0 = cmp1; 964 cmp1 = temp; 965 } 966 967 if (test == ITEST_NE && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0) 968 reg = cmp0; 969 else 970 { 971 reg = (invert || eqne_p) ? gen_reg_rtx (mode) : result; 972 convert_move (reg, gen_rtx_fmt_ee (p_info->test_code, mode, cmp0, cmp1), 0); 973 } 974 975 if (test == ITEST_NE) 976 { 977 convert_move (result, gen_rtx_GTU (mode, reg, const0_rtx), 0); 978 if (p_invert != NULL) 979 *p_invert = 0; 980 invert = 0; 981 } 982 983 else if (test == ITEST_EQ) 984 { 985 reg2 = invert ? gen_reg_rtx (mode) : result; 986 convert_move (reg2, gen_rtx_LTU (mode, reg, const1_rtx), 0); 987 reg = reg2; 988 } 989 990 if (invert) 991 { 992 rtx one; 993 994 one = const1_rtx; 995 convert_move (result, gen_rtx_XOR (mode, reg, one), 0); 996 } 997 998 return result; 999} 1000 1001/* Emit the common code for doing conditional branches. 1002 operand[0] is the label to jump to. 1003 The comparison operands are saved away by cmp{si,di,sf,df}. */ 1004 1005void 1006gen_conditional_branch (rtx operands[], enum rtx_code test_code) 1007{ 1008 enum cmp_type type = branch_type; 1009 rtx cmp0 = branch_cmp[0]; 1010 rtx cmp1 = branch_cmp[1]; 1011 enum machine_mode mode; 1012 rtx reg; 1013 int invert; 1014 rtx label1, label2; 1015 1016 switch (type) 1017 { 1018 case CMP_SI: 1019 case CMP_DI: 1020 mode = type == CMP_SI ? SImode : DImode; 1021 invert = 0; 1022 reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert); 1023 1024 if (reg) 1025 { 1026 cmp0 = reg; 1027 cmp1 = const0_rtx; 1028 test_code = NE; 1029 } 1030 else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0) 1031 /* We don't want to build a comparison against a nonzero 1032 constant. */ 1033 cmp1 = force_reg (mode, cmp1); 1034 1035 break; 1036 1037 case CMP_SF: 1038 case CMP_DF: 1039 reg = gen_reg_rtx (CCmode); 1040 1041 /* For cmp0 != cmp1, build cmp0 == cmp1, and test for result == 0. */ 1042 emit_insn (gen_rtx_SET (VOIDmode, reg, 1043 gen_rtx_fmt_ee (test_code == NE ? EQ : test_code, 1044 CCmode, cmp0, cmp1))); 1045 1046 test_code = test_code == NE ? EQ : NE; 1047 mode = CCmode; 1048 cmp0 = reg; 1049 cmp1 = const0_rtx; 1050 invert = 0; 1051 break; 1052 1053 default: 1054 abort_with_insn (gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1), 1055 "bad test"); 1056 } 1057 1058 /* Generate the branch. */ 1059 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[0]); 1060 label2 = pc_rtx; 1061 1062 if (invert) 1063 { 1064 label2 = label1; 1065 label1 = pc_rtx; 1066 } 1067 1068 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, 1069 gen_rtx_IF_THEN_ELSE (VOIDmode, 1070 gen_rtx_fmt_ee (test_code, 1071 mode, 1072 cmp0, cmp1), 1073 label1, label2))); 1074} 1075 1076/* Initialize CUM for a function FNTYPE. */ 1077 1078void 1079init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, 1080 rtx libname ATTRIBUTE_UNUSED) 1081{ 1082 static CUMULATIVE_ARGS zero_cum; 1083 tree param; 1084 tree next_param; 1085 1086 if (TARGET_DEBUG_D_MODE) 1087 { 1088 fprintf (stderr, 1089 "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype); 1090 1091 if (!fntype) 1092 fputc ('\n', stderr); 1093 1094 else 1095 { 1096 tree ret_type = TREE_TYPE (fntype); 1097 1098 fprintf (stderr, ", fntype code = %s, ret code = %s\n", 1099 tree_code_name[(int)TREE_CODE (fntype)], 1100 tree_code_name[(int)TREE_CODE (ret_type)]); 1101 } 1102 } 1103 1104 *cum = zero_cum; 1105 1106 /* Determine if this function has variable arguments. This is 1107 indicated by the last argument being 'void_type_mode' if there 1108 are no variable arguments. The standard IQ2000 calling sequence 1109 passes all arguments in the general purpose registers in this case. */ 1110 1111 for (param = fntype ? TYPE_ARG_TYPES (fntype) : 0; 1112 param != 0; param = next_param) 1113 { 1114 next_param = TREE_CHAIN (param); 1115 if (next_param == 0 && TREE_VALUE (param) != void_type_node) 1116 cum->gp_reg_found = 1; 1117 } 1118} 1119 1120/* Advance the argument of type TYPE and mode MODE to the next argument 1121 position in CUM. */ 1122 1123void 1124function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type, 1125 int named) 1126{ 1127 if (TARGET_DEBUG_D_MODE) 1128 { 1129 fprintf (stderr, 1130 "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ", 1131 cum->gp_reg_found, cum->arg_number, cum->arg_words, 1132 GET_MODE_NAME (mode)); 1133 fprintf (stderr, "%p", (void *) type); 1134 fprintf (stderr, ", %d )\n\n", named); 1135 } 1136 1137 cum->arg_number++; 1138 switch (mode) 1139 { 1140 case VOIDmode: 1141 break; 1142 1143 default: 1144 gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT 1145 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT); 1146 1147 cum->gp_reg_found = 1; 1148 cum->arg_words += ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) 1149 / UNITS_PER_WORD); 1150 break; 1151 1152 case BLKmode: 1153 cum->gp_reg_found = 1; 1154 cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1) 1155 / UNITS_PER_WORD); 1156 break; 1157 1158 case SFmode: 1159 cum->arg_words ++; 1160 if (! cum->gp_reg_found && cum->arg_number <= 2) 1161 cum->fp_code += 1 << ((cum->arg_number - 1) * 2); 1162 break; 1163 1164 case DFmode: 1165 cum->arg_words += 2; 1166 if (! cum->gp_reg_found && cum->arg_number <= 2) 1167 cum->fp_code += 2 << ((cum->arg_number - 1) * 2); 1168 break; 1169 1170 case DImode: 1171 cum->gp_reg_found = 1; 1172 cum->arg_words += 2; 1173 break; 1174 1175 case QImode: 1176 case HImode: 1177 case SImode: 1178 cum->gp_reg_found = 1; 1179 cum->arg_words ++; 1180 break; 1181 } 1182} 1183 1184/* Return an RTL expression containing the register for the given mode MODE 1185 and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */ 1186 1187struct rtx_def * 1188function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type, 1189 int named) 1190{ 1191 rtx ret; 1192 int regbase = -1; 1193 int bias = 0; 1194 unsigned int *arg_words = &cum->arg_words; 1195 int struct_p = (type != 0 1196 && (TREE_CODE (type) == RECORD_TYPE 1197 || TREE_CODE (type) == UNION_TYPE 1198 || TREE_CODE (type) == QUAL_UNION_TYPE)); 1199 1200 if (TARGET_DEBUG_D_MODE) 1201 { 1202 fprintf (stderr, 1203 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, ", 1204 cum->gp_reg_found, cum->arg_number, cum->arg_words, 1205 GET_MODE_NAME (mode)); 1206 fprintf (stderr, "%p", (void *) type); 1207 fprintf (stderr, ", %d ) = ", named); 1208 } 1209 1210 1211 cum->last_arg_fp = 0; 1212 switch (mode) 1213 { 1214 case SFmode: 1215 regbase = GP_ARG_FIRST; 1216 break; 1217 1218 case DFmode: 1219 cum->arg_words += cum->arg_words & 1; 1220 1221 regbase = GP_ARG_FIRST; 1222 break; 1223 1224 default: 1225 gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT 1226 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT); 1227 1228 /* Drops through. */ 1229 case BLKmode: 1230 if (type != NULL_TREE && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD) 1231 cum->arg_words += (cum->arg_words & 1); 1232 regbase = GP_ARG_FIRST; 1233 break; 1234 1235 case VOIDmode: 1236 case QImode: 1237 case HImode: 1238 case SImode: 1239 regbase = GP_ARG_FIRST; 1240 break; 1241 1242 case DImode: 1243 cum->arg_words += (cum->arg_words & 1); 1244 regbase = GP_ARG_FIRST; 1245 } 1246 1247 if (*arg_words >= (unsigned) MAX_ARGS_IN_REGISTERS) 1248 { 1249 if (TARGET_DEBUG_D_MODE) 1250 fprintf (stderr, "<stack>%s\n", struct_p ? ", [struct]" : ""); 1251 1252 ret = 0; 1253 } 1254 else 1255 { 1256 gcc_assert (regbase != -1); 1257 1258 if (! type || TREE_CODE (type) != RECORD_TYPE 1259 || ! named || ! TYPE_SIZE_UNIT (type) 1260 || ! host_integerp (TYPE_SIZE_UNIT (type), 1)) 1261 ret = gen_rtx_REG (mode, regbase + *arg_words + bias); 1262 else 1263 { 1264 tree field; 1265 1266 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) 1267 if (TREE_CODE (field) == FIELD_DECL 1268 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE 1269 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD 1270 && host_integerp (bit_position (field), 0) 1271 && int_bit_position (field) % BITS_PER_WORD == 0) 1272 break; 1273 1274 /* If the whole struct fits a DFmode register, 1275 we don't need the PARALLEL. */ 1276 if (! field || mode == DFmode) 1277 ret = gen_rtx_REG (mode, regbase + *arg_words + bias); 1278 else 1279 { 1280 unsigned int chunks; 1281 HOST_WIDE_INT bitpos; 1282 unsigned int regno; 1283 unsigned int i; 1284 1285 /* ??? If this is a packed structure, then the last hunk won't 1286 be 64 bits. */ 1287 chunks 1288 = tree_low_cst (TYPE_SIZE_UNIT (type), 1) / UNITS_PER_WORD; 1289 if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS) 1290 chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias; 1291 1292 /* Assign_parms checks the mode of ENTRY_PARM, so we must 1293 use the actual mode here. */ 1294 ret = gen_rtx_PARALLEL (mode, rtvec_alloc (chunks)); 1295 1296 bitpos = 0; 1297 regno = regbase + *arg_words + bias; 1298 field = TYPE_FIELDS (type); 1299 for (i = 0; i < chunks; i++) 1300 { 1301 rtx reg; 1302 1303 for (; field; field = TREE_CHAIN (field)) 1304 if (TREE_CODE (field) == FIELD_DECL 1305 && int_bit_position (field) >= bitpos) 1306 break; 1307 1308 if (field 1309 && int_bit_position (field) == bitpos 1310 && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE 1311 && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD) 1312 reg = gen_rtx_REG (DFmode, regno++); 1313 else 1314 reg = gen_rtx_REG (word_mode, regno); 1315 1316 XVECEXP (ret, 0, i) 1317 = gen_rtx_EXPR_LIST (VOIDmode, reg, 1318 GEN_INT (bitpos / BITS_PER_UNIT)); 1319 1320 bitpos += 64; 1321 regno++; 1322 } 1323 } 1324 } 1325 1326 if (TARGET_DEBUG_D_MODE) 1327 fprintf (stderr, "%s%s\n", reg_names[regbase + *arg_words + bias], 1328 struct_p ? ", [struct]" : ""); 1329 } 1330 1331 /* We will be called with a mode of VOIDmode after the last argument 1332 has been seen. Whatever we return will be passed to the call 1333 insn. If we need any shifts for small structures, return them in 1334 a PARALLEL. */ 1335 if (mode == VOIDmode) 1336 { 1337 if (cum->num_adjusts > 0) 1338 ret = gen_rtx_PARALLEL ((enum machine_mode) cum->fp_code, 1339 gen_rtvec_v (cum->num_adjusts, cum->adjust)); 1340 } 1341 1342 return ret; 1343} 1344 1345static int 1346iq2000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, 1347 tree type ATTRIBUTE_UNUSED, 1348 bool named ATTRIBUTE_UNUSED) 1349{ 1350 if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS - 1) 1351 { 1352 if (TARGET_DEBUG_D_MODE) 1353 fprintf (stderr, "iq2000_arg_partial_bytes=%d\n", UNITS_PER_WORD); 1354 return UNITS_PER_WORD; 1355 } 1356 1357 return 0; 1358} 1359 1360/* Implement va_start. */ 1361 1362void 1363iq2000_va_start (tree valist, rtx nextarg) 1364{ 1365 int int_arg_words; 1366 /* Find out how many non-float named formals. */ 1367 int gpr_save_area_size; 1368 /* Note UNITS_PER_WORD is 4 bytes. */ 1369 int_arg_words = current_function_args_info.arg_words; 1370 1371 if (int_arg_words < 8 ) 1372 /* Adjust for the prologue's economy measure. */ 1373 gpr_save_area_size = (8 - int_arg_words) * UNITS_PER_WORD; 1374 else 1375 gpr_save_area_size = 0; 1376 1377 /* Everything is in the GPR save area, or in the overflow 1378 area which is contiguous with it. */ 1379 nextarg = plus_constant (nextarg, - gpr_save_area_size); 1380 std_expand_builtin_va_start (valist, nextarg); 1381} 1382 1383/* Allocate a chunk of memory for per-function machine-dependent data. */ 1384 1385static struct machine_function * 1386iq2000_init_machine_status (void) 1387{ 1388 struct machine_function *f; 1389 1390 f = ggc_alloc_cleared (sizeof (struct machine_function)); 1391 1392 return f; 1393} 1394 1395/* Implement TARGET_HANDLE_OPTION. */ 1396 1397static bool 1398iq2000_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED) 1399{ 1400 switch (code) 1401 { 1402 case OPT_mcpu_: 1403 if (strcmp (arg, "iq10") == 0) 1404 iq2000_tune = PROCESSOR_IQ10; 1405 else if (strcmp (arg, "iq2000") == 0) 1406 iq2000_tune = PROCESSOR_IQ2000; 1407 else 1408 return false; 1409 return true; 1410 1411 case OPT_march_: 1412 /* This option has no effect at the moment. */ 1413 return (strcmp (arg, "default") == 0 1414 || strcmp (arg, "DEFAULT") == 0 1415 || strcmp (arg, "iq2000") == 0); 1416 1417 default: 1418 return true; 1419 } 1420} 1421 1422/* Detect any conflicts in the switches. */ 1423 1424void 1425override_options (void) 1426{ 1427 target_flags &= ~MASK_GPOPT; 1428 1429 iq2000_isa = IQ2000_ISA_DEFAULT; 1430 1431 /* Identify the processor type. */ 1432 1433 iq2000_print_operand_punct['?'] = 1; 1434 iq2000_print_operand_punct['#'] = 1; 1435 iq2000_print_operand_punct['&'] = 1; 1436 iq2000_print_operand_punct['!'] = 1; 1437 iq2000_print_operand_punct['*'] = 1; 1438 iq2000_print_operand_punct['@'] = 1; 1439 iq2000_print_operand_punct['.'] = 1; 1440 iq2000_print_operand_punct['('] = 1; 1441 iq2000_print_operand_punct[')'] = 1; 1442 iq2000_print_operand_punct['['] = 1; 1443 iq2000_print_operand_punct[']'] = 1; 1444 iq2000_print_operand_punct['<'] = 1; 1445 iq2000_print_operand_punct['>'] = 1; 1446 iq2000_print_operand_punct['{'] = 1; 1447 iq2000_print_operand_punct['}'] = 1; 1448 iq2000_print_operand_punct['^'] = 1; 1449 iq2000_print_operand_punct['$'] = 1; 1450 iq2000_print_operand_punct['+'] = 1; 1451 iq2000_print_operand_punct['~'] = 1; 1452 1453 /* Save GPR registers in word_mode sized hunks. word_mode hasn't been 1454 initialized yet, so we can't use that here. */ 1455 gpr_mode = SImode; 1456 1457 /* Function to allocate machine-dependent function status. */ 1458 init_machine_status = iq2000_init_machine_status; 1459} 1460 1461/* The arg pointer (which is eliminated) points to the virtual frame pointer, 1462 while the frame pointer (which may be eliminated) points to the stack 1463 pointer after the initial adjustments. */ 1464 1465HOST_WIDE_INT 1466iq2000_debugger_offset (rtx addr, HOST_WIDE_INT offset) 1467{ 1468 rtx offset2 = const0_rtx; 1469 rtx reg = eliminate_constant_term (addr, & offset2); 1470 1471 if (offset == 0) 1472 offset = INTVAL (offset2); 1473 1474 if (reg == stack_pointer_rtx || reg == frame_pointer_rtx 1475 || reg == hard_frame_pointer_rtx) 1476 { 1477 HOST_WIDE_INT frame_size = (!cfun->machine->initialized) 1478 ? compute_frame_size (get_frame_size ()) 1479 : cfun->machine->total_size; 1480 1481 offset = offset - frame_size; 1482 } 1483 1484 return offset; 1485} 1486 1487/* If defined, a C statement to be executed just prior to the output of 1488 assembler code for INSN, to modify the extracted operands so they will be 1489 output differently. 1490 1491 Here the argument OPVEC is the vector containing the operands extracted 1492 from INSN, and NOPERANDS is the number of elements of the vector which 1493 contain meaningful data for this insn. The contents of this vector are 1494 what will be used to convert the insn template into assembler code, so you 1495 can change the assembler output by changing the contents of the vector. 1496 1497 We use it to check if the current insn needs a nop in front of it because 1498 of load delays, and also to update the delay slot statistics. */ 1499 1500void 1501final_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED, 1502 int noperands ATTRIBUTE_UNUSED) 1503{ 1504 if (dslots_number_nops > 0) 1505 { 1506 rtx pattern = PATTERN (insn); 1507 int length = get_attr_length (insn); 1508 1509 /* Do we need to emit a NOP? */ 1510 if (length == 0 1511 || (iq2000_load_reg != 0 && reg_mentioned_p (iq2000_load_reg, pattern)) 1512 || (iq2000_load_reg2 != 0 && reg_mentioned_p (iq2000_load_reg2, pattern)) 1513 || (iq2000_load_reg3 != 0 && reg_mentioned_p (iq2000_load_reg3, pattern)) 1514 || (iq2000_load_reg4 != 0 1515 && reg_mentioned_p (iq2000_load_reg4, pattern))) 1516 fputs ("\tnop\n", asm_out_file); 1517 1518 else 1519 dslots_load_filled ++; 1520 1521 while (--dslots_number_nops > 0) 1522 fputs ("\tnop\n", asm_out_file); 1523 1524 iq2000_load_reg = 0; 1525 iq2000_load_reg2 = 0; 1526 iq2000_load_reg3 = 0; 1527 iq2000_load_reg4 = 0; 1528 } 1529 1530 if ( (GET_CODE (insn) == JUMP_INSN 1531 || GET_CODE (insn) == CALL_INSN 1532 || (GET_CODE (PATTERN (insn)) == RETURN)) 1533 && NEXT_INSN (PREV_INSN (insn)) == insn) 1534 { 1535 rtx nop_insn = emit_insn_after (gen_nop (), insn); 1536 1537 INSN_ADDRESSES_NEW (nop_insn, -1); 1538 } 1539 1540 if (TARGET_STATS 1541 && (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN)) 1542 dslots_jump_total ++; 1543} 1544 1545/* Return the bytes needed to compute the frame pointer from the current 1546 stack pointer where SIZE is the # of var. bytes allocated. 1547 1548 IQ2000 stack frames look like: 1549 1550 Before call After call 1551 +-----------------------+ +-----------------------+ 1552 high | | | | 1553 mem. | | | | 1554 | caller's temps. | | caller's temps. | 1555 | | | | 1556 +-----------------------+ +-----------------------+ 1557 | | | | 1558 | arguments on stack. | | arguments on stack. | 1559 | | | | 1560 +-----------------------+ +-----------------------+ 1561 | 4 words to save | | 4 words to save | 1562 | arguments passed | | arguments passed | 1563 | in registers, even | | in registers, even | 1564 SP->| if not passed. | VFP->| if not passed. | 1565 +-----------------------+ +-----------------------+ 1566 | | 1567 | fp register save | 1568 | | 1569 +-----------------------+ 1570 | | 1571 | gp register save | 1572 | | 1573 +-----------------------+ 1574 | | 1575 | local variables | 1576 | | 1577 +-----------------------+ 1578 | | 1579 | alloca allocations | 1580 | | 1581 +-----------------------+ 1582 | | 1583 | GP save for V.4 abi | 1584 | | 1585 +-----------------------+ 1586 | | 1587 | arguments on stack | 1588 | | 1589 +-----------------------+ 1590 | 4 words to save | 1591 | arguments passed | 1592 | in registers, even | 1593 low SP->| if not passed. | 1594 memory +-----------------------+ */ 1595 1596HOST_WIDE_INT 1597compute_frame_size (HOST_WIDE_INT size) 1598{ 1599 int regno; 1600 HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up. */ 1601 HOST_WIDE_INT var_size; /* # bytes that variables take up. */ 1602 HOST_WIDE_INT args_size; /* # bytes that outgoing arguments take up. */ 1603 HOST_WIDE_INT extra_size; /* # extra bytes. */ 1604 HOST_WIDE_INT gp_reg_rounded; /* # bytes needed to store gp after rounding. */ 1605 HOST_WIDE_INT gp_reg_size; /* # bytes needed to store gp regs. */ 1606 HOST_WIDE_INT fp_reg_size; /* # bytes needed to store fp regs. */ 1607 long mask; /* mask of saved gp registers. */ 1608 int fp_inc; /* 1 or 2 depending on the size of fp regs. */ 1609 long fp_bits; /* bitmask to use for each fp register. */ 1610 1611 gp_reg_size = 0; 1612 fp_reg_size = 0; 1613 mask = 0; 1614 extra_size = IQ2000_STACK_ALIGN ((0)); 1615 var_size = IQ2000_STACK_ALIGN (size); 1616 args_size = IQ2000_STACK_ALIGN (current_function_outgoing_args_size); 1617 1618 /* If a function dynamically allocates the stack and 1619 has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */ 1620 if (args_size == 0 && current_function_calls_alloca) 1621 args_size = 4 * UNITS_PER_WORD; 1622 1623 total_size = var_size + args_size + extra_size; 1624 1625 /* Calculate space needed for gp registers. */ 1626 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++) 1627 { 1628 if (MUST_SAVE_REGISTER (regno)) 1629 { 1630 gp_reg_size += GET_MODE_SIZE (gpr_mode); 1631 mask |= 1L << (regno - GP_REG_FIRST); 1632 } 1633 } 1634 1635 /* We need to restore these for the handler. */ 1636 if (current_function_calls_eh_return) 1637 { 1638 unsigned int i; 1639 1640 for (i = 0; ; ++i) 1641 { 1642 regno = EH_RETURN_DATA_REGNO (i); 1643 if (regno == (int) INVALID_REGNUM) 1644 break; 1645 gp_reg_size += GET_MODE_SIZE (gpr_mode); 1646 mask |= 1L << (regno - GP_REG_FIRST); 1647 } 1648 } 1649 1650 fp_inc = 2; 1651 fp_bits = 3; 1652 gp_reg_rounded = IQ2000_STACK_ALIGN (gp_reg_size); 1653 total_size += gp_reg_rounded + IQ2000_STACK_ALIGN (fp_reg_size); 1654 1655 /* The gp reg is caller saved, so there is no need for leaf routines 1656 (total_size == extra_size) to save the gp reg. */ 1657 if (total_size == extra_size 1658 && ! profile_flag) 1659 total_size = extra_size = 0; 1660 1661 total_size += IQ2000_STACK_ALIGN (current_function_pretend_args_size); 1662 1663 /* Save other computed information. */ 1664 cfun->machine->total_size = total_size; 1665 cfun->machine->var_size = var_size; 1666 cfun->machine->args_size = args_size; 1667 cfun->machine->extra_size = extra_size; 1668 cfun->machine->gp_reg_size = gp_reg_size; 1669 cfun->machine->fp_reg_size = fp_reg_size; 1670 cfun->machine->mask = mask; 1671 cfun->machine->initialized = reload_completed; 1672 cfun->machine->num_gp = gp_reg_size / UNITS_PER_WORD; 1673 1674 if (mask) 1675 { 1676 unsigned long offset; 1677 1678 offset = (args_size + extra_size + var_size 1679 + gp_reg_size - GET_MODE_SIZE (gpr_mode)); 1680 1681 cfun->machine->gp_sp_offset = offset; 1682 cfun->machine->gp_save_offset = offset - total_size; 1683 } 1684 else 1685 { 1686 cfun->machine->gp_sp_offset = 0; 1687 cfun->machine->gp_save_offset = 0; 1688 } 1689 1690 cfun->machine->fp_sp_offset = 0; 1691 cfun->machine->fp_save_offset = 0; 1692 1693 /* Ok, we're done. */ 1694 return total_size; 1695} 1696 1697/* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame 1698 pointer, argument pointer, or return address pointer. TO is either 1699 the stack pointer or hard frame pointer. */ 1700 1701int 1702iq2000_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED) 1703{ 1704 int offset; 1705 1706 compute_frame_size (get_frame_size ()); 1707 if ((from) == FRAME_POINTER_REGNUM) 1708 (offset) = 0; 1709 else if ((from) == ARG_POINTER_REGNUM) 1710 (offset) = (cfun->machine->total_size); 1711 else if ((from) == RETURN_ADDRESS_POINTER_REGNUM) 1712 { 1713 if (leaf_function_p ()) 1714 (offset) = 0; 1715 else (offset) = cfun->machine->gp_sp_offset 1716 + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT)) 1717 * (BYTES_BIG_ENDIAN != 0)); 1718 } 1719 1720 return offset; 1721} 1722 1723/* Common code to emit the insns (or to write the instructions to a file) 1724 to save/restore registers. 1725 Other parts of the code assume that IQ2000_TEMP1_REGNUM (aka large_reg) 1726 is not modified within save_restore_insns. */ 1727 1728#define BITSET_P(VALUE,BIT) (((VALUE) & (1L << (BIT))) != 0) 1729 1730/* Emit instructions to load the value (SP + OFFSET) into IQ2000_TEMP2_REGNUM 1731 and return an rtl expression for the register. Write the assembly 1732 instructions directly to FILE if it is not null, otherwise emit them as 1733 rtl. 1734 1735 This function is a subroutine of save_restore_insns. It is used when 1736 OFFSET is too large to add in a single instruction. */ 1737 1738static rtx 1739iq2000_add_large_offset_to_sp (HOST_WIDE_INT offset) 1740{ 1741 rtx reg = gen_rtx_REG (Pmode, IQ2000_TEMP2_REGNUM); 1742 rtx offset_rtx = GEN_INT (offset); 1743 1744 emit_move_insn (reg, offset_rtx); 1745 emit_insn (gen_addsi3 (reg, reg, stack_pointer_rtx)); 1746 return reg; 1747} 1748 1749/* Make INSN frame related and note that it performs the frame-related 1750 operation DWARF_PATTERN. */ 1751 1752static void 1753iq2000_annotate_frame_insn (rtx insn, rtx dwarf_pattern) 1754{ 1755 RTX_FRAME_RELATED_P (insn) = 1; 1756 REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR, 1757 dwarf_pattern, 1758 REG_NOTES (insn)); 1759} 1760 1761/* Emit a move instruction that stores REG in MEM. Make the instruction 1762 frame related and note that it stores REG at (SP + OFFSET). */ 1763 1764static void 1765iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset) 1766{ 1767 rtx dwarf_address = plus_constant (stack_pointer_rtx, offset); 1768 rtx dwarf_mem = gen_rtx_MEM (GET_MODE (reg), dwarf_address); 1769 1770 iq2000_annotate_frame_insn (emit_move_insn (mem, reg), 1771 gen_rtx_SET (GET_MODE (reg), dwarf_mem, reg)); 1772} 1773 1774/* Emit instructions to save/restore registers, as determined by STORE_P. */ 1775 1776static void 1777save_restore_insns (int store_p) 1778{ 1779 long mask = cfun->machine->mask; 1780 int regno; 1781 rtx base_reg_rtx; 1782 HOST_WIDE_INT base_offset; 1783 HOST_WIDE_INT gp_offset; 1784 HOST_WIDE_INT end_offset; 1785 1786 gcc_assert (!frame_pointer_needed 1787 || BITSET_P (mask, HARD_FRAME_POINTER_REGNUM - GP_REG_FIRST)); 1788 1789 if (mask == 0) 1790 { 1791 base_reg_rtx = 0, base_offset = 0; 1792 return; 1793 } 1794 1795 /* Save registers starting from high to low. The debuggers prefer at least 1796 the return register be stored at func+4, and also it allows us not to 1797 need a nop in the epilog if at least one register is reloaded in 1798 addition to return address. */ 1799 1800 /* Save GP registers if needed. */ 1801 /* Pick which pointer to use as a base register. For small frames, just 1802 use the stack pointer. Otherwise, use a temporary register. Save 2 1803 cycles if the save area is near the end of a large frame, by reusing 1804 the constant created in the prologue/epilogue to adjust the stack 1805 frame. */ 1806 1807 gp_offset = cfun->machine->gp_sp_offset; 1808 end_offset 1809 = gp_offset - (cfun->machine->gp_reg_size 1810 - GET_MODE_SIZE (gpr_mode)); 1811 1812 if (gp_offset < 0 || end_offset < 0) 1813 internal_error 1814 ("gp_offset (%ld) or end_offset (%ld) is less than zero", 1815 (long) gp_offset, (long) end_offset); 1816 1817 else if (gp_offset < 32768) 1818 base_reg_rtx = stack_pointer_rtx, base_offset = 0; 1819 else 1820 { 1821 int regno; 1822 int reg_save_count = 0; 1823 1824 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--) 1825 if (BITSET_P (mask, regno - GP_REG_FIRST)) reg_save_count += 1; 1826 base_offset = gp_offset - ((reg_save_count - 1) * 4); 1827 base_reg_rtx = iq2000_add_large_offset_to_sp (base_offset); 1828 } 1829 1830 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--) 1831 { 1832 if (BITSET_P (mask, regno - GP_REG_FIRST)) 1833 { 1834 rtx reg_rtx; 1835 rtx mem_rtx 1836 = gen_rtx_MEM (gpr_mode, 1837 gen_rtx_PLUS (Pmode, base_reg_rtx, 1838 GEN_INT (gp_offset - base_offset))); 1839 1840 reg_rtx = gen_rtx_REG (gpr_mode, regno); 1841 1842 if (store_p) 1843 iq2000_emit_frame_related_store (mem_rtx, reg_rtx, gp_offset); 1844 else 1845 { 1846 emit_move_insn (reg_rtx, mem_rtx); 1847 } 1848 gp_offset -= GET_MODE_SIZE (gpr_mode); 1849 } 1850 } 1851} 1852 1853/* Expand the prologue into a bunch of separate insns. */ 1854 1855void 1856iq2000_expand_prologue (void) 1857{ 1858 int regno; 1859 HOST_WIDE_INT tsize; 1860 int last_arg_is_vararg_marker = 0; 1861 tree fndecl = current_function_decl; 1862 tree fntype = TREE_TYPE (fndecl); 1863 tree fnargs = DECL_ARGUMENTS (fndecl); 1864 rtx next_arg_reg; 1865 int i; 1866 tree next_arg; 1867 tree cur_arg; 1868 CUMULATIVE_ARGS args_so_far; 1869 int store_args_on_stack = (iq2000_can_use_return_insn ()); 1870 1871 /* If struct value address is treated as the first argument. */ 1872 if (aggregate_value_p (DECL_RESULT (fndecl), fndecl) 1873 && ! current_function_returns_pcc_struct 1874 && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0) 1875 { 1876 tree type = build_pointer_type (fntype); 1877 tree function_result_decl = build_decl (PARM_DECL, NULL_TREE, type); 1878 1879 DECL_ARG_TYPE (function_result_decl) = type; 1880 TREE_CHAIN (function_result_decl) = fnargs; 1881 fnargs = function_result_decl; 1882 } 1883 1884 /* For arguments passed in registers, find the register number 1885 of the first argument in the variable part of the argument list, 1886 otherwise GP_ARG_LAST+1. Note also if the last argument is 1887 the varargs special argument, and treat it as part of the 1888 variable arguments. 1889 1890 This is only needed if store_args_on_stack is true. */ 1891 INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, 0, 0); 1892 regno = GP_ARG_FIRST; 1893 1894 for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg) 1895 { 1896 tree passed_type = DECL_ARG_TYPE (cur_arg); 1897 enum machine_mode passed_mode = TYPE_MODE (passed_type); 1898 rtx entry_parm; 1899 1900 if (TREE_ADDRESSABLE (passed_type)) 1901 { 1902 passed_type = build_pointer_type (passed_type); 1903 passed_mode = Pmode; 1904 } 1905 1906 entry_parm = FUNCTION_ARG (args_so_far, passed_mode, passed_type, 1); 1907 1908 FUNCTION_ARG_ADVANCE (args_so_far, passed_mode, passed_type, 1); 1909 next_arg = TREE_CHAIN (cur_arg); 1910 1911 if (entry_parm && store_args_on_stack) 1912 { 1913 if (next_arg == 0 1914 && DECL_NAME (cur_arg) 1915 && ((0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)), 1916 "__builtin_va_alist")) 1917 || (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)), 1918 "va_alist")))) 1919 { 1920 last_arg_is_vararg_marker = 1; 1921 break; 1922 } 1923 else 1924 { 1925 int words; 1926 1927 gcc_assert (GET_CODE (entry_parm) == REG); 1928 1929 /* Passed in a register, so will get homed automatically. */ 1930 if (GET_MODE (entry_parm) == BLKmode) 1931 words = (int_size_in_bytes (passed_type) + 3) / 4; 1932 else 1933 words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4; 1934 1935 regno = REGNO (entry_parm) + words - 1; 1936 } 1937 } 1938 else 1939 { 1940 regno = GP_ARG_LAST+1; 1941 break; 1942 } 1943 } 1944 1945 /* In order to pass small structures by value in registers we need to 1946 shift the value into the high part of the register. 1947 Function_arg has encoded a PARALLEL rtx, holding a vector of 1948 adjustments to be made as the next_arg_reg variable, so we split up the 1949 insns, and emit them separately. */ 1950 next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1); 1951 if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL) 1952 { 1953 rtvec adjust = XVEC (next_arg_reg, 0); 1954 int num = GET_NUM_ELEM (adjust); 1955 1956 for (i = 0; i < num; i++) 1957 { 1958 rtx insn, pattern; 1959 1960 pattern = RTVEC_ELT (adjust, i); 1961 if (GET_CODE (pattern) != SET 1962 || GET_CODE (SET_SRC (pattern)) != ASHIFT) 1963 abort_with_insn (pattern, "Insn is not a shift"); 1964 PUT_CODE (SET_SRC (pattern), ASHIFTRT); 1965 1966 insn = emit_insn (pattern); 1967 1968 /* Global life information isn't valid at this point, so we 1969 can't check whether these shifts are actually used. Mark 1970 them MAYBE_DEAD so that flow2 will remove them, and not 1971 complain about dead code in the prologue. */ 1972 REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX, 1973 REG_NOTES (insn)); 1974 } 1975 } 1976 1977 tsize = compute_frame_size (get_frame_size ()); 1978 1979 /* If this function is a varargs function, store any registers that 1980 would normally hold arguments ($4 - $7) on the stack. */ 1981 if (store_args_on_stack 1982 && ((TYPE_ARG_TYPES (fntype) != 0 1983 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) 1984 != void_type_node)) 1985 || last_arg_is_vararg_marker)) 1986 { 1987 int offset = (regno - GP_ARG_FIRST) * UNITS_PER_WORD; 1988 rtx ptr = stack_pointer_rtx; 1989 1990 for (; regno <= GP_ARG_LAST; regno++) 1991 { 1992 if (offset != 0) 1993 ptr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset)); 1994 emit_move_insn (gen_rtx_MEM (gpr_mode, ptr), 1995 gen_rtx_REG (gpr_mode, regno)); 1996 1997 offset += GET_MODE_SIZE (gpr_mode); 1998 } 1999 } 2000 2001 if (tsize > 0) 2002 { 2003 rtx tsize_rtx = GEN_INT (tsize); 2004 rtx adjustment_rtx, insn, dwarf_pattern; 2005 2006 if (tsize > 32767) 2007 { 2008 adjustment_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM); 2009 emit_move_insn (adjustment_rtx, tsize_rtx); 2010 } 2011 else 2012 adjustment_rtx = tsize_rtx; 2013 2014 insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, 2015 adjustment_rtx)); 2016 2017 dwarf_pattern = gen_rtx_SET (Pmode, stack_pointer_rtx, 2018 plus_constant (stack_pointer_rtx, -tsize)); 2019 2020 iq2000_annotate_frame_insn (insn, dwarf_pattern); 2021 2022 save_restore_insns (1); 2023 2024 if (frame_pointer_needed) 2025 { 2026 rtx insn = 0; 2027 2028 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx, 2029 stack_pointer_rtx)); 2030 2031 if (insn) 2032 RTX_FRAME_RELATED_P (insn) = 1; 2033 } 2034 } 2035 2036 emit_insn (gen_blockage ()); 2037} 2038 2039/* Expand the epilogue into a bunch of separate insns. */ 2040 2041void 2042iq2000_expand_epilogue (void) 2043{ 2044 HOST_WIDE_INT tsize = cfun->machine->total_size; 2045 rtx tsize_rtx = GEN_INT (tsize); 2046 rtx tmp_rtx = (rtx)0; 2047 2048 if (iq2000_can_use_return_insn ()) 2049 { 2050 emit_jump_insn (gen_return ()); 2051 return; 2052 } 2053 2054 if (tsize > 32767) 2055 { 2056 tmp_rtx = gen_rtx_REG (Pmode, IQ2000_TEMP1_REGNUM); 2057 emit_move_insn (tmp_rtx, tsize_rtx); 2058 tsize_rtx = tmp_rtx; 2059 } 2060 2061 if (tsize > 0) 2062 { 2063 if (frame_pointer_needed) 2064 { 2065 emit_insn (gen_blockage ()); 2066 2067 emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx)); 2068 } 2069 2070 save_restore_insns (0); 2071 2072 if (current_function_calls_eh_return) 2073 { 2074 rtx eh_ofs = EH_RETURN_STACKADJ_RTX; 2075 emit_insn (gen_addsi3 (eh_ofs, eh_ofs, tsize_rtx)); 2076 tsize_rtx = eh_ofs; 2077 } 2078 2079 emit_insn (gen_blockage ()); 2080 2081 if (tsize != 0 || current_function_calls_eh_return) 2082 { 2083 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, 2084 tsize_rtx)); 2085 } 2086 } 2087 2088 if (current_function_calls_eh_return) 2089 { 2090 /* Perform the additional bump for __throw. */ 2091 emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM), 2092 stack_pointer_rtx); 2093 emit_insn (gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 2094 HARD_FRAME_POINTER_REGNUM))); 2095 emit_jump_insn (gen_eh_return_internal ()); 2096 } 2097 else 2098 emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode, 2099 GP_REG_FIRST + 31))); 2100} 2101 2102void 2103iq2000_expand_eh_return (rtx address) 2104{ 2105 HOST_WIDE_INT gp_offset = cfun->machine->gp_sp_offset; 2106 rtx scratch; 2107 2108 scratch = plus_constant (stack_pointer_rtx, gp_offset); 2109 emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address); 2110} 2111 2112/* Return nonzero if this function is known to have a null epilogue. 2113 This allows the optimizer to omit jumps to jumps if no stack 2114 was created. */ 2115 2116int 2117iq2000_can_use_return_insn (void) 2118{ 2119 if (! reload_completed) 2120 return 0; 2121 2122 if (regs_ever_live[31] || profile_flag) 2123 return 0; 2124 2125 if (cfun->machine->initialized) 2126 return cfun->machine->total_size == 0; 2127 2128 return compute_frame_size (get_frame_size ()) == 0; 2129} 2130 2131/* Returns nonzero if X contains a SYMBOL_REF. */ 2132 2133static int 2134symbolic_expression_p (rtx x) 2135{ 2136 if (GET_CODE (x) == SYMBOL_REF) 2137 return 1; 2138 2139 if (GET_CODE (x) == CONST) 2140 return symbolic_expression_p (XEXP (x, 0)); 2141 2142 if (UNARY_P (x)) 2143 return symbolic_expression_p (XEXP (x, 0)); 2144 2145 if (ARITHMETIC_P (x)) 2146 return (symbolic_expression_p (XEXP (x, 0)) 2147 || symbolic_expression_p (XEXP (x, 1))); 2148 2149 return 0; 2150} 2151 2152/* Choose the section to use for the constant rtx expression X that has 2153 mode MODE. */ 2154 2155static section * 2156iq2000_select_rtx_section (enum machine_mode mode, rtx x ATTRIBUTE_UNUSED, 2157 unsigned HOST_WIDE_INT align) 2158{ 2159 /* For embedded applications, always put constants in read-only data, 2160 in order to reduce RAM usage. */ 2161 return mergeable_constant_section (mode, align, 0); 2162} 2163 2164/* Choose the section to use for DECL. RELOC is true if its value contains 2165 any relocatable expression. 2166 2167 Some of the logic used here needs to be replicated in 2168 ENCODE_SECTION_INFO in iq2000.h so that references to these symbols 2169 are done correctly. */ 2170 2171static section * 2172iq2000_select_section (tree decl, int reloc ATTRIBUTE_UNUSED, 2173 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED) 2174{ 2175 if (TARGET_EMBEDDED_DATA) 2176 { 2177 /* For embedded applications, always put an object in read-only data 2178 if possible, in order to reduce RAM usage. */ 2179 if ((TREE_CODE (decl) == VAR_DECL 2180 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl) 2181 && DECL_INITIAL (decl) 2182 && (DECL_INITIAL (decl) == error_mark_node 2183 || TREE_CONSTANT (DECL_INITIAL (decl)))) 2184 /* Deal with calls from output_constant_def_contents. */ 2185 || TREE_CODE (decl) != VAR_DECL) 2186 return readonly_data_section; 2187 else 2188 return data_section; 2189 } 2190 else 2191 { 2192 /* For hosted applications, always put an object in small data if 2193 possible, as this gives the best performance. */ 2194 if ((TREE_CODE (decl) == VAR_DECL 2195 && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl) 2196 && DECL_INITIAL (decl) 2197 && (DECL_INITIAL (decl) == error_mark_node 2198 || TREE_CONSTANT (DECL_INITIAL (decl)))) 2199 /* Deal with calls from output_constant_def_contents. */ 2200 || TREE_CODE (decl) != VAR_DECL) 2201 return readonly_data_section; 2202 else 2203 return data_section; 2204 } 2205} 2206/* Return register to use for a function return value with VALTYPE for function 2207 FUNC. */ 2208 2209rtx 2210iq2000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED) 2211{ 2212 int reg = GP_RETURN; 2213 enum machine_mode mode = TYPE_MODE (valtype); 2214 int unsignedp = TYPE_UNSIGNED (valtype); 2215 2216 /* Since we define TARGET_PROMOTE_FUNCTION_RETURN that returns true, 2217 we must promote the mode just as PROMOTE_MODE does. */ 2218 mode = promote_mode (valtype, mode, &unsignedp, 1); 2219 2220 return gen_rtx_REG (mode, reg); 2221} 2222 2223/* Return true when an argument must be passed by reference. */ 2224 2225static bool 2226iq2000_pass_by_reference (CUMULATIVE_ARGS *cum, enum machine_mode mode, 2227 tree type, bool named ATTRIBUTE_UNUSED) 2228{ 2229 int size; 2230 2231 /* We must pass by reference if we would be both passing in registers 2232 and the stack. This is because any subsequent partial arg would be 2233 handled incorrectly in this case. */ 2234 if (cum && targetm.calls.must_pass_in_stack (mode, type)) 2235 { 2236 /* Don't pass the actual CUM to FUNCTION_ARG, because we would 2237 get double copies of any offsets generated for small structs 2238 passed in registers. */ 2239 CUMULATIVE_ARGS temp; 2240 2241 temp = *cum; 2242 if (FUNCTION_ARG (temp, mode, type, named) != 0) 2243 return 1; 2244 } 2245 2246 if (type == NULL_TREE || mode == DImode || mode == DFmode) 2247 return 0; 2248 2249 size = int_size_in_bytes (type); 2250 return size == -1 || size > UNITS_PER_WORD; 2251} 2252 2253/* Return the length of INSN. LENGTH is the initial length computed by 2254 attributes in the machine-description file. */ 2255 2256int 2257iq2000_adjust_insn_length (rtx insn, int length) 2258{ 2259 /* A unconditional jump has an unfilled delay slot if it is not part 2260 of a sequence. A conditional jump normally has a delay slot. */ 2261 if (simplejump_p (insn) 2262 || ( (GET_CODE (insn) == JUMP_INSN 2263 || GET_CODE (insn) == CALL_INSN))) 2264 length += 4; 2265 2266 return length; 2267} 2268 2269/* Output assembly instructions to perform a conditional branch. 2270 2271 INSN is the branch instruction. OPERANDS[0] is the condition. 2272 OPERANDS[1] is the target of the branch. OPERANDS[2] is the target 2273 of the first operand to the condition. If TWO_OPERANDS_P is 2274 nonzero the comparison takes two operands; OPERANDS[3] will be the 2275 second operand. 2276 2277 If INVERTED_P is nonzero we are to branch if the condition does 2278 not hold. If FLOAT_P is nonzero this is a floating-point comparison. 2279 2280 LENGTH is the length (in bytes) of the sequence we are to generate. 2281 That tells us whether to generate a simple conditional branch, or a 2282 reversed conditional branch around a `jr' instruction. */ 2283 2284char * 2285iq2000_output_conditional_branch (rtx insn, rtx * operands, int two_operands_p, 2286 int float_p, int inverted_p, int length) 2287{ 2288 static char buffer[200]; 2289 /* The kind of comparison we are doing. */ 2290 enum rtx_code code = GET_CODE (operands[0]); 2291 /* Nonzero if the opcode for the comparison needs a `z' indicating 2292 that it is a comparison against zero. */ 2293 int need_z_p; 2294 /* A string to use in the assembly output to represent the first 2295 operand. */ 2296 const char *op1 = "%z2"; 2297 /* A string to use in the assembly output to represent the second 2298 operand. Use the hard-wired zero register if there's no second 2299 operand. */ 2300 const char *op2 = (two_operands_p ? ",%z3" : ",%."); 2301 /* The operand-printing string for the comparison. */ 2302 const char *comp = (float_p ? "%F0" : "%C0"); 2303 /* The operand-printing string for the inverted comparison. */ 2304 const char *inverted_comp = (float_p ? "%W0" : "%N0"); 2305 2306 /* Likely variants of each branch instruction annul the instruction 2307 in the delay slot if the branch is not taken. */ 2308 iq2000_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn)); 2309 2310 if (!two_operands_p) 2311 { 2312 /* To compute whether than A > B, for example, we normally 2313 subtract B from A and then look at the sign bit. But, if we 2314 are doing an unsigned comparison, and B is zero, we don't 2315 have to do the subtraction. Instead, we can just check to 2316 see if A is nonzero. Thus, we change the CODE here to 2317 reflect the simpler comparison operation. */ 2318 switch (code) 2319 { 2320 case GTU: 2321 code = NE; 2322 break; 2323 2324 case LEU: 2325 code = EQ; 2326 break; 2327 2328 case GEU: 2329 /* A condition which will always be true. */ 2330 code = EQ; 2331 op1 = "%."; 2332 break; 2333 2334 case LTU: 2335 /* A condition which will always be false. */ 2336 code = NE; 2337 op1 = "%."; 2338 break; 2339 2340 default: 2341 /* Not a special case. */ 2342 break; 2343 } 2344 } 2345 2346 /* Relative comparisons are always done against zero. But 2347 equality comparisons are done between two operands, and therefore 2348 do not require a `z' in the assembly language output. */ 2349 need_z_p = (!float_p && code != EQ && code != NE); 2350 /* For comparisons against zero, the zero is not provided 2351 explicitly. */ 2352 if (need_z_p) 2353 op2 = ""; 2354 2355 /* Begin by terminating the buffer. That way we can always use 2356 strcat to add to it. */ 2357 buffer[0] = '\0'; 2358 2359 switch (length) 2360 { 2361 case 4: 2362 case 8: 2363 /* Just a simple conditional branch. */ 2364 if (float_p) 2365 sprintf (buffer, "b%s%%?\t%%Z2%%1", 2366 inverted_p ? inverted_comp : comp); 2367 else 2368 sprintf (buffer, "b%s%s%%?\t%s%s,%%1", 2369 inverted_p ? inverted_comp : comp, 2370 need_z_p ? "z" : "", 2371 op1, 2372 op2); 2373 return buffer; 2374 2375 case 12: 2376 case 16: 2377 { 2378 /* Generate a reversed conditional branch around ` j' 2379 instruction: 2380 2381 .set noreorder 2382 .set nomacro 2383 bc l 2384 nop 2385 j target 2386 .set macro 2387 .set reorder 2388 l: 2389 2390 Because we have to jump four bytes *past* the following 2391 instruction if this branch was annulled, we can't just use 2392 a label, as in the picture above; there's no way to put the 2393 label after the next instruction, as the assembler does not 2394 accept `.L+4' as the target of a branch. (We can't just 2395 wait until the next instruction is output; it might be a 2396 macro and take up more than four bytes. Once again, we see 2397 why we want to eliminate macros.) 2398 2399 If the branch is annulled, we jump four more bytes that we 2400 would otherwise; that way we skip the annulled instruction 2401 in the delay slot. */ 2402 2403 const char *target 2404 = ((iq2000_branch_likely || length == 16) ? ".+16" : ".+12"); 2405 char *c; 2406 2407 c = strchr (buffer, '\0'); 2408 /* Generate the reversed comparison. This takes four 2409 bytes. */ 2410 if (float_p) 2411 sprintf (c, "b%s\t%%Z2%s", 2412 inverted_p ? comp : inverted_comp, 2413 target); 2414 else 2415 sprintf (c, "b%s%s\t%s%s,%s", 2416 inverted_p ? comp : inverted_comp, 2417 need_z_p ? "z" : "", 2418 op1, 2419 op2, 2420 target); 2421 strcat (c, "\n\tnop\n\tj\t%1"); 2422 if (length == 16) 2423 /* The delay slot was unfilled. Since we're inside 2424 .noreorder, the assembler will not fill in the NOP for 2425 us, so we must do it ourselves. */ 2426 strcat (buffer, "\n\tnop"); 2427 return buffer; 2428 } 2429 2430 default: 2431 gcc_unreachable (); 2432 } 2433 2434 /* NOTREACHED */ 2435 return 0; 2436} 2437 2438#define def_builtin(NAME, TYPE, CODE) \ 2439 lang_hooks.builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \ 2440 NULL, NULL_TREE) 2441 2442static void 2443iq2000_init_builtins (void) 2444{ 2445 tree endlink = void_list_node; 2446 tree void_ftype, void_ftype_int, void_ftype_int_int; 2447 tree void_ftype_int_int_int; 2448 tree int_ftype_int, int_ftype_int_int, int_ftype_int_int_int; 2449 tree int_ftype_int_int_int_int; 2450 2451 /* func () */ 2452 void_ftype 2453 = build_function_type (void_type_node, 2454 tree_cons (NULL_TREE, void_type_node, endlink)); 2455 2456 /* func (int) */ 2457 void_ftype_int 2458 = build_function_type (void_type_node, 2459 tree_cons (NULL_TREE, integer_type_node, endlink)); 2460 2461 /* void func (int, int) */ 2462 void_ftype_int_int 2463 = build_function_type (void_type_node, 2464 tree_cons (NULL_TREE, integer_type_node, 2465 tree_cons (NULL_TREE, integer_type_node, 2466 endlink))); 2467 2468 /* int func (int) */ 2469 int_ftype_int 2470 = build_function_type (integer_type_node, 2471 tree_cons (NULL_TREE, integer_type_node, endlink)); 2472 2473 /* int func (int, int) */ 2474 int_ftype_int_int 2475 = build_function_type (integer_type_node, 2476 tree_cons (NULL_TREE, integer_type_node, 2477 tree_cons (NULL_TREE, integer_type_node, 2478 endlink))); 2479 2480 /* void func (int, int, int) */ 2481void_ftype_int_int_int 2482 = build_function_type 2483 (void_type_node, 2484 tree_cons (NULL_TREE, integer_type_node, 2485 tree_cons (NULL_TREE, integer_type_node, 2486 tree_cons (NULL_TREE, 2487 integer_type_node, 2488 endlink)))); 2489 2490 /* int func (int, int, int, int) */ 2491 int_ftype_int_int_int_int 2492 = build_function_type 2493 (integer_type_node, 2494 tree_cons (NULL_TREE, integer_type_node, 2495 tree_cons (NULL_TREE, integer_type_node, 2496 tree_cons (NULL_TREE, 2497 integer_type_node, 2498 tree_cons (NULL_TREE, 2499 integer_type_node, 2500 endlink))))); 2501 2502 /* int func (int, int, int) */ 2503 int_ftype_int_int_int 2504 = build_function_type 2505 (integer_type_node, 2506 tree_cons (NULL_TREE, integer_type_node, 2507 tree_cons (NULL_TREE, integer_type_node, 2508 tree_cons (NULL_TREE, 2509 integer_type_node, 2510 endlink)))); 2511 2512 /* int func (int, int, int, int) */ 2513 int_ftype_int_int_int_int 2514 = build_function_type 2515 (integer_type_node, 2516 tree_cons (NULL_TREE, integer_type_node, 2517 tree_cons (NULL_TREE, integer_type_node, 2518 tree_cons (NULL_TREE, 2519 integer_type_node, 2520 tree_cons (NULL_TREE, 2521 integer_type_node, 2522 endlink))))); 2523 2524 def_builtin ("__builtin_ado16", int_ftype_int_int, IQ2000_BUILTIN_ADO16); 2525 def_builtin ("__builtin_ram", int_ftype_int_int_int_int, IQ2000_BUILTIN_RAM); 2526 def_builtin ("__builtin_chkhdr", void_ftype_int_int, IQ2000_BUILTIN_CHKHDR); 2527 def_builtin ("__builtin_pkrl", void_ftype_int_int, IQ2000_BUILTIN_PKRL); 2528 def_builtin ("__builtin_cfc0", int_ftype_int, IQ2000_BUILTIN_CFC0); 2529 def_builtin ("__builtin_cfc1", int_ftype_int, IQ2000_BUILTIN_CFC1); 2530 def_builtin ("__builtin_cfc2", int_ftype_int, IQ2000_BUILTIN_CFC2); 2531 def_builtin ("__builtin_cfc3", int_ftype_int, IQ2000_BUILTIN_CFC3); 2532 def_builtin ("__builtin_ctc0", void_ftype_int_int, IQ2000_BUILTIN_CTC0); 2533 def_builtin ("__builtin_ctc1", void_ftype_int_int, IQ2000_BUILTIN_CTC1); 2534 def_builtin ("__builtin_ctc2", void_ftype_int_int, IQ2000_BUILTIN_CTC2); 2535 def_builtin ("__builtin_ctc3", void_ftype_int_int, IQ2000_BUILTIN_CTC3); 2536 def_builtin ("__builtin_mfc0", int_ftype_int, IQ2000_BUILTIN_MFC0); 2537 def_builtin ("__builtin_mfc1", int_ftype_int, IQ2000_BUILTIN_MFC1); 2538 def_builtin ("__builtin_mfc2", int_ftype_int, IQ2000_BUILTIN_MFC2); 2539 def_builtin ("__builtin_mfc3", int_ftype_int, IQ2000_BUILTIN_MFC3); 2540 def_builtin ("__builtin_mtc0", void_ftype_int_int, IQ2000_BUILTIN_MTC0); 2541 def_builtin ("__builtin_mtc1", void_ftype_int_int, IQ2000_BUILTIN_MTC1); 2542 def_builtin ("__builtin_mtc2", void_ftype_int_int, IQ2000_BUILTIN_MTC2); 2543 def_builtin ("__builtin_mtc3", void_ftype_int_int, IQ2000_BUILTIN_MTC3); 2544 def_builtin ("__builtin_lur", void_ftype_int_int, IQ2000_BUILTIN_LUR); 2545 def_builtin ("__builtin_rb", void_ftype_int_int, IQ2000_BUILTIN_RB); 2546 def_builtin ("__builtin_rx", void_ftype_int_int, IQ2000_BUILTIN_RX); 2547 def_builtin ("__builtin_srrd", void_ftype_int, IQ2000_BUILTIN_SRRD); 2548 def_builtin ("__builtin_srwr", void_ftype_int_int, IQ2000_BUILTIN_SRWR); 2549 def_builtin ("__builtin_wb", void_ftype_int_int, IQ2000_BUILTIN_WB); 2550 def_builtin ("__builtin_wx", void_ftype_int_int, IQ2000_BUILTIN_WX); 2551 def_builtin ("__builtin_luc32l", void_ftype_int_int, IQ2000_BUILTIN_LUC32L); 2552 def_builtin ("__builtin_luc64", void_ftype_int_int, IQ2000_BUILTIN_LUC64); 2553 def_builtin ("__builtin_luc64l", void_ftype_int_int, IQ2000_BUILTIN_LUC64L); 2554 def_builtin ("__builtin_luk", void_ftype_int_int, IQ2000_BUILTIN_LUK); 2555 def_builtin ("__builtin_lulck", void_ftype_int, IQ2000_BUILTIN_LULCK); 2556 def_builtin ("__builtin_lum32", void_ftype_int_int, IQ2000_BUILTIN_LUM32); 2557 def_builtin ("__builtin_lum32l", void_ftype_int_int, IQ2000_BUILTIN_LUM32L); 2558 def_builtin ("__builtin_lum64", void_ftype_int_int, IQ2000_BUILTIN_LUM64); 2559 def_builtin ("__builtin_lum64l", void_ftype_int_int, IQ2000_BUILTIN_LUM64L); 2560 def_builtin ("__builtin_lurl", void_ftype_int_int, IQ2000_BUILTIN_LURL); 2561 def_builtin ("__builtin_mrgb", int_ftype_int_int_int, IQ2000_BUILTIN_MRGB); 2562 def_builtin ("__builtin_srrdl", void_ftype_int, IQ2000_BUILTIN_SRRDL); 2563 def_builtin ("__builtin_srulck", void_ftype_int, IQ2000_BUILTIN_SRULCK); 2564 def_builtin ("__builtin_srwru", void_ftype_int_int, IQ2000_BUILTIN_SRWRU); 2565 def_builtin ("__builtin_trapqfl", void_ftype, IQ2000_BUILTIN_TRAPQFL); 2566 def_builtin ("__builtin_trapqne", void_ftype, IQ2000_BUILTIN_TRAPQNE); 2567 def_builtin ("__builtin_traprel", void_ftype_int, IQ2000_BUILTIN_TRAPREL); 2568 def_builtin ("__builtin_wbu", void_ftype_int_int_int, IQ2000_BUILTIN_WBU); 2569 def_builtin ("__builtin_syscall", void_ftype, IQ2000_BUILTIN_SYSCALL); 2570} 2571 2572/* Builtin for ICODE having ARGCOUNT args in ARGLIST where each arg 2573 has an rtx CODE. */ 2574 2575static rtx 2576expand_one_builtin (enum insn_code icode, rtx target, tree arglist, 2577 enum rtx_code *code, int argcount) 2578{ 2579 rtx pat; 2580 tree arg [5]; 2581 rtx op [5]; 2582 enum machine_mode mode [5]; 2583 int i; 2584 2585 mode[0] = insn_data[icode].operand[0].mode; 2586 for (i = 0; i < argcount; i++) 2587 { 2588 arg[i] = TREE_VALUE (arglist); 2589 arglist = TREE_CHAIN (arglist); 2590 op[i] = expand_expr (arg[i], NULL_RTX, VOIDmode, 0); 2591 mode[i] = insn_data[icode].operand[i].mode; 2592 if (code[i] == CONST_INT && GET_CODE (op[i]) != CONST_INT) 2593 error ("argument %qd is not a constant", i + 1); 2594 if (code[i] == REG 2595 && ! (*insn_data[icode].operand[i].predicate) (op[i], mode[i])) 2596 op[i] = copy_to_mode_reg (mode[i], op[i]); 2597 } 2598 2599 if (insn_data[icode].operand[0].constraint[0] == '=') 2600 { 2601 if (target == 0 2602 || GET_MODE (target) != mode[0] 2603 || ! (*insn_data[icode].operand[0].predicate) (target, mode[0])) 2604 target = gen_reg_rtx (mode[0]); 2605 } 2606 else 2607 target = 0; 2608 2609 switch (argcount) 2610 { 2611 case 0: 2612 pat = GEN_FCN (icode) (target); 2613 case 1: 2614 if (target) 2615 pat = GEN_FCN (icode) (target, op[0]); 2616 else 2617 pat = GEN_FCN (icode) (op[0]); 2618 break; 2619 case 2: 2620 if (target) 2621 pat = GEN_FCN (icode) (target, op[0], op[1]); 2622 else 2623 pat = GEN_FCN (icode) (op[0], op[1]); 2624 break; 2625 case 3: 2626 if (target) 2627 pat = GEN_FCN (icode) (target, op[0], op[1], op[2]); 2628 else 2629 pat = GEN_FCN (icode) (op[0], op[1], op[2]); 2630 break; 2631 case 4: 2632 if (target) 2633 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]); 2634 else 2635 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]); 2636 break; 2637 default: 2638 gcc_unreachable (); 2639 } 2640 2641 if (! pat) 2642 return 0; 2643 emit_insn (pat); 2644 return target; 2645} 2646 2647/* Expand an expression EXP that calls a built-in function, 2648 with result going to TARGET if that's convenient 2649 (and in mode MODE if that's convenient). 2650 SUBTARGET may be used as the target for computing one of EXP's operands. 2651 IGNORE is nonzero if the value is to be ignored. */ 2652 2653static rtx 2654iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, 2655 enum machine_mode mode ATTRIBUTE_UNUSED, 2656 int ignore ATTRIBUTE_UNUSED) 2657{ 2658 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); 2659 tree arglist = TREE_OPERAND (exp, 1); 2660 int fcode = DECL_FUNCTION_CODE (fndecl); 2661 enum rtx_code code [5]; 2662 2663 code[0] = REG; 2664 code[1] = REG; 2665 code[2] = REG; 2666 code[3] = REG; 2667 code[4] = REG; 2668 switch (fcode) 2669 { 2670 default: 2671 break; 2672 2673 case IQ2000_BUILTIN_ADO16: 2674 return expand_one_builtin (CODE_FOR_ado16, target, arglist, code, 2); 2675 2676 case IQ2000_BUILTIN_RAM: 2677 code[1] = CONST_INT; 2678 code[2] = CONST_INT; 2679 code[3] = CONST_INT; 2680 return expand_one_builtin (CODE_FOR_ram, target, arglist, code, 4); 2681 2682 case IQ2000_BUILTIN_CHKHDR: 2683 return expand_one_builtin (CODE_FOR_chkhdr, target, arglist, code, 2); 2684 2685 case IQ2000_BUILTIN_PKRL: 2686 return expand_one_builtin (CODE_FOR_pkrl, target, arglist, code, 2); 2687 2688 case IQ2000_BUILTIN_CFC0: 2689 code[0] = CONST_INT; 2690 return expand_one_builtin (CODE_FOR_cfc0, target, arglist, code, 1); 2691 2692 case IQ2000_BUILTIN_CFC1: 2693 code[0] = CONST_INT; 2694 return expand_one_builtin (CODE_FOR_cfc1, target, arglist, code, 1); 2695 2696 case IQ2000_BUILTIN_CFC2: 2697 code[0] = CONST_INT; 2698 return expand_one_builtin (CODE_FOR_cfc2, target, arglist, code, 1); 2699 2700 case IQ2000_BUILTIN_CFC3: 2701 code[0] = CONST_INT; 2702 return expand_one_builtin (CODE_FOR_cfc3, target, arglist, code, 1); 2703 2704 case IQ2000_BUILTIN_CTC0: 2705 code[1] = CONST_INT; 2706 return expand_one_builtin (CODE_FOR_ctc0, target, arglist, code, 2); 2707 2708 case IQ2000_BUILTIN_CTC1: 2709 code[1] = CONST_INT; 2710 return expand_one_builtin (CODE_FOR_ctc1, target, arglist, code, 2); 2711 2712 case IQ2000_BUILTIN_CTC2: 2713 code[1] = CONST_INT; 2714 return expand_one_builtin (CODE_FOR_ctc2, target, arglist, code, 2); 2715 2716 case IQ2000_BUILTIN_CTC3: 2717 code[1] = CONST_INT; 2718 return expand_one_builtin (CODE_FOR_ctc3, target, arglist, code, 2); 2719 2720 case IQ2000_BUILTIN_MFC0: 2721 code[0] = CONST_INT; 2722 return expand_one_builtin (CODE_FOR_mfc0, target, arglist, code, 1); 2723 2724 case IQ2000_BUILTIN_MFC1: 2725 code[0] = CONST_INT; 2726 return expand_one_builtin (CODE_FOR_mfc1, target, arglist, code, 1); 2727 2728 case IQ2000_BUILTIN_MFC2: 2729 code[0] = CONST_INT; 2730 return expand_one_builtin (CODE_FOR_mfc2, target, arglist, code, 1); 2731 2732 case IQ2000_BUILTIN_MFC3: 2733 code[0] = CONST_INT; 2734 return expand_one_builtin (CODE_FOR_mfc3, target, arglist, code, 1); 2735 2736 case IQ2000_BUILTIN_MTC0: 2737 code[1] = CONST_INT; 2738 return expand_one_builtin (CODE_FOR_mtc0, target, arglist, code, 2); 2739 2740 case IQ2000_BUILTIN_MTC1: 2741 code[1] = CONST_INT; 2742 return expand_one_builtin (CODE_FOR_mtc1, target, arglist, code, 2); 2743 2744 case IQ2000_BUILTIN_MTC2: 2745 code[1] = CONST_INT; 2746 return expand_one_builtin (CODE_FOR_mtc2, target, arglist, code, 2); 2747 2748 case IQ2000_BUILTIN_MTC3: 2749 code[1] = CONST_INT; 2750 return expand_one_builtin (CODE_FOR_mtc3, target, arglist, code, 2); 2751 2752 case IQ2000_BUILTIN_LUR: 2753 return expand_one_builtin (CODE_FOR_lur, target, arglist, code, 2); 2754 2755 case IQ2000_BUILTIN_RB: 2756 return expand_one_builtin (CODE_FOR_rb, target, arglist, code, 2); 2757 2758 case IQ2000_BUILTIN_RX: 2759 return expand_one_builtin (CODE_FOR_rx, target, arglist, code, 2); 2760 2761 case IQ2000_BUILTIN_SRRD: 2762 return expand_one_builtin (CODE_FOR_srrd, target, arglist, code, 1); 2763 2764 case IQ2000_BUILTIN_SRWR: 2765 return expand_one_builtin (CODE_FOR_srwr, target, arglist, code, 2); 2766 2767 case IQ2000_BUILTIN_WB: 2768 return expand_one_builtin (CODE_FOR_wb, target, arglist, code, 2); 2769 2770 case IQ2000_BUILTIN_WX: 2771 return expand_one_builtin (CODE_FOR_wx, target, arglist, code, 2); 2772 2773 case IQ2000_BUILTIN_LUC32L: 2774 return expand_one_builtin (CODE_FOR_luc32l, target, arglist, code, 2); 2775 2776 case IQ2000_BUILTIN_LUC64: 2777 return expand_one_builtin (CODE_FOR_luc64, target, arglist, code, 2); 2778 2779 case IQ2000_BUILTIN_LUC64L: 2780 return expand_one_builtin (CODE_FOR_luc64l, target, arglist, code, 2); 2781 2782 case IQ2000_BUILTIN_LUK: 2783 return expand_one_builtin (CODE_FOR_luk, target, arglist, code, 2); 2784 2785 case IQ2000_BUILTIN_LULCK: 2786 return expand_one_builtin (CODE_FOR_lulck, target, arglist, code, 1); 2787 2788 case IQ2000_BUILTIN_LUM32: 2789 return expand_one_builtin (CODE_FOR_lum32, target, arglist, code, 2); 2790 2791 case IQ2000_BUILTIN_LUM32L: 2792 return expand_one_builtin (CODE_FOR_lum32l, target, arglist, code, 2); 2793 2794 case IQ2000_BUILTIN_LUM64: 2795 return expand_one_builtin (CODE_FOR_lum64, target, arglist, code, 2); 2796 2797 case IQ2000_BUILTIN_LUM64L: 2798 return expand_one_builtin (CODE_FOR_lum64l, target, arglist, code, 2); 2799 2800 case IQ2000_BUILTIN_LURL: 2801 return expand_one_builtin (CODE_FOR_lurl, target, arglist, code, 2); 2802 2803 case IQ2000_BUILTIN_MRGB: 2804 code[2] = CONST_INT; 2805 return expand_one_builtin (CODE_FOR_mrgb, target, arglist, code, 3); 2806 2807 case IQ2000_BUILTIN_SRRDL: 2808 return expand_one_builtin (CODE_FOR_srrdl, target, arglist, code, 1); 2809 2810 case IQ2000_BUILTIN_SRULCK: 2811 return expand_one_builtin (CODE_FOR_srulck, target, arglist, code, 1); 2812 2813 case IQ2000_BUILTIN_SRWRU: 2814 return expand_one_builtin (CODE_FOR_srwru, target, arglist, code, 2); 2815 2816 case IQ2000_BUILTIN_TRAPQFL: 2817 return expand_one_builtin (CODE_FOR_trapqfl, target, arglist, code, 0); 2818 2819 case IQ2000_BUILTIN_TRAPQNE: 2820 return expand_one_builtin (CODE_FOR_trapqne, target, arglist, code, 0); 2821 2822 case IQ2000_BUILTIN_TRAPREL: 2823 return expand_one_builtin (CODE_FOR_traprel, target, arglist, code, 1); 2824 2825 case IQ2000_BUILTIN_WBU: 2826 return expand_one_builtin (CODE_FOR_wbu, target, arglist, code, 3); 2827 2828 case IQ2000_BUILTIN_SYSCALL: 2829 return expand_one_builtin (CODE_FOR_syscall, target, arglist, code, 0); 2830 } 2831 2832 return NULL_RTX; 2833} 2834 2835/* Worker function for TARGET_RETURN_IN_MEMORY. */ 2836 2837static bool 2838iq2000_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED) 2839{ 2840 return ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD)) 2841 || (int_size_in_bytes (type) == -1)); 2842} 2843 2844/* Worker function for TARGET_SETUP_INCOMING_VARARGS. */ 2845 2846static void 2847iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *cum, 2848 enum machine_mode mode ATTRIBUTE_UNUSED, 2849 tree type ATTRIBUTE_UNUSED, int * pretend_size, 2850 int no_rtl) 2851{ 2852 unsigned int iq2000_off = ! cum->last_arg_fp; 2853 unsigned int iq2000_fp_off = cum->last_arg_fp; 2854 2855 if ((cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off)) 2856 { 2857 int iq2000_save_gp_regs 2858 = MAX_ARGS_IN_REGISTERS - cum->arg_words - iq2000_off; 2859 int iq2000_save_fp_regs 2860 = (MAX_ARGS_IN_REGISTERS - cum->fp_arg_words - iq2000_fp_off); 2861 2862 if (iq2000_save_gp_regs < 0) 2863 iq2000_save_gp_regs = 0; 2864 if (iq2000_save_fp_regs < 0) 2865 iq2000_save_fp_regs = 0; 2866 2867 *pretend_size = ((iq2000_save_gp_regs * UNITS_PER_WORD) 2868 + (iq2000_save_fp_regs * UNITS_PER_FPREG)); 2869 2870 if (! (no_rtl)) 2871 { 2872 if (cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off) 2873 { 2874 rtx ptr, mem; 2875 ptr = plus_constant (virtual_incoming_args_rtx, 2876 - (iq2000_save_gp_regs 2877 * UNITS_PER_WORD)); 2878 mem = gen_rtx_MEM (BLKmode, ptr); 2879 move_block_from_reg 2880 (cum->arg_words + GP_ARG_FIRST + iq2000_off, 2881 mem, 2882 iq2000_save_gp_regs); 2883 } 2884 } 2885 } 2886} 2887 2888/* A C compound statement to output to stdio stream STREAM the 2889 assembler syntax for an instruction operand that is a memory 2890 reference whose address is ADDR. ADDR is an RTL expression. */ 2891 2892void 2893print_operand_address (FILE * file, rtx addr) 2894{ 2895 if (!addr) 2896 error ("PRINT_OPERAND_ADDRESS, null pointer"); 2897 2898 else 2899 switch (GET_CODE (addr)) 2900 { 2901 case REG: 2902 if (REGNO (addr) == ARG_POINTER_REGNUM) 2903 abort_with_insn (addr, "Arg pointer not eliminated."); 2904 2905 fprintf (file, "0(%s)", reg_names [REGNO (addr)]); 2906 break; 2907 2908 case LO_SUM: 2909 { 2910 rtx arg0 = XEXP (addr, 0); 2911 rtx arg1 = XEXP (addr, 1); 2912 2913 if (GET_CODE (arg0) != REG) 2914 abort_with_insn (addr, 2915 "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG."); 2916 2917 fprintf (file, "%%lo("); 2918 print_operand_address (file, arg1); 2919 fprintf (file, ")(%s)", reg_names [REGNO (arg0)]); 2920 } 2921 break; 2922 2923 case PLUS: 2924 { 2925 rtx reg = 0; 2926 rtx offset = 0; 2927 rtx arg0 = XEXP (addr, 0); 2928 rtx arg1 = XEXP (addr, 1); 2929 2930 if (GET_CODE (arg0) == REG) 2931 { 2932 reg = arg0; 2933 offset = arg1; 2934 if (GET_CODE (offset) == REG) 2935 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, 2 regs"); 2936 } 2937 2938 else if (GET_CODE (arg1) == REG) 2939 reg = arg1, offset = arg0; 2940 else if (CONSTANT_P (arg0) && CONSTANT_P (arg1)) 2941 { 2942 output_addr_const (file, addr); 2943 break; 2944 } 2945 else 2946 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, no regs"); 2947 2948 if (! CONSTANT_P (offset)) 2949 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #2"); 2950 2951 if (REGNO (reg) == ARG_POINTER_REGNUM) 2952 abort_with_insn (addr, "Arg pointer not eliminated."); 2953 2954 output_addr_const (file, offset); 2955 fprintf (file, "(%s)", reg_names [REGNO (reg)]); 2956 } 2957 break; 2958 2959 case LABEL_REF: 2960 case SYMBOL_REF: 2961 case CONST_INT: 2962 case CONST: 2963 output_addr_const (file, addr); 2964 if (GET_CODE (addr) == CONST_INT) 2965 fprintf (file, "(%s)", reg_names [0]); 2966 break; 2967 2968 default: 2969 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, invalid insn #1"); 2970 break; 2971 } 2972} 2973 2974/* A C compound statement to output to stdio stream FILE the 2975 assembler syntax for an instruction operand OP. 2976 2977 LETTER is a value that can be used to specify one of several ways 2978 of printing the operand. It is used when identical operands 2979 must be printed differently depending on the context. LETTER 2980 comes from the `%' specification that was used to request 2981 printing of the operand. If the specification was just `%DIGIT' 2982 then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER 2983 is the ASCII code for LTR. 2984 2985 If OP is a register, this macro should print the register's name. 2986 The names can be found in an array `reg_names' whose type is 2987 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'. 2988 2989 When the machine description has a specification `%PUNCT' (a `%' 2990 followed by a punctuation character), this macro is called with 2991 a null pointer for X and the punctuation character for LETTER. 2992 2993 The IQ2000 specific codes are: 2994 2995 'X' X is CONST_INT, prints upper 16 bits in hexadecimal format = "0x%04x", 2996 'x' X is CONST_INT, prints lower 16 bits in hexadecimal format = "0x%04x", 2997 'd' output integer constant in decimal, 2998 'z' if the operand is 0, use $0 instead of normal operand. 2999 'D' print second part of double-word register or memory operand. 3000 'L' print low-order register of double-word register operand. 3001 'M' print high-order register of double-word register operand. 3002 'C' print part of opcode for a branch condition. 3003 'F' print part of opcode for a floating-point branch condition. 3004 'N' print part of opcode for a branch condition, inverted. 3005 'W' print part of opcode for a floating-point branch condition, inverted. 3006 'A' Print part of opcode for a bit test condition. 3007 'P' Print label for a bit test. 3008 'p' Print log for a bit test. 3009 'B' print 'z' for EQ, 'n' for NE 3010 'b' print 'n' for EQ, 'z' for NE 3011 'T' print 'f' for EQ, 't' for NE 3012 't' print 't' for EQ, 'f' for NE 3013 'Z' print register and a comma, but print nothing for $fcc0 3014 '?' Print 'l' if we are to use a branch likely instead of normal branch. 3015 '@' Print the name of the assembler temporary register (at or $1). 3016 '.' Print the name of the register with a hard-wired zero (zero or $0). 3017 '$' Print the name of the stack pointer register (sp or $29). 3018 '+' Print the name of the gp register (gp or $28). */ 3019 3020void 3021print_operand (FILE *file, rtx op, int letter) 3022{ 3023 enum rtx_code code; 3024 3025 if (PRINT_OPERAND_PUNCT_VALID_P (letter)) 3026 { 3027 switch (letter) 3028 { 3029 case '?': 3030 if (iq2000_branch_likely) 3031 putc ('l', file); 3032 break; 3033 3034 case '@': 3035 fputs (reg_names [GP_REG_FIRST + 1], file); 3036 break; 3037 3038 case '.': 3039 fputs (reg_names [GP_REG_FIRST + 0], file); 3040 break; 3041 3042 case '$': 3043 fputs (reg_names[STACK_POINTER_REGNUM], file); 3044 break; 3045 3046 case '+': 3047 fputs (reg_names[GP_REG_FIRST + 28], file); 3048 break; 3049 3050 default: 3051 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter); 3052 break; 3053 } 3054 3055 return; 3056 } 3057 3058 if (! op) 3059 { 3060 error ("PRINT_OPERAND null pointer"); 3061 return; 3062 } 3063 3064 code = GET_CODE (op); 3065 3066 if (code == SIGN_EXTEND) 3067 op = XEXP (op, 0), code = GET_CODE (op); 3068 3069 if (letter == 'C') 3070 switch (code) 3071 { 3072 case EQ: fputs ("eq", file); break; 3073 case NE: fputs ("ne", file); break; 3074 case GT: fputs ("gt", file); break; 3075 case GE: fputs ("ge", file); break; 3076 case LT: fputs ("lt", file); break; 3077 case LE: fputs ("le", file); break; 3078 case GTU: fputs ("ne", file); break; 3079 case GEU: fputs ("geu", file); break; 3080 case LTU: fputs ("ltu", file); break; 3081 case LEU: fputs ("eq", file); break; 3082 default: 3083 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%C"); 3084 } 3085 3086 else if (letter == 'N') 3087 switch (code) 3088 { 3089 case EQ: fputs ("ne", file); break; 3090 case NE: fputs ("eq", file); break; 3091 case GT: fputs ("le", file); break; 3092 case GE: fputs ("lt", file); break; 3093 case LT: fputs ("ge", file); break; 3094 case LE: fputs ("gt", file); break; 3095 case GTU: fputs ("leu", file); break; 3096 case GEU: fputs ("ltu", file); break; 3097 case LTU: fputs ("geu", file); break; 3098 case LEU: fputs ("gtu", file); break; 3099 default: 3100 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%N"); 3101 } 3102 3103 else if (letter == 'F') 3104 switch (code) 3105 { 3106 case EQ: fputs ("c1f", file); break; 3107 case NE: fputs ("c1t", file); break; 3108 default: 3109 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%F"); 3110 } 3111 3112 else if (letter == 'W') 3113 switch (code) 3114 { 3115 case EQ: fputs ("c1t", file); break; 3116 case NE: fputs ("c1f", file); break; 3117 default: 3118 abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%W"); 3119 } 3120 3121 else if (letter == 'A') 3122 fputs (code == LABEL_REF ? "i" : "in", file); 3123 3124 else if (letter == 'P') 3125 { 3126 if (code == LABEL_REF) 3127 output_addr_const (file, op); 3128 else if (code != PC) 3129 output_operand_lossage ("invalid %%P operand"); 3130 } 3131 3132 else if (letter == 'p') 3133 { 3134 int value; 3135 if (code != CONST_INT 3136 || (value = exact_log2 (INTVAL (op))) < 0) 3137 output_operand_lossage ("invalid %%p value"); 3138 fprintf (file, "%d", value); 3139 } 3140 3141 else if (letter == 'Z') 3142 { 3143 gcc_unreachable (); 3144 } 3145 3146 else if (code == REG || code == SUBREG) 3147 { 3148 int regnum; 3149 3150 if (code == REG) 3151 regnum = REGNO (op); 3152 else 3153 regnum = true_regnum (op); 3154 3155 if ((letter == 'M' && ! WORDS_BIG_ENDIAN) 3156 || (letter == 'L' && WORDS_BIG_ENDIAN) 3157 || letter == 'D') 3158 regnum++; 3159 3160 fprintf (file, "%s", reg_names[regnum]); 3161 } 3162 3163 else if (code == MEM) 3164 { 3165 if (letter == 'D') 3166 output_address (plus_constant (XEXP (op, 0), 4)); 3167 else 3168 output_address (XEXP (op, 0)); 3169 } 3170 3171 else if (code == CONST_DOUBLE 3172 && GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT) 3173 { 3174 char s[60]; 3175 3176 real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (op), sizeof (s), 0, 1); 3177 fputs (s, file); 3178 } 3179 3180 else if (letter == 'x' && GET_CODE (op) == CONST_INT) 3181 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & INTVAL(op)); 3182 3183 else if (letter == 'X' && GET_CODE(op) == CONST_INT) 3184 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & (INTVAL (op) >> 16)); 3185 3186 else if (letter == 'd' && GET_CODE(op) == CONST_INT) 3187 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (INTVAL(op))); 3188 3189 else if (letter == 'z' && GET_CODE (op) == CONST_INT && INTVAL (op) == 0) 3190 fputs (reg_names[GP_REG_FIRST], file); 3191 3192 else if (letter == 'd' || letter == 'x' || letter == 'X') 3193 output_operand_lossage ("invalid use of %%d, %%x, or %%X"); 3194 3195 else if (letter == 'B') 3196 fputs (code == EQ ? "z" : "n", file); 3197 else if (letter == 'b') 3198 fputs (code == EQ ? "n" : "z", file); 3199 else if (letter == 'T') 3200 fputs (code == EQ ? "f" : "t", file); 3201 else if (letter == 't') 3202 fputs (code == EQ ? "t" : "f", file); 3203 3204 else if (code == CONST && GET_CODE (XEXP (op, 0)) == REG) 3205 { 3206 print_operand (file, XEXP (op, 0), letter); 3207 } 3208 3209 else 3210 output_addr_const (file, op); 3211} 3212 3213static bool 3214iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int * total) 3215{ 3216 enum machine_mode mode = GET_MODE (x); 3217 3218 switch (code) 3219 { 3220 case MEM: 3221 { 3222 int num_words = (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1; 3223 3224 if (simple_memory_operand (x, mode)) 3225 return COSTS_N_INSNS (num_words); 3226 3227 * total = COSTS_N_INSNS (2 * num_words); 3228 break; 3229 } 3230 3231 case FFS: 3232 * total = COSTS_N_INSNS (6); 3233 break; 3234 3235 case AND: 3236 case IOR: 3237 case XOR: 3238 case NOT: 3239 * total = COSTS_N_INSNS (mode == DImode ? 2 : 1); 3240 break; 3241 3242 case ASHIFT: 3243 case ASHIFTRT: 3244 case LSHIFTRT: 3245 if (mode == DImode) 3246 * total = COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT) ? 4 : 12); 3247 else 3248 * total = COSTS_N_INSNS (1); 3249 break; 3250 3251 case ABS: 3252 if (mode == SFmode || mode == DFmode) 3253 * total = COSTS_N_INSNS (1); 3254 else 3255 * total = COSTS_N_INSNS (4); 3256 break; 3257 3258 case PLUS: 3259 case MINUS: 3260 if (mode == SFmode || mode == DFmode) 3261 * total = COSTS_N_INSNS (6); 3262 else if (mode == DImode) 3263 * total = COSTS_N_INSNS (4); 3264 else 3265 * total = COSTS_N_INSNS (1); 3266 break; 3267 3268 case NEG: 3269 * total = (mode == DImode) ? 4 : 1; 3270 break; 3271 3272 case MULT: 3273 if (mode == SFmode) 3274 * total = COSTS_N_INSNS (7); 3275 else if (mode == DFmode) 3276 * total = COSTS_N_INSNS (8); 3277 else 3278 * total = COSTS_N_INSNS (10); 3279 break; 3280 3281 case DIV: 3282 case MOD: 3283 if (mode == SFmode) 3284 * total = COSTS_N_INSNS (23); 3285 else if (mode == DFmode) 3286 * total = COSTS_N_INSNS (36); 3287 else 3288 * total = COSTS_N_INSNS (69); 3289 break; 3290 3291 case UDIV: 3292 case UMOD: 3293 * total = COSTS_N_INSNS (69); 3294 break; 3295 3296 case SIGN_EXTEND: 3297 * total = COSTS_N_INSNS (2); 3298 break; 3299 3300 case ZERO_EXTEND: 3301 * total = COSTS_N_INSNS (1); 3302 break; 3303 3304 case CONST_INT: 3305 * total = 0; 3306 break; 3307 3308 case LABEL_REF: 3309 * total = COSTS_N_INSNS (2); 3310 break; 3311 3312 case CONST: 3313 { 3314 rtx offset = const0_rtx; 3315 rtx symref = eliminate_constant_term (XEXP (x, 0), & offset); 3316 3317 if (GET_CODE (symref) == LABEL_REF) 3318 * total = COSTS_N_INSNS (2); 3319 else if (GET_CODE (symref) != SYMBOL_REF) 3320 * total = COSTS_N_INSNS (4); 3321 /* Let's be paranoid.... */ 3322 else if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767) 3323 * total = COSTS_N_INSNS (2); 3324 else 3325 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (symref) ? 1 : 2); 3326 break; 3327 } 3328 3329 case SYMBOL_REF: 3330 * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (x) ? 1 : 2); 3331 break; 3332 3333 case CONST_DOUBLE: 3334 { 3335 rtx high, low; 3336 3337 split_double (x, & high, & low); 3338 3339 * total = COSTS_N_INSNS ( (high == CONST0_RTX (GET_MODE (high)) 3340 || low == CONST0_RTX (GET_MODE (low))) 3341 ? 2 : 4); 3342 break; 3343 } 3344 3345 default: 3346 return false; 3347 } 3348 return true; 3349} 3350 3351#include "gt-iq2000.h" 3352