Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/m32c/bitops.md @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children | f6334be47118 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 ;; Machine Descriptions for R8C/M16C/M32C | |
2 ;; Copyright (C) 2005, 2007, 2008 | |
3 ;; Free Software Foundation, Inc. | |
4 ;; Contributed by Red Hat. | |
5 ;; | |
6 ;; This file is part of GCC. | |
7 ;; | |
8 ;; GCC is free software; you can redistribute it and/or modify it | |
9 ;; under the terms of the GNU General Public License as published | |
10 ;; by the Free Software Foundation; either version 3, or (at your | |
11 ;; option) any later version. | |
12 ;; | |
13 ;; GCC is distributed in the hope that it will be useful, but WITHOUT | |
14 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
15 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | |
16 ;; License for more details. | |
17 ;; | |
18 ;; You should have received a copy of the GNU General Public License | |
19 ;; along with GCC; see the file COPYING3. If not see | |
20 ;; <http://www.gnu.org/licenses/>. | |
21 | |
22 ;; Bit-wise operations (and, ior, xor, shift) | |
23 | |
24 ; On the R8C and M16C, "address" for bit instructions is usually (but | |
25 ; not always!) the *bit* address, not the *byte* address. This | |
26 ; confuses gcc, so we avoid cases where gcc would produce the wrong | |
27 ; code. We're left with absolute addresses and registers, and the odd | |
28 ; case of shifting a bit by a variable. | |
29 | |
30 ; On the M32C, "address" for bit instructions is a regular address, | |
31 ; and the bit number is stored in a separate field. Thus, we can let | |
32 ; gcc do more interesting things. However, the M32C cannot set all | |
33 ; the bits in a 16-bit register, which the R8C/M16C can do. | |
34 | |
35 ; However, it all means that we end up with two sets of patterns, one | |
36 ; for each chip. | |
37 | |
38 ;;---------------------------------------------------------------------- | |
39 | |
40 ;; First off, all the ways we can set one bit, other than plain IOR. | |
41 | |
42 (define_insn "bset_qi" | |
43 [(set (match_operand:QI 0 "memsym_operand" "+Si") | |
44 (ior:QI (subreg:QI (ashift:HI (const_int 1) | |
45 (subreg:QI (match_operand:HI 1 "a_qi_operand" "Raa") 0)) 0) | |
46 (match_operand:QI 2 "memsym_operand" "0")))] | |
47 "TARGET_A16" | |
48 "bset\t%0[%1]" | |
49 [(set_attr "flags" "n")] | |
50 ) | |
51 | |
52 (define_insn "bset_hi" | |
53 [(set (zero_extract:HI (match_operand:QI 0 "memsym_operand" "+Si") | |
54 (const_int 1) | |
55 (zero_extend:HI (subreg:QI (match_operand:HI 1 "a_qi_operand" "Raa") 0))) | |
56 (const_int 1))] | |
57 "TARGET_A16" | |
58 "bset\t%0[%1]" | |
59 [(set_attr "flags" "n")] | |
60 ) | |
61 | |
62 ;;---------------------------------------------------------------------- | |
63 | |
64 ;; Now all the ways we can clear one bit, other than plain AND. | |
65 | |
66 ; This is odd because the shift patterns use QI counts, but we can't | |
67 ; easily put QI in $aN without causing problems elsewhere. | |
68 (define_insn "bclr_qi" | |
69 [(set (zero_extract:HI (match_operand:QI 0 "memsym_operand" "+Si") | |
70 (const_int 1) | |
71 (zero_extend:HI (subreg:QI (match_operand:HI 1 "a_qi_operand" "Raa") 0))) | |
72 (const_int 0))] | |
73 "TARGET_A16" | |
74 "bclr\t%0[%1]" | |
75 [(set_attr "flags" "n")] | |
76 ) | |
77 | |
78 | |
79 ;;---------------------------------------------------------------------- | |
80 | |
81 ;; Now the generic patterns. | |
82 | |
83 (define_insn "andqi3_16" | |
84 [(set (match_operand:QI 0 "mra_operand" "=Sp,Rqi,RhlSd,RhlSd,??Rmm,??Rmm") | |
85 (and:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0") | |
86 (match_operand 2 "mrai_operand" "Imb,Imb,iRhlSd,?Rmm,iRhlSd,?Rmm")))] | |
87 "TARGET_A16" | |
88 "@ | |
89 bclr\t%B2,%0 | |
90 bclr\t%B2,%h0 | |
91 and.b\t%x2,%0 | |
92 and.b\t%x2,%0 | |
93 and.b\t%x2,%0 | |
94 and.b\t%x2,%0" | |
95 [(set_attr "flags" "n,n,sz,sz,sz,sz")] | |
96 ) | |
97 | |
98 (define_insn "andhi3_16" | |
99 [(set (match_operand:HI 0 "mra_operand" "=Sp,Sp,Rhi,RhiSd,??Rmm,RhiSd,??Rmm") | |
100 (and:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0,0,0,0") | |
101 (match_operand:HI 2 "mrai_operand" "ImB,Imw,Imw,iRhiSd,?Rmm,?Rmm,iRhiSd")))] | |
102 "TARGET_A16" | |
103 "@ | |
104 | |
105 bclr\t%B2,%0 | |
106 bclr\t%B2-8,1+%0 | |
107 bclr\t%B2,%0 | |
108 and.w\t%X2,%0 | |
109 and.w\t%X2,%0 | |
110 and.w\t%X2,%0 | |
111 and.w\t%X2,%0" | |
112 [(set_attr "flags" "n,n,n,sz,sz,sz,sz")] | |
113 ) | |
114 | |
115 (define_insn "andsi3" | |
116 [(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm,??Rmm,RsiSd") | |
117 (and:SI (match_operand:SI 1 "mra_operand" "%0,0,0,0,0,0") | |
118 (match_operand:SI 2 "mrai_operand" "i,?Rmm,i,RsiSd,?Rmm,RsiSd")))] | |
119 "" | |
120 "* | |
121 switch (which_alternative) | |
122 { | |
123 case 0: | |
124 output_asm_insn (\"and.w %X2,%h0\",operands); | |
125 operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); | |
126 return \"and.w %X2,%H0\"; | |
127 case 1: | |
128 return \"and.w %h2,%h0\;and.w %H2,%H0\"; | |
129 case 2: | |
130 output_asm_insn (\"and.w %X2,%h0\",operands); | |
131 operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); | |
132 return \"and.w %X2,%H0\"; | |
133 case 3: | |
134 return \"and.w %h2,%h0\;and.w %H2,%H0\"; | |
135 case 4: | |
136 return \"and.w %h2,%h0\;and.w %H2,%H0\"; | |
137 case 5: | |
138 return \"and.w %h2,%h0\;and.w %H2,%H0\"; | |
139 }" | |
140 [(set_attr "flags" "x,x,x,x,x,x")] | |
141 ) | |
142 | |
143 | |
144 (define_insn "iorqi3_16" | |
145 [(set (match_operand:QI 0 "mra_operand" "=Sp,Rqi,RqiSd,??Rmm,RqiSd,??Rmm") | |
146 (ior:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0") | |
147 (match_operand:QI 2 "mrai_operand" "Ilb,Ilb,iRhlSd,iRhlSd,?Rmm,?Rmm")))] | |
148 "TARGET_A16" | |
149 "@ | |
150 bset\t%B2,%0 | |
151 bset\t%B2,%h0 | |
152 or.b\t%x2,%0 | |
153 or.b\t%x2,%0 | |
154 or.b\t%x2,%0 | |
155 or.b\t%x2,%0" | |
156 [(set_attr "flags" "n,n,sz,sz,sz,sz")] | |
157 ) | |
158 | |
159 (define_insn "iorhi3_16" | |
160 [(set (match_operand:HI 0 "mra_operand" "=Sp,Sp,Rhi,RhiSd,RhiSd,??Rmm,??Rmm") | |
161 (ior:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0,0,0,0") | |
162 (match_operand:HI 2 "mrai_operand" "Ilb,Ilw,Ilw,iRhiSd,?Rmm,iRhiSd,?Rmm")))] | |
163 "TARGET_A16" | |
164 "@ | |
165 bset %B2,%0 | |
166 bset\t%B2-8,1+%0 | |
167 bset\t%B2,%0 | |
168 or.w\t%X2,%0 | |
169 or.w\t%X2,%0 | |
170 or.w\t%X2,%0 | |
171 or.w\t%X2,%0" | |
172 [(set_attr "flags" "n,n,n,sz,sz,sz,sz")] | |
173 ) | |
174 | |
175 ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
176 | |
177 (define_insn "andqi3_24" | |
178 [(set (match_operand:QI 0 "mra_operand" "=Sd,Rqi,RhlSd,RhlSd,??Rmm,??Rmm") | |
179 (and:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0") | |
180 (match_operand 2 "mrai_operand" "Imb,Imb,iRhlSd,?Rmm,iRhlSd,?Rmm")))] | |
181 "TARGET_A24" | |
182 "@ | |
183 bclr\t%B2,%0 | |
184 bclr\t%B2,%0 | |
185 and.b\t%x2,%0 | |
186 and.b\t%x2,%0 | |
187 and.b\t%x2,%0 | |
188 and.b\t%x2,%0" | |
189 [(set_attr "flags" "n,n,sz,sz,sz,sz")] | |
190 ) | |
191 | |
192 (define_insn "andhi3_24" | |
193 [(set (match_operand:HI 0 "mra_operand" "=Sd,Sd,?Rhl,?Rhl,RhiSd,??Rmm,RhiSd,??Rmm") | |
194 (and:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0,0,0,0,0") | |
195 (match_operand:HI 2 "mrai_operand" "ImB,Imw,ImB,Imw,iRhiSd,?Rmm,?Rmm,iRhiSd")))] | |
196 "TARGET_A24" | |
197 "@ | |
198 bclr\t%B2,%0 | |
199 bclr\t%B2-8,1+%0 | |
200 bclr\t%B2,%h0 | |
201 bclr\t%B2-8,%H0 | |
202 and.w\t%X2,%0 | |
203 and.w\t%X2,%0 | |
204 and.w\t%X2,%0 | |
205 and.w\t%X2,%0" | |
206 [(set_attr "flags" "n,n,n,n,sz,sz,sz,sz")] | |
207 ) | |
208 | |
209 | |
210 | |
211 (define_insn "iorqi3_24" | |
212 [(set (match_operand:QI 0 "mra_operand" "=RqiSd,RqiSd,??Rmm,RqiSd,??Rmm") | |
213 (ior:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0") | |
214 (match_operand:QI 2 "mrai_operand" "Ilb,iRhlSd,iRhlSd,?Rmm,?Rmm")))] | |
215 "TARGET_A24" | |
216 "@ | |
217 bset\t%B2,%0 | |
218 or.b\t%x2,%0 | |
219 or.b\t%x2,%0 | |
220 or.b\t%x2,%0 | |
221 or.b\t%x2,%0" | |
222 [(set_attr "flags" "n,sz,sz,sz,sz")] | |
223 ) | |
224 | |
225 (define_insn "iorhi3_24" | |
226 [(set (match_operand:HI 0 "mra_operand" "=Sd,Sd,?Rhl,?Rhl,RhiSd,RhiSd,??Rmm,??Rmm") | |
227 (ior:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0,0,0,0,0") | |
228 (match_operand:HI 2 "mrai_operand" "Ilb,Ilw,Ilb,Ilw,iRhiSd,?Rmm,iRhiSd,?Rmm")))] | |
229 "TARGET_A24" | |
230 "@ | |
231 bset\t%B2,%0 | |
232 bset\t%B2-8,1+%0 | |
233 bset\t%B2,%h0 | |
234 bset\t%B2-8,%H0 | |
235 or.w\t%X2,%0 | |
236 or.w\t%X2,%0 | |
237 or.w\t%X2,%0 | |
238 or.w\t%X2,%0" | |
239 [(set_attr "flags" "n,n,n,n,sz,sz,sz,sz")] | |
240 ) | |
241 | |
242 | |
243 ; ---------------------------------------------------------------------- | |
244 | |
245 (define_expand "andqi3" | |
246 [(set (match_operand:QI 0 "mra_operand" "") | |
247 (and:QI (match_operand:QI 1 "mra_operand" "") | |
248 (match_operand:QI 2 "mrai_operand" "")))] | |
249 "" | |
250 "if (TARGET_A16) | |
251 emit_insn (gen_andqi3_16 (operands[0], operands[1], operands[2])); | |
252 else | |
253 emit_insn (gen_andqi3_24 (operands[0], operands[1], operands[2])); | |
254 DONE;" | |
255 ) | |
256 | |
257 (define_expand "andhi3" | |
258 [(set (match_operand:HI 0 "mra_operand" "") | |
259 (and:HI (match_operand:HI 1 "mra_operand" "") | |
260 (match_operand:HI 2 "mrai_operand" "")))] | |
261 "" | |
262 "if (TARGET_A16) | |
263 emit_insn (gen_andhi3_16 (operands[0], operands[1], operands[2])); | |
264 else | |
265 emit_insn (gen_andhi3_24 (operands[0], operands[1], operands[2])); | |
266 DONE;" | |
267 ) | |
268 | |
269 (define_expand "iorqi3" | |
270 [(set (match_operand:QI 0 "mra_operand" "") | |
271 (ior:QI (match_operand:QI 1 "mra_operand" "") | |
272 (match_operand:QI 2 "mrai_operand" "")))] | |
273 "" | |
274 "if (TARGET_A16) | |
275 emit_insn (gen_iorqi3_16 (operands[0], operands[1], operands[2])); | |
276 else | |
277 emit_insn (gen_iorqi3_24 (operands[0], operands[1], operands[2])); | |
278 DONE;" | |
279 ) | |
280 | |
281 (define_expand "iorhi3" | |
282 [(set (match_operand:HI 0 "mra_operand" "") | |
283 (ior:HI (match_operand:HI 1 "mra_operand" "") | |
284 (match_operand:HI 2 "mrai_operand" "")))] | |
285 "" | |
286 "if (TARGET_A16) | |
287 emit_insn (gen_iorhi3_16 (operands[0], operands[1], operands[2])); | |
288 else | |
289 emit_insn (gen_iorhi3_24 (operands[0], operands[1], operands[2])); | |
290 DONE;" | |
291 ) | |
292 | |
293 (define_insn "iorsi3" | |
294 [(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm,??Rmm,RsiSd") | |
295 (ior:SI (match_operand:SI 1 "mra_operand" "%0,0,0,0,0,0") | |
296 (match_operand:SI 2 "mrai_operand" "i,?Rmm,i,RsiSd,?Rmm,RsiSd")))] | |
297 "" | |
298 "* | |
299 switch (which_alternative) | |
300 { | |
301 case 0: | |
302 output_asm_insn (\"or.w %X2,%h0\",operands); | |
303 operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); | |
304 return \"or.w %X2,%H0\"; | |
305 case 1: | |
306 return \"or.w %h2,%h0\;or.w %H2,%H0\"; | |
307 case 2: | |
308 output_asm_insn (\"or.w %X2,%h0\",operands); | |
309 operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); | |
310 return \"or.w %X2,%H0\"; | |
311 case 3: | |
312 return \"or.w %h2,%h0\;or.w %H2,%H0\"; | |
313 case 4: | |
314 return \"or.w %h2,%h0\;or.w %H2,%H0\"; | |
315 case 5: | |
316 return \"or.w %h2,%h0\;or.w %H2,%H0\"; | |
317 }" | |
318 [(set_attr "flags" "x,x,x,x,x,x")] | |
319 ) | |
320 | |
321 (define_insn "xorqi3" | |
322 [(set (match_operand:QI 0 "mra_operand" "=RhlSd,RhlSd,??Rmm,??Rmm") | |
323 (xor:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0") | |
324 (match_operand:QI 2 "mrai_operand" "iRhlSd,?Rmm,iRhlSd,?Rmm")))] | |
325 "" | |
326 "xor.b\t%x2,%0" | |
327 [(set_attr "flags" "sz,sz,sz,sz")] | |
328 ) | |
329 | |
330 (define_insn "xorhi3" | |
331 [(set (match_operand:HI 0 "mra_operand" "=RhiSd,RhiSd,??Rmm,??Rmm") | |
332 (xor:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0") | |
333 (match_operand:HI 2 "mrai_operand" "iRhiSd,?Rmm,iRhiSd,?Rmm")))] | |
334 "" | |
335 "xor.w\t%X2,%0" | |
336 [(set_attr "flags" "sz,sz,sz,sz")] | |
337 ) | |
338 | |
339 (define_insn "xorsi3" | |
340 [(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm,??Rmm,RsiSd") | |
341 (xor:SI (match_operand:SI 1 "mra_operand" "%0,0,0,0,0,0") | |
342 (match_operand:SI 2 "mrai_operand" "i,?Rmm,i,RsiSd,?Rmm,RsiSd")))] | |
343 "" | |
344 "* | |
345 switch (which_alternative) | |
346 { | |
347 case 0: | |
348 output_asm_insn (\"xor.w %X2,%h0\",operands); | |
349 operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); | |
350 return \"xor.w %X2,%H0\"; | |
351 case 1: | |
352 return \"xor.w %h2,%h0\;xor.w %H2,%H0\"; | |
353 case 2: | |
354 output_asm_insn (\"xor.w %X2,%h0\",operands); | |
355 operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); | |
356 return \"xor.w %X2,%H0\"; | |
357 case 3: | |
358 return \"xor.w %h2,%h0\;xor.w %H2,%H0\"; | |
359 case 4: | |
360 return \"xor.w %h2,%h0\;xor.w %H2,%H0\"; | |
361 case 5: | |
362 return \"xor.w %h2,%h0\;xor.w %H2,%H0\"; | |
363 }" | |
364 [(set_attr "flags" "x,x,x,x,x,x")] | |
365 ) | |
366 | |
367 (define_insn "one_cmplqi2" | |
368 [(set (match_operand:QI 0 "mra_operand" "=RhlSd,??Rmm") | |
369 (not:QI (match_operand:QI 1 "mra_operand" "0,0")))] | |
370 "" | |
371 "not.b\t%0" | |
372 [(set_attr "flags" "sz,sz")] | |
373 ) | |
374 | |
375 (define_insn "one_cmplhi2" | |
376 [(set (match_operand:HI 0 "mra_operand" "=RhiSd,??Rmm") | |
377 (not:HI (match_operand:HI 1 "mra_operand" "0,0")))] | |
378 "" | |
379 "not.w\t%0" | |
380 [(set_attr "flags" "sz,sz")] | |
381 ) | |
382 | |
383 ; Optimizations using bit opcodes | |
384 | |
385 ; We need this because combine only looks at three insns at a time, | |
386 ; and the bclr_qi pattern uses four - mov, shift, not, and. GCC | |
387 ; should never expand this pattern, because it only shifts a constant | |
388 ; by a constant, so gcc should do that itself. | |
389 (define_insn "shift1_qi" | |
390 [(set (match_operand:QI 0 "mra_operand" "=Rqi") | |
391 (ashift:QI (const_int 1) | |
392 (match_operand 1 "const_int_operand" "In4")))] | |
393 "" | |
394 "mov.b\t#1,%0\n\tshl.b\t%1,%0" | |
395 ) | |
396 (define_insn "shift1_hi" | |
397 [(set (match_operand:HI 0 "mra_operand" "=Rhi") | |
398 (ashift:HI (const_int 1) | |
399 (match_operand 1 "const_int_operand" "In4")))] | |
400 "" | |
401 "mov.w\t#1,%0\n\tshl.w\t%1,%0" | |
402 ) | |
403 | |
404 ; Generic insert-bit expander, needed so that we can use the bit | |
405 ; opcodes for volatile bitfields. | |
406 | |
407 (define_expand "insv" | |
408 [(set (zero_extract:HI (match_operand:HI 0 "mra_operand" "") | |
409 (match_operand 1 "const_int_operand" "") | |
410 (match_operand 2 "const_int_operand" "")) | |
411 (match_operand:HI 3 "const_int_operand" ""))] | |
412 "" | |
413 "if (m32c_expand_insv (operands)) | |
414 FAIL; | |
415 DONE;" | |
416 ) |