OSDN Git Service

Add NIOS2 support. Code from SourceyG++.
[pf3gnuchains/gcc-fork.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 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 )