xref: /netbsd-src/external/gpl3/gcc/dist/gcc/config/h8300/logical.md (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1;; Generic for binary logicals across the supported integer modes
2(define_expand "<code><mode>3"
3  [(set (match_operand:QHSI 0 "register_operand" "")
4	(logicals:QHSI (match_operand:QHSI 1 "register_operand" "")
5		       (match_operand:QHSI 2 "h8300_src_operand" "")))]
6  ""
7  "
8  {
9    enum machine_mode mode = GET_MODE (operands[0]);
10    /* DImodes are not considered tieable, as a result operations involving
11       subregs of DImode objects are considered expensive which can prevent
12       CSE from doing obvious simplifications.
13
14       We may ultimately change what is tieable, but this is an immediate
15       workaround while we evaluate changes to tieable modes.
16
17       The key in terms of what we want to handle is then the result of
18       the operation is not a constant.  */
19    if ((<CODE> == AND && operands[2] == CONSTM1_RTX (mode))
20	|| (<CODE> == IOR && operands[2] == CONST0_RTX (mode))
21	|| (<CODE> == XOR && operands[2] == CONST0_RTX (mode))
22	|| ((<CODE> == AND || <CODE> == IOR) && operands[1] == operands[2]))
23      {
24	emit_move_insn (operands[0], operands[1]);
25	DONE;
26      }
27  }")
28
29;; There's a ton of cleanup to do from here below.
30;; ----------------------------------------------------------------------
31;; AND INSTRUCTIONS
32;; ----------------------------------------------------------------------
33
34(define_insn "bclr<mode>_msx"
35  [(set (match_operand:QHI 0 "bit_register_indirect_operand" "=WU")
36	(and:QHI (match_operand:QHI 1 "bit_register_indirect_operand" "%0")
37		 (match_operand:QHI 2 "single_zero_operand" "Y0")))]
38  "TARGET_H8300SX && rtx_equal_p (operands[0], operands[1])"
39  "bclr\\t%W2,%0"
40  [(set_attr "length" "8")])
41
42(define_split
43  [(set (match_operand:HI 0 "bit_register_indirect_operand")
44	(and:HI (match_operand:HI 1 "bit_register_indirect_operand")
45		(match_operand:HI 2 "single_zero_operand")))]
46  "TARGET_H8300SX && abs (INTVAL (operands[2])) > 0xff"
47  [(set (match_dup 0)
48	(and:QI (match_dup 1)
49		(match_dup 2)))]
50  {
51    operands[0] = adjust_address (operands[0], QImode, 0);
52    operands[1] = adjust_address (operands[1], QImode, 0);
53    operands[2] = GEN_INT ((INTVAL (operands[2])) >> 8);
54  })
55
56(define_insn_and_split "*andqi3_2"
57  [(set (match_operand:QI 0 "bit_operand" "=U,rQ,r")
58	(and:QI (match_operand:QI 1 "bit_operand" "%0,0,WU")
59		(match_operand:QI 2 "h8300_src_operand" "Y0,rQi,IP1>X")))]
60  "TARGET_H8300SX"
61  "#"
62  "&& reload_completed"
63  [(parallel [(set (match_dup 0) (and:QI (match_dup 1) (match_dup 2)))
64	      (clobber (reg:CC CC_REG))])])
65
66(define_insn "*andqi3_2_clobber_flags"
67  [(set (match_operand:QI 0 "bit_operand" "=U,rQ,r")
68	(and:QI (match_operand:QI 1 "bit_operand" "%0,0,WU")
69		(match_operand:QI 2 "h8300_src_operand" "Y0,rQi,IP1>X")))
70   (clobber (reg:CC CC_REG))]
71  "TARGET_H8300SX"
72  "@
73   bclr\\t %W2,%R0
74   and  %X2,%X0
75   bfld %2,%1,%R0"
76  [(set_attr "length" "8,*,8")
77   (set_attr "length_table" "*,logicb,*")])
78
79(define_insn_and_split "andqi3_1"
80  [(set (match_operand:QI 0 "bit_operand" "=U,r")
81	(and:QI (match_operand:QI 1 "bit_operand" "%0,0")
82		(match_operand:QI 2 "h8300_src_operand" "Y0,rn")))]
83  "register_operand (operands[0], QImode)
84   || single_zero_operand (operands[2], QImode)"
85  "bclr %W2,%R0"
86  "&& reload_completed && !single_zero_operand (operands[2], QImode)"
87  [(parallel [(set (match_dup 0) (and:QI (match_dup 1) (match_dup 2)))
88	      (clobber (reg:CC CC_REG))])]
89  ""
90  [(set_attr "length" "8,2")])
91
92
93(define_insn_and_split "*andor<mode>3"
94  [(set (match_operand:QHSI 0 "register_operand" "=r")
95	(ior:QHSI (and:QHSI (match_operand:QHSI 2 "register_operand" "r")
96			    (match_operand:QHSI 3 "single_one_operand" "n"))
97		  (match_operand:QHSI 1 "register_operand" "0")))]
98  "(<MODE>mode == QImode
99    || <MODE>mode == HImode
100    || (<MODE>mode == SImode
101	&& (INTVAL (operands[3]) & 0xffff) != 0))"
102  "#"
103  "&& reload_completed"
104  [(parallel [(set (match_dup 0) (ior:QHSI (and:QHSI (match_dup 2)
105						     (match_dup 3))
106					   (match_dup 1)))
107	      (clobber (reg:CC CC_REG))])])
108
109(define_insn "*andor<mode>3_clobber_flags"
110  [(set (match_operand:QHSI 0 "register_operand" "=r")
111	(ior:QHSI (and:QHSI (match_operand:QHSI 2 "register_operand" "r")
112			    (match_operand:QHSI 3 "single_one_operand" "n"))
113		  (match_operand:QHSI 1 "register_operand" "0")))
114   (clobber (reg:CC CC_REG))]
115  "(<MODE>mode == QImode
116    || <MODE>mode == HImode
117    || (<MODE>mode == SImode
118	&& (INTVAL (operands[3]) & 0xffff) != 0))"
119  {
120    if (<MODE>mode == QImode)
121      return "bld\\t%V3,%X2\;bor\\t%V3,%X0\;bst\\t%V3,%X0";
122
123    if (<MODE>mode == HImode)
124      {
125	operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
126	if (INTVAL (operands[3]) > 128)
127	  {
128	    operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
129	    return "bld\\t%V3,%t2\;bor\\t%V3,%t0\;bst\\t%V3,%t0";
130	  }
131	return "bld\\t%V3,%s2\;bor\\t%V3,%s0\;bst\\t%V3,%s0";
132      }
133
134    if (<MODE>mode == SImode)
135      {
136	operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
137	if (INTVAL (operands[3]) > 128)
138	  {
139	    operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
140	    return "bld\\t%V3,%x2\;bor\\t%V3,%x0\;bst\\t%V3,%x0";
141	  }
142	return "bld\\t%V3,%w2\;bor\\t%V3,%w0\;bst\\t%V3,%w0";
143      }
144
145    gcc_unreachable ();
146
147  }
148  [(set_attr "length" "6")])
149
150(define_insn_and_split "*andorsi3_shift_8"
151  [(set (match_operand:SI 0 "register_operand" "=r")
152	(ior:SI (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
153				   (const_int 8))
154			(const_int 65280))
155		(match_operand:SI 1 "register_operand" "0")))]
156  ""
157  "#"
158  "&& reload_completed"
159  [(parallel [(set (match_dup 0) (ior:SI (and:SI (ashift:SI (match_dup 2)
160							    (const_int 8))
161						 (const_int 65280))
162					 (match_dup 1)))
163	      (clobber (reg:CC CC_REG))])])
164
165(define_insn "*andorsi3_shift_8_clobber_flags"
166  [(set (match_operand:SI 0 "register_operand" "=r")
167	(ior:SI (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
168				   (const_int 8))
169			(const_int 65280))
170		(match_operand:SI 1 "register_operand" "0")))
171   (clobber (reg:CC CC_REG))]
172  ""
173  "or.b\\t%w2,%x0"
174  [(set_attr "length" "2")])
175
176;; ----------------------------------------------------------------------
177;; OR/XOR INSTRUCTIONS
178;; ----------------------------------------------------------------------
179
180(define_insn "b<code><mode>_msx"
181  [(set (match_operand:QHI 0 "bit_register_indirect_operand" "=WU")
182	(ors:QHI (match_operand:QHI 1 "bit_register_indirect_operand" "%0")
183		 (match_operand:QHI 2 "single_one_operand" "Y2")))]
184  "TARGET_H8300SX && rtx_equal_p (operands[0], operands[1])"
185  { return <CODE> == IOR ? "bset\\t%V2,%0" : "bnot\\t%V2,%0"; }
186  [(set_attr "length" "8")])
187
188(define_insn_and_split "<code>qi3_1"
189  [(set (match_operand:QI 0 "bit_operand" "=U,rQ")
190	(ors:QI (match_operand:QI 1 "bit_operand" "%0,0")
191		(match_operand:QI 2 "h8300_src_operand" "Y2,rQi")))]
192  "TARGET_H8300SX || register_operand (operands[0], QImode)
193   || single_one_operand (operands[2], QImode)"
194  { return <CODE> == IOR ? "bset\\t%V2,%R0" : "bnot\\t%V2,%R0"; }
195  "&& reload_completed && !single_one_operand (operands[2], QImode)"
196  [(parallel [(set (match_dup 0) (ors:QI (match_dup 1) (match_dup 2)))
197	      (clobber (reg:CC CC_REG))])]
198  ""
199  [(set_attr "length" "8")])
200
201(define_insn "*<code>qi3_1<cczn>"
202  [(set (match_operand:QI 0 "bit_operand" "=rQ")
203	(ors:QI (match_operand:QI 1 "bit_operand" "%0")
204		(match_operand:QI 2 "h8300_src_operand" "rQi")))
205   (clobber (reg:CC CC_REG))]
206  "TARGET_H8300SX"
207  { return <CODE> == IOR ? "or\\t%X2,%X0" : "xor\\t%X2,%X0"; }
208  [(set_attr "length" "*")
209   (set_attr "length_table" "logicb")])
210
211(define_insn "*<code>qi3_1<cczn>"
212  [(set (match_operand:QI 0 "register_operand" "=r")
213	(ors:QI (match_operand:QI 1 "register_operand" "%0")
214		(match_operand:QI 2 "h8300_src_operand" "ri")))
215   (clobber (reg:CC CC_REG))]
216  "TARGET_H8300SX"
217  { return <CODE> == IOR ? "or\\t%X2,%X0" : "xor\\t%X2,%X0"; }
218  [(set_attr "length" "*")
219   (set_attr "length_table" "logicb")])
220
221(define_insn "*<code>qi3_1<cczn>"
222  [(set (match_operand:QI 0 "register_operand" "=r")
223	(logicals:QI (match_operand:QI 1 "register_operand" "%0")
224		     (match_operand:QI 2 "h8300_src_operand" "rn")))
225   (clobber (reg:CC CC_REG))]
226  ""
227  {
228    if (<CODE> == IOR)
229      return "or\\t%X2,%X0";
230    else if (<CODE> == XOR)
231      return "xor\\t%X2,%X0";
232    else if (<CODE> == AND)
233      return "and\\t%X2,%X0";
234   gcc_unreachable ();
235  }
236  [(set_attr "length" "2")])
237
238;; ----------------------------------------------------------------------
239;; {AND,IOR,XOR}{HI3,SI3} PATTERNS
240;; ----------------------------------------------------------------------
241
242(define_insn_and_split "*logical<mode>3"
243  [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
244	(logicals:QHSI
245	  (match_operand:QHSI 1 "h8300_dst_operand" "%0")
246	  (match_operand:QHSI 2 "h8300_src_operand" "rQi")))]
247  "h8300_operands_match_p (operands)"
248  "#"
249  "&& reload_completed"
250  [(parallel [(set (match_dup 0)
251		   (logicals:QHSI (match_dup 1) (match_dup 2)))
252	      (clobber (reg:CC CC_REG))])])
253
254(define_insn "*<code><mode>3<cczn>"
255  [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
256	(logicals:QHSI
257	  (match_operand:QHSI 1 "h8300_dst_operand" "%0")
258	  (match_operand:QHSI 2 "h8300_src_operand" "rQi")))
259   (clobber (reg:CC CC_REG))]
260  "h8300_operands_match_p (operands)"
261  { return output_logical_op (<MODE>mode, <CODE>, operands, insn); }
262  [(set (attr "length")
263	(symbol_ref "compute_logical_op_length (<MODE>mode, <CODE>, operands, insn)"))])
264
265;; ----------------------------------------------------------------------
266;; NOT INSTRUCTIONS
267;; ----------------------------------------------------------------------
268
269(define_insn_and_split "one_cmpl<mode>2"
270  [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
271	(not:QHSI (match_operand:QHSI 1 "h8300_dst_operand" "0")))]
272  ""
273  "#"
274  "&& reload_completed"
275  [(parallel [(set (match_dup 0) (not:QHSI (match_dup 1)))
276	      (clobber (reg:CC CC_REG))])])
277
278(define_insn "one_cmpl<mode>2_<cczn>"
279  [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
280	(not:QHSI (match_operand:QHSI 1 "h8300_dst_operand" "0")))
281   (clobber (reg:CC CC_REG))]
282  ""
283  {
284    if (<MODE>mode == E_QImode)
285      return "not	%X0";
286    if (<MODE>mode == E_HImode)
287      return "not.w	%T0";
288    if (<MODE>mode == E_SImode)
289      return "not.l	%S0";
290    gcc_unreachable ();
291  }
292  [(set_attr "length_table" "unary")])
293
294;; The next four peephole2's will try to transform
295;;
296;;   mov.b A,r0l    (or mov.l A,er0)
297;;   and.l #CST,er0
298;;
299;; into
300;;
301;;   sub.l er0
302;;   mov.b A,r0l
303;;   and.b #CST,r0l (if CST is not 255)
304
305(define_peephole2
306  [(parallel [(set (match_operand:QI 0 "register_operand" "")
307		   (match_operand:QI 1 "general_operand" ""))
308	      (clobber (reg:CC CC_REG))])
309   (parallel [(set (match_operand:SI 2 "register_operand" "")
310		   (and:SI (match_dup 2) (const_int 255)))
311	      (clobber (reg:CC CC_REG))])]
312  "!reg_overlap_mentioned_p (operands[2], operands[1])
313   && REGNO (operands[0]) == REGNO (operands[2])"
314  [(parallel [(set (match_dup 2) (const_int 0))
315	      (clobber (reg:CC CC_REG))])
316   (parallel [(set (strict_low_part (match_dup 0)) (match_dup 1))
317	      (clobber (reg:CC CC_REG))])])
318
319(define_peephole2
320  [(parallel [(set (match_operand:SI 0 "register_operand" "")
321		   (match_operand:SI 1 "nonimmediate_operand" ""))
322	      (clobber (reg:CC CC_REG))])
323   (parallel [(set (match_dup 0)
324		   (and:SI (match_dup 0) (const_int 255)))
325	      (clobber (reg:CC CC_REG))])]
326  "!reg_overlap_mentioned_p (operands[0], operands[1])
327   && !(GET_CODE (operands[1]) == MEM && !offsettable_memref_p (operands[1]))
328   && !(GET_CODE (operands[1]) == MEM && MEM_VOLATILE_P (operands[1]))"
329  [(parallel [(set (match_dup 0) (const_int 0))
330	      (clobber (reg:CC CC_REG))])
331   (parallel [(set (strict_low_part (match_dup 2)) (match_dup 3))
332	      (clobber (reg:CC CC_REG))])]
333  {
334    operands[2] = gen_lowpart (QImode, operands[0]);
335    operands[3] = gen_lowpart (QImode, operands[1]);
336  })
337
338(define_peephole2
339  [(parallel [(set (match_operand 0 "register_operand" "")
340		   (match_operand 1 "nonimmediate_operand" ""))
341	      (clobber (reg:CC CC_REG))])
342   (parallel [(set (match_operand:SI 2 "register_operand" "")
343		   (and:SI (match_dup 2)
344			   (match_operand:SI 3 "const_int_qi_operand" "")))
345	      (clobber (reg:CC CC_REG))])]
346  "(GET_MODE (operands[0]) == QImode
347    || GET_MODE (operands[0]) == HImode
348    || GET_MODE (operands[0]) == SImode)
349   && GET_MODE (operands[0]) == GET_MODE (operands[1])
350   && REGNO (operands[0]) == REGNO (operands[2])
351   && !reg_overlap_mentioned_p (operands[2], operands[1])
352   && !(GET_MODE (operands[1]) != QImode
353	&& GET_CODE (operands[1]) == MEM
354	&& !offsettable_memref_p (operands[1]))
355   && !(GET_MODE (operands[1]) != QImode
356	&& GET_CODE (operands[1]) == MEM
357	&& MEM_VOLATILE_P (operands[1]))"
358  [(parallel [(set (match_dup 2) (const_int 0))
359	      (clobber (reg:CC CC_REG))])
360   (parallel [(set (strict_low_part (match_dup 4)) (match_dup 5))
361	      (clobber (reg:CC CC_REG))])
362   (parallel [(set (match_dup 2) (and:SI (match_dup 2) (match_dup 6)))
363	      (clobber (reg:CC CC_REG))])]
364  {
365    operands[4] = gen_lowpart (QImode, operands[0]);
366    operands[5] = gen_lowpart (QImode, operands[1]);
367    operands[6] = GEN_INT (~0xff | INTVAL (operands[3]));
368  })
369
370(define_peephole2
371  [(parallel [(set (match_operand:SI 0 "register_operand" "")
372		   (match_operand:SI 1 "register_operand" ""))
373	      (clobber (reg:CC CC_REG))])
374   (parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65280)))
375	      (clobber (reg:CC CC_REG))])]
376  "!reg_overlap_mentioned_p (operands[0], operands[1])"
377  [(parallel [(set (match_dup 0) (const_int 0))
378	      (clobber (reg:CC CC_REG))])
379   (parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
380		   (lshiftrt:SI (match_dup 1) (const_int 8)))
381	      (clobber (reg:CC CC_REG))])])
382