From 887af464cde973b03e4e95ee3ad13a5c2ea076d8 Mon Sep 17 00:00:00 2001
From: Bob Wilson <bob.wilson@acm.org>
Date: Tue, 21 Nov 2006 21:49:26 +0000
Subject: [PATCH] xtensa.c (xtensa_char_to_class): Delete.

	* config/xtensa/xtensa.c (xtensa_char_to_class): Delete.
	(xtensa_const_ok_for_letter_p): Delete.
	(xtensa_extra_constraint): Delete.
	(override_options): Delete xtensa_char_to_class initialization.
	* config/xtensa/xtensa.h (REG_CLASS_FROM_LETTER): Delete.
	(CONST_OK_FOR_LETTER_P, CONST_DOUBLE_OK_FOR_LETTER_P): Delete.
	(EXTRA_CONSTRAINT): Delete.
	* config/xtensa/xtensa.md: Include constraints.md.
	(call_internal): Combine alternatives.
	(call_value_internal): Likewise, and remove invalid constraints.
	* config/xtensa/constraints.md: New file.
	* config/xtensa/xtensa-protos.h (xtensa_const_ok_for_letter_p): Delete.
	(xtensa_extra_constraint): Delete.
	* doc/md.texi (Machine Constraints): Refer to constraints.md for
	Xtensa constraints.
--Ths line, and those below, will be ignored--

M    gcc/doc/md.texi
M    gcc/ChangeLog
M    gcc/config/xtensa/xtensa.c
M    gcc/config/xtensa/xtensa.h
M    gcc/config/xtensa/xtensa.md
A    gcc/config/xtensa/constraints.md
M    gcc/config/xtensa/xtensa-protos.h

From-SVN: r119072
---
 gcc/ChangeLog                     |  18 ++++
 gcc/config/xtensa/constraints.md  | 140 ++++++++++++++++++++++++++++++
 gcc/config/xtensa/xtensa-protos.h |   2 -
 gcc/config/xtensa/xtensa.c        | 125 +-------------------------
 gcc/config/xtensa/xtensa.h        |  69 ---------------
 gcc/config/xtensa/xtensa.md       |  19 ++--
 gcc/doc/md.texi                   |   2 +-
 7 files changed, 168 insertions(+), 207 deletions(-)
 create mode 100644 gcc/config/xtensa/constraints.md

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c32942e2e298..6c05926a8c7e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,21 @@
+2006-11-21  Bob Wilson  <bob.wilson@acm.org>
+
+	* config/xtensa/xtensa.c (xtensa_char_to_class): Delete.
+	(xtensa_const_ok_for_letter_p): Delete.
+	(xtensa_extra_constraint): Delete.
+	(override_options): Delete xtensa_char_to_class initialization.
+	* config/xtensa/xtensa.h (REG_CLASS_FROM_LETTER): Delete.
+	(CONST_OK_FOR_LETTER_P, CONST_DOUBLE_OK_FOR_LETTER_P): Delete.
+	(EXTRA_CONSTRAINT): Delete.
+	* config/xtensa/xtensa.md: Include constraints.md.
+	(call_internal): Combine alternatives.
+	(call_value_internal): Likewise, and remove invalid constraints.
+	* config/xtensa/constraints.md: New file.
+	* config/xtensa/xtensa-protos.h (xtensa_const_ok_for_letter_p): Delete.
+	(xtensa_extra_constraint): Delete.
+	* doc/md.texi (Machine Constraints): Refer to constraints.md for
+	Xtensa constraints.
+
 2006-11-21  Janis Johnson  <janis187@us.ibm.com>
 
 	* config/dfp-bits.c (DFP_TO_INT): Remove code to saturate result
diff --git a/gcc/config/xtensa/constraints.md b/gcc/config/xtensa/constraints.md
new file mode 100644
index 000000000000..c58d979c3ce0
--- /dev/null
+++ b/gcc/config/xtensa/constraints.md
@@ -0,0 +1,140 @@
+;; Constraint definitions for Xtensa.
+;; Copyright (C) 2006 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 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.
+
+;; Register constraints.
+
+(define_register_constraint "a" "GR_REGS"
+ "General-purpose AR registers @code{a0}-@code{a15},
+  except @code{a1} (@code{sp}).")
+
+(define_register_constraint "b" "TARGET_BOOLEANS ? BR_REGS : NO_REGS"
+ "Boolean registers @code{b0}-@code{b15}; only available if the Xtensa
+  Boolean Option is configured.")
+
+(define_register_constraint "d" "TARGET_DENSITY ? AR_REGS: NO_REGS"
+ "@internal
+  All AR registers, including sp, but only if the Xtensa Code Density
+  Option is configured.")
+
+(define_register_constraint "f" "TARGET_HARD_FLOAT ? FP_REGS : NO_REGS"
+ "Floating-point registers @code{f0}-@code{f15}; only available if the
+  Xtensa Floating-Pointer Coprocessor is configured.")
+
+(define_register_constraint "q" "SP_REG"
+ "@internal
+  The stack pointer (register @code{a1}).")
+
+(define_register_constraint "A" "TARGET_MAC16 ? ACC_REG : NO_REGS"
+ "The low 32 bits of the accumulator from the Xtensa MAC16 Option.")
+
+(define_register_constraint "B" "TARGET_SEXT ? GR_REGS : NO_REGS"
+ "@internal
+  General-purpose AR registers, but only if the Xtensa Sign Extend
+  Option is configured.")
+
+(define_register_constraint "C" "TARGET_MUL16 ? GR_REGS: NO_REGS"
+ "@internal
+  General-purpose AR registers, but only if the Xtensa 16-Bit Integer
+  Multiply Option is configured.")
+
+(define_register_constraint "D" "TARGET_DENSITY ? GR_REGS: NO_REGS"
+ "@internal
+  General-purpose AR registers, but only if the Xtensa Code Density
+  Option is configured.")
+
+(define_register_constraint "W" "TARGET_CONST16 ? GR_REGS: NO_REGS"
+ "@internal
+  General-purpose AR registers, but only if the Xtensa Const16
+  Option is configured.")
+
+;; Integer constant constraints.
+
+(define_constraint "I"
+ "A signed 12-bit integer constant for use with MOVI instructions."
+ (and (match_code "const_int")
+      (match_test "xtensa_simm12b (ival)")))
+
+(define_constraint "J"
+ "A signed 8-bit integer constant for use with ADDI instructions."
+ (and (match_code "const_int")
+      (match_test "xtensa_simm8 (ival)")))
+
+(define_constraint "K"
+ "A constant integer that can be an immediate operand of an Xtensa
+  conditional branch instruction that performs a signed comparison or
+  a comparison against zero."
+ (and (match_code "const_int")
+      (match_test "xtensa_b4const_or_zero (ival)")))
+
+(define_constraint "L"
+ "A constant integer that can be an immediate operand of an Xtensa
+  conditional branch instruction that performs an unsigned comparison."
+ (and (match_code "const_int")
+      (match_test "xtensa_b4constu (ival)")))
+
+(define_constraint "M"
+ "An integer constant in the range @minus{}32-95 for use with MOVI.N
+  instructions."
+ (and (match_code "const_int")
+      (match_test "ival >= -32 && ival <= 95")))
+
+(define_constraint "N"
+ "An unsigned 8-bit integer constant shifted left by 8 bits for use
+  with ADDMI instructions."
+ (and (match_code "const_int")
+      (match_test "xtensa_simm8x256 (ival)")))
+
+(define_constraint "O"
+ "An integer constant that can be used in ADDI.N instructions."
+ (and (match_code "const_int")
+      (match_test "ival == -1 || (ival >= 1 && ival <= 15)")))
+
+(define_constraint "P"
+ "An integer constant that can be used as a mask value in an EXTUI
+  instruction."
+ (and (match_code "const_int")
+      (match_test "xtensa_mask_immediate (ival)")))
+
+;; Memory constraints.  Do not use define_memory_constraint here.  Doing so
+;; causes reload to force some constants into the constant pool, but since
+;; the Xtensa constant pool can only be accessed with L32R instructions, it
+;; is always better to just copy a constant into a register.  Instead, use
+;; regular constraints but add a check to allow pseudos during reload.
+
+(define_constraint "R"
+ "Memory that can be accessed with a 4-bit unsigned offset from a register."
+ (ior (and (match_code "mem")
+	   (match_test "smalloffset_mem_p (op)"))
+      (and (match_code "reg")
+	   (match_test "reload_in_progress
+			&& REGNO (op) >= FIRST_PSEUDO_REGISTER"))))
+
+(define_constraint "T"
+ "Memory in a literal pool (addressable with an L32R instruction)."
+ (and (match_code "mem")
+      (match_test "!TARGET_CONST16 && constantpool_mem_p (op)")))
+
+(define_constraint "U"
+ "Memory that is not in a literal pool."
+ (ior (and (match_code "mem")
+	   (match_test "! constantpool_mem_p (op)"))
+      (and (match_code "reg")
+	   (match_test "reload_in_progress
+			&& REGNO (op) >= FIRST_PSEUDO_REGISTER"))))
diff --git a/gcc/config/xtensa/xtensa-protos.h b/gcc/config/xtensa/xtensa-protos.h
index 7f8ad2e8065b..762aa0aed61e 100644
--- a/gcc/config/xtensa/xtensa-protos.h
+++ b/gcc/config/xtensa/xtensa-protos.h
@@ -29,7 +29,6 @@ extern bool xtensa_simm12b (HOST_WIDE_INT);
 extern bool xtensa_b4const_or_zero (HOST_WIDE_INT);
 extern bool xtensa_b4constu (HOST_WIDE_INT);
 extern bool xtensa_mask_immediate (HOST_WIDE_INT);
-extern bool xtensa_const_ok_for_letter_p (HOST_WIDE_INT, int);
 extern bool xtensa_mem_offset (unsigned, enum machine_mode);
 
 /* Functions within xtensa.c that we reference.  */
@@ -40,7 +39,6 @@ extern int smalloffset_mem_p (rtx);
 extern int constantpool_address_p (rtx);
 extern int constantpool_mem_p (rtx);
 extern void xtensa_extend_reg (rtx, rtx);
-extern bool xtensa_extra_constraint (rtx, int);
 extern void xtensa_expand_conditional_branch (rtx *, enum rtx_code);
 extern int xtensa_expand_conditional_move (rtx *, int);
 extern int xtensa_expand_scc (rtx *);
diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
index fa5f08d2d233..011f63cd275d 100644
--- a/gcc/config/xtensa/xtensa.c
+++ b/gcc/config/xtensa/xtensa.c
@@ -123,75 +123,6 @@ const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER] =
   ACC_REG,
 };
 
-/* Map register constraint character to register class.  */
-enum reg_class xtensa_char_to_class[256] =
-{
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
-};
-
 static enum internal_test map_test_to_internal_test (enum rtx_code);
 static rtx gen_int_relational (enum rtx_code, rtx, rtx, int *);
 static rtx gen_float_relational (enum rtx_code, rtx, rtx);
@@ -276,11 +207,9 @@ static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] =
 #define TARGET_EXPAND_BUILTIN xtensa_expand_builtin
 
 struct gcc_target targetm = TARGET_INITIALIZER;
-
 
-/*
- * Functions to test Xtensa immediate operand validity.
- */
+
+/* Functions to test Xtensa immediate operand validity.  */
 
 bool
 xtensa_simm8 (HOST_WIDE_INT v)
@@ -406,25 +335,6 @@ xtensa_mask_immediate (HOST_WIDE_INT v)
 }
 
 
-bool
-xtensa_const_ok_for_letter_p (HOST_WIDE_INT v, int c)
-{
-  switch (c)
-    {
-    case 'I': return xtensa_simm12b (v);
-    case 'J': return xtensa_simm8 (v);
-    case 'K': return (v == 0 || xtensa_b4const (v));
-    case 'L': return xtensa_b4constu (v);
-    case 'M': return (v >= -32 && v <= 95);
-    case 'N': return xtensa_simm8x256 (v);
-    case 'O': return (v == -1 || (v >= 1 && v <= 15));
-    case 'P': return xtensa_mask_immediate (v);
-    default: break;
-    }
-  return false;
-}
-
-
 /* This is just like the standard true_regnum() function except that it
    works even when reg_renumber is not initialized.  */
 
@@ -590,26 +500,6 @@ xtensa_mem_offset (unsigned v, enum machine_mode mode)
 }
 
 
-bool
-xtensa_extra_constraint (rtx op, int c)
-{
-  /* Allow pseudo registers during reload.  */
-  if (GET_CODE (op) != MEM)
-    return (c >= 'R' && c <= 'U'
-	    && reload_in_progress && GET_CODE (op) == REG
-	    && REGNO (op) >= FIRST_PSEUDO_REGISTER);
-
-  switch (c)
-    {
-    case 'R': return smalloffset_mem_p (op);
-    case 'T': return !TARGET_CONST16 && constantpool_mem_p (op);
-    case 'U': return !constantpool_mem_p (op);
-    default: break;
-    }
-  return false;
-}
-
-
 /* Make normal rtx_code into something we can index from an array.  */
 
 static enum internal_test
@@ -1623,17 +1513,6 @@ override_options (void)
   if (!TARGET_BOOLEANS && TARGET_HARD_FLOAT)
     error ("boolean registers required for the floating-point option");
 
-  xtensa_char_to_class['q'] = SP_REG;
-  xtensa_char_to_class['a'] = GR_REGS;
-  xtensa_char_to_class['b'] = ((TARGET_BOOLEANS) ? BR_REGS : NO_REGS);
-  xtensa_char_to_class['f'] = ((TARGET_HARD_FLOAT) ? FP_REGS : NO_REGS);
-  xtensa_char_to_class['A'] = ((TARGET_MAC16) ? ACC_REG : NO_REGS);
-  xtensa_char_to_class['B'] = ((TARGET_SEXT) ? GR_REGS : NO_REGS);
-  xtensa_char_to_class['C'] = ((TARGET_MUL16) ? GR_REGS: NO_REGS);
-  xtensa_char_to_class['D'] = ((TARGET_DENSITY) ? GR_REGS: NO_REGS);
-  xtensa_char_to_class['d'] = ((TARGET_DENSITY) ? AR_REGS: NO_REGS);
-  xtensa_char_to_class['W'] = ((TARGET_CONST16) ? GR_REGS: NO_REGS);
-
   /* Set up array giving whether a given register can hold a given mode.  */
   for (mode = VOIDmode;
        mode != MAX_MACHINE_MODE;
diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h
index 0f35da52cdb1..4300e11d7114 100644
--- a/gcc/config/xtensa/xtensa.h
+++ b/gcc/config/xtensa/xtensa.h
@@ -485,75 +485,6 @@ extern const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER];
    incoming or outgoing arguments.  */
 #define SMALL_REGISTER_CLASSES 1
 
-
-/* REGISTER AND CONSTANT CLASSES */
-
-/* Get reg_class from a letter such as appears in the machine
-   description.
-
-   Available letters: a-f,h,j-l,q,t-z,A-D,W,Y-Z
-
-   DEFINED REGISTER CLASSES:
-
-   'a'  general-purpose registers except sp
-   'q'  sp (aka a1)
-   'D'	general-purpose registers (only if density option enabled)
-   'd'  general-purpose registers, including sp (only if density enabled)
-   'A'	MAC16 accumulator (only if MAC16 option enabled)
-   'B'	general-purpose registers (only if sext instruction enabled)
-   'C'  general-purpose registers (only if mul16 option enabled)
-   'W'  general-purpose registers (only if const16 option enabled)
-   'b'	coprocessor boolean registers
-   'f'	floating-point registers
-*/
-
-extern enum reg_class xtensa_char_to_class[256];
-
-#define REG_CLASS_FROM_LETTER(C) xtensa_char_to_class[ (int) (C) ]
-
-/* The letters I, J, K, L, M, N, O, and P 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.
-
-   For Xtensa:
-
-   I = 12-bit signed immediate for MOVI
-   J = 8-bit signed immediate for ADDI
-   K = 4-bit value in (b4const U {0})
-   L = 4-bit value in b4constu
-   M = 7-bit immediate value for MOVI.N
-   N = 8-bit unsigned immediate shifted left by 8 bits for ADDMI
-   O = 4-bit immediate for ADDI.N
-   P = valid immediate mask value for EXTUI */
-
-#define CONST_OK_FOR_LETTER_P  xtensa_const_ok_for_letter_p
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) (0)
-
-
-/* Other letters can be defined in a machine-dependent fashion to
-   stand for particular classes of registers or other arbitrary
-   operand types.
-
-   R = memory that can be accessed with a 4-bit unsigned offset
-   T = memory in a constant pool (addressable with a pc-relative load)
-   U = memory *NOT* in a constant pool
-
-   The offset range should not be checked here (except to distinguish
-   denser versions of the instructions for which more general versions
-   are available).  Doing so leads to problems in reloading: an
-   argptr-relative address may become invalid when the phony argptr is
-   eliminated in favor of the stack pointer (the offset becomes too
-   large to fit in the instruction's immediate field); a reload is
-   generated to fix this but the RTL is not immediately updated; in
-   the meantime, the constraints are checked and none match.  The
-   solution seems to be to simply skip the offset check here.  The
-   address will be checked anyway because of the code in
-   GO_IF_LEGITIMATE_ADDRESS.  */
-
-#define EXTRA_CONSTRAINT  xtensa_extra_constraint
-
 #define PREFERRED_RELOAD_CLASS(X, CLASS)				\
   xtensa_preferred_reload_class (X, CLASS, 0)
 
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index c3f38cb93e80..6b48e86e1dce 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -117,9 +117,10 @@
 			 (eq_attr "type" "fconv")
 			 "nothing")
 
-;; Include predicate definitions
+;; Include predicates and constraints.
 
 (include "predicates.md")
+(include "constraints.md")
 
 
 ;; Addition.
@@ -1570,8 +1571,8 @@
 })
 
 (define_insn "call_internal"
-  [(call (mem (match_operand:SI 0 "call_insn_operand" "n,i,r"))
-	 (match_operand 1 "" "i,i,i"))]
+  [(call (mem (match_operand:SI 0 "call_insn_operand" "nir"))
+	 (match_operand 1 "" "i"))]
   ""
 {
   return xtensa_emit_call (0, operands);
@@ -1594,16 +1595,10 @@
     XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
 })
 
-;; Cannot combine constraints for operand 0 into "afvb":
-;; reload.c:find_reloads seems to assume that grouped constraints somehow
-;; specify related register classes, and when they don't the constraints
-;; fail to match.  By not grouping the constraints, we get the correct
-;; behavior.
 (define_insn "call_value_internal"
-   [(set (match_operand 0 "register_operand" "=af,af,af,v,v,v,b,b,b")
-         (call (mem (match_operand:SI 1 "call_insn_operand"
-					"n,i,r,n,i,r,n,i,r"))
-               (match_operand 2 "" "i,i,i,i,i,i,i,i,i")))]
+   [(set (match_operand 0 "register_operand" "=a")
+         (call (mem (match_operand:SI 1 "call_insn_operand" "nir"))
+               (match_operand 2 "" "i")))]
   ""
 {
   return xtensa_emit_call (1, operands);
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 2696eca7ebfd..6e7a55a34ec2 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -3006,7 +3006,7 @@ The constant 0.
 
 @end table
 
-@item Xtensa---@file{config/xtensa/xtensa.h}
+@item Xtensa---@file{config/xtensa/constraints.md}
 @table @code
 @item a
 General-purpose 32-bit register
-- 
GitLab