From 7d0f7bf8796f6f2af3eb54c527ac5714fe193883 Mon Sep 17 00:00:00 2001 From: bwilson Date: Mon, 21 Mar 2005 18:08:32 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@96824 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 41 +++ gcc/config/xtensa/predicates.md | 157 ++++++++++++ gcc/config/xtensa/xtensa-protos.h | 43 +--- gcc/config/xtensa/xtensa.c | 508 +++++++++----------------------------- gcc/config/xtensa/xtensa.h | 70 +----- gcc/config/xtensa/xtensa.md | 5 + 6 files changed, 342 insertions(+), 482 deletions(-) create mode 100644 gcc/config/xtensa/predicates.md diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a6642c7a1f9..e86cd11cfb1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,44 @@ +2005-03-21 Bob Wilson + + * 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 * 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 index 00000000000..335584d00e1 --- /dev/null +++ b/gcc/config/xtensa/predicates.md @@ -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")) diff --git a/gcc/config/xtensa/xtensa-protos.h b/gcc/config/xtensa/xtensa-protos.h index f50286d058f..5f19ebfe028 100644 --- a/gcc/config/xtensa/xtensa-protos.h +++ b/gcc/config/xtensa/xtensa-protos.h @@ -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); diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c index 0c29324eeec..cdba18c8388 100644 --- a/gcc/config/xtensa/xtensa.c +++ b/gcc/config/xtensa/xtensa.c @@ -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 */ diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h index f60df57bb93..ebaed273d14 100644 --- a/gcc/config/xtensa/xtensa.h +++ b/gcc/config/xtensa/xtensa.h @@ -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 \ diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md index 448a892d744..8d93db0e999 100644 --- a/gcc/config/xtensa/xtensa.md +++ b/gcc/config/xtensa/xtensa.md @@ -88,6 +88,11 @@ (eq_attr "type" "fconv") "nothing") +;; Include predicate definitions + +(include "predicates.md") + + ;; Addition. (define_expand "adddi3" -- 2.11.0