testsuite: Correct vec-rlmi-rlnm.c testsuite expected result
[official-gcc.git] / gcc / config / h8300 / bitfield.md
blobbed712d830b827554c6626f1976c260e53824bc9
1 ;; -----------------------------------------------------------------
2 ;; BIT FIELDS
3 ;; -----------------------------------------------------------------
4 ;; The H8/300 has given 1/8th of its opcode space to bitfield
5 ;; instructions so let's use them as well as we can.
7 ;; You'll never believe all these patterns perform one basic action --
8 ;; load a bit from the source, optionally invert the bit, then store it
9 ;; in the destination (which is known to be zero).
11 ;; Combine obviously need some work to better identify this situation and
12 ;; canonicalize the form better.
15 ;; Inverted loads with a 16bit destination.
18 (define_insn ""
19   [(set (match_operand:HI 0 "register_operand" "=&r")
20         (zero_extract:HI (xor:HI (match_operand:HI 1 "register_operand" "r")
21                                  (match_operand:HI 3 "const_int_operand" "n"))
22                          (const_int 1)
23                          (match_operand:HI 2 "const_int_operand" "n")))]
24   "(TARGET_H8300SX)
25     && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
26   "sub.w        %0,%0\;bild     %Z2,%Y1\;bst    #0,%X0"
27   [(set_attr "length" "8")])
30 ;; Normal loads with a 32bit destination.
33 (define_insn "*extzv_1_r_h8300hs"
34   [(set (match_operand:SI 0 "register_operand" "=r,r")
35         (zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
36                          (const_int 1)
37                          (match_operand 2 "const_int_operand" "n,n")))]
38   "INTVAL (operands[2]) < 16"
40   return output_simode_bld (0, operands);
42   [(set_attr "cc" "set_znv,set_znv")
43    (set_attr "length" "8,6")])
46 ;; Inverted loads with a 32bit destination.
49 (define_insn "*extzv_1_r_inv_h8300hs"
50   [(set (match_operand:SI 0 "register_operand" "=r,r")
51         (zero_extract:SI (xor:SI (match_operand:SI 1 "register_operand" "?0,r")
52                                  (match_operand 3 "const_int_operand" "n,n"))
53                          (const_int 1)
54                          (match_operand 2 "const_int_operand" "n,n")))]
55   "INTVAL (operands[2]) < 16
56     && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
58   return output_simode_bld (1, operands);
60   [(set_attr "cc" "set_znv,set_znv")
61    (set_attr "length" "8,6")])
63 (define_expand "insv"
64   [(set (zero_extract:HI (match_operand:HI 0 "general_operand" "")
65                          (match_operand:HI 1 "general_operand" "")
66                          (match_operand:HI 2 "general_operand" ""))
67         (match_operand:HI 3 "general_operand" ""))]
68   "TARGET_H8300SX"
69   {
70     if (GET_CODE (operands[1]) == CONST_INT
71         && GET_CODE (operands[2]) == CONST_INT
72         && INTVAL (operands[1]) <= 8
73         && INTVAL (operands[2]) >= 0
74         && INTVAL (operands[1]) + INTVAL (operands[2]) <= 8
75         && memory_operand (operands[0], GET_MODE (operands[0])))
76       {
77         /* If the source operand is zero, it's better to use AND rather
78            than BFST.  Likewise OR if the operand is all ones.  */
79         if (GET_CODE (operands[3]) == CONST_INT)
80           {
81             HOST_WIDE_INT mask = (1 << INTVAL (operands[1])) - 1;
82             if ((INTVAL (operands[3]) & mask) == 0)
83               FAIL;
84             if ((INTVAL (operands[3]) & mask) == mask)
85               FAIL;
86           }
87         if (! bit_memory_operand (operands[0], GET_MODE (operands[0])))
88           {
89             if (!can_create_pseudo_p ())
90               FAIL;
91             operands[0] =  replace_equiv_address (operands[0], force_reg (Pmode,
92                                                   XEXP (operands[0], 0)));
93           }
94         operands[3] = gen_lowpart (QImode, operands[3]);
95         if (! operands[3])
96           FAIL;
97         if (! register_operand (operands[3], QImode))
98           {
99             if (!can_create_pseudo_p ())
100               FAIL;
101             operands[3] = force_reg (QImode, operands[3]);
102           }
103         emit_insn (gen_bfst (adjust_address (operands[0], QImode, 0),
104                                              operands[3], operands[1], operands[2]));
105         DONE;
106       }
107     FAIL;
108   })
110 (define_insn ""
111   [(set (zero_extract:HI (match_operand:HI 0 "register_operand" "+r")
112                          (const_int 1)
113                          (match_operand:HI 1 "immediate_operand" "n"))
114         (match_operand:HI 2 "register_operand" "r"))]
115   ""
116   "bld  #0,%R2\;bst     %Z1,%Y0 ; i1"
117   [(set_attr "length" "4")])
119 (define_expand "extzv"
120   [(set (match_operand:HI 0 "register_operand" "")
121         (zero_extract:HI (match_operand:HI 1 "bit_operand" "")
122                          (match_operand:HI 2 "general_operand" "")
123                          (match_operand:HI 3 "general_operand" "")))]
124   "TARGET_H8300SX"
125   {
126     if (GET_CODE (operands[2]) == CONST_INT
127         && GET_CODE (operands[3]) == CONST_INT
128         && INTVAL (operands[2]) <= 8
129         && INTVAL (operands[3]) >= 0
130         && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8
131         && memory_operand (operands[1], QImode))
132       {
133         rtx temp;
135         /* Optimize the case where we're extracting into a paradoxical
136            subreg.  It's only necessary to extend to the inner reg.  */
137         if (GET_CODE (operands[0]) == SUBREG
138             && subreg_lowpart_p (operands[0])
139             && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0])))
140                 < GET_MODE_SIZE (GET_MODE (operands[0])))
141             && (GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0])))
142                 == MODE_INT))
143            operands[0] = SUBREG_REG (operands[0]);
145         if (!can_create_pseudo_p ())
146           temp = gen_lowpart (QImode, operands[0]);
147         else
148           temp = gen_reg_rtx (QImode);
149         if (! temp)
150           FAIL;
151         if (! bit_memory_operand (operands[1], QImode))
152           {
153             if (!can_create_pseudo_p ())
154               FAIL;
155             operands[1] = replace_equiv_address (operands[1],
156                                                  force_reg (Pmode, XEXP (operands[1], 0)));
157           }
158         emit_insn (gen_bfld (temp, operands[1], operands[2], operands[3]));
159         convert_move (operands[0], temp, 1);
160         DONE;
161       }
162     FAIL;
163   })
165 ;; BAND, BOR, and BXOR patterns
167 (define_insn ""
168   [(set (match_operand:HI 0 "bit_operand" "=Ur")
169         (match_operator:HI 4 "bit_operator"
170          [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
171                            (const_int 1)
172                            (match_operand:HI 2 "immediate_operand" "n"))
173           (match_operand:HI 3 "bit_operand" "0")]))]
174   ""
175   "bld  %Z2,%Y1\;b%c4   #0,%R0\;bst     #0,%R0; bl1"
176   [(set_attr "length" "6")])
178 (define_insn ""
179   [(set (match_operand:HI 0 "bit_operand" "=Ur")
180         (match_operator:HI 5 "bit_operator"
181          [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
182                            (const_int 1)
183                            (match_operand:HI 2 "immediate_operand" "n"))
184           (zero_extract:HI (match_operand:HI 3 "register_operand" "r")
185                            (const_int 1)
186                            (match_operand:HI 4 "immediate_operand" "n"))]))]
187   ""
188   "bld  %Z2,%Y1\;b%c5   %Z4,%Y3\;bst    #0,%R0; bl3"
189   [(set_attr "length" "6")])
191 (define_insn "bfld"
192   [(set (match_operand:QI 0 "register_operand" "=r")
193         (zero_extract:QI (match_operand:QI 1 "bit_memory_operand" "WU")
194                          (match_operand:QI 2 "immediate_operand" "n")
195                          (match_operand:QI 3 "immediate_operand" "n")))]
196   "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8"
198   operands[2] = GEN_INT ((1 << (INTVAL (operands[2]) + INTVAL (operands[3])))
199                          - (1 << INTVAL (operands[3])));
200   return "bfld  %2,%1,%R0";
202   [(set_attr "cc" "none_0hit")
203    (set_attr "length_table" "bitfield")])
205 (define_insn "bfst"
206   [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
207                          (match_operand:QI 2 "immediate_operand" "n")
208                          (match_operand:QI 3 "immediate_operand" "n"))
209         (match_operand:QI 1 "register_operand" "r"))]
210   "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8"
212   operands[2] = GEN_INT ((1 << (INTVAL (operands[2]) + INTVAL (operands[3])))
213                          - (1 << INTVAL (operands[3])));
214   return "bfst  %R1,%2,%0";
216   [(set_attr "cc" "none_0hit")
217    (set_attr "length_table" "bitfield")])
219 (define_expand "cstoreqi4"
220   [(use (match_operator 1 "eqne_operator"
221          [(match_operand:QI 2 "h8300_dst_operand" "")
222           (match_operand:QI 3 "h8300_src_operand" "")]))
223    (clobber (match_operand:HI 0 "register_operand"))]
224   "TARGET_H8300SX"
225   {
226     h8300_expand_store (operands);
227     DONE;
228   })
230 (define_expand "cstorehi4"
231   [(use (match_operator 1 "eqne_operator"
232          [(match_operand:HI 2 "h8300_dst_operand" "")
233           (match_operand:HI 3 "h8300_src_operand" "")]))
234    (clobber (match_operand:HI 0 "register_operand"))]
235   "TARGET_H8300SX"
236   {
237     h8300_expand_store (operands);
238     DONE;
239   })
241 (define_expand "cstoresi4"
242   [(use (match_operator 1 "eqne_operator"
243          [(match_operand:SI 2 "h8300_dst_operand" "")
244           (match_operand:SI 3 "h8300_src_operand" "")]))
245    (clobber (match_operand:HI 0 "register_operand"))]
246   "TARGET_H8300SX"
247   {
248     h8300_expand_store (operands);
249     DONE;
250   })
252 (define_insn "*bstzhireg"
253   [(set (match_operand:HI 0 "register_operand" "=r")
254         (match_operator:HI 1 "eqne_operator" [(cc0) (const_int 0)]))]
255   "TARGET_H8300SX"
256   "mulu.w       #0,%T0\;b%k1    .Lh8BR%=\;inc.w #1,%T0\\n.Lh8BR%=:"
257   [(set_attr "cc" "clobber")])
259 (define_insn_and_split "*cmpstz"
260   [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU,WU")
261                          (const_int 1)
262                          (match_operand:QI 1 "immediate_operand" "n,n"))
263         (match_operator:QI 2 "eqne_operator"
264          [(match_operand 3 "h8300_dst_operand" "r,rQ")
265           (match_operand 4 "h8300_src_operand" "I,rQi")]))]
266   "TARGET_H8300SX
267    && (GET_MODE (operands[3]) == GET_MODE (operands[4])
268        || GET_CODE (operands[4]) == CONST_INT)
269    && GET_MODE_CLASS (GET_MODE (operands[3])) == MODE_INT
270    && GET_MODE_SIZE (GET_MODE (operands[3])) <= 4"
271   "#"
272   "reload_completed"
273   [(set (cc0) (match_dup 5))
274    (set (zero_extract:QI (match_dup 0) (const_int 1) (match_dup 1))
275         (match_op_dup:QI 2 [(cc0) (const_int 0)]))]
276   {
277     operands[5] = gen_rtx_COMPARE (VOIDmode, operands[3], operands[4]);
278   }
279   [(set_attr "cc" "set_znv,compare")])
281 (define_insn "*bstz"
282   [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
283                          (const_int 1)
284                          (match_operand:QI 1 "immediate_operand" "n"))
285         (eq:QI (cc0) (const_int 0)))]
286   "TARGET_H8300SX && reload_completed"
287   "bstz %1,%0"
288   [(set_attr "cc" "none_0hit")
289    (set_attr "length_table" "unary")])
291 (define_insn "*bistz"
292   [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
293                          (const_int 1)
294                          (match_operand:QI 1 "immediate_operand" "n"))
295         (ne:QI (cc0) (const_int 0)))]
296   "TARGET_H8300SX && reload_completed"
297   "bistz        %1,%0"
298   [(set_attr "cc" "none_0hit")
299    (set_attr "length_table" "unary")])
301 (define_insn_and_split "*cmpcondbset"
302   [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
303         (if_then_else:QI (match_operator 1 "eqne_operator"
304                           [(match_operand 2 "h8300_dst_operand" "r,rQ")
305                            (match_operand 3 "h8300_src_operand" "I,rQi")])
306                          (ior:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
307                                  (match_operand:QI 5 "single_one_operand" "n,n"))
308                          (match_dup 4)))]
309   "TARGET_H8300SX"
310   "#"
311   "reload_completed"
312   [(set (cc0) (match_dup 6))
313    (set (match_dup 0)
314         (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
315                          (ior:QI (match_dup 4) (match_dup 5))
316                          (match_dup 4)))]
317   {
318     operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
319   }
320   [(set_attr "cc" "set_znv,compare")])
322 (define_insn "*condbset"
323   [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
324         (if_then_else:QI (match_operator:QI 2 "eqne_operator"
325                           [(cc0) (const_int 0)])
326                          (ior:QI (match_operand:QI 3 "bit_memory_operand" "0")
327                                  (match_operand:QI 1 "single_one_operand" "n"))
328                          (match_dup 3)))]
329   "TARGET_H8300SX && reload_completed"
330   "bset/%j2\t%V1,%0"
331   [(set_attr "cc" "none_0hit")
332    (set_attr "length_table" "logicb")])
334 (define_insn_and_split "*cmpcondbclr"
335   [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
336         (if_then_else:QI (match_operator 1 "eqne_operator"
337                           [(match_operand 2 "h8300_dst_operand" "r,rQ")
338                            (match_operand 3 "h8300_src_operand" "I,rQi")])
339                          (and:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
340                                  (match_operand:QI 5 "single_zero_operand" "n,n"))
341                          (match_dup 4)))]
342   "TARGET_H8300SX"
343   "#"
344   "reload_completed"
345   [(set (cc0) (match_dup 6))
346    (set (match_dup 0)
347         (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
348                          (and:QI (match_dup 4) (match_dup 5))
349                          (match_dup 4)))]
350   {
351     operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
352   }
353   [(set_attr "cc" "set_znv,compare")])
355 (define_insn "*condbclr"
356   [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
357         (if_then_else:QI (match_operator:QI 2 "eqne_operator"
358                           [(cc0) (const_int 0)])
359                          (and:QI (match_operand:QI 3 "bit_memory_operand" "0")
360                                  (match_operand:QI 1 "single_zero_operand" "n"))
361                          (match_dup 3)))]
362   "TARGET_H8300SX && reload_completed"
363   "bclr/%j2\t%W1,%0"
364   [(set_attr "cc" "none_0hit")
365    (set_attr "length_table" "logicb")])
367 (define_insn_and_split "*cmpcondbsetreg"
368   [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
369         (if_then_else:QI (match_operator 1 "eqne_operator"
370                           [(match_operand 2 "h8300_dst_operand" "r,rQ")
371                            (match_operand 3 "h8300_src_operand" "I,rQi")])
372                          (ior:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
373                                  (ashift:QI (const_int 1)
374                                             (match_operand:QI 5 "register_operand" "r,r")))
375                          (match_dup 4)))]
376   "TARGET_H8300SX"
377   "#"
378   "reload_completed"
379   [(set (cc0) (match_dup 6))
380    (set (match_dup 0)
381         (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
382                          (ior:QI (match_dup 4)
383                                  (ashift:QI (const_int 1)
384                                             (match_operand:QI 5 "register_operand" "r,r")))
385                          (match_dup 4)))]
386   {
387     operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
388   }
389   [(set_attr "cc" "set_znv,compare")])
391 (define_insn "*condbsetreg"
392   [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
393         (if_then_else:QI (match_operator:QI 2 "eqne_operator"
394                           [(cc0) (const_int 0)])
395                          (ior:QI (match_operand:QI 3 "bit_memory_operand" "0")
396                                  (ashift:QI (const_int 1)
397                                             (match_operand:QI 1 "register_operand" "r")))
398                          (match_dup 3)))]
399   "TARGET_H8300SX && reload_completed"
400   "bset/%j2\t%R1,%0"
401   [(set_attr "cc" "none_0hit")
402    (set_attr "length_table" "logicb")])
404 (define_insn_and_split "*cmpcondbclrreg"
405   [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
406         (if_then_else:QI (match_operator 1 "eqne_operator"
407                           [(match_operand 2 "h8300_dst_operand" "r,rQ")
408                            (match_operand 3 "h8300_src_operand" "I,rQi")])
409                          (and:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
410                                  (ashift:QI (const_int 1)
411                                             (match_operand:QI 5 "register_operand" "r,r")))
412                          (match_dup 4)))]
413   "TARGET_H8300SX"
414   "#"
415   "reload_completed"
416   [(set (cc0) (match_dup 6))
417    (set (match_dup 0)
418         (if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
419                          (and:QI (match_dup 4)
420                                  (ashift:QI (const_int 1)
421                                             (match_operand:QI 5 "register_operand" "r,r")))
422                          (match_dup 4)))]
423   {
424     operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
425   }
426   [(set_attr "cc" "set_znv,compare")])
428 (define_insn "*condbclrreg"
429   [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
430         (if_then_else:QI (match_operator:QI 2 "eqne_operator"
431                           [(cc0) (const_int 0)])
432                          (and:QI (match_operand:QI 3 "bit_memory_operand" "0")
433                                  (ashift:QI (const_int 1)
434                                             (match_operand:QI 1 "register_operand" "r")))
435                          (match_dup 3)))]
436   "TARGET_H8300SX && reload_completed"
437   "bclr/%j2\t%R1,%0"
438   [(set_attr "cc" "none_0hit")
439    (set_attr "length_table" "logicb")])