From f105c84e805cf5be81e46372d90547ef594bc2b8 Mon Sep 17 00:00:00 2001 From: hp Date: Wed, 12 Sep 2012 01:52:36 +0000 Subject: [PATCH] * config/mmix/mmix.h (MMIX_REG_OK_STRICT): Delete. (REG_CLASS_FROM_LETTER, CONST_OK_FOR_LETTER_P): Delete. (CONST_DOUBLE_OK_FOR_LETTER_P, EXTRA_CONSTRAINT): Delete. * config/mmix/mmix-protos.h (mmix_intval): Declare. (mmix_const_ok_for_letter_p, mmix_extra_constraint): Delete. (mmix_const_double_ok_for_letter_p): Delete. * config/mmix/constraints.md: New file. * config/mmix/mmix.md: Include it. (iordi3): Fix typo; use "I" instead of undefined "H" constraint. ("*call_real"): Update comment about not using the "p" constraint. * config/mmix/predicates.md (mmix_reg_or_8bit_operand): Use satisfies_constraint_I. (mmix_address_operand): New predicate. (mmix_symbolic_or_address_operand): Use it instead of address_operand. * config/mmix/mmix.c: #include tm-constrs.h. (mmix_intval): Delete declaration. Make non-static. (mmix_const_ok_for_letter_p, mmix_extra_constraint): Delete. (mmix_const_double_ok_for_letter_p): Delete. (mmix_legitimate_address_p): Use satisfies_constraint_I. (mmix_print_operand_address): Likewise. (mmix_emit_sp_add): Adjust to use insn_const_int_ok_for_constraint when matching "L" constraint. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@191208 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 26 ++++++++++ gcc/config/mmix/constraints.md | 112 +++++++++++++++++++++++++++++++++++++++++ gcc/config/mmix/mmix-protos.h | 4 +- gcc/config/mmix/mmix.c | 93 ++-------------------------------- gcc/config/mmix/mmix.h | 21 -------- gcc/config/mmix/mmix.md | 4 +- gcc/config/mmix/predicates.md | 12 ++++- 7 files changed, 157 insertions(+), 115 deletions(-) create mode 100644 gcc/config/mmix/constraints.md diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 347bfee..dbe2345 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,29 @@ +2012-09-12 Nathan Froyd + Hans-Peter Nilsson + + * config/mmix/mmix.h (MMIX_REG_OK_STRICT): Delete. + (REG_CLASS_FROM_LETTER, CONST_OK_FOR_LETTER_P): Delete. + (CONST_DOUBLE_OK_FOR_LETTER_P, EXTRA_CONSTRAINT): Delete. + * config/mmix/mmix-protos.h (mmix_intval): Declare. + (mmix_const_ok_for_letter_p, mmix_extra_constraint): Delete. + (mmix_const_double_ok_for_letter_p): Delete. + * config/mmix/constraints.md: New file. + * config/mmix/mmix.md: Include it. + (iordi3): Fix typo; use "I" instead of undefined "H" constraint. + ("*call_real"): Update comment about not using the "p" constraint. + * config/mmix/predicates.md (mmix_reg_or_8bit_operand): Use + satisfies_constraint_I. + (mmix_address_operand): New predicate. + (mmix_symbolic_or_address_operand): Use it instead of address_operand. + * config/mmix/mmix.c: #include tm-constrs.h. + (mmix_intval): Delete declaration. Make non-static. + (mmix_const_ok_for_letter_p, mmix_extra_constraint): Delete. + (mmix_const_double_ok_for_letter_p): Delete. + (mmix_legitimate_address_p): Use satisfies_constraint_I. + (mmix_print_operand_address): Likewise. + (mmix_emit_sp_add): Adjust to use insn_const_int_ok_for_constraint + when matching "L" constraint. + 2012-09-11 Steven Bosscher * tree.h (expand_case): Move prototype ... diff --git a/gcc/config/mmix/constraints.md b/gcc/config/mmix/constraints.md new file mode 100644 index 0000000..954cdda --- /dev/null +++ b/gcc/config/mmix/constraints.md @@ -0,0 +1,112 @@ +;; MMIX constraints +;; Copyright (C) 2012 Free Software Foundation, Inc. +;; +;; 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 3, 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 COPYING3. If not see +;; . */ + +(define_register_constraint "x" "SYSTEM_REGS" + "@internal") + +(define_register_constraint "y" "REMAINDER_REG" + "@internal") + +(define_register_constraint "z" "HIMULT_REG" + "@internal") + +(define_constraint "I" + "A 8-bit unsigned integer" + (and (match_code "const_int") + (match_test "IN_RANGE (ival, 0, 255)"))) + +(define_constraint "J" + "A 16-bit unsigned integer." + (and (match_code "const_int") + (match_test "IN_RANGE (ival, 0, 65535)"))) + +(define_constraint "K" + "An integer between -255 and 0." + (and (match_code "const_int") + (match_test "IN_RANGE (ival, -255, 0)"))) + +(define_constraint "L" + "@internal" + (and (match_code "const_int") + (match_test "mmix_shiftable_wyde_value (ival)"))) + +(define_constraint "M" + "The value 0." + (and (match_code "const_int") + (match_test "ival == 0"))) + +(define_constraint "N" + "@internal" + (and (match_code "const_int") + (match_test "mmix_shiftable_wyde_value (~ival)"))) + +(define_constraint "O" + "The value 3, 5, 9, or 17." + (and (match_code "const_int") + (ior (match_test "ival == 3") + (match_test "ival == 5") + (match_test "ival == 9") + (match_test "ival == 17")))) + +;; FIXME: M (or G) is redundant. + +(define_constraint "G" + "Floating-point zero." + (and (match_code "const_double") + (match_test "op == CONST0_RTX (mode)"))) + +;; R asks whether x is to be loaded with GETA or something else. Right +;; now, only a SYMBOL_REF and LABEL_REF can fit for +;; TARGET_BASE_ADDRESSES. +;; +;; Only constant symbolic addresses apply. With TARGET_BASE_ADDRESSES, +;; we just allow straight LABEL_REF or SYMBOL_REFs with SYMBOL_REF_FLAG +;; set right now; only function addresses and code labels. If we change +;; to let SYMBOL_REF_FLAG be set on other symbols, we have to check +;; inside CONST expressions. When TARGET_BASE_ADDRESSES is not in +;; effect, a "raw" constant check together with mmix_constant_address_p +;; is all that's needed; we want all constant addresses to be loaded +;; with GETA then. + +(define_constraint "R" + "@internal" + (and (not (match_code "const_int,const_double")) + (match_test "mmix_constant_address_p (op)") + (ior (match_test "!TARGET_BASE_ADDRESSES") + (match_code "LABEL_REF") + (and (match_code "SYMBOL_REF") + (match_test "SYMBOL_REF_FLAG (op)"))))) + +;; FIXME: L (or S) is redundant. + +(define_constraint "S" + "@internal" + (and (match_code "const_int,const_double") + (match_test "mmix_shiftable_wyde_value (mmix_intval (op))"))) + +;; FIXME: N (or T) is redundant. + +(define_constraint "T" + "@internal" + (and (match_code "const_int,const_double") + (match_test "mmix_shiftable_wyde_value (~mmix_intval (op))"))) + +(define_address_constraint "U" + "@internal" + (match_operand 0 "mmix_address_operand")) diff --git a/gcc/config/mmix/mmix-protos.h b/gcc/config/mmix/mmix-protos.h index 4e8c338..62cdbae 100644 --- a/gcc/config/mmix/mmix-protos.h +++ b/gcc/config/mmix/mmix-protos.h @@ -40,6 +40,7 @@ extern void mmix_asm_output_reg_push (FILE *, int); extern void mmix_asm_output_reg_pop (FILE *, int); extern void mmix_asm_output_skip (FILE *, int); extern void mmix_asm_output_align (FILE *, int); +extern HOST_WIDEST_INT mmix_intval (const_rtx); extern int mmix_shiftable_wyde_value (unsigned HOST_WIDEST_INT); extern void mmix_output_register_setting (FILE *, int, HOST_WIDEST_INT, int); extern int mmix_opposite_regno (int, int); @@ -59,9 +60,6 @@ extern void mmix_asm_output_addr_diff_elt (FILE *, rtx, int, int); extern void mmix_asm_output_addr_vec_elt (FILE *, int); extern enum reg_class mmix_secondary_reload_class (enum reg_class, enum machine_mode, rtx, int); -extern int mmix_const_ok_for_letter_p (HOST_WIDE_INT, int); -extern int mmix_const_double_ok_for_letter_p (rtx, int); -extern int mmix_extra_constraint (rtx, int, int); extern rtx mmix_dynamic_chain_address (rtx); extern rtx mmix_return_addr_rtx (int, rtx); extern rtx mmix_eh_return_stackadj_rtx (void); diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c index eaf5f2e..d5d72df 100644 --- a/gcc/config/mmix/mmix.c +++ b/gcc/config/mmix/mmix.c @@ -44,6 +44,7 @@ along with GCC; see the file COPYING3. If not see #include "target.h" #include "target-def.h" #include "df.h" +#include "tm-constrs.h" /* First some local helper definitions. */ #define MMIX_FIRST_GLOBAL_REGNUM 32 @@ -118,7 +119,6 @@ static void mmix_output_shiftvalue_op_from_str (FILE *, const char *, HOST_WIDEST_INT); static void mmix_output_shifted_value (FILE *, HOST_WIDEST_INT); static void mmix_output_condition (FILE *, const_rtx, int); -static HOST_WIDEST_INT mmix_intval (const_rtx); static void mmix_output_octa (FILE *, HOST_WIDEST_INT, int); static bool mmix_assemble_integer (rtx, unsigned int, int); static struct machine_function *mmix_init_machine_status (void); @@ -459,87 +459,6 @@ mmix_secondary_reload_class (enum reg_class rclass, return NO_REGS; } -/* CONST_OK_FOR_LETTER_P. */ - -int -mmix_const_ok_for_letter_p (HOST_WIDE_INT value, int c) -{ - return - (c == 'I' ? value >= 0 && value <= 255 - : c == 'J' ? value >= 0 && value <= 65535 - : c == 'K' ? value <= 0 && value >= -255 - : c == 'L' ? mmix_shiftable_wyde_value (value) - : c == 'M' ? value == 0 - : c == 'N' ? mmix_shiftable_wyde_value (~value) - : c == 'O' ? (value == 3 || value == 5 || value == 9 - || value == 17) - : 0); -} - -/* CONST_DOUBLE_OK_FOR_LETTER_P. */ - -int -mmix_const_double_ok_for_letter_p (rtx value, int c) -{ - return - (c == 'G' ? value == CONST0_RTX (GET_MODE (value)) - : 0); -} - -/* EXTRA_CONSTRAINT. - We need this since our constants are not always expressible as - CONST_INT:s, but rather often as CONST_DOUBLE:s. */ - -int -mmix_extra_constraint (rtx x, int c, int strict) -{ - HOST_WIDEST_INT value; - - /* When checking for an address, we need to handle strict vs. non-strict - register checks. Don't use address_operand, but instead its - equivalent (its callee, which it is just a wrapper for), - memory_operand_p and the strict-equivalent strict_memory_address_p. */ - if (c == 'U') - return - strict - ? strict_memory_address_p (Pmode, x) - : memory_address_p (Pmode, x); - - /* R asks whether x is to be loaded with GETA or something else. Right - now, only a SYMBOL_REF and LABEL_REF can fit for - TARGET_BASE_ADDRESSES. - - Only constant symbolic addresses apply. With TARGET_BASE_ADDRESSES, - we just allow straight LABEL_REF or SYMBOL_REFs with SYMBOL_REF_FLAG - set right now; only function addresses and code labels. If we change - to let SYMBOL_REF_FLAG be set on other symbols, we have to check - inside CONST expressions. When TARGET_BASE_ADDRESSES is not in - effect, a "raw" constant check together with mmix_constant_address_p - is all that's needed; we want all constant addresses to be loaded - with GETA then. */ - if (c == 'R') - return - GET_CODE (x) != CONST_INT && GET_CODE (x) != CONST_DOUBLE - && mmix_constant_address_p (x) - && (! TARGET_BASE_ADDRESSES - || (GET_CODE (x) == LABEL_REF - || (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FLAG (x)))); - - if (GET_CODE (x) != CONST_DOUBLE || GET_MODE (x) != VOIDmode) - return 0; - - value = mmix_intval (x); - - /* We used to map Q->J, R->K, S->L, T->N, U->O, but we don't have to any - more ('U' taken for address_operand, 'R' similarly). Some letters map - outside of CONST_INT, though; we still use 'S' and 'T'. */ - if (c == 'S') - return mmix_shiftable_wyde_value (value); - else if (c == 'T') - return mmix_shiftable_wyde_value (~value); - return 0; -} - /* DYNAMIC_CHAIN_ADDRESS. */ rtx @@ -1161,8 +1080,7 @@ mmix_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, return 1; /* (mem (plus (reg) (0..255?))) */ - if (GET_CODE (x2) == CONST_INT - && CONST_OK_FOR_LETTER_P (INTVAL (x2), 'I')) + if (satisfies_constraint_I (x2)) return 1; return 0; @@ -1843,8 +1761,7 @@ mmix_print_operand_address (FILE *stream, rtx x) reg_names[MMIX_OUTPUT_REGNO (REGNO (x2))]); return; } - else if (GET_CODE (x2) == CONST_INT - && CONST_OK_FOR_LETTER_P (INTVAL (x2), 'I')) + else if (satisfies_constraint_I (x2)) { output_addr_const (stream, x2); return; @@ -2529,7 +2446,7 @@ mmix_emit_sp_add (HOST_WIDE_INT offset) { /* Positive adjustments are in the epilogue only. Don't mark them as "frame-related" for unwind info. */ - if (CONST_OK_FOR_LETTER_P (offset, 'L')) + if (insn_const_int_ok_for_constraint (offset, CONSTRAINT_L)) emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (offset))); @@ -2754,7 +2671,7 @@ mmix_output_condition (FILE *stream, const_rtx x, int reversed) /* Return the bit-value for a const_int or const_double. */ -static HOST_WIDEST_INT +HOST_WIDEST_INT mmix_intval (const_rtx x) { unsigned HOST_WIDEST_INT retval; diff --git a/gcc/config/mmix/mmix.h b/gcc/config/mmix/mmix.h index 787f64f..07b7368 100644 --- a/gcc/config/mmix/mmix.h +++ b/gcc/config/mmix/mmix.h @@ -72,12 +72,6 @@ along with GCC; see the file COPYING3. If not see untouched by the epilogue". */ #define MMIX_EH_RETURN_STACKADJ_REGNUM MMIX_STATIC_CHAIN_REGNUM -#ifdef REG_OK_STRICT -# define MMIX_REG_OK_STRICT 1 -#else -# define MMIX_REG_OK_STRICT 0 -#endif - #define MMIX_FUNCTION_ARG_SIZE(MODE, TYPE) \ ((MODE) != BLKmode ? GET_MODE_SIZE (MODE) : int_size_in_bytes (TYPE)) @@ -439,11 +433,6 @@ enum reg_class #define INDEX_REG_CLASS GENERAL_REGS -#define REG_CLASS_FROM_LETTER(CHAR) \ - ((CHAR) == 'x' ? SYSTEM_REGS \ - : (CHAR) == 'y' ? REMAINDER_REG \ - : (CHAR) == 'z' ? HIMULT_REG : NO_REGS) - #define REGNO_OK_FOR_BASE_P(REGNO) \ ((REGNO) <= MMIX_LAST_GENERAL_REGISTER \ || (REGNO) == MMIX_ARG_POINTER_REGNUM \ @@ -460,16 +449,6 @@ enum reg_class #define CLASS_MAX_NREGS(CLASS, MODE) HARD_REGNO_NREGS (CLASS, MODE) -#define CONST_OK_FOR_LETTER_P(VALUE, C) \ - mmix_const_ok_for_letter_p (VALUE, C) - -#define EXTRA_CONSTRAINT(VALUE, C) \ - mmix_extra_constraint (VALUE, C, MMIX_REG_OK_STRICT) - -/* Do we need anything serious here? Yes, any FLOT constant. */ -#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \ - mmix_const_double_ok_for_letter_p (VALUE, C) - /* Node: Frame Layout */ diff --git a/gcc/config/mmix/mmix.md b/gcc/config/mmix/mmix.md index 1cd397a..24d6292 100644 --- a/gcc/config/mmix/mmix.md +++ b/gcc/config/mmix/mmix.md @@ -43,6 +43,7 @@ ;; Operand and operator predicates. (include "predicates.md") +(include "constraints.md") ;; FIXME: Can we remove the reg-to-reg for smaller modes? Shouldn't they ;; be synthesized ok? @@ -274,7 +275,7 @@ (define_insn "iordi3" [(set (match_operand:DI 0 "register_operand" "=r,r") (ior:DI (match_operand:DI 1 "register_operand" "%r,0") - (match_operand:DI 2 "mmix_reg_or_constant_operand" "rH,LS")))] + (match_operand:DI 2 "mmix_reg_or_constant_operand" "rI,LS")))] "" "@ OR %0,%1,%2 @@ -1037,6 +1038,7 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2") ;; first ("p") alternative by adding ? in the first operand ;; might do the trick. We define 'U' as a synonym to 'p', but without the ;; caveats (and very small advantages) of 'p'. +;; As of r190682 still so: newlib/libc/stdlib/dtoa.c ICEs if "p" is used. (define_insn "*call_real" [(call (mem:QI (match_operand:DI 0 "mmix_symbolic_or_address_operand" "s,rU")) diff --git a/gcc/config/mmix/predicates.md b/gcc/config/mmix/predicates.md index b5773b8..f9ba32c 100644 --- a/gcc/config/mmix/predicates.md +++ b/gcc/config/mmix/predicates.md @@ -118,7 +118,7 @@ return 1; /* Fall through. */ default: - return address_operand (op, mode); + return mmix_address_operand (op, mode); } }) @@ -152,4 +152,12 @@ (ior (match_operand 0 "register_operand") (and (match_code "const_int") - (match_test "CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')")))) + (match_test "satisfies_constraint_I (op)")))) + +;; True if this is a memory address, possibly strictly. +;; See also comment above the "*call_real" pattern. + +(define_predicate "mmix_address_operand" + (if_then_else (match_test "reload_in_progress || reload_completed") + (match_test "strict_memory_address_p (Pmode, op)") + (match_test "memory_address_p (Pmode, op)"))) -- 2.7.4