1/* Subroutines for insn-output.c for VAX. 2 Copyright (C) 1987, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 3 2004, 2005, 2006, 2007, 2008, 2009 4 Free Software Foundation, Inc. 5 6This file is part of GCC. 7 8GCC is free software; you can redistribute it and/or modify 9it under the terms of the GNU General Public License as published by 10the Free Software Foundation; either version 3, or (at your option) 11any later version. 12 13GCC is distributed in the hope that it will be useful, 14but WITHOUT ANY WARRANTY; without even the implied warranty of 15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16GNU General Public License for more details. 17 18You should have received a copy of the GNU General Public License 19along with GCC; see the file COPYING3. If not see 20<http://www.gnu.org/licenses/>. */ 21 22#include "config.h" 23#include "system.h" 24#include "coretypes.h" 25#include "tm.h" 26#include "rtl.h" 27#include "df.h" 28#include "tree.h" 29#include "regs.h" 30#include "hard-reg-set.h" 31#include "real.h" 32#include "insn-config.h" 33#include "conditions.h" 34#include "function.h" 35#include "output.h" 36#include "insn-attr.h" 37#include "recog.h" 38#include "expr.h" 39#include "optabs.h" 40#include "flags.h" 41#include "debug.h" 42#include "toplev.h" 43#include "tm-preds.h" 44#include "tm-constrs.h" 45#include "tm_p.h" 46#include "target.h" 47#include "target-def.h" 48 49static bool vax_legitimate_address_p (enum machine_mode, rtx, bool); 50static void vax_output_function_prologue (FILE *, HOST_WIDE_INT); 51static void vax_file_start (void); 52static void vax_init_libfuncs (void); 53static void vax_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, 54 HOST_WIDE_INT, tree); 55static int vax_address_cost_1 (rtx); 56static int vax_address_cost (rtx, bool); 57static bool vax_rtx_costs (rtx, int, int, int *, bool); 58static rtx vax_struct_value_rtx (tree, int); 59static rtx vax_builtin_setjmp_frame_value (void); 60static void vax_asm_trampoline_template (FILE *); 61static void vax_trampoline_init (rtx, tree, rtx); 62 63/* Initialize the GCC target structure. */ 64#undef TARGET_ASM_ALIGNED_HI_OP 65#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t" 66 67#undef TARGET_ASM_FUNCTION_PROLOGUE 68#define TARGET_ASM_FUNCTION_PROLOGUE vax_output_function_prologue 69 70#undef TARGET_ASM_FILE_START 71#define TARGET_ASM_FILE_START vax_file_start 72#undef TARGET_ASM_FILE_START_APP_OFF 73#define TARGET_ASM_FILE_START_APP_OFF true 74 75#undef TARGET_INIT_LIBFUNCS 76#define TARGET_INIT_LIBFUNCS vax_init_libfuncs 77 78#undef TARGET_ASM_OUTPUT_MI_THUNK 79#define TARGET_ASM_OUTPUT_MI_THUNK vax_output_mi_thunk 80#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK 81#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall 82 83#undef TARGET_DEFAULT_TARGET_FLAGS 84#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT 85 86#undef TARGET_RTX_COSTS 87#define TARGET_RTX_COSTS vax_rtx_costs 88#undef TARGET_ADDRESS_COST 89#define TARGET_ADDRESS_COST vax_address_cost 90 91#undef TARGET_PROMOTE_PROTOTYPES 92#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true 93 94#undef TARGET_STRUCT_VALUE_RTX 95#define TARGET_STRUCT_VALUE_RTX vax_struct_value_rtx 96 97#undef TARGET_BUILTIN_SETJMP_FRAME_VALUE 98#define TARGET_BUILTIN_SETJMP_FRAME_VALUE vax_builtin_setjmp_frame_value 99 100#undef TARGET_LEGITIMATE_ADDRESS_P 101#define TARGET_LEGITIMATE_ADDRESS_P vax_legitimate_address_p 102 103#undef TARGET_FRAME_POINTER_REQUIRED 104#define TARGET_FRAME_POINTER_REQUIRED hook_bool_void_true 105 106#undef TARGET_ASM_TRAMPOLINE_TEMPLATE 107#define TARGET_ASM_TRAMPOLINE_TEMPLATE vax_asm_trampoline_template 108#undef TARGET_TRAMPOLINE_INIT 109#define TARGET_TRAMPOLINE_INIT vax_trampoline_init 110 111struct gcc_target targetm = TARGET_INITIALIZER; 112 113/* Set global variables as needed for the options enabled. */ 114 115void 116override_options (void) 117{ 118 /* We're VAX floating point, not IEEE floating point. */ 119 if (TARGET_G_FLOAT) 120 REAL_MODE_FORMAT (DFmode) = &vax_g_format; 121} 122 123/* Generate the assembly code for function entry. FILE is a stdio 124 stream to output the code to. SIZE is an int: how many units of 125 temporary storage to allocate. 126 127 Refer to the array `regs_ever_live' to determine which registers to 128 save; `regs_ever_live[I]' is nonzero if register number I is ever 129 used in the function. This function is responsible for knowing 130 which registers should not be saved even if used. */ 131 132static void 133vax_output_function_prologue (FILE * file, HOST_WIDE_INT size) 134{ 135 int regno; 136 int mask = 0; 137 138 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 139 if (df_regs_ever_live_p (regno) && !call_used_regs[regno]) 140 mask |= 1 << regno; 141 142 fprintf (file, "\t.word 0x%x\n", mask); 143 144 if (dwarf2out_do_frame ()) 145 { 146 const char *label = dwarf2out_cfi_label (false); 147 int offset = 0; 148 149 for (regno = FIRST_PSEUDO_REGISTER-1; regno >= 0; --regno) 150 if (df_regs_ever_live_p (regno) && !call_used_regs[regno]) 151 dwarf2out_reg_save (label, regno, offset -= 4); 152 153 dwarf2out_reg_save (label, PC_REGNUM, offset -= 4); 154 dwarf2out_reg_save (label, FRAME_POINTER_REGNUM, offset -= 4); 155 dwarf2out_reg_save (label, ARG_POINTER_REGNUM, offset -= 4); 156 dwarf2out_def_cfa (label, FRAME_POINTER_REGNUM, -(offset - 4)); 157 } 158 159 size -= STARTING_FRAME_OFFSET; 160 if (size >= 64) 161 asm_fprintf (file, "\tmovab %wd(%Rsp),%Rsp\n", -size); 162 else if (size) 163 asm_fprintf (file, "\tsubl2 $%wd,%Rsp\n", size); 164} 165 166/* When debugging with stabs, we want to output an extra dummy label 167 so that gas can distinguish between D_float and G_float prior to 168 processing the .stabs directive identifying type double. */ 169static void 170vax_file_start (void) 171{ 172 default_file_start (); 173 174 if (write_symbols == DBX_DEBUG) 175 fprintf (asm_out_file, "___vax_%c_doubles:\n", ASM_DOUBLE_CHAR); 176} 177 178/* We can use the BSD C library routines for the libgcc calls that are 179 still generated, since that's what they boil down to anyways. When 180 ELF, avoid the user's namespace. */ 181 182static void 183vax_init_libfuncs (void) 184{ 185 if (TARGET_BSD_DIVMOD) 186 { 187 set_optab_libfunc (udiv_optab, SImode, TARGET_ELF ? "*__udiv" : "*udiv"); 188 set_optab_libfunc (umod_optab, SImode, TARGET_ELF ? "*__urem" : "*urem"); 189 } 190} 191 192/* This is like nonimmediate_operand with a restriction on the type of MEM. */ 193 194static void 195split_quadword_operands (rtx insn, enum rtx_code code, rtx * operands, 196 rtx * low, int n) 197{ 198 int i; 199 200 for (i = 0; i < n; i++) 201 low[i] = 0; 202 203 for (i = 0; i < n; i++) 204 { 205 if (MEM_P (operands[i]) 206 && (GET_CODE (XEXP (operands[i], 0)) == PRE_DEC 207 || GET_CODE (XEXP (operands[i], 0)) == POST_INC)) 208 { 209 rtx addr = XEXP (operands[i], 0); 210 operands[i] = low[i] = gen_rtx_MEM (SImode, addr); 211 } 212 else if (optimize_size && MEM_P (operands[i]) 213 && REG_P (XEXP (operands[i], 0)) 214 && (code != MINUS || operands[1] != const0_rtx) 215 && find_regno_note (insn, REG_DEAD, 216 REGNO (XEXP (operands[i], 0)))) 217 { 218 low[i] = gen_rtx_MEM (SImode, 219 gen_rtx_POST_INC (Pmode, 220 XEXP (operands[i], 0))); 221 operands[i] = gen_rtx_MEM (SImode, XEXP (operands[i], 0)); 222 } 223 else 224 { 225 low[i] = operand_subword (operands[i], 0, 0, DImode); 226 operands[i] = operand_subword (operands[i], 1, 0, DImode); 227 } 228 } 229} 230 231void 232print_operand_address (FILE * file, rtx addr) 233{ 234 rtx orig = addr; 235 rtx reg1, breg, ireg; 236 rtx offset; 237 238 retry: 239 switch (GET_CODE (addr)) 240 { 241 case MEM: 242 fprintf (file, "*"); 243 addr = XEXP (addr, 0); 244 goto retry; 245 246 case REG: 247 fprintf (file, "(%s)", reg_names[REGNO (addr)]); 248 break; 249 250 case PRE_DEC: 251 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]); 252 break; 253 254 case POST_INC: 255 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]); 256 break; 257 258 case PLUS: 259 /* There can be either two or three things added here. One must be a 260 REG. One can be either a REG or a MULT of a REG and an appropriate 261 constant, and the third can only be a constant or a MEM. 262 263 We get these two or three things and put the constant or MEM in 264 OFFSET, the MULT or REG in IREG, and the REG in BREG. If we have 265 a register and can't tell yet if it is a base or index register, 266 put it into REG1. */ 267 268 reg1 = 0; ireg = 0; breg = 0; offset = 0; 269 270 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)) 271 || MEM_P (XEXP (addr, 0))) 272 { 273 offset = XEXP (addr, 0); 274 addr = XEXP (addr, 1); 275 } 276 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)) 277 || MEM_P (XEXP (addr, 1))) 278 { 279 offset = XEXP (addr, 1); 280 addr = XEXP (addr, 0); 281 } 282 else if (GET_CODE (XEXP (addr, 1)) == MULT) 283 { 284 ireg = XEXP (addr, 1); 285 addr = XEXP (addr, 0); 286 } 287 else if (GET_CODE (XEXP (addr, 0)) == MULT) 288 { 289 ireg = XEXP (addr, 0); 290 addr = XEXP (addr, 1); 291 } 292 else if (REG_P (XEXP (addr, 1))) 293 { 294 reg1 = XEXP (addr, 1); 295 addr = XEXP (addr, 0); 296 } 297 else if (REG_P (XEXP (addr, 0))) 298 { 299 reg1 = XEXP (addr, 0); 300 addr = XEXP (addr, 1); 301 } 302 else 303 { 304 debug_rtx (orig); 305 gcc_unreachable (); 306 } 307 308 if (REG_P (addr)) 309 { 310 if (reg1) 311 ireg = addr; 312 else 313 reg1 = addr; 314 } 315 else if (GET_CODE (addr) == MULT) 316 ireg = addr; 317 else if (GET_CODE (addr) == PLUS) 318 { 319 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)) 320 || MEM_P (XEXP (addr, 0))) 321 { 322 if (offset) 323 { 324 if (CONST_INT_P (offset)) 325 offset = plus_constant (XEXP (addr, 0), INTVAL (offset)); 326 else if (CONST_INT_P (XEXP (addr, 0))) 327 { 328 offset = plus_constant (offset, INTVAL (XEXP (addr, 0))); 329 } 330 else 331 { 332 debug_rtx (orig); 333 gcc_unreachable (); 334 } 335 } 336 offset = XEXP (addr, 0); 337 } 338 else if (REG_P (XEXP (addr, 0))) 339 { 340 if (reg1) 341 ireg = reg1, breg = XEXP (addr, 0), reg1 = 0; 342 else 343 reg1 = XEXP (addr, 0); 344 } 345 else if (GET_CODE (XEXP (addr, 0)) == MULT && !ireg) 346 { 347 ireg = XEXP (addr, 0); 348 } 349 else 350 { 351 debug_rtx (orig); 352 gcc_unreachable (); 353 } 354 355 if (CONSTANT_ADDRESS_P (XEXP (addr, 1)) 356 || MEM_P (XEXP (addr, 1))) 357 { 358 if (offset) 359 { 360 if (CONST_INT_P (offset)) 361 offset = plus_constant (XEXP (addr, 1), INTVAL (offset)); 362 else 363 { 364 gcc_assert (CONST_INT_P (XEXP (addr, 1))); 365 offset = plus_constant (offset, INTVAL (XEXP (addr, 1))); 366 } 367 } 368 offset = XEXP (addr, 1); 369 } 370 else if (REG_P (XEXP (addr, 1))) 371 { 372 if (reg1) 373 ireg = reg1, breg = XEXP (addr, 1), reg1 = 0; 374 else 375 reg1 = XEXP (addr, 1); 376 } 377 else if (GET_CODE (XEXP (addr, 1)) == MULT && !ireg) 378 { 379 ireg = XEXP (addr, 1); 380 } 381 else 382 { 383 debug_rtx (orig); 384 gcc_unreachable (); 385 } 386 } 387 else 388 { 389 debug_rtx (orig); 390 gcc_unreachable (); 391 } 392 393 /* If REG1 is nonzero, figure out if it is a base or index register. */ 394 if (reg1) 395 { 396 if (breg 397 || (flag_pic && GET_CODE (addr) == SYMBOL_REF) 398 || (offset 399 && (MEM_P (offset) 400 || (flag_pic && symbolic_operand (offset, SImode))))) 401 { 402 if (ireg) 403 { 404 debug_rtx (orig); 405 gcc_unreachable (); 406 } 407 ireg = reg1; 408 } 409 else 410 breg = reg1; 411 } 412 413 if (offset != 0) 414 { 415 if (flag_pic && symbolic_operand (offset, SImode)) 416 { 417 if (breg && ireg) 418 { 419 debug_rtx (orig); 420 output_operand_lossage ("symbol used with both base and indexed registers"); 421 } 422 423#ifdef NO_EXTERNAL_INDIRECT_ADDRESS 424 if (flag_pic > 1 && GET_CODE (offset) == CONST 425 && GET_CODE (XEXP (XEXP (offset, 0), 0)) == SYMBOL_REF 426 && !SYMBOL_REF_LOCAL_P (XEXP (XEXP (offset, 0), 0))) 427 { 428 debug_rtx (orig); 429 output_operand_lossage ("symbol with offset used in PIC mode"); 430 } 431#endif 432 433 /* symbol(reg) isn't PIC, but symbol[reg] is. */ 434 if (breg) 435 { 436 ireg = breg; 437 breg = 0; 438 } 439 440 } 441 442 output_address (offset); 443 } 444 445 if (breg != 0) 446 fprintf (file, "(%s)", reg_names[REGNO (breg)]); 447 448 if (ireg != 0) 449 { 450 if (GET_CODE (ireg) == MULT) 451 ireg = XEXP (ireg, 0); 452 if (! REG_P (ireg)) 453 { 454 debug_rtx (orig); 455 output_operand_lossage ("non-register index expression"); 456 } 457 fprintf (file, "[%s]", reg_names[REGNO (ireg)]); 458 } 459 break; 460 461 default: 462 gcc_assert (! REG_P(addr)); 463 output_addr_const (file, addr); 464 } 465} 466 467void 468print_operand (FILE *file, rtx x, int code) 469{ 470 if (code == '#') 471 fputc (ASM_DOUBLE_CHAR, file); 472 else if (code == '|') 473 fputs (REGISTER_PREFIX, file); 474 else if (code == 'c') 475 fputs (cond_name (x), file); 476 else if (code == 'C') 477 fputs (rev_cond_name (x), file); 478 else if (code == 'D' && CONST_INT_P (x) && INTVAL (x) < 0) 479 fprintf (file, "$" NEG_HWI_PRINT_HEX16, INTVAL (x)); 480 else if (code == 'P' && CONST_INT_P (x)) 481 fprintf (file, "$" HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + 1); 482 else if (code == 'N' && CONST_INT_P (x)) 483 fprintf (file, "$" HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x)); 484 /* rotl instruction cannot deal with negative arguments. */ 485 else if (code == 'R' && CONST_INT_P (x)) 486 fprintf (file, "$" HOST_WIDE_INT_PRINT_DEC, 32 - INTVAL (x)); 487 else if (code == 'H' && CONST_INT_P (x)) 488 fprintf (file, "$%d", (int) (0xffff & ~ INTVAL (x))); 489 else if (code == 'h' && CONST_INT_P (x)) 490 fprintf (file, "$%d", (short) - INTVAL (x)); 491 else if (code == 'B' && CONST_INT_P (x)) 492 fprintf (file, "$%d", (int) (0xff & ~ INTVAL (x))); 493 else if (code == 'b' && CONST_INT_P (x)) 494 fprintf (file, "$%d", (int) (0xff & - INTVAL (x))); 495 else if (code == 'M' && CONST_INT_P (x)) 496 fprintf (file, "$%d", ~((1 << INTVAL (x)) - 1)); 497 else if (REG_P (x)) 498 fprintf (file, "%s", reg_names[REGNO (x)]); 499 else if (MEM_P (x)) 500 output_address (XEXP (x, 0)); 501 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode) 502 { 503 char dstr[30]; 504 real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (x), 505 sizeof (dstr), 0, 1); 506 fprintf (file, "$0f%s", dstr); 507 } 508 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode) 509 { 510 char dstr[30]; 511 real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (x), 512 sizeof (dstr), 0, 1); 513 fprintf (file, "$0%c%s", ASM_DOUBLE_CHAR, dstr); 514 } 515 else 516 { 517 if (flag_pic > 1 && symbolic_operand (x, SImode)) 518 { 519 debug_rtx (x); 520 output_operand_lossage ("symbol used as immediate operand"); 521 } 522 putc ('$', file); 523 output_addr_const (file, x); 524 } 525} 526 527const char * 528cond_name (rtx op) 529{ 530 switch (GET_CODE (op)) 531 { 532 case NE: 533 return "neq"; 534 case EQ: 535 return "eql"; 536 case GE: 537 return "geq"; 538 case GT: 539 return "gtr"; 540 case LE: 541 return "leq"; 542 case LT: 543 return "lss"; 544 case GEU: 545 return "gequ"; 546 case GTU: 547 return "gtru"; 548 case LEU: 549 return "lequ"; 550 case LTU: 551 return "lssu"; 552 553 default: 554 gcc_unreachable (); 555 } 556} 557 558const char * 559rev_cond_name (rtx op) 560{ 561 switch (GET_CODE (op)) 562 { 563 case EQ: 564 return "neq"; 565 case NE: 566 return "eql"; 567 case LT: 568 return "geq"; 569 case LE: 570 return "gtr"; 571 case GT: 572 return "leq"; 573 case GE: 574 return "lss"; 575 case LTU: 576 return "gequ"; 577 case LEU: 578 return "gtru"; 579 case GTU: 580 return "lequ"; 581 case GEU: 582 return "lssu"; 583 584 default: 585 gcc_unreachable (); 586 } 587} 588 589static bool 590vax_float_literal (rtx c) 591{ 592 enum machine_mode mode; 593 REAL_VALUE_TYPE r, s; 594 int i; 595 596 if (GET_CODE (c) != CONST_DOUBLE) 597 return false; 598 599 mode = GET_MODE (c); 600 601 if (c == const_tiny_rtx[(int) mode][0] 602 || c == const_tiny_rtx[(int) mode][1] 603 || c == const_tiny_rtx[(int) mode][2]) 604 return true; 605 606 REAL_VALUE_FROM_CONST_DOUBLE (r, c); 607 608 for (i = 0; i < 7; i++) 609 { 610 int x = 1 << i; 611 bool ok; 612 REAL_VALUE_FROM_INT (s, x, 0, mode); 613 614 if (REAL_VALUES_EQUAL (r, s)) 615 return true; 616 ok = exact_real_inverse (mode, &s); 617 gcc_assert (ok); 618 if (REAL_VALUES_EQUAL (r, s)) 619 return true; 620 } 621 return false; 622} 623 624 625/* Return the cost in cycles of a memory address, relative to register 626 indirect. 627 628 Each of the following adds the indicated number of cycles: 629 630 1 - symbolic address 631 1 - pre-decrement 632 1 - indexing and/or offset(register) 633 2 - indirect */ 634 635 636static int 637vax_address_cost_1 (rtx addr) 638{ 639 int reg = 0, indexed = 0, indir = 0, offset = 0, predec = 0; 640 rtx plus_op0 = 0, plus_op1 = 0; 641 restart: 642 switch (GET_CODE (addr)) 643 { 644 case PRE_DEC: 645 predec = 1; 646 case REG: 647 case SUBREG: 648 case POST_INC: 649 reg = 1; 650 break; 651 case MULT: 652 indexed = 1; /* 2 on VAX 2 */ 653 break; 654 case CONST_INT: 655 /* byte offsets cost nothing (on a VAX 2, they cost 1 cycle) */ 656 if (offset == 0) 657 offset = (unsigned HOST_WIDE_INT)(INTVAL(addr)+128) > 256; 658 break; 659 case CONST: 660 case SYMBOL_REF: 661 offset = 1; /* 2 on VAX 2 */ 662 break; 663 case LABEL_REF: /* this is probably a byte offset from the pc */ 664 if (offset == 0) 665 offset = 1; 666 break; 667 case PLUS: 668 if (plus_op0) 669 plus_op1 = XEXP (addr, 0); 670 else 671 plus_op0 = XEXP (addr, 0); 672 addr = XEXP (addr, 1); 673 goto restart; 674 case MEM: 675 indir = 2; /* 3 on VAX 2 */ 676 addr = XEXP (addr, 0); 677 goto restart; 678 default: 679 break; 680 } 681 682 /* Up to 3 things can be added in an address. They are stored in 683 plus_op0, plus_op1, and addr. */ 684 685 if (plus_op0) 686 { 687 addr = plus_op0; 688 plus_op0 = 0; 689 goto restart; 690 } 691 if (plus_op1) 692 { 693 addr = plus_op1; 694 plus_op1 = 0; 695 goto restart; 696 } 697 /* Indexing and register+offset can both be used (except on a VAX 2) 698 without increasing execution time over either one alone. */ 699 if (reg && indexed && offset) 700 return reg + indir + offset + predec; 701 return reg + indexed + indir + offset + predec; 702} 703 704static int 705vax_address_cost (rtx x, bool speed ATTRIBUTE_UNUSED) 706{ 707 return (1 + (REG_P (x) ? 0 : vax_address_cost_1 (x))); 708} 709 710/* Cost of an expression on a VAX. This version has costs tuned for the 711 CVAX chip (found in the VAX 3 series) with comments for variations on 712 other models. 713 714 FIXME: The costs need review, particularly for TRUNCATE, FLOAT_EXTEND 715 and FLOAT_TRUNCATE. We need a -mcpu option to allow provision of 716 costs on a per cpu basis. */ 717 718static bool 719vax_rtx_costs (rtx x, int code, int outer_code, int *total, 720 bool speed ATTRIBUTE_UNUSED) 721{ 722 enum machine_mode mode = GET_MODE (x); 723 int i = 0; /* may be modified in switch */ 724 const char *fmt = GET_RTX_FORMAT (code); /* may be modified in switch */ 725 726 switch (code) 727 { 728 /* On a VAX, constants from 0..63 are cheap because they can use the 729 1 byte literal constant format. Compare to -1 should be made cheap 730 so that decrement-and-branch insns can be formed more easily (if 731 the value -1 is copied to a register some decrement-and-branch 732 patterns will not match). */ 733 case CONST_INT: 734 if (INTVAL (x) == 0) 735 { 736 *total = 0; 737 return true; 738 } 739 if (outer_code == AND) 740 { 741 *total = ((unsigned HOST_WIDE_INT) ~INTVAL (x) <= 077) ? 1 : 2; 742 return true; 743 } 744 if ((unsigned HOST_WIDE_INT) INTVAL (x) <= 077 745 || (outer_code == COMPARE 746 && INTVAL (x) == -1) 747 || ((outer_code == PLUS || outer_code == MINUS) 748 && (unsigned HOST_WIDE_INT) -INTVAL (x) <= 077)) 749 { 750 *total = 1; 751 return true; 752 } 753 /* FALLTHRU */ 754 755 case CONST: 756 case LABEL_REF: 757 case SYMBOL_REF: 758 *total = 3; 759 return true; 760 761 case CONST_DOUBLE: 762 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) 763 *total = vax_float_literal (x) ? 5 : 8; 764 else 765 *total = ((CONST_DOUBLE_HIGH (x) == 0 766 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x) < 64) 767 || (outer_code == PLUS 768 && CONST_DOUBLE_HIGH (x) == -1 769 && (unsigned HOST_WIDE_INT)-CONST_DOUBLE_LOW (x) < 64)) 770 ? 2 : 5; 771 return true; 772 773 case POST_INC: 774 *total = 2; 775 return true; /* Implies register operand. */ 776 777 case PRE_DEC: 778 *total = 3; 779 return true; /* Implies register operand. */ 780 781 case MULT: 782 switch (mode) 783 { 784 case DFmode: 785 *total = 16; /* 4 on VAX 9000 */ 786 break; 787 case SFmode: 788 *total = 9; /* 4 on VAX 9000, 12 on VAX 2 */ 789 break; 790 case DImode: 791 *total = 16; /* 6 on VAX 9000, 28 on VAX 2 */ 792 break; 793 case SImode: 794 case HImode: 795 case QImode: 796 *total = 10; /* 3-4 on VAX 9000, 20-28 on VAX 2 */ 797 break; 798 default: 799 *total = MAX_COST; /* Mode is not supported. */ 800 return true; 801 } 802 break; 803 804 case UDIV: 805 if (mode != SImode) 806 { 807 *total = MAX_COST; /* Mode is not supported. */ 808 return true; 809 } 810 *total = 17; 811 break; 812 813 case DIV: 814 if (mode == DImode) 815 *total = 30; /* Highly variable. */ 816 else if (mode == DFmode) 817 /* divide takes 28 cycles if the result is not zero, 13 otherwise */ 818 *total = 24; 819 else 820 *total = 11; /* 25 on VAX 2 */ 821 break; 822 823 case MOD: 824 *total = 23; 825 break; 826 827 case UMOD: 828 if (mode != SImode) 829 { 830 *total = MAX_COST; /* Mode is not supported. */ 831 return true; 832 } 833 *total = 29; 834 break; 835 836 case FLOAT: 837 *total = (6 /* 4 on VAX 9000 */ 838 + (mode == DFmode) + (GET_MODE (XEXP (x, 0)) != SImode)); 839 break; 840 841 case FIX: 842 *total = 7; /* 17 on VAX 2 */ 843 break; 844 845 case ASHIFT: 846 case LSHIFTRT: 847 case ASHIFTRT: 848 if (mode == DImode) 849 *total = 12; 850 else 851 *total = 10; /* 6 on VAX 9000 */ 852 break; 853 854 case ROTATE: 855 case ROTATERT: 856 *total = 6; /* 5 on VAX 2, 4 on VAX 9000 */ 857 if (CONST_INT_P (XEXP (x, 1))) 858 fmt = "e"; /* all constant rotate counts are short */ 859 break; 860 861 case PLUS: 862 case MINUS: 863 *total = (mode == DFmode) ? 13 : 8; /* 6/8 on VAX 9000, 16/15 on VAX 2 */ 864 /* Small integer operands can use subl2 and addl2. */ 865 if ((CONST_INT_P (XEXP (x, 1))) 866 && (unsigned HOST_WIDE_INT)(INTVAL (XEXP (x, 1)) + 63) < 127) 867 fmt = "e"; 868 break; 869 870 case IOR: 871 case XOR: 872 *total = 3; 873 break; 874 875 case AND: 876 /* AND is special because the first operand is complemented. */ 877 *total = 3; 878 if (CONST_INT_P (XEXP (x, 0))) 879 { 880 if ((unsigned HOST_WIDE_INT)~INTVAL (XEXP (x, 0)) > 63) 881 *total = 4; 882 fmt = "e"; 883 i = 1; 884 } 885 break; 886 887 case NEG: 888 if (mode == DFmode) 889 *total = 9; 890 else if (mode == SFmode) 891 *total = 6; 892 else if (mode == DImode) 893 *total = 4; 894 else 895 *total = 2; 896 break; 897 898 case NOT: 899 *total = 2; 900 break; 901 902 case ZERO_EXTRACT: 903 case SIGN_EXTRACT: 904 *total = 15; 905 break; 906 907 case MEM: 908 if (mode == DImode || mode == DFmode) 909 *total = 5; /* 7 on VAX 2 */ 910 else 911 *total = 3; /* 4 on VAX 2 */ 912 x = XEXP (x, 0); 913 if (!REG_P (x) && GET_CODE (x) != POST_INC) 914 *total += vax_address_cost_1 (x); 915 return true; 916 917 case FLOAT_EXTEND: 918 case FLOAT_TRUNCATE: 919 case TRUNCATE: 920 *total = 3; /* FIXME: Costs need to be checked */ 921 break; 922 923 default: 924 return false; 925 } 926 927 /* Now look inside the expression. Operands which are not registers or 928 short constants add to the cost. 929 930 FMT and I may have been adjusted in the switch above for instructions 931 which require special handling. */ 932 933 while (*fmt++ == 'e') 934 { 935 rtx op = XEXP (x, i); 936 937 i += 1; 938 code = GET_CODE (op); 939 940 /* A NOT is likely to be found as the first operand of an AND 941 (in which case the relevant cost is of the operand inside 942 the not) and not likely to be found anywhere else. */ 943 if (code == NOT) 944 op = XEXP (op, 0), code = GET_CODE (op); 945 946 switch (code) 947 { 948 case CONST_INT: 949 if ((unsigned HOST_WIDE_INT)INTVAL (op) > 63 950 && GET_MODE (x) != QImode) 951 *total += 1; /* 2 on VAX 2 */ 952 break; 953 case CONST: 954 case LABEL_REF: 955 case SYMBOL_REF: 956 *total += 1; /* 2 on VAX 2 */ 957 break; 958 case CONST_DOUBLE: 959 if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT) 960 { 961 /* Registers are faster than floating point constants -- even 962 those constants which can be encoded in a single byte. */ 963 if (vax_float_literal (op)) 964 *total += 1; 965 else 966 *total += (GET_MODE (x) == DFmode) ? 3 : 2; 967 } 968 else 969 { 970 if (CONST_DOUBLE_HIGH (op) != 0 971 || (unsigned HOST_WIDE_INT)CONST_DOUBLE_LOW (op) > 63) 972 *total += 2; 973 } 974 break; 975 case MEM: 976 *total += 1; /* 2 on VAX 2 */ 977 if (!REG_P (XEXP (op, 0))) 978 *total += vax_address_cost_1 (XEXP (op, 0)); 979 break; 980 case REG: 981 case SUBREG: 982 break; 983 default: 984 *total += 1; 985 break; 986 } 987 } 988 return true; 989} 990 991/* Output code to add DELTA to the first argument, and then jump to FUNCTION. 992 Used for C++ multiple inheritance. 993 .mask ^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11> #conservative entry mask 994 addl2 $DELTA, 4(ap) #adjust first argument 995 jmp FUNCTION+2 #jump beyond FUNCTION's entry mask 996*/ 997 998static void 999vax_output_mi_thunk (FILE * file, 1000 tree thunk ATTRIBUTE_UNUSED, 1001 HOST_WIDE_INT delta, 1002 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED, 1003 tree function) 1004{ 1005 fprintf (file, "\t.word 0x0ffc\n\taddl2 $" HOST_WIDE_INT_PRINT_DEC, delta); 1006 asm_fprintf (file, ",4(%Rap)\n"); 1007 fprintf (file, "\tjmp "); 1008 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0)); 1009 fprintf (file, "+2\n"); 1010} 1011 1012static rtx 1013vax_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED, 1014 int incoming ATTRIBUTE_UNUSED) 1015{ 1016 return gen_rtx_REG (Pmode, VAX_STRUCT_VALUE_REGNUM); 1017} 1018 1019static rtx 1020vax_builtin_setjmp_frame_value (void) 1021{ 1022 return hard_frame_pointer_rtx; 1023} 1024 1025/* Worker function for NOTICE_UPDATE_CC. */ 1026 1027void 1028vax_notice_update_cc (rtx exp, rtx insn ATTRIBUTE_UNUSED) 1029{ 1030 if (GET_CODE (exp) == SET) 1031 { 1032 if (GET_CODE (SET_SRC (exp)) == CALL) 1033 CC_STATUS_INIT; 1034 else if (GET_CODE (SET_DEST (exp)) != ZERO_EXTRACT 1035 && GET_CODE (SET_DEST (exp)) != PC) 1036 { 1037 cc_status.flags = 0; 1038 /* The integer operations below don't set carry or 1039 set it in an incompatible way. That's ok though 1040 as the Z bit is all we need when doing unsigned 1041 comparisons on the result of these insns (since 1042 they're always with 0). Set CC_NO_OVERFLOW to 1043 generate the correct unsigned branches. */ 1044 switch (GET_CODE (SET_SRC (exp))) 1045 { 1046 case NEG: 1047 if (GET_MODE_CLASS (GET_MODE (exp)) == MODE_FLOAT) 1048 break; 1049 case AND: 1050 case IOR: 1051 case XOR: 1052 case NOT: 1053 case MEM: 1054 case REG: 1055 cc_status.flags = CC_NO_OVERFLOW; 1056 break; 1057 default: 1058 break; 1059 } 1060 cc_status.value1 = SET_DEST (exp); 1061 cc_status.value2 = SET_SRC (exp); 1062 } 1063 } 1064 else if (GET_CODE (exp) == PARALLEL 1065 && GET_CODE (XVECEXP (exp, 0, 0)) == SET) 1066 { 1067 if (GET_CODE (SET_SRC (XVECEXP (exp, 0, 0))) == CALL) 1068 CC_STATUS_INIT; 1069 else if (GET_CODE (SET_DEST (XVECEXP (exp, 0, 0))) != PC) 1070 { 1071 cc_status.flags = 0; 1072 cc_status.value1 = SET_DEST (XVECEXP (exp, 0, 0)); 1073 cc_status.value2 = SET_SRC (XVECEXP (exp, 0, 0)); 1074 } 1075 else 1076 /* PARALLELs whose first element sets the PC are aob, 1077 sob insns. They do change the cc's. */ 1078 CC_STATUS_INIT; 1079 } 1080 else 1081 CC_STATUS_INIT; 1082 if (cc_status.value1 && REG_P (cc_status.value1) 1083 && cc_status.value2 1084 && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2)) 1085 cc_status.value2 = 0; 1086 if (cc_status.value1 && MEM_P (cc_status.value1) 1087 && cc_status.value2 1088 && MEM_P (cc_status.value2)) 1089 cc_status.value2 = 0; 1090 /* Actual condition, one line up, should be that value2's address 1091 depends on value1, but that is too much of a pain. */ 1092} 1093 1094/* Output integer move instructions. */ 1095 1096const char * 1097vax_output_int_move (rtx insn ATTRIBUTE_UNUSED, rtx *operands, 1098 enum machine_mode mode) 1099{ 1100 rtx hi[3], lo[3]; 1101 const char *pattern_hi, *pattern_lo; 1102 1103 switch (mode) 1104 { 1105 case DImode: 1106 if (operands[1] == const0_rtx) 1107 return "clrq %0"; 1108 if (TARGET_QMATH && optimize_size 1109 && (CONST_INT_P (operands[1]) 1110 || GET_CODE (operands[1]) == CONST_DOUBLE)) 1111 { 1112 unsigned HOST_WIDE_INT hval, lval; 1113 int n; 1114 1115 if (GET_CODE (operands[1]) == CONST_DOUBLE) 1116 { 1117 gcc_assert (HOST_BITS_PER_WIDE_INT != 64); 1118 1119 /* Make sure only the low 32 bits are valid. */ 1120 lval = CONST_DOUBLE_LOW (operands[1]) & 0xffffffff; 1121 hval = CONST_DOUBLE_HIGH (operands[1]) & 0xffffffff; 1122 } 1123 else 1124 { 1125 lval = INTVAL (operands[1]); 1126 hval = 0; 1127 } 1128 1129 /* Here we see if we are trying to see if the 64bit value is really 1130 a 6bit shifted some arbitrary amount. If so, we can use ashq to 1131 shift it to the correct value saving 7 bytes (1 addr-mode-byte + 1132 8 bytes - 1 shift byte - 1 short literal byte. */ 1133 if (lval != 0 1134 && (n = exact_log2 (lval & (- lval))) != -1 1135 && (lval >> n) < 64) 1136 { 1137 lval >>= n; 1138 1139#if HOST_BITS_PER_WIDE_INT == 32 1140 /* On 32bit platforms, if the 6bits didn't overflow into the 1141 upper 32bit value that value better be 0. If we have 1142 overflowed, make sure it wasn't too much. */ 1143 if (hval != 0) 1144 { 1145 if (n <= 26 || hval >= ((unsigned)1 << (n - 26))) 1146 n = 0; /* failure */ 1147 else 1148 lval |= hval << (32 - n); 1149 } 1150#endif 1151 /* If n is 0, then ashq is not the best way to emit this. */ 1152 if (n > 0) 1153 { 1154 operands[1] = GEN_INT (lval); 1155 operands[2] = GEN_INT (n); 1156 return "ashq %2,%D1,%0"; 1157 } 1158#if HOST_BITS_PER_WIDE_INT == 32 1159 } 1160 /* On 32bit platforms, if the low 32bit value is 0, checkout the 1161 upper 32bit value. */ 1162 else if (hval != 0 1163 && (n = exact_log2 (hval & (- hval)) - 1) != -1 1164 && (hval >> n) < 64) 1165 { 1166 operands[1] = GEN_INT (hval >> n); 1167 operands[2] = GEN_INT (n + 32); 1168 return "ashq %2,%D1,%0"; 1169#endif 1170 } 1171 } 1172 1173 if (TARGET_QMATH 1174 && (!MEM_P (operands[0]) 1175 || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC 1176 || GET_CODE (XEXP (operands[0], 0)) == POST_INC 1177 || !illegal_addsub_di_memory_operand (operands[0], DImode)) 1178 && ((CONST_INT_P (operands[1]) 1179 && (unsigned HOST_WIDE_INT) INTVAL (operands[1]) >= 64) 1180 || GET_CODE (operands[1]) == CONST_DOUBLE)) 1181 { 1182 hi[0] = operands[0]; 1183 hi[1] = operands[1]; 1184 1185 split_quadword_operands (insn, SET, hi, lo, 2); 1186 1187 pattern_lo = vax_output_int_move (NULL, lo, SImode); 1188 pattern_hi = vax_output_int_move (NULL, hi, SImode); 1189 1190 /* The patterns are just movl/movl or pushl/pushl then a movq will 1191 be shorter (1 opcode byte + 1 addrmode byte + 8 immediate value 1192 bytes .vs. 2 opcode bytes + 2 addrmode bytes + 8 immediate value 1193 value bytes. */ 1194 if ((!strncmp (pattern_lo, "movl", 4) 1195 && !strncmp (pattern_hi, "movl", 4)) 1196 || (!strncmp (pattern_lo, "pushl", 5) 1197 && !strncmp (pattern_hi, "pushl", 5))) 1198 return "movq %1,%0"; 1199 1200 if (MEM_P (operands[0]) 1201 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) 1202 { 1203 output_asm_insn (pattern_hi, hi); 1204 operands[0] = lo[0]; 1205 operands[1] = lo[1]; 1206 operands[2] = lo[2]; 1207 return pattern_lo; 1208 } 1209 else 1210 { 1211 output_asm_insn (pattern_lo, lo); 1212 operands[0] = hi[0]; 1213 operands[1] = hi[1]; 1214 operands[2] = hi[2]; 1215 return pattern_hi; 1216 } 1217 } 1218 return "movq %1,%0"; 1219 1220 case SImode: 1221 if (symbolic_operand (operands[1], SImode)) 1222 { 1223 if (push_operand (operands[0], SImode)) 1224 return "pushab %a1"; 1225 return "movab %a1,%0"; 1226 } 1227 1228 if (operands[1] == const0_rtx) 1229 { 1230 if (push_operand (operands[1], SImode)) 1231 return "pushl %1"; 1232 return "clrl %0"; 1233 } 1234 1235 if (CONST_INT_P (operands[1]) 1236 && (unsigned HOST_WIDE_INT) INTVAL (operands[1]) >= 64) 1237 { 1238 HOST_WIDE_INT i = INTVAL (operands[1]); 1239 int n; 1240 if ((unsigned HOST_WIDE_INT)(~i) < 64) 1241 return "mcoml %N1,%0"; 1242 if ((unsigned HOST_WIDE_INT)i < 0x100) 1243 return "movzbl %1,%0"; 1244 if (i >= -0x80 && i < 0) 1245 return "cvtbl %1,%0"; 1246 if (optimize_size 1247 && (n = exact_log2 (i & (-i))) != -1 1248 && ((unsigned HOST_WIDE_INT)i >> n) < 64) 1249 { 1250 operands[1] = GEN_INT ((unsigned HOST_WIDE_INT)i >> n); 1251 operands[2] = GEN_INT (n); 1252 return "ashl %2,%1,%0"; 1253 } 1254 if ((unsigned HOST_WIDE_INT)i < 0x10000) 1255 return "movzwl %1,%0"; 1256 if (i >= -0x8000 && i < 0) 1257 return "cvtwl %1,%0"; 1258 } 1259 if (push_operand (operands[0], SImode)) 1260 return "pushl %1"; 1261 return "movl %1,%0"; 1262 1263 case HImode: 1264 if (CONST_INT_P (operands[1])) 1265 { 1266 HOST_WIDE_INT i = INTVAL (operands[1]); 1267 if (i == 0) 1268 return "clrw %0"; 1269 else if ((unsigned HOST_WIDE_INT)i < 64) 1270 return "movw %1,%0"; 1271 else if ((unsigned HOST_WIDE_INT)~i < 64) 1272 return "mcomw %H1,%0"; 1273 else if ((unsigned HOST_WIDE_INT)i < 256) 1274 return "movzbw %1,%0"; 1275 else if (i >= -0x80 && i < 0) 1276 return "cvtbw %1,%0"; 1277 } 1278 return "movw %1,%0"; 1279 1280 case QImode: 1281 if (CONST_INT_P (operands[1])) 1282 { 1283 HOST_WIDE_INT i = INTVAL (operands[1]); 1284 if (i == 0) 1285 return "clrb %0"; 1286 else if ((unsigned HOST_WIDE_INT)~i < 64) 1287 return "mcomb %B1,%0"; 1288 } 1289 return "movb %1,%0"; 1290 1291 default: 1292 gcc_unreachable (); 1293 } 1294} 1295 1296/* Output integer add instructions. 1297 1298 The space-time-opcode tradeoffs for addition vary by model of VAX. 1299 1300 On a VAX 3 "movab (r1)[r2],r3" is faster than "addl3 r1,r2,r3", 1301 but it not faster on other models. 1302 1303 "movab #(r1),r2" is usually shorter than "addl3 #,r1,r2", and is 1304 faster on a VAX 3, but some VAXen (e.g. VAX 9000) will stall if 1305 a register is used in an address too soon after it is set. 1306 Compromise by using movab only when it is shorter than the add 1307 or the base register in the address is one of sp, ap, and fp, 1308 which are not modified very often. */ 1309 1310const char * 1311vax_output_int_add (rtx insn, rtx *operands, enum machine_mode mode) 1312{ 1313 switch (mode) 1314 { 1315 case DImode: 1316 { 1317 rtx low[3]; 1318 const char *pattern; 1319 int carry = 1; 1320 bool sub; 1321 1322 if (TARGET_QMATH && 0) 1323 debug_rtx (insn); 1324 1325 split_quadword_operands (insn, PLUS, operands, low, 3); 1326 1327 if (TARGET_QMATH) 1328 { 1329 gcc_assert (rtx_equal_p (operands[0], operands[1])); 1330#ifdef NO_EXTERNAL_INDIRECT_ADDRESSS 1331 gcc_assert (!flag_pic || !external_memory_operand (low[2], SImode)); 1332 gcc_assert (!flag_pic || !external_memory_operand (low[0], SImode)); 1333#endif 1334 1335 /* No reason to add a 0 to the low part and thus no carry, so just 1336 emit the appropriate add/sub instruction. */ 1337 if (low[2] == const0_rtx) 1338 return vax_output_int_add (NULL, operands, SImode); 1339 1340 /* Are we doing addition or subtraction? */ 1341 sub = CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0; 1342 1343 /* We can't use vax_output_int_add since some the patterns don't 1344 modify the carry bit. */ 1345 if (sub) 1346 { 1347 if (low[2] == constm1_rtx) 1348 pattern = "decl %0"; 1349 else 1350 pattern = "subl2 $%n2,%0"; 1351 } 1352 else 1353 { 1354 if (low[2] == const1_rtx) 1355 pattern = "incl %0"; 1356 else 1357 pattern = "addl2 %2,%0"; 1358 } 1359 output_asm_insn (pattern, low); 1360 1361 /* In 2's complement, -n = ~n + 1. Since we are dealing with 1362 two 32bit parts, we complement each and then add one to 1363 low part. We know that the low part can't overflow since 1364 it's value can never be 0. */ 1365 if (sub) 1366 return "sbwc %N2,%0"; 1367 return "adwc %2,%0"; 1368 } 1369 1370 /* Add low parts. */ 1371 if (rtx_equal_p (operands[0], operands[1])) 1372 { 1373 if (low[2] == const0_rtx) 1374 /* Should examine operand, punt if not POST_INC. */ 1375 pattern = "tstl %0", carry = 0; 1376 else if (low[2] == const1_rtx) 1377 pattern = "incl %0"; 1378 else 1379 pattern = "addl2 %2,%0"; 1380 } 1381 else 1382 { 1383 if (low[2] == const0_rtx) 1384 pattern = "movl %1,%0", carry = 0; 1385 else 1386 pattern = "addl3 %2,%1,%0"; 1387 } 1388 if (pattern) 1389 output_asm_insn (pattern, low); 1390 if (!carry) 1391 /* If CARRY is 0, we don't have any carry value to worry about. */ 1392 return get_insn_template (CODE_FOR_addsi3, insn); 1393 /* %0 = C + %1 + %2 */ 1394 if (!rtx_equal_p (operands[0], operands[1])) 1395 output_asm_insn ((operands[1] == const0_rtx 1396 ? "clrl %0" 1397 : "movl %1,%0"), operands); 1398 return "adwc %2,%0"; 1399 } 1400 1401 case SImode: 1402 if (rtx_equal_p (operands[0], operands[1])) 1403 { 1404 if (operands[2] == const1_rtx) 1405 return "incl %0"; 1406 if (operands[2] == constm1_rtx) 1407 return "decl %0"; 1408 if (CONST_INT_P (operands[2]) 1409 && (unsigned HOST_WIDE_INT) (- INTVAL (operands[2])) < 64) 1410 return "subl2 $%n2,%0"; 1411 if (CONST_INT_P (operands[2]) 1412 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 64 1413 && REG_P (operands[1]) 1414 && ((INTVAL (operands[2]) < 32767 && INTVAL (operands[2]) > -32768) 1415 || REGNO (operands[1]) > 11)) 1416 return "movab %c2(%1),%0"; 1417 if (REG_P (operands[0]) && symbolic_operand (operands[2], SImode)) 1418 return "movab %a2[%0],%0"; 1419 return "addl2 %2,%0"; 1420 } 1421 1422 if (rtx_equal_p (operands[0], operands[2])) 1423 { 1424 if (REG_P (operands[0]) && symbolic_operand (operands[1], SImode)) 1425 return "movab %a1[%0],%0"; 1426 return "addl2 %1,%0"; 1427 } 1428 1429 if (CONST_INT_P (operands[2]) 1430 && INTVAL (operands[2]) < 32767 1431 && INTVAL (operands[2]) > -32768 1432 && REG_P (operands[1]) 1433 && push_operand (operands[0], SImode)) 1434 return "pushab %c2(%1)"; 1435 1436 if (CONST_INT_P (operands[2]) 1437 && (unsigned HOST_WIDE_INT) (- INTVAL (operands[2])) < 64) 1438 return "subl3 $%n2,%1,%0"; 1439 1440 if (CONST_INT_P (operands[2]) 1441 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 64 1442 && REG_P (operands[1]) 1443 && ((INTVAL (operands[2]) < 32767 && INTVAL (operands[2]) > -32768) 1444 || REGNO (operands[1]) > 11)) 1445 return "movab %c2(%1),%0"; 1446 1447 /* Add this if using gcc on a VAX 3xxx: 1448 if (REG_P (operands[1]) && REG_P (operands[2])) 1449 return "movab (%1)[%2],%0"; 1450 */ 1451 1452 if (REG_P (operands[1]) && symbolic_operand (operands[2], SImode)) 1453 { 1454 if (push_operand (operands[0], SImode)) 1455 return "pushab %a2[%1]"; 1456 return "movab %a2[%1],%0"; 1457 } 1458 1459 if (REG_P (operands[2]) && symbolic_operand (operands[1], SImode)) 1460 { 1461 if (push_operand (operands[0], SImode)) 1462 return "pushab %a1[%2]"; 1463 return "movab %a1[%2],%0"; 1464 } 1465 1466 if (flag_pic && REG_P (operands[0]) 1467 && symbolic_operand (operands[2], SImode)) 1468 return "movab %a2,%0;addl2 %1,%0"; 1469 1470 if (flag_pic 1471 && (symbolic_operand (operands[1], SImode) 1472 || symbolic_operand (operands[1], SImode))) 1473 debug_rtx (insn); 1474 1475 return "addl3 %1,%2,%0"; 1476 1477 case HImode: 1478 if (rtx_equal_p (operands[0], operands[1])) 1479 { 1480 if (operands[2] == const1_rtx) 1481 return "incw %0"; 1482 if (operands[2] == constm1_rtx) 1483 return "decw %0"; 1484 if (CONST_INT_P (operands[2]) 1485 && (unsigned HOST_WIDE_INT) (- INTVAL (operands[2])) < 64) 1486 return "subw2 $%n2,%0"; 1487 return "addw2 %2,%0"; 1488 } 1489 if (rtx_equal_p (operands[0], operands[2])) 1490 return "addw2 %1,%0"; 1491 if (CONST_INT_P (operands[2]) 1492 && (unsigned HOST_WIDE_INT) (- INTVAL (operands[2])) < 64) 1493 return "subw3 $%n2,%1,%0"; 1494 return "addw3 %1,%2,%0"; 1495 1496 case QImode: 1497 if (rtx_equal_p (operands[0], operands[1])) 1498 { 1499 if (operands[2] == const1_rtx) 1500 return "incb %0"; 1501 if (operands[2] == constm1_rtx) 1502 return "decb %0"; 1503 if (CONST_INT_P (operands[2]) 1504 && (unsigned HOST_WIDE_INT) (- INTVAL (operands[2])) < 64) 1505 return "subb2 $%n2,%0"; 1506 return "addb2 %2,%0"; 1507 } 1508 if (rtx_equal_p (operands[0], operands[2])) 1509 return "addb2 %1,%0"; 1510 if (CONST_INT_P (operands[2]) 1511 && (unsigned HOST_WIDE_INT) (- INTVAL (operands[2])) < 64) 1512 return "subb3 $%n2,%1,%0"; 1513 return "addb3 %1,%2,%0"; 1514 1515 default: 1516 gcc_unreachable (); 1517 } 1518} 1519 1520const char * 1521vax_output_int_subtract (rtx insn, rtx *operands, enum machine_mode mode) 1522{ 1523 switch (mode) 1524 { 1525 case DImode: 1526 { 1527 rtx low[3]; 1528 const char *pattern; 1529 int carry = 1; 1530 1531 if (TARGET_QMATH && 0) 1532 debug_rtx (insn); 1533 1534 split_quadword_operands (insn, MINUS, operands, low, 3); 1535 1536 if (TARGET_QMATH) 1537 { 1538 if (operands[1] == const0_rtx && low[1] == const0_rtx) 1539 { 1540 /* Negation is tricky. It's basically complement and increment. 1541 Negate hi, then lo, and subtract the carry back. */ 1542 if ((MEM_P (low[0]) && GET_CODE (XEXP (low[0], 0)) == POST_INC) 1543 || (MEM_P (operands[0]) 1544 && GET_CODE (XEXP (operands[0], 0)) == POST_INC)) 1545 fatal_insn ("illegal operand detected", insn); 1546 output_asm_insn ("mnegl %2,%0", operands); 1547 output_asm_insn ("mnegl %2,%0", low); 1548 return "sbwc $0,%0"; 1549 } 1550 gcc_assert (rtx_equal_p (operands[0], operands[1])); 1551 gcc_assert (rtx_equal_p (low[0], low[1])); 1552 if (low[2] == const1_rtx) 1553 output_asm_insn ("decl %0", low); 1554 else 1555 output_asm_insn ("subl2 %2,%0", low); 1556 return "sbwc %2,%0"; 1557 } 1558 1559 /* Subtract low parts. */ 1560 if (rtx_equal_p (operands[0], operands[1])) 1561 { 1562 if (low[2] == const0_rtx) 1563 pattern = 0, carry = 0; 1564 else if (low[2] == constm1_rtx) 1565 pattern = "decl %0"; 1566 else 1567 pattern = "subl2 %2,%0"; 1568 } 1569 else 1570 { 1571 if (low[2] == constm1_rtx) 1572 pattern = "decl %0"; 1573 else if (low[2] == const0_rtx) 1574 pattern = get_insn_template (CODE_FOR_movsi, insn), carry = 0; 1575 else 1576 pattern = "subl3 %2,%1,%0"; 1577 } 1578 if (pattern) 1579 output_asm_insn (pattern, low); 1580 if (carry) 1581 { 1582 if (!rtx_equal_p (operands[0], operands[1])) 1583 return "movl %1,%0;sbwc %2,%0"; 1584 return "sbwc %2,%0"; 1585 /* %0 = %2 - %1 - C */ 1586 } 1587 return get_insn_template (CODE_FOR_subsi3, insn); 1588 } 1589 1590 default: 1591 gcc_unreachable (); 1592 } 1593} 1594 1595static rtx 1596mkrtx(enum rtx_code code, enum machine_mode mode, rtx base, HOST_WIDE_INT off) 1597{ 1598 rtx tmp; 1599 1600 if (GET_CODE (base) == CONST) 1601 base = XEXP (base, 0); 1602 1603 if (GET_CODE (base) == PLUS) 1604 { 1605 rtx a = XEXP (base, 0); 1606 rtx b = XEXP (base, 1); 1607 if (GET_CODE (b) == CONST) 1608 b = XEXP (b, 0); 1609 if (CONST_INT_P (b)) 1610 { 1611 off += INTVAL (b); 1612 base = a; 1613 } 1614 else if (REG_P (a) && GET_CODE (b) == SYMBOL_REF) 1615 { 1616 if (off != 0) 1617 { 1618 base = gen_rtx_PLUS (Pmode, a, plus_constant(b, off)); 1619 off = 0; 1620 } 1621 } 1622 else if (REG_P (a) && GET_CODE (b) == PLUS) 1623 { 1624 off += INTVAL (XEXP (b, 1)); 1625 base = gen_rtx_PLUS (Pmode, a, plus_constant(XEXP (b, 0), off)); 1626 off = 0; 1627 } 1628 else 1629 { 1630 debug_rtx(base); 1631 gcc_unreachable (); 1632 } 1633 } 1634 if (code == POST_INC) 1635 tmp = gen_rtx_POST_INC (SImode, base); 1636 else if (off == 0 || (REG_P (base) && code == REG)) 1637 tmp = base; 1638 else 1639 tmp = plus_constant (base, off); 1640 return gen_rtx_MEM (mode, tmp); 1641} 1642 1643const char * 1644vax_output_movmemsi (rtx insn, rtx *operands) 1645{ 1646 HOST_WIDE_INT n = INTVAL (operands[2]); 1647 HOST_WIDE_INT off; 1648 rtx src, dest; 1649 const char *pat = NULL; 1650 const enum rtx_code *src_codes; 1651 const enum rtx_code *dest_codes; 1652 int code_idx = 0; 1653 int mode_idx; 1654 1655 static const enum machine_mode xmodes[4] = 1656 { 1657 QImode, HImode, SImode, DImode 1658 }; 1659 static const char * const pats[4] = 1660 { 1661 "movb %1,%0", "movw %1,%0", "movl %1,%0", "movq %1,%0", 1662 }; 1663 static const enum rtx_code codes[2][3] = 1664 { 1665 { PLUS, PLUS, PLUS }, 1666 { POST_INC, POST_INC, REG }, 1667 }; 1668 1669 src = XEXP (operands[1], 0); 1670 1671 src_codes = 1672 codes[REG_P (src) && find_regno_note (insn, REG_DEAD, REGNO(src))]; 1673 1674 dest = XEXP (operands[0], 0); 1675 1676 dest_codes = 1677 codes[REG_P (dest) && find_regno_note (insn, REG_DEAD, REGNO(dest))]; 1678 1679 for (off = 0, code_idx = 0, mode_idx = 3; mode_idx >= 0; mode_idx--) 1680 { 1681 const enum machine_mode mode = xmodes[mode_idx]; 1682 const HOST_WIDE_INT mode_len = GET_MODE_SIZE (mode); 1683 for (; n >= mode_len; n -= mode_len, off += mode_len) 1684 { 1685 if (pat != NULL) 1686 output_asm_insn (pat, operands); 1687 if (n == mode_len) 1688 code_idx = 2; 1689 operands[0] = mkrtx(dest_codes[code_idx], mode, dest, off); 1690 operands[1] = mkrtx(src_codes[code_idx], mode, src, off); 1691 if (pat == NULL) 1692 code_idx = 1; 1693 pat = pats[mode_idx]; 1694 } 1695 } 1696 1697 return pat; 1698} 1699 1700/* True if X is an rtx for a constant that is a valid address. */ 1701 1702bool 1703legitimate_constant_address_p (rtx x) 1704{ 1705 if (GET_CODE (x) == LABEL_REF || GET_CODE (x) == SYMBOL_REF 1706 || CONST_INT_P (x) || GET_CODE (x) == HIGH) 1707 return true; 1708 if (GET_CODE (x) != CONST) 1709 return false; 1710#ifdef NO_EXTERNAL_INDIRECT_ADDRESS 1711 if (flag_pic 1712 && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF 1713 && !SYMBOL_REF_LOCAL_P (XEXP (XEXP (x, 0), 0))) 1714 return false; 1715#endif 1716 gcc_assert (! REG_P (x)); 1717 return true; 1718} 1719 1720/* True if the constant value X is a legitimate general operand. 1721 It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */ 1722 1723bool 1724legitimate_constant_p (rtx x ATTRIBUTE_UNUSED) 1725{ 1726 return true; 1727} 1728 1729/* The other macros defined here are used only in legitimate_address_p (). */ 1730 1731/* Nonzero if X is a hard reg that can be used as an index 1732 or, if not strict, if it is a pseudo reg. */ 1733#define INDEX_REGISTER_P(X, STRICT) \ 1734(REG_P (X) && (!(STRICT) || REGNO_OK_FOR_INDEX_P (REGNO (X)))) 1735 1736/* Nonzero if X is a hard reg that can be used as a base reg 1737 or, if not strict, if it is a pseudo reg. */ 1738#define BASE_REGISTER_P(X, STRICT) \ 1739(REG_P (X) && (!(STRICT) || REGNO_OK_FOR_BASE_P (REGNO (X)))) 1740 1741#ifdef NO_EXTERNAL_INDIRECT_ADDRESS 1742 1743/* Re-definition of CONSTANT_ADDRESS_P, which is true only when there 1744 are no SYMBOL_REFs for external symbols present. */ 1745 1746static bool 1747indirectable_constant_address_p (rtx x, bool indirect) 1748{ 1749 if (GET_CODE (x) == SYMBOL_REF) 1750 return !flag_pic || SYMBOL_REF_LOCAL_P (x) || !indirect; 1751 1752 if (GET_CODE (x) == CONST) 1753 return !flag_pic 1754 || GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF 1755 || SYMBOL_REF_LOCAL_P (XEXP (XEXP (x, 0), 0)); 1756 1757 return CONSTANT_ADDRESS_P (x); 1758} 1759 1760#else /* not NO_EXTERNAL_INDIRECT_ADDRESS */ 1761 1762static bool 1763indirectable_constant_address_p (rtx x, bool indirect ATTRIBUTE_UNUSED) 1764{ 1765 return CONSTANT_ADDRESS_P (x); 1766} 1767 1768#endif /* not NO_EXTERNAL_INDIRECT_ADDRESS */ 1769 1770/* True if X is an address which can be indirected. External symbols 1771 could be in a sharable image library, so we disallow those. */ 1772 1773static bool 1774indirectable_address_p (rtx x, bool strict, bool indirect) 1775{ 1776 if (indirectable_constant_address_p (x, indirect) 1777 || BASE_REGISTER_P (x, strict)) 1778 return true; 1779 if (GET_CODE (x) != PLUS 1780 || !BASE_REGISTER_P (XEXP (x, 0), strict) 1781 || (flag_pic && !CONST_INT_P (XEXP (x, 1)))) 1782 return false; 1783 return indirectable_constant_address_p (XEXP (x, 1), indirect); 1784} 1785 1786/* Return true if x is a valid address not using indexing. 1787 (This much is the easy part.) */ 1788static bool 1789nonindexed_address_p (rtx x, bool strict) 1790{ 1791 rtx xfoo0; 1792 if (REG_P (x)) 1793 { 1794 extern rtx *reg_equiv_mem; 1795 if (! reload_in_progress 1796 || reg_equiv_mem[REGNO (x)] == 0 1797 || indirectable_address_p (reg_equiv_mem[REGNO (x)], strict, false)) 1798 return true; 1799 } 1800 if (indirectable_constant_address_p (x, false)) 1801 return true; 1802 if (indirectable_address_p (x, strict, false)) 1803 return true; 1804 xfoo0 = XEXP (x, 0); 1805 if (MEM_P (x) && indirectable_address_p (xfoo0, strict, true)) 1806 return true; 1807 if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC) 1808 && BASE_REGISTER_P (xfoo0, strict)) 1809 return true; 1810 return false; 1811} 1812 1813/* True if PROD is either a reg times size of mode MODE and MODE is less 1814 than or equal 8 bytes, or just a reg if MODE is one byte. */ 1815 1816static bool 1817index_term_p (rtx prod, enum machine_mode mode, bool strict) 1818{ 1819 rtx xfoo0, xfoo1; 1820 1821 if (GET_MODE_SIZE (mode) == 1) 1822 return BASE_REGISTER_P (prod, strict); 1823 1824 if (GET_CODE (prod) != MULT || GET_MODE_SIZE (mode) > 8) 1825 return false; 1826 1827 xfoo0 = XEXP (prod, 0); 1828 xfoo1 = XEXP (prod, 1); 1829 1830 if (CONST_INT_P (xfoo0) 1831 && INTVAL (xfoo0) == (int)GET_MODE_SIZE (mode) 1832 && INDEX_REGISTER_P (xfoo1, strict)) 1833 return true; 1834 1835 if (CONST_INT_P (xfoo1) 1836 && INTVAL (xfoo1) == (int)GET_MODE_SIZE (mode) 1837 && INDEX_REGISTER_P (xfoo0, strict)) 1838 return true; 1839 1840 return false; 1841} 1842 1843/* Return true if X is the sum of a register 1844 and a valid index term for mode MODE. */ 1845static bool 1846reg_plus_index_p (rtx x, enum machine_mode mode, bool strict) 1847{ 1848 rtx xfoo0, xfoo1; 1849 1850 if (GET_CODE (x) != PLUS) 1851 return false; 1852 1853 xfoo0 = XEXP (x, 0); 1854 xfoo1 = XEXP (x, 1); 1855 1856 if (BASE_REGISTER_P (xfoo0, strict) && index_term_p (xfoo1, mode, strict)) 1857 return true; 1858 1859 if (BASE_REGISTER_P (xfoo1, strict) && index_term_p (xfoo0, mode, strict)) 1860 return true; 1861 1862 return false; 1863} 1864 1865/* Return true if xfoo0 and xfoo1 constitute a valid indexed address. */ 1866static bool 1867indexable_address_p (rtx xfoo0, rtx xfoo1, enum machine_mode mode, bool strict) 1868{ 1869 if (!CONSTANT_ADDRESS_P (xfoo0)) 1870 return false; 1871 if (BASE_REGISTER_P (xfoo1, strict)) 1872 return !flag_pic || mode == QImode; 1873 if (flag_pic && symbolic_operand (xfoo0, SImode)) 1874 return false; 1875 return reg_plus_index_p (xfoo1, mode, strict); 1876} 1877 1878/* legitimate_address_p returns true if it recognizes an RTL expression "x" 1879 that is a valid memory address for an instruction. 1880 The MODE argument is the machine mode for the MEM expression 1881 that wants to use this address. */ 1882bool 1883vax_legitimate_address_p (enum machine_mode mode, rtx x, bool strict) 1884{ 1885 rtx xfoo0, xfoo1; 1886 1887 if (nonindexed_address_p (x, strict)) 1888 return true; 1889 1890 if (GET_CODE (x) != PLUS) 1891 return false; 1892 1893 /* Handle <address>[index] represented with index-sum outermost */ 1894 1895 xfoo0 = XEXP (x, 0); 1896 xfoo1 = XEXP (x, 1); 1897 1898 if (index_term_p (xfoo0, mode, strict) 1899 && nonindexed_address_p (xfoo1, strict)) 1900 return true; 1901 1902 if (index_term_p (xfoo1, mode, strict) 1903 && nonindexed_address_p (xfoo0, strict)) 1904 return true; 1905 1906 /* Handle offset(reg)[index] with offset added outermost */ 1907 1908 if (indexable_address_p (xfoo0, xfoo1, mode, strict) 1909 || indexable_address_p (xfoo1, xfoo0, mode, strict)) 1910 return true; 1911 1912 return false; 1913} 1914 1915/* Return true if x (a legitimate address expression) has an effect that 1916 depends on the machine mode it is used for. On the VAX, the predecrement 1917 and postincrement address depend thus (the amount of decrement or 1918 increment being the length of the operand) and all indexed address depend 1919 thus (because the index scale factor is the length of the operand). */ 1920 1921bool 1922vax_mode_dependent_address_p (rtx x) 1923{ 1924 rtx xfoo0, xfoo1; 1925 1926 /* Auto-increment cases are now dealt with generically in recog.c. */ 1927 if (GET_CODE (x) != PLUS) 1928 return false; 1929 1930 xfoo0 = XEXP (x, 0); 1931 xfoo1 = XEXP (x, 1); 1932 1933 if (CONST_INT_P (xfoo0) && REG_P (xfoo1)) 1934 return false; 1935 if (CONST_INT_P (xfoo1) && REG_P (xfoo0)) 1936 return false; 1937 if (!flag_pic && CONSTANT_ADDRESS_P (xfoo0) && REG_P (xfoo1)) 1938 return false; 1939 if (!flag_pic && CONSTANT_ADDRESS_P (xfoo1) && REG_P (xfoo0)) 1940 return false; 1941 1942 return true; 1943} 1944 1945static rtx 1946fixup_mathdi_operand (rtx x, enum machine_mode mode) 1947{ 1948 if (illegal_addsub_di_memory_operand (x, mode)) 1949 { 1950 rtx addr = XEXP (x, 0); 1951 rtx temp = gen_reg_rtx (Pmode); 1952 rtx offset = 0; 1953#ifdef NO_EXTERNAL_INDIRECT_ADDRESS 1954 if (GET_CODE (addr) == CONST && flag_pic) 1955 { 1956 offset = XEXP (XEXP (addr, 0), 1); 1957 addr = XEXP (XEXP (addr, 0), 0); 1958 } 1959#endif 1960 emit_move_insn (temp, addr); 1961 if (offset) 1962 temp = gen_rtx_PLUS (Pmode, temp, offset); 1963 x = gen_rtx_MEM (DImode, temp); 1964 } 1965 return x; 1966} 1967 1968void 1969vax_expand_addsub_di_operands (rtx * operands, enum rtx_code code) 1970{ 1971 int hi_only = operand_subword (operands[2], 0, 0, DImode) == const0_rtx; 1972 rtx temp; 1973 1974 rtx (*gen_old_insn)(rtx, rtx, rtx); 1975 rtx (*gen_si_insn)(rtx, rtx, rtx); 1976 rtx (*gen_insn)(rtx, rtx, rtx); 1977 1978 if (code == PLUS) 1979 { 1980 gen_old_insn = gen_adddi3_old; 1981 gen_si_insn = gen_addsi3; 1982 gen_insn = gen_adcdi3; 1983 } 1984 else if (code == MINUS) 1985 { 1986 gen_old_insn = gen_subdi3_old; 1987 gen_si_insn = gen_subsi3; 1988 gen_insn = gen_sbcdi3; 1989 } 1990 else 1991 gcc_unreachable (); 1992 1993 /* If this is addition (thus operands are commutative) and if there is one 1994 addend that duplicates the desination, we want that addend to be the 1995 first addend. */ 1996 if (code == PLUS 1997 && rtx_equal_p (operands[0], operands[2]) 1998 && !rtx_equal_p (operands[1], operands[2])) 1999 { 2000 temp = operands[2]; 2001 operands[2] = operands[1]; 2002 operands[1] = temp; 2003 } 2004 2005 if (!TARGET_QMATH) 2006 { 2007 emit_insn ((*gen_old_insn) (operands[0], operands[1], operands[2])); 2008 } 2009 else if (hi_only) 2010 { 2011 if (!rtx_equal_p (operands[0], operands[1]) 2012 && (REG_P (operands[0]) && MEM_P (operands[1]))) 2013 { 2014 emit_move_insn (operands[0], operands[1]); 2015 operands[1] = operands[0]; 2016 } 2017 2018 operands[0] = fixup_mathdi_operand (operands[0], DImode); 2019 operands[1] = fixup_mathdi_operand (operands[1], DImode); 2020 operands[2] = fixup_mathdi_operand (operands[2], DImode); 2021 2022 if (!rtx_equal_p (operands[0], operands[1])) 2023 emit_move_insn (operand_subword (operands[0], 0, 0, DImode), 2024 operand_subword (operands[1], 0, 0, DImode)); 2025 2026 emit_insn ((*gen_si_insn) (operand_subword (operands[0], 1, 0, DImode), 2027 operand_subword (operands[1], 1, 0, DImode), 2028 operand_subword (operands[2], 1, 0, DImode))); 2029 } 2030 else 2031 { 2032 /* If are adding the same value together, that's really a multiply by 2, 2033 and that's just a left shift of 1. */ 2034 if (rtx_equal_p (operands[1], operands[2])) 2035 { 2036 if (code == MINUS) 2037 emit_insn (gen_movdi (operands[0], const0_rtx)); 2038 else 2039 emit_insn (gen_ashldi3 (operands[0], operands[1], const1_rtx)); 2040 return; 2041 } 2042 2043 operands[0] = fixup_mathdi_operand (operands[0], DImode); 2044 2045 /* If an operand is the same as operand[0], use the operand[0] rtx 2046 because fixup will an equivalent rtx but not an equal one. */ 2047 2048 if (rtx_equal_p (operands[0], operands[1])) 2049 operands[1] = operands[0]; 2050 else 2051 operands[1] = fixup_mathdi_operand (operands[1], DImode); 2052 2053 if (rtx_equal_p (operands[0], operands[2])) 2054 operands[2] = operands[0]; 2055 else 2056 operands[2] = fixup_mathdi_operand (operands[2], DImode); 2057 2058 /* If we are subtracting not from ourselves [d = a - b], and because the 2059 carry ops are two operand only, we would need to do a move prior to 2060 the subtract. And if d == b, we would need a temp otherwise 2061 [d = a, d -= d] and we end up with 0. Instead we rewrite d = a - b 2062 into d = -b, d += a. Since -b can never overflow, even if b == d, 2063 no temp is needed. 2064 2065 If we are doing addition, since the carry ops are two operand, if 2066 we aren't adding to ourselves, move the first addend to the 2067 destination first. */ 2068 2069 gcc_assert (operands[1] != const0_rtx || code == MINUS); 2070 if (!rtx_equal_p (operands[0], operands[1]) && operands[1] != const0_rtx) 2071 { 2072 if (code == MINUS && CONSTANT_P (operands[1])) 2073 { 2074 temp = gen_reg_rtx (DImode); 2075 emit_insn (gen_sbcdi3 (operands[0], const0_rtx, operands[2])); 2076 code = PLUS; 2077 gen_insn = gen_adcdi3; 2078 operands[2] = operands[1]; 2079 operands[1] = operands[0]; 2080 } 2081 else 2082 emit_move_insn (operands[0], operands[1]); 2083 } 2084 2085 /* Subtracting a constant will have been rewritten to an addition of the 2086 negative of that constant before we get here. */ 2087 gcc_assert (!CONSTANT_P (operands[2]) || code == PLUS); 2088 emit_insn ((*gen_insn) (operands[0], operands[1], operands[2])); 2089 } 2090} 2091 2092bool 2093adjacent_operands_p (rtx lo, rtx hi, enum machine_mode mode) 2094{ 2095 HOST_WIDE_INT lo_offset; 2096 HOST_WIDE_INT hi_offset; 2097 2098 if (GET_CODE (lo) != GET_CODE (hi)) 2099 return false; 2100 2101 if (REG_P (lo)) 2102 return mode == SImode && REGNO (lo) + 1 == REGNO (hi); 2103 if (CONST_INT_P (lo)) 2104 return INTVAL (hi) == 0 && 0 <= INTVAL (lo) && INTVAL (lo) < 64; 2105 if (CONST_INT_P (lo)) 2106 return mode != SImode; 2107 2108 if (!MEM_P (lo)) 2109 return false; 2110 2111 if (MEM_VOLATILE_P (lo) || MEM_VOLATILE_P (hi)) 2112 return false; 2113 2114 lo = XEXP (lo, 0); 2115 hi = XEXP (hi, 0); 2116 2117 if (GET_CODE (lo) == POST_INC /* || GET_CODE (lo) == PRE_DEC */) 2118 return rtx_equal_p (lo, hi); 2119 2120 switch (GET_CODE (lo)) 2121 { 2122 case REG: 2123 case SYMBOL_REF: 2124 lo_offset = 0; 2125 break; 2126 case CONST: 2127 lo = XEXP (lo, 0); 2128 /* FALLTHROUGH */ 2129 case PLUS: 2130 if (!CONST_INT_P (XEXP (lo, 1))) 2131 return false; 2132 lo_offset = INTVAL (XEXP (lo, 1)); 2133 lo = XEXP (lo, 0); 2134 break; 2135 default: 2136 return false; 2137 } 2138 2139 switch (GET_CODE (hi)) 2140 { 2141 case REG: 2142 case SYMBOL_REF: 2143 hi_offset = 0; 2144 break; 2145 case CONST: 2146 hi = XEXP (hi, 0); 2147 /* FALLTHROUGH */ 2148 case PLUS: 2149 if (!CONST_INT_P (XEXP (hi, 1))) 2150 return false; 2151 hi_offset = INTVAL (XEXP (hi, 1)); 2152 hi = XEXP (hi, 0); 2153 break; 2154 default: 2155 return false; 2156 } 2157 2158 if (GET_CODE (lo) == MULT || GET_CODE (lo) == PLUS) 2159 return false; 2160 2161 return rtx_equal_p (lo, hi) 2162 && hi_offset - lo_offset == GET_MODE_SIZE (mode); 2163} 2164 2165/* Output assembler code for a block containing the constant parts 2166 of a trampoline, leaving space for the variable parts. */ 2167 2168/* On the VAX, the trampoline contains an entry mask and two instructions: 2169 .word NN 2170 movl $STATIC,r0 (store the functions static chain) 2171 jmp *$FUNCTION (jump to function code at address FUNCTION) */ 2172 2173static void 2174vax_asm_trampoline_template (FILE *f ATTRIBUTE_UNUSED) 2175{ 2176 assemble_aligned_integer (2, const0_rtx); 2177 assemble_aligned_integer (2, GEN_INT (0x8fd0)); 2178 assemble_aligned_integer (4, const0_rtx); 2179 assemble_aligned_integer (1, GEN_INT (0x50 + STATIC_CHAIN_REGNUM)); 2180 assemble_aligned_integer (2, GEN_INT (0x9f17)); 2181 assemble_aligned_integer (4, const0_rtx); 2182} 2183 2184/* We copy the register-mask from the function's pure code 2185 to the start of the trampoline. */ 2186 2187static void 2188vax_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt) 2189{ 2190 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0); 2191 rtx mem; 2192 2193 emit_block_move (m_tramp, assemble_trampoline_template (), 2194 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL); 2195 2196 mem = adjust_address (m_tramp, HImode, 0); 2197 emit_move_insn (mem, gen_const_mem (HImode, fnaddr)); 2198 2199 mem = adjust_address (m_tramp, SImode, 4); 2200 emit_move_insn (mem, cxt); 2201 mem = adjust_address (m_tramp, SImode, 11); 2202 emit_move_insn (mem, plus_constant (fnaddr, 2)); 2203 emit_insn (gen_sync_istream ()); 2204} 2205 2206