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:
Bob Wilson 2005-03-21 18:08:32 +00:00 committed by Bob Wilson
parent c690027275
commit 8eb1bc5cf5
6 changed files with 348 additions and 488 deletions

View 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

View 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"))

View 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);

View 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,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 */

View 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 */
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 \

View File

@ -87,6 +87,11 @@
(define_insn_reservation "xtensa_fconv" 2
(eq_attr "type" "fconv")
"nothing")
;; Include predicate definitions
(include "predicates.md")
;; Addition.