OSDN Git Service

* config/xtensa/xtensa-protos.h: (xtensa_simm7, xtensa_uimm8,
authorbwilson <bwilson@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 21 Mar 2005 18:08:32 +0000 (18:08 +0000)
committerbwilson <bwilson@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 21 Mar 2005 18:08:32 +0000 (18:08 +0000)
xtensa_uimm8x2, xtensa_uimm8x4, xtensa_ai4const, xtensa_lsi4x4,
xtensa_b4const): Delete prototypes.
(xtensa_simm8, xtensa_simm8x256, xtensa_simm12b, xtensa_b4constu,
xtensa_mask_immediate, xtensa_mem_offset): Update prototypes.
(xtensa_b4const_or_zero, xtensa_const_ok_for_letter_p,
xtensa_extra_constraint): New prototypes.
(add_operand, arith_operand, nonimmed_operand, mem_operand,
mask_operand, extui_fldsz_operand, sext_operand, sext_fldsz_operand,
lsbitnum_operand, branch_operand, ubranch_operand, call_insn_operand,
move_operand, const_float_1_operand, fpmem_offset_operand,
branch_operator, ubranch_operator, boolean_operator): Delete prototypes.
* config/xtensa/xtensa.c (b4const_or_zero): Rename to ...
(xtensa_b4const_or_zero): ...this.  Change return type to bool and
argument type to HOST_WIDE_INT.
(xtensa_simm8, xtensa_simm8x256, xtensa_simm12b,
xtensa_mask_immediate): Likewise.
(xtensa_uimm8, xtensa_uimm8x2, xtensa_uimm8x4, xtensa_b4const):
Likewise.  Also make these functions static.
(xtensa_simm7, xtensa_ai4const, xtensa_lsi4x4): Delete.
(xtensa_const_ok_for_letter_p): New.
(add_operand, arith_operand, nonimmed_operand, mem_operand,
mask_operand, extui_fldsz_operand, sext_operand, sext_fldsz_operand,
lsbitnum_operand, branch_operand, ubranch_operand, call_insn_operand,
move_operand, const_float_1_operand, fpmem_offset_operand,
branch_operator, ubranch_operator, boolean_operator): Move to
predicates.md.
(smalloffset_mem_p): Inline code from xtensa_lsi4x4.
(xtensa_mem_offset): Change return type to bool.
(xtensa_extra_constraint): New.
(gen_int_relational): Update type of const_range_p function pointer.
Use xtensa_b4const_or_zero.
* config/xtensa/xtensa.h (CONST_OK_FOR_LETTER_P): Define to
xtensa_const_ok_for_letter_p.  Update comments.
(EXTRA_CONSTRAINT): Define to xtensa_extra_constraint.
(PREDICATE_CODES): Delete.
* config/xtensa/xtensa.md: Include predicates.md.
* config/xtensa/predicates.md: New file.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@96824 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/xtensa/predicates.md [new file with mode: 0644]
gcc/config/xtensa/xtensa-protos.h
gcc/config/xtensa/xtensa.c
gcc/config/xtensa/xtensa.h
gcc/config/xtensa/xtensa.md

index a6642c7..e86cd11 100644 (file)
@@ -1,3 +1,44 @@
+2005-03-21  Bob Wilson  <bob.wilson@acm.org>
+
+       * config/xtensa/xtensa-protos.h: (xtensa_simm7, xtensa_uimm8,
+       xtensa_uimm8x2, xtensa_uimm8x4, xtensa_ai4const, xtensa_lsi4x4,
+       xtensa_b4const): Delete prototypes.
+       (xtensa_simm8, xtensa_simm8x256, xtensa_simm12b, xtensa_b4constu,
+       xtensa_mask_immediate, xtensa_mem_offset): Update prototypes.
+       (xtensa_b4const_or_zero, xtensa_const_ok_for_letter_p,
+       xtensa_extra_constraint): New prototypes.
+       (add_operand, arith_operand, nonimmed_operand, mem_operand,
+       mask_operand, extui_fldsz_operand, sext_operand, sext_fldsz_operand,
+       lsbitnum_operand, branch_operand, ubranch_operand, call_insn_operand,
+       move_operand, const_float_1_operand, fpmem_offset_operand,
+       branch_operator, ubranch_operator, boolean_operator): Delete prototypes.
+       * config/xtensa/xtensa.c (b4const_or_zero): Rename to ...
+       (xtensa_b4const_or_zero): ...this.  Change return type to bool and
+       argument type to HOST_WIDE_INT.
+       (xtensa_simm8, xtensa_simm8x256, xtensa_simm12b,
+       xtensa_mask_immediate): Likewise.
+       (xtensa_uimm8, xtensa_uimm8x2, xtensa_uimm8x4, xtensa_b4const):
+       Likewise.  Also make these functions static.
+       (xtensa_simm7, xtensa_ai4const, xtensa_lsi4x4): Delete.
+       (xtensa_const_ok_for_letter_p): New.
+       (add_operand, arith_operand, nonimmed_operand, mem_operand,
+       mask_operand, extui_fldsz_operand, sext_operand, sext_fldsz_operand,
+       lsbitnum_operand, branch_operand, ubranch_operand, call_insn_operand,
+       move_operand, const_float_1_operand, fpmem_offset_operand,
+       branch_operator, ubranch_operator, boolean_operator): Move to
+       predicates.md.
+       (smalloffset_mem_p): Inline code from xtensa_lsi4x4.
+       (xtensa_mem_offset): Change return type to bool.
+       (xtensa_extra_constraint): New.
+       (gen_int_relational): Update type of const_range_p function pointer.
+       Use xtensa_b4const_or_zero.
+       * config/xtensa/xtensa.h (CONST_OK_FOR_LETTER_P): Define to
+       xtensa_const_ok_for_letter_p.  Update comments.
+       (EXTRA_CONSTRAINT): Define to xtensa_extra_constraint.
+       (PREDICATE_CODES): Delete.
+       * config/xtensa/xtensa.md: Include predicates.md.
+       * config/xtensa/predicates.md: New file.
+
 2005-03-21  Kazu Hirata  <kazu@cs.umass.edu>
 
        * config/v850/v850-protos.h: Remove the prototypes for
diff --git a/gcc/config/xtensa/predicates.md b/gcc/config/xtensa/predicates.md
new file mode 100644 (file)
index 0000000..335584d
--- /dev/null
@@ -0,0 +1,157 @@
+;; Predicate definitions for Xtensa.
+;; Copyright (C) 2005 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, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+(define_predicate "add_operand"
+  (ior (and (match_code "const_int")
+           (match_test "xtensa_simm8 (INTVAL (op))
+                        || xtensa_simm8x256 (INTVAL (op))"))
+       (match_operand 0 "register_operand")))
+
+(define_predicate "arith_operand"
+  (ior (and (match_code "const_int")
+           (match_test "xtensa_simm8 (INTVAL (op))"))
+       (match_operand 0 "register_operand")))
+
+;; Non-immediate operand excluding the constant pool.
+(define_predicate "nonimmed_operand"
+  (ior (and (match_operand 0 "memory_operand")
+           (match_test "!constantpool_address_p (XEXP (op, 0))"))
+       (match_operand 0 "register_operand")))
+
+;; Memory operand excluding the constant pool.
+(define_predicate "mem_operand"
+  (and (match_operand 0 "memory_operand")
+       (match_test "!constantpool_address_p (XEXP (op, 0))")))
+
+(define_predicate "mask_operand"
+  (ior (and (match_code "const_int")
+           (match_test "xtensa_mask_immediate (INTVAL (op))"))
+       (match_operand 0 "register_operand")))
+
+(define_predicate "extui_fldsz_operand"
+  (and (match_code "const_int")
+       (match_test "xtensa_mask_immediate ((1 << INTVAL (op)) - 1)")))
+
+(define_predicate "sext_operand"
+  (if_then_else (match_test "TARGET_SEXT")
+               (match_operand 0 "nonimmed_operand")
+               (match_operand 0 "mem_operand")))
+
+(define_predicate "sext_fldsz_operand"
+  (and (match_code "const_int")
+       (match_test "INTVAL (op) >= 8 && INTVAL (op) <= 23")))
+
+(define_predicate "lsbitnum_operand"
+  (and (match_code "const_int")
+       (match_test "BITS_BIG_ENDIAN
+                   ? (INTVAL (op) == BITS_PER_WORD - 1)
+                   : (INTVAL (op) == 0)")))
+
+(define_predicate "branch_operand"
+  (ior (and (match_code "const_int")
+           (match_test "xtensa_b4const_or_zero (INTVAL (op))"))
+       (match_operand 0 "register_operand")))
+
+(define_predicate "ubranch_operand"
+  (ior (and (match_code "const_int")
+           (match_test "xtensa_b4constu (INTVAL (op))"))
+       (match_operand 0 "register_operand")))
+
+(define_predicate "call_insn_operand"
+  (match_code "const_int,const,symbol_ref,reg")
+{
+  if ((GET_CODE (op) == REG)
+      && (op != arg_pointer_rtx)
+      && ((REGNO (op) < FRAME_POINTER_REGNUM)
+         || (REGNO (op) > LAST_VIRTUAL_REGISTER)))
+    return true;
+
+  if (CONSTANT_ADDRESS_P (op))
+    {
+      /* Direct calls only allowed to static functions with PIC.  */
+      if (flag_pic)
+       {
+         tree callee, callee_sec, caller_sec;
+
+         if (GET_CODE (op) != SYMBOL_REF
+             || !SYMBOL_REF_LOCAL_P (op) || SYMBOL_REF_EXTERNAL_P (op))
+           return false;
+
+         /* Don't attempt a direct call if the callee is known to be in
+            a different section, since there's a good chance it will be
+            out of range.  */
+
+         if (flag_function_sections
+             || DECL_ONE_ONLY (current_function_decl))
+           return false;
+         caller_sec = DECL_SECTION_NAME (current_function_decl);
+         callee = SYMBOL_REF_DECL (op);
+         if (callee)
+           {
+             if (DECL_ONE_ONLY (callee))
+               return false;
+             callee_sec = DECL_SECTION_NAME (callee);
+             if (((caller_sec == NULL_TREE) ^ (callee_sec == NULL_TREE))
+                 || (caller_sec != NULL_TREE
+                     && strcmp (TREE_STRING_POINTER (caller_sec),
+                                TREE_STRING_POINTER (callee_sec)) != 0))
+               return false;
+           }
+         else if (caller_sec != NULL_TREE)
+           return false;
+       }
+      return true;
+    }
+
+  return false;
+})
+
+(define_predicate "move_operand"
+  (ior
+     (ior (match_operand 0 "register_operand")
+         (match_operand 0 "memory_operand"))
+     (ior (and (match_code "const_int")
+              (match_test "GET_MODE_CLASS (mode) == MODE_INT
+                           && xtensa_simm12b (INTVAL (op))"))
+         (and (match_code "const_int,const_double,const,symbol_ref,label_ref")
+              (match_test "TARGET_CONST16 && CONSTANT_P (op)
+                           && GET_MODE_SIZE (mode) % UNITS_PER_WORD == 0")))))
+
+;; Accept the floating point constant 1 in the appropriate mode.
+(define_predicate "const_float_1_operand"
+  (match_code "const_double")
+{
+  REAL_VALUE_TYPE d;
+  REAL_VALUE_FROM_CONST_DOUBLE (d, op);
+  return REAL_VALUES_EQUAL (d, dconst1);
+})
+
+(define_predicate "fpmem_offset_operand"
+  (and (match_code "const_int")
+       (match_test "xtensa_mem_offset (INTVAL (op), SFmode)")))
+
+(define_predicate "branch_operator"
+  (match_code "eq,ne,lt,ge"))
+
+(define_predicate "ubranch_operator"
+  (match_code "ltu,geu"))
+
+(define_predicate "boolean_operator"
+  (match_code "eq,ne"))
index f50286d..5f19ebf 100644 (file)
@@ -1,5 +1,5 @@
 /* Prototypes of target machine for GNU compiler for Xtensa.
-   Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
 
 This file is part of GCC.
@@ -23,45 +23,24 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #define __XTENSA_PROTOS_H__
 
 /* Functions to test whether an immediate fits in a given field.  */
-extern int xtensa_simm7 (int);
-extern int xtensa_simm8 (int);
-extern int xtensa_simm8x256 (int);
-extern int xtensa_simm12b (int);
-extern int xtensa_uimm8 (int);
-extern int xtensa_uimm8x2 (int);
-extern int xtensa_uimm8x4 (int);
-extern int xtensa_ai4const (int);
-extern int xtensa_lsi4x4 (int);
-extern int xtensa_b4const (int);
-extern int xtensa_b4constu (int);
-extern int xtensa_tp7 (int);
+extern bool xtensa_simm8 (HOST_WIDE_INT);
+extern bool xtensa_simm8x256 (HOST_WIDE_INT);
+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.  */
 #ifdef RTX_CODE
 extern int xt_true_regnum (rtx);
-extern int add_operand (rtx, enum machine_mode);
-extern int arith_operand (rtx, enum machine_mode);
-extern int nonimmed_operand (rtx, enum machine_mode);
-extern int mem_operand (rtx, enum machine_mode);
 extern int xtensa_valid_move (enum machine_mode, rtx *);
-extern int mask_operand (rtx, enum machine_mode);
-extern int extui_fldsz_operand (rtx, enum machine_mode);
-extern int sext_operand (rtx, enum machine_mode);
-extern int sext_fldsz_operand (rtx, enum machine_mode);
-extern int lsbitnum_operand (rtx, enum machine_mode);
-extern int branch_operand (rtx, enum machine_mode);
-extern int ubranch_operand (rtx, enum machine_mode);
-extern int call_insn_operand (rtx, enum machine_mode);
-extern int move_operand (rtx, enum machine_mode);
 extern int smalloffset_mem_p (rtx);
 extern int constantpool_address_p (rtx);
 extern int constantpool_mem_p (rtx);
-extern int const_float_1_operand (rtx, enum machine_mode);
-extern int fpmem_offset_operand (rtx, enum machine_mode);
 extern void xtensa_extend_reg (rtx, rtx);
-extern int branch_operator (rtx, enum machine_mode);
-extern int ubranch_operator (rtx, enum machine_mode);
-extern int boolean_operator (rtx, enum machine_mode);
+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 *);
@@ -94,8 +73,6 @@ extern struct rtx_def *function_arg (CUMULATIVE_ARGS *, enum machine_mode,
                                     tree, int);
 #endif /* TREE_CODE */
 
-extern int xtensa_mask_immediate (int);
-extern int xtensa_mem_offset (unsigned, enum machine_mode);
 extern void xtensa_setup_frame_addresses (void);
 extern int xtensa_dbx_register_number (int);
 extern void override_options (void);
index 0c29324..cdba18c 100644 (file)
@@ -1,5 +1,5 @@
 /* Subroutines for insn-output.c for Tensilica's Xtensa architecture.
-   Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
 
 This file is part of GCC.
@@ -192,7 +192,6 @@ enum reg_class xtensa_char_to_class[256] =
   NO_REGS,     NO_REGS,        NO_REGS,        NO_REGS,
 };
 
-static int b4const_or_zero (int);
 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);
@@ -270,13 +269,55 @@ struct gcc_target targetm = TARGET_INITIALIZER;
  * Functions to test Xtensa immediate operand validity.
  */
 
-int
-xtensa_b4constu (int v)
+bool
+xtensa_simm8 (HOST_WIDE_INT v)
+{
+  return v >= -128 && v <= 127;
+}
+
+
+bool
+xtensa_simm8x256 (HOST_WIDE_INT v)
+{
+  return (v & 255) == 0 && (v >= -32768 && v <= 32512);
+}
+
+
+bool
+xtensa_simm12b (HOST_WIDE_INT v)
+{
+  return v >= -2048 && v <= 2047;
+}
+
+
+static bool
+xtensa_uimm8 (HOST_WIDE_INT v)
+{
+  return v >= 0 && v <= 255;
+}
+
+
+static bool
+xtensa_uimm8x2 (HOST_WIDE_INT v)
+{
+  return (v & 1) == 0 && (v >= 0 && v <= 510);
+}
+
+
+static bool
+xtensa_uimm8x4 (HOST_WIDE_INT v)
+{
+  return (v & 3) == 0 && (v >= 0 && v <= 1020);
+}
+
+
+static bool
+xtensa_b4const (HOST_WIDE_INT v)
 {
   switch (v)
     {
-    case 32768:
-    case 65536:
+    case -1:
+    case 1:
     case 2:
     case 3:
     case 4:
@@ -291,36 +332,28 @@ xtensa_b4constu (int v)
     case 64:
     case 128:
     case 256:
-      return 1;
+      return true;
     }
-  return 0;
+  return false;
 }
 
-int
-xtensa_simm8x256 (int v)
-{
-  return (v & 255) == 0 && (v >= -32768 && v <= 32512);
-}
 
-int
-xtensa_ai4const (int v)
+bool
+xtensa_b4const_or_zero (HOST_WIDE_INT v)
 {
-  return (v == -1 || (v >= 1 && v <= 15));
+  if (v == 0)
+    return true;
+  return xtensa_b4const (v);
 }
 
-int
-xtensa_simm7 (int v)
-{
-  return v >= -32 && v <= 95;
-}
 
-int
-xtensa_b4const (int v)
+bool
+xtensa_b4constu (HOST_WIDE_INT v)
 {
   switch (v)
     {
-    case -1:
-    case 1:
+    case 32768:
+    case 65536:
     case 2:
     case 3:
     case 4:
@@ -335,51 +368,47 @@ xtensa_b4const (int v)
     case 64:
     case 128:
     case 256:
-      return 1;
+      return true;
     }
-  return 0;
+  return false;
 }
 
-int
-xtensa_simm8 (int v)
-{
-  return v >= -128 && v <= 127;
-}
-
-int
-xtensa_tp7 (int v)
-{
-  return (v >= 7 && v <= 22);
-}
 
-int
-xtensa_lsi4x4 (int v)
+bool
+xtensa_mask_immediate (HOST_WIDE_INT v)
 {
-  return (v & 3) == 0 && (v >= 0 && v <= 60);
-}
+#define MAX_MASK_SIZE 16
+  int mask_size;
 
-int
-xtensa_simm12b (int v)
-{
-  return v >= -2048 && v <= 2047;
-}
+  for (mask_size = 1; mask_size <= MAX_MASK_SIZE; mask_size++)
+    {
+      if ((v & 1) == 0)
+       return false;
+      v = v >> 1;
+      if (v == 0)
+       return true;
+    }
 
-int
-xtensa_uimm8 (int v)
-{
-  return v >= 0 && v <= 255;
+  return false;
 }
 
-int
-xtensa_uimm8x2 (int v)
-{
-  return (v & 1) == 0 && (v >= 0 && v <= 510);
-}
 
-int
-xtensa_uimm8x4 (int v)
+bool
+xtensa_const_ok_for_letter_p (HOST_WIDE_INT v, int c)
 {
-  return (v & 3) == 0 && (v >= 0 && v <= 1020);
+  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;
 }
 
 
@@ -410,52 +439,6 @@ xt_true_regnum (rtx x)
 
 
 int
-add_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_CODE (op) == CONST_INT)
-    return (xtensa_simm8 (INTVAL (op)) || xtensa_simm8x256 (INTVAL (op)));
-
-  return register_operand (op, mode);
-}
-
-
-int
-arith_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_CODE (op) == CONST_INT)
-    return xtensa_simm8 (INTVAL (op));
-
-  return register_operand (op, mode);
-}
-
-
-int
-nonimmed_operand (rtx op, enum machine_mode mode)
-{
-  /* We cannot use the standard nonimmediate_operand() predicate because
-     it includes constant pool memory operands.  */
-
-  if (memory_operand (op, mode))
-    return !constantpool_address_p (XEXP (op, 0));
-
-  return register_operand (op, mode);
-}
-
-
-int
-mem_operand (rtx op, enum machine_mode mode)
-{
-  /* We cannot use the standard memory_operand() predicate because
-     it includes constant pool memory operands.  */
-
-  if (memory_operand (op, mode))
-    return !constantpool_address_p (XEXP (op, 0));
-
-  return FALSE;
-}
-
-
-int
 xtensa_valid_move (enum machine_mode mode, rtx *operands)
 {
   /* Either the destination or source must be a register, and the
@@ -485,165 +468,6 @@ xtensa_valid_move (enum machine_mode mode, rtx *operands)
 
 
 int
-mask_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_CODE (op) == CONST_INT)
-    return xtensa_mask_immediate (INTVAL (op));
-
-  return register_operand (op, mode);
-}
-
-
-int
-extui_fldsz_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return ((GET_CODE (op) == CONST_INT)
-         && xtensa_mask_immediate ((1 << INTVAL (op)) - 1));
-}
-
-
-int
-sext_operand (rtx op, enum machine_mode mode)
-{
-  if (TARGET_SEXT)
-    return nonimmed_operand (op, mode);
-  return mem_operand (op, mode);
-}
-
-
-int
-sext_fldsz_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return ((GET_CODE (op) == CONST_INT) && xtensa_tp7 (INTVAL (op) - 1));
-}
-
-
-int
-lsbitnum_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  if (GET_CODE (op) == CONST_INT)
-    {
-      return (BITS_BIG_ENDIAN
-             ? (INTVAL (op) == BITS_PER_WORD-1)
-             : (INTVAL (op) == 0));
-    }
-  return FALSE;
-}
-
-
-static int
-b4const_or_zero (int v)
-{
-  if (v == 0)
-    return TRUE;
-  return xtensa_b4const (v);
-}
-
-
-int
-branch_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_CODE (op) == CONST_INT)
-    return b4const_or_zero (INTVAL (op));
-
-  return register_operand (op, mode);
-}
-
-
-int
-ubranch_operand (rtx op, enum machine_mode mode)
-{
-  if (GET_CODE (op) == CONST_INT)
-    return xtensa_b4constu (INTVAL (op));
-
-  return register_operand (op, mode);
-}
-
-
-int
-call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  if ((GET_CODE (op) == REG)
-      && (op != arg_pointer_rtx)
-      && ((REGNO (op) < FRAME_POINTER_REGNUM)
-         || (REGNO (op) > LAST_VIRTUAL_REGISTER)))
-    return TRUE;
-
-  if (CONSTANT_ADDRESS_P (op))
-    {
-      /* Direct calls only allowed to static functions with PIC.  */
-      if (flag_pic)
-       {
-         tree callee, callee_sec, caller_sec;
-
-         if (GET_CODE (op) != SYMBOL_REF
-             || !SYMBOL_REF_LOCAL_P (op) || SYMBOL_REF_EXTERNAL_P (op))
-           return FALSE;
-
-         /* Don't attempt a direct call if the callee is known to be in
-            a different section, since there's a good chance it will be
-            out of range.  */
-
-         if (flag_function_sections
-             || DECL_ONE_ONLY (current_function_decl))
-           return FALSE;
-         caller_sec = DECL_SECTION_NAME (current_function_decl);
-         callee = SYMBOL_REF_DECL (op);
-         if (callee)
-           {
-             if (DECL_ONE_ONLY (callee))
-               return FALSE;
-             callee_sec = DECL_SECTION_NAME (callee);
-             if (((caller_sec == NULL_TREE) ^ (callee_sec == NULL_TREE))
-                 || (caller_sec != NULL_TREE
-                     && strcmp (TREE_STRING_POINTER (caller_sec),
-                                TREE_STRING_POINTER (callee_sec)) != 0))
-               return FALSE;
-           }
-         else if (caller_sec != NULL_TREE)
-           return FALSE;
-       }
-      return TRUE;
-    }
-
-  return FALSE;
-}
-
-
-int
-move_operand (rtx op, enum machine_mode mode)
-{
-  if (register_operand (op, mode)
-      || memory_operand (op, mode))
-    return TRUE;
-
-  switch (mode)
-    {
-    case DFmode:
-    case SFmode:
-      return TARGET_CONST16 && CONSTANT_P (op);
-
-    case DImode:
-    case SImode:
-      if (TARGET_CONST16)
-       return CONSTANT_P (op);
-      /* Fall through.  */
-
-    case HImode:
-    case QImode:
-      if (GET_CODE (op) == CONST_INT && xtensa_simm12b (INTVAL (op)))
-       return TRUE;
-      break;
-
-    default:
-      break;
-    }
-
-  return FALSE;
-}
-
-
-int
 smalloffset_mem_p (rtx op)
 {
   if (GET_CODE (op) == MEM)
@@ -654,11 +478,14 @@ smalloffset_mem_p (rtx op)
       if (GET_CODE (addr) == PLUS)
        {
          rtx offset = XEXP (addr, 0);
+         HOST_WIDE_INT val;
          if (GET_CODE (offset) != CONST_INT)
            offset = XEXP (addr, 1);
          if (GET_CODE (offset) != CONST_INT)
            return FALSE;
-         return xtensa_lsi4x4 (INTVAL (offset));
+
+         val = INTVAL (offset);
+         return (val & 3) == 0 && (val >= 0 && val <= 60);
        }
     }
   return FALSE;
@@ -704,46 +531,6 @@ constantpool_mem_p (rtx op)
 }
 
 
-/* Accept the floating point constant 1 in the appropriate mode.  */
-
-int
-const_float_1_operand (rtx op, enum machine_mode mode)
-{
-  REAL_VALUE_TYPE d;
-  static REAL_VALUE_TYPE onedf;
-  static REAL_VALUE_TYPE onesf;
-  static int one_initialized;
-
-  if ((GET_CODE (op) != CONST_DOUBLE)
-      || (mode != GET_MODE (op))
-      || (mode != DFmode && mode != SFmode))
-    return FALSE;
-
-  REAL_VALUE_FROM_CONST_DOUBLE (d, op);
-
-  if (! one_initialized)
-    {
-      onedf = REAL_VALUE_ATOF ("1.0", DFmode);
-      onesf = REAL_VALUE_ATOF ("1.0", SFmode);
-      one_initialized = TRUE;
-    }
-
-  if (mode == DFmode)
-    return REAL_VALUES_EQUAL (d, onedf);
-  else
-    return REAL_VALUES_EQUAL (d, onesf);
-}
-
-
-int
-fpmem_offset_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  if (GET_CODE (op) == CONST_INT)
-    return xtensa_mem_offset (INTVAL (op), SFmode);
-  return 0;
-}
-
-
 void
 xtensa_extend_reg (rtx dst, rtx src)
 {
@@ -759,82 +546,7 @@ xtensa_extend_reg (rtx dst, rtx src)
 }
 
 
-int
-branch_operator (rtx x, enum machine_mode mode)
-{
-  if (GET_MODE (x) != mode)
-    return FALSE;
-
-  switch (GET_CODE (x))
-    {
-    case EQ:
-    case NE:
-    case LT:
-    case GE:
-      return TRUE;
-    default:
-      break;
-    }
-  return FALSE;
-}
-
-
-int
-ubranch_operator (rtx x, enum machine_mode mode)
-{
-  if (GET_MODE (x) != mode)
-    return FALSE;
-
-  switch (GET_CODE (x))
-    {
-    case LTU:
-    case GEU:
-      return TRUE;
-    default:
-      break;
-    }
-  return FALSE;
-}
-
-
-int
-boolean_operator (rtx x, enum machine_mode mode)
-{
-  if (GET_MODE (x) != mode)
-    return FALSE;
-
-  switch (GET_CODE (x))
-    {
-    case EQ:
-    case NE:
-      return TRUE;
-    default:
-      break;
-    }
-  return FALSE;
-}
-
-
-int
-xtensa_mask_immediate (int v)
-{
-#define MAX_MASK_SIZE 16
-  int mask_size;
-
-  for (mask_size = 1; mask_size <= MAX_MASK_SIZE; mask_size++)
-    {
-      if ((v & 1) == 0)
-       return FALSE;
-      v = v >> 1;
-      if (v == 0)
-       return TRUE;
-    }
-
-  return FALSE;
-}
-
-
-int
+bool
 xtensa_mem_offset (unsigned v, enum machine_mode mode)
 {
   switch (mode)
@@ -865,6 +577,26 @@ 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
@@ -903,7 +635,7 @@ gen_int_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
   struct cmp_info
   {
     enum rtx_code test_code;   /* test code to use in insn */
-    int (*const_range_p) (int);        /* predicate function to check range */
+    bool (*const_range_p) (HOST_WIDE_INT); /* range check function */
     int const_add;             /* constant to add (convert LE -> LT) */
     int reverse_regs;          /* reverse registers in test */
     int invert_const;          /* != 0 if invert value if cmp1 is constant */
@@ -913,13 +645,13 @@ gen_int_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
 
   static struct cmp_info info[ (int)ITEST_MAX ] = {
 
-    { EQ,      b4const_or_zero,        0, 0, 0, 0, 0 },        /* EQ  */
-    { NE,      b4const_or_zero,        0, 0, 0, 0, 0 },        /* NE  */
+    { EQ,      xtensa_b4const_or_zero, 0, 0, 0, 0, 0 },        /* EQ  */
+    { NE,      xtensa_b4const_or_zero, 0, 0, 0, 0, 0 },        /* NE  */
 
-    { LT,      b4const_or_zero,        1, 1, 1, 0, 0 },        /* GT  */
-    { GE,      b4const_or_zero,        0, 0, 0, 0, 0 },        /* GE  */
-    { LT,      b4const_or_zero,        0, 0, 0, 0, 0 },        /* LT  */
-    { GE,      b4const_or_zero,        1, 1, 1, 0, 0 },        /* LE  */
+    { LT,      xtensa_b4const_or_zero, 1, 1, 1, 0, 0 },        /* GT  */
+    { GE,      xtensa_b4const_or_zero, 0, 0, 0, 0, 0 },        /* GE  */
+    { LT,      xtensa_b4const_or_zero, 0, 0, 0, 0, 0 },        /* LT  */
+    { GE,      xtensa_b4const_or_zero, 1, 1, 1, 0, 0 },        /* LE  */
 
     { LTU,     xtensa_b4constu,        1, 1, 1, 0, 1 },        /* GTU */
     { GEU,     xtensa_b4constu,        0, 0, 0, 0, 1 },        /* GEU */
index f60df57..ebaed27 100644 (file)
@@ -545,29 +545,16 @@ extern enum reg_class xtensa_char_to_class[256];
 
    For Xtensa:
 
-   I = 12-bit signed immediate for movi
-   J = 8-bit signed immediate for addi
+   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 value in simm7
-   N = 8-bit unsigned immediate shifted left by 8 bits for addmi
-   O = 4-bit value in ai4const
-   P = valid immediate mask value for extui */
-
-#define CONST_OK_FOR_LETTER_P(VALUE, C)                                        \
-  ((C) == 'I' ? (xtensa_simm12b (VALUE))                               \
-   : (C) == 'J' ? (xtensa_simm8 (VALUE))                               \
-   : (C) == 'K' ? (((VALUE) == 0) || xtensa_b4const (VALUE))           \
-   : (C) == 'L' ? (xtensa_b4constu (VALUE))                            \
-   : (C) == 'M' ? (xtensa_simm7 (VALUE))                               \
-   : (C) == 'N' ? (xtensa_simm8x256 (VALUE))                           \
-   : (C) == 'O' ? (xtensa_ai4const (VALUE))                            \
-   : (C) == 'P' ? (xtensa_mask_immediate (VALUE))                      \
-   : FALSE)
-
-
-/* Similar, but for floating constants, and defining letters G and H.
-   Here VALUE is the CONST_DOUBLE rtx itself.  */
+   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)
 
 
@@ -591,15 +578,7 @@ extern enum reg_class xtensa_char_to_class[256];
    address will be checked anyway because of the code in
    GO_IF_LEGITIMATE_ADDRESS.  */
 
-#define EXTRA_CONSTRAINT(OP, CODE)                                     \
-  ((GET_CODE (OP) != MEM) ?                                            \
-       ((CODE) >= 'R' && (CODE) <= 'U'                                 \
-       && reload_in_progress && GET_CODE (OP) == REG                   \
-        && REGNO (OP) >= FIRST_PSEUDO_REGISTER)                                \
-   : ((CODE) == 'R') ? smalloffset_mem_p (OP)                          \
-   : ((CODE) == 'T') ? !TARGET_CONST16 && constantpool_mem_p (OP)      \
-   : ((CODE) == 'U') ? !constantpool_mem_p (OP)                                \
-   : FALSE)
+#define EXTRA_CONSTRAINT  xtensa_extra_constraint
 
 #define PREFERRED_RELOAD_CLASS(X, CLASS)                               \
   xtensa_preferred_reload_class (X, CLASS, 0)
@@ -1149,37 +1128,6 @@ typedef struct xtensa_args
 
 #define BRANCH_COST 3
 
-/* Optionally define this if you have added predicates to
-   'MACHINE.c'.  This macro is called within an initializer of an
-   array of structures.  The first field in the structure is the
-   name of a predicate and the second field is an array of rtl
-   codes.  For each predicate, list all rtl codes that can be in
-   expressions matched by the predicate.  The list should have a
-   trailing comma.  */
-
-#define PREDICATE_CODES                                                        \
-  {"add_operand",              { REG, CONST_INT, SUBREG }},            \
-  {"arith_operand",            { REG, CONST_INT, SUBREG }},            \
-  {"nonimmed_operand",         { REG, SUBREG, MEM }},                  \
-  {"mem_operand",              { MEM }},                               \
-  {"mask_operand",             { REG, CONST_INT, SUBREG }},            \
-  {"extui_fldsz_operand",      { CONST_INT }},                         \
-  {"sext_fldsz_operand",       { CONST_INT }},                         \
-  {"lsbitnum_operand",         { CONST_INT }},                         \
-  {"fpmem_offset_operand",     { CONST_INT }},                         \
-  {"sext_operand",             { REG, SUBREG, MEM }},                  \
-  {"branch_operand",           { REG, CONST_INT, SUBREG }},            \
-  {"ubranch_operand",          { REG, CONST_INT, SUBREG }},            \
-  {"call_insn_operand",                { CONST_INT, CONST, SYMBOL_REF, REG }}, \
-  {"move_operand",             { REG, SUBREG, MEM, CONST_INT, CONST_DOUBLE, \
-                                 CONST, SYMBOL_REF, LABEL_REF }},      \
-  {"const_float_1_operand",    { CONST_DOUBLE }},                      \
-  {"branch_operator",          { EQ, NE, LT, GE }},                    \
-  {"ubranch_operator",         { LTU, GEU }},                          \
-  {"boolean_operator",         { EQ, NE }},
-
-/* Control the assembler format that we output.  */
-
 /* How to refer to registers in assembler output.
    This sequence is indexed by compiler's hard-register-number (see above).  */
 #define REGISTER_NAMES                                                 \
index 448a892..8d93db0 100644 (file)
                         (eq_attr "type" "fconv")
                         "nothing")
 \f
+;; Include predicate definitions
+
+(include "predicates.md")
+
+\f
 ;; Addition.
 
 (define_expand "adddi3"