diff options
author | Kazu Hirata <kazu@codesourcery.com> | 2005-06-30 15:55:35 +0000 |
---|---|---|
committer | Kazu Hirata <kazu@gcc.gnu.org> | 2005-06-30 15:55:35 +0000 |
commit | 9e9d785dcb02c60ea70a6b01c4dcde3f6c776e47 (patch) | |
tree | b20c583c841591f0e1128a16516e72fe36b4077e /gcc | |
parent | 3aebbe5f49f9b9ccda66fc1eb907603e84813878 (diff) | |
download | gcc-9e9d785dcb02c60ea70a6b01c4dcde3f6c776e47.zip gcc-9e9d785dcb02c60ea70a6b01c4dcde3f6c776e47.tar.gz gcc-9e9d785dcb02c60ea70a6b01c4dcde3f6c776e47.tar.bz2 |
c4x-protos.h: Remove the prototypes for those functions removed from c4x.c.
* config/c4x/c4x-protos.h: Remove the prototypes for those
functions removed from c4x.c. Add prototypes for those
functions exported in c4x.c.
* config/c4x/c4x.c (any_operand, fp_zero_operand,
const_operand, stik_const_operand, not_const_operand,
reg_operand, r0r1_reg_operand, r2r3_reg_operand,
ext_low_reg_operand, ext_reg_operand, std_reg_operand,
std_or_reg_operand, addr_reg_operand, index_reg_operand,
dp_reg_operand, sp_reg_operand, st_reg_operand,
rc_reg_operand, call_address_operand,
symbolic_address_operand, dst_operand, src_operand,
src_hi_operand, lsrc_operand, tsrc_operand,
nonimmediate_src_operand, nonimmediate_lsrc_operand,
reg_or_const_operand, par_ind_operand, parallel_operand):
Remove.
(c4x_immed_float_p, c4x_a_register, c4x_x_register,
c4x_K_constant, c4x_N_constant, c4x_O_constant,
c4x_S_indirect): Export.
* config/c4x/c4x.h (PREDICATE_CODES): Remove.
* config/c4x/c4x.md: Include predicates.md.
* config/c4x/predicates.md: New.
From-SVN: r101469
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 24 | ||||
-rw-r--r-- | gcc/config/c4x/c4x-protos.h | 74 | ||||
-rw-r--r-- | gcc/config/c4x/c4x.c | 422 | ||||
-rw-r--r-- | gcc/config/c4x/c4x.h | 35 | ||||
-rw-r--r-- | gcc/config/c4x/c4x.md | 3 | ||||
-rw-r--r-- | gcc/config/c4x/predicates.md | 404 |
6 files changed, 452 insertions, 510 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 54cc32c..e4f3e8a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,27 @@ +2005-06-30 Kazu Hirata <kazu@codesourcery.com> + + * config/c4x/c4x-protos.h: Remove the prototypes for those + functions removed from c4x.c. Add prototypes for those + functions exported in c4x.c. + * config/c4x/c4x.c (any_operand, fp_zero_operand, + const_operand, stik_const_operand, not_const_operand, + reg_operand, r0r1_reg_operand, r2r3_reg_operand, + ext_low_reg_operand, ext_reg_operand, std_reg_operand, + std_or_reg_operand, addr_reg_operand, index_reg_operand, + dp_reg_operand, sp_reg_operand, st_reg_operand, + rc_reg_operand, call_address_operand, + symbolic_address_operand, dst_operand, src_operand, + src_hi_operand, lsrc_operand, tsrc_operand, + nonimmediate_src_operand, nonimmediate_lsrc_operand, + reg_or_const_operand, par_ind_operand, parallel_operand): + Remove. + (c4x_immed_float_p, c4x_a_register, c4x_x_register, + c4x_K_constant, c4x_N_constant, c4x_O_constant, + c4x_S_indirect): Export. + * config/c4x/c4x.h (PREDICATE_CODES): Remove. + * config/c4x/c4x.md: Include predicates.md. + * config/c4x/predicates.md: New. + 2005-06-30 Jakub Jelinek <jakub@redhat.com> * function.c (stack_protect_epilogue): Pass label to diff --git a/gcc/config/c4x/c4x-protos.h b/gcc/config/c4x/c4x-protos.h index 1b830fd..059e25b 100644 --- a/gcc/config/c4x/c4x-protos.h +++ b/gcc/config/c4x/c4x-protos.h @@ -1,5 +1,5 @@ /* Definitions of target machine for GNU compiler. TMS320C[34]x - Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2003, 2004 + Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2003, 2004, 2005 Free Software Foundation, Inc. Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz) @@ -98,66 +98,12 @@ extern int c4x_check_laj_p (rtx); extern int c4x_autoinc_operand (rtx, enum machine_mode); -extern int any_operand (rtx, enum machine_mode); - -extern int fp_zero_operand (rtx, enum machine_mode); - -extern int const_operand (rtx, enum machine_mode); - -extern int stik_const_operand (rtx, enum machine_mode); - -extern int not_const_operand (rtx, enum machine_mode); - -extern int parallel_operand (rtx, enum machine_mode); - extern int reg_or_const_operand (rtx, enum machine_mode); -extern int reg_operand (rtx, enum machine_mode); - extern int mixed_subreg_operand (rtx, enum machine_mode); extern int reg_imm_operand (rtx, enum machine_mode); -extern int r0r1_reg_operand (rtx, enum machine_mode); - -extern int r2r3_reg_operand (rtx, enum machine_mode); - -extern int ext_low_reg_operand (rtx, enum machine_mode); - -extern int ext_reg_operand (rtx, enum machine_mode); - -extern int std_reg_operand (rtx, enum machine_mode); - -extern int std_or_reg_operand (rtx, enum machine_mode); - -extern int dst_operand (rtx, enum machine_mode); - -extern int src_operand (rtx, enum machine_mode); - -extern int src_hi_operand (rtx, enum machine_mode); - -extern int lsrc_operand (rtx, enum machine_mode); - -extern int tsrc_operand (rtx, enum machine_mode); - -extern int nonimmediate_src_operand (rtx, enum machine_mode); - -extern int nonimmediate_lsrc_operand (rtx, enum machine_mode); - -extern int addr_reg_operand (rtx, enum machine_mode); - -extern int index_reg_operand (rtx, enum machine_mode); - -extern int dp_reg_operand (rtx, enum machine_mode); - -extern int sp_reg_operand (rtx, enum machine_mode); - -extern int rc_reg_operand (rtx, enum machine_mode); - -extern int st_reg_operand (rtx, enum machine_mode); - -extern int symbolic_address_operand (rtx, enum machine_mode); - extern int ar0_reg_operand (rtx, enum machine_mode); extern int ar0_mem_operand (rtx, enum machine_mode); @@ -204,28 +150,38 @@ extern int group1_mem_operand (rtx, enum machine_mode); extern int arx_reg_operand (rtx, enum machine_mode); -extern int call_address_operand (rtx, enum machine_mode); - -extern int par_ind_operand (rtx, enum machine_mode); - extern int not_rc_reg (rtx, enum machine_mode); extern int not_modify_reg (rtx, enum machine_mode); extern int c4x_shiftable_constant (rtx); +extern int c4x_immed_float_p (rtx); + +extern int c4x_a_register (rtx); + +extern int c4x_x_register (rtx); + extern int c4x_H_constant (rtx); extern int c4x_I_constant (rtx); extern int c4x_J_constant (rtx); +extern int c4x_K_constant (rtx); + extern int c4x_L_constant (rtx); +extern int c4x_N_constant (rtx); + +extern int c4x_O_constant (rtx); + extern int c4x_Q_constraint (rtx); extern int c4x_R_constraint (rtx); +extern int c4x_S_indirect (rtx); + extern int c4x_S_constraint (rtx); extern int c4x_T_constraint (rtx); diff --git a/gcc/config/c4x/c4x.c b/gcc/config/c4x/c4x.c index 6e51172..bc9d396 100644 --- a/gcc/config/c4x/c4x.c +++ b/gcc/config/c4x/c4x.c @@ -169,16 +169,9 @@ static bool c4x_handle_option (size_t, const char *, int); static int c4x_isr_reg_used_p (unsigned int); static int c4x_leaf_function_p (void); static int c4x_naked_function_p (void); -static int c4x_immed_float_p (rtx); -static int c4x_a_register (rtx); -static int c4x_x_register (rtx); static int c4x_immed_int_constant (rtx); static int c4x_immed_float_constant (rtx); -static int c4x_K_constant (rtx); -static int c4x_N_constant (rtx); -static int c4x_O_constant (rtx); static int c4x_R_indirect (rtx); -static int c4x_S_indirect (rtx); static void c4x_S_address_parse (rtx , int *, int *, int *, int *); static int c4x_valid_operands (enum rtx_code, rtx *, enum machine_mode, int); static int c4x_arn_reg_operand (rtx, enum machine_mode, unsigned int); @@ -2150,7 +2143,7 @@ c4x_print_operand_address (FILE *file, rtx addr) /* Return nonzero if the floating point operand will fit in the immediate field. */ -static int +int c4x_immed_float_p (rtx op) { long convval[2]; @@ -2460,14 +2453,14 @@ c4x_reorg (void) } -static int +int c4x_a_register (rtx op) { return REG_P (op) && IS_ADDR_OR_PSEUDO_REG (op); } -static int +int c4x_x_register (rtx op) { return REG_P (op) && IS_INDEX_OR_PSEUDO_REG (op); @@ -2543,7 +2536,7 @@ c4x_J_constant (rtx op) } -static int +int c4x_K_constant (rtx op) { if (TARGET_C3X || ! c4x_immed_int_constant (op)) @@ -2559,14 +2552,14 @@ c4x_L_constant (rtx op) } -static int +int c4x_N_constant (rtx op) { return c4x_immed_int_constant (op) && IS_NOT_UINT16_CONST (INTVAL (op)); } -static int +int c4x_O_constant (rtx op) { return c4x_immed_int_constant (op) && IS_HIGH_CONST (INTVAL (op)); @@ -2771,7 +2764,7 @@ c4x_S_constraint (rtx op) } -static int +int c4x_S_indirect (rtx op) { enum machine_mode mode = GET_MODE (op); @@ -2907,88 +2900,6 @@ c4x_autoinc_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) } -/* Match any operand. */ - -int -any_operand (register rtx op ATTRIBUTE_UNUSED, - enum machine_mode mode ATTRIBUTE_UNUSED) -{ - return 1; -} - - -/* Nonzero if OP is a floating point value with value 0.0. */ - -int -fp_zero_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) -{ - REAL_VALUE_TYPE r; - - if (GET_CODE (op) != CONST_DOUBLE) - return 0; - REAL_VALUE_FROM_CONST_DOUBLE (r, op); - return REAL_VALUES_EQUAL (r, dconst0); -} - - -int -const_operand (register rtx op, register enum machine_mode mode) -{ - switch (mode) - { - case QFmode: - case HFmode: - if (GET_CODE (op) != CONST_DOUBLE - || GET_MODE (op) != mode - || GET_MODE_CLASS (mode) != MODE_FLOAT) - return 0; - - return c4x_immed_float_p (op); - -#if Pmode != QImode - case Pmode: -#endif - case QImode: - if (GET_CODE (op) != CONST_INT - || (GET_MODE (op) != VOIDmode && GET_MODE (op) != mode) - || GET_MODE_CLASS (mode) != MODE_INT) - return 0; - - return IS_HIGH_CONST (INTVAL (op)) || IS_INT16_CONST (INTVAL (op)); - - case HImode: - return 0; - - default: - return 0; - } -} - - -int -stik_const_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) -{ - return c4x_K_constant (op); -} - - -int -not_const_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) -{ - return c4x_N_constant (op); -} - - -int -reg_operand (rtx op, enum machine_mode mode) -{ - if (GET_CODE (op) == SUBREG - && GET_MODE (op) == QFmode) - return 0; - return register_operand (op, mode); -} - - int mixed_subreg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) { @@ -3067,325 +2978,6 @@ not_rc_reg (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) } -/* Extended precision register R0-R1. */ - -int -r0r1_reg_operand (rtx op, enum machine_mode mode) -{ - if (! reg_operand (op, mode)) - return 0; - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - return REG_P (op) && IS_R0R1_OR_PSEUDO_REG (op); -} - - -/* Extended precision register R2-R3. */ - -int -r2r3_reg_operand (rtx op, enum machine_mode mode) -{ - if (! reg_operand (op, mode)) - return 0; - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - return REG_P (op) && IS_R2R3_OR_PSEUDO_REG (op); -} - - -/* Low extended precision register R0-R7. */ - -int -ext_low_reg_operand (rtx op, enum machine_mode mode) -{ - if (! reg_operand (op, mode)) - return 0; - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - return REG_P (op) && IS_EXT_LOW_OR_PSEUDO_REG (op); -} - - -/* Extended precision register. */ - -int -ext_reg_operand (rtx op, enum machine_mode mode) -{ - if (! reg_operand (op, mode)) - return 0; - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - if (! REG_P (op)) - return 0; - return IS_EXT_OR_PSEUDO_REG (op); -} - - -/* Standard precision register. */ - -int -std_reg_operand (rtx op, enum machine_mode mode) -{ - if (! reg_operand (op, mode)) - return 0; - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - return REG_P (op) && IS_STD_OR_PSEUDO_REG (op); -} - -/* Standard precision or normal register. */ - -int -std_or_reg_operand (rtx op, enum machine_mode mode) -{ - if (reload_in_progress) - return std_reg_operand (op, mode); - return reg_operand (op, mode); -} - -/* Address register. */ - -int -addr_reg_operand (rtx op, enum machine_mode mode) -{ - if (! reg_operand (op, mode)) - return 0; - return c4x_a_register (op); -} - - -/* Index register. */ - -int -index_reg_operand (rtx op, enum machine_mode mode) -{ - if (! reg_operand (op, mode)) - return 0; - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - return c4x_x_register (op); -} - - -/* DP register. */ - -int -dp_reg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) -{ - return REG_P (op) && IS_DP_OR_PSEUDO_REG (op); -} - - -/* SP register. */ - -int -sp_reg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) -{ - return REG_P (op) && IS_SP_OR_PSEUDO_REG (op); -} - - -/* ST register. */ - -int -st_reg_operand (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) -{ - return REG_P (op) && IS_ST_OR_PSEUDO_REG (op); -} - - -/* RC register. */ - -int -rc_reg_operand (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) -{ - return REG_P (op) && IS_RC_OR_PSEUDO_REG (op); -} - - -int -call_address_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) -{ - return (REG_P (op) || symbolic_address_operand (op, mode)); -} - - -/* Symbolic address operand. */ - -int -symbolic_address_operand (register rtx op, - enum machine_mode mode ATTRIBUTE_UNUSED) -{ - switch (GET_CODE (op)) - { - case CONST: - case SYMBOL_REF: - case LABEL_REF: - return 1; - default: - return 0; - } -} - - -/* Check dst operand of a move instruction. */ - -int -dst_operand (rtx op, enum machine_mode mode) -{ - if (GET_CODE (op) == SUBREG - && mixed_subreg_operand (op, mode)) - return 0; - - if (REG_P (op)) - return reg_operand (op, mode); - - return nonimmediate_operand (op, mode); -} - - -/* Check src operand of two operand arithmetic instructions. */ - -int -src_operand (rtx op, enum machine_mode mode) -{ - if (GET_CODE (op) == SUBREG - && mixed_subreg_operand (op, mode)) - return 0; - - if (REG_P (op)) - return reg_operand (op, mode); - - if (mode == VOIDmode) - mode = GET_MODE (op); - - if (GET_CODE (op) == CONST_INT) - return (mode == QImode || mode == Pmode || mode == HImode) - && c4x_I_constant (op); - - /* We don't like CONST_DOUBLE integers. */ - if (GET_CODE (op) == CONST_DOUBLE) - return c4x_H_constant (op); - - /* Disallow symbolic addresses. Only the predicate - symbolic_address_operand will match these. */ - if (GET_CODE (op) == SYMBOL_REF - || GET_CODE (op) == LABEL_REF - || GET_CODE (op) == CONST) - return 0; - - /* If TARGET_LOAD_DIRECT_MEMS is nonzero, disallow direct memory - access to symbolic addresses. These operands will get forced - into a register and the movqi expander will generate a - HIGH/LO_SUM pair if TARGET_EXPOSE_LDP is nonzero. */ - if (GET_CODE (op) == MEM - && ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF - || GET_CODE (XEXP (op, 0)) == LABEL_REF - || GET_CODE (XEXP (op, 0)) == CONST))) - return !TARGET_EXPOSE_LDP && - ! TARGET_LOAD_DIRECT_MEMS && GET_MODE (op) == mode; - - return general_operand (op, mode); -} - - -int -src_hi_operand (rtx op, enum machine_mode mode) -{ - if (c4x_O_constant (op)) - return 1; - return src_operand (op, mode); -} - - -/* Check src operand of two operand logical instructions. */ - -int -lsrc_operand (rtx op, enum machine_mode mode) -{ - if (mode == VOIDmode) - mode = GET_MODE (op); - - if (mode != QImode && mode != Pmode) - fatal_insn ("mode not QImode", op); - - if (GET_CODE (op) == CONST_INT) - return c4x_L_constant (op) || c4x_J_constant (op); - - return src_operand (op, mode); -} - - -/* Check src operand of two operand tricky instructions. */ - -int -tsrc_operand (rtx op, enum machine_mode mode) -{ - if (mode == VOIDmode) - mode = GET_MODE (op); - - if (mode != QImode && mode != Pmode) - fatal_insn ("mode not QImode", op); - - if (GET_CODE (op) == CONST_INT) - return c4x_L_constant (op) || c4x_N_constant (op) || c4x_J_constant (op); - - return src_operand (op, mode); -} - - -/* Check src operand of two operand non immediate instructions. */ - -int -nonimmediate_src_operand (rtx op, enum machine_mode mode) -{ - if (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE) - return 0; - - return src_operand (op, mode); -} - - -/* Check logical src operand of two operand non immediate instructions. */ - -int -nonimmediate_lsrc_operand (rtx op, enum machine_mode mode) -{ - if (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE) - return 0; - - return lsrc_operand (op, mode); -} - - -int -reg_or_const_operand (rtx op, enum machine_mode mode) -{ - return reg_operand (op, mode) || const_operand (op, mode); -} - - -/* Check for indirect operands allowable in parallel instruction. */ - -int -par_ind_operand (rtx op, enum machine_mode mode) -{ - if (mode != VOIDmode && mode != GET_MODE (op)) - return 0; - - return c4x_S_indirect (op); -} - - -/* Check for operands allowable in parallel instruction. */ - -int -parallel_operand (rtx op, enum machine_mode mode) -{ - return ext_low_reg_operand (op, mode) || par_ind_operand (op, mode); -} - - static void c4x_S_address_parse (rtx op, int *base, int *incdec, int *index, int *disp) { diff --git a/gcc/config/c4x/c4x.h b/gcc/config/c4x/c4x.h index 895a34b..e36fe43 100644 --- a/gcc/config/c4x/c4x.h +++ b/gcc/config/c4x/c4x.h @@ -1667,41 +1667,6 @@ if (final_sequence != NULL_RTX) \ #define ASM_OUTPUT_ASM(FILE, STRING) fprintf (FILE, "%s\n", STRING) -/* Define the codes that are matched by predicates in c4x.c. */ - -#define PREDICATE_CODES \ - {"fp_zero_operand", {CONST_DOUBLE}}, \ - {"const_operand", {CONST_INT, CONST_DOUBLE}}, \ - {"stik_const_operand", {CONST_INT}}, \ - {"not_const_operand", {CONST_INT}}, \ - {"reg_operand", {REG, SUBREG}}, \ - {"reg_or_const_operand", {REG, SUBREG, CONST_INT, CONST_DOUBLE}},\ - {"r0r1_reg_operand", {REG, SUBREG}}, \ - {"r2r3_reg_operand", {REG, SUBREG}}, \ - {"ext_low_reg_operand", {REG, SUBREG}}, \ - {"ext_reg_operand", {REG, SUBREG}}, \ - {"std_reg_operand", {REG, SUBREG}}, \ - {"std_or_reg_operand", {REG, SUBREG}}, \ - {"addr_reg_operand", {REG, SUBREG}}, \ - {"index_reg_operand", {REG, SUBREG}}, \ - {"dp_reg_operand", {REG}}, \ - {"sp_reg_operand", {REG}}, \ - {"st_reg_operand", {REG}}, \ - {"rc_reg_operand", {REG}}, \ - {"call_address_operand", {REG, SYMBOL_REF, LABEL_REF, CONST}}, \ - {"dst_operand", {SUBREG, REG, MEM}}, \ - {"src_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE}}, \ - {"src_hi_operand", {SUBREG, REG, MEM, CONST_DOUBLE}}, \ - {"lsrc_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE}}, \ - {"tsrc_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE}}, \ - {"nonimmediate_src_operand", {SUBREG, REG, MEM}}, \ - {"nonimmediate_lsrc_operand", {SUBREG, REG, MEM}}, \ - {"any_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE}}, \ - {"par_ind_operand", {MEM}}, \ - {"parallel_operand", {SUBREG, REG, MEM}}, \ - {"symbolic_address_operand", {SYMBOL_REF, LABEL_REF, CONST}}, - - /* Define the intrinsic functions for the c3x/c4x. */ enum c4x_builtins diff --git a/gcc/config/c4x/c4x.md b/gcc/config/c4x/c4x.md index f0eb202..f37a49b 100644 --- a/gcc/config/c4x/c4x.md +++ b/gcc/config/c4x/c4x.md @@ -1,6 +1,6 @@ ;; Machine description for the TMS320C[34]x for GCC ;; Copyright (C) 1994, 1995, 1996, 1997, 1998, -;; 1999, 2000, 2002, 2004 Free Software Foundation, Inc. +;; 1999, 2000, 2002, 2004, 2005 Free Software Foundation, Inc. ;; Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz) ;; and Herman Ten Brugge (Haj.Ten.Brugge@net.HCC.nl) @@ -907,6 +907,7 @@ (const_int 1) (const_int 0))] (const_int 0))) +(include "predicates.md") ; ; C4x INSN PATTERNS: diff --git a/gcc/config/c4x/predicates.md b/gcc/config/c4x/predicates.md new file mode 100644 index 0000000..b36e349 --- /dev/null +++ b/gcc/config/c4x/predicates.md @@ -0,0 +1,404 @@ +;; Predicate definitions for TMS320C[34]x. +;; 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. + +;; Nonzero if OP is a floating point value with value 0.0. + +(define_predicate "fp_zero_operand" + (match_code "const_double") +{ + REAL_VALUE_TYPE r; + + if (GET_CODE (op) != CONST_DOUBLE) + return 0; + REAL_VALUE_FROM_CONST_DOUBLE (r, op); + return REAL_VALUES_EQUAL (r, dconst0); +}) + +;; TODO: Add a comment here. + +(define_predicate "const_operand" + (match_code "const_int,const_double") +{ + switch (mode) + { + case QFmode: + case HFmode: + if (GET_CODE (op) != CONST_DOUBLE + || GET_MODE (op) != mode + || GET_MODE_CLASS (mode) != MODE_FLOAT) + return 0; + + return c4x_immed_float_p (op); + +#if Pmode != QImode + case Pmode: +#endif + case QImode: + if (GET_CODE (op) != CONST_INT + || (GET_MODE (op) != VOIDmode && GET_MODE (op) != mode) + || GET_MODE_CLASS (mode) != MODE_INT) + return 0; + + return IS_HIGH_CONST (INTVAL (op)) || IS_INT16_CONST (INTVAL (op)); + + case HImode: + return 0; + + default: + return 0; + } +}) + +;; TODO: Add a comment here. + +(define_predicate "stik_const_operand" + (match_code "const_int") +{ + return c4x_K_constant (op); +}) + +;; TODO: Add a comment here. + +(define_predicate "not_const_operand" + (match_code "const_int") +{ + return c4x_N_constant (op); +}) + +;; TODO: Add a comment here. + +(define_predicate "reg_operand" + (match_code "reg,subreg") +{ + if (GET_CODE (op) == SUBREG + && GET_MODE (op) == QFmode) + return 0; + return register_operand (op, mode); +}) + +;; TODO: Add a comment here. + +(define_predicate "reg_or_const_operand" + (match_code "reg,subreg,const_int,const_double") +{ + return reg_operand (op, mode) || const_operand (op, mode); +}) + +;; Extended precision register R0-R1. + +(define_predicate "r0r1_reg_operand" + (match_code "reg,subreg") +{ + if (! reg_operand (op, mode)) + return 0; + if (GET_CODE (op) == SUBREG) + op = SUBREG_REG (op); + return REG_P (op) && IS_R0R1_OR_PSEUDO_REG (op); +}) + +;; Extended precision register R2-R3. + +(define_predicate "r2r3_reg_operand" + (match_code "reg,subreg") +{ + if (! reg_operand (op, mode)) + return 0; + if (GET_CODE (op) == SUBREG) + op = SUBREG_REG (op); + return REG_P (op) && IS_R2R3_OR_PSEUDO_REG (op); +}) + +;; Low extended precision register R0-R7. + +(define_predicate "ext_low_reg_operand" + (match_code "reg,subreg") +{ + if (! reg_operand (op, mode)) + return 0; + if (GET_CODE (op) == SUBREG) + op = SUBREG_REG (op); + return REG_P (op) && IS_EXT_LOW_OR_PSEUDO_REG (op); +}) + +;; Extended precision register. + +(define_predicate "ext_reg_operand" + (match_code "reg,subreg") +{ + if (! reg_operand (op, mode)) + return 0; + if (GET_CODE (op) == SUBREG) + op = SUBREG_REG (op); + if (! REG_P (op)) + return 0; + return IS_EXT_OR_PSEUDO_REG (op); +}) + +;; Standard precision register. + +(define_predicate "std_reg_operand" + (match_code "reg,subreg") +{ + if (! reg_operand (op, mode)) + return 0; + if (GET_CODE (op) == SUBREG) + op = SUBREG_REG (op); + return REG_P (op) && IS_STD_OR_PSEUDO_REG (op); +}) + +;; Standard precision or normal register. + +(define_predicate "std_or_reg_operand" + (match_code "reg,subreg") +{ + if (reload_in_progress) + return std_reg_operand (op, mode); + return reg_operand (op, mode); +}) + +;; Address register. + +(define_predicate "addr_reg_operand" + (match_code "reg,subreg") +{ + if (! reg_operand (op, mode)) + return 0; + return c4x_a_register (op); +}) + +;; Index register. + +(define_predicate "index_reg_operand" + (match_code "reg,subreg") +{ + if (! reg_operand (op, mode)) + return 0; + if (GET_CODE (op) == SUBREG) + op = SUBREG_REG (op); + return c4x_x_register (op); +}) + +;; DP register. + +(define_predicate "dp_reg_operand" + (match_code "reg") +{ + return REG_P (op) && IS_DP_OR_PSEUDO_REG (op); +}) + +;; SP register. + +(define_predicate "sp_reg_operand" + (match_code "reg") +{ + return REG_P (op) && IS_SP_OR_PSEUDO_REG (op); +}) + +;; ST register. + +(define_predicate "st_reg_operand" + (match_code "reg") +{ + return REG_P (op) && IS_ST_OR_PSEUDO_REG (op); +}) + +;; RC register. + +(define_predicate "rc_reg_operand" + (match_code "reg") +{ + return REG_P (op) && IS_RC_OR_PSEUDO_REG (op); +}) + +;; TODO: Add a comment here. + +(define_predicate "call_address_operand" + (match_code "reg,symbol_ref,label_ref,const") +{ + return (REG_P (op) || symbolic_address_operand (op, mode)); +}) + +;; Check dst operand of a move instruction. + +(define_predicate "dst_operand" + (match_code "subreg,reg,mem") +{ + if (GET_CODE (op) == SUBREG + && mixed_subreg_operand (op, mode)) + return 0; + + if (REG_P (op)) + return reg_operand (op, mode); + + return nonimmediate_operand (op, mode); +}) + +;; Check src operand of two operand arithmetic instructions. + +(define_predicate "src_operand" + (match_code "subreg,reg,mem,const_int,const_double") +{ + if (GET_CODE (op) == SUBREG + && mixed_subreg_operand (op, mode)) + return 0; + + if (REG_P (op)) + return reg_operand (op, mode); + + if (mode == VOIDmode) + mode = GET_MODE (op); + + if (GET_CODE (op) == CONST_INT) + return (mode == QImode || mode == Pmode || mode == HImode) + && c4x_I_constant (op); + + /* We don't like CONST_DOUBLE integers. */ + if (GET_CODE (op) == CONST_DOUBLE) + return c4x_H_constant (op); + + /* Disallow symbolic addresses. Only the predicate + symbolic_address_operand will match these. */ + if (GET_CODE (op) == SYMBOL_REF + || GET_CODE (op) == LABEL_REF + || GET_CODE (op) == CONST) + return 0; + + /* If TARGET_LOAD_DIRECT_MEMS is nonzero, disallow direct memory + access to symbolic addresses. These operands will get forced + into a register and the movqi expander will generate a + HIGH/LO_SUM pair if TARGET_EXPOSE_LDP is nonzero. */ + if (GET_CODE (op) == MEM + && ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF + || GET_CODE (XEXP (op, 0)) == LABEL_REF + || GET_CODE (XEXP (op, 0)) == CONST))) + return !TARGET_EXPOSE_LDP && + ! TARGET_LOAD_DIRECT_MEMS && GET_MODE (op) == mode; + + return general_operand (op, mode); +}) + +;; TODO: Add a comment here. + +(define_predicate "src_hi_operand" + (match_code "subreg,reg,mem,const_double") +{ + if (c4x_O_constant (op)) + return 1; + return src_operand (op, mode); +}) + +;; Check src operand of two operand logical instructions. + +(define_predicate "lsrc_operand" + (match_code "subreg,reg,mem,const_int,const_double") +{ + if (mode == VOIDmode) + mode = GET_MODE (op); + + if (mode != QImode && mode != Pmode) + fatal_insn ("mode not QImode", op); + + if (GET_CODE (op) == CONST_INT) + return c4x_L_constant (op) || c4x_J_constant (op); + + return src_operand (op, mode); +}) + +;; Check src operand of two operand tricky instructions. + +(define_predicate "tsrc_operand" + (match_code "subreg,reg,mem,const_int,const_double") +{ + if (mode == VOIDmode) + mode = GET_MODE (op); + + if (mode != QImode && mode != Pmode) + fatal_insn ("mode not QImode", op); + + if (GET_CODE (op) == CONST_INT) + return c4x_L_constant (op) || c4x_N_constant (op) || c4x_J_constant (op); + + return src_operand (op, mode); +}) + +;; Check src operand of two operand non immediate instructions. + +(define_predicate "nonimmediate_src_operand" + (match_code "subreg,reg,mem") +{ + if (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE) + return 0; + + return src_operand (op, mode); +}) + +;; Check logical src operand of two operand non immediate instructions. + +(define_predicate "nonimmediate_lsrc_operand" + (match_code "subreg,reg,mem") +{ + if (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE) + return 0; + + return lsrc_operand (op, mode); +}) + +;; Match any operand. + +(define_predicate "any_operand" + (match_code "subreg,reg,mem,const_int,const_double") +{ + return 1; +}) + +;; Check for indirect operands allowable in parallel instruction. + +(define_predicate "par_ind_operand" + (match_code "mem") +{ + if (mode != VOIDmode && mode != GET_MODE (op)) + return 0; + + return c4x_S_indirect (op); +}) + +;; Check for operands allowable in parallel instruction. + +(define_predicate "parallel_operand" + (match_code "subreg,reg,mem") +{ + return ext_low_reg_operand (op, mode) || par_ind_operand (op, mode); +}) + +;; Symbolic address operand. + +(define_predicate "symbolic_address_operand" + (match_code "symbol_ref,label_ref,const") +{ + switch (GET_CODE (op)) + { + case CONST: + case SYMBOL_REF: + case LABEL_REF: + return 1; + default: + return 0; + } +}) |