--- gcc/config/vax.h 2018/04/24 17:51:34 1.1 +++ gcc/config/vax.h 2018/04/24 18:04:54 1.1.1.4 @@ -93,7 +93,7 @@ extern int target_flags; /* This is not true on the vax. */ #define WORDS_BIG_ENDIAN 0 -/* Number of bits in an addressible storage unit */ +/* Number of bits in an addressable storage unit */ #define BITS_PER_UNIT 8 /* Width in bits of a "word", which is the contents of a machine register. @@ -130,9 +130,12 @@ extern int target_flags; /* No structure field wants to be aligned rounder than this. */ #define BIGGEST_FIELD_ALIGNMENT (TARGET_VAXC_ALIGNMENT ? 8 : 32) -/* Define this if move instructions will actually fail to work +/* Set this nonzero if move instructions will actually fail to work when given unaligned data. */ -/* #define STRICT_ALIGNMENT */ +#define STRICT_ALIGNMENT 0 + +/* Let's keep the stack somewhat aligned. */ +#define STACK_BOUNDARY 32 /* Standard register usage. */ @@ -283,6 +286,16 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_ || (VALUE) == CONST0_RTX (SFmode)) \ : 0) +/* Optional extra constraints for this machine. + + For the VAX, `Q' means that OP is a MEM that does not have a mode-dependent + address. */ + +#define EXTRA_CONSTRAINT(OP, C) \ + ((C) == 'Q' \ + ? GET_CODE (OP) == MEM && ! mode_dependent_address_p (XEXP (OP, 0)) \ + : 0) + /* Given an rtx X being reloaded into a reg required to be in class CLASS, return the class of reg to actually use. In general this is just CLASS; but on some machines @@ -822,32 +835,45 @@ gen_rtx (PLUS, Pmode, frame, gen_rtx (CO of a switch statement. If the code is computed here, return it with a return statement. Otherwise, break from the switch. */ -#define CONST_COSTS(RTX,CODE) \ +/* On a VAX, constants from 0..63 are cheap because they can use the + 1 byte literal constant format. compare to -1 should be made cheap + so that decrement-and-branch insns can be formed more easily (if + the value -1 is copied to a register some decrement-and-branch patterns + will not match). */ + +#define CONST_COSTS(RTX,CODE,OUTER_CODE) \ case CONST_INT: \ - /* Constant zero is super cheap due to clr instruction. */ \ - if ((RTX) == const0_rtx) return 0; \ - /* Constants of +/- 1 should also be super cheap since \ - may be used in decl/incl/aob/sob insns. */ \ - if ((RTX) == const1_rtx || (RTX) == constm1_rtx) return 0; \ - if ((unsigned) INTVAL (RTX) < 077) return 1; \ + if (INTVAL (RTX) == 0) return 0; \ + if ((OUTER_CODE) == AND) \ + return ((unsigned) ~INTVAL (RTX) <= 077) ? 1 : 2; \ + if ((unsigned) INTVAL (RTX) <= 077) return 1; \ + if ((OUTER_CODE) == COMPARE && INTVAL (RTX) == -1) \ + return 1; \ + if ((OUTER_CODE) == PLUS && (unsigned) -INTVAL (RTX) <= 077)\ + return 1; \ case CONST: \ case LABEL_REF: \ case SYMBOL_REF: \ return 3; \ case CONST_DOUBLE: \ - return 5; + if (GET_MODE_CLASS (GET_MODE (RTX)) == MODE_FLOAT) \ + return vax_float_literal (RTX) ? 5 : 8; \ + else \ + return (((CONST_DOUBLE_HIGH (RTX) == 0 \ + && (unsigned) CONST_DOUBLE_LOW (RTX) < 64) \ + || ((OUTER_CODE) == PLUS \ + && CONST_DOUBLE_HIGH (RTX) == -1 \ + && (unsigned)-CONST_DOUBLE_LOW (RTX) < 64)) \ + ? 2 : 5); + +#define RTX_COSTS(RTX,CODE,OUTER_CODE) case FIX: case FLOAT: \ + case MULT: case DIV: case UDIV: case MOD: case UMOD: \ + case LSHIFT: case ASHIFT: case LSHIFTRT: case ASHIFTRT: \ + case ROTATE: case ROTATERT: case PLUS: case MINUS: case IOR: \ + case XOR: case AND: case NEG: case NOT: case ZERO_EXTRACT: \ + case SIGN_EXTRACT: case MEM: return vax_rtx_cost(RTX) -/* On most VAX models, shift are almost as expensive as multiplies, so - we'd rather use multiply unless it can be done in an extremely small - sequence. */ -#define RTX_COSTS(RTX,CODE) \ - case LSHIFT: \ - case ASHIFT: \ - case ASHIFTRT: \ - case LSHIFTRT: \ - case ROTATE: \ - case ROTATERT: \ - return COSTS_N_INSNS (4); +#define ADDRESS_COST(RTX) (1 + (GET_CODE (RTX) == REG ? 0 : vax_address_cost(RTX))) /* Specify the cost of a branch insn; roughly the number of extra insns that should be added to avoid a branch. @@ -867,7 +893,7 @@ gen_rtx (PLUS, Pmode, frame, gen_rtx (CO /* Check a `double' value for validity for a particular machine mode. */ -/* note that it is very hard to accidently create a number that fits in a +/* note that it is very hard to accidentally create a number that fits in a double but not in a float, since their ranges are almost the same */ #define CHECK_FLOAT_VALUE(mode, d) \ if ((mode) == SFmode) \ @@ -1157,15 +1183,25 @@ gen_rtx (PLUS, Pmode, frame, gen_rtx (CO /* Print an instruction operand X on file FILE. CODE is the code from the %-spec that requested printing this operand; if `%z3' was used to print operand 3, then CODE is 'z'. - On the Vax, the codes used are: - `#', indicating that either `d' or `g' should be printed, - depending on whether we're using dfloat or gfloat. - `C', indicating the reverse of the condition name specified by the - operand. - `P', indicating one plus a constant operand - `N', indicating the one's complement of a constant operand - `H', indicating the low-order 16 bits of the one's complement of a constant - `B', similarly for the low-order 8 bits. */ + +VAX operand formatting codes: + + letter print + C reverse branch condition + D 64-bit immediate operand + B the low 8 bits of the complement of a constant operand + H the low 16 bits of the complement of a constant operand + M a mask for the N highest bits of a word + N the complement of a constant integer operand + P constant operand plus 1 + R 32 - constant operand + b the low 8 bits of a negated constant operand + h the low 16 bits of a negated constant operand + # 'd' or 'g' depending on whether dfloat or gfloat is used */ + +/* The purpose of D is to get around a quirk or bug in vax assembler + whereby -1 in a 64-bit immediate operand means 0x00000000ffffffff, + which is not a 64-bit minus one. */ #define PRINT_OPERAND_PUNCT_VALID_P(CODE) \ ((CODE) == '#') @@ -1175,6 +1211,8 @@ gen_rtx (PLUS, Pmode, frame, gen_rtx (CO if (CODE == '#') fputc (ASM_DOUBLE_CHAR, FILE); \ else if (CODE == 'C') \ fputs (rev_cond_name (X), FILE); \ + else if (CODE == 'D' && GET_CODE (X) == CONST_INT && INTVAL (X) < 0) \ + fprintf (FILE, "0xffffffff%08x", INTVAL (X)); \ else if (CODE == 'P' && GET_CODE (X) == CONST_INT) \ fprintf (FILE, "$%d", INTVAL (X) + 1); \ else if (CODE == 'N' && GET_CODE (X) == CONST_INT) \ @@ -1184,13 +1222,23 @@ gen_rtx (PLUS, Pmode, frame, gen_rtx (CO fprintf (FILE, "$%d", 32 - INTVAL (X)); \ else if (CODE == 'H' && GET_CODE (X) == CONST_INT) \ fprintf (FILE, "$%d", 0xffff & ~ INTVAL (X)); \ + else if (CODE == 'h' && GET_CODE (X) == CONST_INT) \ + fprintf (FILE, "$%d", (short) - INTVAL (x)); \ else if (CODE == 'B' && GET_CODE (X) == CONST_INT) \ fprintf (FILE, "$%d", 0xff & ~ INTVAL (X)); \ + else if (CODE == 'b' && GET_CODE (X) == CONST_INT) \ + fprintf (FILE, "$%d", 0xff & - INTVAL (X)); \ + else if (CODE == 'M' && GET_CODE (X) == CONST_INT) \ + fprintf (FILE, "$%d", ~((1 << INTVAL (x)) - 1)); \ else if (GET_CODE (X) == REG) \ fprintf (FILE, "%s", reg_names[REGNO (X)]); \ else if (GET_CODE (X) == MEM) \ output_address (XEXP (X, 0)); \ - else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != DImode) \ + else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode) \ + { union { double d; int i[2]; } u; \ + u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X); \ + fprintf (FILE, "$0f%.20e", u.d); } \ + else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == DFmode) \ { union { double d; int i[2]; } u; \ u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X); \ fprintf (FILE, "$0%c%.20e", ASM_DOUBLE_CHAR, u.d); } \