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