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