1 ;; Predicate definitions for Motorola 68HC11 and 68HC12.
2 ;; Copyright (C) 2005 Free Software Foundation, Inc.
4 ;; This file is part of GCC.
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)
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, 51 Franklin Street, Fifth Floor,
19 ;; Boston, MA 02110-1301, USA.
21 ;; TODO: Add a comment here.
23 (define_predicate "stack_register_operand"
24 (match_code "subreg,reg")
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)
37 if (GET_CODE (op) == SUBREG)
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)
54 if (GET_CODE (op) == SUBREG)
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)
71 if (GET_CODE (op) == SUBREG)
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"
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)
143 if (push_operand (op, mode) == 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)
156 if (push_operand (op, mode) == 1)
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)
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)
175 rtx op0 = XEXP (op, 0);
178 if (symbolic_memory_operand (op0, mode))
181 if (IS_STACK_PUSH (op))
184 if (GET_CODE (op) == REG && reload_in_progress
185 && REGNO (op) >= FIRST_PSEUDO_REGISTER
186 && reg_equiv_memory_loc[REGNO (op)])
188 op = reg_equiv_memory_loc[REGNO (op)];
189 op = eliminate_regs (op, 0, NULL_RTX);
191 if (GET_CODE (op) != MEM)
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);
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)
210 rtx addr = XEXP (op, 0);
211 if (m68hc11_auto_inc_p (addr))
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)
224 rtx addr = XEXP (op, 0);
225 if (m68hc11_auto_inc_p (addr))
228 return general_operand (op, mode);