testcompare.md revision 1.1 1 1.1 mrg ;; ----------------------------------------------------------------------
2 1.1 mrg ;; TEST INSTRUCTIONS
3 1.1 mrg ;; ----------------------------------------------------------------------
4 1.1 mrg
5 1.1 mrg ;; (define_insn_and_split "*tst_extzv_1_n"
6 1.1 mrg ;; [(set (cc0)
7 1.1 mrg ;; (compare (zero_extract:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>")
8 1.1 mrg ;; (const_int 1)
9 1.1 mrg ;; (match_operand 1 "const_int_operand" "n,n,n"))
10 1.1 mrg ;; (const_int 0)))
11 1.1 mrg ;; (clobber (match_scratch:QI 2 "=X,X,&r"))]
12 1.1 mrg ;; "!CONSTANT_P (operands[0])"
13 1.1 mrg ;; "@
14 1.1 mrg ;; btst\\t%Z1,%Y0
15 1.1 mrg ;; btst\\t%Z1,%Y0
16 1.1 mrg ;; #"
17 1.1 mrg ;; "&& reload_completed
18 1.1 mrg ;; && !satisfies_constraint_U (operands[0])"
19 1.1 mrg ;; [(set (match_dup 2)
20 1.1 mrg ;; (match_dup 0))
21 1.1 mrg ;; (parallel [(set (cc0) (compare (zero_extract:SI (match_dup 2)
22 1.1 mrg ;; (const_int 1)
23 1.1 mrg ;; (match_dup 1))
24 1.1 mrg ;; (const_int 0)))
25 1.1 mrg ;; (clobber (scratch:QI))])]
26 1.1 mrg ;; ""
27 1.1 mrg ;; [(set_attr "length" "2,8,10")])
28 1.1 mrg ;;
29 1.1 mrg (define_insn ""
30 1.1 mrg [(set (reg:CCZ CC_REG)
31 1.1 mrg (eq (zero_extract:HSI (match_operand:HSI 0 "register_operand" "r")
32 1.1 mrg (const_int 1)
33 1.1 mrg (match_operand 1 "const_int_operand" "n"))
34 1.1 mrg (const_int 0)))]
35 1.1 mrg "INTVAL (operands[1]) < 16"
36 1.1 mrg "btst %Z1,%Y0"
37 1.1 mrg [(set_attr "length" "2")])
38 1.1 mrg
39 1.1 mrg (define_insn "*tst<mode>"
40 1.1 mrg [(set (reg:CCZN CC_REG)
41 1.1 mrg (compare:CCZN (match_operand:QHSI 0 "register_operand" "r")
42 1.1 mrg (const_int 0)))]
43 1.1 mrg ""
44 1.1 mrg {
45 1.1 mrg if (<MODE>mode == QImode)
46 1.1 mrg return "mov.b %X0,%X0";
47 1.1 mrg else if (<MODE>mode == HImode)
48 1.1 mrg return "mov.w %T0,%T0";
49 1.1 mrg else if (<MODE>mode == SImode)
50 1.1 mrg return "mov.l %S0,%S0";
51 1.1 mrg gcc_unreachable ();
52 1.1 mrg }
53 1.1 mrg [(set_attr "length" "2")])
54 1.1 mrg
55 1.1 mrg (define_insn "*tsthi_upper"
56 1.1 mrg [(set (reg:CCZN CC_REG)
57 1.1 mrg (compare (and:HI (match_operand:HI 0 "register_operand" "r")
58 1.1 mrg (const_int -256))
59 1.1 mrg (const_int 0)))]
60 1.1 mrg "reload_completed"
61 1.1 mrg "mov.b %t0,%t0"
62 1.1 mrg [(set_attr "length" "2")])
63 1.1 mrg
64 1.1 mrg (define_insn "*tstsi_upper"
65 1.1 mrg [(set (reg:CCZN CC_REG)
66 1.1 mrg (compare (and:SI (match_operand:SI 0 "register_operand" "r")
67 1.1 mrg (const_int -65536))
68 1.1 mrg (const_int 0)))]
69 1.1 mrg "reload_completed"
70 1.1 mrg "mov.w %e0,%e0"
71 1.1 mrg [(set_attr "length" "2")])
72 1.1 mrg
73 1.1 mrg (define_insn "*cmp<mode>_c"
74 1.1 mrg [(set (reg:CCC CC_REG)
75 1.1 mrg (ltu (match_operand:QHSI 0 "h8300_dst_operand" "rQ")
76 1.1 mrg (match_operand:QHSI 1 "h8300_src_operand" "rQi")))]
77 1.1 mrg "reload_completed"
78 1.1 mrg {
79 1.1 mrg if (<MODE>mode == QImode)
80 1.1 mrg return "cmp.b %X1,%X0";
81 1.1 mrg else if (<MODE>mode == HImode)
82 1.1 mrg return "cmp.w %T1,%T0";
83 1.1 mrg else if (<MODE>mode == SImode)
84 1.1 mrg return "cmp.l %S1,%S0";
85 1.1 mrg gcc_unreachable ();
86 1.1 mrg }
87 1.1 mrg [(set_attr "length_table" "add")])
88 1.1 mrg
89 1.1 mrg (define_insn "*cmpqi"
90 1.1 mrg [(set (reg:CC CC_REG)
91 1.1 mrg (compare (match_operand:QI 0 "h8300_dst_operand" "rQ")
92 1.1 mrg (match_operand:QI 1 "h8300_src_operand" "rQi")))]
93 1.1 mrg "reload_completed"
94 1.1 mrg "cmp.b %X1,%X0"
95 1.1 mrg [(set_attr "length_table" "add")])
96 1.1 mrg
97 1.1 mrg (define_insn "*cmphi"
98 1.1 mrg [(set (reg:CC CC_REG)
99 1.1 mrg (compare (match_operand:HI 0 "h8300_dst_operand" "rU,rQ")
100 1.1 mrg (match_operand:HI 1 "h8300_src_operand" "P3>X,rQi")))]
101 1.1 mrg "reload_completed"
102 1.1 mrg {
103 1.1 mrg switch (which_alternative)
104 1.1 mrg {
105 1.1 mrg case 0:
106 1.1 mrg if (!TARGET_H8300SX)
107 1.1 mrg return "cmp.w %T1,%T0";
108 1.1 mrg else
109 1.1 mrg return "cmp.w %T1:3,%T0";
110 1.1 mrg case 1:
111 1.1 mrg return "cmp.w %T1,%T0";
112 1.1 mrg default:
113 1.1 mrg gcc_unreachable ();
114 1.1 mrg }
115 1.1 mrg }
116 1.1 mrg [(set_attr "length_table" "short_immediate,add")])
117 1.1 mrg
118 1.1 mrg (define_insn "cmpsi"
119 1.1 mrg [(set (reg:CC CC_REG)
120 1.1 mrg (compare (match_operand:SI 0 "h8300_dst_operand" "r,rQ")
121 1.1 mrg (match_operand:SI 1 "h8300_src_operand" "P3>X,rQi")))]
122 1.1 mrg "reload_completed"
123 1.1 mrg {
124 1.1 mrg switch (which_alternative)
125 1.1 mrg {
126 1.1 mrg case 0:
127 1.1 mrg if (!TARGET_H8300SX)
128 1.1 mrg return "cmp.l %S1,%S0";
129 1.1 mrg else
130 1.1 mrg return "cmp.l %S1:3,%S0";
131 1.1 mrg case 1:
132 1.1 mrg return "cmp.l %S1,%S0";
133 1.1 mrg default:
134 1.1 mrg gcc_unreachable ();
135 1.1 mrg }
136 1.1 mrg }
137 1.1 mrg [(set_attr "length" "2,*")
138 1.1 mrg (set_attr "length_table" "*,add")])
139 1.1 mrg
140 1.1 mrg ;; Convert a memory comparison to a move if there is a scratch register.
141 1.1 mrg
142 1.1 mrg (define_peephole2
143 1.1 mrg [(match_scratch:QHSI 1 "r")
144 1.1 mrg (set (reg:CC CC_REG)
145 1.1 mrg (compare (match_operand:QHSI 0 "memory_operand" "")
146 1.1 mrg (const_int 0)))]
147 1.1 mrg ""
148 1.1 mrg [(parallel [(set (match_dup 1) (match_dup 0)) (clobber (reg:CC CC_REG))])
149 1.1 mrg (set (reg:CC CC_REG) (compare:CC (match_dup 1) (const_int 0)))])
150 1.1 mrg
151 1.1 mrg ;; The compare-elimination pass does not handle memory reference. So this
152 1.1 mrg ;; little peephole helps fill the gap and avoid code quality regressions.
153 1.1 mrg (define_peephole2
154 1.1 mrg [(parallel [(set (match_operand:QHSI 0 "register_operand" "")
155 1.1 mrg (match_operand:QHSI 1 "simple_memory_operand" ""))
156 1.1 mrg (clobber (reg:CC CC_REG))])
157 1.1 mrg (set (reg:CCZN CC_REG)
158 1.1 mrg (compare:CCZN (match_dup 0) (const_int 0)))]
159 1.1 mrg ""
160 1.1 mrg [(parallel [(set (reg:CCZN CC_REG) (compare:CCZN (match_dup 1) (const_int 0)))
161 1.1 mrg (set (match_dup 0) (match_dup 1))])])
162 1.1 mrg
163 1.1 mrg ;; This exists solely to convince ifcvt to try some store-flag sequences.
164 1.1 mrg ;;
165 1.1 mrg ;; Essentially we don't want to expose a general store-flag capability.
166 1.1 mrg ;; The only generally useful/profitable case is when we want to test the
167 1.1 mrg ;; C bit. In that case we can use addx, subx, bst, or bist to get the bit
168 1.1 mrg ;; into a GPR.
169 1.1 mrg ;;
170 1.1 mrg ;; Others could be handled with stc, shifts and masking, but it likely isn't
171 1.1 mrg ;; profitable.
172 1.1 mrg ;;
173 1.1 mrg (define_expand "cstore<mode>4"
174 1.1 mrg [(use (match_operator 1 "eqne_operator"
175 1.1 mrg [(match_operand:QHSI 2 "h8300_dst_operand" "")
176 1.1 mrg (match_operand:QHSI 3 "h8300_src_operand" "")]))
177 1.1 mrg (clobber (match_operand:QHSI 0 "register_operand"))]
178 1.1 mrg ""
179 1.1 mrg {
180 1.1 mrg FAIL;
181 1.1 mrg })
182 1.1 mrg
183 1.1 mrg ;; Storing the C bit is pretty simple since there are many ways to
184 1.1 mrg ;; introduce it into a GPR. addx, subx and a variety of bit manipulation
185 1.1 mrg ;; instructions
186 1.1 mrg ;;
187 1.1 mrg (define_insn "*store_c_<mode>"
188 1.1 mrg [(set (match_operand:QHSI 0 "register_operand" "=r")
189 1.1 mrg (eqne:QHSI (reg:CCC CC_REG) (const_int 0)))]
190 1.1 mrg "reload_completed"
191 1.1 mrg {
192 1.1 mrg if (<CODE> == NE)
193 1.1 mrg {
194 1.1 mrg if (<MODE>mode == QImode)
195 1.1 mrg return "xor.b\t%X0,%X0\;bst\t#0,%X0";
196 1.1 mrg else if (<MODE>mode == HImode)
197 1.1 mrg return "xor.w\t%T0,%T0\;bst\t#0,%s0";
198 1.1 mrg else if (<MODE>mode == SImode)
199 1.1 mrg return "xor.l\t%S0,%S0\;bst\t#0,%w0";
200 1.1 mrg gcc_unreachable ();
201 1.1 mrg }
202 1.1 mrg else if (<CODE> == EQ)
203 1.1 mrg {
204 1.1 mrg if (<MODE>mode == QImode)
205 1.1 mrg return "xor.b\t%X0,%X0\;bist\t#0,%X0";
206 1.1 mrg else if (<MODE>mode == HImode)
207 1.1 mrg return "xor.w\t%T0,%T0\;bist\t#0,%s0";
208 1.1 mrg else if (<MODE>mode == SImode)
209 1.1 mrg return "xor.l\t%S0,%S0\;bist\t#0,%w0";
210 1.1 mrg gcc_unreachable ();
211 1.1 mrg }
212 1.1 mrg }
213 1.1 mrg [(set (attr "length") (symbol_ref "<MODE>mode == SImode ? 6 : 4"))])
214 1.1 mrg
215 1.1 mrg ;; Similarly, but with a negated result
216 1.1 mrg (define_insn "*store_neg_c_<mode>"
217 1.1 mrg [(set (match_operand:QHSI 0 "register_operand" "=r")
218 1.1 mrg (neg:QHSI (ne:QHSI (reg:CCC CC_REG) (const_int 0))))]
219 1.1 mrg "reload_completed"
220 1.1 mrg {
221 1.1 mrg if (<MODE>mode == QImode)
222 1.1 mrg return "subx\t%X0,%X0";
223 1.1 mrg else if (<MODE>mode == HImode)
224 1.1 mrg return "subx\t%X0,%X0\;exts.w\t%T0";
225 1.1 mrg else if (<MODE>mode == SImode)
226 1.1 mrg return "subx\t%X0,%X0\;exts.w\t%T0\;exts.l\t%S0";
227 1.1 mrg gcc_unreachable ();
228 1.1 mrg }
229 1.1 mrg [(set
230 1.1 mrg (attr "length")
231 1.1 mrg (symbol_ref "(<MODE>mode == SImode ? 6 : <MODE>mode == HImode ? 4 : 2)"))])
232 1.1 mrg
233 1.1 mrg ;; Using b[i]st we can store the C bit into any of the low 16 bits of
234 1.1 mrg ;; a destination. We can also rotate it up into the high bit of a 32 bit
235 1.1 mrg ;; destination.
236 1.1 mrg (define_insn "*store_shifted_c<mode>"
237 1.1 mrg [(set (match_operand:QHSI 0 "register_operand" "=r")
238 1.1 mrg (ashift:QHSI (eqne:QHSI (reg:CCC CC_REG) (const_int 0))
239 1.1 mrg (match_operand 1 "immediate_operand" "n")))]
240 1.1 mrg "(reload_completed
241 1.1 mrg && (INTVAL (operands[1]) == 31 || INTVAL (operands[1]) <= 15))"
242 1.1 mrg {
243 1.1 mrg if (<CODE> == NE)
244 1.1 mrg {
245 1.1 mrg if (<MODE>mode == QImode)
246 1.1 mrg return "xor.b\t%X0,%X0\;bst\t%1,%X0";
247 1.1 mrg else if (<MODE>mode == HImode && INTVAL (operands[1]) < 8)
248 1.1 mrg return "xor.w\t%T0,%T0\;bst\t%1,%X0";
249 1.1 mrg else if (<MODE>mode == HImode)
250 1.1 mrg {
251 1.1 mrg operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
252 1.1 mrg output_asm_insn ("xor.w\t%T0,%T0\;bst\t%1,%t0", operands);
253 1.1 mrg return "";
254 1.1 mrg }
255 1.1 mrg else if (<MODE>mode == SImode && INTVAL (operands[1]) == 31)
256 1.1 mrg return "xor.l\t%S0,%S0\;rotxr.l\t%S0";
257 1.1 mrg else if (<MODE>mode == SImode && INTVAL (operands[1]) < 8)
258 1.1 mrg return "xor.l\t%S0,%S0\;bst\t%1,%X0";
259 1.1 mrg else if (<MODE>mode == SImode)
260 1.1 mrg {
261 1.1 mrg operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
262 1.1 mrg output_asm_insn ("xor.l\t%S0,%S0\;bst\t%1,%t0", operands);
263 1.1 mrg return "";
264 1.1 mrg }
265 1.1 mrg gcc_unreachable ();
266 1.1 mrg }
267 1.1 mrg else if (<CODE> == EQ)
268 1.1 mrg {
269 1.1 mrg if (<MODE>mode == QImode)
270 1.1 mrg return "xor.b\t%X0,%X0\;bist\t%1,%X0";
271 1.1 mrg else if (<MODE>mode == HImode && INTVAL (operands[1]) < 8)
272 1.1 mrg return "xor.w\t%T0,%T0\;bist\t%1,%X0";
273 1.1 mrg else if (<MODE>mode == HImode)
274 1.1 mrg {
275 1.1 mrg operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
276 1.1 mrg output_asm_insn ("xor.w\t%T0,%T0\;bist\t%1,%t0", operands);
277 1.1 mrg return "";
278 1.1 mrg }
279 1.1 mrg else if (<MODE>mode == SImode && INTVAL (operands[1]) == 31)
280 1.1 mrg return "xor.l\t%S0,%S0\;bixor\t#0,%X0\;rotxr.l\t%S0";
281 1.1 mrg else if (<MODE>mode == SImode && INTVAL (operands[1]) < 8)
282 1.1 mrg return "xor.l\t%S0,%S0\;bist\t%1,%X0";
283 1.1 mrg else if (<MODE>mode == SImode)
284 1.1 mrg {
285 1.1 mrg operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
286 1.1 mrg output_asm_insn ("xor.l\t%S0,%S0\;bist\t%1,%t0", operands);
287 1.1 mrg return "";
288 1.1 mrg }
289 1.1 mrg gcc_unreachable ();
290 1.1 mrg }
291 1.1 mrg gcc_unreachable ();
292 1.1 mrg }
293 1.1 mrg [(set
294 1.1 mrg (attr "length")
295 1.1 mrg (symbol_ref "(<MODE>mode == QImode ? 4
296 1.1 mrg : <MODE>mode == HImode ? 4
297 1.1 mrg : <CODE> == NE ? 6
298 1.1 mrg : INTVAL (operands[1]) == 31 ? 8 : 6)"))])
299 1.1 mrg
300 1.1 mrg ;; Recognize this scc and generate code we can match
301 1.1 mrg (define_insn_and_split "*store_c"
302 1.1 mrg [(set (match_operand:QHSI 0 "register_operand" "=r")
303 1.1 mrg (geultu:QHSI (match_operand:QHSI2 1 "register_operand" "r")
304 1.1 mrg (match_operand:QHSI2 2 "register_operand" "r")))]
305 1.1 mrg ""
306 1.1 mrg "#"
307 1.1 mrg "&& reload_completed"
308 1.1 mrg [(set (reg:CCC CC_REG)
309 1.1 mrg (ltu:CCC (match_dup 1) (match_dup 2)))
310 1.1 mrg (set (match_dup 0)
311 1.1 mrg (<geultu_to_c>:QHSI (reg:CCC CC_REG) (const_int 0)))])
312 1.1 mrg
313 1.1 mrg ;; We can fold in negation of the result and generate better code than
314 1.1 mrg ;; what the generic bits would do when testing for C == 1
315 1.1 mrg (define_insn_and_split "*store_neg_c"
316 1.1 mrg [(set (match_operand:QHSI 0 "register_operand" "=r")
317 1.1 mrg (neg:QHSI
318 1.1 mrg (ltu:QHSI (match_operand:QHSI2 1 "register_operand" "r")
319 1.1 mrg (match_operand:QHSI2 2 "register_operand" "r"))))]
320 1.1 mrg ""
321 1.1 mrg "#"
322 1.1 mrg "&& reload_completed"
323 1.1 mrg [(set (reg:CCC CC_REG)
324 1.1 mrg (ltu:CCC (match_dup 1) (match_dup 2)))
325 1.1 mrg (set (match_dup 0)
326 1.1 mrg (neg:QHSI (ne:QHSI (reg:CCC CC_REG) (const_int 0))))])
327 1.1 mrg
328 1.1 mrg ;; We can use rotates and bst/bist to put the C bit into various places
329 1.1 mrg ;; in the destination.
330 1.1 mrg (define_insn_and_split "*store_shifted_c"
331 1.1 mrg [(set (match_operand:QHSI 0 "register_operand" "=r")
332 1.1 mrg (ashift:QHSI (geultu:QHSI (match_operand:QHSI2 1 "register_operand" "r")
333 1.1 mrg (match_operand:QHSI2 2 "register_operand" "r"))
334 1.1 mrg (match_operand 3 "immediate_operand" "n")))]
335 1.1 mrg "INTVAL (operands[3]) == 31 || INTVAL (operands[3]) <= 15"
336 1.1 mrg "#"
337 1.1 mrg "&& reload_completed"
338 1.1 mrg [(set (reg:CCC CC_REG) (ltu:CCC (match_dup 1) (match_dup 2)))
339 1.1 mrg (set (match_dup 0)
340 1.1 mrg (ashift:QHSI (<geultu_to_c>:QHSI (reg:CCC CC_REG) (const_int 0))
341 1.1 mrg (match_dup 3)))])
342 1.1 mrg
343