diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 910e36e6867..8d5320bfced 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2006-05-07 Richard Earnshaw + + * genpeep.c (main): Make insn-peep.c depend on flags.h. + * arm/constraints.md: New file. + * arm.h (REG_CLASS_FROM_LETTER_P): Delete. + (CONST_OK_FOR_ARM_LETTER, CONST_OK_FOR_THUMB_LETTER) + (CONST_OK_FOR_LETTER_P, CONST_DOUBLE_OK_FOR_ARM_LETTER) + (CONST_DOUBLE_OK_FOR_LETTER_P, EXTRA_CONSTRAINT_STR_ARM) + (CONSTRAINT_LEN, EXTRA_CONSTRAINT_THUMB, EXTRA_CONSTRAINT_STR) + (EXTRA_MEMORY_CONSTRAINT): Likewise. + * arm.md: Include constraints.md. + (thumb_movsi_insn): Use satisfies_constraint_J. + (movhi, movqi): Use satisfies_constraint_I. + 2006-04-29 Anatoly Sokolov * config/avr/avr.h (CRT_BINUTILS_SPECS): Fixed crt* file name diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 6cc612b0d9f..26d397726db 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -1061,119 +1061,6 @@ enum reg_class registers. */ #define SMALL_REGISTER_CLASSES TARGET_THUMB -/* Get reg_class from a letter such as appears in the machine description. - We only need constraint `f' for FPA_REGS (`r' == GENERAL_REGS) for the - ARM, but several more letters for the Thumb. */ -#define REG_CLASS_FROM_LETTER(C) \ - ( (C) == 'f' ? FPA_REGS \ - : (C) == 'v' ? CIRRUS_REGS \ - : (C) == 'w' ? VFP_REGS \ - : (C) == 'y' ? IWMMXT_REGS \ - : (C) == 'z' ? IWMMXT_GR_REGS \ - : (C) == 'l' ? (TARGET_ARM ? GENERAL_REGS : LO_REGS) \ - : TARGET_ARM ? NO_REGS \ - : (C) == 'h' ? HI_REGS \ - : (C) == 'b' ? BASE_REGS \ - : (C) == 'k' ? STACK_REG \ - : (C) == 'c' ? CC_REG \ - : NO_REGS) - -/* The letters I, J, K, L and M in a register constraint string - can be used to stand for particular ranges of immediate operands. - This macro defines what the ranges are. - C is the letter, and VALUE is a constant value. - Return 1 if VALUE is in the range specified by C. - I: immediate arithmetic operand (i.e. 8 bits shifted as required). - J: valid indexing constants. - K: ~value ok in rhs argument of data operand. - L: -value ok in rhs argument of data operand. - M: 0..32, or a power of 2 (for shifts, or mult done by shift). */ -#define CONST_OK_FOR_ARM_LETTER(VALUE, C) \ - ((C) == 'I' ? const_ok_for_arm (VALUE) : \ - (C) == 'J' ? ((VALUE) < 4096 && (VALUE) > -4096) : \ - (C) == 'K' ? (const_ok_for_arm (~(VALUE))) : \ - (C) == 'L' ? (const_ok_for_arm (-(VALUE))) : \ - (C) == 'M' ? (((VALUE >= 0 && VALUE <= 32)) \ - || (((VALUE) & ((VALUE) - 1)) == 0)) \ - : 0) - -#define CONST_OK_FOR_THUMB_LETTER(VAL, C) \ - ((C) == 'I' ? (unsigned HOST_WIDE_INT) (VAL) < 256 : \ - (C) == 'J' ? (VAL) > -256 && (VAL) < 0 : \ - (C) == 'K' ? thumb_shiftable_const (VAL) : \ - (C) == 'L' ? (VAL) > -8 && (VAL) < 8 : \ - (C) == 'M' ? ((unsigned HOST_WIDE_INT) (VAL) < 1024 \ - && ((VAL) & 3) == 0) : \ - (C) == 'N' ? ((unsigned HOST_WIDE_INT) (VAL) < 32) : \ - (C) == 'O' ? ((VAL) >= -508 && (VAL) <= 508) \ - : 0) - -#define CONST_OK_FOR_LETTER_P(VALUE, C) \ - (TARGET_ARM ? \ - CONST_OK_FOR_ARM_LETTER (VALUE, C) : CONST_OK_FOR_THUMB_LETTER (VALUE, C)) - -/* Constant letter 'G' for the FP immediate constants. - 'H' means the same constant negated. */ -#define CONST_DOUBLE_OK_FOR_ARM_LETTER(X, C) \ - ((C) == 'G' ? arm_const_double_rtx (X) : \ - (C) == 'H' ? neg_const_double_rtx_ok_for_fpa (X) : 0) - -#define CONST_DOUBLE_OK_FOR_LETTER_P(X, C) \ - (TARGET_ARM ? \ - CONST_DOUBLE_OK_FOR_ARM_LETTER (X, C) : 0) - -/* For the ARM, `Q' means that this is a memory operand that is just - an offset from a register. - `S' means any symbol that has the SYMBOL_REF_FLAG set or a CONSTANT_POOL - address. This means that the symbol is in the text segment and can be - accessed without using a load. - 'D' Prefixes a number of const_double operands where: - 'Da' is a constant that takes two ARM insns to load. - 'Db' takes three ARM insns. - 'Dc' takes four ARM insns, if we allow that in this compilation. - 'U' Prefixes an extended memory constraint where: - 'Uv' is an address valid for VFP load/store insns. - 'Uy' is an address valid for iwmmxt load/store insns. - 'Uq' is an address valid for ldrsb. */ - -#define EXTRA_CONSTRAINT_STR_ARM(OP, C, STR) \ - (((C) == 'D') ? ((GET_CODE (OP) == CONST_DOUBLE \ - || GET_CODE (OP) == CONST_INT \ - || GET_CODE (OP) == CONST_VECTOR) \ - && (((STR)[1] == 'a' \ - && arm_const_double_inline_cost (OP) == 2) \ - || ((STR)[1] == 'b' \ - && arm_const_double_inline_cost (OP) == 3) \ - || ((STR)[1] == 'c' \ - && arm_const_double_inline_cost (OP) == 4 \ - && !(optimize_size || arm_ld_sched)))) : \ - ((C) == 'Q') ? (GET_CODE (OP) == MEM \ - && GET_CODE (XEXP (OP, 0)) == REG) : \ - ((C) == 'R') ? (GET_CODE (OP) == MEM \ - && GET_CODE (XEXP (OP, 0)) == SYMBOL_REF \ - && CONSTANT_POOL_ADDRESS_P (XEXP (OP, 0))) : \ - ((C) == 'S') ? (optimize > 0 && CONSTANT_ADDRESS_P (OP)) : \ - ((C) == 'T') ? cirrus_memory_offset (OP) : \ - ((C) == 'U' && (STR)[1] == 'v') ? arm_coproc_mem_operand (OP, FALSE) : \ - ((C) == 'U' && (STR)[1] == 'y') ? arm_coproc_mem_operand (OP, TRUE) : \ - ((C) == 'U' && (STR)[1] == 'q') \ - ? arm_extendqisi_mem_op (OP, GET_MODE (OP)) \ - : 0) - -#define CONSTRAINT_LEN(C,STR) \ - (((C) == 'U' || (C) == 'D') ? 2 : DEFAULT_CONSTRAINT_LEN (C, STR)) - -#define EXTRA_CONSTRAINT_THUMB(X, C) \ - ((C) == 'Q' ? (GET_CODE (X) == MEM \ - && GET_CODE (XEXP (X, 0)) == LABEL_REF) : 0) - -#define EXTRA_CONSTRAINT_STR(X, C, STR) \ - (TARGET_ARM \ - ? EXTRA_CONSTRAINT_STR_ARM (X, C, STR) \ - : EXTRA_CONSTRAINT_THUMB (X, C)) - -#define EXTRA_MEMORY_CONSTRAINT(C, STR) ((C) == 'U') - /* 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 for the Thumb we prefer diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 53b633ddc7f..9abe62c17f7 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -309,6 +309,7 @@ ;; Predicates (include "predicates.md") +(include "constraints.md") ;;--------------------------------------------------------------------------- ;; Pipeline descriptions @@ -4443,7 +4444,7 @@ (define_split [(set (match_operand:SI 0 "register_operand" "") (match_operand:SI 1 "const_int_operand" ""))] - "TARGET_THUMB && CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'J')" + "TARGET_THUMB && satisfies_constraint_J (operands[1])" [(set (match_dup 0) (match_dup 1)) (set (match_dup 0) (neg:SI (match_dup 0)))] "operands[1] = GEN_INT (- INTVAL (operands[1]));" @@ -4452,7 +4453,7 @@ (define_split [(set (match_operand:SI 0 "register_operand" "") (match_operand:SI 1 "const_int_operand" ""))] - "TARGET_THUMB && CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'K')" + "TARGET_THUMB && satisfies_constraint_K (operands[1])" [(set (match_dup 0) (match_dup 1)) (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))] " @@ -4905,7 +4906,7 @@ operands[1] = force_reg (HImode, operands[1]); } else if (GET_CODE (operands[1]) == CONST_INT - && !CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'I')) + && !satisfies_constraint_I (operands[1])) { /* Handle loading a large integer during reload. */ @@ -5138,7 +5139,7 @@ } else if (TARGET_THUMB && GET_CODE (operands[1]) == CONST_INT - && !CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'I')) + && !satisfies_constraint_I (operands[1])) { /* Handle loading a large integer during reload. */ diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md new file mode 100644 index 00000000000..728a4e7a7c2 --- /dev/null +++ b/gcc/config/arm/constraints.md @@ -0,0 +1,186 @@ +;; Constraint definitions for ARM and Thumb +;; Copyright (C) 2006 Free Software Foundation, Inc. +;; Contributed by ARM Ltd. + +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 2, or (at your +;; option) any later version. + +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING. If not, write to +;; the Free Software Foundation, 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;; The following register constraints have been used: +;; - in ARM state: f, v, w, y, z +;; - in Thumb state: h, k, b +;; - in both states: l, c +;; In ARM state, 'l' is an alias for 'r' + +;; The following normal constraints have been used: +;; in ARM state: G, H, I, J, K, L, M +;; in Thumb state: I, J, K, L, M, N, O + +;; The following multi-letter normal constraints have been used: +;; in ARM state: Da, Db, Dc + +;; The following memory constraints have been used: +;; in ARM state: Q, Uq, Uv, Uy + + +(define_register_constraint "f" "TARGET_ARM ? FPA_REGS : NO_REGS" + "Legacy FPA registers @code{f0}-@code{f7}.") + +(define_register_constraint "v" "TARGET_ARM ? CIRRUS_REGS : NO_REGS" + "The Cirrus Maverick co-processor registers.") + +(define_register_constraint "w" "TARGET_ARM ? VFP_REGS : NO_REGS" + "The VFP registers @code{s0}-@code{s31}.") + +(define_register_constraint "y" "TARGET_REALLY_IWMMXT ? IWMMXT_REGS : NO_REGS" + "The Intel iWMMX co-processor registers.") + +(define_register_constraint "z" + "TARGET_REALLY_IWMMXT ? IWMMXT_GR_REGS : NO_REGS" + "The Intel iWMMX GR registers.") + +(define_register_constraint "l" "TARGET_THUMB ? LO_REGS : GENERAL_REGS" + "In Thumb state the core registers @code{r0}-@code{r7}.") + +(define_register_constraint "h" "TARGET_THUMB ? HI_REGS : NO_REGS" + "In Thumb state the core registers @code{r8}-@code{r15}.") + +(define_register_constraint "k" "TARGET_THUMB ? STACK_REG : NO_REGS" + "@internal + Thumb only. The stack register.") + +(define_register_constraint "b" "TARGET_THUMB ? BASE_REGS : NO_REGS" + "@internal + Thumb only. The union of the low registers and the stack register.") + +(define_register_constraint "c" "CC_REG" + "@interal The condition code register.") + +(define_constraint "I" + "In ARM state a constant that can be used as an immediate value in a Data + Processing instruction. In Thumb state a constant in the range 0-255." + (and (match_code "const_int") + (match_test "TARGET_ARM ? const_ok_for_arm (ival) + : ival >= 0 && ival <= 255"))) + +(define_constraint "J" + "In ARM state a constant in the range @minus{}4095-4095. In Thumb state + a constant in the range @minus{}255-@minus{}1." + (and (match_code "const_int") + (match_test "TARGET_ARM ? (ival >= -4095 && ival <= 4095) + : (ival >= -255 && ival <= -1)"))) + +(define_constraint "K" + "In ARM state a constant that satisfies the @code{I} constraint if inverted. + In Thumb state a constant that satisfies the @code{I} constraint multiplied + by any power of 2." + (and (match_code "const_int") + (match_test "TARGET_ARM ? const_ok_for_arm (~ival) + : thumb_shiftable_const (ival)"))) + +(define_constraint "L" + "In ARM state a constant that satisfies the @code{I} constraint if negated. + In Thumb state a constant in the range @minus{}7-7." + (and (match_code "const_int") + (match_test "TARGET_ARM ? const_ok_for_arm (-ival) + : (ival >= -7 && ival <= 7)"))) + +;; The ARM state version is internal... +;; @internal In ARM state a constant in the range 0-32 or any power of 2. +(define_constraint "M" + "In Thumb state a constant that is a multiple of 4 in the range 0-1020." + (and (match_code "const_int") + (match_test "TARGET_ARM ? ((ival >= 0 && ival <= 32) + || ((ival & (ival - 1)) == 0)) + : ((ival >= 0 && ival <= 1020) && ((ival & 3) == 0))"))) + +(define_constraint "N" + "In Thumb state a constant in the range 0-31." + (and (match_code "const_int") + (match_test "TARGET_THUMB && ival >= 0 && ival <= 31"))) + +(define_constraint "O" + "In Thumb state a constant that is a multiple of 4 in the range + @minus{}508-508." + (and (match_code "const_int") + (match_test "TARGET_THUMB && ival >= -508 && ival <= 508 + && ((ival & 3) == 0)"))) + +(define_constraint "G" + "In ARM state a valid FPA immediate constant." + (and (match_code "const_double") + (match_test "TARGET_ARM && arm_const_double_rtx (op)"))) + +(define_constraint "H" + "In ARM state a valid FPA immediate constant when negated." + (and (match_code "const_double") + (match_test "TARGET_ARM && neg_const_double_rtx_ok_for_fpa (op)"))) + +(define_constraint "Da" + "@internal + In ARM state a const_int, const_double or const_vector that can + be generated with two Data Processing insns." + (and (match_code "const_double,const_int,const_vector") + (match_test "TARGET_ARM && arm_const_double_inline_cost (op) == 2"))) + +(define_constraint "Db" + "@internal + In ARM state a const_int, const_double or const_vector that can + be generated with three Data Processing insns." + (and (match_code "const_double,const_int,const_vector") + (match_test "TARGET_ARM && arm_const_double_inline_cost (op) == 3"))) + +(define_constraint "Dc" + "@internal + In ARM state a const_int, const_double or const_vector that can + be generated with four Data Processing insns. This pattern is disabled + if optimizing for space or when we have load-delay slots to fill." + (and (match_code "const_double,const_int,const_vector") + (match_test "TARGET_ARM && arm_const_double_inline_cost (op) == 4 + && !(optimize_size || arm_ld_sched)"))) + +(define_memory_constraint "Uv" + "@internal + In ARM state a valid VFP load/store address." + (and (match_code "mem") + (match_test "TARGET_ARM && arm_coproc_mem_operand (op, FALSE)"))) + +(define_memory_constraint "Uy" + "@internal + In ARM state a valid iWMMX load/store address." + (and (match_code "mem") + (match_test "TARGET_ARM && arm_coproc_mem_operand (op, TRUE)"))) + +(define_memory_constraint "Uq" + "@internal + In ARM state an address valid in ldrsb instructions." + (and (match_code "mem") + (match_test "TARGET_ARM + && arm_legitimate_address_p (GET_MODE (op), XEXP (op, 0), + SIGN_EXTEND, 0)"))) + +(define_memory_constraint "Q" + "@internal + In ARM state an address that is a single base register." + (and (match_code "mem") + (match_test "REG_P (XEXP (op, 0))"))) + +;; We used to have constraint letters for S and R in ARM state, but +;; all uses of these now appear to have been removed. + +;; Additionally, we used to have a Q constraint in Thumb state, but +;; this wasn't really a valid memory constraint. Again, all uses of +;; this now seem to have been removed. diff --git a/gcc/genpeep.c b/gcc/genpeep.c index 80ce3f120cd..c5a7fc2927d 100644 --- a/gcc/genpeep.c +++ b/gcc/genpeep.c @@ -379,6 +379,7 @@ from the machine description file `md'. */\n\n"); printf ("#include \"except.h\"\n"); printf ("#include \"function.h\"\n"); printf ("#include \"toplev.h\"\n"); + printf ("#include \"flags.h\"\n"); printf ("#include \"tm-constrs.h\"\n\n"); printf ("#ifdef HAVE_peephole\n");