Merge reload-branch up to revision 101000
[official-gcc.git] / gcc / config / m68hc11 / predicates.md
blob49e3edd4582d33aeaf872db243d5a68915294650
1 ;; Predicate definitions for Motorola 68HC11 and 68HC12.
2 ;; Copyright (C) 2005 Free Software Foundation, Inc.
3 ;;
4 ;; This file is part of GCC.
5 ;;
6 ;; GCC is free software; you can redistribute it and/or modify
7 ;; it under the terms of the GNU General Public License as published by
8 ;; the Free Software Foundation; either version 2, or (at your option)
9 ;; any later version.
11 ;; GCC is distributed in the hope that it will be useful,
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 ;; GNU General Public License for more details.
16 ;; You should have received a copy of the GNU General Public License
17 ;; along with GCC; see the file COPYING.  If not, write to
18 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
19 ;; Boston, MA 02111-1307, USA.
21 ;; TODO: Add a comment here.
23 (define_predicate "stack_register_operand"
24   (match_code "subreg,reg")
26   return SP_REG_P (op);
29 ;; TODO: Add a comment here.
31 (define_predicate "d_register_operand"
32   (match_code "subreg,reg")
34   if (GET_MODE (op) != mode && mode != VOIDmode)
35     return 0;
37   if (GET_CODE (op) == SUBREG)
38     op = XEXP (op, 0);
40   return GET_CODE (op) == REG
41     && (REGNO (op) >= FIRST_PSEUDO_REGISTER
42         || REGNO (op) == HARD_D_REGNUM
43         || (mode == QImode && REGNO (op) == HARD_B_REGNUM));
46 ;; TODO: Add a comment here.
48 (define_predicate "hard_addr_reg_operand"
49   (match_code "subreg,reg")
51   if (GET_MODE (op) != mode && mode != VOIDmode)
52     return 0;
54   if (GET_CODE (op) == SUBREG)
55     op = XEXP (op, 0);
57   return GET_CODE (op) == REG
58     && (REGNO (op) == HARD_X_REGNUM
59         || REGNO (op) == HARD_Y_REGNUM
60         || REGNO (op) == HARD_Z_REGNUM);
63 ;; TODO: Add a comment here.
65 (define_predicate "hard_reg_operand"
66   (match_code "subreg,reg")
68   if (GET_MODE (op) != mode && mode != VOIDmode)
69     return 0;
71   if (GET_CODE (op) == SUBREG)
72     op = XEXP (op, 0);
74   return GET_CODE (op) == REG
75     && (REGNO (op) >= FIRST_PSEUDO_REGISTER
76         || H_REGNO_P (REGNO (op)));
79 ;; TODO: Add a comment here.
81 (define_predicate "m68hc11_logical_operator"
82   (match_code "and,ior,xor")
84   return GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR;
87 ;; TODO: Add a comment here.
89 (define_predicate "m68hc11_arith_operator"
90   (match_code "and,ior,xor,plus,minus,ashift,ashiftrt,lshiftrt,rotate,rotatert")
92   return GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR
93     || GET_CODE (op) == PLUS || GET_CODE (op) == MINUS
94     || GET_CODE (op) == ASHIFT || GET_CODE (op) == ASHIFTRT
95     || GET_CODE (op) == LSHIFTRT || GET_CODE (op) == ROTATE
96     || GET_CODE (op) == ROTATERT;
99 ;; TODO: Add a comment here.
101 (define_predicate "m68hc11_non_shift_operator"
102   (match_code "and,ior,xor,plus,minus")
104   return GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR
105     || GET_CODE (op) == PLUS || GET_CODE (op) == MINUS;
108 ;; TODO: Add a comment here.
110 (define_predicate "m68hc11_unary_operator"
111   (match_code "neg,not,sign_extend,zero_extend")
113   return GET_CODE (op) == NEG || GET_CODE (op) == NOT
114     || GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND;
117 ;; Return true if op is a shift operator.
119 (define_predicate "m68hc11_shift_operator"
120   (match_code "ashift,ashiftrt,lshiftrt,rotate,rotatert")
122   return GET_CODE (op) == ROTATE || GET_CODE (op) == ROTATERT
123     || GET_CODE (op) == LSHIFTRT || GET_CODE (op) == ASHIFT
124     || GET_CODE (op) == ASHIFTRT;
127 ;; TODO: Add a comment here.
129 (define_predicate "m68hc11_eq_compare_operator"
130   (match_code "eq,ne")
132   return GET_CODE (op) == EQ || GET_CODE (op) == NE;
135 ;; TODO: Add a comment here.
137 (define_predicate "non_push_operand"
138   (match_code "subreg,reg,mem")
140   if (general_operand (op, mode) == 0)
141     return 0;
143   if (push_operand (op, mode) == 1)
144     return 0;
145   return 1;
148 ;; TODO: Add a comment here.
150 (define_predicate "splitable_operand"
151   (match_code "subreg,reg,mem,symbol_ref,label_ref,const_int,const_double")
153   if (general_operand (op, mode) == 0)
154     return 0;
156   if (push_operand (op, mode) == 1)
157     return 0;
159   /* Reject a (MEM (MEM X)) because the patterns that use non_push_operand
160      need to split such addresses to access the low and high part but it
161      is not possible to express a valid address for the low part.  */
162   if (mode != QImode && GET_CODE (op) == MEM
163       && GET_CODE (XEXP (op, 0)) == MEM)
164     return 0;
165   return 1;
168 ;; TODO: Add a comment here.
170 (define_predicate "reg_or_some_mem_operand"
171   (match_code "subreg,reg,mem")
173   if (GET_CODE (op) == MEM)
174     {
175       rtx op0 = XEXP (op, 0);
176       int addr_mode;
178       if (symbolic_memory_operand (op0, mode))
179         return 1;
181       if (IS_STACK_PUSH (op))
182         return 1;
184       if (GET_CODE (op) == REG && reload_in_progress
185           && REGNO (op) >= FIRST_PSEUDO_REGISTER
186           && reg_equiv_memory_loc[REGNO (op)])
187          {
188             op = reg_equiv_memory_loc[REGNO (op)];
189             op = eliminate_regs (op, 0, NULL_RTX);
190          }
191       if (GET_CODE (op) != MEM)
192          return 0;
194       op0 = XEXP (op, 0);
195       addr_mode = m68hc11_addr_mode | (reload_completed ? ADDR_STRICT : 0);
196       addr_mode &= ~ADDR_INDIRECT;
197       return m68hc11_valid_addressing_p (op0, mode, addr_mode);
198     }
200   return register_operand (op, mode);
203 ;; TODO: Add a comment here.
205 (define_predicate "tst_operand"
206   (match_code "subreg,reg,mem")
208   if (GET_CODE (op) == MEM && reload_completed == 0)
209     {
210       rtx addr = XEXP (op, 0);
211       if (m68hc11_auto_inc_p (addr))
212         return 0;
213     }
214   return nonimmediate_operand (op, mode);
217 ;; TODO: Add a comment here.
219 (define_predicate "cmp_operand"
220   (match_code "subreg,reg,mem,symbol_ref,label_ref,const_int,const_double")
222   if (GET_CODE (op) == MEM)
223     {
224       rtx addr = XEXP (op, 0);
225       if (m68hc11_auto_inc_p (addr))
226         return 0;
227     }
228   return general_operand (op, mode);