xtensa-protos.h: (xtensa_simm7...
* 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. From-SVN: r96824
This commit is contained in:
parent
c690027275
commit
8eb1bc5cf5
6 changed files with 348 additions and 488 deletions
|
@ -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
|
||||
|
|
157
gcc/config/xtensa/predicates.md
Normal file
157
gcc/config/xtensa/predicates.md
Normal file
|
@ -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"))
|
|
@ -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);
|
||||
|
|
|
@ -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,52 +269,50 @@ 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)
|
||||
{
|
||||
switch (v)
|
||||
{
|
||||
case 32768:
|
||||
case 65536:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 10:
|
||||
case 12:
|
||||
case 16:
|
||||
case 32:
|
||||
case 64:
|
||||
case 128:
|
||||
case 256:
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return v >= -128 && v <= 127;
|
||||
}
|
||||
|
||||
int
|
||||
xtensa_simm8x256 (int v)
|
||||
|
||||
bool
|
||||
xtensa_simm8x256 (HOST_WIDE_INT v)
|
||||
{
|
||||
return (v & 255) == 0 && (v >= -32768 && v <= 32512);
|
||||
}
|
||||
|
||||
int
|
||||
xtensa_ai4const (int v)
|
||||
|
||||
bool
|
||||
xtensa_simm12b (HOST_WIDE_INT v)
|
||||
{
|
||||
return (v == -1 || (v >= 1 && v <= 15));
|
||||
return v >= -2048 && v <= 2047;
|
||||
}
|
||||
|
||||
int
|
||||
xtensa_simm7 (int v)
|
||||
|
||||
static bool
|
||||
xtensa_uimm8 (HOST_WIDE_INT v)
|
||||
{
|
||||
return v >= -32 && v <= 95;
|
||||
return v >= 0 && v <= 255;
|
||||
}
|
||||
|
||||
int
|
||||
xtensa_b4const (int v)
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -335,51 +332,83 @@ xtensa_b4const (int v)
|
|||
case 64:
|
||||
case 128:
|
||||
case 256:
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
int
|
||||
xtensa_simm8 (int v)
|
||||
|
||||
bool
|
||||
xtensa_b4const_or_zero (HOST_WIDE_INT v)
|
||||
{
|
||||
return v >= -128 && v <= 127;
|
||||
if (v == 0)
|
||||
return true;
|
||||
return xtensa_b4const (v);
|
||||
}
|
||||
|
||||
int
|
||||
xtensa_tp7 (int v)
|
||||
|
||||
bool
|
||||
xtensa_b4constu (HOST_WIDE_INT v)
|
||||
{
|
||||
return (v >= 7 && v <= 22);
|
||||
switch (v)
|
||||
{
|
||||
case 32768:
|
||||
case 65536:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 10:
|
||||
case 12:
|
||||
case 16:
|
||||
case 32:
|
||||
case 64:
|
||||
case 128:
|
||||
case 256:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
xtensa_simm12b (int v)
|
||||
{
|
||||
return v >= -2048 && v <= 2047;
|
||||
}
|
||||
|
||||
int
|
||||
xtensa_uimm8 (int v)
|
||||
bool
|
||||
xtensa_const_ok_for_letter_p (HOST_WIDE_INT v, int c)
|
||||
{
|
||||
return v >= 0 && v <= 255;
|
||||
}
|
||||
|
||||
int
|
||||
xtensa_uimm8x2 (int v)
|
||||
{
|
||||
return (v & 1) == 0 && (v >= 0 && v <= 510);
|
||||
}
|
||||
|
||||
int
|
||||
xtensa_uimm8x4 (int v)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -409,52 +438,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)
|
||||
{
|
||||
|
@ -484,165 +467,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)
|
||||
{
|
||||
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
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(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. */
|
||||
#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 \
|
||||
|
|
|
@ -87,6 +87,11 @@
|
|||
(define_insn_reservation "xtensa_fconv" 2
|
||||
(eq_attr "type" "fconv")
|
||||
"nothing")
|
||||
|
||||
;; Include predicate definitions
|
||||
|
||||
(include "predicates.md")
|
||||
|
||||
|
||||
;; Addition.
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue