X-Git-Url: https://oss.titaniummirror.com/gitweb?a=blobdiff_plain;f=gcc%2Fconfig%2Fstormy16%2Fpredicates.md;fp=gcc%2Fconfig%2Fstormy16%2Fpredicates.md;h=0e1d39431f718992a4abb531981f68cbad434a61;hb=6fed43773c9b0ce596dca5686f37ac3fc0fa11c0;hp=0000000000000000000000000000000000000000;hpb=27b11d56b743098deb193d510b337ba22dc52e5c;p=msp430-gcc.git diff --git a/gcc/config/stormy16/predicates.md b/gcc/config/stormy16/predicates.md new file mode 100644 index 00000000..0e1d3943 --- /dev/null +++ b/gcc/config/stormy16/predicates.md @@ -0,0 +1,178 @@ +;; Predicate definitions for XSTORMY16. +;; Copyright (C) 2005, 2007, 2008 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 3, 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 COPYING3. If not see +;; . + +;; Return 1 if OP is a shift operator. + +(define_predicate "shift_operator" + (match_code "ashift,ashiftrt,lshiftrt") +{ + enum rtx_code code = GET_CODE (op); + + return (code == ASHIFT + || code == ASHIFTRT + || code == LSHIFTRT); +}) + +;; Return 1 if this is an EQ or NE operator. + +(define_predicate "equality_operator" + (match_code "eq,ne") +{ + return ((mode == VOIDmode || GET_MODE (op) == mode) + && (GET_CODE (op) == EQ || GET_CODE (op) == NE)); +}) + +;; Return 1 if this is a comparison operator but not an EQ or NE +;; operator. + +(define_predicate "inequality_operator" + (match_code "ge,gt,le,lt,geu,gtu,leu,ltu") +{ + return comparison_operator (op, mode) && ! equality_operator (op, mode); +}) + +;; Return 1 if this is a LT, GE, LTU, or GEU operator. + +(define_predicate "xstormy16_ineqsi_operator" + (match_code "lt,ge,ltu,geu") +{ + enum rtx_code code = GET_CODE (op); + + return ((mode == VOIDmode || GET_MODE (op) == mode) + && (code == LT || code == GE || code == LTU || code == GEU)); +}) + +;; Predicate for MEMs that can use special 8-bit addressing. + +(define_predicate "xstormy16_below100_operand" + (match_code "mem") +{ + if (GET_MODE (op) != mode) + return 0; + if (GET_CODE (op) == MEM) + op = XEXP (op, 0); + else if (GET_CODE (op) == SUBREG + && GET_CODE (XEXP (op, 0)) == MEM + && !MEM_VOLATILE_P (XEXP (op, 0))) + op = XEXP (XEXP (op, 0), 0); + else + return 0; + if (GET_CODE (op) == CONST_INT) + { + HOST_WIDE_INT i = INTVAL (op); + return (i >= 0x7f00 && i < 0x7fff); + } + return xstormy16_below100_symbol (op, HImode); +}) + +;; TODO: Add a comment here. + +(define_predicate "xstormy16_below100_or_register" + (match_code "mem,reg,subreg") +{ + return (xstormy16_below100_operand (op, mode) + || register_operand (op, mode)); +}) + +;; TODO: Add a comment here. + +(define_predicate "xstormy16_splittable_below100_or_register" + (match_code "mem,reg,subreg") +{ + if (GET_CODE (op) == MEM && MEM_VOLATILE_P (op)) + return 0; + return (xstormy16_below100_operand (op, mode) + || register_operand (op, mode)); +}) + +;; Predicate for constants with exactly one bit not set. + +(define_predicate "xstormy16_onebit_clr_operand" + (match_code "const_int") +{ + HOST_WIDE_INT i; + if (GET_CODE (op) != CONST_INT) + return 0; + i = ~ INTVAL (op); + if (mode == QImode) + i &= 0xff; + if (mode == HImode) + i &= 0xffff; + return exact_log2 (i) != -1; +}) + +;; Predicate for constants with exactly one bit set. + +(define_predicate "xstormy16_onebit_set_operand" + (match_code "const_int") +{ + HOST_WIDE_INT i; + if (GET_CODE (op) != CONST_INT) + return 0; + i = INTVAL (op); + if (mode == QImode) + i &= 0xff; + if (mode == HImode) + i &= 0xffff; + return exact_log2 (i) != -1; +}) + +;; TODO: Add a comment here. + +(define_predicate "nonimmediate_nonstack_operand" + (match_code "reg,mem,subreg") +{ + /* 'Q' is for pushes, 'R' for pops. */ + return (nonimmediate_operand (op, mode) + && ! xstormy16_extra_constraint_p (op, 'Q') + && ! xstormy16_extra_constraint_p (op, 'R')); +}) + +(define_predicate "xstormy16_carry_plus_operand" + (match_code "plus") +{ + return (GET_CODE (XEXP (op, 1)) == CONST_INT + && (INTVAL (XEXP (op, 1)) < -4 || INTVAL (XEXP (op, 1)) > 4)); +}) + +(define_predicate "xs_hi_general_operand" + (match_code "const_int,reg,subreg,mem,symbol_ref,label_ref,const") +{ + if ((GET_CODE (op) == CONST_INT) + && ((INTVAL (op) >= 32768) || (INTVAL (op) < -32768))) + { + error ("constant halfword load operand out of range"); + return false; + } + + return general_operand (op, mode); +}) + +(define_predicate "xs_hi_nonmemory_operand" + (match_code "const_int,reg,subreg,const") +{ + if ((GET_CODE (op) == CONST_INT) + && ((INTVAL (op) >= 32768) || (INTVAL (op) < -32768))) + { + error ("constant arithmetic operand out of range"); + return false; + } + + return nonmemory_operand (op, mode); +})