]>
Commit | Line | Data |
---|---|---|
41b6a5e2 | 1 | ;; Predicate definitions for Motorola 68000. |
2f83c7d6 | 2 | ;; Copyright (C) 2005, 2007 Free Software Foundation, Inc. |
41b6a5e2 KH |
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 | |
2f83c7d6 | 8 | ;; the Free Software Foundation; either version 3, or (at your option) |
41b6a5e2 KH |
9 | ;; any later version. |
10 | ;; | |
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. | |
15 | ;; | |
16 | ;; You should have received a copy of the GNU General Public License | |
2f83c7d6 NC |
17 | ;; along with GCC; see the file COPYING3. If not see |
18 | ;; <http://www.gnu.org/licenses/>. | |
41b6a5e2 KH |
19 | |
20 | ;; Special case of a general operand that's used as a source | |
21 | ;; operand. Use this to permit reads from PC-relative memory when | |
22 | ;; -mpcrel is specified. | |
23 | ||
24 | (define_predicate "general_src_operand" | |
25 | (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,mem") | |
26 | { | |
27 | if (TARGET_PCREL | |
28 | && GET_CODE (op) == MEM | |
29 | && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF | |
30 | || GET_CODE (XEXP (op, 0)) == LABEL_REF | |
31 | || GET_CODE (XEXP (op, 0)) == CONST)) | |
32 | return 1; | |
33 | return general_operand (op, mode); | |
34 | }) | |
35 | ||
36 | ;; Special case of a nonimmediate operand that's used as a source. Use | |
37 | ;; this to permit reads from PC-relative memory when -mpcrel is | |
38 | ;; specified. | |
39 | ||
40 | (define_predicate "nonimmediate_src_operand" | |
41 | (match_code "subreg,reg,mem") | |
42 | { | |
43 | if (TARGET_PCREL && GET_CODE (op) == MEM | |
44 | && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF | |
45 | || GET_CODE (XEXP (op, 0)) == LABEL_REF | |
46 | || GET_CODE (XEXP (op, 0)) == CONST)) | |
47 | return 1; | |
48 | return nonimmediate_operand (op, mode); | |
49 | }) | |
50 | ||
51 | ;; Special case of a memory operand that's used as a source. Use this | |
52 | ;; to permit reads from PC-relative memory when -mpcrel is specified. | |
53 | ||
54 | (define_predicate "memory_src_operand" | |
55 | (match_code "subreg,mem") | |
56 | { | |
57 | if (TARGET_PCREL && GET_CODE (op) == MEM | |
58 | && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF | |
59 | || GET_CODE (XEXP (op, 0)) == LABEL_REF | |
60 | || GET_CODE (XEXP (op, 0)) == CONST)) | |
61 | return 1; | |
62 | return memory_operand (op, mode); | |
63 | }) | |
64 | ||
65 | ;; Similar to general_operand, but exclude stack_pointer_rtx. | |
66 | ||
67 | (define_predicate "not_sp_operand" | |
68 | (match_code "subreg,reg,mem") | |
69 | { | |
70 | return op != stack_pointer_rtx && nonimmediate_operand (op, mode); | |
71 | }) | |
72 | ||
73 | ;; Predicate that accepts only a pc-relative address. This is needed | |
74 | ;; because pc-relative addresses don't satisfy the predicate | |
75 | ;; "general_src_operand". | |
76 | ||
77 | (define_predicate "pcrel_address" | |
4fbe09f9 | 78 | (match_code "symbol_ref,label_ref,const")) |
41b6a5e2 KH |
79 | |
80 | ;; Accept integer operands in the range 0..0xffffffff. We have to | |
81 | ;; check the range carefully since this predicate is used in DImode | |
82 | ;; contexts. Also, we need some extra crud to make it work when | |
83 | ;; hosted on 64-bit machines. | |
84 | ||
85 | (define_predicate "const_uint32_operand" | |
86 | (match_code "const_int,const_double") | |
87 | { | |
88 | /* It doesn't make sense to ask this question with a mode that is | |
89 | not larger than 32 bits. */ | |
4fbe09f9 | 90 | gcc_assert (GET_MODE_BITSIZE (mode) > 32); |
41b6a5e2 KH |
91 | |
92 | #if HOST_BITS_PER_WIDE_INT > 32 | |
93 | /* All allowed constants will fit a CONST_INT. */ | |
94 | return (GET_CODE (op) == CONST_INT | |
95 | && (INTVAL (op) >= 0 && INTVAL (op) <= 0xffffffffL)); | |
96 | #else | |
97 | return (GET_CODE (op) == CONST_INT | |
98 | || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0)); | |
99 | #endif | |
100 | }) | |
101 | ||
102 | ;; Accept integer operands in the range -0x80000000..0x7fffffff. We | |
103 | ;; have to check the range carefully since this predicate is used in | |
104 | ;; DImode contexts. | |
105 | ||
106 | (define_predicate "const_sint32_operand" | |
107 | (match_code "const_int") | |
108 | { | |
109 | /* It doesn't make sense to ask this question with a mode that is | |
110 | not larger than 32 bits. */ | |
4fbe09f9 | 111 | gcc_assert (GET_MODE_BITSIZE (mode) > 32); |
41b6a5e2 KH |
112 | |
113 | /* All allowed constants will fit a CONST_INT. */ | |
114 | return (GET_CODE (op) == CONST_INT | |
115 | && (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff)); | |
116 | }) | |
117 | ||
118 | ;; Return true if X is a valid comparison operator for the dbcc | |
119 | ;; instruction. Note it rejects floating point comparison | |
120 | ;; operators. (In the future we could use Fdbcc). It also rejects | |
121 | ;; some comparisons when CC_NO_OVERFLOW is set. | |
122 | ||
123 | (define_predicate "valid_dbcc_comparison_p" | |
4fbe09f9 KH |
124 | (and (match_code "eq,ne,gtu,ltu,geu,leu,gt,lt,ge,le") |
125 | (match_test "valid_dbcc_comparison_p_2 (op, mode)"))) | |
41b6a5e2 KH |
126 | |
127 | ;; Check for sign_extend or zero_extend. Used for bit-count operands. | |
128 | ||
129 | (define_predicate "extend_operator" | |
4fbe09f9 | 130 | (match_code "sign_extend,zero_extend")) |
41b6a5e2 KH |
131 | |
132 | ;; Returns true if OP is either a symbol reference or a sum of a | |
133 | ;; symbol reference and a constant. | |
134 | ||
135 | (define_predicate "symbolic_operand" | |
136 | (match_code "symbol_ref,label_ref,const") | |
137 | { | |
138 | switch (GET_CODE (op)) | |
139 | { | |
140 | case SYMBOL_REF: | |
141 | case LABEL_REF: | |
142 | return true; | |
143 | ||
144 | case CONST: | |
145 | op = XEXP (op, 0); | |
146 | return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF | |
147 | || GET_CODE (XEXP (op, 0)) == LABEL_REF) | |
148 | && GET_CODE (XEXP (op, 1)) == CONST_INT); | |
149 | ||
150 | #if 0 /* Deleted, with corresponding change in m68k.h, | |
151 | so as to fit the specs. No CONST_DOUBLE is ever symbolic. */ | |
152 | case CONST_DOUBLE: | |
153 | return GET_MODE (op) == mode; | |
154 | #endif | |
155 | ||
156 | default: | |
157 | return false; | |
158 | } | |
159 | }) | |
160 | ||
4e2b26aa | 161 | ;; A constant that can be used the address in a call insn |
29ca003a RS |
162 | (define_predicate "const_call_operand" |
163 | (ior (match_operand 0 "const_int_operand") | |
164 | (and (match_test "m68k_symbolic_call != NULL") | |
165 | (match_operand 0 "symbolic_operand")))) | |
166 | ||
167 | ;; An operand that can be used as the address in a call insn. | |
168 | (define_predicate "call_operand" | |
169 | (ior (match_operand 0 "const_call_operand") | |
170 | (match_operand 0 "register_operand"))) | |
171 | ||
4e2b26aa NS |
172 | ;; A constant that can be used the address in a sibcall insn |
173 | (define_predicate "const_sibcall_operand" | |
174 | (ior (match_operand 0 "const_int_operand") | |
175 | (and (match_test "m68k_symbolic_jump != NULL") | |
176 | (match_operand 0 "symbolic_operand")))) | |
177 | ||
f7e70894 RS |
178 | ;; An operand that can be used as the address in a sibcall insn. |
179 | (define_predicate "sibcall_operand" | |
4e2b26aa | 180 | (ior (match_operand 0 "const_sibcall_operand") |
f7e70894 RS |
181 | (and (match_code "reg") |
182 | (match_test "REGNO (op) == STATIC_CHAIN_REGNUM")))) | |
183 | ||
41b6a5e2 KH |
184 | ;; TODO: Add a comment here. |
185 | ||
186 | (define_predicate "post_inc_operand" | |
4fbe09f9 KH |
187 | (and (match_code "mem") |
188 | (match_test "GET_CODE (XEXP (op, 0)) == POST_INC"))) | |
41b6a5e2 KH |
189 | |
190 | ;; TODO: Add a comment here. | |
191 | ||
192 | (define_predicate "pre_dec_operand" | |
4fbe09f9 KH |
193 | (and (match_code "mem") |
194 | (match_test "GET_CODE (XEXP (op, 0)) == PRE_DEC"))) |