1 /* Subroutines for insn-output.c for MIPS 2 Contributed by A. Lichnewsky, lich@inria.inria.fr. 3 Changes by Michael Meissner, meissner@osf.org. 4 Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc. 5 6 This file is part of GNU CC. 7 8 GNU CC is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2, or (at your option) 11 any later version. 12 13 GNU CC is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with GNU CC; see the file COPYING. If not, write to 20 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 21 22 #include "config.h" 23 #include "rtl.h" 24 #include "regs.h" 25 #include "hard-reg-set.h" 26 #include "real.h" 27 #include "insn-config.h" 28 #include "conditions.h" 29 #include "insn-flags.h" 30 #include "insn-attr.h" 31 #include "insn-codes.h" 32 #include "recog.h" 33 #include "output.h" 34 35 #undef MAX /* sys/param.h may also define these */ 36 #undef MIN 37 38 #include <stdio.h> 39 #include <signal.h> 40 #include <sys/types.h> 41 #include <sys/file.h> 42 #include <ctype.h> 43 #include "tree.h" 44 #include "expr.h" 45 #include "flags.h" 46 47 #ifndef R_OK 48 #define R_OK 4 49 #define W_OK 2 50 #define X_OK 1 51 #endif 52 53 #if defined(USG) || defined(NO_STAB_H) 54 #include "gstab.h" /* If doing DBX on sysV, use our own stab.h. */ 55 #else 56 #include <stab.h> /* On BSD, use the system's stab.h. */ 57 #endif /* not USG */ 58 59 #ifdef __GNU_STAB__ 60 #define STAB_CODE_TYPE enum __stab_debug_code 61 #else 62 #define STAB_CODE_TYPE int 63 #endif 64 65 extern void abort (); 66 extern int atoi (); 67 extern char *getenv (); 68 extern char *mktemp (); 69 70 extern rtx adj_offsettable_operand (); 71 extern rtx copy_to_reg (); 72 extern void error (); 73 extern void fatal (); 74 extern tree lookup_name (); 75 extern void pfatal_with_name (); 76 extern void warning (); 77 78 extern tree current_function_decl; 79 extern FILE *asm_out_file; 80 81 /* Enumeration for all of the relational tests, so that we can build 82 arrays indexed by the test type, and not worry about the order 83 of EQ, NE, etc. */ 84 85 enum internal_test { 86 ITEST_EQ, 87 ITEST_NE, 88 ITEST_GT, 89 ITEST_GE, 90 ITEST_LT, 91 ITEST_LE, 92 ITEST_GTU, 93 ITEST_GEU, 94 ITEST_LTU, 95 ITEST_LEU, 96 ITEST_MAX 97 }; 98 99 /* Global variables for machine-dependent things. */ 100 101 /* Threshold for data being put into the small data/bss area, instead 102 of the normal data area (references to the small data/bss area take 103 1 instruction, and use the global pointer, references to the normal 104 data area takes 2 instructions). */ 105 int mips_section_threshold = -1; 106 107 /* Count the number of .file directives, so that .loc is up to date. */ 108 int num_source_filenames = 0; 109 110 /* Count the number of sdb related labels are generated (to find block 111 start and end boundaries). */ 112 int sdb_label_count = 0; 113 114 /* Non-zero if inside of a function, because the stupid MIPS asm can't 115 handle .files inside of functions. */ 116 int inside_function = 0; 117 118 /* Files to separate the text and the data output, so that all of the data 119 can be emitted before the text, which will mean that the assembler will 120 generate smaller code, based on the global pointer. */ 121 FILE *asm_out_data_file; 122 FILE *asm_out_text_file; 123 124 /* Linked list of all externals that are to be emitted when optimizing 125 for the global pointer if they haven't been declared by the end of 126 the program with an appropriate .comm or initialization. */ 127 128 struct extern_list { 129 struct extern_list *next; /* next external */ 130 char *name; /* name of the external */ 131 int size; /* size in bytes */ 132 } *extern_head = 0; 133 134 /* Name of the file containing the current function. */ 135 char *current_function_file = ""; 136 137 /* Warning given that Mips ECOFF can't support changing files 138 within a function. */ 139 int file_in_function_warning = FALSE; 140 141 /* Whether to suppress issuing .loc's because the user attempted 142 to change the filename within a function. */ 143 int ignore_line_number = FALSE; 144 145 /* Number of nested .set noreorder, noat, nomacro, and volatile requests. */ 146 int set_noreorder; 147 int set_noat; 148 int set_nomacro; 149 int set_volatile; 150 151 /* The next branch instruction is a branch likely, not branch normal. */ 152 int mips_branch_likely; 153 154 /* Count of delay slots and how many are filled. */ 155 int dslots_load_total; 156 int dslots_load_filled; 157 int dslots_jump_total; 158 int dslots_jump_filled; 159 160 /* # of nops needed by previous insn */ 161 int dslots_number_nops; 162 163 /* Number of 1/2/3 word references to data items (ie, not jal's). */ 164 int num_refs[3]; 165 166 /* registers to check for load delay */ 167 rtx mips_load_reg, mips_load_reg2, mips_load_reg3, mips_load_reg4; 168 169 /* Cached operands, and operator to compare for use in set/branch on 170 condition codes. */ 171 rtx branch_cmp[2]; 172 173 /* what type of branch to use */ 174 enum cmp_type branch_type; 175 176 /* Number of previously seen half-pic pointers and references. */ 177 static int prev_half_pic_ptrs = 0; 178 static int prev_half_pic_refs = 0; 179 180 /* which cpu are we scheduling for */ 181 enum processor_type mips_cpu; 182 183 /* which instruction set architecture to use. */ 184 int mips_isa; 185 186 /* Strings to hold which cpu and instruction set architecture to use. */ 187 char *mips_cpu_string; /* for -mcpu=<xxx> */ 188 char *mips_isa_string; /* for -mips{1,2,3} */ 189 190 /* Array to RTX class classification. At present, we care about 191 whether the operator is an add-type operator, or a divide/modulus, 192 and if divide/modulus, whether it is unsigned. This is for the 193 peephole code. */ 194 char mips_rtx_classify[NUM_RTX_CODE]; 195 196 /* Array giving truth value on whether or not a given hard register 197 can support a given mode. */ 198 char mips_hard_regno_mode_ok[(int)MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER]; 199 200 /* Current frame information calculated by compute_frame_size. */ 201 struct mips_frame_info current_frame_info; 202 203 /* Zero structure to initialize current_frame_info. */ 204 struct mips_frame_info zero_frame_info; 205 206 /* Temporary filename used to buffer .text until end of program 207 for -mgpopt. */ 208 static char *temp_filename; 209 210 /* List of all MIPS punctuation characters used by print_operand. */ 211 char mips_print_operand_punct[256]; 212 213 /* Map GCC register number to debugger register number. */ 214 int mips_dbx_regno[FIRST_PSEUDO_REGISTER]; 215 216 /* Buffer to use to enclose a load/store operation with %{ %} to 217 turn on .set volatile. */ 218 static char volatile_buffer[60]; 219 220 /* Hardware names for the registers. If -mrnames is used, this 221 will be overwritten with mips_sw_reg_names. */ 222 223 char mips_reg_names[][8] = 224 { 225 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", 226 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", 227 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", 228 "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31", 229 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", 230 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", 231 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", 232 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", 233 "hi", "lo", "$fcr31" 234 }; 235 236 /* Mips software names for the registers, used to overwrite the 237 mips_reg_names array. */ 238 239 char mips_sw_reg_names[][8] = 240 { 241 "$0", "at", "v0", "v1", "a0", "a1", "a2", "a3", 242 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", 243 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 244 "t8", "t9", "k0", "k1", "gp", "sp", "$fp", "ra", 245 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", 246 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", 247 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", 248 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", 249 "hi", "lo", "$fcr31" 250 }; 251 252 /* Map hard register number to register class */ 253 enum reg_class mips_regno_to_class[] = 254 { 255 GR_REGS, GR_REGS, GR_REGS, GR_REGS, 256 GR_REGS, GR_REGS, GR_REGS, GR_REGS, 257 GR_REGS, GR_REGS, GR_REGS, GR_REGS, 258 GR_REGS, GR_REGS, GR_REGS, GR_REGS, 259 GR_REGS, GR_REGS, GR_REGS, GR_REGS, 260 GR_REGS, GR_REGS, GR_REGS, GR_REGS, 261 GR_REGS, GR_REGS, GR_REGS, GR_REGS, 262 GR_REGS, GR_REGS, GR_REGS, GR_REGS, 263 FP_REGS, FP_REGS, FP_REGS, FP_REGS, 264 FP_REGS, FP_REGS, FP_REGS, FP_REGS, 265 FP_REGS, FP_REGS, FP_REGS, FP_REGS, 266 FP_REGS, FP_REGS, FP_REGS, FP_REGS, 267 FP_REGS, FP_REGS, FP_REGS, FP_REGS, 268 FP_REGS, FP_REGS, FP_REGS, FP_REGS, 269 FP_REGS, FP_REGS, FP_REGS, FP_REGS, 270 FP_REGS, FP_REGS, FP_REGS, FP_REGS, 271 HI_REG, LO_REG, ST_REGS 272 }; 273 274 /* Map register constraint character to register class. */ 275 enum reg_class mips_char_to_class[256] = 276 { 277 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 278 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 279 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 280 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 281 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 282 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 283 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 284 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 285 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 286 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 287 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 288 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 289 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 290 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 291 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 292 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 293 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 294 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 295 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 296 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 297 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 298 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 299 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 300 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 301 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 302 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 303 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 304 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 305 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 306 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 307 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 308 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 309 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 310 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 311 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 312 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 313 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 314 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 315 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 316 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 317 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 318 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 319 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 320 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 321 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 322 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 323 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 324 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 325 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 326 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 327 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 328 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 329 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 330 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 331 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 332 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 333 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 334 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 335 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 336 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 337 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 338 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 339 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 340 NO_REGS, NO_REGS, NO_REGS, NO_REGS, 341 }; 342 343 344 /* Return truth value of whether OP can be used as an operands 345 where a register or 16 bit unsigned integer is needed. */ 346 347 int 348 uns_arith_operand (op, mode) 349 rtx op; 350 enum machine_mode mode; 351 { 352 if (GET_CODE (op) == CONST_INT && SMALL_INT_UNSIGNED (op)) 353 return TRUE; 354 355 return register_operand (op, mode); 356 } 357 358 /* Return truth value of whether OP can be used as an operands 359 where a 16 bit integer is needed */ 360 361 int 362 arith_operand (op, mode) 363 rtx op; 364 enum machine_mode mode; 365 { 366 if (GET_CODE (op) == CONST_INT && SMALL_INT (op)) 367 return TRUE; 368 369 return register_operand (op, mode); 370 } 371 372 /* Return truth value of whether OP can be used as an operand in a two 373 address arithmetic insn (such as set 123456,%o4) of mode MODE. */ 374 375 int 376 arith32_operand (op, mode) 377 rtx op; 378 enum machine_mode mode; 379 { 380 if (GET_CODE (op) == CONST_INT) 381 return TRUE; 382 383 return register_operand (op, mode); 384 } 385 386 /* Return truth value of whether OP is a integer which fits in 16 bits */ 387 388 int 389 small_int (op, mode) 390 rtx op; 391 enum machine_mode mode; 392 { 393 return (GET_CODE (op) == CONST_INT && SMALL_INT (op)); 394 } 395 396 /* Return truth value of whether OP is an integer which is too big to 397 be loaded with one instruction. */ 398 399 int 400 large_int (op, mode) 401 rtx op; 402 enum machine_mode mode; 403 { 404 HOST_WIDE_INT value; 405 406 if (GET_CODE (op) != CONST_INT) 407 return FALSE; 408 409 value = INTVAL (op); 410 if ((value & ~0x0000ffff) == 0) /* ior reg,$r0,value */ 411 return FALSE; 412 413 if (((unsigned long)(value + 32768)) <= 32767) /* subu reg,$r0,value */ 414 return FALSE; 415 416 if ((value & 0xffff0000) == value) /* lui reg,value>>16 */ 417 return FALSE; 418 419 return TRUE; 420 } 421 422 /* Return truth value of whether OP is a register or the constant 0. */ 423 424 int 425 reg_or_0_operand (op, mode) 426 rtx op; 427 enum machine_mode mode; 428 { 429 switch (GET_CODE (op)) 430 { 431 default: 432 break; 433 434 case CONST_INT: 435 return (INTVAL (op) == 0); 436 437 case CONST_DOUBLE: 438 if (CONST_DOUBLE_HIGH (op) != 0 || CONST_DOUBLE_LOW (op) != 0) 439 return FALSE; 440 441 return TRUE; 442 443 case REG: 444 case SUBREG: 445 return register_operand (op, mode); 446 } 447 448 return FALSE; 449 } 450 451 /* Return truth value of whether OP is one of the special multiply/divide 452 registers (hi, lo). */ 453 454 int 455 md_register_operand (op, mode) 456 rtx op; 457 enum machine_mode mode; 458 { 459 return (GET_MODE_CLASS (mode) == MODE_INT 460 && GET_CODE (op) == REG 461 && MD_REG_P (REGNO (op))); 462 } 463 464 /* Return truth value of whether OP is the FP status register. */ 465 466 int 467 fpsw_register_operand (op, mode) 468 rtx op; 469 enum machine_mode mode; 470 { 471 return (GET_CODE (op) == REG && ST_REG_P (REGNO (op))); 472 } 473 474 /* Return truth value if a CONST_DOUBLE is ok to be a legitimate constant. */ 475 476 int 477 mips_const_double_ok (op, mode) 478 rtx op; 479 enum machine_mode mode; 480 { 481 if (GET_CODE (op) != CONST_DOUBLE) 482 return FALSE; 483 484 if (mode == DImode) 485 return TRUE; 486 487 if (mode != SFmode && mode != DFmode) 488 return FALSE; 489 490 if (CONST_DOUBLE_HIGH (op) == 0 && CONST_DOUBLE_LOW (op) == 0) 491 return TRUE; 492 493 #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT 494 if (TARGET_MIPS_AS) /* gas doesn't like li.d/li.s yet */ 495 { 496 union { double d; int i[2]; } u; 497 double d; 498 499 u.i[0] = CONST_DOUBLE_LOW (op); 500 u.i[1] = CONST_DOUBLE_HIGH (op); 501 d = u.d; 502 503 if (d != d) 504 return FALSE; /* NAN */ 505 506 if (d < 0.0) 507 d = - d; 508 509 /* Rather than trying to get the accuracy down to the last bit, 510 just use approximate ranges. */ 511 512 if (mode == DFmode && d > 1.0e-300 && d < 1.0e300) 513 return TRUE; 514 515 if (mode == SFmode && d > 1.0e-38 && d < 1.0e+38) 516 return TRUE; 517 } 518 #endif 519 520 return FALSE; 521 } 522 523 /* Return truth value if a memory operand fits in a single instruction 524 (ie, register + small offset). */ 525 526 int 527 simple_memory_operand (op, mode) 528 rtx op; 529 enum machine_mode mode; 530 { 531 rtx addr, plus0, plus1; 532 533 /* Eliminate non-memory operations */ 534 if (GET_CODE (op) != MEM) 535 return FALSE; 536 537 /* dword operations really put out 2 instructions, so eliminate them. */ 538 if (GET_MODE_SIZE (GET_MODE (op)) > (HAVE_64BIT_P () ? 8 : 4)) 539 return FALSE; 540 541 /* Decode the address now. */ 542 addr = XEXP (op, 0); 543 switch (GET_CODE (addr)) 544 { 545 default: 546 break; 547 548 case REG: 549 return TRUE; 550 551 case CONST_INT: 552 return SMALL_INT (op); 553 554 case PLUS: 555 plus0 = XEXP (addr, 0); 556 plus1 = XEXP (addr, 1); 557 if (GET_CODE (plus0) == REG 558 && GET_CODE (plus1) == CONST_INT 559 && SMALL_INT (plus1)) 560 return TRUE; 561 562 else if (GET_CODE (plus1) == REG 563 && GET_CODE (plus0) == CONST_INT 564 && SMALL_INT (plus0)) 565 return TRUE; 566 567 else 568 return FALSE; 569 570 #if 0 571 /* We used to allow small symbol refs here (ie, stuff in .sdata 572 or .sbss), but this causes some bugs in G++. Also, it won't 573 interfere if the MIPS linker rewrites the store instruction 574 because the function is PIC. */ 575 576 case LABEL_REF: /* never gp relative */ 577 break; 578 579 case CONST: 580 /* If -G 0, we can never have a GP relative memory operation. 581 Also, save some time if not optimizing. */ 582 if (mips_section_threshold == 0 || !optimize || !TARGET_GP_OPT) 583 return FALSE; 584 585 { 586 rtx offset = const0_rtx; 587 addr = eliminate_constant_term (addr, &offset); 588 if (GET_CODE (op) != SYMBOL_REF) 589 return FALSE; 590 591 /* let's be paranoid.... */ 592 if (INTVAL (offset) < 0 || INTVAL (offset) > 0xffff) 593 return FALSE; 594 } 595 /* fall through */ 596 597 case SYMBOL_REF: 598 return SYMBOL_REF_FLAG (addr); 599 #endif 600 } 601 602 return FALSE; 603 } 604 605 /* Return true if the code of this rtx pattern is EQ or NE. */ 606 607 int 608 equality_op (op, mode) 609 rtx op; 610 enum machine_mode mode; 611 { 612 if (mode != GET_MODE (op)) 613 return FALSE; 614 615 return (classify_op (op, mode) & CLASS_EQUALITY_OP) != 0; 616 } 617 618 /* Return true if the code is a relational operations (EQ, LE, etc.) */ 619 620 int 621 cmp_op (op, mode) 622 rtx op; 623 enum machine_mode mode; 624 { 625 if (mode != GET_MODE (op)) 626 return FALSE; 627 628 return (classify_op (op, mode) & CLASS_CMP_OP) != 0; 629 } 630 631 632 /* Genrecog does not take the type of match_operator into consideration, 633 and would complain about two patterns being the same if the same 634 function is used, so make it believe they are different. */ 635 636 int 637 cmp2_op (op, mode) 638 rtx op; 639 enum machine_mode mode; 640 { 641 if (mode != GET_MODE (op)) 642 return FALSE; 643 644 return (classify_op (op, mode) & CLASS_CMP_OP) != 0; 645 } 646 647 /* Return true if the code is an unsigned relational operations (LEU, etc.) */ 648 649 int 650 uns_cmp_op (op,mode) 651 rtx op; 652 enum machine_mode mode; 653 { 654 if (mode != GET_MODE (op)) 655 return FALSE; 656 657 return (classify_op (op, mode) & CLASS_UNS_CMP_OP) == CLASS_UNS_CMP_OP; 658 } 659 660 /* Return true if the code is a relational operation FP can use. */ 661 662 int 663 fcmp_op (op, mode) 664 rtx op; 665 enum machine_mode mode; 666 { 667 if (mode != GET_MODE (op)) 668 return FALSE; 669 670 return (classify_op (op, mode) & CLASS_FCMP_OP) != 0; 671 } 672 673 674 /* Return true if the operand is either the PC or a label_ref. */ 675 676 int 677 pc_or_label_operand (op, mode) 678 rtx op; 679 enum machine_mode mode; 680 { 681 if (op == pc_rtx) 682 return TRUE; 683 684 if (GET_CODE (op) == LABEL_REF) 685 return TRUE; 686 687 return FALSE; 688 } 689 690 691 /* Return an operand string if the given instruction's delay slot or 692 wrap it in a .set noreorder section. This is for filling delay 693 slots on load type instructions under GAS, which does no reordering 694 on its own. For the MIPS assembler, all we do is update the filled 695 delay slot statistics. 696 697 We assume that operands[0] is the target register that is set. 698 699 In order to check the next insn, most of this functionality is moved 700 to FINAL_PRESCAN_INSN, and we just set the global variables that 701 it needs. */ 702 703 char * 704 mips_fill_delay_slot (ret, type, operands, cur_insn) 705 char *ret; /* normal string to return */ 706 enum delay_type type; /* type of delay */ 707 rtx operands[]; /* operands to use */ 708 rtx cur_insn; /* current insn */ 709 { 710 register rtx set_reg; 711 register enum machine_mode mode; 712 register rtx next_insn = (cur_insn) ? NEXT_INSN (cur_insn) : (rtx)0; 713 register int num_nops; 714 715 if (type == DELAY_LOAD || type == DELAY_FCMP) 716 num_nops = 1; 717 718 else if (type == DELAY_HILO) 719 num_nops = 2; 720 721 else 722 num_nops = 0; 723 724 /* Make sure that we don't put nop's after labels. */ 725 next_insn = NEXT_INSN (cur_insn); 726 while (next_insn != (rtx)0 && GET_CODE (next_insn) == NOTE) 727 next_insn = NEXT_INSN (next_insn); 728 729 dslots_load_total += num_nops; 730 if (TARGET_DEBUG_F_MODE 731 || !optimize 732 || type == DELAY_NONE 733 || operands == (rtx *)0 734 || cur_insn == (rtx)0 735 || next_insn == (rtx)0 736 || GET_CODE (next_insn) == CODE_LABEL 737 || (set_reg = operands[0]) == (rtx)0) 738 { 739 dslots_number_nops = 0; 740 mips_load_reg = (rtx)0; 741 mips_load_reg2 = (rtx)0; 742 mips_load_reg3 = (rtx)0; 743 mips_load_reg4 = (rtx)0; 744 return ret; 745 } 746 747 set_reg = operands[0]; 748 if (set_reg == (rtx)0) 749 return ret; 750 751 while (GET_CODE (set_reg) == SUBREG) 752 set_reg = SUBREG_REG (set_reg); 753 754 mode = GET_MODE (set_reg); 755 dslots_number_nops = num_nops; 756 mips_load_reg = set_reg; 757 mips_load_reg2 = (mode == DImode || mode == DFmode) 758 ? gen_rtx (REG, SImode, REGNO (set_reg) + 1) 759 : (rtx)0; 760 761 if (type == DELAY_HILO) 762 { 763 mips_load_reg3 = gen_rtx (REG, SImode, MD_REG_FIRST); 764 mips_load_reg4 = gen_rtx (REG, SImode, MD_REG_FIRST+1); 765 } 766 else 767 { 768 mips_load_reg3 = 0; 769 mips_load_reg4 = 0; 770 } 771 772 if (TARGET_GAS && set_noreorder++ == 0) 773 fputs ("\t.set\tnoreorder\n", asm_out_file); 774 775 return ret; 776 } 777 778 779 /* Determine whether a memory reference takes one (based off of the GP pointer), 780 two (normal), or three (label + reg) instructions, and bump the appropriate 781 counter for -mstats. */ 782 783 void 784 mips_count_memory_refs (op, num) 785 rtx op; 786 int num; 787 { 788 int additional = 0; 789 int n_words = 0; 790 rtx addr, plus0, plus1; 791 enum rtx_code code0, code1; 792 int looping; 793 794 if (TARGET_DEBUG_B_MODE) 795 { 796 fprintf (stderr, "\n========== mips_count_memory_refs:\n"); 797 debug_rtx (op); 798 } 799 800 /* Skip MEM if passed, otherwise handle movsi of address. */ 801 addr = (GET_CODE (op) != MEM) ? op : XEXP (op, 0); 802 803 /* Loop, going through the address RTL */ 804 do 805 { 806 looping = FALSE; 807 switch (GET_CODE (addr)) 808 { 809 default: 810 break; 811 812 case REG: 813 case CONST_INT: 814 break; 815 816 case PLUS: 817 plus0 = XEXP (addr, 0); 818 plus1 = XEXP (addr, 1); 819 code0 = GET_CODE (plus0); 820 code1 = GET_CODE (plus1); 821 822 if (code0 == REG) 823 { 824 additional++; 825 addr = plus1; 826 looping = TRUE; 827 continue; 828 } 829 830 if (code0 == CONST_INT) 831 { 832 addr = plus1; 833 looping = TRUE; 834 continue; 835 } 836 837 if (code1 == REG) 838 { 839 additional++; 840 addr = plus0; 841 looping = TRUE; 842 continue; 843 } 844 845 if (code1 == CONST_INT) 846 { 847 addr = plus0; 848 looping = TRUE; 849 continue; 850 } 851 852 if (code0 == SYMBOL_REF || code0 == LABEL_REF || code0 == CONST) 853 { 854 addr = plus0; 855 looping = TRUE; 856 continue; 857 } 858 859 if (code1 == SYMBOL_REF || code1 == LABEL_REF || code1 == CONST) 860 { 861 addr = plus1; 862 looping = TRUE; 863 continue; 864 } 865 866 break; 867 868 case LABEL_REF: 869 n_words = 2; /* always 2 words */ 870 break; 871 872 case CONST: 873 addr = XEXP (addr, 0); 874 looping = TRUE; 875 continue; 876 877 case SYMBOL_REF: 878 n_words = SYMBOL_REF_FLAG (addr) ? 1 : 2; 879 break; 880 } 881 } 882 while (looping); 883 884 if (n_words == 0) 885 return; 886 887 n_words += additional; 888 if (n_words > 3) 889 n_words = 3; 890 891 num_refs[n_words-1] += num; 892 } 893 894 895 /* Return the appropriate instructions to move one operand to another. */ 896 897 char * 898 mips_move_1word (operands, insn, unsignedp) 899 rtx operands[]; 900 rtx insn; 901 int unsignedp; 902 { 903 char *ret = 0; 904 rtx op0 = operands[0]; 905 rtx op1 = operands[1]; 906 enum rtx_code code0 = GET_CODE (op0); 907 enum rtx_code code1 = GET_CODE (op1); 908 enum machine_mode mode = GET_MODE (op0); 909 int subreg_word0 = 0; 910 int subreg_word1 = 0; 911 enum delay_type delay = DELAY_NONE; 912 913 while (code0 == SUBREG) 914 { 915 subreg_word0 += SUBREG_WORD (op0); 916 op0 = SUBREG_REG (op0); 917 code0 = GET_CODE (op0); 918 } 919 920 while (code1 == SUBREG) 921 { 922 subreg_word1 += SUBREG_WORD (op1); 923 op1 = SUBREG_REG (op1); 924 code1 = GET_CODE (op1); 925 } 926 927 if (code0 == REG) 928 { 929 int regno0 = REGNO (op0) + subreg_word0; 930 931 if (code1 == REG) 932 { 933 int regno1 = REGNO (op1) + subreg_word1; 934 935 /* Just in case, don't do anything for assigning a register 936 to itself, unless we are filling a delay slot. */ 937 if (regno0 == regno1 && set_nomacro == 0) 938 ret = ""; 939 940 else if (GP_REG_P (regno0)) 941 { 942 if (GP_REG_P (regno1)) 943 ret = "move\t%0,%1"; 944 945 else if (MD_REG_P (regno1)) 946 { 947 delay = DELAY_HILO; 948 ret = "mf%1\t%0"; 949 } 950 951 else 952 { 953 delay = DELAY_LOAD; 954 if (FP_REG_P (regno1)) 955 ret = "mfc1\t%0,%1"; 956 957 else if (regno1 == FPSW_REGNUM) 958 ret = "cfc1\t%0,$31"; 959 } 960 } 961 962 else if (FP_REG_P (regno0)) 963 { 964 if (GP_REG_P (regno1)) 965 { 966 delay = DELAY_LOAD; 967 ret = "mtc1\t%1,%0"; 968 } 969 970 if (FP_REG_P (regno1)) 971 ret = "mov.s\t%0,%1"; 972 } 973 974 else if (MD_REG_P (regno0)) 975 { 976 if (GP_REG_P (regno1)) 977 { 978 delay = DELAY_HILO; 979 ret = "mt%0\t%1"; 980 } 981 } 982 983 else if (regno0 == FPSW_REGNUM) 984 { 985 if (GP_REG_P (regno1)) 986 { 987 delay = DELAY_LOAD; 988 ret = "ctc1\t%0,$31"; 989 } 990 } 991 } 992 993 else if (code1 == MEM) 994 { 995 delay = DELAY_LOAD; 996 997 if (TARGET_STATS) 998 mips_count_memory_refs (op1, 1); 999 1000 if (GP_REG_P (regno0)) 1001 { 1002 /* For loads, use the mode of the memory item, instead of the 1003 target, so zero/sign extend can use this code as well. */ 1004 switch (GET_MODE (op1)) 1005 { 1006 default: break; 1007 case SFmode: ret = "lw\t%0,%1"; break; 1008 case SImode: ret = "lw\t%0,%1"; break; 1009 case HImode: ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1"; break; 1010 case QImode: ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1"; break; 1011 } 1012 } 1013 1014 else if (FP_REG_P (regno0) && (mode == SImode || mode == SFmode)) 1015 ret = "l.s\t%0,%1"; 1016 1017 if (ret != (char *)0 && MEM_VOLATILE_P (op1)) 1018 { 1019 int i = strlen (ret); 1020 if (i > sizeof (volatile_buffer) - sizeof ("%{%}")) 1021 abort (); 1022 1023 sprintf (volatile_buffer, "%%{%s%%}", ret); 1024 ret = volatile_buffer; 1025 } 1026 } 1027 1028 else if (code1 == CONST_INT) 1029 { 1030 if (INTVAL (op1) == 0) 1031 { 1032 if (GP_REG_P (regno0)) 1033 ret = "move\t%0,%z1"; 1034 1035 else if (FP_REG_P (regno0)) 1036 { 1037 delay = DELAY_LOAD; 1038 ret = "mtc1\t%z1,%0"; 1039 } 1040 } 1041 1042 else if (GP_REG_P (regno0)) 1043 ret = (INTVAL (op1) < 0) ? "li\t%0,%1\t\t\t# %X1" : "li\t%0,%X1\t\t# %1"; 1044 } 1045 1046 else if (code1 == CONST_DOUBLE && mode == SFmode) 1047 { 1048 if (CONST_DOUBLE_HIGH (op1) == 0 && CONST_DOUBLE_LOW (op1) == 0) 1049 { 1050 if (GP_REG_P (regno0)) 1051 ret = "move\t%0,%."; 1052 1053 else if (FP_REG_P (regno0)) 1054 { 1055 delay = DELAY_LOAD; 1056 ret = "mtc1\t%.,%0"; 1057 } 1058 } 1059 1060 else 1061 { 1062 delay = DELAY_LOAD; 1063 ret = "li.s\t%0,%1"; 1064 } 1065 } 1066 1067 else if (code1 == LABEL_REF) 1068 { 1069 if (TARGET_STATS) 1070 mips_count_memory_refs (op1, 1); 1071 1072 ret = "la\t%0,%a1"; 1073 } 1074 1075 else if (code1 == SYMBOL_REF || code1 == CONST) 1076 { 1077 if (HALF_PIC_P () && CONSTANT_P (op1) && HALF_PIC_ADDRESS_P (op1)) 1078 { 1079 rtx offset = const0_rtx; 1080 1081 if (GET_CODE (op1) == CONST) 1082 op1 = eliminate_constant_term (XEXP (op1, 0), &offset); 1083 1084 if (GET_CODE (op1) == SYMBOL_REF) 1085 { 1086 operands[2] = HALF_PIC_PTR (op1); 1087 1088 if (TARGET_STATS) 1089 mips_count_memory_refs (operands[2], 1); 1090 1091 if (INTVAL (offset) == 0) 1092 { 1093 delay = DELAY_LOAD; 1094 ret = "lw\t%0,%2"; 1095 } 1096 else 1097 { 1098 dslots_load_total++; 1099 operands[3] = offset; 1100 ret = (SMALL_INT (offset)) 1101 ? "lw\t%0,%2%#\n\tadd\t%0,%0,%3" 1102 : "lw\t%0,%2%#\n\t%[li\t%@,%3\n\tadd\t%0,%0,%@%]"; 1103 } 1104 } 1105 } 1106 else 1107 { 1108 if (TARGET_STATS) 1109 mips_count_memory_refs (op1, 1); 1110 1111 ret = "la\t%0,%a1"; 1112 } 1113 } 1114 1115 else if (code1 == PLUS) 1116 { 1117 rtx add_op0 = XEXP (op1, 0); 1118 rtx add_op1 = XEXP (op1, 1); 1119 1120 if (GET_CODE (XEXP (op1, 1)) == REG && GET_CODE (XEXP (op1, 0)) == CONST_INT) 1121 { 1122 add_op0 = XEXP (op1, 1); /* reverse operands */ 1123 add_op1 = XEXP (op1, 0); 1124 } 1125 1126 operands[2] = add_op0; 1127 operands[3] = add_op1; 1128 ret = "add%:\t%0,%2,%3"; 1129 } 1130 } 1131 1132 else if (code0 == MEM) 1133 { 1134 if (TARGET_STATS) 1135 mips_count_memory_refs (op0, 1); 1136 1137 if (code1 == REG) 1138 { 1139 int regno1 = REGNO (op1) + subreg_word1; 1140 1141 if (GP_REG_P (regno1)) 1142 { 1143 switch (mode) 1144 { 1145 default: break; 1146 case SFmode: ret = "sw\t%1,%0"; break; 1147 case SImode: ret = "sw\t%1,%0"; break; 1148 case HImode: ret = "sh\t%1,%0"; break; 1149 case QImode: ret = "sb\t%1,%0"; break; 1150 } 1151 } 1152 1153 else if (FP_REG_P (regno1) && (mode == SImode || mode == SFmode)) 1154 ret = "s.s\t%1,%0"; 1155 } 1156 1157 else if (code1 == CONST_INT && INTVAL (op1) == 0) 1158 { 1159 switch (mode) 1160 { 1161 default: break; 1162 case SFmode: ret = "sw\t%z1,%0"; break; 1163 case SImode: ret = "sw\t%z1,%0"; break; 1164 case HImode: ret = "sh\t%z1,%0"; break; 1165 case QImode: ret = "sb\t%z1,%0"; break; 1166 } 1167 } 1168 1169 else if (code1 == CONST_DOUBLE && CONST_DOUBLE_HIGH (op1) == 0 && CONST_DOUBLE_LOW (op1) == 0) 1170 { 1171 switch (mode) 1172 { 1173 default: break; 1174 case SFmode: ret = "sw\t%.,%0"; break; 1175 case SImode: ret = "sw\t%.,%0"; break; 1176 case HImode: ret = "sh\t%.,%0"; break; 1177 case QImode: ret = "sb\t%.,%0"; break; 1178 } 1179 } 1180 1181 if (ret != (char *)0 && MEM_VOLATILE_P (op0)) 1182 { 1183 int i = strlen (ret); 1184 if (i > sizeof (volatile_buffer) - sizeof ("%{%}")) 1185 abort (); 1186 1187 sprintf (volatile_buffer, "%%{%s%%}", ret); 1188 ret = volatile_buffer; 1189 } 1190 } 1191 1192 if (ret == (char *)0) 1193 { 1194 abort_with_insn (insn, "Bad move"); 1195 return 0; 1196 } 1197 1198 if (delay != DELAY_NONE) 1199 return mips_fill_delay_slot (ret, delay, operands, insn); 1200 1201 return ret; 1202 } 1203 1204 1205 /* Return the appropriate instructions to move 2 words */ 1206 1207 char * 1208 mips_move_2words (operands, insn) 1209 rtx operands[]; 1210 rtx insn; 1211 { 1212 char *ret = 0; 1213 rtx op0 = operands[0]; 1214 rtx op1 = operands[1]; 1215 enum rtx_code code0 = GET_CODE (operands[0]); 1216 enum rtx_code code1 = GET_CODE (operands[1]); 1217 int subreg_word0 = 0; 1218 int subreg_word1 = 0; 1219 enum delay_type delay = DELAY_NONE; 1220 1221 while (code0 == SUBREG) 1222 { 1223 subreg_word0 += SUBREG_WORD (op0); 1224 op0 = SUBREG_REG (op0); 1225 code0 = GET_CODE (op0); 1226 } 1227 1228 while (code1 == SUBREG) 1229 { 1230 subreg_word1 += SUBREG_WORD (op1); 1231 op1 = SUBREG_REG (op1); 1232 code1 = GET_CODE (op1); 1233 } 1234 1235 if (code0 == REG) 1236 { 1237 int regno0 = REGNO (op0) + subreg_word0; 1238 1239 if (code1 == REG) 1240 { 1241 int regno1 = REGNO (op1) + subreg_word1; 1242 1243 /* Just in case, don't do anything for assigning a register 1244 to itself, unless we are filling a delay slot. */ 1245 if (regno0 == regno1 && set_nomacro == 0) 1246 ret = ""; 1247 1248 else if (FP_REG_P (regno0)) 1249 { 1250 if (FP_REG_P (regno1)) 1251 ret = "mov.d\t%0,%1"; 1252 1253 else 1254 { 1255 delay = DELAY_LOAD; 1256 ret = (TARGET_FLOAT64) 1257 ? "dmtc1\t%1,%0" 1258 : "mtc1\t%L1,%0\n\tmtc1\t%M1,%D0"; 1259 } 1260 } 1261 1262 else if (FP_REG_P (regno1)) 1263 { 1264 delay = DELAY_LOAD; 1265 ret = (TARGET_FLOAT64) 1266 ? "dmfc1\t%0,%1" 1267 : "mfc1\t%L0,%1\n\tmfc1\t%M0,%D1"; 1268 } 1269 1270 else if (MD_REG_P (regno0) && GP_REG_P (regno1)) 1271 { 1272 delay = DELAY_HILO; 1273 ret = "mthi\t%M1\n\tmtlo\t%L1"; 1274 } 1275 1276 else if (GP_REG_P (regno0) && MD_REG_P (regno1)) 1277 { 1278 delay = DELAY_HILO; 1279 ret = "mfhi\t%M0\n\tmflo\t%L0"; 1280 } 1281 1282 else if (regno0 != (regno1+1)) 1283 ret = "move\t%0,%1\n\tmove\t%D0,%D1"; 1284 1285 else 1286 ret = "move\t%D0,%D1\n\tmove\t%0,%1"; 1287 } 1288 1289 else if (code1 == CONST_DOUBLE) 1290 { 1291 if (CONST_DOUBLE_HIGH (op1) != 0 || CONST_DOUBLE_LOW (op1) != 0) 1292 { 1293 if (GET_MODE (op1) == DFmode) 1294 { 1295 delay = DELAY_LOAD; 1296 ret = "li.d\t%0,%1"; 1297 } 1298 1299 else 1300 { 1301 operands[2] = GEN_INT (CONST_DOUBLE_LOW (op1)); 1302 operands[3] = GEN_INT (CONST_DOUBLE_HIGH (op1)); 1303 ret = "li\t%M0,%3\n\tli\t%L0,%2"; 1304 } 1305 } 1306 1307 else 1308 { 1309 if (GP_REG_P (regno0)) 1310 ret = "move\t%0,%.\n\tmove\t%D0,%."; 1311 1312 else if (FP_REG_P (regno0)) 1313 { 1314 delay = DELAY_LOAD; 1315 ret = (TARGET_FLOAT64) 1316 ? "dmtc1\t%.,%0" 1317 : "mtc1\t%.,%0\n\tmtc1\t%.,%D0"; 1318 } 1319 } 1320 } 1321 1322 else if (code1 == CONST_INT && INTVAL (op1) == 0) 1323 { 1324 if (GP_REG_P (regno0)) 1325 ret = "move\t%0,%.\n\tmove\t%D0,%."; 1326 1327 else if (FP_REG_P (regno0)) 1328 { 1329 delay = DELAY_LOAD; 1330 ret = (TARGET_FLOAT64) 1331 ? "dmtc1\t%.,%0" 1332 : "mtc1\t%.,%0\n\tmtc1\t%.,%D0"; 1333 } 1334 } 1335 1336 else if (code1 == CONST_INT && GET_MODE (op0) == DImode && GP_REG_P (regno0)) 1337 { 1338 operands[2] = GEN_INT (INTVAL (operands[1]) >= 0 ? 0 : -1); 1339 ret = "li\t%M0,%2\n\tli\t%L0,%1"; 1340 } 1341 1342 else if (code1 == MEM) 1343 { 1344 delay = DELAY_LOAD; 1345 1346 if (TARGET_STATS) 1347 mips_count_memory_refs (op1, 2); 1348 1349 if (FP_REG_P (regno0)) 1350 ret = "l.d\t%0,%1"; 1351 1352 else if (offsettable_address_p (1, DFmode, XEXP (op1, 0))) 1353 { 1354 operands[2] = adj_offsettable_operand (op1, 4); 1355 if (reg_mentioned_p (op0, op1)) 1356 ret = "lw\t%D0,%2\n\tlw\t%0,%1"; 1357 else 1358 ret = "lw\t%0,%1\n\tlw\t%D0,%2"; 1359 } 1360 1361 if (ret != (char *)0 && MEM_VOLATILE_P (op1)) 1362 { 1363 int i = strlen (ret); 1364 if (i > sizeof (volatile_buffer) - sizeof ("%{%}")) 1365 abort (); 1366 1367 sprintf (volatile_buffer, "%%{%s%%}", ret); 1368 ret = volatile_buffer; 1369 } 1370 } 1371 } 1372 1373 else if (code0 == MEM) 1374 { 1375 if (code1 == REG) 1376 { 1377 int regno1 = REGNO (op1) + subreg_word1; 1378 1379 if (FP_REG_P (regno1)) 1380 ret = "s.d\t%1,%0"; 1381 1382 else if (offsettable_address_p (1, DFmode, XEXP (op0, 0))) 1383 { 1384 operands[2] = adj_offsettable_operand (op0, 4); 1385 ret = "sw\t%1,%0\n\tsw\t%D1,%2"; 1386 } 1387 } 1388 1389 else if (code1 == CONST_DOUBLE 1390 && CONST_DOUBLE_HIGH (op1) == 0 1391 && CONST_DOUBLE_LOW (op1) == 0 1392 && offsettable_address_p (1, DFmode, XEXP (op0, 0))) 1393 { 1394 if (TARGET_FLOAT64) 1395 ret = "sd\t%.,%0"; 1396 else 1397 { 1398 operands[2] = adj_offsettable_operand (op0, 4); 1399 ret = "sw\t%.,%0\n\tsw\t%.,%2"; 1400 } 1401 } 1402 1403 if (TARGET_STATS) 1404 mips_count_memory_refs (op0, 2); 1405 1406 if (ret != (char *)0 && MEM_VOLATILE_P (op0)) 1407 { 1408 int i = strlen (ret); 1409 if (i > sizeof (volatile_buffer) - sizeof ("%{%}")) 1410 abort (); 1411 1412 sprintf (volatile_buffer, "%%{%s%%}", ret); 1413 ret = volatile_buffer; 1414 } 1415 } 1416 1417 if (ret == (char *)0) 1418 { 1419 abort_with_insn (insn, "Bad move"); 1420 return 0; 1421 } 1422 1423 if (delay != DELAY_NONE) 1424 return mips_fill_delay_slot (ret, delay, operands, insn); 1425 1426 return ret; 1427 } 1428 1429 1430 /* Provide the costs of an addressing mode that contains ADDR. 1431 If ADDR is not a valid address, its cost is irrelevant. */ 1432 1433 int 1434 mips_address_cost (addr) 1435 rtx addr; 1436 { 1437 switch (GET_CODE (addr)) 1438 { 1439 default: 1440 break; 1441 1442 case LO_SUM: 1443 case HIGH: 1444 return 1; 1445 1446 case LABEL_REF: 1447 return 2; 1448 1449 case CONST: 1450 { 1451 rtx offset = const0_rtx; 1452 addr = eliminate_constant_term (addr, &offset); 1453 if (GET_CODE (addr) == LABEL_REF) 1454 return 2; 1455 1456 if (GET_CODE (addr) != SYMBOL_REF) 1457 return 4; 1458 1459 if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767) 1460 return 2; 1461 } 1462 /* fall through */ 1463 1464 case SYMBOL_REF: 1465 return SYMBOL_REF_FLAG (addr) ? 1 : 2; 1466 1467 case PLUS: 1468 { 1469 register rtx plus0 = XEXP (addr, 0); 1470 register rtx plus1 = XEXP (addr, 1); 1471 1472 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG) 1473 { 1474 plus0 = XEXP (addr, 1); 1475 plus1 = XEXP (addr, 0); 1476 } 1477 1478 if (GET_CODE (plus0) != REG) 1479 break; 1480 1481 switch (GET_CODE (plus1)) 1482 { 1483 default: 1484 break; 1485 1486 case CONST_INT: 1487 { 1488 int value = INTVAL (plus1); 1489 return (value < -32768 || value > 32767) ? 2 : 1; 1490 } 1491 1492 case CONST: 1493 case SYMBOL_REF: 1494 case LABEL_REF: 1495 case HIGH: 1496 case LO_SUM: 1497 return mips_address_cost (plus1) + 1; 1498 } 1499 } 1500 } 1501 1502 return 4; 1503 } 1504 1505 1506 /* Make normal rtx_code into something we can index from an array */ 1507 1508 static enum internal_test 1509 map_test_to_internal_test (test_code) 1510 enum rtx_code test_code; 1511 { 1512 enum internal_test test = ITEST_MAX; 1513 1514 switch (test_code) 1515 { 1516 default: break; 1517 case EQ: test = ITEST_EQ; break; 1518 case NE: test = ITEST_NE; break; 1519 case GT: test = ITEST_GT; break; 1520 case GE: test = ITEST_GE; break; 1521 case LT: test = ITEST_LT; break; 1522 case LE: test = ITEST_LE; break; 1523 case GTU: test = ITEST_GTU; break; 1524 case GEU: test = ITEST_GEU; break; 1525 case LTU: test = ITEST_LTU; break; 1526 case LEU: test = ITEST_LEU; break; 1527 } 1528 1529 return test; 1530 } 1531 1532 1533 /* Generate the code to compare two integer values. The return value is: 1534 (reg:SI xx) The pseudo register the comparison is in 1535 (rtx)0 No register, generate a simple branch. */ 1536 1537 rtx 1538 gen_int_relational (test_code, result, cmp0, cmp1, p_invert) 1539 enum rtx_code test_code; /* relational test (EQ, etc) */ 1540 rtx result; /* result to store comp. or 0 if branch */ 1541 rtx cmp0; /* first operand to compare */ 1542 rtx cmp1; /* second operand to compare */ 1543 int *p_invert; /* NULL or ptr to hold whether branch needs */ 1544 /* to reverse its test */ 1545 { 1546 struct cmp_info { 1547 enum rtx_code test_code; /* code to use in instruction (LT vs. LTU) */ 1548 int const_low; /* low bound of constant we can accept */ 1549 int const_high; /* high bound of constant we can accept */ 1550 int const_add; /* constant to add (convert LE -> LT) */ 1551 int reverse_regs; /* reverse registers in test */ 1552 int invert_const; /* != 0 if invert value if cmp1 is constant */ 1553 int invert_reg; /* != 0 if invert value if cmp1 is register */ 1554 int unsignedp; /* != 0 for unsigned comparisons. */ 1555 }; 1556 1557 static struct cmp_info info[ (int)ITEST_MAX ] = { 1558 1559 { XOR, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */ 1560 { XOR, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */ 1561 { LT, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */ 1562 { LT, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */ 1563 { LT, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */ 1564 { LT, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */ 1565 { LTU, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */ 1566 { LTU, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */ 1567 { LTU, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */ 1568 { LTU, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */ 1569 }; 1570 1571 enum internal_test test; 1572 struct cmp_info *p_info; 1573 int branch_p; 1574 int eqne_p; 1575 int invert; 1576 rtx reg; 1577 rtx reg2; 1578 1579 test = map_test_to_internal_test (test_code); 1580 if (test == ITEST_MAX) 1581 abort (); 1582 1583 p_info = &info[ (int)test ]; 1584 eqne_p = (p_info->test_code == XOR); 1585 1586 /* Eliminate simple branches */ 1587 branch_p = (result == (rtx)0); 1588 if (branch_p) 1589 { 1590 if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG) 1591 { 1592 /* Comparisons against zero are simple branches */ 1593 if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0) 1594 return (rtx)0; 1595 1596 /* Test for beq/bne. */ 1597 if (eqne_p) 1598 return (rtx)0; 1599 } 1600 1601 /* allocate a pseudo to calculate the value in. */ 1602 result = gen_reg_rtx (SImode); 1603 } 1604 1605 /* Make sure we can handle any constants given to us. */ 1606 if (GET_CODE (cmp0) == CONST_INT) 1607 cmp0 = force_reg (SImode, cmp0); 1608 1609 if (GET_CODE (cmp1) == CONST_INT) 1610 { 1611 HOST_WIDE_INT value = INTVAL (cmp1); 1612 if (value < p_info->const_low || value > p_info->const_high) 1613 cmp1 = force_reg (SImode, cmp1); 1614 } 1615 1616 /* See if we need to invert the result. */ 1617 invert = (GET_CODE (cmp1) == CONST_INT) 1618 ? p_info->invert_const 1619 : p_info->invert_reg; 1620 1621 if (p_invert != (int *)0) 1622 { 1623 *p_invert = invert; 1624 invert = FALSE; 1625 } 1626 1627 /* Comparison to constants, may involve adding 1 to change a LT into LE. 1628 Comparison between two registers, may involve switching operands. */ 1629 if (GET_CODE (cmp1) == CONST_INT) 1630 { 1631 if (p_info->const_add != 0) 1632 { 1633 HOST_WIDE_INT new = INTVAL (cmp1) + p_info->const_add; 1634 /* If modification of cmp1 caused overflow, 1635 we would get the wrong answer if we follow the usual path; 1636 thus, x > 0xffffffffu would turn into x > 0u. */ 1637 if ((p_info->unsignedp 1638 ? (unsigned HOST_WIDE_INT) new > INTVAL (cmp1) 1639 : new > INTVAL (cmp1)) 1640 != (p_info->const_add > 0)) 1641 /* 1 is the right value in the LE and LEU case. 1642 In the GT and GTU case, *p_invert is already set, 1643 so this is effectively 0. */ 1644 return force_reg (SImode, const1_rtx); 1645 else 1646 cmp1 = GEN_INT (new); 1647 } 1648 } 1649 else if (p_info->reverse_regs) 1650 { 1651 rtx temp = cmp0; 1652 cmp0 = cmp1; 1653 cmp1 = temp; 1654 } 1655 1656 if (test == ITEST_NE && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0) 1657 reg = cmp0; 1658 else 1659 { 1660 reg = (invert || eqne_p) ? gen_reg_rtx (SImode) : result; 1661 emit_move_insn (reg, gen_rtx (p_info->test_code, SImode, cmp0, cmp1)); 1662 } 1663 1664 if (test == ITEST_NE) 1665 { 1666 emit_move_insn (result, gen_rtx (GTU, SImode, reg, const0_rtx)); 1667 invert = FALSE; 1668 } 1669 1670 else if (test == ITEST_EQ) 1671 { 1672 reg2 = (invert) ? gen_reg_rtx (SImode) : result; 1673 emit_move_insn (reg2, gen_rtx (LTU, SImode, reg, const1_rtx)); 1674 reg = reg2; 1675 } 1676 1677 if (invert) 1678 emit_move_insn (result, gen_rtx (XOR, SImode, reg, const1_rtx)); 1679 1680 return result; 1681 } 1682 1683 1684 /* Emit the common code for doing conditional branches. 1685 operand[0] is the label to jump to. 1686 The comparison operands are saved away by cmp{si,sf,df}. */ 1687 1688 void 1689 gen_conditional_branch (operands, test_code) 1690 rtx operands[]; 1691 enum rtx_code test_code; 1692 { 1693 static enum machine_mode mode_map[(int)CMP_MAX][(int)ITEST_MAX] = { 1694 { /* CMP_SI */ 1695 SImode, /* eq */ 1696 SImode, /* ne */ 1697 SImode, /* gt */ 1698 SImode, /* ge */ 1699 SImode, /* lt */ 1700 SImode, /* le */ 1701 SImode, /* gtu */ 1702 SImode, /* geu */ 1703 SImode, /* ltu */ 1704 SImode, /* leu */ 1705 }, 1706 { /* CMP_SF */ 1707 CC_FPmode, /* eq */ 1708 CC_REV_FPmode, /* ne */ 1709 CC_FPmode, /* gt */ 1710 CC_FPmode, /* ge */ 1711 CC_FPmode, /* lt */ 1712 CC_FPmode, /* le */ 1713 VOIDmode, /* gtu */ 1714 VOIDmode, /* geu */ 1715 VOIDmode, /* ltu */ 1716 VOIDmode, /* leu */ 1717 }, 1718 { /* CMP_DF */ 1719 CC_FPmode, /* eq */ 1720 CC_REV_FPmode, /* ne */ 1721 CC_FPmode, /* gt */ 1722 CC_FPmode, /* ge */ 1723 CC_FPmode, /* lt */ 1724 CC_FPmode, /* le */ 1725 VOIDmode, /* gtu */ 1726 VOIDmode, /* geu */ 1727 VOIDmode, /* ltu */ 1728 VOIDmode, /* leu */ 1729 }, 1730 }; 1731 1732 enum machine_mode mode; 1733 enum cmp_type type = branch_type; 1734 rtx cmp0 = branch_cmp[0]; 1735 rtx cmp1 = branch_cmp[1]; 1736 rtx label1 = gen_rtx (LABEL_REF, VOIDmode, operands[0]); 1737 rtx label2 = pc_rtx; 1738 rtx reg = (rtx)0; 1739 int invert = 0; 1740 enum internal_test test = map_test_to_internal_test (test_code); 1741 1742 if (test == ITEST_MAX) 1743 { 1744 mode = SImode; 1745 goto fail; 1746 } 1747 1748 /* Get the machine mode to use (CCmode, CC_EQmode, CC_FPmode, or CC_REV_FPmode). */ 1749 mode = mode_map[(int)type][(int)test]; 1750 if (mode == VOIDmode) 1751 goto fail; 1752 1753 switch (branch_type) 1754 { 1755 default: 1756 goto fail; 1757 1758 case CMP_SI: 1759 reg = gen_int_relational (test_code, (rtx)0, cmp0, cmp1, &invert); 1760 if (reg != (rtx)0) 1761 { 1762 cmp0 = reg; 1763 cmp1 = const0_rtx; 1764 test_code = NE; 1765 } 1766 1767 /* Make sure not non-zero constant if ==/!= */ 1768 else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0) 1769 cmp1 = force_reg (SImode, cmp1); 1770 1771 break; 1772 1773 case CMP_DF: 1774 case CMP_SF: 1775 { 1776 rtx reg = gen_rtx (REG, mode, FPSW_REGNUM); 1777 emit_insn (gen_rtx (SET, VOIDmode, reg, gen_rtx (test_code, mode, cmp0, cmp1))); 1778 cmp0 = reg; 1779 cmp1 = const0_rtx; 1780 test_code = NE; 1781 } 1782 break; 1783 } 1784 1785 /* Generate the jump */ 1786 if (invert) 1787 { 1788 label2 = label1; 1789 label1 = pc_rtx; 1790 } 1791 1792 emit_jump_insn (gen_rtx (SET, VOIDmode, 1793 pc_rtx, 1794 gen_rtx (IF_THEN_ELSE, VOIDmode, 1795 gen_rtx (test_code, mode, cmp0, cmp1), 1796 label1, 1797 label2))); 1798 1799 return; 1800 1801 fail: 1802 abort_with_insn (gen_rtx (test_code, mode, cmp0, cmp1), "bad test"); 1803 } 1804 1805 1806 #define UNITS_PER_SHORT (SHORT_TYPE_SIZE / BITS_PER_UNIT) 1807 1808 /* Internal code to generate the load and store of one word/short/byte. 1809 The load is emitted directly, and the store insn is returned. */ 1810 1811 #if 0 1812 static rtx 1813 block_move_load_store (dest_reg, src_reg, p_bytes, p_offset, align, orig_src) 1814 rtx src_reg; /* register holding source memory address */ 1815 rtx dest_reg; /* register holding dest. memory address */ 1816 int *p_bytes; /* pointer to # bytes remaining */ 1817 int *p_offset; /* pointer to current offset */ 1818 int align; /* alignment */ 1819 rtx orig_src; /* original source for making a reg note */ 1820 { 1821 int bytes; /* # bytes remaining */ 1822 int offset; /* offset to use */ 1823 int size; /* size in bytes of load/store */ 1824 enum machine_mode mode; /* mode to use for load/store */ 1825 rtx reg; /* temporary register */ 1826 rtx src_addr; /* source address */ 1827 rtx dest_addr; /* destination address */ 1828 rtx insn; /* insn of the load */ 1829 rtx orig_src_addr; /* original source address */ 1830 rtx (*load_func)(); /* function to generate load insn */ 1831 rtx (*store_func)(); /* function to generate destination insn */ 1832 1833 bytes = *p_bytes; 1834 if (bytes <= 0 || align <= 0) 1835 abort (); 1836 1837 if (bytes >= UNITS_PER_WORD && align >= UNITS_PER_WORD) 1838 { 1839 mode = SImode; 1840 size = UNITS_PER_WORD; 1841 load_func = gen_movsi; 1842 store_func = gen_movsi; 1843 } 1844 1845 #if 0 1846 /* Don't generate unligned moves here, rather defer those to the 1847 general movestrsi_internal pattern. */ 1848 else if (bytes >= UNITS_PER_WORD) 1849 { 1850 mode = SImode; 1851 size = UNITS_PER_WORD; 1852 load_func = gen_movsi_ulw; 1853 store_func = gen_movsi_usw; 1854 } 1855 #endif 1856 1857 else if (bytes >= UNITS_PER_SHORT && align >= UNITS_PER_SHORT) 1858 { 1859 mode = HImode; 1860 size = UNITS_PER_SHORT; 1861 load_func = gen_movhi; 1862 store_func = gen_movhi; 1863 } 1864 1865 else 1866 { 1867 mode = QImode; 1868 size = 1; 1869 load_func = gen_movqi; 1870 store_func = gen_movqi; 1871 } 1872 1873 offset = *p_offset; 1874 *p_offset = offset + size; 1875 *p_bytes = bytes - size; 1876 1877 if (offset == 0) 1878 { 1879 src_addr = src_reg; 1880 dest_addr = dest_reg; 1881 } 1882 else 1883 { 1884 src_addr = gen_rtx (PLUS, Pmode, src_reg, GEN_INT (offset)); 1885 dest_addr = gen_rtx (PLUS, Pmode, dest_reg, GEN_INT (offset)); 1886 } 1887 1888 reg = gen_reg_rtx (mode); 1889 insn = emit_insn ((*load_func) (reg, gen_rtx (MEM, mode, src_addr))); 1890 orig_src_addr = XEXP (orig_src, 0); 1891 if (CONSTANT_P (orig_src_addr)) 1892 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUIV, 1893 plus_constant (orig_src_addr, offset), 1894 REG_NOTES (insn)); 1895 1896 return (*store_func) (gen_rtx (MEM, mode, dest_addr), reg); 1897 } 1898 #endif 1899 1900 1901 /* Write a series of loads/stores to move some bytes. Generate load/stores as follows: 1902 1903 load 1 1904 load 2 1905 load 3 1906 store 1 1907 load 4 1908 store 2 1909 load 5 1910 store 3 1911 ... 1912 1913 This way, no NOP's are needed, except at the end, and only 1914 two temp registers are needed. Two delay slots are used 1915 in deference to the R4000. */ 1916 1917 #if 0 1918 static void 1919 block_move_sequence (dest_reg, src_reg, bytes, align, orig_src) 1920 rtx dest_reg; /* register holding destination address */ 1921 rtx src_reg; /* register holding source address */ 1922 int bytes; /* # bytes to move */ 1923 int align; /* max alignment to assume */ 1924 rtx orig_src; /* original source for making a reg note */ 1925 { 1926 int offset = 0; 1927 rtx prev2_store = (rtx)0; 1928 rtx prev_store = (rtx)0; 1929 rtx cur_store = (rtx)0; 1930 1931 while (bytes > 0) 1932 { 1933 /* Is there a store to do? */ 1934 if (prev2_store) 1935 emit_insn (prev2_store); 1936 1937 prev2_store = prev_store; 1938 prev_store = cur_store; 1939 cur_store = block_move_load_store (dest_reg, src_reg, 1940 &bytes, &offset, 1941 align, orig_src); 1942 } 1943 1944 /* Finish up last three stores. */ 1945 if (prev2_store) 1946 emit_insn (prev2_store); 1947 1948 if (prev_store) 1949 emit_insn (prev_store); 1950 1951 if (cur_store) 1952 emit_insn (cur_store); 1953 } 1954 #endif 1955 1956 1957 /* Write a loop to move a constant number of bytes. Generate load/stores as follows: 1958 1959 do { 1960 temp1 = src[0]; 1961 temp2 = src[1]; 1962 ... 1963 temp<last> = src[MAX_MOVE_REGS-1]; 1964 dest[0] = temp1; 1965 dest[1] = temp2; 1966 ... 1967 dest[MAX_MOVE_REGS-1] = temp<last>; 1968 src += MAX_MOVE_REGS; 1969 dest += MAX_MOVE_REGS; 1970 } while (src != final); 1971 1972 This way, no NOP's are needed, and only MAX_MOVE_REGS+3 temp 1973 registers are needed. 1974 1975 Aligned moves move MAX_MOVE_REGS*4 bytes every (2*MAX_MOVE_REGS)+3 1976 cycles, unaligned moves move MAX_MOVE_REGS*4 bytes every 1977 (4*MAX_MOVE_REGS)+3 cycles, assuming no cache misses. */ 1978 1979 #define MAX_MOVE_REGS 4 1980 #define MAX_MOVE_BYTES (MAX_MOVE_REGS * UNITS_PER_WORD) 1981 1982 static void 1983 block_move_loop (dest_reg, src_reg, bytes, align, orig_src) 1984 rtx dest_reg; /* register holding destination address */ 1985 rtx src_reg; /* register holding source address */ 1986 int bytes; /* # bytes to move */ 1987 int align; /* alignment */ 1988 rtx orig_src; /* original source for making a reg note */ 1989 { 1990 rtx dest_mem = gen_rtx (MEM, BLKmode, dest_reg); 1991 rtx src_mem = gen_rtx (MEM, BLKmode, src_reg); 1992 rtx align_rtx = GEN_INT (align); 1993 rtx label; 1994 rtx final_src; 1995 rtx bytes_rtx; 1996 int leftover; 1997 1998 if (bytes < 2*MAX_MOVE_BYTES) 1999 abort (); 2000 2001 leftover = bytes % MAX_MOVE_BYTES; 2002 bytes -= leftover; 2003 2004 label = gen_label_rtx (); 2005 final_src = gen_reg_rtx (Pmode); 2006 bytes_rtx = GEN_INT (bytes); 2007 2008 if (bytes > 0x7fff) 2009 { 2010 emit_insn (gen_movsi (final_src, bytes_rtx)); 2011 emit_insn (gen_addsi3 (final_src, final_src, src_reg)); 2012 } 2013 else 2014 emit_insn (gen_addsi3 (final_src, src_reg, bytes_rtx)); 2015 2016 emit_label (label); 2017 2018 bytes_rtx = GEN_INT (MAX_MOVE_BYTES); 2019 emit_insn (gen_movstrsi_internal (dest_mem, src_mem, bytes_rtx, align_rtx)); 2020 emit_insn (gen_addsi3 (src_reg, src_reg, bytes_rtx)); 2021 emit_insn (gen_addsi3 (dest_reg, dest_reg, bytes_rtx)); 2022 emit_insn (gen_cmpsi (src_reg, final_src)); 2023 emit_jump_insn (gen_bne (label)); 2024 2025 if (leftover) 2026 emit_insn (gen_movstrsi_internal (dest_mem, src_mem, 2027 GEN_INT (leftover), 2028 align_rtx)); 2029 } 2030 2031 2032 /* Use a library function to move some bytes. */ 2033 2034 static void 2035 block_move_call (dest_reg, src_reg, bytes_rtx) 2036 rtx dest_reg; 2037 rtx src_reg; 2038 rtx bytes_rtx; 2039 { 2040 #ifdef TARGET_MEM_FUNCTIONS 2041 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "memcpy"), 0, 2042 VOIDmode, 3, 2043 dest_reg, Pmode, 2044 src_reg, Pmode, 2045 bytes_rtx, SImode); 2046 #else 2047 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "bcopy"), 0, 2048 VOIDmode, 3, 2049 src_reg, Pmode, 2050 dest_reg, Pmode, 2051 bytes_rtx, SImode); 2052 #endif 2053 } 2054 2055 2056 /* Expand string/block move operations. 2057 2058 operands[0] is the pointer to the destination. 2059 operands[1] is the pointer to the source. 2060 operands[2] is the number of bytes to move. 2061 operands[3] is the alignment. */ 2062 2063 void 2064 expand_block_move (operands) 2065 rtx operands[]; 2066 { 2067 rtx bytes_rtx = operands[2]; 2068 rtx align_rtx = operands[3]; 2069 int constp = (GET_CODE (bytes_rtx) == CONST_INT); 2070 int bytes = (constp ? INTVAL (bytes_rtx) : 0); 2071 int align = INTVAL (align_rtx); 2072 rtx orig_src = operands[1]; 2073 rtx src_reg; 2074 rtx dest_reg; 2075 2076 if (constp && bytes <= 0) 2077 return; 2078 2079 if (align > UNITS_PER_WORD) 2080 align = UNITS_PER_WORD; 2081 2082 /* Move the address into scratch registers. */ 2083 dest_reg = copy_addr_to_reg (XEXP (operands[0], 0)); 2084 src_reg = copy_addr_to_reg (XEXP (orig_src, 0)); 2085 2086 if (TARGET_MEMCPY) 2087 block_move_call (dest_reg, src_reg, bytes_rtx); 2088 2089 #if 0 2090 else if (constp && bytes <= 3*align) 2091 block_move_sequence (dest_reg, src_reg, bytes, align, orig_src); 2092 #endif 2093 2094 else if (constp && bytes <= 2*MAX_MOVE_BYTES) 2095 emit_insn (gen_movstrsi_internal (gen_rtx (MEM, BLKmode, dest_reg), 2096 gen_rtx (MEM, BLKmode, src_reg), 2097 bytes_rtx, align_rtx)); 2098 2099 else if (constp && align >= UNITS_PER_WORD && optimize) 2100 block_move_loop (dest_reg, src_reg, bytes, align, orig_src); 2101 2102 else if (constp && optimize) 2103 { 2104 /* If the alignment is not word aligned, generate a test at 2105 runtime, to see whether things wound up aligned, and we 2106 can use the faster lw/sw instead ulw/usw. */ 2107 2108 rtx temp = gen_reg_rtx (Pmode); 2109 rtx aligned_label = gen_label_rtx (); 2110 rtx join_label = gen_label_rtx (); 2111 int leftover = bytes % MAX_MOVE_BYTES; 2112 2113 bytes -= leftover; 2114 2115 emit_insn (gen_iorsi3 (temp, src_reg, dest_reg)); 2116 emit_insn (gen_andsi3 (temp, temp, GEN_INT (UNITS_PER_WORD-1))); 2117 emit_insn (gen_cmpsi (temp, const0_rtx)); 2118 emit_jump_insn (gen_beq (aligned_label)); 2119 2120 /* Unaligned loop. */ 2121 block_move_loop (dest_reg, src_reg, bytes, 1, orig_src); 2122 emit_jump_insn (gen_jump (join_label)); 2123 emit_barrier (); 2124 2125 /* Aligned loop. */ 2126 emit_label (aligned_label); 2127 block_move_loop (dest_reg, src_reg, bytes, UNITS_PER_WORD, orig_src); 2128 emit_label (join_label); 2129 2130 /* Bytes at the end of the loop. */ 2131 if (leftover) 2132 { 2133 #if 0 2134 if (leftover <= 3*align) 2135 block_move_sequence (dest_reg, src_reg, leftover, align, orig_src); 2136 2137 else 2138 #endif 2139 emit_insn (gen_movstrsi_internal (gen_rtx (MEM, BLKmode, dest_reg), 2140 gen_rtx (MEM, BLKmode, src_reg), 2141 GEN_INT (leftover), 2142 GEN_INT (align))); 2143 } 2144 } 2145 2146 else 2147 block_move_call (dest_reg, src_reg, bytes_rtx); 2148 } 2149 2150 2151 /* Emit load/stores for a small constant block_move. 2152 2153 operands[0] is the memory address of the destination. 2154 operands[1] is the memory address of the source. 2155 operands[2] is the number of bytes to move. 2156 operands[3] is the alignment. 2157 operands[4] is a temp register. 2158 operands[5] is a temp register. 2159 ... 2160 operands[3+num_regs] is the last temp register. 2161 2162 The block move type can be one of the following: 2163 BLOCK_MOVE_NORMAL Do all of the block move. 2164 BLOCK_MOVE_NOT_LAST Do all but the last store. 2165 BLOCK_MOVE_LAST Do just the last store. */ 2166 2167 char * 2168 output_block_move (insn, operands, num_regs, move_type) 2169 rtx insn; 2170 rtx operands[]; 2171 int num_regs; 2172 enum block_move_type move_type; 2173 { 2174 rtx dest_reg = XEXP (operands[0], 0); 2175 rtx src_reg = XEXP (operands[1], 0); 2176 int bytes = INTVAL (operands[2]); 2177 int align = INTVAL (operands[3]); 2178 int num = 0; 2179 int offset = 0; 2180 int use_lwl_lwr = FALSE; 2181 int last_operand = num_regs+4; 2182 int i; 2183 rtx xoperands[10]; 2184 2185 struct { 2186 char *load; /* load insn without nop */ 2187 char *load_nop; /* load insn with trailing nop */ 2188 char *store; /* store insn */ 2189 char *final; /* if last_store used: NULL or swr */ 2190 char *last_store; /* last store instruction */ 2191 int offset; /* current offset */ 2192 enum machine_mode mode; /* mode to use on (MEM) */ 2193 } load_store[4]; 2194 2195 /* Detect a bug in GCC, where it can give us a register 2196 the same as one of the addressing registers. */ 2197 for (i = 4; i < last_operand; i++) 2198 { 2199 if (reg_mentioned_p (operands[i], operands[0]) 2200 || reg_mentioned_p (operands[i], operands[1])) 2201 { 2202 abort_with_insn (insn, "register passed as address and temp register to block move"); 2203 } 2204 } 2205 2206 /* If we are given global or static addresses, and we would be 2207 emitting a few instructions, try to save time by using a 2208 temporary register for the pointer. */ 2209 if (bytes > 2*align || move_type != BLOCK_MOVE_NORMAL) 2210 { 2211 if (CONSTANT_P (src_reg)) 2212 { 2213 if (TARGET_STATS) 2214 mips_count_memory_refs (operands[1], 1); 2215 2216 src_reg = operands[ 3 + num_regs-- ]; 2217 if (move_type != BLOCK_MOVE_LAST) 2218 { 2219 xoperands[1] = operands[1]; 2220 xoperands[0] = src_reg; 2221 output_asm_insn ("la\t%0,%1", xoperands); 2222 } 2223 } 2224 2225 if (CONSTANT_P (dest_reg)) 2226 { 2227 if (TARGET_STATS) 2228 mips_count_memory_refs (operands[0], 1); 2229 2230 dest_reg = operands[ 3 + num_regs-- ]; 2231 if (move_type != BLOCK_MOVE_LAST) 2232 { 2233 xoperands[1] = operands[0]; 2234 xoperands[0] = dest_reg; 2235 output_asm_insn ("la\t%0,%1", xoperands); 2236 } 2237 } 2238 } 2239 2240 if (num_regs > (sizeof (load_store) / sizeof (load_store[0]))) 2241 num_regs = (sizeof (load_store) / sizeof (load_store[0])); 2242 2243 else if (num_regs < 1) 2244 abort (); 2245 2246 if (TARGET_GAS && move_type != BLOCK_MOVE_LAST && set_noreorder++ == 0) 2247 output_asm_insn (".set\tnoreorder", operands); 2248 2249 while (bytes > 0) 2250 { 2251 load_store[num].offset = offset; 2252 2253 if (bytes >= UNITS_PER_WORD && align >= UNITS_PER_WORD) 2254 { 2255 load_store[num].load = "lw\t%0,%1"; 2256 load_store[num].load_nop = "lw\t%0,%1%#"; 2257 load_store[num].store = "sw\t%0,%1"; 2258 load_store[num].last_store = "sw\t%0,%1"; 2259 load_store[num].final = (char *)0; 2260 load_store[num].mode = SImode; 2261 offset += UNITS_PER_WORD; 2262 bytes -= UNITS_PER_WORD; 2263 } 2264 2265 else if (bytes >= UNITS_PER_WORD) 2266 { 2267 #if BYTES_BIG_ENDIAN 2268 load_store[num].load = "lwl\t%0,%1\n\tlwr\t%0,%2"; 2269 load_store[num].load_nop = "lwl\t%0,%1\n\tlwr\t%0,%2%#"; 2270 load_store[num].store = "swl\t%0,%1\n\tswr\t%0,%2"; 2271 load_store[num].last_store = "swr\t%0,%2"; 2272 load_store[num].final = "swl\t%0,%1"; 2273 #else 2274 load_store[num].load = "lwl\t%0,%2\n\tlwr\t%0,%1"; 2275 load_store[num].load_nop = "lwl\t%0,%2\n\tlwr\t%0,%1%#"; 2276 load_store[num].store = "swl\t%0,%2\n\tswr\t%0,%1"; 2277 load_store[num].last_store = "swr\t%0,%1"; 2278 load_store[num].final = "swl\t%0,%2"; 2279 #endif 2280 load_store[num].mode = SImode; 2281 offset += UNITS_PER_WORD; 2282 bytes -= UNITS_PER_WORD; 2283 use_lwl_lwr = TRUE; 2284 } 2285 2286 else if (bytes >= UNITS_PER_SHORT && align >= UNITS_PER_SHORT) 2287 { 2288 load_store[num].load = "lh\t%0,%1"; 2289 load_store[num].load_nop = "lh\t%0,%1%#"; 2290 load_store[num].store = "sh\t%0,%1"; 2291 load_store[num].last_store = "sh\t%0,%1"; 2292 load_store[num].final = (char *)0; 2293 load_store[num].offset = offset; 2294 load_store[num].mode = HImode; 2295 offset += UNITS_PER_SHORT; 2296 bytes -= UNITS_PER_SHORT; 2297 } 2298 2299 else 2300 { 2301 load_store[num].load = "lb\t%0,%1"; 2302 load_store[num].load_nop = "lb\t%0,%1%#"; 2303 load_store[num].store = "sb\t%0,%1"; 2304 load_store[num].last_store = "sb\t%0,%1"; 2305 load_store[num].final = (char *)0; 2306 load_store[num].mode = QImode; 2307 offset++; 2308 bytes--; 2309 } 2310 2311 if (TARGET_STATS && move_type != BLOCK_MOVE_LAST) 2312 { 2313 dslots_load_total++; 2314 dslots_load_filled++; 2315 2316 if (CONSTANT_P (src_reg)) 2317 mips_count_memory_refs (src_reg, 1); 2318 2319 if (CONSTANT_P (dest_reg)) 2320 mips_count_memory_refs (dest_reg, 1); 2321 } 2322 2323 /* Emit load/stores now if we have run out of registers or are 2324 at the end of the move. */ 2325 2326 if (++num == num_regs || bytes == 0) 2327 { 2328 /* If only load/store, we need a NOP after the load. */ 2329 if (num == 1) 2330 { 2331 load_store[0].load = load_store[0].load_nop; 2332 if (TARGET_STATS && move_type != BLOCK_MOVE_LAST) 2333 dslots_load_filled--; 2334 } 2335 2336 if (move_type != BLOCK_MOVE_LAST) 2337 { 2338 for (i = 0; i < num; i++) 2339 { 2340 int offset; 2341 2342 if (!operands[i+4]) 2343 abort (); 2344 2345 if (GET_MODE (operands[i+4]) != load_store[i].mode) 2346 operands[i+4] = gen_rtx (REG, load_store[i].mode, REGNO (operands[i+4])); 2347 2348 offset = load_store[i].offset; 2349 xoperands[0] = operands[i+4]; 2350 xoperands[1] = gen_rtx (MEM, load_store[i].mode, 2351 plus_constant (src_reg, offset)); 2352 2353 if (use_lwl_lwr) 2354 xoperands[2] = gen_rtx (MEM, load_store[i].mode, 2355 plus_constant (src_reg, UNITS_PER_WORD-1+offset)); 2356 2357 output_asm_insn (load_store[i].load, xoperands); 2358 } 2359 } 2360 2361 for (i = 0; i < num; i++) 2362 { 2363 int last_p = (i == num-1 && bytes == 0); 2364 int offset = load_store[i].offset; 2365 2366 xoperands[0] = operands[i+4]; 2367 xoperands[1] = gen_rtx (MEM, load_store[i].mode, 2368 plus_constant (dest_reg, offset)); 2369 2370 2371 if (use_lwl_lwr) 2372 xoperands[2] = gen_rtx (MEM, load_store[i].mode, 2373 plus_constant (dest_reg, UNITS_PER_WORD-1+offset)); 2374 2375 if (move_type == BLOCK_MOVE_NORMAL) 2376 output_asm_insn (load_store[i].store, xoperands); 2377 2378 else if (move_type == BLOCK_MOVE_NOT_LAST) 2379 { 2380 if (!last_p) 2381 output_asm_insn (load_store[i].store, xoperands); 2382 2383 else if (load_store[i].final != (char *)0) 2384 output_asm_insn (load_store[i].final, xoperands); 2385 } 2386 2387 else if (last_p) 2388 output_asm_insn (load_store[i].last_store, xoperands); 2389 } 2390 2391 num = 0; /* reset load_store */ 2392 use_lwl_lwr = FALSE; /* reset whether or not we used lwl/lwr */ 2393 } 2394 } 2395 2396 if (TARGET_GAS && move_type != BLOCK_MOVE_LAST && --set_noreorder == 0) 2397 output_asm_insn (".set\treorder", operands); 2398 2399 return ""; 2400 } 2401 2402 2403 /* Argument support functions. */ 2404 2405 /* Initialize CUMULATIVE_ARGS for a function. */ 2406 2407 void 2408 init_cumulative_args (cum, fntype, libname) 2409 CUMULATIVE_ARGS *cum; /* argument info to initialize */ 2410 tree fntype; /* tree ptr for function decl */ 2411 rtx libname; /* SYMBOL_REF of library name or 0 */ 2412 { 2413 static CUMULATIVE_ARGS zero_cum; 2414 tree param, next_param; 2415 2416 if (TARGET_DEBUG_E_MODE) 2417 { 2418 fprintf (stderr, "\ninit_cumulative_args, fntype = 0x%.8lx", (long)fntype); 2419 if (!fntype) 2420 fputc ('\n', stderr); 2421 2422 else 2423 { 2424 tree ret_type = TREE_TYPE (fntype); 2425 fprintf (stderr, ", fntype code = %s, ret code = %s\n", 2426 tree_code_name[ (int)TREE_CODE (fntype) ], 2427 tree_code_name[ (int)TREE_CODE (ret_type) ]); 2428 } 2429 } 2430 2431 *cum = zero_cum; 2432 2433 /* Determine if this function has variable arguments. This is 2434 indicated by the last argument being 'void_type_mode' if there 2435 are no variable arguments. The standard MIPS calling sequence 2436 passes all arguments in the general purpose registers in this 2437 case. */ 2438 2439 for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0; 2440 param != (tree)0; 2441 param = next_param) 2442 { 2443 next_param = TREE_CHAIN (param); 2444 if (next_param == (tree)0 && TREE_VALUE (param) != void_type_node) 2445 cum->gp_reg_found = 1; 2446 } 2447 } 2448 2449 /* Advance the argument to the next argument position. */ 2450 2451 void 2452 function_arg_advance (cum, mode, type, named) 2453 CUMULATIVE_ARGS *cum; /* current arg information */ 2454 enum machine_mode mode; /* current arg mode */ 2455 tree type; /* type of the argument or 0 if lib support */ 2456 int named; /* whether or not the argument was named */ 2457 { 2458 if (TARGET_DEBUG_E_MODE) 2459 fprintf (stderr, 2460 "function_adv( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, 0x%.8x, %d )\n\n", 2461 cum->gp_reg_found, cum->arg_number, cum->arg_words, GET_MODE_NAME (mode), 2462 type, named); 2463 2464 cum->arg_number++; 2465 switch (mode) 2466 { 2467 default: 2468 error ("Illegal mode given to function_arg_advance"); 2469 break; 2470 2471 case VOIDmode: 2472 break; 2473 2474 case BLKmode: 2475 cum->gp_reg_found = 1; 2476 cum->arg_words += (int_size_in_bytes (type) + 3) / 4; 2477 break; 2478 2479 case SFmode: 2480 cum->arg_words++; 2481 break; 2482 2483 case DFmode: 2484 cum->arg_words += 2; 2485 break; 2486 2487 case DImode: 2488 cum->gp_reg_found = 1; 2489 cum->arg_words += 2; 2490 break; 2491 2492 case QImode: 2493 case HImode: 2494 case SImode: 2495 cum->gp_reg_found = 1; 2496 cum->arg_words++; 2497 break; 2498 } 2499 } 2500 2501 /* Return a RTL expression containing the register for the given mode, 2502 or 0 if the argument is too be passed on the stack. */ 2503 2504 struct rtx_def * 2505 function_arg (cum, mode, type, named) 2506 CUMULATIVE_ARGS *cum; /* current arg information */ 2507 enum machine_mode mode; /* current arg mode */ 2508 tree type; /* type of the argument or 0 if lib support */ 2509 int named; /* != 0 for normal args, == 0 for ... args */ 2510 { 2511 rtx ret; 2512 int regbase = -1; 2513 int bias = 0; 2514 int struct_p = ((type != (tree)0) 2515 && (TREE_CODE (type) == RECORD_TYPE 2516 || TREE_CODE (type) == UNION_TYPE)); 2517 2518 if (TARGET_DEBUG_E_MODE) 2519 fprintf (stderr, 2520 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, 0x%.8x, %d ) = ", 2521 cum->gp_reg_found, cum->arg_number, cum->arg_words, GET_MODE_NAME (mode), 2522 type, named); 2523 2524 switch (mode) 2525 { 2526 default: 2527 error ("Illegal mode given to function_arg"); 2528 break; 2529 2530 case SFmode: 2531 if (cum->gp_reg_found || cum->arg_number >= 2) 2532 regbase = GP_ARG_FIRST; 2533 else { 2534 regbase = (TARGET_SOFT_FLOAT) ? GP_ARG_FIRST : FP_ARG_FIRST; 2535 if (cum->arg_words == 1) /* first arg was float */ 2536 bias = 1; /* use correct reg */ 2537 } 2538 2539 break; 2540 2541 case DFmode: 2542 cum->arg_words += (cum->arg_words & 1); 2543 regbase = (cum->gp_reg_found || TARGET_SOFT_FLOAT) 2544 ? GP_ARG_FIRST 2545 : FP_ARG_FIRST; 2546 break; 2547 2548 case BLKmode: 2549 if (type != (tree)0 && TYPE_ALIGN (type) > BITS_PER_WORD) 2550 cum->arg_words += (cum->arg_words & 1); 2551 2552 regbase = GP_ARG_FIRST; 2553 break; 2554 2555 case VOIDmode: 2556 case QImode: 2557 case HImode: 2558 case SImode: 2559 regbase = GP_ARG_FIRST; 2560 break; 2561 2562 case DImode: 2563 cum->arg_words += (cum->arg_words & 1); 2564 regbase = GP_ARG_FIRST; 2565 } 2566 2567 if (cum->arg_words >= MAX_ARGS_IN_REGISTERS) 2568 { 2569 if (TARGET_DEBUG_E_MODE) 2570 fprintf (stderr, "<stack>%s\n", struct_p ? ", [struct]" : ""); 2571 2572 ret = (rtx)0; 2573 } 2574 else 2575 { 2576 if (regbase == -1) 2577 abort (); 2578 2579 ret = gen_rtx (REG, mode, regbase + cum->arg_words + bias); 2580 2581 if (TARGET_DEBUG_E_MODE) 2582 fprintf (stderr, "%s%s\n", reg_names[regbase + cum->arg_words + bias], 2583 struct_p ? ", [struct]" : ""); 2584 2585 /* The following is a hack in order to pass 1 byte structures 2586 the same way that the MIPS compiler does (namely by passing 2587 the structure in the high byte or half word of the register). 2588 This also makes varargs work. If we have such a structure, 2589 we save the adjustment RTL, and the call define expands will 2590 emit them. For the VOIDmode argument (argument after the 2591 last real argument, pass back a parallel vector holding each 2592 of the adjustments. */ 2593 2594 if (struct_p && (mode == QImode || mode == HImode)) 2595 { 2596 rtx amount = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (mode)); 2597 rtx reg = gen_rtx (REG, SImode, regbase + cum->arg_words + bias); 2598 cum->adjust[ cum->num_adjusts++ ] = gen_ashlsi3 (reg, reg, amount); 2599 } 2600 } 2601 2602 if (mode == VOIDmode && cum->num_adjusts > 0) 2603 ret = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (cum->num_adjusts, cum->adjust)); 2604 2605 return ret; 2606 } 2607 2608 2609 int 2610 function_arg_partial_nregs (cum, mode, type, named) 2611 CUMULATIVE_ARGS *cum; /* current arg information */ 2612 enum machine_mode mode; /* current arg mode */ 2613 tree type; /* type of the argument or 0 if lib support */ 2614 int named; /* != 0 for normal args, == 0 for ... args */ 2615 { 2616 if (mode == BLKmode && cum->arg_words < MAX_ARGS_IN_REGISTERS) 2617 { 2618 int words = (int_size_in_bytes (type) + 3) / 4; 2619 2620 if (words + cum->arg_words < MAX_ARGS_IN_REGISTERS) 2621 return 0; /* structure fits in registers */ 2622 2623 if (TARGET_DEBUG_E_MODE) 2624 fprintf (stderr, "function_arg_partial_nregs = %d\n", 2625 MAX_ARGS_IN_REGISTERS - cum->arg_words); 2626 2627 return MAX_ARGS_IN_REGISTERS - cum->arg_words; 2628 } 2629 2630 else if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS-1) 2631 { 2632 if (TARGET_DEBUG_E_MODE) 2633 fprintf (stderr, "function_arg_partial_nregs = 1\n"); 2634 2635 return 1; 2636 } 2637 2638 return 0; 2639 } 2640 2641 2642 /* Print the options used in the assembly file. */ 2643 2644 static struct {char *name; int value;} target_switches [] 2645 = TARGET_SWITCHES; 2646 2647 void 2648 print_options (out) 2649 FILE *out; 2650 { 2651 int line_len; 2652 int len; 2653 int j; 2654 char **p; 2655 int mask = TARGET_DEFAULT; 2656 2657 /* Allow assembly language comparisons with -mdebug eliminating the 2658 compiler version number and switch lists. */ 2659 2660 if (TARGET_DEBUG_MODE) 2661 return; 2662 2663 fprintf (out, "\n # %s %s", language_string, version_string); 2664 #ifdef TARGET_VERSION_INTERNAL 2665 TARGET_VERSION_INTERNAL (out); 2666 #endif 2667 #ifdef __GNUC__ 2668 fprintf (out, " compiled by GNU C\n\n"); 2669 #else 2670 fprintf (out, " compiled by CC\n\n"); 2671 #endif 2672 2673 fprintf (out, " # Cc1 defaults:"); 2674 line_len = 32767; 2675 for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++) 2676 { 2677 if (target_switches[j].name[0] != '\0' 2678 && target_switches[j].value > 0 2679 && (target_switches[j].value & mask) == target_switches[j].value) 2680 { 2681 mask &= ~ target_switches[j].value; 2682 len = strlen (target_switches[j].name) + 1; 2683 if (len + line_len > 79) 2684 { 2685 line_len = 2; 2686 fputs ("\n #", out); 2687 } 2688 fprintf (out, " -m%s", target_switches[j].name); 2689 line_len += len; 2690 } 2691 } 2692 2693 fprintf (out, "\n\n # Cc1 arguments (-G value = %d, Cpu = %s, ISA = %d):", 2694 mips_section_threshold, mips_cpu_string, mips_isa); 2695 2696 line_len = 32767; 2697 for (p = &save_argv[1]; *p != (char *)0; p++) 2698 { 2699 char *arg = *p; 2700 if (*arg == '-') 2701 { 2702 len = strlen (arg) + 1; 2703 if (len + line_len > 79) 2704 { 2705 line_len = 2; 2706 fputs ("\n #", out); 2707 } 2708 fprintf (out, " %s", *p); 2709 line_len += len; 2710 } 2711 } 2712 2713 fputs ("\n\n", out); 2714 } 2715 2716 2717 /* Abort after printing out a specific insn. */ 2718 2719 void 2720 abort_with_insn (insn, reason) 2721 rtx insn; 2722 char *reason; 2723 { 2724 error (reason); 2725 debug_rtx (insn); 2726 abort (); 2727 } 2728 2729 /* Write a message to stderr (for use in macros expanded in files that do not 2730 include stdio.h). */ 2731 2732 void 2733 trace (s, s1, s2) 2734 char *s, *s1, *s2; 2735 { 2736 fprintf (stderr, s, s1, s2); 2737 } 2738 2739 2740 #ifdef SIGINFO 2741 2742 static void 2743 siginfo (signo) 2744 int signo; 2745 { 2746 fprintf (stderr, "compiling '%s' in '%s'\n", 2747 (current_function_name != (char *)0) ? current_function_name : "<toplevel>", 2748 (current_function_file != (char *)0) ? current_function_file : "<no file>"); 2749 fflush (stderr); 2750 } 2751 #endif /* SIGINFO */ 2752 2753 2754 /* Set up the threshold for data to go into the small data area, instead 2755 of the normal data area, and detect any conflicts in the switches. */ 2756 2757 void 2758 override_options () 2759 { 2760 register int i, start; 2761 register int regno; 2762 register enum machine_mode mode; 2763 2764 if (g_switch_set) 2765 mips_section_threshold = g_switch_value; 2766 2767 else 2768 mips_section_threshold = (TARGET_MIPS_AS) ? 8 : 0; 2769 2770 /* Identify the processor type */ 2771 if (mips_cpu_string == (char *)0 2772 || !strcmp (mips_cpu_string, "default") 2773 || !strcmp (mips_cpu_string, "DEFAULT")) 2774 { 2775 mips_cpu_string = "default"; 2776 mips_cpu = PROCESSOR_DEFAULT; 2777 } 2778 2779 else 2780 { 2781 char *p = mips_cpu_string; 2782 2783 if (*p == 'r' || *p == 'R') 2784 p++; 2785 2786 /* Since there is no difference between a R2000 and R3000 in 2787 terms of the scheduler, we collapse them into just an R3000. */ 2788 2789 mips_cpu = PROCESSOR_DEFAULT; 2790 switch (*p) 2791 { 2792 case '2': 2793 if (!strcmp (p, "2000") || !strcmp (p, "2k") || !strcmp (p, "2K")) 2794 mips_cpu = PROCESSOR_R3000; 2795 break; 2796 2797 case '3': 2798 if (!strcmp (p, "3000") || !strcmp (p, "3k") || !strcmp (p, "3K")) 2799 mips_cpu = PROCESSOR_R3000; 2800 break; 2801 2802 case '4': 2803 if (!strcmp (p, "4000") || !strcmp (p, "4k") || !strcmp (p, "4K")) 2804 mips_cpu = PROCESSOR_R4000; 2805 break; 2806 2807 case '6': 2808 if (!strcmp (p, "6000") || !strcmp (p, "6k") || !strcmp (p, "6K")) 2809 mips_cpu = PROCESSOR_R6000; 2810 break; 2811 } 2812 2813 if (mips_cpu == PROCESSOR_DEFAULT) 2814 { 2815 error ("bad value (%s) for -mcpu= switch", mips_cpu_string); 2816 mips_cpu_string = "default"; 2817 } 2818 } 2819 2820 /* Now get the architectural level. */ 2821 if (mips_isa_string == (char *)0) 2822 mips_isa = 1; 2823 2824 else if (isdigit (*mips_isa_string)) 2825 mips_isa = atoi (mips_isa_string); 2826 2827 else 2828 { 2829 error ("bad value (%s) for -mips switch", mips_isa_string); 2830 mips_isa = 1; 2831 } 2832 2833 if (mips_isa < 0 || mips_isa > 3) 2834 error ("-mips%d not supported", mips_isa); 2835 2836 else if (mips_isa > 1 2837 && (mips_cpu == PROCESSOR_DEFAULT || mips_cpu == PROCESSOR_R3000)) 2838 error ("-mcpu=%s does not support -mips%d", mips_cpu_string, mips_isa); 2839 2840 else if (mips_cpu == PROCESSOR_R6000 && mips_isa > 2) 2841 error ("-mcpu=%s does not support -mips%d", mips_cpu_string, mips_isa); 2842 2843 /* make sure sizes of ints/longs/etc. are ok */ 2844 if (mips_isa < 3) 2845 { 2846 if (TARGET_INT64) 2847 fatal ("Only the r4000 can support 64 bit ints"); 2848 2849 else if (TARGET_LONG64) 2850 fatal ("Only the r4000 can support 64 bit longs"); 2851 2852 else if (TARGET_LLONG128) 2853 fatal ("Only the r4000 can support 128 bit long longs"); 2854 2855 else if (TARGET_FLOAT64) 2856 fatal ("Only the r4000 can support 64 bit fp registers"); 2857 } 2858 else if (TARGET_INT64 || TARGET_LONG64 || TARGET_LLONG128 || TARGET_FLOAT64) 2859 warning ("r4000 64/128 bit types not yet supported"); 2860 2861 /* Tell halfpic.c that we have half-pic code if we do. */ 2862 if (TARGET_HALF_PIC) 2863 HALF_PIC_INIT (); 2864 2865 /* -mrnames says to use the MIPS software convention for register 2866 names instead of the hardware names (ie, a0 instead of $4). 2867 We do this by switching the names in mips_reg_names, which the 2868 reg_names points into via the REGISTER_NAMES macro. */ 2869 2870 if (TARGET_NAME_REGS) 2871 { 2872 if (TARGET_GAS) 2873 { 2874 target_flags &= ~ MASK_NAME_REGS; 2875 error ("Gas does not support the MIPS software register name convention."); 2876 } 2877 else 2878 bcopy ((char *) mips_sw_reg_names, (char *) mips_reg_names, sizeof (mips_reg_names)); 2879 } 2880 2881 /* If this is OSF/1, set up a SIGINFO handler so we can see what function 2882 is currently being compiled. */ 2883 #ifdef SIGINFO 2884 if (getenv ("GCC_SIGINFO") != (char *)0) 2885 { 2886 struct sigaction action; 2887 action.sa_handler = siginfo; 2888 action.sa_mask = 0; 2889 action.sa_flags = SA_RESTART; 2890 sigaction (SIGINFO, &action, (struct sigaction *)0); 2891 } 2892 #endif 2893 2894 #if defined(_IOLBF) 2895 #if defined(ultrix) || defined(__ultrix) || defined(__OSF1__) || defined(__osf__) || defined(osf) 2896 /* If -mstats and -quiet, make stderr line buffered. */ 2897 if (quiet_flag && TARGET_STATS) 2898 setvbuf (stderr, (char *)0, _IOLBF, BUFSIZ); 2899 #endif 2900 #endif 2901 2902 /* Set up the classification arrays now. */ 2903 mips_rtx_classify[(int)PLUS] = CLASS_ADD_OP; 2904 mips_rtx_classify[(int)MINUS] = CLASS_ADD_OP; 2905 mips_rtx_classify[(int)DIV] = CLASS_DIVMOD_OP; 2906 mips_rtx_classify[(int)MOD] = CLASS_DIVMOD_OP; 2907 mips_rtx_classify[(int)UDIV] = CLASS_DIVMOD_OP | CLASS_UNSIGNED_OP; 2908 mips_rtx_classify[(int)UMOD] = CLASS_DIVMOD_OP | CLASS_UNSIGNED_OP; 2909 mips_rtx_classify[(int)EQ] = CLASS_CMP_OP | CLASS_EQUALITY_OP | CLASS_FCMP_OP; 2910 mips_rtx_classify[(int)NE] = CLASS_CMP_OP | CLASS_EQUALITY_OP | CLASS_FCMP_OP; 2911 mips_rtx_classify[(int)GT] = CLASS_CMP_OP | CLASS_FCMP_OP; 2912 mips_rtx_classify[(int)GE] = CLASS_CMP_OP | CLASS_FCMP_OP; 2913 mips_rtx_classify[(int)LT] = CLASS_CMP_OP | CLASS_FCMP_OP; 2914 mips_rtx_classify[(int)LE] = CLASS_CMP_OP | CLASS_FCMP_OP; 2915 mips_rtx_classify[(int)GTU] = CLASS_CMP_OP | CLASS_UNSIGNED_OP; 2916 mips_rtx_classify[(int)GEU] = CLASS_CMP_OP | CLASS_UNSIGNED_OP; 2917 mips_rtx_classify[(int)LTU] = CLASS_CMP_OP | CLASS_UNSIGNED_OP; 2918 mips_rtx_classify[(int)LEU] = CLASS_CMP_OP | CLASS_UNSIGNED_OP; 2919 2920 mips_print_operand_punct['?'] = TRUE; 2921 mips_print_operand_punct['#'] = TRUE; 2922 mips_print_operand_punct['&'] = TRUE; 2923 mips_print_operand_punct['!'] = TRUE; 2924 mips_print_operand_punct['*'] = TRUE; 2925 mips_print_operand_punct['@'] = TRUE; 2926 mips_print_operand_punct['.'] = TRUE; 2927 mips_print_operand_punct['('] = TRUE; 2928 mips_print_operand_punct[')'] = TRUE; 2929 mips_print_operand_punct['['] = TRUE; 2930 mips_print_operand_punct[']'] = TRUE; 2931 mips_print_operand_punct['<'] = TRUE; 2932 mips_print_operand_punct['>'] = TRUE; 2933 mips_print_operand_punct['{'] = TRUE; 2934 mips_print_operand_punct['}'] = TRUE; 2935 2936 mips_char_to_class['d'] = GR_REGS; 2937 mips_char_to_class['f'] = ((TARGET_HARD_FLOAT) ? FP_REGS : NO_REGS); 2938 mips_char_to_class['h'] = HI_REG; 2939 mips_char_to_class['l'] = LO_REG; 2940 mips_char_to_class['x'] = MD_REGS; 2941 mips_char_to_class['y'] = GR_REGS; 2942 mips_char_to_class['z'] = ST_REGS; 2943 2944 /* Set up array to map GCC register number to debug register number. 2945 Ignore the special purpose register numbers. */ 2946 2947 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 2948 mips_dbx_regno[i] = -1; 2949 2950 start = GP_DBX_FIRST - GP_REG_FIRST; 2951 for (i = GP_REG_FIRST; i <= GP_REG_LAST; i++) 2952 mips_dbx_regno[i] = i + start; 2953 2954 start = FP_DBX_FIRST - FP_REG_FIRST; 2955 for (i = FP_REG_FIRST; i <= FP_REG_LAST; i++) 2956 mips_dbx_regno[i] = i + start; 2957 2958 /* Set up array giving whether a given register can hold a given mode. 2959 At present, restrict ints from being in FP registers, because reload 2960 is a little enthusiastic about storing extra values in FP registers, 2961 and this is not good for things like OS kernels. Also, due to the 2962 mandatory delay, it is as fast to load from cached memory as to move 2963 from the FP register. */ 2964 2965 for (mode = VOIDmode; 2966 mode != MAX_MACHINE_MODE; 2967 mode = (enum machine_mode)((int)mode + 1)) 2968 { 2969 register int size = GET_MODE_SIZE (mode); 2970 register enum mode_class class = GET_MODE_CLASS (mode); 2971 2972 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 2973 { 2974 register int temp; 2975 2976 if (mode == CC_FPmode || mode == CC_REV_FPmode) 2977 temp = (regno == FPSW_REGNUM); 2978 2979 else if (GP_REG_P (regno)) 2980 temp = ((regno & 1) == 0 || (size <= UNITS_PER_WORD)); 2981 2982 else if (FP_REG_P (regno)) 2983 temp = ((TARGET_FLOAT64 || ((regno & 1) == 0)) 2984 && (class == MODE_FLOAT 2985 || class == MODE_COMPLEX_FLOAT 2986 || (TARGET_DEBUG_H_MODE && class == MODE_INT))); 2987 2988 else if (MD_REG_P (regno)) 2989 temp = (mode == SImode || (regno == MD_REG_FIRST && mode == DImode)); 2990 2991 else 2992 temp = FALSE; 2993 2994 mips_hard_regno_mode_ok[(int)mode][regno] = temp; 2995 } 2996 } 2997 } 2998 2999 3000 /* 3001 * The MIPS debug format wants all automatic variables and arguments 3002 * to be in terms of the virtual frame pointer (stack pointer before 3003 * any adjustment in the function), while the MIPS 3.0 linker wants 3004 * the frame pointer to be the stack pointer after the initial 3005 * adjustment. So, we do the adjustment here. The arg pointer (which 3006 * is eliminated) points to the virtual frame pointer, while the frame 3007 * pointer (which may be eliminated) points to the stack pointer after 3008 * the initial adjustments. 3009 */ 3010 3011 int 3012 mips_debugger_offset (addr, offset) 3013 rtx addr; 3014 int offset; 3015 { 3016 rtx offset2 = const0_rtx; 3017 rtx reg = eliminate_constant_term (addr, &offset2); 3018 3019 if (!offset) 3020 offset = INTVAL (offset2); 3021 3022 if (reg == stack_pointer_rtx || reg == frame_pointer_rtx) 3023 { 3024 int frame_size = (!current_frame_info.initialized) 3025 ? compute_frame_size (get_frame_size ()) 3026 : current_frame_info.total_size; 3027 3028 offset = offset - frame_size; 3029 } 3030 /* sdbout_parms does not want this to crash for unrecognized cases. */ 3031 #if 0 3032 else if (reg != arg_pointer_rtx) 3033 abort_with_insn (addr, "mips_debugger_offset called with non stack/frame/arg pointer."); 3034 #endif 3035 3036 return offset; 3037 } 3038 3039 3040 /* A C compound statement to output to stdio stream STREAM the 3041 assembler syntax for an instruction operand X. X is an RTL 3042 expression. 3043 3044 CODE is a value that can be used to specify one of several ways 3045 of printing the operand. It is used when identical operands 3046 must be printed differently depending on the context. CODE 3047 comes from the `%' specification that was used to request 3048 printing of the operand. If the specification was just `%DIGIT' 3049 then CODE is 0; if the specification was `%LTR DIGIT' then CODE 3050 is the ASCII code for LTR. 3051 3052 If X is a register, this macro should print the register's name. 3053 The names can be found in an array `reg_names' whose type is 3054 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'. 3055 3056 When the machine description has a specification `%PUNCT' (a `%' 3057 followed by a punctuation character), this macro is called with 3058 a null pointer for X and the punctuation character for CODE. 3059 3060 The MIPS specific codes are: 3061 3062 'X' X is CONST_INT, prints 32 bits in hexadecimal format = "0x%08x", 3063 'x' X is CONST_INT, prints 16 bits in hexadecimal format = "0x%04x", 3064 'd' output integer constant in decimal, 3065 'z' if the operand is 0, use $0 instead of normal operand. 3066 'D' print second register of double-word register operand. 3067 'L' print low-order register of double-word register operand. 3068 'M' print high-order register of double-word register operand. 3069 'C' print part of opcode for a branch condition. 3070 'N' print part of opcode for a branch condition, inverted. 3071 '(' Turn on .set noreorder 3072 ')' Turn on .set reorder 3073 '[' Turn on .set noat 3074 ']' Turn on .set at 3075 '<' Turn on .set nomacro 3076 '>' Turn on .set macro 3077 '{' Turn on .set volatile (not GAS) 3078 '}' Turn on .set novolatile (not GAS) 3079 '&' Turn on .set noreorder if filling delay slots 3080 '*' Turn on both .set noreorder and .set nomacro if filling delay slots 3081 '!' Turn on .set nomacro if filling delay slots 3082 '#' Print nop if in a .set noreorder section. 3083 '?' Print 'l' if we are to use a branch likely instead of normal branch. 3084 '@' Print the name of the assembler temporary register (at or $1). 3085 '.' Print the name of the register with a hard-wired zero (zero or $0). */ 3086 3087 void 3088 print_operand (file, op, letter) 3089 FILE *file; /* file to write to */ 3090 rtx op; /* operand to print */ 3091 int letter; /* %<letter> or 0 */ 3092 { 3093 register enum rtx_code code; 3094 3095 if (PRINT_OPERAND_PUNCT_VALID_P (letter)) 3096 { 3097 switch (letter) 3098 { 3099 default: 3100 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter); 3101 break; 3102 3103 case '?': 3104 if (mips_branch_likely) 3105 putc ('l', file); 3106 break; 3107 3108 case '@': 3109 fputs (reg_names [GP_REG_FIRST + 1], file); 3110 break; 3111 3112 case '.': 3113 fputs (reg_names [GP_REG_FIRST + 0], file); 3114 break; 3115 3116 case '&': 3117 if (final_sequence != 0 && set_noreorder++ == 0) 3118 fputs (".set\tnoreorder\n\t", file); 3119 break; 3120 3121 case '*': 3122 if (final_sequence != 0) 3123 { 3124 if (set_noreorder++ == 0) 3125 fputs (".set\tnoreorder\n\t", file); 3126 3127 if (set_nomacro++ == 0) 3128 fputs (".set\tnomacro\n\t", file); 3129 } 3130 break; 3131 3132 case '!': 3133 if (final_sequence != 0 && set_nomacro++ == 0) 3134 fputs ("\n\t.set\tnomacro", file); 3135 break; 3136 3137 case '#': 3138 if (set_noreorder != 0) 3139 fputs ("\n\tnop", file); 3140 3141 else if (TARGET_GAS || TARGET_STATS) 3142 fputs ("\n\t#nop", file); 3143 3144 break; 3145 3146 case '(': 3147 if (set_noreorder++ == 0) 3148 fputs (".set\tnoreorder\n\t", file); 3149 break; 3150 3151 case ')': 3152 if (set_noreorder == 0) 3153 error ("internal error: %%) found without a %%( in assembler pattern"); 3154 3155 else if (--set_noreorder == 0) 3156 fputs ("\n\t.set\treorder", file); 3157 3158 break; 3159 3160 case '[': 3161 if (set_noat++ == 0) 3162 fputs (".set\tnoat\n\t", file); 3163 break; 3164 3165 case ']': 3166 if (set_noat == 0) 3167 error ("internal error: %%] found without a %%[ in assembler pattern"); 3168 3169 else if (--set_noat == 0) 3170 fputs ("\n\t.set\tat", file); 3171 3172 break; 3173 3174 case '<': 3175 if (set_nomacro++ == 0) 3176 fputs (".set\tnomacro\n\t", file); 3177 break; 3178 3179 case '>': 3180 if (set_nomacro == 0) 3181 error ("internal error: %%> found without a %%< in assembler pattern"); 3182 3183 else if (--set_nomacro == 0) 3184 fputs ("\n\t.set\tmacro", file); 3185 3186 break; 3187 3188 case '{': 3189 if (set_volatile++ == 0) 3190 fprintf (file, "%s.set\tvolatile\n\t", (TARGET_MIPS_AS) ? "" : "#"); 3191 break; 3192 3193 case '}': 3194 if (set_volatile == 0) 3195 error ("internal error: %%} found without a %%{ in assembler pattern"); 3196 3197 else if (--set_volatile == 0) 3198 fprintf (file, "\n\t%s.set\tnovolatile", (TARGET_MIPS_AS) ? "" : "#"); 3199 3200 break; 3201 } 3202 return; 3203 } 3204 3205 if (! op) 3206 { 3207 error ("PRINT_OPERAND null pointer"); 3208 return; 3209 } 3210 3211 code = GET_CODE (op); 3212 if (letter == 'C') 3213 switch (code) 3214 { 3215 case EQ: fputs ("eq", file); break; 3216 case NE: fputs ("ne", file); break; 3217 case GT: fputs ("gt", file); break; 3218 case GE: fputs ("ge", file); break; 3219 case LT: fputs ("lt", file); break; 3220 case LE: fputs ("le", file); break; 3221 case GTU: fputs ("gtu", file); break; 3222 case GEU: fputs ("geu", file); break; 3223 case LTU: fputs ("ltu", file); break; 3224 case LEU: fputs ("leu", file); break; 3225 3226 default: 3227 abort_with_insn (op, "PRINT_OPERAND, illegal insn for %%C"); 3228 } 3229 3230 else if (letter == 'N') 3231 switch (code) 3232 { 3233 case EQ: fputs ("ne", file); break; 3234 case NE: fputs ("eq", file); break; 3235 case GT: fputs ("le", file); break; 3236 case GE: fputs ("lt", file); break; 3237 case LT: fputs ("ge", file); break; 3238 case LE: fputs ("gt", file); break; 3239 case GTU: fputs ("leu", file); break; 3240 case GEU: fputs ("ltu", file); break; 3241 case LTU: fputs ("geu", file); break; 3242 case LEU: fputs ("gtu", file); break; 3243 3244 default: 3245 abort_with_insn (op, "PRINT_OPERAND, illegal insn for %%N"); 3246 } 3247 3248 else if (code == REG) 3249 { 3250 register int regnum = REGNO (op); 3251 3252 if (letter == 'M') 3253 regnum += MOST_SIGNIFICANT_WORD; 3254 3255 else if (letter == 'L') 3256 regnum += LEAST_SIGNIFICANT_WORD; 3257 3258 else if (letter == 'D') 3259 regnum++; 3260 3261 fprintf (file, "%s", reg_names[regnum]); 3262 } 3263 3264 else if (code == MEM) 3265 output_address (XEXP (op, 0)); 3266 3267 else if (code == CONST_DOUBLE) 3268 { 3269 #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT 3270 union { double d; int i[2]; } u; 3271 u.i[0] = CONST_DOUBLE_LOW (op); 3272 u.i[1] = CONST_DOUBLE_HIGH (op); 3273 if (GET_MODE (op) == SFmode) 3274 { 3275 float f; 3276 f = u.d; 3277 u.d = f; 3278 } 3279 fprintf (file, "%.20e", u.d); 3280 #else 3281 fatal ("CONST_DOUBLE found in cross compilation"); 3282 #endif 3283 } 3284 3285 else if ((letter == 'x') && (GET_CODE(op) == CONST_INT)) 3286 fprintf (file, "0x%04x", 0xffff & (INTVAL(op))); 3287 3288 else if ((letter == 'X') && (GET_CODE(op) == CONST_INT)) 3289 fprintf (file, "0x%08x", INTVAL(op)); 3290 3291 else if ((letter == 'd') && (GET_CODE(op) == CONST_INT)) 3292 fprintf (file, "%d", (INTVAL(op))); 3293 3294 else if (letter == 'z' 3295 && (GET_CODE (op) == CONST_INT) 3296 && INTVAL (op) == 0) 3297 fputs (reg_names[GP_REG_FIRST], file); 3298 3299 else if (letter == 'd' || letter == 'x' || letter == 'X') 3300 fatal ("PRINT_OPERAND: letter %c was found & insn was not CONST_INT", letter); 3301 3302 else 3303 output_addr_const (file, op); 3304 } 3305 3306 3307 /* A C compound statement to output to stdio stream STREAM the 3308 assembler syntax for an instruction operand that is a memory 3309 reference whose address is ADDR. ADDR is an RTL expression. 3310 3311 On some machines, the syntax for a symbolic address depends on 3312 the section that the address refers to. On these machines, 3313 define the macro `ENCODE_SECTION_INFO' to store the information 3314 into the `symbol_ref', and then check for it here. */ 3315 3316 void 3317 print_operand_address (file, addr) 3318 FILE *file; 3319 rtx addr; 3320 { 3321 if (!addr) 3322 error ("PRINT_OPERAND_ADDRESS, null pointer"); 3323 3324 else 3325 switch (GET_CODE (addr)) 3326 { 3327 default: 3328 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, illegal insn #1"); 3329 break; 3330 3331 case REG: 3332 if (REGNO (addr) == ARG_POINTER_REGNUM) 3333 abort_with_insn (addr, "Arg pointer not eliminated."); 3334 3335 fprintf (file, "0(%s)", reg_names [REGNO (addr)]); 3336 break; 3337 3338 case PLUS: 3339 { 3340 register rtx reg = (rtx)0; 3341 register rtx offset = (rtx)0; 3342 register rtx arg0 = XEXP (addr, 0); 3343 register rtx arg1 = XEXP (addr, 1); 3344 3345 if (GET_CODE (arg0) == REG) 3346 { 3347 reg = arg0; 3348 offset = arg1; 3349 if (GET_CODE (offset) == REG) 3350 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, 2 regs"); 3351 } 3352 else if (GET_CODE (arg1) == REG) 3353 { 3354 reg = arg1; 3355 offset = arg0; 3356 } 3357 else if (CONSTANT_P (arg0) && CONSTANT_P (arg1)) 3358 { 3359 output_addr_const (file, addr); 3360 break; 3361 } 3362 else 3363 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, no regs"); 3364 3365 if (!CONSTANT_P (offset)) 3366 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, illegal insn #2"); 3367 3368 if (REGNO (reg) == ARG_POINTER_REGNUM) 3369 abort_with_insn (addr, "Arg pointer not eliminated."); 3370 3371 output_addr_const (file, offset); 3372 fprintf (file, "(%s)", reg_names [REGNO (reg)]); 3373 } 3374 break; 3375 3376 case LABEL_REF: 3377 case SYMBOL_REF: 3378 case CONST_INT: 3379 case CONST: 3380 output_addr_const (file, addr); 3381 break; 3382 } 3383 } 3384 3385 3386 /* If optimizing for the global pointer, keep track of all of 3387 the externs, so that at the end of the file, we can emit 3388 the appropriate .extern declaration for them, before writing 3389 out the text section. We assume that all names passed to 3390 us are in the permanent obstack, so that they will be valid 3391 at the end of the compilation. 3392 3393 If we have -G 0, or the extern size is unknown, don't bother 3394 emitting the .externs. */ 3395 3396 int 3397 mips_output_external (file, decl, name) 3398 FILE *file; 3399 tree decl; 3400 char *name; 3401 { 3402 register struct extern_list *p; 3403 int len; 3404 3405 if (TARGET_GP_OPT 3406 && mips_section_threshold != 0 3407 && ((TREE_CODE (decl)) != FUNCTION_DECL) 3408 && ((len = int_size_in_bytes (TREE_TYPE (decl))) > 0)) 3409 { 3410 p = (struct extern_list *)permalloc ((long) sizeof (struct extern_list)); 3411 p->next = extern_head; 3412 p->name = name; 3413 p->size = len; 3414 extern_head = p; 3415 } 3416 return 0; 3417 } 3418 3419 3420 /* Compute a string to use as a temporary file name. */ 3421 3422 static FILE * 3423 make_temp_file () 3424 { 3425 FILE *stream; 3426 char *base = getenv ("TMPDIR"); 3427 int len; 3428 3429 if (base == (char *)0) 3430 { 3431 #ifdef P_tmpdir 3432 if (access (P_tmpdir, R_OK | W_OK) == 0) 3433 base = P_tmpdir; 3434 else 3435 #endif 3436 if (access ("/usr/tmp", R_OK | W_OK) == 0) 3437 base = "/usr/tmp/"; 3438 else 3439 base = "/tmp/"; 3440 } 3441 3442 len = strlen (base); 3443 temp_filename = (char *) alloca (len + sizeof("/ccXXXXXX")); 3444 strcpy (temp_filename, base); 3445 if (len > 0 && temp_filename[len-1] != '/') 3446 temp_filename[len++] = '/'; 3447 3448 strcpy (temp_filename + len, "ccXXXXXX"); 3449 mktemp (temp_filename); 3450 3451 stream = fopen (temp_filename, "w+"); 3452 if (!stream) 3453 pfatal_with_name (temp_filename); 3454 3455 unlink (temp_filename); 3456 return stream; 3457 } 3458 3459 3460 /* Emit a new filename to a stream. If this is MIPS ECOFF, watch out 3461 for .file's that start within a function. If we are smuggling stabs, try to 3462 put out a MIPS ECOFF file and a stab. */ 3463 3464 void 3465 mips_output_filename (stream, name) 3466 FILE *stream; 3467 char *name; 3468 { 3469 static int first_time = TRUE; 3470 char ltext_label_name[100]; 3471 3472 if (first_time) 3473 { 3474 first_time = FALSE; 3475 SET_FILE_NUMBER (); 3476 current_function_file = name; 3477 fprintf (stream, "\t.file\t%d \"%s\"\n", num_source_filenames, name); 3478 if (!TARGET_GAS && write_symbols == DBX_DEBUG) 3479 fprintf (stream, "\t#@stabs\n"); 3480 } 3481 3482 else if (write_symbols == DBX_DEBUG) 3483 { 3484 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0); 3485 fprintf (stream, "%s \"%s\",%d,0,0,%s\n", ASM_STABS_OP, 3486 name, N_SOL, <ext_label_name[1]); 3487 } 3488 3489 else if (name != current_function_file 3490 && strcmp (name, current_function_file) != 0) 3491 { 3492 if (inside_function && !TARGET_GAS) 3493 { 3494 if (!file_in_function_warning) 3495 { 3496 file_in_function_warning = TRUE; 3497 ignore_line_number = TRUE; 3498 warning ("MIPS ECOFF format does not allow changing filenames within functions with #line"); 3499 } 3500 3501 fprintf (stream, "\t#.file\t%d \"%s\"\n", num_source_filenames, name); 3502 } 3503 3504 else 3505 { 3506 SET_FILE_NUMBER (); 3507 current_function_file = name; 3508 fprintf (stream, "\t.file\t%d \"%s\"\n", num_source_filenames, name); 3509 } 3510 } 3511 } 3512 3513 3514 /* Emit a linenumber. For encapsulated stabs, we need to put out a stab 3515 as well as a .loc, since it is possible that MIPS ECOFF might not be 3516 able to represent the location for inlines that come from a different 3517 file. */ 3518 3519 void 3520 mips_output_lineno (stream, line) 3521 FILE *stream; 3522 int line; 3523 { 3524 if (write_symbols == DBX_DEBUG) 3525 { 3526 fprintf (stream, "\t%s %d,0,%d\n", ASM_STABD_OP, N_SLINE, line); 3527 } 3528 3529 else 3530 { 3531 fprintf (stream, "\n\t%s.loc\t%d %d\n", 3532 (ignore_line_number) ? "#" : "", 3533 num_source_filenames, line); 3534 3535 LABEL_AFTER_LOC (stream); 3536 } 3537 } 3538 3539 3540 /* If defined, a C statement to be executed just prior to the 3541 output of assembler code for INSN, to modify the extracted 3542 operands so they will be output differently. 3543 3544 Here the argument OPVEC is the vector containing the operands 3545 extracted from INSN, and NOPERANDS is the number of elements of 3546 the vector which contain meaningful data for this insn. The 3547 contents of this vector are what will be used to convert the 3548 insn template into assembler code, so you can change the 3549 assembler output by changing the contents of the vector. 3550 3551 We use it to check if the current insn needs a nop in front of it 3552 because of load delays, and also to update the delay slot 3553 statistics. */ 3554 3555 void 3556 final_prescan_insn (insn, opvec, noperands) 3557 rtx insn; 3558 rtx opvec[]; 3559 int noperands; 3560 { 3561 if (dslots_number_nops > 0) 3562 { 3563 rtx pattern = PATTERN (insn); 3564 int length = get_attr_length (insn); 3565 3566 /* Do we need to emit a NOP? */ 3567 if (length == 0 3568 || (mips_load_reg != (rtx)0 && reg_mentioned_p (mips_load_reg, pattern)) 3569 || (mips_load_reg2 != (rtx)0 && reg_mentioned_p (mips_load_reg2, pattern)) 3570 || (mips_load_reg3 != (rtx)0 && reg_mentioned_p (mips_load_reg3, pattern)) 3571 || (mips_load_reg4 != (rtx)0 && reg_mentioned_p (mips_load_reg4, pattern))) 3572 fputs ((set_noreorder) ? "\tnop\n" : "\t#nop\n", asm_out_file); 3573 3574 else 3575 dslots_load_filled++; 3576 3577 while (--dslots_number_nops > 0) 3578 fputs ((set_noreorder) ? "\tnop\n" : "\t#nop\n", asm_out_file); 3579 3580 mips_load_reg = (rtx)0; 3581 mips_load_reg2 = (rtx)0; 3582 mips_load_reg3 = (rtx)0; 3583 mips_load_reg4 = (rtx)0; 3584 3585 if (set_noreorder && --set_noreorder == 0) 3586 fputs ("\t.set\treorder\n", asm_out_file); 3587 } 3588 3589 if (TARGET_STATS) 3590 { 3591 enum rtx_code code = GET_CODE (insn); 3592 if (code == JUMP_INSN || code == CALL_INSN) 3593 dslots_jump_total++; 3594 } 3595 } 3596 3597 3598 /* Output at beginning of assembler file. 3599 If we are optimizing to use the global pointer, create a temporary 3600 file to hold all of the text stuff, and write it out to the end. 3601 This is needed because the MIPS assembler is evidently one pass, 3602 and if it hasn't seen the relevant .comm/.lcomm/.extern/.sdata 3603 declaration when the code is processed, it generates a two 3604 instruction sequence. */ 3605 3606 void 3607 mips_asm_file_start (stream) 3608 FILE *stream; 3609 { 3610 ASM_OUTPUT_SOURCE_FILENAME (stream, main_input_filename); 3611 3612 /* Versions of the MIPS assembler before 2.20 generate errors 3613 if a branch inside of a .set noreorder section jumps to a 3614 label outside of the .set noreorder section. Revision 2.20 3615 just set nobopt silently rather than fixing the bug. */ 3616 3617 if (TARGET_MIPS_AS && optimize && flag_delayed_branch) 3618 fprintf (stream, "\t.set\tnobopt\n"); 3619 3620 /* Generate the pseudo ops that the Pyramid based System V.4 wants. */ 3621 if (TARGET_ABICALLS) 3622 fprintf (stream, "\t.abicalls\n"); 3623 3624 if (TARGET_GP_OPT) 3625 { 3626 asm_out_data_file = stream; 3627 asm_out_text_file = make_temp_file (); 3628 } 3629 else 3630 asm_out_data_file = asm_out_text_file = stream; 3631 3632 if (TARGET_NAME_REGS) 3633 fprintf (asm_out_file, "#include <regdef.h>\n"); 3634 3635 print_options (stream); 3636 } 3637 3638 3639 /* If we are optimizing the global pointer, emit the text section now 3640 and any small externs which did not have .comm, etc that are 3641 needed. Also, give a warning if the data area is more than 32K and 3642 -pic because 3 instructions are needed to reference the data 3643 pointers. */ 3644 3645 void 3646 mips_asm_file_end (file) 3647 FILE *file; 3648 { 3649 char buffer[8192]; 3650 tree name_tree; 3651 struct extern_list *p; 3652 int len; 3653 3654 if (HALF_PIC_P ()) 3655 HALF_PIC_FINISH (file); 3656 3657 if (TARGET_GP_OPT) 3658 { 3659 if (extern_head) 3660 fputs ("\n", file); 3661 3662 for (p = extern_head; p != 0; p = p->next) 3663 { 3664 name_tree = get_identifier (p->name); 3665 3666 /* Positively ensure only one .extern for any given symbol. */ 3667 if (! TREE_ASM_WRITTEN (name_tree)) 3668 { 3669 TREE_ASM_WRITTEN (name_tree) = 1; 3670 fputs ("\t.extern\t", file); 3671 assemble_name (file, p->name); 3672 fprintf (file, ", %d\n", p->size); 3673 } 3674 } 3675 3676 fprintf (file, "\n\t.text\n"); 3677 rewind (asm_out_text_file); 3678 if (ferror (asm_out_text_file)) 3679 fatal_io_error (temp_filename); 3680 3681 while ((len = fread (buffer, 1, sizeof (buffer), asm_out_text_file)) > 0) 3682 if (fwrite (buffer, 1, len, file) != len) 3683 pfatal_with_name (asm_file_name); 3684 3685 if (len < 0) 3686 pfatal_with_name (temp_filename); 3687 3688 if (fclose (asm_out_text_file) != 0) 3689 pfatal_with_name (temp_filename); 3690 } 3691 } 3692 3693 3694 /* Emit either a label, .comm, or .lcomm directive, and mark 3695 that the symbol is used, so that we don't emit an .extern 3696 for it in mips_asm_file_end. */ 3697 3698 void 3699 mips_declare_object (stream, name, init_string, final_string, size) 3700 FILE *stream; 3701 char *name; 3702 char *init_string; 3703 char *final_string; 3704 int size; 3705 { 3706 fputs (init_string, stream); /* "", "\t.comm\t", or "\t.lcomm\t" */ 3707 assemble_name (stream, name); 3708 fprintf (stream, final_string, size); /* ":\n", ",%u\n", ",%u\n" */ 3709 3710 if (TARGET_GP_OPT && mips_section_threshold != 0) 3711 { 3712 tree name_tree = get_identifier (name); 3713 TREE_ASM_WRITTEN (name_tree) = 1; 3714 } 3715 } 3716 3717 3718 /* Output a double precision value to the assembler. If both the 3719 host and target are IEEE, emit the values in hex. */ 3720 3721 void 3722 mips_output_double (stream, value) 3723 FILE *stream; 3724 REAL_VALUE_TYPE value; 3725 { 3726 #ifdef REAL_VALUE_TO_TARGET_DOUBLE 3727 long value_long[2]; 3728 REAL_VALUE_TO_TARGET_DOUBLE (value, value_long); 3729 3730 fprintf (stream, "\t.word\t0x%08lx\t\t# %.20g\n\t.word\t0x%08lx\n", 3731 value_long[0], value, value_long[1]); 3732 #else 3733 fprintf (stream, "\t.double\t%.20g\n", value); 3734 #endif 3735 } 3736 3737 3738 /* Output a single precision value to the assembler. If both the 3739 host and target are IEEE, emit the values in hex. */ 3740 3741 void 3742 mips_output_float (stream, value) 3743 FILE *stream; 3744 REAL_VALUE_TYPE value; 3745 { 3746 #ifdef REAL_VALUE_TO_TARGET_SINGLE 3747 long value_long; 3748 REAL_VALUE_TO_TARGET_SINGLE (value, value_long); 3749 3750 fprintf (stream, "\t.word\t0x%08lx\t\t# %.12g (float)\n", value_long, value); 3751 #else 3752 fprintf (stream, "\t.float\t%.12g\n", value); 3753 #endif 3754 } 3755 3756 3757 /* Return TRUE if any register used in the epilogue is used. This to insure 3758 any insn put into the epilogue delay slots is safe. */ 3759 3760 int 3761 epilogue_reg_mentioned_p (insn) 3762 rtx insn; 3763 { 3764 register char *fmt; 3765 register int i; 3766 register enum rtx_code code; 3767 register int regno; 3768 3769 if (insn == (rtx)0) 3770 return 0; 3771 3772 if (GET_CODE (insn) == LABEL_REF) 3773 return 0; 3774 3775 code = GET_CODE (insn); 3776 switch (code) 3777 { 3778 case REG: 3779 regno = REGNO (insn); 3780 if (regno == STACK_POINTER_REGNUM) 3781 return 1; 3782 3783 if (regno == FRAME_POINTER_REGNUM && frame_pointer_needed) 3784 return 1; 3785 3786 if (!call_used_regs[regno]) 3787 return 1; 3788 3789 if (regno != MIPS_TEMP1_REGNUM && regno != MIPS_TEMP2_REGNUM) 3790 return 0; 3791 3792 if (!current_frame_info.initialized) 3793 compute_frame_size (get_frame_size ()); 3794 3795 return (current_frame_info.total_size >= 32768); 3796 3797 case SCRATCH: 3798 case CC0: 3799 case PC: 3800 case CONST_INT: 3801 case CONST_DOUBLE: 3802 return 0; 3803 } 3804 3805 fmt = GET_RTX_FORMAT (code); 3806 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 3807 { 3808 if (fmt[i] == 'E') 3809 { 3810 register int j; 3811 for (j = XVECLEN (insn, i) - 1; j >= 0; j--) 3812 if (epilogue_reg_mentioned_p (XVECEXP (insn, i, j))) 3813 return 1; 3814 } 3815 else if (fmt[i] == 'e' && epilogue_reg_mentioned_p (XEXP (insn, i))) 3816 return 1; 3817 } 3818 3819 return 0; 3820 } 3821 3822 3823 /* Return the bytes needed to compute the frame pointer from the current 3824 stack pointer. 3825 3826 Mips stack frames look like: 3827 3828 Before call After call 3829 +-----------------------+ +-----------------------+ 3830 high | | | | 3831 mem. | | | | 3832 | caller's temps. | | caller's temps. | 3833 | | | | 3834 +-----------------------+ +-----------------------+ 3835 | | | | 3836 | arguments on stack. | | arguments on stack. | 3837 | | | | 3838 +-----------------------+ +-----------------------+ 3839 | 4 words to save | | 4 words to save | 3840 | arguments passed | | arguments passed | 3841 | in registers, even | | in registers, even | 3842 SP->| if not passed. | FP->| if not passed. | 3843 +-----------------------+ +-----------------------+ 3844 | | 3845 | GP save for V.4 abi | 3846 | | 3847 +-----------------------+ 3848 | | 3849 | fp register save | 3850 | | 3851 +-----------------------+ 3852 | | 3853 | gp register save | 3854 | | 3855 +-----------------------+ 3856 | | 3857 | local variables | 3858 | | 3859 +-----------------------+ 3860 | | 3861 | alloca allocations | 3862 | | 3863 +-----------------------+ 3864 | | 3865 | arguments on stack | 3866 | | 3867 +-----------------------+ 3868 | 4 words to save | 3869 | arguments passed | 3870 | in registers, even | 3871 low SP->| if not passed. | 3872 memory +-----------------------+ 3873 3874 */ 3875 3876 long 3877 compute_frame_size (size) 3878 int size; /* # of var. bytes allocated */ 3879 { 3880 int regno; 3881 long total_size; /* # bytes that the entire frame takes up */ 3882 long var_size; /* # bytes that variables take up */ 3883 long args_size; /* # bytes that outgoing arguments take up */ 3884 long extra_size; /* # extra bytes */ 3885 long gp_reg_rounded; /* # bytes needed to store gp after rounding */ 3886 long gp_reg_size; /* # bytes needed to store gp regs */ 3887 long fp_reg_size; /* # bytes needed to store fp regs */ 3888 long mask; /* mask of saved gp registers */ 3889 long fmask; /* mask of saved fp registers */ 3890 int fp_inc; /* 1 or 2 depending on the size of fp regs */ 3891 long fp_bits; /* bitmask to use for each fp register */ 3892 3893 gp_reg_size = 0; 3894 fp_reg_size = 0; 3895 mask = 0; 3896 fmask = 0; 3897 extra_size = MIPS_STACK_ALIGN (((TARGET_ABICALLS) ? UNITS_PER_WORD : 0)); 3898 var_size = MIPS_STACK_ALIGN (size); 3899 args_size = MIPS_STACK_ALIGN (current_function_outgoing_args_size); 3900 3901 /* The MIPS 3.0 linker does not like functions that dynamically 3902 allocate the stack and have 0 for STACK_DYNAMIC_OFFSET, since it 3903 looks like we are trying to create a second frame pointer to the 3904 function, so allocate some stack space to make it happy. */ 3905 3906 if (args_size == 0 && current_function_calls_alloca) 3907 args_size = 4*UNITS_PER_WORD; 3908 3909 total_size = var_size + args_size + extra_size; 3910 3911 /* Calculate space needed for gp registers. */ 3912 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++) 3913 { 3914 if (MUST_SAVE_REGISTER (regno)) 3915 { 3916 gp_reg_size += UNITS_PER_WORD; 3917 mask |= 1L << (regno - GP_REG_FIRST); 3918 } 3919 } 3920 3921 /* Calculate space needed for fp registers. */ 3922 if (TARGET_FLOAT64) 3923 { 3924 fp_inc = 1; 3925 fp_bits = 1; 3926 } 3927 else 3928 { 3929 fp_inc = 2; 3930 fp_bits = 3; 3931 } 3932 3933 for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno += fp_inc) 3934 { 3935 if (regs_ever_live[regno] && !call_used_regs[regno]) 3936 { 3937 fp_reg_size += 2*UNITS_PER_WORD; 3938 fmask |= fp_bits << (regno - FP_REG_FIRST); 3939 } 3940 } 3941 3942 gp_reg_rounded = MIPS_STACK_ALIGN (gp_reg_size); 3943 total_size += gp_reg_rounded + fp_reg_size; 3944 3945 if (total_size == extra_size) 3946 total_size = extra_size = 0; 3947 3948 /* Save other computed information. */ 3949 current_frame_info.total_size = total_size; 3950 current_frame_info.var_size = var_size; 3951 current_frame_info.args_size = args_size; 3952 current_frame_info.extra_size = extra_size; 3953 current_frame_info.gp_reg_size = gp_reg_size; 3954 current_frame_info.fp_reg_size = fp_reg_size; 3955 current_frame_info.mask = mask; 3956 current_frame_info.fmask = fmask; 3957 current_frame_info.initialized = reload_completed; 3958 current_frame_info.num_gp = gp_reg_size / UNITS_PER_WORD; 3959 current_frame_info.num_fp = fp_reg_size / (2*UNITS_PER_WORD); 3960 3961 if (mask) 3962 { 3963 unsigned long offset = args_size + var_size + gp_reg_size - UNITS_PER_WORD; 3964 current_frame_info.gp_sp_offset = offset; 3965 current_frame_info.gp_save_offset = offset - total_size; 3966 } 3967 else 3968 { 3969 current_frame_info.gp_sp_offset = 0; 3970 current_frame_info.gp_save_offset = 0; 3971 } 3972 3973 3974 if (fmask) 3975 { 3976 unsigned long offset = args_size + var_size + gp_reg_rounded + fp_reg_size - 2*UNITS_PER_WORD; 3977 current_frame_info.fp_sp_offset = offset; 3978 current_frame_info.fp_save_offset = offset - total_size + UNITS_PER_WORD; 3979 } 3980 else 3981 { 3982 current_frame_info.fp_sp_offset = 0; 3983 current_frame_info.fp_save_offset = 0; 3984 } 3985 3986 /* Ok, we're done. */ 3987 return total_size; 3988 } 3989 3990 3991 /* Common code to emit the insns (or to write the instructions to a file) 3992 to save/restore registers. 3993 3994 Other parts of the code assume that MIPS_TEMP1_REGNUM (aka large_reg) 3995 is not modified within save_restore_insns. */ 3996 3997 #define BITSET_P(value,bit) (((value) & (1L << (bit))) != 0) 3998 3999 static void 4000 save_restore_insns (store_p, large_reg, large_offset, file) 4001 int store_p; /* true if this is prologue */ 4002 rtx large_reg; /* register holding large offset constant or NULL */ 4003 long large_offset; /* large constant offset value */ 4004 FILE *file; /* file to write instructions to instead of making RTL */ 4005 { 4006 long mask = current_frame_info.mask; 4007 long fmask = current_frame_info.fmask; 4008 int regno; 4009 rtx base_reg_rtx; 4010 long base_offset; 4011 long gp_offset; 4012 long fp_offset; 4013 long end_offset; 4014 4015 if (frame_pointer_needed && !BITSET_P (mask, FRAME_POINTER_REGNUM - GP_REG_FIRST)) 4016 abort (); 4017 4018 if (mask == 0 && fmask == 0) 4019 return; 4020 4021 /* Save registers starting from high to low. The debuggers prefer 4022 at least the return register be stored at func+4, and also it 4023 allows us not to need a nop in the epilog if at least one 4024 register is reloaded in addition to return address. */ 4025 4026 /* Save GP registers if needed. */ 4027 if (mask) 4028 { 4029 /* Pick which pointer to use as a base register. For small 4030 frames, just use the stack pointer. Otherwise, use a 4031 temporary register. Save 2 cycles if the save area is near 4032 the end of a large frame, by reusing the constant created in 4033 the prologue/epilogue to adjust the stack frame. */ 4034 4035 gp_offset = current_frame_info.gp_sp_offset; 4036 end_offset = gp_offset - (current_frame_info.gp_reg_size - UNITS_PER_WORD); 4037 4038 if (gp_offset < 0 || end_offset < 0) 4039 fatal ("gp_offset (%ld) or end_offset (%ld) is less than zero.", 4040 gp_offset, end_offset); 4041 4042 else if (gp_offset < 32768) 4043 { 4044 base_reg_rtx = stack_pointer_rtx; 4045 base_offset = 0; 4046 } 4047 4048 else if (large_reg != (rtx)0 4049 && (((unsigned long)(large_offset - gp_offset)) < 32768) 4050 && (((unsigned long)(large_offset - end_offset)) < 32768)) 4051 { 4052 base_reg_rtx = gen_rtx (REG, Pmode, MIPS_TEMP2_REGNUM); 4053 base_offset = large_offset; 4054 if (file == (FILE *)0) 4055 emit_insn (gen_addsi3 (base_reg_rtx, large_reg, stack_pointer_rtx)); 4056 else 4057 fprintf (file, "\taddu\t%s,%s,%s\n", 4058 reg_names[MIPS_TEMP2_REGNUM], 4059 reg_names[REGNO (large_reg)], 4060 reg_names[STACK_POINTER_REGNUM]); 4061 } 4062 4063 else 4064 { 4065 base_reg_rtx = gen_rtx (REG, Pmode, MIPS_TEMP2_REGNUM); 4066 base_offset = gp_offset; 4067 if (file == (FILE *)0) 4068 { 4069 emit_move_insn (base_reg_rtx, GEN_INT (gp_offset)); 4070 emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, stack_pointer_rtx)); 4071 } 4072 else 4073 fprintf (file, "\tli\t%s,0x%.08lx\t# %ld\n\taddu\t%s,%s,%s\n", 4074 reg_names[MIPS_TEMP2_REGNUM], 4075 (long)base_offset, 4076 (long)base_offset, 4077 reg_names[MIPS_TEMP2_REGNUM], 4078 reg_names[MIPS_TEMP2_REGNUM], 4079 reg_names[STACK_POINTER_REGNUM]); 4080 } 4081 4082 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--) 4083 { 4084 if (BITSET_P (mask, regno - GP_REG_FIRST)) 4085 { 4086 if (file == (FILE *)0) 4087 { 4088 rtx reg_rtx = gen_rtx (REG, Pmode, regno); 4089 rtx mem_rtx = gen_rtx (MEM, Pmode, 4090 gen_rtx (PLUS, Pmode, base_reg_rtx, 4091 GEN_INT (gp_offset - base_offset))); 4092 4093 if (store_p) 4094 emit_move_insn (mem_rtx, reg_rtx); 4095 else 4096 emit_move_insn (reg_rtx, mem_rtx); 4097 } 4098 else 4099 fprintf (file, "\t%s\t%s,%ld(%s)\n", 4100 (store_p) ? "sw" : "lw", 4101 reg_names[regno], 4102 gp_offset - base_offset, 4103 reg_names[REGNO(base_reg_rtx)]); 4104 4105 gp_offset -= UNITS_PER_WORD; 4106 } 4107 } 4108 } 4109 else 4110 { 4111 base_reg_rtx = (rtx)0; /* Make sure these are initialzed */ 4112 base_offset = 0; 4113 } 4114 4115 /* Save floating point registers if needed. */ 4116 if (fmask) 4117 { 4118 int fp_inc = (TARGET_FLOAT64) ? 1 : 2; 4119 4120 /* Pick which pointer to use as a base register. */ 4121 fp_offset = current_frame_info.fp_sp_offset; 4122 end_offset = fp_offset - (current_frame_info.fp_reg_size - UNITS_PER_WORD); 4123 4124 if (fp_offset < 0 || end_offset < 0) 4125 fatal ("fp_offset (%ld) or end_offset (%ld) is less than zero.", 4126 fp_offset, end_offset); 4127 4128 else if (fp_offset < 32768) 4129 { 4130 base_reg_rtx = stack_pointer_rtx; 4131 base_offset = 0; 4132 } 4133 4134 else if (base_reg_rtx != (rtx)0 4135 && (((unsigned long)(base_offset - fp_offset)) < 32768) 4136 && (((unsigned long)(base_offset - end_offset)) < 32768)) 4137 { 4138 ; /* already set up for gp registers above */ 4139 } 4140 4141 else if (large_reg != (rtx)0 4142 && (((unsigned long)(large_offset - fp_offset)) < 32768) 4143 && (((unsigned long)(large_offset - end_offset)) < 32768)) 4144 { 4145 base_reg_rtx = gen_rtx (REG, Pmode, MIPS_TEMP2_REGNUM); 4146 base_offset = large_offset; 4147 if (file == (FILE *)0) 4148 emit_insn (gen_addsi3 (base_reg_rtx, large_reg, stack_pointer_rtx)); 4149 else 4150 fprintf (file, "\taddu\t%s,%s,%s\n", 4151 reg_names[MIPS_TEMP2_REGNUM], 4152 reg_names[REGNO (large_reg)], 4153 reg_names[STACK_POINTER_REGNUM]); 4154 } 4155 4156 else 4157 { 4158 base_reg_rtx = gen_rtx (REG, Pmode, MIPS_TEMP2_REGNUM); 4159 base_offset = fp_offset; 4160 if (file == (FILE *)0) 4161 { 4162 emit_move_insn (base_reg_rtx, GEN_INT (fp_offset)); 4163 emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, stack_pointer_rtx)); 4164 } 4165 else 4166 fprintf (file, "\tli\t%s,0x%.08lx\t# %ld\n\taddu\t%s,%s,%s\n", 4167 reg_names[MIPS_TEMP2_REGNUM], 4168 (long)base_offset, 4169 (long)base_offset, 4170 reg_names[MIPS_TEMP2_REGNUM], 4171 reg_names[MIPS_TEMP2_REGNUM], 4172 reg_names[STACK_POINTER_REGNUM]); 4173 } 4174 4175 for (regno = FP_REG_LAST-1; regno >= FP_REG_FIRST; regno -= fp_inc) 4176 { 4177 if (BITSET_P (fmask, regno - FP_REG_FIRST)) 4178 { 4179 if (file == (FILE *)0) 4180 { 4181 rtx reg_rtx = gen_rtx (REG, DFmode, regno); 4182 rtx mem_rtx = gen_rtx (MEM, DFmode, 4183 gen_rtx (PLUS, Pmode, base_reg_rtx, 4184 GEN_INT (fp_offset - base_offset))); 4185 4186 if (store_p) 4187 emit_move_insn (mem_rtx, reg_rtx); 4188 else 4189 emit_move_insn (reg_rtx, mem_rtx); 4190 } 4191 else 4192 fprintf (file, "\t%s\t%s,%ld(%s)\n", 4193 (store_p) ? "s.d" : "l.d", 4194 reg_names[regno], 4195 fp_offset - base_offset, 4196 reg_names[REGNO(base_reg_rtx)]); 4197 4198 4199 fp_offset -= 2*UNITS_PER_WORD; 4200 } 4201 } 4202 } 4203 } 4204 4205 4206 /* Set up the stack and frame (if desired) for the function. */ 4207 4208 void 4209 function_prologue (file, size) 4210 FILE *file; 4211 int size; 4212 { 4213 long tsize = current_frame_info.total_size; 4214 4215 ASM_OUTPUT_SOURCE_FILENAME (file, DECL_SOURCE_FILE (current_function_decl)); 4216 4217 if (debug_info_level != DINFO_LEVEL_TERSE) 4218 ASM_OUTPUT_SOURCE_LINE (file, DECL_SOURCE_LINE (current_function_decl)); 4219 4220 inside_function = 1; 4221 fputs ("\t.ent\t", file); 4222 assemble_name (file, current_function_name); 4223 fputs ("\n", file); 4224 4225 assemble_name (file, current_function_name); 4226 fputs (":\n", file); 4227 4228 if (TARGET_ABICALLS) 4229 fprintf (file, 4230 "\t.set\tnoreorder\n\t.cpload\t%s\n\t.set\treorder\n", 4231 reg_names[ GP_REG_FIRST + 25 ]); 4232 4233 tsize = current_frame_info.total_size; 4234 if (tsize > 0 && TARGET_ABICALLS) 4235 fprintf (file, "\t.cprestore %d\n", tsize + STARTING_FRAME_OFFSET); 4236 4237 fprintf (file, "\t.frame\t%s,%d,%s\t\t# vars= %d, regs= %d/%d, args = %d, extra= %d\n", 4238 reg_names[ (frame_pointer_needed) ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM ], 4239 tsize, 4240 reg_names[31 + GP_REG_FIRST], 4241 current_frame_info.var_size, 4242 current_frame_info.num_gp, 4243 current_frame_info.num_fp, 4244 current_function_outgoing_args_size, 4245 current_frame_info.extra_size); 4246 4247 fprintf (file, "\t.mask\t0x%08lx,%d\n\t.fmask\t0x%08lx,%d\n", 4248 current_frame_info.mask, 4249 current_frame_info.gp_save_offset, 4250 current_frame_info.fmask, 4251 current_frame_info.fp_save_offset); 4252 } 4253 4254 4255 /* Expand the prologue into a bunch of separate insns. */ 4256 4257 void 4258 mips_expand_prologue () 4259 { 4260 int regno; 4261 long tsize; 4262 rtx tmp_rtx = (rtx)0; 4263 char *arg_name = (char *)0; 4264 tree fndecl = current_function_decl; 4265 tree fntype = TREE_TYPE (fndecl); 4266 tree fnargs = (TREE_CODE (fntype) != METHOD_TYPE) 4267 ? DECL_ARGUMENTS (fndecl) 4268 : 0; 4269 rtx next_arg_reg; 4270 int i; 4271 tree next_arg; 4272 tree cur_arg; 4273 CUMULATIVE_ARGS args_so_far; 4274 4275 /* Determine the last argument, and get its name. */ 4276 4277 INIT_CUMULATIVE_ARGS (args_so_far, fntype, (rtx)0); 4278 regno = GP_ARG_FIRST; 4279 4280 for (cur_arg = fnargs; cur_arg != (tree)0; cur_arg = next_arg) 4281 { 4282 tree type = DECL_ARG_TYPE (cur_arg); 4283 enum machine_mode passed_mode = TYPE_MODE (type); 4284 rtx entry_parm = FUNCTION_ARG (args_so_far, 4285 passed_mode, 4286 DECL_ARG_TYPE (cur_arg), 4287 1); 4288 4289 if (entry_parm) 4290 { 4291 int words; 4292 4293 /* passed in a register, so will get homed automatically */ 4294 if (GET_MODE (entry_parm) == BLKmode) 4295 words = (int_size_in_bytes (type) + 3) / 4; 4296 else 4297 words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4; 4298 4299 regno = REGNO (entry_parm) + words - 1; 4300 } 4301 else 4302 { 4303 regno = GP_ARG_LAST+1; 4304 break; 4305 } 4306 4307 FUNCTION_ARG_ADVANCE (args_so_far, 4308 passed_mode, 4309 DECL_ARG_TYPE (cur_arg), 4310 1); 4311 4312 next_arg = TREE_CHAIN (cur_arg); 4313 if (next_arg == (tree)0) 4314 { 4315 if (DECL_NAME (cur_arg)) 4316 arg_name = IDENTIFIER_POINTER (DECL_NAME (cur_arg)); 4317 4318 break; 4319 } 4320 } 4321 4322 /* In order to pass small structures by value in registers 4323 compatibly with the MIPS compiler, we need to shift the value 4324 into the high part of the register. Function_arg has encoded a 4325 PARALLEL rtx, holding a vector of adjustments to be made as the 4326 next_arg_reg variable, so we split up the insns, and emit them 4327 separately. */ 4328 4329 next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1); 4330 if (next_arg_reg != (rtx)0 && GET_CODE (next_arg_reg) == PARALLEL) 4331 { 4332 rtvec adjust = XVEC (next_arg_reg, 0); 4333 int num = GET_NUM_ELEM (adjust); 4334 4335 for (i = 0; i < num; i++) 4336 { 4337 rtx pattern = RTVEC_ELT (adjust, i); 4338 if (GET_CODE (pattern) != SET 4339 || GET_CODE (SET_SRC (pattern)) != ASHIFT) 4340 abort_with_insn (pattern, "Insn is not a shift"); 4341 4342 PUT_CODE (SET_SRC (pattern), ASHIFTRT); 4343 emit_insn (pattern); 4344 } 4345 } 4346 4347 /* If this function is a varargs function, store any registers that 4348 would normally hold arguments ($4 - $7) on the stack. */ 4349 if ((TYPE_ARG_TYPES (fntype) != 0 4350 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) != void_type_node)) 4351 || (arg_name != (char *)0 4352 && ((arg_name[0] == '_' && strcmp (arg_name, "__builtin_va_alist") == 0) 4353 || (arg_name[0] == 'v' && strcmp (arg_name, "va_alist") == 0)))) 4354 { 4355 for (; regno <= GP_ARG_LAST; regno++) 4356 { 4357 rtx ptr = stack_pointer_rtx; 4358 if (regno != GP_ARG_FIRST) 4359 ptr = gen_rtx (PLUS, Pmode, ptr, 4360 GEN_INT ((regno - GP_ARG_FIRST) * UNITS_PER_WORD)); 4361 4362 emit_move_insn (gen_rtx (MEM, Pmode, ptr), gen_rtx (REG, Pmode, regno)); 4363 } 4364 } 4365 4366 tsize = compute_frame_size (get_frame_size ()); 4367 if (tsize > 0) 4368 { 4369 rtx tsize_rtx = GEN_INT (tsize); 4370 4371 if (tsize > 32767) 4372 { 4373 tmp_rtx = gen_rtx (REG, SImode, MIPS_TEMP1_REGNUM); 4374 emit_move_insn (tmp_rtx, tsize_rtx); 4375 tsize_rtx = tmp_rtx; 4376 } 4377 4378 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tsize_rtx)); 4379 4380 save_restore_insns (TRUE, tmp_rtx, tsize, (FILE *)0); 4381 4382 if (frame_pointer_needed) 4383 emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx)); 4384 } 4385 4386 /* If we are profiling, make sure no instructions are scheduled before 4387 the call to mcount. */ 4388 4389 if (profile_flag || profile_block_flag) 4390 emit_insn (gen_blockage ()); 4391 } 4392 4393 4394 /* Do any necessary cleanup after a function to restore stack, frame, and regs. */ 4395 4396 void 4397 function_epilogue (file, size) 4398 FILE *file; 4399 int size; 4400 { 4401 long tsize; 4402 char *sp_str = reg_names[STACK_POINTER_REGNUM]; 4403 char *t1_str = reg_names[MIPS_TEMP1_REGNUM]; 4404 rtx epilogue_delay = current_function_epilogue_delay_list; 4405 int noreorder = !TARGET_MIPS_AS || (epilogue_delay != 0); 4406 int noepilogue = FALSE; 4407 int load_nop = FALSE; 4408 int load_only_r31; 4409 rtx tmp_rtx = (rtx)0; 4410 rtx restore_rtx; 4411 int i; 4412 4413 /* The epilogue does not depend on any registers, but the stack 4414 registers, so we assume that if we have 1 pending nop, it can be 4415 ignored, and 2 it must be filled (2 nops occur for integer 4416 multiply and divide). */ 4417 4418 if (dslots_number_nops > 0) 4419 { 4420 if (dslots_number_nops == 1) 4421 { 4422 dslots_number_nops = 0; 4423 dslots_load_filled++; 4424 } 4425 else 4426 { 4427 while (--dslots_number_nops > 0) 4428 fputs ((set_noreorder) ? "\tnop\n" : "\t#nop\n", asm_out_file); 4429 } 4430 4431 if (set_noreorder > 0 && --set_noreorder == 0) 4432 fputs ("\t.set\treorder\n", file); 4433 } 4434 4435 if (set_noat != 0) 4436 { 4437 set_noat = 0; 4438 fputs ("\t.set\tat\n", file); 4439 error ("internal gcc error: .set noat left on in epilogue"); 4440 } 4441 4442 if (set_nomacro != 0) 4443 { 4444 set_nomacro = 0; 4445 fputs ("\t.set\tmacro\n", file); 4446 error ("internal gcc error: .set nomacro left on in epilogue"); 4447 } 4448 4449 if (set_noreorder != 0) 4450 { 4451 set_noreorder = 0; 4452 fputs ("\t.set\treorder\n", file); 4453 error ("internal gcc error: .set noreorder left on in epilogue"); 4454 } 4455 4456 if (set_volatile != 0) 4457 { 4458 set_volatile = 0; 4459 fprintf (file, "\t#.set\tnovolatile\n", (TARGET_MIPS_AS) ? "" : "#"); 4460 error ("internal gcc error: .set volatile left on in epilogue"); 4461 } 4462 4463 size = MIPS_STACK_ALIGN (size); 4464 tsize = (!current_frame_info.initialized) 4465 ? compute_frame_size (size) 4466 : current_frame_info.total_size; 4467 4468 if (tsize == 0 && epilogue_delay == 0) 4469 { 4470 rtx insn = get_last_insn (); 4471 4472 /* If the last insn was a BARRIER, we don't have to write any code 4473 because a jump (aka return) was put there. */ 4474 if (GET_CODE (insn) == NOTE) 4475 insn = prev_nonnote_insn (insn); 4476 if (insn && GET_CODE (insn) == BARRIER) 4477 noepilogue = TRUE; 4478 4479 noreorder = FALSE; 4480 } 4481 4482 if (!noepilogue) 4483 { 4484 /* In the reload sequence, we don't need to fill the load delay 4485 slots for most of the loads, also see if we can fill the final 4486 delay slot if not otherwise filled by the reload sequence. */ 4487 4488 if (noreorder) 4489 fprintf (file, "\t.set\tnoreorder\n"); 4490 4491 if (tsize > 32767) 4492 { 4493 fprintf (file, "\tli\t%s,0x%.08lx\t# %ld\n", t1_str, (long)tsize, (long)tsize); 4494 tmp_rtx = gen_rtx (REG, Pmode, MIPS_TEMP1_REGNUM); 4495 } 4496 4497 if (frame_pointer_needed) 4498 fprintf (file, "\tmove\t%s,%s\t\t\t# sp not trusted here\n", 4499 sp_str, reg_names[FRAME_POINTER_REGNUM]); 4500 4501 save_restore_insns (FALSE, tmp_rtx, tsize, file); 4502 4503 load_only_r31 = (current_frame_info.mask == (1 << 31) 4504 && current_frame_info.fmask == 0); 4505 4506 if (noreorder) 4507 { 4508 /* If the only register saved is the return address, we need a 4509 nop, unless we have an instruction to put into it. Otherwise 4510 we don't since reloading multiple registers doesn't reference 4511 the register being loaded. */ 4512 4513 if (load_only_r31) 4514 { 4515 if (epilogue_delay) 4516 final_scan_insn (XEXP (epilogue_delay, 0), 4517 file, 4518 1, /* optimize */ 4519 -2, /* prescan */ 4520 1); /* nopeepholes */ 4521 else 4522 { 4523 fprintf (file, "\tnop\n"); 4524 load_nop = TRUE; 4525 } 4526 } 4527 4528 fprintf (file, "\tj\t%s\n", reg_names[GP_REG_FIRST + 31]); 4529 4530 if (tsize > 32767) 4531 fprintf (file, "\taddu\t%s,%s,%s\n", sp_str, sp_str, t1_str); 4532 4533 else if (tsize > 0) 4534 fprintf (file, "\taddu\t%s,%s,%d\n", sp_str, sp_str, tsize); 4535 4536 else if (!load_only_r31 && epilogue_delay != 0) 4537 final_scan_insn (XEXP (epilogue_delay, 0), 4538 file, 4539 1, /* optimize */ 4540 -2, /* prescan */ 4541 1); /* nopeepholes */ 4542 4543 fprintf (file, "\t.set\treorder\n"); 4544 } 4545 4546 else 4547 { 4548 if (tsize > 32767) 4549 fprintf (file, "\taddu\t%s,%s,%s\n", sp_str, sp_str, t1_str); 4550 4551 else if (tsize > 0) 4552 fprintf (file, "\taddu\t%s,%s,%d\n", sp_str, sp_str, tsize); 4553 4554 fprintf (file, "\tj\t%s\n", reg_names[GP_REG_FIRST + 31]); 4555 } 4556 } 4557 4558 fputs ("\t.end\t", file); 4559 assemble_name (file, current_function_name); 4560 fputs ("\n", file); 4561 4562 if (TARGET_STATS) 4563 { 4564 int num_gp_regs = current_frame_info.gp_reg_size / 4; 4565 int num_fp_regs = current_frame_info.fp_reg_size / 8; 4566 int num_regs = num_gp_regs + num_fp_regs; 4567 char *name = current_function_name; 4568 4569 if (name[0] == '*') 4570 name++; 4571 4572 dslots_load_total += num_regs; 4573 4574 if (!noepilogue) 4575 dslots_jump_total++; 4576 4577 if (noreorder) 4578 { 4579 dslots_load_filled += num_regs; 4580 4581 /* If the only register saved is the return register, we 4582 can't fill this register's delay slot. */ 4583 4584 if (load_only_r31 && epilogue_delay == 0) 4585 dslots_load_filled--; 4586 4587 if (tsize > 0 || (!load_only_r31 && epilogue_delay != 0)) 4588 dslots_jump_filled++; 4589 } 4590 4591 fprintf (stderr, 4592 "%-20s fp=%c leaf=%c alloca=%c setjmp=%c stack=%4ld arg=%3ld reg=%2d/%d delay=%3d/%3dL %3d/%3dJ refs=%3d/%3d/%3d", 4593 name, 4594 (frame_pointer_needed) ? 'y' : 'n', 4595 ((current_frame_info.mask & (1 << 31)) != 0) ? 'n' : 'y', 4596 (current_function_calls_alloca) ? 'y' : 'n', 4597 (current_function_calls_setjmp) ? 'y' : 'n', 4598 (long)current_frame_info.total_size, 4599 (long)current_function_outgoing_args_size, 4600 num_gp_regs, num_fp_regs, 4601 dslots_load_total, dslots_load_filled, 4602 dslots_jump_total, dslots_jump_filled, 4603 num_refs[0], num_refs[1], num_refs[2]); 4604 4605 if (HALF_PIC_NUMBER_PTRS > prev_half_pic_ptrs) 4606 { 4607 fprintf (stderr, " half-pic=%3d", HALF_PIC_NUMBER_PTRS - prev_half_pic_ptrs); 4608 prev_half_pic_ptrs = HALF_PIC_NUMBER_PTRS; 4609 } 4610 4611 if (HALF_PIC_NUMBER_REFS > prev_half_pic_refs) 4612 { 4613 fprintf (stderr, " pic-ref=%3d", HALF_PIC_NUMBER_REFS - prev_half_pic_refs); 4614 prev_half_pic_refs = HALF_PIC_NUMBER_REFS; 4615 } 4616 4617 fputc ('\n', stderr); 4618 } 4619 4620 /* Reset state info for each function. */ 4621 inside_function = FALSE; 4622 ignore_line_number = FALSE; 4623 dslots_load_total = 0; 4624 dslots_jump_total = 0; 4625 dslots_load_filled = 0; 4626 dslots_jump_filled = 0; 4627 num_refs[0] = 0; 4628 num_refs[1] = 0; 4629 num_refs[2] = 0; 4630 mips_load_reg = (rtx)0; 4631 mips_load_reg2 = (rtx)0; 4632 current_frame_info = zero_frame_info; 4633 4634 /* Restore the output file if optimizing the GP (optimizing the GP causes 4635 the text to be diverted to a tempfile, so that data decls come before 4636 references to the data). */ 4637 4638 if (TARGET_GP_OPT) 4639 asm_out_file = asm_out_data_file; 4640 } 4641 4642 4643 /* Expand the epilogue into a bunch of separate insns. */ 4644 4645 void 4646 mips_expand_epilogue () 4647 { 4648 long tsize = current_frame_info.total_size; 4649 rtx tsize_rtx = GEN_INT (tsize); 4650 rtx tmp_rtx = (rtx)0; 4651 4652 if (tsize > 32767) 4653 { 4654 tmp_rtx = gen_rtx (REG, SImode, MIPS_TEMP1_REGNUM); 4655 emit_move_insn (tmp_rtx, tsize_rtx); 4656 tsize_rtx = tmp_rtx; 4657 } 4658 4659 if (tsize > 0) 4660 { 4661 if (frame_pointer_needed) 4662 emit_insn (gen_movsi (stack_pointer_rtx, frame_pointer_rtx)); 4663 4664 save_restore_insns (FALSE, tmp_rtx, tsize, (FILE *)0); 4665 4666 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, tsize_rtx)); 4667 } 4668 4669 emit_jump_insn (gen_return_internal (gen_rtx (REG, Pmode, GP_REG_FIRST+31))); 4670 } 4671 4672 4673 /* Define the number of delay slots needed for the function epilogue. 4674 4675 On the mips, we need a slot if either no stack has been allocated, 4676 or the only register saved is the return register. */ 4677 4678 int 4679 mips_epilogue_delay_slots () 4680 { 4681 if (!current_frame_info.initialized) 4682 (void) compute_frame_size (get_frame_size ()); 4683 4684 if (current_frame_info.total_size == 0) 4685 return 1; 4686 4687 if (current_frame_info.mask == (1 << 31) && current_frame_info.fmask == 0) 4688 return 1; 4689 4690 return 0; 4691 } 4692 4693 4694 /* Return true if this function is known to have a null epilogue. 4695 This allows the optimizer to omit jumps to jumps if no stack 4696 was created. */ 4697 4698 int 4699 simple_epilogue_p () 4700 { 4701 if (!reload_completed) 4702 return 0; 4703 4704 if (current_frame_info.initialized) 4705 return current_frame_info.total_size == 0; 4706 4707 return (compute_frame_size (get_frame_size ())) == 0; 4708 } 4709