+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
--- /dev/null
+;; 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"))
/* 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.
#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 *);
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);
/* 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.
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);
* 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:
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:
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;
}
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
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)
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;
}
-/* 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)
{
}
-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)
}
+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
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 */
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 */
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)
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)
#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 \
(eq_attr "type" "fconv")
"nothing")
\f
+;; Include predicate definitions
+
+(include "predicates.md")
+
+\f
;; Addition.
(define_expand "adddi3"