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