]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/lm32/lm32.md
Update copyright years in gcc/
[thirdparty/gcc.git] / gcc / config / lm32 / lm32.md
1 ;; Machine description of the Lattice Mico32 architecture for GNU C compiler.
2 ;; Contributed by Jon Beniston <jon@beniston.com>
3
4 ;; Copyright (C) 2009-2013 Free Software Foundation, Inc.
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 ;; Include predicate and constraint definitions
23 (include "predicates.md")
24 (include "constraints.md")
25
26
27 ;; Register numbers
28 (define_constants
29 [(RA_REGNUM 29) ; return address register.
30 ]
31 )
32
33 ;; LM32 specific volatile operations
34 (define_constants
35 [(UNSPECV_BLOCKAGE 1)] ; prevent scheduling across pro/epilog boundaries
36 )
37
38 ;; LM32 specific operations
39 (define_constants
40 [(UNSPEC_GOT 2)
41 (UNSPEC_GOTOFF_HI16 3)
42 (UNSPEC_GOTOFF_LO16 4)]
43 )
44
45 ;; ---------------------------------
46 ;; instruction types
47 ;; ---------------------------------
48
49 (define_attr "type"
50 "unknown,load,store,arith,compare,shift,multiply,divide,call,icall,ubranch,uibranch,cbranch"
51 (const_string "unknown"))
52
53 ;; ---------------------------------
54 ;; instruction lengths
55 ;; ---------------------------------
56
57 ; All instructions are 4 bytes
58 ; Except for branches that are out of range, and have to be implemented
59 ; as two instructions
60 (define_attr "length" ""
61 (cond [
62 (eq_attr "type" "cbranch")
63 (if_then_else
64 (lt (abs (minus (match_dup 2) (pc)))
65 (const_int 32768)
66 )
67 (const_int 4)
68 (const_int 8)
69 )
70 ]
71 (const_int 4))
72 )
73
74 ;; ---------------------------------
75 ;; scheduling
76 ;; ---------------------------------
77
78 (define_automaton "lm32")
79
80 (define_cpu_unit "x" "lm32")
81 (define_cpu_unit "m" "lm32")
82 (define_cpu_unit "w" "lm32")
83
84 (define_insn_reservation "singlecycle" 1
85 (eq_attr "type" "store,arith,call,icall,ubranch,uibranch,cbranch")
86 "x")
87
88 (define_insn_reservation "twocycle" 2
89 (eq_attr "type" "compare,shift,divide")
90 "x,m")
91
92 (define_insn_reservation "threecycle" 3
93 (eq_attr "type" "load,multiply")
94 "x,m,w")
95
96 ;; ---------------------------------
97 ;; mov
98 ;; ---------------------------------
99
100 (define_expand "movqi"
101 [(set (match_operand:QI 0 "general_operand" "")
102 (match_operand:QI 1 "general_operand" ""))]
103 ""
104 "
105 {
106 if (can_create_pseudo_p ())
107 {
108 if (GET_CODE (operand0) == MEM)
109 {
110 /* Source operand for store must be in a register. */
111 operands[1] = force_reg (QImode, operands[1]);
112 }
113 }
114 }")
115
116 (define_expand "movhi"
117 [(set (match_operand:HI 0 "general_operand" "")
118 (match_operand:HI 1 "general_operand" ""))]
119 ""
120 "
121 {
122 if (can_create_pseudo_p ())
123 {
124 if (GET_CODE (operands[0]) == MEM)
125 {
126 /* Source operand for store must be in a register. */
127 operands[1] = force_reg (HImode, operands[1]);
128 }
129 }
130 }")
131
132 (define_expand "movsi"
133 [(set (match_operand:SI 0 "general_operand" "")
134 (match_operand:SI 1 "general_operand" ""))]
135 ""
136 "
137 {
138 if (can_create_pseudo_p ())
139 {
140 if (GET_CODE (operands[0]) == MEM
141 || (GET_CODE (operands[0]) == SUBREG
142 && GET_CODE (SUBREG_REG (operands[0])) == MEM))
143 {
144 /* Source operand for store must be in a register. */
145 operands[1] = force_reg (SImode, operands[1]);
146 }
147 }
148
149 if (flag_pic && symbolic_operand (operands[1], SImode))
150 {
151 if (GET_CODE (operands[1]) == LABEL_REF
152 || (GET_CODE (operands[1]) == SYMBOL_REF
153 && SYMBOL_REF_LOCAL_P (operands[1])
154 && !SYMBOL_REF_WEAK (operands[1])))
155 {
156 emit_insn (gen_movsi_gotoff_hi16 (operands[0], operands[1]));
157 emit_insn (gen_addsi3 (operands[0],
158 operands[0],
159 pic_offset_table_rtx));
160 emit_insn (gen_movsi_gotoff_lo16 (operands[0],
161 operands[0],
162 operands[1]));
163 }
164 else
165 emit_insn (gen_movsi_got (operands[0], operands[1]));
166 crtl->uses_pic_offset_table = 1;
167 DONE;
168 }
169 else if (flag_pic && GET_CODE (operands[1]) == CONST)
170 {
171 rtx op = XEXP (operands[1], 0);
172 if (GET_CODE (op) == PLUS)
173 {
174 rtx arg0 = XEXP (op, 0);
175 rtx arg1 = XEXP (op, 1);
176 if (GET_CODE (arg0) == LABEL_REF
177 || (GET_CODE (arg0) == SYMBOL_REF
178 && SYMBOL_REF_LOCAL_P (arg0)
179 && !SYMBOL_REF_WEAK (arg0)))
180 {
181 emit_insn (gen_movsi_gotoff_hi16 (operands[0], arg0));
182 emit_insn (gen_addsi3 (operands[0],
183 operands[0],
184 pic_offset_table_rtx));
185 emit_insn (gen_movsi_gotoff_lo16 (operands[0],
186 operands[0],
187 arg0));
188 }
189 else
190 emit_insn (gen_movsi_got (operands[0], arg0));
191 emit_insn (gen_addsi3 (operands[0], operands[0], arg1));
192 crtl->uses_pic_offset_table = 1;
193 DONE;
194 }
195 }
196 else if (!flag_pic && reloc_operand (operands[1], GET_MODE (operands[1])))
197 {
198 emit_insn (gen_rtx_SET (SImode, operands[0], gen_rtx_HIGH (SImode, operands[1])));
199 emit_insn (gen_rtx_SET (SImode, operands[0], gen_rtx_LO_SUM (SImode, operands[0], operands[1])));
200 DONE;
201 }
202 else if (GET_CODE (operands[1]) == CONST_INT)
203 {
204 if (!(satisfies_constraint_K (operands[1])
205 || satisfies_constraint_L (operands[1])
206 || satisfies_constraint_U (operands[1])))
207 {
208 emit_insn (gen_movsi_insn (operands[0],
209 GEN_INT (INTVAL (operands[1]) & ~0xffff)));
210 emit_insn (gen_iorsi3 (operands[0],
211 operands[0],
212 GEN_INT (INTVAL (operands[1]) & 0xffff)));
213 DONE;
214 }
215 }
216 }")
217
218 (define_expand "movmemsi"
219 [(parallel [(set (match_operand:BLK 0 "general_operand" "")
220 (match_operand:BLK 1 "general_operand" ""))
221 (use (match_operand:SI 2 "" ""))
222 (use (match_operand:SI 3 "const_int_operand" ""))])]
223 ""
224 {
225 if (!lm32_expand_block_move (operands))
226 FAIL;
227 DONE;
228 })
229
230 ;; ---------------------------------
231 ;; load/stores/moves
232 ;; ---------------------------------
233
234 (define_insn "movsi_got"
235 [(set (match_operand:SI 0 "register_operand" "=r")
236 (unspec:SI [(match_operand 1 "" "")] UNSPEC_GOT))]
237 "flag_pic"
238 "lw %0, (gp+got(%1))"
239 [(set_attr "type" "load")]
240 )
241
242 (define_insn "movsi_gotoff_hi16"
243 [(set (match_operand:SI 0 "register_operand" "=r")
244 (unspec:SI [(match_operand 1 "" "")] UNSPEC_GOTOFF_HI16))]
245 "flag_pic"
246 "orhi %0, r0, gotoffhi16(%1)"
247 [(set_attr "type" "load")]
248 )
249
250 (define_insn "movsi_gotoff_lo16"
251 [(set (match_operand:SI 0 "register_operand" "=r")
252 (unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "0")
253 (match_operand 2 "" ""))] UNSPEC_GOTOFF_LO16))]
254 "flag_pic"
255 "addi %0, %1, gotofflo16(%2)"
256 [(set_attr "type" "arith")]
257 )
258
259 (define_insn "*movsi_lo_sum"
260 [(set (match_operand:SI 0 "register_operand" "=r")
261 (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
262 (match_operand:SI 2 "reloc_operand" "i")))]
263 "!flag_pic"
264 "ori %0, %0, lo(%2)"
265 [(set_attr "type" "arith")]
266 )
267
268 (define_insn "*movqi_insn"
269 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,m,r")
270 (match_operand:QI 1 "general_operand" "m,r,r,J,n"))]
271 "lm32_move_ok (QImode, operands)"
272 "@
273 lbu %0, %1
274 or %0, %1, r0
275 sb %0, %1
276 sb %0, r0
277 addi %0, r0, %1"
278 [(set_attr "type" "load,arith,store,store,arith")]
279 )
280
281 (define_insn "*movhi_insn"
282 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,m,r,r")
283 (match_operand:HI 1 "general_operand" "m,r,r,J,K,L"))]
284 "lm32_move_ok (HImode, operands)"
285 "@
286 lhu %0, %1
287 or %0, %1, r0
288 sh %0, %1
289 sh %0, r0
290 addi %0, r0, %1
291 ori %0, r0, %1"
292 [(set_attr "type" "load,arith,store,store,arith,arith")]
293 )
294
295 (define_insn "movsi_insn"
296 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,m,r,r,r,r,r")
297 (match_operand:SI 1 "movsi_rhs_operand" "m,r,r,J,K,L,U,S,Y"))]
298 "lm32_move_ok (SImode, operands)"
299 "@
300 lw %0, %1
301 or %0, %1, r0
302 sw %0, %1
303 sw %0, r0
304 addi %0, r0, %1
305 ori %0, r0, %1
306 orhi %0, r0, hi(%1)
307 mva %0, gp(%1)
308 orhi %0, r0, hi(%1)"
309 [(set_attr "type" "load,arith,store,store,arith,arith,arith,arith,arith")]
310 )
311
312 ;; ---------------------------------
313 ;; sign and zero extension
314 ;; ---------------------------------
315
316 (define_insn "*extendqihi2"
317 [(set (match_operand:HI 0 "register_operand" "=r,r")
318 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m,r")))]
319 "TARGET_SIGN_EXTEND_ENABLED || (GET_CODE (operands[1]) != REG)"
320 "@
321 lb %0, %1
322 sextb %0, %1"
323 [(set_attr "type" "load,arith")]
324 )
325
326 (define_insn "zero_extendqihi2"
327 [(set (match_operand:HI 0 "register_operand" "=r,r")
328 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m,r")))]
329 ""
330 "@
331 lbu %0, %1
332 andi %0, %1, 0xff"
333 [(set_attr "type" "load,arith")]
334 )
335
336 (define_insn "*extendqisi2"
337 [(set (match_operand:SI 0 "register_operand" "=r,r")
338 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m,r")))]
339 "TARGET_SIGN_EXTEND_ENABLED || (GET_CODE (operands[1]) != REG)"
340 "@
341 lb %0, %1
342 sextb %0, %1"
343 [(set_attr "type" "load,arith")]
344 )
345
346 (define_insn "zero_extendqisi2"
347 [(set (match_operand:SI 0 "register_operand" "=r,r")
348 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m,r")))]
349 ""
350 "@
351 lbu %0, %1
352 andi %0, %1, 0xff"
353 [(set_attr "type" "load,arith")]
354 )
355
356 (define_insn "*extendhisi2"
357 [(set (match_operand:SI 0 "register_operand" "=r,r")
358 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
359 "TARGET_SIGN_EXTEND_ENABLED || (GET_CODE (operands[1]) != REG)"
360 "@
361 lh %0, %1
362 sexth %0, %1"
363 [(set_attr "type" "load,arith")]
364 )
365
366 (define_insn "zero_extendhisi2"
367 [(set (match_operand:SI 0 "register_operand" "=r,r")
368 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
369 ""
370 "@
371 lhu %0, %1
372 andi %0, %1, 0xffff"
373 [(set_attr "type" "load,arith")]
374 )
375
376 ;; ---------------------------------
377 ;; compare
378 ;; ---------------------------------
379
380 (define_expand "cstoresi4"
381 [(set (match_operand:SI 0 "register_operand")
382 (match_operator:SI 1 "ordered_comparison_operator"
383 [(match_operand:SI 2 "register_operand")
384 (match_operand:SI 3 "register_or_int_operand")]))]
385 ""
386 {
387 lm32_expand_scc (operands);
388 DONE;
389 })
390
391 (define_insn "*seq"
392 [(set (match_operand:SI 0 "register_operand" "=r,r")
393 (eq:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
394 (match_operand:SI 2 "register_or_K_operand" "r,K")))]
395 ""
396 "@
397 cmpe %0, %z1, %2
398 cmpei %0, %z1, %2"
399 [(set_attr "type" "compare")]
400 )
401
402 (define_insn "*sne"
403 [(set (match_operand:SI 0 "register_operand" "=r,r")
404 (ne:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
405 (match_operand:SI 2 "register_or_K_operand" "r,K")))]
406 ""
407 "@
408 cmpne %0, %z1, %2
409 cmpnei %0, %z1, %2"
410 [(set_attr "type" "compare")]
411 )
412
413 (define_insn "*sgt"
414 [(set (match_operand:SI 0 "register_operand" "=r,r")
415 (gt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
416 (match_operand:SI 2 "register_or_K_operand" "r,K")))]
417 ""
418 "@
419 cmpg %0, %z1, %2
420 cmpgi %0, %z1, %2"
421 [(set_attr "type" "compare")]
422 )
423
424 (define_insn "*sge"
425 [(set (match_operand:SI 0 "register_operand" "=r,r")
426 (ge:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
427 (match_operand:SI 2 "register_or_K_operand" "r,K")))]
428 ""
429 "@
430 cmpge %0, %z1, %2
431 cmpgei %0, %z1, %2"
432 [(set_attr "type" "compare")]
433 )
434
435 (define_insn "*sgtu"
436 [(set (match_operand:SI 0 "register_operand" "=r,r")
437 (gtu:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
438 (match_operand:SI 2 "register_or_L_operand" "r,L")))]
439 ""
440 "@
441 cmpgu %0, %z1, %2
442 cmpgui %0, %z1, %2"
443 [(set_attr "type" "compare")]
444 )
445
446 (define_insn "*sgeu"
447 [(set (match_operand:SI 0 "register_operand" "=r,r")
448 (geu:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
449 (match_operand:SI 2 "register_or_L_operand" "r,L")))]
450 ""
451 "@
452 cmpgeu %0, %z1, %2
453 cmpgeui %0, %z1, %2"
454 [(set_attr "type" "compare")]
455 )
456
457 ;; ---------------------------------
458 ;; unconditional branch
459 ;; ---------------------------------
460
461 (define_insn "jump"
462 [(set (pc) (label_ref (match_operand 0 "" "")))]
463 ""
464 "bi %0"
465 [(set_attr "type" "ubranch")]
466 )
467
468 (define_insn "indirect_jump"
469 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
470 ""
471 "b %0"
472 [(set_attr "type" "uibranch")]
473 )
474
475 ;; ---------------------------------
476 ;; conditional branch
477 ;; ---------------------------------
478
479 (define_expand "cbranchsi4"
480 [(set (pc)
481 (if_then_else (match_operator 0 "comparison_operator"
482 [(match_operand:SI 1 "register_operand")
483 (match_operand:SI 2 "nonmemory_operand")])
484 (label_ref (match_operand 3 "" ""))
485 (pc)))]
486 ""
487 "
488 {
489 lm32_expand_conditional_branch (operands);
490 DONE;
491 }")
492
493 (define_insn "*beq"
494 [(set (pc)
495 (if_then_else (eq:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
496 (match_operand:SI 1 "register_or_zero_operand" "rJ"))
497 (label_ref (match_operand 2 "" ""))
498 (pc)))]
499 ""
500 {
501 return get_attr_length (insn) == 4
502 ? "be %z0,%z1,%2"
503 : "bne %z0,%z1,8\n\tbi %2";
504 }
505 [(set_attr "type" "cbranch")])
506
507 (define_insn "*bne"
508 [(set (pc)
509 (if_then_else (ne:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
510 (match_operand:SI 1 "register_or_zero_operand" "rJ"))
511 (label_ref (match_operand 2 "" ""))
512 (pc)))]
513 ""
514 {
515 return get_attr_length (insn) == 4
516 ? "bne %z0,%z1,%2"
517 : "be %z0,%z1,8\n\tbi %2";
518 }
519 [(set_attr "type" "cbranch")])
520
521 (define_insn "*bgt"
522 [(set (pc)
523 (if_then_else (gt:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
524 (match_operand:SI 1 "register_or_zero_operand" "rJ"))
525 (label_ref (match_operand 2 "" ""))
526 (pc)))]
527 ""
528 {
529 return get_attr_length (insn) == 4
530 ? "bg %z0,%z1,%2"
531 : "bge %z1,%z0,8\n\tbi %2";
532 }
533 [(set_attr "type" "cbranch")])
534
535 (define_insn "*bge"
536 [(set (pc)
537 (if_then_else (ge:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
538 (match_operand:SI 1 "register_or_zero_operand" "rJ"))
539 (label_ref (match_operand 2 "" ""))
540 (pc)))]
541 ""
542 {
543 return get_attr_length (insn) == 4
544 ? "bge %z0,%z1,%2"
545 : "bg %z1,%z0,8\n\tbi %2";
546 }
547 [(set_attr "type" "cbranch")])
548
549 (define_insn "*bgtu"
550 [(set (pc)
551 (if_then_else (gtu:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
552 (match_operand:SI 1 "register_or_zero_operand" "rJ"))
553 (label_ref (match_operand 2 "" ""))
554 (pc)))]
555 ""
556 {
557 return get_attr_length (insn) == 4
558 ? "bgu %z0,%z1,%2"
559 : "bgeu %z1,%z0,8\n\tbi %2";
560 }
561 [(set_attr "type" "cbranch")])
562
563 (define_insn "*bgeu"
564 [(set (pc)
565 (if_then_else (geu:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
566 (match_operand:SI 1 "register_or_zero_operand" "rJ"))
567 (label_ref (match_operand 2 "" ""))
568 (pc)))]
569 ""
570 {
571 return get_attr_length (insn) == 4
572 ? "bgeu %z0,%z1,%2"
573 : "bgu %z1,%z0,8\n\tbi %2";
574 }
575 [(set_attr "type" "cbranch")])
576
577 ;; ---------------------------------
578 ;; call
579 ;; ---------------------------------
580
581 (define_expand "call"
582 [(parallel [(call (match_operand 0 "" "")
583 (match_operand 1 "" ""))
584 (clobber (reg:SI RA_REGNUM))
585 ])]
586 ""
587 "
588 {
589 rtx addr = XEXP (operands[0], 0);
590 if (!CONSTANT_ADDRESS_P (addr))
591 XEXP (operands[0], 0) = force_reg (Pmode, addr);
592 }")
593
594 (define_insn "*call"
595 [(call (mem:SI (match_operand:SI 0 "call_operand" "r,s"))
596 (match_operand 1 "" ""))
597 (clobber (reg:SI RA_REGNUM))]
598 ""
599 "@
600 call %0
601 calli %0"
602 [(set_attr "type" "call,icall")]
603 )
604
605 (define_expand "call_value"
606 [(parallel [(set (match_operand 0 "" "")
607 (call (match_operand 1 "" "")
608 (match_operand 2 "" "")))
609 (clobber (reg:SI RA_REGNUM))
610 ])]
611 ""
612 "
613 {
614 rtx addr = XEXP (operands[1], 0);
615 if (!CONSTANT_ADDRESS_P (addr))
616 XEXP (operands[1], 0) = force_reg (Pmode, addr);
617 }")
618
619 (define_insn "*call_value"
620 [(set (match_operand 0 "register_operand" "=r,r")
621 (call (mem:SI (match_operand:SI 1 "call_operand" "r,s"))
622 (match_operand 2 "" "")))
623 (clobber (reg:SI RA_REGNUM))]
624 ""
625 "@
626 call %1
627 calli %1"
628 [(set_attr "type" "call,icall")]
629 )
630
631 (define_insn "return_internal"
632 [(use (match_operand:SI 0 "register_operand" "r"))
633 (return)]
634 ""
635 "b %0"
636 [(set_attr "type" "uibranch")]
637 )
638
639 (define_insn "return"
640 [(return)]
641 "lm32_can_use_return ()"
642 "ret"
643 [(set_attr "type" "uibranch")]
644 )
645
646 ;; ---------------------------------
647 ;; switch/case statements
648 ;; ---------------------------------
649
650 (define_expand "tablejump"
651 [(set (pc) (match_operand 0 "register_operand" ""))
652 (use (label_ref (match_operand 1 "" "")))]
653 ""
654 "
655 {
656 rtx target = operands[0];
657 if (flag_pic)
658 {
659 /* For PIC, the table entry is relative to the start of the table. */
660 rtx label = gen_reg_rtx (SImode);
661 target = gen_reg_rtx (SImode);
662 emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1]));
663 emit_insn (gen_addsi3 (target, operands[0], label));
664 }
665 emit_jump_insn (gen_tablejumpsi (target, operands[1]));
666 DONE;
667 }")
668
669 (define_insn "tablejumpsi"
670 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
671 (use (label_ref (match_operand 1 "" "")))]
672 ""
673 "b %0"
674 [(set_attr "type" "ubranch")]
675 )
676
677 ;; ---------------------------------
678 ;; arithmetic
679 ;; ---------------------------------
680
681 (define_insn "addsi3"
682 [(set (match_operand:SI 0 "register_operand" "=r,r")
683 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
684 (match_operand:SI 2 "register_or_K_operand" "r,K")))]
685 ""
686 "@
687 add %0, %z1, %2
688 addi %0, %z1, %2"
689 [(set_attr "type" "arith")]
690 )
691
692 (define_insn "subsi3"
693 [(set (match_operand:SI 0 "register_operand" "=r")
694 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
695 (match_operand:SI 2 "register_or_zero_operand" "rJ")))]
696 ""
697 "sub %0, %z1, %z2"
698 [(set_attr "type" "arith")]
699 )
700
701 (define_insn "mulsi3"
702 [(set (match_operand:SI 0 "register_operand" "=r,r")
703 (mult:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
704 (match_operand:SI 2 "register_or_K_operand" "r,K")))]
705 "TARGET_MULTIPLY_ENABLED"
706 "@
707 mul %0, %z1, %2
708 muli %0, %z1, %2"
709 [(set_attr "type" "multiply")]
710 )
711
712 (define_insn "udivsi3"
713 [(set (match_operand:SI 0 "register_operand" "=r")
714 (udiv:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
715 (match_operand:SI 2 "register_operand" "r")))]
716 "TARGET_DIVIDE_ENABLED"
717 "divu %0, %z1, %2"
718 [(set_attr "type" "divide")]
719 )
720
721 (define_insn "umodsi3"
722 [(set (match_operand:SI 0 "register_operand" "=r")
723 (umod:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
724 (match_operand:SI 2 "register_operand" "r")))]
725 "TARGET_DIVIDE_ENABLED"
726 "modu %0, %z1, %2"
727 [(set_attr "type" "divide")]
728 )
729
730 ;; ---------------------------------
731 ;; negation and inversion
732 ;; ---------------------------------
733
734 (define_insn "negsi2"
735 [(set (match_operand:SI 0 "register_operand" "=r")
736 (neg:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")))]
737 ""
738 "sub %0, r0, %z1"
739 [(set_attr "type" "arith")]
740 )
741
742 (define_insn "one_cmplsi2"
743 [(set (match_operand:SI 0 "register_operand" "=r")
744 (not:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")))]
745 ""
746 "not %0, %z1"
747 [(set_attr "type" "arith")]
748 )
749
750 ;; ---------------------------------
751 ;; logical
752 ;; ---------------------------------
753
754 (define_insn "andsi3"
755 [(set (match_operand:SI 0 "register_operand" "=r,r")
756 (and:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
757 (match_operand:SI 2 "register_or_L_operand" "r,L")))]
758 ""
759 "@
760 and %0, %z1, %2
761 andi %0, %z1, %2"
762 [(set_attr "type" "arith")]
763 )
764
765 (define_insn "iorsi3"
766 [(set (match_operand:SI 0 "register_operand" "=r,r")
767 (ior:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
768 (match_operand:SI 2 "register_or_L_operand" "r,L")))]
769 ""
770 "@
771 or %0, %z1, %2
772 ori %0, %z1, %2"
773 [(set_attr "type" "arith")]
774 )
775
776 (define_insn "xorsi3"
777 [(set (match_operand:SI 0 "register_operand" "=r,r")
778 (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
779 (match_operand:SI 2 "register_or_L_operand" "r,L")))]
780 ""
781 "@
782 xor %0, %z1, %2
783 xori %0, %z1, %2"
784 [(set_attr "type" "arith")]
785 )
786
787 (define_insn "*norsi3"
788 [(set (match_operand:SI 0 "register_operand" "=r,r")
789 (not:SI (ior:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
790 (match_operand:SI 2 "register_or_L_operand" "r,L"))))]
791 ""
792 "@
793 nor %0, %z1, %2
794 nori %0, %z1, %2"
795 [(set_attr "type" "arith")]
796 )
797
798 (define_insn "*xnorsi3"
799 [(set (match_operand:SI 0 "register_operand" "=r,r")
800 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
801 (match_operand:SI 2 "register_or_L_operand" "r,L"))))]
802 ""
803 "@
804 xnor %0, %z1, %2
805 xnori %0, %z1, %2"
806 [(set_attr "type" "arith")]
807 )
808
809 ;; ---------------------------------
810 ;; shifts
811 ;; ---------------------------------
812
813 (define_expand "ashlsi3"
814 [(set (match_operand:SI 0 "register_operand" "")
815 (ashift:SI (match_operand:SI 1 "register_or_zero_operand" "")
816 (match_operand:SI 2 "register_or_L_operand" "")))]
817 ""
818 {
819 if (!TARGET_BARREL_SHIFT_ENABLED)
820 {
821 if (!optimize_size
822 && satisfies_constraint_L (operands[2])
823 && INTVAL (operands[2]) <= 8)
824 {
825 int i;
826 int shifts = INTVAL (operands[2]);
827 rtx one = GEN_INT (1);
828
829 if (shifts == 0)
830 emit_move_insn (operands[0], operands[1]);
831 else
832 emit_insn (gen_addsi3 (operands[0], operands[1], operands[1]));
833 for (i = 1; i < shifts; i++)
834 emit_insn (gen_addsi3 (operands[0], operands[0], operands[0]));
835 DONE;
836 }
837 else
838 FAIL;
839 }
840 })
841
842 (define_insn "*ashlsi3"
843 [(set (match_operand:SI 0 "register_operand" "=r,r")
844 (ashift:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
845 (match_operand:SI 2 "register_or_L_operand" "r,L")))]
846 "TARGET_BARREL_SHIFT_ENABLED"
847 "@
848 sl %0, %z1, %2
849 sli %0, %z1, %2"
850 [(set_attr "type" "shift")]
851 )
852
853 (define_expand "ashrsi3"
854 [(set (match_operand:SI 0 "register_operand" "")
855 (ashiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "")
856 (match_operand:SI 2 "register_or_L_operand" "")))]
857 ""
858 {
859 if (!TARGET_BARREL_SHIFT_ENABLED)
860 {
861 if (!optimize_size
862 && satisfies_constraint_L (operands[2])
863 && INTVAL (operands[2]) <= 8)
864 {
865 int i;
866 int shifts = INTVAL (operands[2]);
867 rtx one = GEN_INT (1);
868
869 if (shifts == 0)
870 emit_move_insn (operands[0], operands[1]);
871 else
872 emit_insn (gen_ashrsi3_1bit (operands[0], operands[1], one));
873 for (i = 1; i < shifts; i++)
874 emit_insn (gen_ashrsi3_1bit (operands[0], operands[0], one));
875 DONE;
876 }
877 else
878 FAIL;
879 }
880 })
881
882 (define_insn "*ashrsi3"
883 [(set (match_operand:SI 0 "register_operand" "=r,r")
884 (ashiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
885 (match_operand:SI 2 "register_or_L_operand" "r,L")))]
886 "TARGET_BARREL_SHIFT_ENABLED"
887 "@
888 sr %0, %z1, %2
889 sri %0, %z1, %2"
890 [(set_attr "type" "shift")]
891 )
892
893 (define_insn "ashrsi3_1bit"
894 [(set (match_operand:SI 0 "register_operand" "=r")
895 (ashiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
896 (match_operand:SI 2 "constant_M_operand" "M")))]
897 "!TARGET_BARREL_SHIFT_ENABLED"
898 "sri %0, %z1, %2"
899 [(set_attr "type" "shift")]
900 )
901
902 (define_expand "lshrsi3"
903 [(set (match_operand:SI 0 "register_operand" "")
904 (lshiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "")
905 (match_operand:SI 2 "register_or_L_operand" "")))]
906 ""
907 {
908 if (!TARGET_BARREL_SHIFT_ENABLED)
909 {
910 if (!optimize_size
911 && satisfies_constraint_L (operands[2])
912 && INTVAL (operands[2]) <= 8)
913 {
914 int i;
915 int shifts = INTVAL (operands[2]);
916 rtx one = GEN_INT (1);
917
918 if (shifts == 0)
919 emit_move_insn (operands[0], operands[1]);
920 else
921 emit_insn (gen_lshrsi3_1bit (operands[0], operands[1], one));
922 for (i = 1; i < shifts; i++)
923 emit_insn (gen_lshrsi3_1bit (operands[0], operands[0], one));
924 DONE;
925 }
926 else
927 FAIL;
928 }
929 })
930
931 (define_insn "*lshrsi3"
932 [(set (match_operand:SI 0 "register_operand" "=r,r")
933 (lshiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
934 (match_operand:SI 2 "register_or_L_operand" "r,L")))]
935 "TARGET_BARREL_SHIFT_ENABLED"
936 "@
937 sru %0, %z1, %2
938 srui %0, %z1, %2"
939 [(set_attr "type" "shift")]
940 )
941
942 (define_insn "lshrsi3_1bit"
943 [(set (match_operand:SI 0 "register_operand" "=r")
944 (lshiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
945 (match_operand:SI 2 "constant_M_operand" "M")))]
946 "!TARGET_BARREL_SHIFT_ENABLED"
947 "srui %0, %z1, %2"
948 [(set_attr "type" "shift")]
949 )
950
951 ;; ---------------------------------
952 ;; function entry / exit
953 ;; ---------------------------------
954
955 (define_expand "prologue"
956 [(const_int 1)]
957 ""
958 "
959 {
960 lm32_expand_prologue ();
961 DONE;
962 }")
963
964 (define_expand "epilogue"
965 [(return)]
966 ""
967 "
968 {
969 lm32_expand_epilogue ();
970 DONE;
971 }")
972
973 ;; ---------------------------------
974 ;; nop
975 ;; ---------------------------------
976
977 (define_insn "nop"
978 [(const_int 0)]
979 ""
980 "nop"
981 [(set_attr "type" "arith")]
982 )
983
984 ;; ---------------------------------
985 ;; blockage
986 ;; ---------------------------------
987
988 ;; used to stop the scheduler from
989 ;; scheduling code across certain boundaries
990
991 (define_insn "blockage"
992 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
993 ""
994 ""
995 [(set_attr "length" "0")]
996 )