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