]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/lm32/lm32.md
Update copyright years.
[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-2023 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 (operands[0], gen_rtx_HIGH (SImode, operands[1])));
199 emit_insn (gen_rtx_SET (operands[0], gen_rtx_LO_SUM (SImode, operands[0],
200 operands[1])));
201 DONE;
202 }
203 else if (GET_CODE (operands[1]) == CONST_INT)
204 {
205 if (!(satisfies_constraint_K (operands[1])
206 || satisfies_constraint_L (operands[1])
207 || satisfies_constraint_U (operands[1])))
208 {
209 emit_insn (gen_movsi_insn (operands[0],
210 GEN_INT (INTVAL (operands[1]) & ~0xffff)));
211 emit_insn (gen_iorsi3 (operands[0],
212 operands[0],
213 GEN_INT (INTVAL (operands[1]) & 0xffff)));
214 DONE;
215 }
216 }
217 }")
218
219 (define_expand "cpymemsi"
220 [(parallel [(set (match_operand:BLK 0 "general_operand" "")
221 (match_operand:BLK 1 "general_operand" ""))
222 (use (match_operand:SI 2 "" ""))
223 (use (match_operand:SI 3 "const_int_operand" ""))])]
224 ""
225 {
226 if (!lm32_expand_block_move (operands))
227 FAIL;
228 DONE;
229 })
230
231 ;; ---------------------------------
232 ;; load/stores/moves
233 ;; ---------------------------------
234
235 (define_insn "movsi_got"
236 [(set (match_operand:SI 0 "register_operand" "=r")
237 (unspec:SI [(match_operand 1 "" "")] UNSPEC_GOT))]
238 "flag_pic"
239 "lw %0, (gp+got(%1))"
240 [(set_attr "type" "load")]
241 )
242
243 (define_insn "movsi_gotoff_hi16"
244 [(set (match_operand:SI 0 "register_operand" "=r")
245 (unspec:SI [(match_operand 1 "" "")] UNSPEC_GOTOFF_HI16))]
246 "flag_pic"
247 "orhi %0, r0, gotoffhi16(%1)"
248 [(set_attr "type" "load")]
249 )
250
251 (define_insn "movsi_gotoff_lo16"
252 [(set (match_operand:SI 0 "register_operand" "=r")
253 (unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "0")
254 (match_operand 2 "" ""))] UNSPEC_GOTOFF_LO16))]
255 "flag_pic"
256 "addi %0, %1, gotofflo16(%2)"
257 [(set_attr "type" "arith")]
258 )
259
260 (define_insn "*movsi_lo_sum"
261 [(set (match_operand:SI 0 "register_operand" "=r")
262 (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
263 (match_operand:SI 2 "reloc_operand" "i")))]
264 "!flag_pic"
265 "ori %0, %0, lo(%2)"
266 [(set_attr "type" "arith")]
267 )
268
269 (define_insn "*movqi_insn"
270 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,m,r")
271 (match_operand:QI 1 "general_operand" "m,r,r,J,n"))]
272 "lm32_move_ok (QImode, operands)"
273 "@
274 lbu %0, %1
275 or %0, %1, r0
276 sb %0, %1
277 sb %0, r0
278 addi %0, r0, %1"
279 [(set_attr "type" "load,arith,store,store,arith")]
280 )
281
282 (define_insn "*movhi_insn"
283 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,m,r,r")
284 (match_operand:HI 1 "general_operand" "m,r,r,J,K,L"))]
285 "lm32_move_ok (HImode, operands)"
286 "@
287 lhu %0, %1
288 or %0, %1, r0
289 sh %0, %1
290 sh %0, r0
291 addi %0, r0, %1
292 ori %0, r0, %1"
293 [(set_attr "type" "load,arith,store,store,arith,arith")]
294 )
295
296 (define_insn "movsi_insn"
297 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,m,r,r,r,r,r,r")
298 (match_operand:SI 1 "general_operand" "m,r,r,J,K,L,U,S,Y,n"))]
299 "lm32_move_ok (SImode, operands)"
300 "@
301 lw %0, %1
302 or %0, %1, r0
303 sw %0, %1
304 sw %0, r0
305 addi %0, r0, %1
306 ori %0, r0, %1
307 orhi %0, r0, hi(%1)
308 mva %0, gp(%1)
309 orhi %0, r0, hi(%1)
310 ori %0, r0, lo(%1); orhi %0, %0, hi(%1)"
311 [(set_attr "type" "load,arith,store,store,arith,arith,arith,arith,arith,arith")]
312 )
313
314 ;; ---------------------------------
315 ;; sign and zero extension
316 ;; ---------------------------------
317
318 (define_insn "*extendqihi2"
319 [(set (match_operand:HI 0 "register_operand" "=r,r")
320 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m,r")))]
321 "TARGET_SIGN_EXTEND_ENABLED || (GET_CODE (operands[1]) != REG)"
322 "@
323 lb %0, %1
324 sextb %0, %1"
325 [(set_attr "type" "load,arith")]
326 )
327
328 (define_insn "zero_extendqihi2"
329 [(set (match_operand:HI 0 "register_operand" "=r,r")
330 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m,r")))]
331 ""
332 "@
333 lbu %0, %1
334 andi %0, %1, 0xff"
335 [(set_attr "type" "load,arith")]
336 )
337
338 (define_insn "*extendqisi2"
339 [(set (match_operand:SI 0 "register_operand" "=r,r")
340 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m,r")))]
341 "TARGET_SIGN_EXTEND_ENABLED || (GET_CODE (operands[1]) != REG)"
342 "@
343 lb %0, %1
344 sextb %0, %1"
345 [(set_attr "type" "load,arith")]
346 )
347
348 (define_insn "zero_extendqisi2"
349 [(set (match_operand:SI 0 "register_operand" "=r,r")
350 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m,r")))]
351 ""
352 "@
353 lbu %0, %1
354 andi %0, %1, 0xff"
355 [(set_attr "type" "load,arith")]
356 )
357
358 (define_insn "*extendhisi2"
359 [(set (match_operand:SI 0 "register_operand" "=r,r")
360 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
361 "TARGET_SIGN_EXTEND_ENABLED || (GET_CODE (operands[1]) != REG)"
362 "@
363 lh %0, %1
364 sexth %0, %1"
365 [(set_attr "type" "load,arith")]
366 )
367
368 (define_insn "zero_extendhisi2"
369 [(set (match_operand:SI 0 "register_operand" "=r,r")
370 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
371 ""
372 "@
373 lhu %0, %1
374 andi %0, %1, 0xffff"
375 [(set_attr "type" "load,arith")]
376 )
377
378 ;; ---------------------------------
379 ;; compare
380 ;; ---------------------------------
381
382 (define_expand "cstoresi4"
383 [(set (match_operand:SI 0 "register_operand")
384 (match_operator:SI 1 "ordered_comparison_operator"
385 [(match_operand:SI 2 "register_operand")
386 (match_operand:SI 3 "register_or_int_operand")]))]
387 ""
388 {
389 lm32_expand_scc (operands);
390 DONE;
391 })
392
393 (define_insn "*seq"
394 [(set (match_operand:SI 0 "register_operand" "=r,r")
395 (eq:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
396 (match_operand:SI 2 "register_or_K_operand" "r,K")))]
397 ""
398 "@
399 cmpe %0, %z1, %2
400 cmpei %0, %z1, %2"
401 [(set_attr "type" "compare")]
402 )
403
404 (define_insn "*sne"
405 [(set (match_operand:SI 0 "register_operand" "=r,r")
406 (ne:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
407 (match_operand:SI 2 "register_or_K_operand" "r,K")))]
408 ""
409 "@
410 cmpne %0, %z1, %2
411 cmpnei %0, %z1, %2"
412 [(set_attr "type" "compare")]
413 )
414
415 (define_insn "*sgt"
416 [(set (match_operand:SI 0 "register_operand" "=r,r")
417 (gt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
418 (match_operand:SI 2 "register_or_K_operand" "r,K")))]
419 ""
420 "@
421 cmpg %0, %z1, %2
422 cmpgi %0, %z1, %2"
423 [(set_attr "type" "compare")]
424 )
425
426 (define_insn "*sge"
427 [(set (match_operand:SI 0 "register_operand" "=r,r")
428 (ge:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
429 (match_operand:SI 2 "register_or_K_operand" "r,K")))]
430 ""
431 "@
432 cmpge %0, %z1, %2
433 cmpgei %0, %z1, %2"
434 [(set_attr "type" "compare")]
435 )
436
437 (define_insn "*sgtu"
438 [(set (match_operand:SI 0 "register_operand" "=r,r")
439 (gtu:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
440 (match_operand:SI 2 "register_or_L_operand" "r,L")))]
441 ""
442 "@
443 cmpgu %0, %z1, %2
444 cmpgui %0, %z1, %2"
445 [(set_attr "type" "compare")]
446 )
447
448 (define_insn "*sgeu"
449 [(set (match_operand:SI 0 "register_operand" "=r,r")
450 (geu:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
451 (match_operand:SI 2 "register_or_L_operand" "r,L")))]
452 ""
453 "@
454 cmpgeu %0, %z1, %2
455 cmpgeui %0, %z1, %2"
456 [(set_attr "type" "compare")]
457 )
458
459 ;; ---------------------------------
460 ;; unconditional branch
461 ;; ---------------------------------
462
463 (define_insn "jump"
464 [(set (pc) (label_ref (match_operand 0 "" "")))]
465 ""
466 "bi %0"
467 [(set_attr "type" "ubranch")]
468 )
469
470 (define_insn "indirect_jump"
471 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
472 ""
473 "b %0"
474 [(set_attr "type" "uibranch")]
475 )
476
477 ;; ---------------------------------
478 ;; conditional branch
479 ;; ---------------------------------
480
481 (define_expand "cbranchsi4"
482 [(set (pc)
483 (if_then_else (match_operator 0 "comparison_operator"
484 [(match_operand:SI 1 "register_operand")
485 (match_operand:SI 2 "nonmemory_operand")])
486 (label_ref (match_operand 3 "" ""))
487 (pc)))]
488 ""
489 "
490 {
491 lm32_expand_conditional_branch (operands);
492 DONE;
493 }")
494
495 (define_insn "*beq"
496 [(set (pc)
497 (if_then_else (eq:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
498 (match_operand:SI 1 "register_or_zero_operand" "rJ"))
499 (label_ref (match_operand 2 "" ""))
500 (pc)))]
501 ""
502 {
503 return get_attr_length (insn) == 4
504 ? "be %z0,%z1,%2"
505 : "bne %z0,%z1,8\n\tbi %2";
506 }
507 [(set_attr "type" "cbranch")])
508
509 (define_insn "*bne"
510 [(set (pc)
511 (if_then_else (ne:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
512 (match_operand:SI 1 "register_or_zero_operand" "rJ"))
513 (label_ref (match_operand 2 "" ""))
514 (pc)))]
515 ""
516 {
517 return get_attr_length (insn) == 4
518 ? "bne %z0,%z1,%2"
519 : "be %z0,%z1,8\n\tbi %2";
520 }
521 [(set_attr "type" "cbranch")])
522
523 (define_insn "*bgt"
524 [(set (pc)
525 (if_then_else (gt:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
526 (match_operand:SI 1 "register_or_zero_operand" "rJ"))
527 (label_ref (match_operand 2 "" ""))
528 (pc)))]
529 ""
530 {
531 return get_attr_length (insn) == 4
532 ? "bg %z0,%z1,%2"
533 : "bge %z1,%z0,8\n\tbi %2";
534 }
535 [(set_attr "type" "cbranch")])
536
537 (define_insn "*bge"
538 [(set (pc)
539 (if_then_else (ge:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
540 (match_operand:SI 1 "register_or_zero_operand" "rJ"))
541 (label_ref (match_operand 2 "" ""))
542 (pc)))]
543 ""
544 {
545 return get_attr_length (insn) == 4
546 ? "bge %z0,%z1,%2"
547 : "bg %z1,%z0,8\n\tbi %2";
548 }
549 [(set_attr "type" "cbranch")])
550
551 (define_insn "*bgtu"
552 [(set (pc)
553 (if_then_else (gtu:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
554 (match_operand:SI 1 "register_or_zero_operand" "rJ"))
555 (label_ref (match_operand 2 "" ""))
556 (pc)))]
557 ""
558 {
559 return get_attr_length (insn) == 4
560 ? "bgu %z0,%z1,%2"
561 : "bgeu %z1,%z0,8\n\tbi %2";
562 }
563 [(set_attr "type" "cbranch")])
564
565 (define_insn "*bgeu"
566 [(set (pc)
567 (if_then_else (geu:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
568 (match_operand:SI 1 "register_or_zero_operand" "rJ"))
569 (label_ref (match_operand 2 "" ""))
570 (pc)))]
571 ""
572 {
573 return get_attr_length (insn) == 4
574 ? "bgeu %z0,%z1,%2"
575 : "bgu %z1,%z0,8\n\tbi %2";
576 }
577 [(set_attr "type" "cbranch")])
578
579 ;; ---------------------------------
580 ;; call
581 ;; ---------------------------------
582
583 (define_expand "call"
584 [(parallel [(call (match_operand 0 "" "")
585 (match_operand 1 "" ""))
586 (clobber (reg:SI RA_REGNUM))
587 ])]
588 ""
589 "
590 {
591 rtx addr = XEXP (operands[0], 0);
592 if (!CONSTANT_ADDRESS_P (addr))
593 XEXP (operands[0], 0) = force_reg (Pmode, addr);
594 }")
595
596 (define_insn "*call"
597 [(call (mem:SI (match_operand:SI 0 "call_operand" "r,s"))
598 (match_operand 1 "" ""))
599 (clobber (reg:SI RA_REGNUM))]
600 ""
601 "@
602 call %0
603 calli %0"
604 [(set_attr "type" "call,icall")]
605 )
606
607 (define_expand "call_value"
608 [(parallel [(set (match_operand 0 "" "")
609 (call (match_operand 1 "" "")
610 (match_operand 2 "" "")))
611 (clobber (reg:SI RA_REGNUM))
612 ])]
613 ""
614 "
615 {
616 rtx addr = XEXP (operands[1], 0);
617 if (!CONSTANT_ADDRESS_P (addr))
618 XEXP (operands[1], 0) = force_reg (Pmode, addr);
619 }")
620
621 (define_insn "*call_value"
622 [(set (match_operand 0 "register_operand" "=r,r")
623 (call (mem:SI (match_operand:SI 1 "call_operand" "r,s"))
624 (match_operand 2 "" "")))
625 (clobber (reg:SI RA_REGNUM))]
626 ""
627 "@
628 call %1
629 calli %1"
630 [(set_attr "type" "call,icall")]
631 )
632
633 (define_insn "return_internal"
634 [(use (match_operand:SI 0 "register_operand" "r"))
635 (return)]
636 ""
637 "b %0"
638 [(set_attr "type" "uibranch")]
639 )
640
641 (define_expand "return"
642 [(return)]
643 "lm32_can_use_return ()"
644 ""
645 )
646
647 (define_expand "simple_return"
648 [(simple_return)]
649 ""
650 ""
651 )
652
653 (define_insn "*return"
654 [(return)]
655 "reload_completed"
656 "ret"
657 [(set_attr "type" "uibranch")]
658 )
659
660 (define_insn "*simple_return"
661 [(simple_return)]
662 ""
663 "ret"
664 [(set_attr "type" "uibranch")]
665 )
666
667 ;; ---------------------------------
668 ;; switch/case statements
669 ;; ---------------------------------
670
671 (define_expand "tablejump"
672 [(set (pc) (match_operand 0 "register_operand" ""))
673 (use (label_ref (match_operand 1 "" "")))]
674 ""
675 "
676 {
677 rtx target = operands[0];
678 if (flag_pic)
679 {
680 /* For PIC, the table entry is relative to the start of the table. */
681 rtx label = gen_reg_rtx (SImode);
682 target = gen_reg_rtx (SImode);
683 emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1]));
684 emit_insn (gen_addsi3 (target, operands[0], label));
685 }
686 emit_jump_insn (gen_tablejumpsi (target, operands[1]));
687 DONE;
688 }")
689
690 (define_insn "tablejumpsi"
691 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
692 (use (label_ref (match_operand 1 "" "")))]
693 ""
694 "b %0"
695 [(set_attr "type" "ubranch")]
696 )
697
698 ;; ---------------------------------
699 ;; arithmetic
700 ;; ---------------------------------
701
702 (define_insn "addsi3"
703 [(set (match_operand:SI 0 "register_operand" "=r,r")
704 (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
705 (match_operand:SI 2 "register_or_K_operand" "r,K")))]
706 ""
707 "@
708 add %0, %z1, %2
709 addi %0, %z1, %2"
710 [(set_attr "type" "arith")]
711 )
712
713 (define_insn "subsi3"
714 [(set (match_operand:SI 0 "register_operand" "=r")
715 (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
716 (match_operand:SI 2 "register_or_zero_operand" "rJ")))]
717 ""
718 "sub %0, %z1, %z2"
719 [(set_attr "type" "arith")]
720 )
721
722 (define_insn "mulsi3"
723 [(set (match_operand:SI 0 "register_operand" "=r,r")
724 (mult:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
725 (match_operand:SI 2 "register_or_K_operand" "r,K")))]
726 "TARGET_MULTIPLY_ENABLED"
727 "@
728 mul %0, %z1, %2
729 muli %0, %z1, %2"
730 [(set_attr "type" "multiply")]
731 )
732
733 (define_insn "udivsi3"
734 [(set (match_operand:SI 0 "register_operand" "=r")
735 (udiv:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
736 (match_operand:SI 2 "register_operand" "r")))]
737 "TARGET_DIVIDE_ENABLED"
738 "divu %0, %z1, %2"
739 [(set_attr "type" "divide")]
740 )
741
742 (define_insn "umodsi3"
743 [(set (match_operand:SI 0 "register_operand" "=r")
744 (umod:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
745 (match_operand:SI 2 "register_operand" "r")))]
746 "TARGET_DIVIDE_ENABLED"
747 "modu %0, %z1, %2"
748 [(set_attr "type" "divide")]
749 )
750
751 ;; ---------------------------------
752 ;; negation and inversion
753 ;; ---------------------------------
754
755 (define_insn "negsi2"
756 [(set (match_operand:SI 0 "register_operand" "=r")
757 (neg:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")))]
758 ""
759 "sub %0, r0, %z1"
760 [(set_attr "type" "arith")]
761 )
762
763 (define_insn "one_cmplsi2"
764 [(set (match_operand:SI 0 "register_operand" "=r")
765 (not:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")))]
766 ""
767 "not %0, %z1"
768 [(set_attr "type" "arith")]
769 )
770
771 ;; ---------------------------------
772 ;; logical
773 ;; ---------------------------------
774
775 (define_insn "andsi3"
776 [(set (match_operand:SI 0 "register_operand" "=r,r")
777 (and:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
778 (match_operand:SI 2 "register_or_L_operand" "r,L")))]
779 ""
780 "@
781 and %0, %z1, %2
782 andi %0, %z1, %2"
783 [(set_attr "type" "arith")]
784 )
785
786 (define_insn "iorsi3"
787 [(set (match_operand:SI 0 "register_operand" "=r,r")
788 (ior:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
789 (match_operand:SI 2 "register_or_L_operand" "r,L")))]
790 ""
791 "@
792 or %0, %z1, %2
793 ori %0, %z1, %2"
794 [(set_attr "type" "arith")]
795 )
796
797 (define_insn "xorsi3"
798 [(set (match_operand:SI 0 "register_operand" "=r,r")
799 (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
800 (match_operand:SI 2 "register_or_L_operand" "r,L")))]
801 ""
802 "@
803 xor %0, %z1, %2
804 xori %0, %z1, %2"
805 [(set_attr "type" "arith")]
806 )
807
808 (define_insn "*norsi3"
809 [(set (match_operand:SI 0 "register_operand" "=r,r")
810 (not:SI (ior:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
811 (match_operand:SI 2 "register_or_L_operand" "r,L"))))]
812 ""
813 "@
814 nor %0, %z1, %2
815 nori %0, %z1, %2"
816 [(set_attr "type" "arith")]
817 )
818
819 (define_insn "*xnorsi3"
820 [(set (match_operand:SI 0 "register_operand" "=r,r")
821 (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
822 (match_operand:SI 2 "register_or_L_operand" "r,L"))))]
823 ""
824 "@
825 xnor %0, %z1, %2
826 xnori %0, %z1, %2"
827 [(set_attr "type" "arith")]
828 )
829
830 ;; ---------------------------------
831 ;; shifts
832 ;; ---------------------------------
833
834 (define_expand "ashlsi3"
835 [(set (match_operand:SI 0 "register_operand" "")
836 (ashift:SI (match_operand:SI 1 "register_or_zero_operand" "")
837 (match_operand:SI 2 "register_or_L_operand" "")))]
838 ""
839 {
840 if (!TARGET_BARREL_SHIFT_ENABLED)
841 {
842 if (!optimize_size
843 && satisfies_constraint_L (operands[2])
844 && INTVAL (operands[2]) <= 8)
845 {
846 int i;
847 int shifts = INTVAL (operands[2]);
848
849 if (shifts == 0)
850 emit_move_insn (operands[0], operands[1]);
851 else
852 emit_insn (gen_addsi3 (operands[0], operands[1], operands[1]));
853 for (i = 1; i < shifts; i++)
854 emit_insn (gen_addsi3 (operands[0], operands[0], operands[0]));
855 DONE;
856 }
857 else
858 FAIL;
859 }
860 })
861
862 (define_insn "*ashlsi3"
863 [(set (match_operand:SI 0 "register_operand" "=r,r")
864 (ashift:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
865 (match_operand:SI 2 "register_or_L_operand" "r,L")))]
866 "TARGET_BARREL_SHIFT_ENABLED"
867 "@
868 sl %0, %z1, %2
869 sli %0, %z1, %2"
870 [(set_attr "type" "shift")]
871 )
872
873 (define_expand "ashrsi3"
874 [(set (match_operand:SI 0 "register_operand" "")
875 (ashiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "")
876 (match_operand:SI 2 "register_or_L_operand" "")))]
877 ""
878 {
879 if (!TARGET_BARREL_SHIFT_ENABLED)
880 {
881 if (!optimize_size
882 && satisfies_constraint_L (operands[2])
883 && INTVAL (operands[2]) <= 8)
884 {
885 int i;
886 int shifts = INTVAL (operands[2]);
887 rtx one = GEN_INT (1);
888
889 if (shifts == 0)
890 emit_move_insn (operands[0], operands[1]);
891 else
892 emit_insn (gen_ashrsi3_1bit (operands[0], operands[1], one));
893 for (i = 1; i < shifts; i++)
894 emit_insn (gen_ashrsi3_1bit (operands[0], operands[0], one));
895 DONE;
896 }
897 else
898 FAIL;
899 }
900 })
901
902 (define_insn "*ashrsi3"
903 [(set (match_operand:SI 0 "register_operand" "=r,r")
904 (ashiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
905 (match_operand:SI 2 "register_or_L_operand" "r,L")))]
906 "TARGET_BARREL_SHIFT_ENABLED"
907 "@
908 sr %0, %z1, %2
909 sri %0, %z1, %2"
910 [(set_attr "type" "shift")]
911 )
912
913 (define_insn "ashrsi3_1bit"
914 [(set (match_operand:SI 0 "register_operand" "=r")
915 (ashiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
916 (match_operand:SI 2 "constant_M_operand" "M")))]
917 "!TARGET_BARREL_SHIFT_ENABLED"
918 "sri %0, %z1, %2"
919 [(set_attr "type" "shift")]
920 )
921
922 (define_expand "lshrsi3"
923 [(set (match_operand:SI 0 "register_operand" "")
924 (lshiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "")
925 (match_operand:SI 2 "register_or_L_operand" "")))]
926 ""
927 {
928 if (!TARGET_BARREL_SHIFT_ENABLED)
929 {
930 if (!optimize_size
931 && satisfies_constraint_L (operands[2])
932 && INTVAL (operands[2]) <= 8)
933 {
934 int i;
935 int shifts = INTVAL (operands[2]);
936 rtx one = GEN_INT (1);
937
938 if (shifts == 0)
939 emit_move_insn (operands[0], operands[1]);
940 else
941 emit_insn (gen_lshrsi3_1bit (operands[0], operands[1], one));
942 for (i = 1; i < shifts; i++)
943 emit_insn (gen_lshrsi3_1bit (operands[0], operands[0], one));
944 DONE;
945 }
946 else
947 FAIL;
948 }
949 })
950
951 (define_insn "*lshrsi3"
952 [(set (match_operand:SI 0 "register_operand" "=r,r")
953 (lshiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
954 (match_operand:SI 2 "register_or_L_operand" "r,L")))]
955 "TARGET_BARREL_SHIFT_ENABLED"
956 "@
957 sru %0, %z1, %2
958 srui %0, %z1, %2"
959 [(set_attr "type" "shift")]
960 )
961
962 (define_insn "lshrsi3_1bit"
963 [(set (match_operand:SI 0 "register_operand" "=r")
964 (lshiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
965 (match_operand:SI 2 "constant_M_operand" "M")))]
966 "!TARGET_BARREL_SHIFT_ENABLED"
967 "srui %0, %z1, %2"
968 [(set_attr "type" "shift")]
969 )
970
971 ;; ---------------------------------
972 ;; function entry / exit
973 ;; ---------------------------------
974
975 (define_expand "prologue"
976 [(const_int 1)]
977 ""
978 "
979 {
980 lm32_expand_prologue ();
981 DONE;
982 }")
983
984 (define_expand "epilogue"
985 [(return)]
986 ""
987 "
988 {
989 lm32_expand_epilogue ();
990 DONE;
991 }")
992
993 ;; ---------------------------------
994 ;; nop
995 ;; ---------------------------------
996
997 (define_insn "nop"
998 [(const_int 0)]
999 ""
1000 "nop"
1001 [(set_attr "type" "arith")]
1002 )
1003
1004 ;; ---------------------------------
1005 ;; blockage
1006 ;; ---------------------------------
1007
1008 ;; used to stop the scheduler from
1009 ;; scheduling code across certain boundaries
1010
1011 (define_insn "blockage"
1012 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
1013 ""
1014 ""
1015 [(set_attr "length" "0")]
1016 )