00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "config.h"
00024 #include "system.h"
00025 #include "coretypes.h"
00026 #include "tm.h"
00027 #include "rtl.h"
00028 #include "tree.h"
00029 #include "regs.h"
00030 #include "hard-reg-set.h"
00031 #include "real.h"
00032 #include "insn-config.h"
00033 #include "conditions.h"
00034 #include "function.h"
00035 #include "output.h"
00036 #include "insn-attr.h"
00037 #include "recog.h"
00038 #include "expr.h"
00039 #include "optabs.h"
00040 #include "flags.h"
00041 #include "debug.h"
00042 #include "toplev.h"
00043 #include "tm_p.h"
00044 #include "target.h"
00045 #include "target-def.h"
00046
00047 static void vax_output_function_prologue (FILE *, HOST_WIDE_INT);
00048 static void vax_file_start (void);
00049 static void vax_init_libfuncs (void);
00050 static void vax_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
00051 HOST_WIDE_INT, tree);
00052 static int vax_address_cost_1 (rtx);
00053 static int vax_address_cost (rtx);
00054 static bool vax_rtx_costs (rtx, int, int, int *);
00055 static rtx vax_struct_value_rtx (tree, int);
00056
00057
00058 #undef TARGET_ASM_ALIGNED_HI_OP
00059 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
00060
00061 #undef TARGET_ASM_FUNCTION_PROLOGUE
00062 #define TARGET_ASM_FUNCTION_PROLOGUE vax_output_function_prologue
00063
00064 #undef TARGET_ASM_FILE_START
00065 #define TARGET_ASM_FILE_START vax_file_start
00066 #undef TARGET_ASM_FILE_START_APP_OFF
00067 #define TARGET_ASM_FILE_START_APP_OFF true
00068
00069 #undef TARGET_INIT_LIBFUNCS
00070 #define TARGET_INIT_LIBFUNCS vax_init_libfuncs
00071
00072 #undef TARGET_ASM_OUTPUT_MI_THUNK
00073 #define TARGET_ASM_OUTPUT_MI_THUNK vax_output_mi_thunk
00074 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
00075 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
00076
00077 #undef TARGET_DEFAULT_TARGET_FLAGS
00078 #define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT
00079
00080 #undef TARGET_RTX_COSTS
00081 #define TARGET_RTX_COSTS vax_rtx_costs
00082 #undef TARGET_ADDRESS_COST
00083 #define TARGET_ADDRESS_COST vax_address_cost
00084
00085 #undef TARGET_PROMOTE_PROTOTYPES
00086 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
00087
00088 #undef TARGET_STRUCT_VALUE_RTX
00089 #define TARGET_STRUCT_VALUE_RTX vax_struct_value_rtx
00090
00091 struct gcc_target targetm = TARGET_INITIALIZER;
00092
00093
00094
00095 void
00096 override_options (void)
00097 {
00098
00099 if (TARGET_G_FLOAT)
00100 REAL_MODE_FORMAT (DFmode) = &vax_g_format;
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 static void
00113 vax_output_function_prologue (FILE * file, HOST_WIDE_INT size)
00114 {
00115 int regno;
00116 int mask = 0;
00117
00118 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
00119 if (regs_ever_live[regno] && !call_used_regs[regno])
00120 mask |= 1 << regno;
00121
00122 fprintf (file, "\t.word 0x%x\n", mask);
00123
00124 if (dwarf2out_do_frame ())
00125 {
00126 const char *label = dwarf2out_cfi_label ();
00127 int offset = 0;
00128
00129 for (regno = FIRST_PSEUDO_REGISTER-1; regno >= 0; --regno)
00130 if (regs_ever_live[regno] && !call_used_regs[regno])
00131 dwarf2out_reg_save (label, regno, offset -= 4);
00132
00133 dwarf2out_reg_save (label, PC_REGNUM, offset -= 4);
00134 dwarf2out_reg_save (label, FRAME_POINTER_REGNUM, offset -= 4);
00135 dwarf2out_reg_save (label, ARG_POINTER_REGNUM, offset -= 4);
00136 dwarf2out_def_cfa (label, FRAME_POINTER_REGNUM, -(offset - 4));
00137 }
00138
00139 size -= STARTING_FRAME_OFFSET;
00140 if (size >= 64)
00141 asm_fprintf (file, "\tmovab %wd(%Rsp),%Rsp\n", -size);
00142 else if (size)
00143 asm_fprintf (file, "\tsubl2 $%wd,%Rsp\n", size);
00144 }
00145
00146
00147
00148
00149 static void
00150 vax_file_start (void)
00151 {
00152 default_file_start ();
00153
00154 if (write_symbols == DBX_DEBUG)
00155 fprintf (asm_out_file, "___vax_%c_doubles:\n", ASM_DOUBLE_CHAR);
00156 }
00157
00158
00159
00160
00161
00162 static void
00163 vax_init_libfuncs (void)
00164 {
00165 set_optab_libfunc (udiv_optab, SImode, TARGET_ELF ? "*__udiv" : "*udiv");
00166 set_optab_libfunc (umod_optab, SImode, TARGET_ELF ? "*__urem" : "*urem");
00167 }
00168
00169
00170
00171 void
00172 split_quadword_operands (rtx * operands, rtx * low, int n ATTRIBUTE_UNUSED)
00173 {
00174 int i;
00175
00176
00177 low[0] = low[1] = low[2] = 0;
00178 for (i = 0; i < 3; i++)
00179 {
00180 if (low[i])
00181 ;
00182 else if (MEM_P (operands[i])
00183 && (GET_CODE (XEXP (operands[i], 0)) == POST_INC))
00184 {
00185 rtx addr = XEXP (operands[i], 0);
00186 operands[i] = low[i] = gen_rtx_MEM (SImode, addr);
00187 if (which_alternative == 0 && i == 0)
00188 {
00189 addr = XEXP (operands[i], 0);
00190 operands[i+1] = low[i+1] = gen_rtx_MEM (SImode, addr);
00191 }
00192 }
00193 else
00194 {
00195 low[i] = operand_subword (operands[i], 0, 0, DImode);
00196 operands[i] = operand_subword (operands[i], 1, 0, DImode);
00197 }
00198 }
00199 }
00200
00201 void
00202 print_operand_address (FILE * file, rtx addr)
00203 {
00204 rtx reg1, breg, ireg;
00205 rtx offset;
00206
00207 retry:
00208 switch (GET_CODE (addr))
00209 {
00210 case MEM:
00211 fprintf (file, "*");
00212 addr = XEXP (addr, 0);
00213 goto retry;
00214
00215 case REG:
00216 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
00217 break;
00218
00219 case PRE_DEC:
00220 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
00221 break;
00222
00223 case POST_INC:
00224 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
00225 break;
00226
00227 case PLUS:
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 reg1 = 0; ireg = 0; breg = 0; offset = 0;
00238
00239 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
00240 || MEM_P (XEXP (addr, 0)))
00241 {
00242 offset = XEXP (addr, 0);
00243 addr = XEXP (addr, 1);
00244 }
00245 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
00246 || MEM_P (XEXP (addr, 1)))
00247 {
00248 offset = XEXP (addr, 1);
00249 addr = XEXP (addr, 0);
00250 }
00251 else if (GET_CODE (XEXP (addr, 1)) == MULT)
00252 {
00253 ireg = XEXP (addr, 1);
00254 addr = XEXP (addr, 0);
00255 }
00256 else if (GET_CODE (XEXP (addr, 0)) == MULT)
00257 {
00258 ireg = XEXP (addr, 0);
00259 addr = XEXP (addr, 1);
00260 }
00261 else if (REG_P (XEXP (addr, 1)))
00262 {
00263 reg1 = XEXP (addr, 1);
00264 addr = XEXP (addr, 0);
00265 }
00266 else if (REG_P (XEXP (addr, 0)))
00267 {
00268 reg1 = XEXP (addr, 0);
00269 addr = XEXP (addr, 1);
00270 }
00271 else
00272 gcc_unreachable ();
00273
00274 if (REG_P (addr))
00275 {
00276 if (reg1)
00277 ireg = addr;
00278 else
00279 reg1 = addr;
00280 }
00281 else if (GET_CODE (addr) == MULT)
00282 ireg = addr;
00283 else
00284 {
00285 gcc_assert (GET_CODE (addr) == PLUS);
00286 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
00287 || MEM_P (XEXP (addr, 0)))
00288 {
00289 if (offset)
00290 {
00291 if (CONST_INT_P (offset))
00292 offset = plus_constant (XEXP (addr, 0), INTVAL (offset));
00293 else
00294 {
00295 gcc_assert (CONST_INT_P (XEXP (addr, 0)));
00296 offset = plus_constant (offset, INTVAL (XEXP (addr, 0)));
00297 }
00298 }
00299 offset = XEXP (addr, 0);
00300 }
00301 else if (REG_P (XEXP (addr, 0)))
00302 {
00303 if (reg1)
00304 ireg = reg1, breg = XEXP (addr, 0), reg1 = 0;
00305 else
00306 reg1 = XEXP (addr, 0);
00307 }
00308 else
00309 {
00310 gcc_assert (GET_CODE (XEXP (addr, 0)) == MULT);
00311 gcc_assert (!ireg);
00312 ireg = XEXP (addr, 0);
00313 }
00314
00315 if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
00316 || MEM_P (XEXP (addr, 1)))
00317 {
00318 if (offset)
00319 {
00320 if (CONST_INT_P (offset))
00321 offset = plus_constant (XEXP (addr, 1), INTVAL (offset));
00322 else
00323 {
00324 gcc_assert (CONST_INT_P (XEXP (addr, 1)));
00325 offset = plus_constant (offset, INTVAL (XEXP (addr, 1)));
00326 }
00327 }
00328 offset = XEXP (addr, 1);
00329 }
00330 else if (REG_P (XEXP (addr, 1)))
00331 {
00332 if (reg1)
00333 ireg = reg1, breg = XEXP (addr, 1), reg1 = 0;
00334 else
00335 reg1 = XEXP (addr, 1);
00336 }
00337 else
00338 {
00339 gcc_assert (GET_CODE (XEXP (addr, 1)) == MULT);
00340 gcc_assert (!ireg);
00341 ireg = XEXP (addr, 1);
00342 }
00343 }
00344
00345
00346 if (reg1)
00347 {
00348 if (breg != 0 || (offset && MEM_P (offset)))
00349 {
00350 gcc_assert (!ireg);
00351 ireg = reg1;
00352 }
00353 else
00354 breg = reg1;
00355 }
00356
00357 if (offset != 0)
00358 output_address (offset);
00359
00360 if (breg != 0)
00361 fprintf (file, "(%s)", reg_names[REGNO (breg)]);
00362
00363 if (ireg != 0)
00364 {
00365 if (GET_CODE (ireg) == MULT)
00366 ireg = XEXP (ireg, 0);
00367 gcc_assert (REG_P (ireg));
00368 fprintf (file, "[%s]", reg_names[REGNO (ireg)]);
00369 }
00370 break;
00371
00372 default:
00373 output_addr_const (file, addr);
00374 }
00375 }
00376
00377 const char *
00378 rev_cond_name (rtx op)
00379 {
00380 switch (GET_CODE (op))
00381 {
00382 case EQ:
00383 return "neq";
00384 case NE:
00385 return "eql";
00386 case LT:
00387 return "geq";
00388 case LE:
00389 return "gtr";
00390 case GT:
00391 return "leq";
00392 case GE:
00393 return "lss";
00394 case LTU:
00395 return "gequ";
00396 case LEU:
00397 return "gtru";
00398 case GTU:
00399 return "lequ";
00400 case GEU:
00401 return "lssu";
00402
00403 default:
00404 gcc_unreachable ();
00405 }
00406 }
00407
00408 int
00409 vax_float_literal(rtx c)
00410 {
00411 enum machine_mode mode;
00412 REAL_VALUE_TYPE r, s;
00413 int i;
00414
00415 if (GET_CODE (c) != CONST_DOUBLE)
00416 return 0;
00417
00418 mode = GET_MODE (c);
00419
00420 if (c == const_tiny_rtx[(int) mode][0]
00421 || c == const_tiny_rtx[(int) mode][1]
00422 || c == const_tiny_rtx[(int) mode][2])
00423 return 1;
00424
00425 REAL_VALUE_FROM_CONST_DOUBLE (r, c);
00426
00427 for (i = 0; i < 7; i++)
00428 {
00429 int x = 1 << i;
00430 bool ok;
00431 REAL_VALUE_FROM_INT (s, x, 0, mode);
00432
00433 if (REAL_VALUES_EQUAL (r, s))
00434 return 1;
00435 ok = exact_real_inverse (mode, &s);
00436 gcc_assert (ok);
00437 if (REAL_VALUES_EQUAL (r, s))
00438 return 1;
00439 }
00440 return 0;
00441 }
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455 static int
00456 vax_address_cost_1 (rtx addr)
00457 {
00458 int reg = 0, indexed = 0, indir = 0, offset = 0, predec = 0;
00459 rtx plus_op0 = 0, plus_op1 = 0;
00460 restart:
00461 switch (GET_CODE (addr))
00462 {
00463 case PRE_DEC:
00464 predec = 1;
00465 case REG:
00466 case SUBREG:
00467 case POST_INC:
00468 reg = 1;
00469 break;
00470 case MULT:
00471 indexed = 1;
00472 break;
00473 case CONST_INT:
00474
00475 if (offset == 0)
00476 offset = (unsigned HOST_WIDE_INT)(INTVAL(addr)+128) > 256;
00477 break;
00478 case CONST:
00479 case SYMBOL_REF:
00480 offset = 1;
00481 break;
00482 case LABEL_REF:
00483 if (offset == 0)
00484 offset = 1;
00485 break;
00486 case PLUS:
00487 if (plus_op0)
00488 plus_op1 = XEXP (addr, 0);
00489 else
00490 plus_op0 = XEXP (addr, 0);
00491 addr = XEXP (addr, 1);
00492 goto restart;
00493 case MEM:
00494 indir = 2;
00495 addr = XEXP (addr, 0);
00496 goto restart;
00497 default:
00498 break;
00499 }
00500
00501
00502
00503
00504 if (plus_op0)
00505 {
00506 addr = plus_op0;
00507 plus_op0 = 0;
00508 goto restart;
00509 }
00510 if (plus_op1)
00511 {
00512 addr = plus_op1;
00513 plus_op1 = 0;
00514 goto restart;
00515 }
00516
00517
00518 if (reg && indexed && offset)
00519 return reg + indir + offset + predec;
00520 return reg + indexed + indir + offset + predec;
00521 }
00522
00523 static int
00524 vax_address_cost (rtx x)
00525 {
00526 return (1 + (REG_P (x) ? 0 : vax_address_cost_1 (x)));
00527 }
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537 static bool
00538 vax_rtx_costs (rtx x, int code, int outer_code, int *total)
00539 {
00540 enum machine_mode mode = GET_MODE (x);
00541 int i = 0;
00542 const char *fmt = GET_RTX_FORMAT (code);
00543
00544 switch (code)
00545 {
00546
00547
00548
00549
00550
00551 case CONST_INT:
00552 if (INTVAL (x) == 0)
00553 return true;
00554 if (outer_code == AND)
00555 {
00556 *total = ((unsigned HOST_WIDE_INT) ~INTVAL (x) <= 077) ? 1 : 2;
00557 return true;
00558 }
00559 if ((unsigned HOST_WIDE_INT) INTVAL (x) <= 077
00560 || (outer_code == COMPARE
00561 && INTVAL (x) == -1)
00562 || ((outer_code == PLUS || outer_code == MINUS)
00563 && (unsigned HOST_WIDE_INT) -INTVAL (x) <= 077))
00564 {
00565 *total = 1;
00566 return true;
00567 }
00568
00569
00570 case CONST:
00571 case LABEL_REF:
00572 case SYMBOL_REF:
00573 *total = 3;
00574 return true;
00575
00576 case CONST_DOUBLE:
00577 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
00578 *total = vax_float_literal (x) ? 5 : 8;
00579 else
00580 *total = ((CONST_DOUBLE_HIGH (x) == 0
00581 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x) < 64)
00582 || (outer_code == PLUS
00583 && CONST_DOUBLE_HIGH (x) == -1
00584 && (unsigned HOST_WIDE_INT)-CONST_DOUBLE_LOW (x) < 64))
00585 ? 2 : 5;
00586 return true;
00587
00588 case POST_INC:
00589 *total = 2;
00590 return true;
00591
00592 case PRE_DEC:
00593 *total = 3;
00594 return true;
00595
00596 case MULT:
00597 switch (mode)
00598 {
00599 case DFmode:
00600 *total = 16;
00601 break;
00602 case SFmode:
00603 *total = 9;
00604 break;
00605 case DImode:
00606 *total = 16;
00607 break;
00608 case SImode:
00609 case HImode:
00610 case QImode:
00611 *total = 10;
00612 break;
00613 default:
00614 *total = MAX_COST;
00615 return true;
00616 }
00617 break;
00618
00619 case UDIV:
00620 if (mode != SImode)
00621 {
00622 *total = MAX_COST;
00623 return true;
00624 }
00625 *total = 17;
00626 break;
00627
00628 case DIV:
00629 if (mode == DImode)
00630 *total = 30;
00631 else if (mode == DFmode)
00632
00633 *total = 24;
00634 else
00635 *total = 11;
00636 break;
00637
00638 case MOD:
00639 *total = 23;
00640 break;
00641
00642 case UMOD:
00643 if (mode != SImode)
00644 {
00645 *total = MAX_COST;
00646 return true;
00647 }
00648 *total = 29;
00649 break;
00650
00651 case FLOAT:
00652 *total = (6
00653 + (mode == DFmode) + (GET_MODE (XEXP (x, 0)) != SImode));
00654 break;
00655
00656 case FIX:
00657 *total = 7;
00658 break;
00659
00660 case ASHIFT:
00661 case LSHIFTRT:
00662 case ASHIFTRT:
00663 if (mode == DImode)
00664 *total = 12;
00665 else
00666 *total = 10;
00667 break;
00668
00669 case ROTATE:
00670 case ROTATERT:
00671 *total = 6;
00672 if (CONST_INT_P (XEXP (x, 1)))
00673 fmt = "e";
00674 break;
00675
00676 case PLUS:
00677 case MINUS:
00678 *total = (mode == DFmode) ? 13 : 8;
00679
00680 if ((CONST_INT_P (XEXP (x, 1)))
00681 && (unsigned HOST_WIDE_INT)(INTVAL (XEXP (x, 1)) + 63) < 127)
00682 fmt = "e";
00683 break;
00684
00685 case IOR:
00686 case XOR:
00687 *total = 3;
00688 break;
00689
00690 case AND:
00691
00692 *total = 3;
00693 if (CONST_INT_P (XEXP (x, 0)))
00694 {
00695 if ((unsigned HOST_WIDE_INT)~INTVAL (XEXP (x, 0)) > 63)
00696 *total = 4;
00697 fmt = "e";
00698 i = 1;
00699 }
00700 break;
00701
00702 case NEG:
00703 if (mode == DFmode)
00704 *total = 9;
00705 else if (mode == SFmode)
00706 *total = 6;
00707 else if (mode == DImode)
00708 *total = 4;
00709 else
00710 *total = 2;
00711 break;
00712
00713 case NOT:
00714 *total = 2;
00715 break;
00716
00717 case ZERO_EXTRACT:
00718 case SIGN_EXTRACT:
00719 *total = 15;
00720 break;
00721
00722 case MEM:
00723 if (mode == DImode || mode == DFmode)
00724 *total = 5;
00725 else
00726 *total = 3;
00727 x = XEXP (x, 0);
00728 if (!REG_P (x) && GET_CODE (x) != POST_INC)
00729 *total += vax_address_cost_1 (x);
00730 return true;
00731
00732 case FLOAT_EXTEND:
00733 case FLOAT_TRUNCATE:
00734 case TRUNCATE:
00735 *total = 3;
00736 break;
00737
00738 default:
00739 return false;
00740 }
00741
00742
00743
00744
00745
00746
00747
00748 while (*fmt++ == 'e')
00749 {
00750 rtx op = XEXP (x, i);
00751
00752 i += 1;
00753 code = GET_CODE (op);
00754
00755
00756
00757
00758 if (code == NOT)
00759 op = XEXP (op, 0), code = GET_CODE (op);
00760
00761 switch (code)
00762 {
00763 case CONST_INT:
00764 if ((unsigned HOST_WIDE_INT)INTVAL (op) > 63
00765 && GET_MODE (x) != QImode)
00766 *total += 1;
00767 break;
00768 case CONST:
00769 case LABEL_REF:
00770 case SYMBOL_REF:
00771 *total += 1;
00772 break;
00773 case CONST_DOUBLE:
00774 if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
00775 {
00776
00777
00778 if (vax_float_literal (op))
00779 *total += 1;
00780 else
00781 *total += (GET_MODE (x) == DFmode) ? 3 : 2;
00782 }
00783 else
00784 {
00785 if (CONST_DOUBLE_HIGH (op) != 0
00786 || (unsigned)CONST_DOUBLE_LOW (op) > 63)
00787 *total += 2;
00788 }
00789 break;
00790 case MEM:
00791 *total += 1;
00792 if (!REG_P (XEXP (op, 0)))
00793 *total += vax_address_cost_1 (XEXP (op, 0));
00794 break;
00795 case REG:
00796 case SUBREG:
00797 break;
00798 default:
00799 *total += 1;
00800 break;
00801 }
00802 }
00803 return true;
00804 }
00805
00806
00807
00808
00809
00810
00811
00812
00813 static void
00814 vax_output_mi_thunk (FILE * file,
00815 tree thunk ATTRIBUTE_UNUSED,
00816 HOST_WIDE_INT delta,
00817 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
00818 tree function)
00819 {
00820 fprintf (file, "\t.word 0x0ffc\n\taddl2 $" HOST_WIDE_INT_PRINT_DEC, delta);
00821 asm_fprintf (file, ",4(%Rap)\n");
00822 fprintf (file, "\tjmp ");
00823 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
00824 fprintf (file, "+2\n");
00825 }
00826
00827 static rtx
00828 vax_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
00829 int incoming ATTRIBUTE_UNUSED)
00830 {
00831 return gen_rtx_REG (Pmode, VAX_STRUCT_VALUE_REGNUM);
00832 }
00833
00834
00835
00836 void
00837 vax_notice_update_cc (rtx exp, rtx insn ATTRIBUTE_UNUSED)
00838 {
00839 if (GET_CODE (exp) == SET)
00840 {
00841 if (GET_CODE (SET_SRC (exp)) == CALL)
00842 CC_STATUS_INIT;
00843 else if (GET_CODE (SET_DEST (exp)) != ZERO_EXTRACT
00844 && GET_CODE (SET_DEST (exp)) != PC)
00845 {
00846 cc_status.flags = 0;
00847
00848
00849
00850
00851
00852
00853 switch (GET_CODE (SET_SRC (exp)))
00854 {
00855 case NEG:
00856 if (GET_MODE_CLASS (GET_MODE (exp)) == MODE_FLOAT)
00857 break;
00858 case AND:
00859 case IOR:
00860 case XOR:
00861 case NOT:
00862 case MEM:
00863 case REG:
00864 cc_status.flags = CC_NO_OVERFLOW;
00865 break;
00866 default:
00867 break;
00868 }
00869 cc_status.value1 = SET_DEST (exp);
00870 cc_status.value2 = SET_SRC (exp);
00871 }
00872 }
00873 else if (GET_CODE (exp) == PARALLEL
00874 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
00875 {
00876 if (GET_CODE (SET_SRC (XVECEXP (exp, 0, 0))) == CALL)
00877 CC_STATUS_INIT;
00878 else if (GET_CODE (SET_DEST (XVECEXP (exp, 0, 0))) != PC)
00879 {
00880 cc_status.flags = 0;
00881 cc_status.value1 = SET_DEST (XVECEXP (exp, 0, 0));
00882 cc_status.value2 = SET_SRC (XVECEXP (exp, 0, 0));
00883 }
00884 else
00885
00886
00887 CC_STATUS_INIT;
00888 }
00889 else
00890 CC_STATUS_INIT;
00891 if (cc_status.value1 && REG_P (cc_status.value1)
00892 && cc_status.value2
00893 && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
00894 cc_status.value2 = 0;
00895 if (cc_status.value1 && MEM_P (cc_status.value1)
00896 && cc_status.value2
00897 && MEM_P (cc_status.value2))
00898 cc_status.value2 = 0;
00899
00900
00901 }
00902
00903
00904
00905 const char *
00906 vax_output_int_move (rtx insn ATTRIBUTE_UNUSED, rtx *operands,
00907 enum machine_mode mode)
00908 {
00909 switch (mode)
00910 {
00911 case SImode:
00912 if (GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST)
00913 {
00914 if (push_operand (operands[0], SImode))
00915 return "pushab %a1";
00916 return "movab %a1,%0";
00917 }
00918 if (operands[1] == const0_rtx)
00919 return "clrl %0";
00920 if (CONST_INT_P (operands[1])
00921 && (unsigned) INTVAL (operands[1]) >= 64)
00922 {
00923 int i = INTVAL (operands[1]);
00924 if ((unsigned)(~i) < 64)
00925 return "mcoml %N1,%0";
00926 if ((unsigned)i < 0x100)
00927 return "movzbl %1,%0";
00928 if (i >= -0x80 && i < 0)
00929 return "cvtbl %1,%0";
00930 if ((unsigned)i < 0x10000)
00931 return "movzwl %1,%0";
00932 if (i >= -0x8000 && i < 0)
00933 return "cvtwl %1,%0";
00934 }
00935 if (push_operand (operands[0], SImode))
00936 return "pushl %1";
00937 return "movl %1,%0";
00938
00939 case HImode:
00940 if (CONST_INT_P (operands[1]))
00941 {
00942 int i = INTVAL (operands[1]);
00943 if (i == 0)
00944 return "clrw %0";
00945 else if ((unsigned int)i < 64)
00946 return "movw %1,%0";
00947 else if ((unsigned int)~i < 64)
00948 return "mcomw %H1,%0";
00949 else if ((unsigned int)i < 256)
00950 return "movzbw %1,%0";
00951 }
00952 return "movw %1,%0";
00953
00954 case QImode:
00955 if (CONST_INT_P (operands[1]))
00956 {
00957 int i = INTVAL (operands[1]);
00958 if (i == 0)
00959 return "clrb %0";
00960 else if ((unsigned int)~i < 64)
00961 return "mcomb %B1,%0";
00962 }
00963 return "movb %1,%0";
00964
00965 default:
00966 gcc_unreachable ();
00967 }
00968 }
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984 const char *
00985 vax_output_int_add (rtx insn ATTRIBUTE_UNUSED, rtx *operands,
00986 enum machine_mode mode)
00987 {
00988 switch (mode)
00989 {
00990 case SImode:
00991 if (rtx_equal_p (operands[0], operands[1]))
00992 {
00993 if (operands[2] == const1_rtx)
00994 return "incl %0";
00995 if (operands[2] == constm1_rtx)
00996 return "decl %0";
00997 if (CONST_INT_P (operands[2])
00998 && (unsigned) (- INTVAL (operands[2])) < 64)
00999 return "subl2 $%n2,%0";
01000 if (CONST_INT_P (operands[2])
01001 && (unsigned) INTVAL (operands[2]) >= 64
01002 && REG_P (operands[1])
01003 && ((INTVAL (operands[2]) < 32767 && INTVAL (operands[2]) > -32768)
01004 || REGNO (operands[1]) > 11))
01005 return "movab %c2(%1),%0";
01006 return "addl2 %2,%0";
01007 }
01008
01009 if (rtx_equal_p (operands[0], operands[2]))
01010 return "addl2 %1,%0";
01011
01012 if (CONST_INT_P (operands[2])
01013 && INTVAL (operands[2]) < 32767
01014 && INTVAL (operands[2]) > -32768
01015 && REG_P (operands[1])
01016 && push_operand (operands[0], SImode))
01017 return "pushab %c2(%1)";
01018
01019 if (CONST_INT_P (operands[2])
01020 && (unsigned) (- INTVAL (operands[2])) < 64)
01021 return "subl3 $%n2,%1,%0";
01022
01023 if (CONST_INT_P (operands[2])
01024 && (unsigned) INTVAL (operands[2]) >= 64
01025 && REG_P (operands[1])
01026 && ((INTVAL (operands[2]) < 32767 && INTVAL (operands[2]) > -32768)
01027 || REGNO (operands[1]) > 11))
01028 return "movab %c2(%1),%0";
01029
01030
01031
01032
01033
01034 return "addl3 %1,%2,%0";
01035
01036 case HImode:
01037 if (rtx_equal_p (operands[0], operands[1]))
01038 {
01039 if (operands[2] == const1_rtx)
01040 return "incw %0";
01041 if (operands[2] == constm1_rtx)
01042 return "decw %0";
01043 if (CONST_INT_P (operands[2])
01044 && (unsigned) (- INTVAL (operands[2])) < 64)
01045 return "subw2 $%n2,%0";
01046 return "addw2 %2,%0";
01047 }
01048 if (rtx_equal_p (operands[0], operands[2]))
01049 return "addw2 %1,%0";
01050 if (CONST_INT_P (operands[2])
01051 && (unsigned) (- INTVAL (operands[2])) < 64)
01052 return "subw3 $%n2,%1,%0";
01053 return "addw3 %1,%2,%0";
01054
01055 case QImode:
01056 if (rtx_equal_p (operands[0], operands[1]))
01057 {
01058 if (operands[2] == const1_rtx)
01059 return "incb %0";
01060 if (operands[2] == constm1_rtx)
01061 return "decb %0";
01062 if (CONST_INT_P (operands[2])
01063 && (unsigned) (- INTVAL (operands[2])) < 64)
01064 return "subb2 $%n2,%0";
01065 return "addb2 %2,%0";
01066 }
01067 if (rtx_equal_p (operands[0], operands[2]))
01068 return "addb2 %1,%0";
01069 if (CONST_INT_P (operands[2])
01070 && (unsigned) (- INTVAL (operands[2])) < 64)
01071 return "subb3 $%n2,%1,%0";
01072 return "addb3 %1,%2,%0";
01073
01074 default:
01075 gcc_unreachable ();
01076 }
01077 }
01078
01079
01080 const char *
01081 vax_output_conditional_branch (enum rtx_code code)
01082 {
01083 switch (code)
01084 {
01085 case EQ: return "jeql %l0";
01086 case NE: return "jneq %l0";
01087 case GT: return "jgtr %l0";
01088 case LT: return "jlss %l0";
01089 case GTU: return "jgtru %l0";
01090 case LTU: return "jlssu %l0";
01091 case GE: return "jgeq %l0";
01092 case LE: return "jleq %l0";
01093 case GEU: return "jgequ %l0";
01094 case LEU: return "jlequ %l0";
01095 default:
01096 gcc_unreachable ();
01097 }
01098 }
01099
01100
01101
01102 int
01103 legitimate_constant_address_p (rtx x)
01104 {
01105 return (GET_CODE (x) == LABEL_REF || GET_CODE (x) == SYMBOL_REF
01106 || CONST_INT_P (x) || GET_CODE (x) == CONST
01107 || GET_CODE (x) == HIGH);
01108 }
01109
01110
01111
01112
01113 int
01114 legitimate_constant_p (rtx x ATTRIBUTE_UNUSED)
01115 {
01116 return 1;
01117 }
01118
01119
01120
01121
01122
01123 #define INDEX_REGISTER_P(X, STRICT) \
01124 (REG_P (X) && (!(STRICT) || REGNO_OK_FOR_INDEX_P (REGNO (X))))
01125
01126
01127
01128 #define BASE_REGISTER_P(X, STRICT) \
01129 (REG_P (X) && (!(STRICT) || REGNO_OK_FOR_BASE_P (REGNO (X))))
01130
01131 #ifdef NO_EXTERNAL_INDIRECT_ADDRESS
01132
01133
01134
01135
01136 static int
01137 indirectable_constant_address_p (rtx x)
01138 {
01139 if (!CONSTANT_ADDRESS_P (x))
01140 return 0;
01141 if (GET_CODE (x) == CONST && GET_CODE (XEXP ((x), 0)) == PLUS)
01142 x = XEXP (XEXP (x, 0), 0);
01143 if (GET_CODE (x) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (x))
01144 return 0;
01145
01146 return 1;
01147 }
01148
01149 #else
01150
01151 static int
01152 indirectable_constant_address_p (rtx x)
01153 {
01154 return CONSTANT_ADDRESS_P (x);
01155 }
01156
01157 #endif
01158
01159
01160
01161
01162 static int
01163 indirectable_address_p(rtx x, int strict)
01164 {
01165 if (indirectable_constant_address_p (x))
01166 return 1;
01167 if (BASE_REGISTER_P (x, strict))
01168 return 1;
01169 if (GET_CODE (x) == PLUS
01170 && BASE_REGISTER_P (XEXP (x, 0), strict)
01171 && indirectable_constant_address_p (XEXP (x, 1)))
01172 return 1;
01173 return 0;
01174 }
01175
01176
01177
01178 static int
01179 nonindexed_address_p (rtx x, int strict)
01180 {
01181 rtx xfoo0;
01182 if (REG_P (x))
01183 {
01184 extern rtx *reg_equiv_mem;
01185 if (!reload_in_progress
01186 || reg_equiv_mem[REGNO (x)] == 0
01187 || indirectable_address_p (reg_equiv_mem[REGNO (x)], strict))
01188 return 1;
01189 }
01190 if (indirectable_constant_address_p (x))
01191 return 1;
01192 if (indirectable_address_p (x, strict))
01193 return 1;
01194 xfoo0 = XEXP (x, 0);
01195 if (MEM_P (x) && indirectable_address_p (xfoo0, strict))
01196 return 1;
01197 if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
01198 && BASE_REGISTER_P (xfoo0, strict))
01199 return 1;
01200 return 0;
01201 }
01202
01203
01204
01205
01206 static int
01207 index_term_p (rtx prod, enum machine_mode mode, int strict)
01208 {
01209 rtx xfoo0, xfoo1;
01210
01211 if (GET_MODE_SIZE (mode) == 1)
01212 return BASE_REGISTER_P (prod, strict);
01213
01214 if (GET_CODE (prod) != MULT || GET_MODE_SIZE (mode) > 8)
01215 return 0;
01216
01217 xfoo0 = XEXP (prod, 0);
01218 xfoo1 = XEXP (prod, 1);
01219
01220 if (CONST_INT_P (xfoo0)
01221 && INTVAL (xfoo0) == (int)GET_MODE_SIZE (mode)
01222 && INDEX_REGISTER_P (xfoo1, strict))
01223 return 1;
01224
01225 if (CONST_INT_P (xfoo1)
01226 && INTVAL (xfoo1) == (int)GET_MODE_SIZE (mode)
01227 && INDEX_REGISTER_P (xfoo0, strict))
01228 return 1;
01229
01230 return 0;
01231 }
01232
01233
01234
01235 static int
01236 reg_plus_index_p (rtx x, enum machine_mode mode, int strict)
01237 {
01238 rtx xfoo0, xfoo1;
01239
01240 if (GET_CODE (x) != PLUS)
01241 return 0;
01242
01243 xfoo0 = XEXP (x, 0);
01244 xfoo1 = XEXP (x, 1);
01245
01246 if (BASE_REGISTER_P (xfoo0, strict) && index_term_p (xfoo1, mode, strict))
01247 return 1;
01248
01249 if (BASE_REGISTER_P (xfoo1, strict) && index_term_p (xfoo0, mode, strict))
01250 return 1;
01251
01252 return 0;
01253 }
01254
01255
01256
01257
01258
01259 int
01260 legitimate_address_p (enum machine_mode mode, rtx x, int strict)
01261 {
01262 rtx xfoo0, xfoo1;
01263
01264 if (nonindexed_address_p (x, strict))
01265 return 1;
01266
01267 if (GET_CODE (x) != PLUS)
01268 return 0;
01269
01270
01271
01272 xfoo0 = XEXP (x, 0);
01273 xfoo1 = XEXP (x, 1);
01274
01275 if (index_term_p (xfoo0, mode, strict)
01276 && nonindexed_address_p (xfoo1, strict))
01277 return 1;
01278
01279 if (index_term_p (xfoo1, mode, strict)
01280 && nonindexed_address_p (xfoo0, strict))
01281 return 1;
01282
01283
01284
01285 if (indirectable_constant_address_p (xfoo0)
01286 && (BASE_REGISTER_P (xfoo1, strict)
01287 || reg_plus_index_p (xfoo1, mode, strict)))
01288 return 1;
01289
01290 if (indirectable_constant_address_p (xfoo1)
01291 && (BASE_REGISTER_P (xfoo0, strict)
01292 || reg_plus_index_p (xfoo0, mode, strict)))
01293 return 1;
01294
01295 return 0;
01296 }
01297
01298
01299
01300
01301
01302
01303
01304 int
01305 vax_mode_dependent_address_p (rtx x)
01306 {
01307 rtx xfoo0, xfoo1;
01308
01309 if (GET_CODE (x) == POST_INC || GET_CODE (x) == PRE_DEC)
01310 return 1;
01311 if (GET_CODE (x) != PLUS)
01312 return 0;
01313
01314 xfoo0 = XEXP (x, 0);
01315 xfoo1 = XEXP (x, 1);
01316
01317 if (CONSTANT_ADDRESS_P (xfoo0) && REG_P (xfoo1))
01318 return 0;
01319 if (CONSTANT_ADDRESS_P (xfoo1) && REG_P (xfoo0))
01320 return 0;
01321
01322 return 1;
01323 }