Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/ft32/ft32.md @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 ;; Machine description for FT32 | |
2 ;; Copyright (C) 2015-2017 Free Software Foundation, Inc. | |
3 ;; Contributed by FTDI <support@ftdi.com> | |
4 | |
5 ;; This file is part of GCC. | |
6 | |
7 ;; GCC is free software; you can redistribute it and/or modify it | |
8 ;; under the terms of the GNU General Public License as published | |
9 ;; by the Free Software Foundation; either version 3, or (at your | |
10 ;; option) any later version. | |
11 | |
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT | |
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
14 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | |
15 ;; License for more details. | |
16 | |
17 ;; You should have received a copy of the GNU General Public License | |
18 ;; along with GCC; see the file COPYING3. If not see | |
19 ;; <http://www.gnu.org/licenses/>. | |
20 | |
21 ;; ------------------------------------------------------------------------- | |
22 ;; FT32 specific constraints, predicates and attributes | |
23 ;; ------------------------------------------------------------------------- | |
24 | |
25 (include "constraints.md") | |
26 (include "predicates.md") | |
27 | |
28 (define_constants [ | |
29 (FP_REG 0) | |
30 (SP_REG 1) | |
31 (CC_REG 35) | |
32 ]) | |
33 | |
34 (define_c_enum "unspec" | |
35 [UNSPEC_STRLEN | |
36 UNSPEC_MOVMEM | |
37 UNSPEC_SETMEM | |
38 UNSPEC_STPCPY | |
39 UNSPEC_INDEX_JMP | |
40 UNSPEC_LPM | |
41 UNSPEC_FMUL | |
42 UNSPEC_FMULS | |
43 UNSPEC_FMULSU | |
44 UNSPEC_COPYSIGN | |
45 UNSPEC_IDENTITY | |
46 UNSPEC_INSERT_BITS | |
47 UNSPEC_JMP_EPILOG | |
48 UNSPEC_JMP_EPILOG24 | |
49 UNSPEC_JMP_PROLOG | |
50 UNSPEC_XCHG | |
51 ]) | |
52 | |
53 ;; ------------------------------------------------------------------------- | |
54 ;; nop instruction | |
55 ;; ------------------------------------------------------------------------- | |
56 | |
57 (define_insn "nop" | |
58 [(const_int 0)] | |
59 "" | |
60 "nop") | |
61 | |
62 ;; ------------------------------------------------------------------------- | |
63 ;; Arithmetic instructions | |
64 ;; ------------------------------------------------------------------------- | |
65 | |
66 (define_insn "addsi3" | |
67 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
68 (plus:SI | |
69 (match_operand:SI 1 "register_operand" "r,r") | |
70 (match_operand:SI 2 "ft32_rimm_operand" "KA,r"))) | |
71 ] | |
72 "" | |
73 "add.l %0,%1,%2") | |
74 | |
75 (define_insn "subsi3" | |
76 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
77 (minus:SI | |
78 (match_operand:SI 1 "register_operand" "r,r") | |
79 (match_operand:SI 2 "ft32_rimm_operand" "KA,r")))] | |
80 "" | |
81 "sub.l %0,%1,%2") | |
82 | |
83 (define_insn "mulsi3" | |
84 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
85 (mult:SI | |
86 (match_operand:SI 1 "register_operand" "r,r") | |
87 (match_operand:SI 2 "ft32_rimm_operand" "KA,r")))] | |
88 "" | |
89 "mul.l %0,%1,%2") | |
90 | |
91 (define_insn "umulsidi3" | |
92 [(set (match_operand:DI 0 "register_operand" "=r,r") | |
93 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
94 (zero_extend:DI (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))) | |
95 (clobber (reg:CC CC_REG))] | |
96 "" | |
97 "mul.l $cc,%1,%2\;muluh.l %h0,%1,%2\;move.l %0,$cc") | |
98 | |
99 (define_insn "divsi3" | |
100 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
101 (div:SI | |
102 (match_operand:SI 1 "register_operand" "r,r") | |
103 (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))] | |
104 "!TARGET_NODIV" | |
105 "div.l %0,%1,%2") | |
106 | |
107 (define_insn "modsi3" | |
108 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
109 (mod:SI | |
110 (match_operand:SI 1 "register_operand" "r,r") | |
111 (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))] | |
112 "!TARGET_NODIV" | |
113 "mod.l %0,%1,%2") | |
114 | |
115 (define_insn "udivsi3" | |
116 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
117 (udiv:SI | |
118 (match_operand:SI 1 "register_operand" "r,r") | |
119 (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))] | |
120 "!TARGET_NODIV" | |
121 "udiv.l %0,%1,%2") | |
122 | |
123 (define_insn "umodsi3" | |
124 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
125 (umod:SI | |
126 (match_operand:SI 1 "register_operand" "r,r") | |
127 (match_operand:SI 2 "register_operand" "r,KA")))] | |
128 "!TARGET_NODIV" | |
129 "umod.l %0,%1,%2") | |
130 | |
131 (define_insn "extvsi" | |
132 [(set (match_operand:SI 0 "register_operand" "=r") | |
133 (sign_extract:SI (match_operand:SI 1 "register_operand" "r") | |
134 (match_operand:SI 2 "ft32_bwidth_operand" "b") | |
135 (match_operand:SI 3 "const_int_operand" "i")))] | |
136 "" | |
137 "bexts.l %0,%1,((15 & %2) << 5) | (%3)") | |
138 | |
139 (define_insn "extzvsi" | |
140 [(set (match_operand:SI 0 "register_operand" "=r") | |
141 (zero_extract:SI (match_operand:SI 1 "register_operand" "r") | |
142 (match_operand:SI 2 "ft32_bwidth_operand" "b") | |
143 (match_operand:SI 3 "const_int_operand" "i")))] | |
144 "" | |
145 "bextu.l %0,%1,((15 & %2) << 5) | (%3)") | |
146 | |
147 (define_insn "insvsi" | |
148 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r") | |
149 (match_operand:SI 1 "ft32_bwidth_operand" "b,b") | |
150 (match_operand:SI 2 "const_int_operand" "i,i")) | |
151 (match_operand:SI 3 "general_operand" "r,O")) | |
152 (clobber (match_scratch:SI 4 "=&r,r"))] | |
153 "" | |
154 { | |
155 if (which_alternative == 0) | |
156 { | |
157 return \"ldl.l %4,%3,((%1&15)<<5)|(%2)\;bins.l %0,%0,%4\"; | |
158 } | |
159 else | |
160 { | |
161 if ((INTVAL(operands[3]) == 0) || (INTVAL(operands[1]) == 1)) | |
162 return \"bins.l %0,%0,(%3<<9)|((%1&15)<<5)|(%2)\"; | |
163 else | |
164 return \"ldk.l %4,(%3<<10)|((%1&15)<<5)|(%2)\;bins.l %0,%0,%4\"; | |
165 } | |
166 }) | |
167 | |
168 ;; ------------------------------------------------------------------------- | |
169 ;; Unary arithmetic instructions | |
170 ;; ------------------------------------------------------------------------- | |
171 | |
172 (define_insn "one_cmplsi2" | |
173 [(set (match_operand:SI 0 "register_operand" "=r") | |
174 (not:SI (match_operand:SI 1 "register_operand" "r")))] | |
175 "" | |
176 "xor.l %0,%1,-1") | |
177 | |
178 ;; ------------------------------------------------------------------------- | |
179 ;; Logical operators | |
180 ;; ------------------------------------------------------------------------- | |
181 | |
182 (define_insn "andsi3" | |
183 [(set (match_operand:SI 0 "register_operand" "=r,r,r") | |
184 (and:SI (match_operand:SI 1 "register_operand" "r,r,r") | |
185 (match_operand:SI 2 "general_operand" "r,x,KA")))] | |
186 "" | |
187 "@ | |
188 and.l %0,%1,%2 | |
189 bins.l %0,%1,%g2 | |
190 and.l %0,%1,%2") | |
191 | |
192 (define_insn "andqi3" | |
193 [(set (match_operand:QI 0 "register_operand" "=r,r,r") | |
194 (and:QI (match_operand:QI 1 "register_operand" "r,r,r") | |
195 (match_operand:QI 2 "general_operand" "r,x,KA")))] | |
196 "" | |
197 "@ | |
198 and.b %0,%1,%2 | |
199 bins.b %0,%1,%g2 | |
200 and.b %0,%1,%2") | |
201 | |
202 (define_insn "xorsi3" | |
203 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
204 (xor:SI (match_operand:SI 1 "register_operand" "r,r") | |
205 (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))] | |
206 "" | |
207 { | |
208 return "xor.l %0,%1,%2"; | |
209 }) | |
210 | |
211 (define_insn "iorsi3" | |
212 [(set (match_operand:SI 0 "register_operand" "=r,r,r") | |
213 (ior:SI (match_operand:SI 1 "register_operand" "r,r,r") | |
214 (match_operand:SI 2 "general_operand" "r,w,KA")))] | |
215 "" | |
216 "@ | |
217 or.l %0,%1,%2 | |
218 bins.l %0,%1,%f2 | |
219 or.l %0,%1,%2") | |
220 | |
221 ;; ------------------------------------------------------------------------- | |
222 ;; Shifters | |
223 ;; ------------------------------------------------------------------------- | |
224 | |
225 (define_insn "ashlsi3" | |
226 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
227 (ashift:SI (match_operand:SI 1 "register_operand" "r,r") | |
228 (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))] | |
229 "" | |
230 { | |
231 return "ashl.l %0,%1,%2"; | |
232 }) | |
233 | |
234 (define_insn "ashrsi3" | |
235 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
236 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r") | |
237 (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))] | |
238 "" | |
239 { | |
240 return "ashr.l %0,%1,%2"; | |
241 }) | |
242 | |
243 (define_insn "lshrsi3" | |
244 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
245 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r") | |
246 (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))] | |
247 "" | |
248 { | |
249 return "lshr.l %0,%1,%2"; | |
250 }) | |
251 | |
252 ;; ------------------------------------------------------------------------- | |
253 ;; Move instructions | |
254 ;; ------------------------------------------------------------------------- | |
255 | |
256 ;; SImode | |
257 | |
258 (define_insn "*sne" | |
259 [(set (match_operand:SI 0 "register_operand" "=r") | |
260 (reg:SI CC_REG))] | |
261 "" | |
262 "bextu.l %0,$cc,32|0\;xor.l %0,%0,-1" | |
263 ) | |
264 | |
265 ;; Push a register onto the stack | |
266 (define_insn "movsi_push" | |
267 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) | |
268 (match_operand:SI 0 "register_operand" "r"))] | |
269 "" | |
270 "push.l %0") | |
271 | |
272 ;; Pop a register from the stack | |
273 (define_insn "movsi_pop" | |
274 [(set (match_operand:SI 0 "register_operand" "=r") | |
275 (mem:SI (post_inc:SI (reg:SI SP_REG))))] | |
276 "" | |
277 "pop.l %0") | |
278 | |
279 (define_expand "movsi" | |
280 [(set (match_operand:SI 0 "general_operand" "") | |
281 (match_operand:SI 1 "general_operand" ""))] | |
282 "" | |
283 { | |
284 /* If this is a store, force the value into a register. */ | |
285 if (!(reload_in_progress || reload_completed)) | |
286 { | |
287 if (MEM_P (operands[0])) | |
288 { | |
289 operands[1] = force_reg (SImode, operands[1]); | |
290 if (MEM_P (XEXP (operands[0], 0))) | |
291 operands[0] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[0], 0))); | |
292 } | |
293 else | |
294 { | |
295 if (MEM_P (operands[1]) && MEM_P (XEXP (operands[1], 0))) | |
296 operands[1] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[1], 0))); | |
297 } | |
298 /* | |
299 if (MEM_P (operands[0])) { | |
300 rtx o = XEXP (operands[0], 0); | |
301 if (!REG_P(o) && | |
302 !CONST_INT_P(o) && | |
303 GET_CODE(o) != SYMBOL_REF && | |
304 GET_CODE(o) != LABEL_REF) { | |
305 operands[0] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[0], 0))); | |
306 } | |
307 } | |
308 */ | |
309 } | |
310 }) | |
311 | |
312 (define_insn "*rtestsi" | |
313 [(set (reg:SI CC_REG) | |
314 (match_operand:SI 0 "register_operand" "r"))] | |
315 "" | |
316 "cmp.l %0,0" | |
317 ) | |
318 | |
319 (define_insn "*rtestqi" | |
320 [(set (reg:QI CC_REG) | |
321 (match_operand:QI 0 "register_operand" "r"))] | |
322 "" | |
323 "cmp.b %0,0" | |
324 ) | |
325 | |
326 (define_insn "*movsi" | |
327 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,BW,r,r,r,r,A,r,r") | |
328 (match_operand:SI 1 "ft32_general_movsrc_operand" "r,r,BW,A,S,i,r,e,f"))] | |
329 "register_operand (operands[0], SImode) || register_operand (operands[1], SImode)" | |
330 "@ | |
331 move.l %0,%1 | |
332 sti.l %0,%1 | |
333 ldi.l %0,%1 | |
334 lda.l %0,%1 | |
335 ldk.l %0,%1 | |
336 *return ft32_load_immediate(operands[0], INTVAL(operands[1])); | |
337 sta.l %0,%1 | |
338 lpm.l %0,%1 | |
339 lpmi.l %0,%1" | |
340 ) | |
341 | |
342 (define_expand "movqi" | |
343 [(set (match_operand:QI 0 "general_operand" "") | |
344 (match_operand:QI 1 "general_operand" ""))] | |
345 "" | |
346 { | |
347 /* If this is a store, force the value into a register. */ | |
348 if (!(reload_in_progress || reload_completed)) | |
349 { | |
350 if (MEM_P (operands[0])) | |
351 { | |
352 operands[1] = force_reg (QImode, operands[1]); | |
353 if (MEM_P (XEXP (operands[0], 0))) | |
354 operands[0] = gen_rtx_MEM (QImode, force_reg (SImode, XEXP (operands[0], 0))); | |
355 } | |
356 else | |
357 { | |
358 if (MEM_P (operands[1]) && MEM_P (XEXP (operands[1], 0))) | |
359 operands[1] = gen_rtx_MEM (QImode, force_reg (SImode, XEXP (operands[1], 0))); | |
360 } | |
361 if (MEM_P (operands[0]) && !REG_P(XEXP (operands[0], 0))) | |
362 { | |
363 operands[0] = gen_rtx_MEM (QImode, force_reg (SImode, XEXP (operands[0], 0))); | |
364 } | |
365 } | |
366 }) | |
367 | |
368 (define_insn "zero_extendqisi2" | |
369 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r") | |
370 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "BW,r,f")))] | |
371 "" | |
372 "@ | |
373 ldi.b %0,%1 | |
374 and.l %0,%1,255 | |
375 lpmi.b %0,%1" | |
376 ) | |
377 | |
378 (define_insn "extendqisi2" | |
379 [(set (match_operand:SI 0 "nonimmediate_operand" "=r") | |
380 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r")))] | |
381 "" | |
382 "bexts.l %0,%1,(8<<5)|0" | |
383 ) | |
384 | |
385 (define_insn "zero_extendhisi2" | |
386 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r") | |
387 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "BW,r,f")))] | |
388 "" | |
389 "@ | |
390 ldi.s %0,%1 | |
391 bextu.l %0,%1,(0<<5)|0 | |
392 lpmi.s %0,%1" | |
393 ) | |
394 | |
395 (define_insn "extendhisi2" | |
396 [(set (match_operand:SI 0 "nonimmediate_operand" "=r") | |
397 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))] | |
398 "" | |
399 "bexts.l %0,%1,(0<<5)|0" | |
400 ) | |
401 | |
402 (define_insn "*movqi" | |
403 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,BW,r,r,A,r,r,r") | |
404 (match_operand:QI 1 "ft32_general_movsrc_operand" "r,r,BW,A,r,I,e,f"))] | |
405 "register_operand (operands[0], QImode) | |
406 || register_operand (operands[1], QImode)" | |
407 "@ | |
408 move.b %0,%1 | |
409 sti.b %0,%1 | |
410 ldi.b %0,%1 | |
411 lda.b %0,%1 | |
412 sta.b %0,%1 | |
413 ldk.b %0,%1 | |
414 lpm.b %0,%1 | |
415 lpmi.b %0,%1" | |
416 ) | |
417 | |
418 (define_expand "movhi" | |
419 [(set (match_operand:HI 0 "general_operand" "") | |
420 (match_operand:HI 1 "general_operand" ""))] | |
421 "" | |
422 { | |
423 /* If this is a store, force the value into a register. */ | |
424 if (!(reload_in_progress || reload_completed)) | |
425 { | |
426 if (MEM_P (operands[0])) | |
427 { | |
428 operands[1] = force_reg (HImode, operands[1]); | |
429 if (MEM_P (XEXP (operands[0], 0))) | |
430 operands[0] = gen_rtx_MEM (HImode, force_reg (SImode, XEXP (operands[0], 0))); | |
431 } | |
432 else | |
433 { | |
434 if (MEM_P (operands[1]) && MEM_P (XEXP (operands[1], 0))) | |
435 operands[1] = gen_rtx_MEM (HImode, force_reg (SImode, XEXP (operands[1], 0))); | |
436 } | |
437 if (MEM_P (operands[0])) | |
438 { | |
439 rtx o = XEXP (operands[0], 0); | |
440 if (!REG_P(o) && | |
441 !CONST_INT_P(o) && | |
442 GET_CODE(o) != SYMBOL_REF && | |
443 GET_CODE(o) != LABEL_REF) { | |
444 operands[0] = gen_rtx_MEM (HImode, force_reg (SImode, XEXP (operands[0], 0))); | |
445 } | |
446 } | |
447 } | |
448 }) | |
449 | |
450 (define_insn "*movhi" | |
451 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,BW,r,r,A,r,r,r") | |
452 (match_operand:HI 1 "ft32_general_movsrc_operand" "r,r,BW,A,r,I,e,f"))] | |
453 "(register_operand (operands[0], HImode) | |
454 || register_operand (operands[1], HImode))" | |
455 "@ | |
456 move.s %0,%1 | |
457 sti.s %0,%1 | |
458 ldi.s %0,%1 | |
459 lda.s %0,%1 | |
460 sta.s %0,%1 | |
461 ldk.s %0,%1 | |
462 lpm.s %0,%1 | |
463 lpmi.s %0,%1" | |
464 ) | |
465 | |
466 (define_expand "movsf" | |
467 [(set (match_operand:SF 0 "general_operand" "") | |
468 (match_operand:SF 1 "general_operand" ""))] | |
469 "" | |
470 { | |
471 /* If this is a store, force the value into a register. */ | |
472 if (MEM_P (operands[0])) | |
473 operands[1] = force_reg (SFmode, operands[1]); | |
474 if (CONST_DOUBLE_P(operands[1])) | |
475 operands[1] = force_const_mem(SFmode, operands[1]); | |
476 }) | |
477 | |
478 (define_insn "*movsf" | |
479 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,BW,r,r,A,r,r") | |
480 (match_operand:SF 1 "ft32_general_movsrc_operand" "r,r,BW,A,r,I,f"))] | |
481 "(register_operand (operands[0], SFmode) | |
482 || register_operand (operands[1], SFmode))" | |
483 "@ | |
484 move.l %0,%1 | |
485 sti.l %0,%1 | |
486 ldi.l %0,%1 | |
487 lda.l %0,%1 | |
488 sta.l %0,%1 | |
489 ldk.l %0,%1 | |
490 lpmi.l %0,%1" | |
491 ) | |
492 | |
493 ;; ------------------------------------------------------------------------- | |
494 ;; Compare instructions | |
495 ;; ------------------------------------------------------------------------- | |
496 | |
497 (define_expand "cbranchsi4" | |
498 [(set (reg:CC CC_REG) | |
499 (compare:CC | |
500 (match_operand:SI 1 "register_operand" "") | |
501 (match_operand:SI 2 "ft32_rimm_operand" ""))) | |
502 (set (pc) | |
503 (if_then_else (match_operator 0 "comparison_operator" | |
504 [(reg:CC CC_REG) (const_int 0)]) | |
505 (label_ref (match_operand 3 "" "")) | |
506 (pc)))] | |
507 "" | |
508 "") | |
509 | |
510 (define_insn "cmpsi" | |
511 [(set (reg:CC CC_REG) | |
512 (compare:CC | |
513 (match_operand:SI 0 "register_operand" "r,r") | |
514 (match_operand:SI 1 "ft32_rimm_operand" "r,KA")))] | |
515 "" | |
516 "cmp.l %0,%1") | |
517 | |
518 (define_insn "" | |
519 [(set (pc) | |
520 (if_then_else | |
521 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r") | |
522 (const_int 1) | |
523 (match_operand:SI 1 "const_int_operand" "i")) | |
524 (const_int 0)) | |
525 (label_ref (match_operand 2 "" "")) | |
526 (pc))) | |
527 (clobber (reg:CC CC_REG))] | |
528 "" | |
529 "btst.l %0,(1<<5)|%1\;jmpc nz,%l2") | |
530 | |
531 (define_insn "" | |
532 [(set (pc) | |
533 (if_then_else | |
534 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r") | |
535 (const_int 1) | |
536 (match_operand:SI 1 "const_int_operand" "i")) | |
537 (const_int 0)) | |
538 (label_ref (match_operand 2 "" "")) | |
539 (pc))) | |
540 (clobber (reg:CC CC_REG))] | |
541 "" | |
542 "btst.l %0,(1<<5)|%1\;jmpc z,%l2") | |
543 | |
544 (define_expand "cbranchqi4" | |
545 [(set (reg:CC CC_REG) | |
546 (compare:CC | |
547 (match_operand:QI 1 "register_operand" "") | |
548 (match_operand:QI 2 "ft32_rimm_operand" ""))) | |
549 (set (pc) | |
550 (if_then_else (match_operator 0 "comparison_operator" | |
551 [(reg:CC CC_REG) (const_int 0)]) | |
552 (label_ref (match_operand 3 "" "")) | |
553 (pc)))] | |
554 "" | |
555 "") | |
556 | |
557 (define_insn "*cmpqi" | |
558 [(set (reg:CC CC_REG) | |
559 (compare:CC | |
560 (match_operand:QI 0 "register_operand" "r,r") | |
561 (match_operand:QI 1 "ft32_rimm_operand" "r,KA")))] | |
562 "" | |
563 "cmp.b %0,%1") | |
564 | |
565 ;; ------------------------------------------------------------------------- | |
566 ;; Branch instructions | |
567 ;; ------------------------------------------------------------------------- | |
568 | |
569 (define_code_iterator cond [ne eq lt ltu gt gtu ge le geu leu]) | |
570 (define_code_attr CC [(ne "nz") (eq "z") (lt "lt") (ltu "b") | |
571 (gt "gt") (gtu "a") (ge "gte") (le "lte") | |
572 (geu "ae") (leu "be") ]) | |
573 (define_code_attr rCC [(ne "z") (eq "nz") (lt "gte") (ltu "ae") | |
574 (gt "lte") (gtu "be") (ge "lt") (le "gt") | |
575 (geu "b") (leu "a") ]) | |
576 | |
577 (define_insn "*b<cond:code>" | |
578 [(set (pc) | |
579 (if_then_else (cond (reg:CC CC_REG) | |
580 (const_int 0)) | |
581 (label_ref (match_operand 0 "" "")) | |
582 (pc)))] | |
583 "" | |
584 { | |
585 return "jmpc <CC>,%l0"; | |
586 } | |
587 ) | |
588 | |
589 (define_expand "cstoresi4" | |
590 [(set (reg:CC CC_REG) | |
591 (compare:CC (match_operand:SI 2 "register_operand" "r,r") | |
592 (match_operand:SI 3 "ft32_rimm_operand" "r,KA"))) | |
593 (set (match_operand:SI 0 "register_operand") | |
594 (match_operator:SI 1 "ordered_comparison_operator" | |
595 [(reg:CC CC_REG) (const_int 0)]))] | |
596 "" | |
597 { | |
598 rtx test; | |
599 | |
600 switch (GET_CODE (operands[1])) { | |
601 case NE: | |
602 case GEU: | |
603 case LT: | |
604 case LE: | |
605 case LEU: | |
606 test = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])), | |
607 SImode, operands[2], operands[3]); | |
608 emit_insn(gen_cstoresi4(operands[0], test, operands[2], operands[3])); | |
609 emit_insn(gen_xorsi3(operands[0], operands[0], gen_int_mode(1, SImode))); | |
610 DONE; | |
611 default: | |
612 ; | |
613 } | |
614 }) | |
615 | |
616 (define_insn "*seq" | |
617 [(set (match_operand:SI 0 "register_operand" "=r") | |
618 (eq:SI (reg CC_REG) (const_int 0)))] | |
619 "" | |
620 "bextu.l %0,$cc,32|0" | |
621 ) | |
622 | |
623 (define_insn "*sltu" | |
624 [(set (match_operand:SI 0 "register_operand" "=r") | |
625 (ltu:SI (reg CC_REG) (const_int 0)))] | |
626 "" | |
627 "bextu.l %0,$cc,32|1" | |
628 ) | |
629 | |
630 (define_insn "*sge" | |
631 [(set (match_operand:SI 0 "register_operand" "=r") | |
632 (ge:SI (reg CC_REG) (const_int 0)))] | |
633 "" | |
634 "bextu.l %0,$cc,32|4" | |
635 ) | |
636 | |
637 (define_insn "*sgt" | |
638 [(set (match_operand:SI 0 "register_operand" "=r") | |
639 (gt:SI (reg CC_REG) (const_int 0)))] | |
640 "" | |
641 "bextu.l %0,$cc,32|5" | |
642 ) | |
643 | |
644 (define_insn "*sgtu" | |
645 [(set (match_operand:SI 0 "register_operand" "=r") | |
646 (gtu:SI (reg CC_REG) (const_int 0)))] | |
647 "" | |
648 "bextu.l %0,$cc,32|6" | |
649 ) | |
650 | |
651 ;; ------------------------------------------------------------------------- | |
652 ;; Call and Jump instructions | |
653 ;; ------------------------------------------------------------------------- | |
654 | |
655 (define_expand "call" | |
656 [(call (match_operand:QI 0 "memory_operand" "") | |
657 (match_operand 1 "general_operand" ""))] | |
658 "" | |
659 { | |
660 gcc_assert (MEM_P (operands[0])); | |
661 }) | |
662 | |
663 (define_insn "*call" | |
664 [(call (mem:QI (match_operand:SI | |
665 0 "nonmemory_operand" "i,r")) | |
666 (match_operand 1 "" ""))] | |
667 "" | |
668 "@ | |
669 call %0 | |
670 calli %0" | |
671 ) | |
672 | |
673 (define_expand "call_value" | |
674 [(set (match_operand 0 "" "") | |
675 (call (match_operand:QI 1 "memory_operand" "") | |
676 (match_operand 2 "" "")))] | |
677 "" | |
678 { | |
679 gcc_assert (MEM_P (operands[1])); | |
680 }) | |
681 | |
682 (define_insn "*call_value" | |
683 [(set (match_operand 0 "register_operand" "=r") | |
684 (call (mem:QI (match_operand:SI | |
685 1 "immediate_operand" "i")) | |
686 (match_operand 2 "" "")))] | |
687 "" | |
688 "call %1" | |
689 ) | |
690 | |
691 (define_insn "*call_value_indirect" | |
692 [(set (match_operand 0 "register_operand" "=r") | |
693 (call (mem:QI (match_operand:SI | |
694 1 "register_operand" "r")) | |
695 (match_operand 2 "" "")))] | |
696 "" | |
697 "calli %1" | |
698 ) | |
699 | |
700 (define_insn "indirect_jump" | |
701 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "r"))] | |
702 "" | |
703 "jmpi %0") | |
704 | |
705 (define_insn "jump" | |
706 [(set (pc) | |
707 (label_ref (match_operand 0 "" "")))] | |
708 "" | |
709 "jmp %l0" | |
710 ) | |
711 | |
712 (define_insn "call_prolog" | |
713 [(unspec:SI [(match_operand 0 "" "")] | |
714 UNSPEC_JMP_PROLOG)] | |
715 "" | |
716 "call __prolog_%0" | |
717 ) | |
718 | |
719 (define_insn "jump_epilog" | |
720 [(unspec:SI [(match_operand 0 "" "")] | |
721 UNSPEC_JMP_EPILOG)] | |
722 "" | |
723 "jmp __epilog_%0" | |
724 ) | |
725 | |
726 (define_insn "jump_epilog24" | |
727 [(unspec:SI [(match_operand 0 "" "")] | |
728 UNSPEC_JMP_EPILOG24)] | |
729 "" | |
730 "jmp __epilog24_%0" | |
731 ) | |
732 | |
733 | |
734 ;; Subroutines of "casesi". | |
735 ;; operand 0 is index | |
736 ;; operand 1 is the minimum bound | |
737 ;; operand 2 is the maximum bound - minimum bound + 1 | |
738 ;; operand 3 is CODE_LABEL for the table; | |
739 ;; operand 4 is the CODE_LABEL to go to if index out of range. | |
740 | |
741 (define_expand "casesi" | |
742 [(match_operand:SI 0 "general_operand" "") | |
743 (match_operand:SI 1 "const_int_operand" "") | |
744 (match_operand:SI 2 "const_int_operand" "") | |
745 (match_operand 3 "" "") | |
746 (match_operand 4 "" "")] | |
747 "" | |
748 " | |
749 { | |
750 if (GET_CODE (operands[0]) != REG) | |
751 operands[0] = force_reg (SImode, operands[0]); | |
752 | |
753 if (operands[1] != const0_rtx) | |
754 { | |
755 rtx index = gen_reg_rtx (SImode); | |
756 rtx offset = gen_reg_rtx (SImode); | |
757 | |
758 emit_insn (gen_movsi (offset, operands[1])); | |
759 emit_insn (gen_subsi3 (index, operands[0], offset)); | |
760 operands[0] = index; | |
761 } | |
762 | |
763 { | |
764 rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]); | |
765 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4])); | |
766 } | |
767 | |
768 emit_jump_insn (gen_casesi0 (operands[0], operands[3])); | |
769 DONE; | |
770 }") | |
771 | |
772 (define_insn "casesi0" | |
773 [(set (pc) (mem:SI (plus:SI | |
774 (mult:SI (match_operand:SI 0 "register_operand" "r") | |
775 (const_int 4)) | |
776 (label_ref (match_operand 1 "" ""))))) | |
777 (clobber (match_scratch:SI 2 "=&r")) | |
778 ] | |
779 "" | |
780 "ldk.l\t$cc,%l1\;ashl.l\t%2,%0,2\;add.l\t%2,%2,$cc\;jmpi\t%2" | |
781 ) | |
782 | |
783 ;; ------------------------------------------------------------------------- | |
784 ;; Atomic exchange instruction | |
785 ;; ------------------------------------------------------------------------- | |
786 | |
787 (define_insn "atomic_exchangesi" | |
788 [(set (match_operand:SI 0 "register_operand" "=&r,r") ;; output | |
789 (match_operand:SI 1 "memory_operand" "+BW,A")) ;; memory | |
790 (set (match_dup 1) | |
791 (unspec:SI | |
792 [(match_operand:SI 2 "register_operand" "0,0") ;; input | |
793 (match_operand:SI 3 "const_int_operand")] ;; model | |
794 UNSPEC_XCHG))] | |
795 "" | |
796 "@ | |
797 exi.l %0,%1 | |
798 exa.l %0,%1") | |
799 | |
800 (define_insn "atomic_exchangehi" | |
801 [(set (match_operand:HI 0 "register_operand" "=&r,r") ;; output | |
802 (match_operand:HI 1 "memory_operand" "+BW,A")) ;; memory | |
803 (set (match_dup 1) | |
804 (unspec:HI | |
805 [(match_operand:HI 2 "register_operand" "0,0") ;; input | |
806 (match_operand:HI 3 "const_int_operand")] ;; model | |
807 UNSPEC_XCHG))] | |
808 "" | |
809 "@ | |
810 exi.s %0,%1 | |
811 exa.s %0,%1") | |
812 | |
813 (define_insn "atomic_exchangeqi" | |
814 [(set (match_operand:QI 0 "register_operand" "=&r,r") ;; output | |
815 (match_operand:QI 1 "memory_operand" "+BW,A")) ;; memory | |
816 (set (match_dup 1) | |
817 (unspec:QI | |
818 [(match_operand:QI 2 "register_operand" "0,0") ;; input | |
819 (match_operand:QI 3 "const_int_operand")] ;; model | |
820 UNSPEC_XCHG))] | |
821 "" | |
822 "@ | |
823 exi.b %0,%1 | |
824 exa.b %0,%1") | |
825 | |
826 ;; ------------------------------------------------------------------------- | |
827 ;; String instructions | |
828 ;; ------------------------------------------------------------------------- | |
829 | |
830 (define_insn "cmpstrsi" | |
831 [(set (match_operand:SI 0 "register_operand" "=r,r") | |
832 (compare:SI (match_operand:BLK 1 "memory_operand" "W,BW") | |
833 (match_operand:BLK 2 "memory_operand" "W,BW"))) | |
834 (clobber (match_operand:SI 3)) | |
835 ] | |
836 "" | |
837 "strcmp.%d3 %0,%b1,%b2" | |
838 ) | |
839 | |
840 (define_insn "movstr" | |
841 [(set (match_operand:BLK 1 "memory_operand" "=W") | |
842 (match_operand:BLK 2 "memory_operand" "W")) | |
843 (use (match_operand:SI 0)) | |
844 (clobber (match_dup 0)) | |
845 ] | |
846 "0" | |
847 "stpcpy %b1,%b2 # %0 %b1 %b2" | |
848 ) | |
849 | |
850 (define_insn "movmemsi" | |
851 [(set (match_operand:BLK 0 "memory_operand" "=W,BW") | |
852 (match_operand:BLK 1 "memory_operand" "W,BW")) | |
853 (use (match_operand:SI 2 "ft32_imm_operand" "KA,KA")) | |
854 (use (match_operand:SI 3)) | |
855 ] | |
856 "" | |
857 "memcpy.%d3 %b0,%b1,%2 " | |
858 ) | |
859 | |
860 (define_insn "setmemsi" | |
861 [(set (match_operand:BLK 0 "memory_operand" "=BW") (unspec:BLK [ | |
862 (use (match_operand:QI 2 "register_operand" "r")) | |
863 (use (match_operand:SI 1 "ft32_imm_operand" "KA")) | |
864 ] UNSPEC_SETMEM)) | |
865 (use (match_operand:SI 3)) | |
866 ] | |
867 "" | |
868 "memset.%d3 %b0,%2,%1" | |
869 ) | |
870 | |
871 (define_insn "strlensi" | |
872 [(set (match_operand:SI 0 "register_operand" "=r") | |
873 (unspec:SI [(match_operand:BLK 1 "memory_operand" "W") | |
874 (match_operand:QI 2 "const_int_operand" "") | |
875 (match_operand:SI 3 "ft32_rimm_operand" "")] | |
876 UNSPEC_STRLEN))] | |
877 "" | |
878 "strlen.%d3 %0,%b1 # %2 %3" | |
879 ) | |
880 | |
881 ;; ------------------------------------------------------------------------- | |
882 ;; Prologue & Epilogue | |
883 ;; ------------------------------------------------------------------------- | |
884 | |
885 (define_expand "prologue" | |
886 [(clobber (const_int 0))] | |
887 "" | |
888 { | |
889 extern void ft32_expand_prologue(); | |
890 ft32_expand_prologue (); | |
891 DONE; | |
892 }) | |
893 | |
894 | |
895 (define_expand "epilogue" | |
896 [(return)] | |
897 "" | |
898 { | |
899 extern void ft32_expand_epilogue(); | |
900 ft32_expand_epilogue (); | |
901 DONE; | |
902 }) | |
903 | |
904 (define_insn "link" | |
905 [ | |
906 ;; (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) | |
907 ;; (reg:SI FP_REG)) | |
908 (set (match_operand:SI 0) | |
909 (reg:SI SP_REG)) | |
910 (set (reg:SI SP_REG) | |
911 (plus:SI (reg:SI SP_REG) | |
912 (match_operand:SI 1 "general_operand" "L")))] | |
913 "" | |
914 "link %0,%m1" | |
915 ) | |
916 | |
917 (define_insn "unlink" | |
918 [(set (reg:SI FP_REG) | |
919 (mem:SI (reg:SI FP_REG))) | |
920 (set (reg:SI SP_REG) | |
921 (plus:SI (reg:SI FP_REG) | |
922 (const_int 4)))] | |
923 "" | |
924 "unlink $r29" | |
925 ) | |
926 | |
927 (define_insn "returner" | |
928 [(return)] | |
929 "reload_completed" | |
930 "return") | |
931 | |
932 (define_insn "pretend_returner" | |
933 [(set (reg:SI SP_REG) | |
934 (plus:SI (reg:SI SP_REG) | |
935 (match_operand:SI 0))) | |
936 (return)] | |
937 "reload_completed" | |
938 "pop.l $cc\;add.l $sp,$sp,%0\;jmpi $cc") | |
939 | |
940 (define_insn "returner24" | |
941 [ | |
942 (set (reg:SI SP_REG) | |
943 (plus:SI | |
944 (reg:SI SP_REG) | |
945 (const_int 24))) | |
946 (return)] | |
947 "" | |
948 "jmp __epilog24") |