Rebase.
[official-gcc.git] / gcc / config / lm32 / lm32.md
blob26d16823c1a9e47ff6000a8247b70cef258eaf21
1 ;; Machine description of the Lattice Mico32 architecture for GNU C compiler.
2 ;; Contributed by Jon Beniston <jon@beniston.com>
4 ;; Copyright (C) 2009-2014 Free Software Foundation, Inc.
6 ;; This file is part of GCC.
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.
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.
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/>.  
22 ;; Include predicate and constraint definitions
23 (include "predicates.md")
24 (include "constraints.md")
27 ;; Register numbers
28 (define_constants
29   [(RA_REGNUM           29)     ; return address register.
30   ]
33 ;; LM32 specific volatile operations
34 (define_constants
35   [(UNSPECV_BLOCKAGE    1)]     ; prevent scheduling across pro/epilog boundaries
38 ;; LM32 specific operations
39 (define_constants
40   [(UNSPEC_GOT          2)
41    (UNSPEC_GOTOFF_HI16  3)
42    (UNSPEC_GOTOFF_LO16  4)]     
45 ;; --------------------------------- 
46 ;;      instruction types
47 ;; ---------------------------------
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))
73                     
74 ;; ---------------------------------
75 ;;           scheduling 
76 ;; ---------------------------------
78 (define_automaton "lm32")
80 (define_cpu_unit "x" "lm32")
81 (define_cpu_unit "m" "lm32")
82 (define_cpu_unit "w" "lm32")
84 (define_insn_reservation "singlecycle" 1
85   (eq_attr "type" "store,arith,call,icall,ubranch,uibranch,cbranch")
86  "x")
88 (define_insn_reservation "twocycle" 2
89   (eq_attr "type" "compare,shift,divide")
90  "x,m") 
92 (define_insn_reservation "threecycle" 3
93   (eq_attr "type" "load,multiply")
94  "x,m,w")
96 ;; ---------------------------------
97 ;;               mov 
98 ;; ---------------------------------
100 (define_expand "movqi"
101   [(set (match_operand:QI 0 "general_operand" "")
102         (match_operand:QI 1 "general_operand" ""))]
103   ""
104   "
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     }
116 (define_expand "movhi"
117   [(set (match_operand:HI 0 "general_operand" "")
118         (match_operand:HI 1 "general_operand" ""))]
119   ""
120   "
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     }
132 (define_expand "movsi"
133   [(set (match_operand:SI 0 "general_operand" "")
134         (match_operand:SI 1 "general_operand" ""))]
135   ""
136   "
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     }
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     }    
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   ""
225   if (!lm32_expand_block_move (operands))
226     FAIL;
227   DONE;
230 ;; ---------------------------------
231 ;;        load/stores/moves 
232 ;; ---------------------------------
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")]
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")]
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")]
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")]
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")]   
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")]   
295 (define_insn "movsi_insn"
296   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,m,r,r,r,r,r,r")
297         (match_operand:SI 1 "general_operand" "m,r,r,J,K,L,U,S,Y,n"))]
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    ori      %0, r0, lo(%1); orhi     %0, %0, hi(%1)"
310   [(set_attr "type" "load,arith,store,store,arith,arith,arith,arith,arith,arith")]   
313 ;; ---------------------------------
314 ;;      sign and zero extension 
315 ;; ---------------------------------
317 (define_insn "*extendqihi2"
318   [(set (match_operand:HI 0 "register_operand" "=r,r")
319         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m,r")))]
320   "TARGET_SIGN_EXTEND_ENABLED || (GET_CODE (operands[1]) != REG)"
321   "@
322    lb       %0, %1
323    sextb    %0, %1"
324   [(set_attr "type" "load,arith")]
327 (define_insn "zero_extendqihi2"
328   [(set (match_operand:HI 0 "register_operand" "=r,r")
329         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m,r")))]
330   ""
331   "@
332    lbu      %0, %1
333    andi     %0, %1, 0xff"
334   [(set_attr "type" "load,arith")]  
337 (define_insn "*extendqisi2"
338   [(set (match_operand:SI 0 "register_operand" "=r,r")
339         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m,r")))]
340   "TARGET_SIGN_EXTEND_ENABLED || (GET_CODE (operands[1]) != REG)"
341   "@
342    lb       %0, %1
343    sextb    %0, %1"
344   [(set_attr "type" "load,arith")]
347 (define_insn "zero_extendqisi2"
348   [(set (match_operand:SI 0 "register_operand" "=r,r")
349         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m,r")))]
350   ""
351   "@
352    lbu      %0, %1
353    andi     %0, %1, 0xff"
354   [(set_attr "type" "load,arith")]  
357 (define_insn "*extendhisi2"
358   [(set (match_operand:SI 0 "register_operand" "=r,r")
359         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
360   "TARGET_SIGN_EXTEND_ENABLED || (GET_CODE (operands[1]) != REG)"
361   "@
362    lh       %0, %1
363    sexth    %0, %1"
364   [(set_attr "type" "load,arith")]
367 (define_insn "zero_extendhisi2"
368   [(set (match_operand:SI 0 "register_operand" "=r,r")
369         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
370   ""
371   "@
372    lhu      %0, %1
373    andi     %0, %1, 0xffff"
374   [(set_attr "type" "load,arith")]  
377 ;; ---------------------------------
378 ;;             compare 
379 ;; ---------------------------------
381 (define_expand "cstoresi4"
382   [(set (match_operand:SI 0 "register_operand")
383         (match_operator:SI 1 "ordered_comparison_operator"
384          [(match_operand:SI 2 "register_operand")
385           (match_operand:SI 3 "register_or_int_operand")]))]
386   ""
388   lm32_expand_scc (operands);
389   DONE;
392 (define_insn "*seq"
393   [(set (match_operand:SI 0 "register_operand" "=r,r")
394         (eq:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
395                (match_operand:SI 2 "register_or_K_operand" "r,K")))]
396   ""
397   "@
398    cmpe     %0, %z1, %2
399    cmpei    %0, %z1, %2"
400   [(set_attr "type" "compare")]
403 (define_insn "*sne"
404   [(set (match_operand:SI 0 "register_operand" "=r,r")
405         (ne:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
406                (match_operand:SI 2 "register_or_K_operand" "r,K")))]
407   ""
408   "@
409    cmpne    %0, %z1, %2
410    cmpnei   %0, %z1, %2"
411   [(set_attr "type" "compare")]
414 (define_insn "*sgt"
415   [(set (match_operand:SI 0 "register_operand" "=r,r")
416         (gt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
417                (match_operand:SI 2 "register_or_K_operand" "r,K")))]
418   ""
419   "@
420    cmpg     %0, %z1, %2
421    cmpgi    %0, %z1, %2"
422   [(set_attr "type" "compare")]
425 (define_insn "*sge"
426   [(set (match_operand:SI 0 "register_operand" "=r,r")
427         (ge:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
428                (match_operand:SI 2 "register_or_K_operand" "r,K")))]
429   ""
430   "@
431    cmpge    %0, %z1, %2
432    cmpgei   %0, %z1, %2"
433   [(set_attr "type" "compare")]
436 (define_insn "*sgtu"
437   [(set (match_operand:SI 0 "register_operand" "=r,r")
438         (gtu:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
439                 (match_operand:SI 2 "register_or_L_operand" "r,L")))]
440   ""
441   "@
442    cmpgu    %0, %z1, %2
443    cmpgui   %0, %z1, %2"
444   [(set_attr "type" "compare")]
447 (define_insn "*sgeu"
448   [(set (match_operand:SI 0 "register_operand" "=r,r")
449         (geu:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
450                 (match_operand:SI 2 "register_or_L_operand" "r,L")))]
451   ""
452   "@
453    cmpgeu   %0, %z1, %2
454    cmpgeui  %0, %z1, %2"
455   [(set_attr "type" "compare")]
458 ;; ---------------------------------
459 ;;       unconditional branch
460 ;; ---------------------------------
462 (define_insn "jump"
463   [(set (pc) (label_ref (match_operand 0 "" "")))]
464   ""
465   "bi       %0"
466   [(set_attr "type" "ubranch")]
469 (define_insn "indirect_jump"
470   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
471   ""
472   "b        %0"
473   [(set_attr "type" "uibranch")]
476 ;; ---------------------------------
477 ;;        conditional branch
478 ;; ---------------------------------
480 (define_expand "cbranchsi4"
481   [(set (pc)
482    (if_then_else (match_operator 0 "comparison_operator" 
483                   [(match_operand:SI 1 "register_operand")
484                    (match_operand:SI 2 "nonmemory_operand")])
485                  (label_ref (match_operand 3 "" ""))
486                  (pc)))]
487   ""
488   "
489 {   
490   lm32_expand_conditional_branch (operands);
491   DONE;
494 (define_insn "*beq"
495   [(set (pc)
496         (if_then_else (eq:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
497                              (match_operand:SI 1 "register_or_zero_operand" "rJ"))
498                       (label_ref (match_operand 2 "" ""))
499                       (pc)))]
500   ""
502   return get_attr_length (insn) == 4
503         ? "be     %z0,%z1,%2"
504         : "bne    %z0,%z1,8\n\tbi     %2";
505 }  
506   [(set_attr "type" "cbranch")])
508 (define_insn "*bne"
509   [(set (pc)
510         (if_then_else (ne:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
511                              (match_operand:SI 1 "register_or_zero_operand" "rJ"))
512                       (label_ref (match_operand 2 "" ""))
513                       (pc)))]
514   ""
516   return get_attr_length (insn) == 4
517         ? "bne    %z0,%z1,%2"
518         : "be     %z0,%z1,8\n\tbi     %2";
519 }  
520   [(set_attr "type" "cbranch")])
522 (define_insn "*bgt"
523   [(set (pc)
524         (if_then_else (gt:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
525                              (match_operand:SI 1 "register_or_zero_operand" "rJ"))
526                       (label_ref (match_operand 2 "" ""))
527                       (pc)))]
528   ""
530   return get_attr_length (insn) == 4
531         ? "bg     %z0,%z1,%2"
532         : "bge    %z1,%z0,8\n\tbi     %2";
533 }  
534   [(set_attr "type" "cbranch")])
536 (define_insn "*bge"
537   [(set (pc)
538         (if_then_else (ge:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
539                              (match_operand:SI 1 "register_or_zero_operand" "rJ"))
540                       (label_ref (match_operand 2 "" ""))
541                       (pc)))]
542   ""
544   return get_attr_length (insn) == 4
545         ? "bge    %z0,%z1,%2"
546         : "bg     %z1,%z0,8\n\tbi     %2";
547 }  
548   [(set_attr "type" "cbranch")])
550 (define_insn "*bgtu"
551   [(set (pc)
552         (if_then_else (gtu:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
553                               (match_operand:SI 1 "register_or_zero_operand" "rJ"))
554                       (label_ref (match_operand 2 "" ""))
555                       (pc)))]
556   ""
558   return get_attr_length (insn) == 4
559         ? "bgu    %z0,%z1,%2"
560         : "bgeu   %z1,%z0,8\n\tbi     %2";
561 }  
562   [(set_attr "type" "cbranch")])
564 (define_insn "*bgeu"
565   [(set (pc)
566         (if_then_else (geu:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
567                               (match_operand:SI 1 "register_or_zero_operand" "rJ"))
568                       (label_ref (match_operand 2 "" ""))
569                       (pc)))]
570   ""
572   return get_attr_length (insn) == 4
573         ? "bgeu   %z0,%z1,%2"
574         : "bgu    %z1,%z0,8\n\tbi     %2";
575 }  
576   [(set_attr "type" "cbranch")])
578 ;; ---------------------------------
579 ;;               call 
580 ;; ---------------------------------
582 (define_expand "call"
583   [(parallel [(call (match_operand 0 "" "")
584                     (match_operand 1 "" ""))
585               (clobber (reg:SI RA_REGNUM))
586              ])]
587   ""
588   "
590   rtx addr = XEXP (operands[0], 0);
591   if (!CONSTANT_ADDRESS_P (addr))
592     XEXP (operands[0], 0) = force_reg (Pmode, addr);
595 (define_insn "*call"
596   [(call (mem:SI (match_operand:SI 0 "call_operand" "r,s"))
597          (match_operand 1 "" ""))
598    (clobber (reg:SI RA_REGNUM))]
599   ""
600   "@
601    call     %0
602    calli    %0"
603   [(set_attr "type" "call,icall")]  
606 (define_expand "call_value"
607   [(parallel [(set (match_operand 0 "" "")
608                    (call (match_operand 1 "" "")
609                          (match_operand 2 "" "")))
610               (clobber (reg:SI RA_REGNUM))
611              ])]
612   ""
613   "
615   rtx addr = XEXP (operands[1], 0);
616   if (!CONSTANT_ADDRESS_P (addr))
617     XEXP (operands[1], 0) = force_reg (Pmode, addr); 
620 (define_insn "*call_value"
621   [(set (match_operand 0 "register_operand" "=r,r")
622         (call (mem:SI (match_operand:SI 1 "call_operand" "r,s"))
623               (match_operand 2 "" "")))
624    (clobber (reg:SI RA_REGNUM))]
625   ""
626   "@
627    call     %1
628    calli    %1"
629   [(set_attr "type" "call,icall")]  
632 (define_insn "return_internal"
633   [(use (match_operand:SI 0 "register_operand" "r"))
634    (return)]
635   ""
636   "b        %0"
637   [(set_attr "type" "uibranch")]  
640 (define_expand "return"
641   [(return)]
642   "lm32_can_use_return ()"
643   ""
646 (define_expand "simple_return"
647   [(simple_return)]
648   ""
649   ""
652 (define_insn "*return"
653   [(return)]
654   "reload_completed"
655   "ret"
656   [(set_attr "type" "uibranch")]  
659 (define_insn "*simple_return"
660   [(simple_return)]
661   ""
662   "ret"
663   [(set_attr "type" "uibranch")]  
666 ;; ---------------------------------
667 ;;       switch/case statements 
668 ;; ---------------------------------
669   
670 (define_expand "tablejump"
671   [(set (pc) (match_operand 0 "register_operand" ""))
672    (use (label_ref (match_operand 1 "" "")))]
673   ""
674   "
676   rtx target = operands[0];
677   if (flag_pic)
678     {
679       /* For PIC, the table entry is relative to the start of the table.  */
680       rtx label = gen_reg_rtx (SImode);
681       target = gen_reg_rtx (SImode);
682       emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1]));
683       emit_insn (gen_addsi3 (target, operands[0], label));
684     }
685   emit_jump_insn (gen_tablejumpsi (target, operands[1]));
686   DONE;
689 (define_insn "tablejumpsi"
690   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
691    (use (label_ref (match_operand 1 "" "")))]
692   ""
693   "b        %0"
694   [(set_attr "type" "ubranch")]  
697 ;; ---------------------------------
698 ;;            arithmetic 
699 ;; ---------------------------------
701 (define_insn "addsi3"
702   [(set (match_operand:SI 0 "register_operand" "=r,r")
703         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
704                  (match_operand:SI 2 "register_or_K_operand" "r,K")))]
705   ""
706   "@
707    add      %0, %z1, %2
708    addi     %0, %z1, %2"
709   [(set_attr "type" "arith")]  
712 (define_insn "subsi3"
713   [(set (match_operand:SI 0 "register_operand" "=r")
714         (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
715                   (match_operand:SI 2 "register_or_zero_operand" "rJ")))]
716   ""
717   "sub      %0, %z1, %z2"
718   [(set_attr "type" "arith")]  
721 (define_insn "mulsi3"
722   [(set (match_operand:SI 0 "register_operand" "=r,r")
723         (mult:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
724                  (match_operand:SI 2 "register_or_K_operand" "r,K")))]
725   "TARGET_MULTIPLY_ENABLED"
726   "@
727    mul      %0, %z1, %2
728    muli     %0, %z1, %2"
729   [(set_attr "type" "multiply")]
732 (define_insn "udivsi3"
733   [(set (match_operand:SI 0 "register_operand" "=r")
734         (udiv:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
735                  (match_operand:SI 2 "register_operand" "r")))]
736   "TARGET_DIVIDE_ENABLED"
737   "divu     %0, %z1, %2"
738   [(set_attr "type" "divide")]
741 (define_insn "umodsi3"
742   [(set (match_operand:SI 0 "register_operand" "=r")
743         (umod:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
744                  (match_operand:SI 2 "register_operand" "r")))]
745   "TARGET_DIVIDE_ENABLED"
746   "modu     %0, %z1, %2"
747   [(set_attr "type" "divide")]
750 ;; ---------------------------------
751 ;;      negation and inversion 
752 ;; ---------------------------------
753                
754 (define_insn "negsi2"
755   [(set (match_operand:SI 0 "register_operand" "=r")
756         (neg:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")))]
757   ""
758   "sub      %0, r0, %z1"
759   [(set_attr "type" "arith")]
760 )      
762 (define_insn "one_cmplsi2"
763   [(set (match_operand:SI 0 "register_operand" "=r")
764         (not:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")))]
765   ""
766   "not      %0, %z1"
767   [(set_attr "type" "arith")]
770 ;; ---------------------------------
771 ;;             logical 
772 ;; ---------------------------------
774 (define_insn "andsi3"
775   [(set (match_operand:SI 0 "register_operand" "=r,r")
776         (and:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
777                 (match_operand:SI 2 "register_or_L_operand" "r,L")))]
778   ""
779   "@
780    and      %0, %z1, %2
781    andi     %0, %z1, %2"
782   [(set_attr "type" "arith")]
785 (define_insn "iorsi3"
786   [(set (match_operand:SI 0 "register_operand" "=r,r")
787         (ior:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
788                 (match_operand:SI 2 "register_or_L_operand" "r,L")))]
789   ""
790   "@
791    or       %0, %z1, %2
792    ori      %0, %z1, %2"
793   [(set_attr "type" "arith")]
796 (define_insn "xorsi3"
797   [(set (match_operand:SI 0 "register_operand" "=r,r")
798         (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
799                 (match_operand:SI 2 "register_or_L_operand" "r,L")))]
800   ""
801   "@
802    xor      %0, %z1, %2
803    xori     %0, %z1, %2"
804   [(set_attr "type" "arith")]
807 (define_insn "*norsi3"
808   [(set (match_operand:SI 0 "register_operand" "=r,r")
809         (not:SI (ior:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
810                         (match_operand:SI 2 "register_or_L_operand" "r,L"))))]
811   ""
812   "@ 
813    nor      %0, %z1, %2
814    nori     %0, %z1, %2"                
815   [(set_attr "type" "arith")]
816 )                
818 (define_insn "*xnorsi3"
819   [(set (match_operand:SI 0 "register_operand" "=r,r")
820         (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
821                         (match_operand:SI 2 "register_or_L_operand" "r,L"))))]
822   ""
823   "@
824    xnor     %0, %z1, %2
825    xnori    %0, %z1, %2"                
826   [(set_attr "type" "arith")]
827 )                
829 ;; ---------------------------------
830 ;;              shifts 
831 ;; ---------------------------------
833 (define_expand "ashlsi3"
834   [(set (match_operand:SI 0 "register_operand" "")
835         (ashift:SI (match_operand:SI 1 "register_or_zero_operand" "")
836                    (match_operand:SI 2 "register_or_L_operand" "")))]
837   ""
839   if (!TARGET_BARREL_SHIFT_ENABLED)
840     {
841       if (!optimize_size 
842           && satisfies_constraint_L (operands[2])
843           && INTVAL (operands[2]) <= 8)
844         {
845           int i;
846           int shifts = INTVAL (operands[2]);
847           
848           if (shifts == 0)
849             emit_move_insn (operands[0], operands[1]);
850           else
851             emit_insn (gen_addsi3 (operands[0], operands[1], operands[1]));
852           for (i = 1; i < shifts; i++) 
853             emit_insn (gen_addsi3 (operands[0], operands[0], operands[0]));
854           DONE;                  
855         }
856       else
857         FAIL;
858     }
859 })  
861 (define_insn "*ashlsi3"
862   [(set (match_operand:SI 0 "register_operand" "=r,r")
863         (ashift:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
864                    (match_operand:SI 2 "register_or_L_operand" "r,L")))]
865   "TARGET_BARREL_SHIFT_ENABLED"
866   "@ 
867    sl       %0, %z1, %2
868    sli      %0, %z1, %2"
869   [(set_attr "type" "shift")]
872 (define_expand "ashrsi3"
873   [(set (match_operand:SI 0 "register_operand" "")
874         (ashiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "")
875                      (match_operand:SI 2 "register_or_L_operand" "")))]
876   ""
878   if (!TARGET_BARREL_SHIFT_ENABLED)
879     {
880       if (!optimize_size 
881           && satisfies_constraint_L (operands[2])
882           && INTVAL (operands[2]) <= 8)
883         {
884           int i;
885           int shifts = INTVAL (operands[2]);
886           rtx one = GEN_INT (1);
887           
888           if (shifts == 0)
889             emit_move_insn (operands[0], operands[1]);
890           else
891             emit_insn (gen_ashrsi3_1bit (operands[0], operands[1], one));
892           for (i = 1; i < shifts; i++) 
893             emit_insn (gen_ashrsi3_1bit (operands[0], operands[0], one));
894           DONE;                  
895         }
896       else
897         FAIL;
898     }
899 })  
900                        
901 (define_insn "*ashrsi3"
902   [(set (match_operand:SI 0 "register_operand" "=r,r")
903         (ashiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
904                      (match_operand:SI 2 "register_or_L_operand" "r,L")))]
905   "TARGET_BARREL_SHIFT_ENABLED"
906   "@
907    sr       %0, %z1, %2
908    sri      %0, %z1, %2"
909   [(set_attr "type" "shift")]
912 (define_insn "ashrsi3_1bit"
913   [(set (match_operand:SI 0 "register_operand" "=r")
914         (ashiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
915                      (match_operand:SI 2 "constant_M_operand" "M")))]
916   "!TARGET_BARREL_SHIFT_ENABLED"
917   "sri      %0, %z1, %2"
918   [(set_attr "type" "shift")]
921 (define_expand "lshrsi3"
922   [(set (match_operand:SI 0 "register_operand" "")
923         (lshiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "")
924                      (match_operand:SI 2 "register_or_L_operand" "")))]
925   ""
927   if (!TARGET_BARREL_SHIFT_ENABLED)
928     {
929       if (!optimize_size 
930           && satisfies_constraint_L (operands[2])
931           && INTVAL (operands[2]) <= 8)
932         {
933           int i;
934           int shifts = INTVAL (operands[2]);
935           rtx one = GEN_INT (1);
936           
937           if (shifts == 0)
938             emit_move_insn (operands[0], operands[1]);
939           else
940             emit_insn (gen_lshrsi3_1bit (operands[0], operands[1], one));
941           for (i = 1; i < shifts; i++) 
942             emit_insn (gen_lshrsi3_1bit (operands[0], operands[0], one));
943           DONE;                  
944         }
945       else
946         FAIL;
947     }
948 })  
950 (define_insn "*lshrsi3"
951   [(set (match_operand:SI 0 "register_operand" "=r,r")
952         (lshiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
953                      (match_operand:SI 2 "register_or_L_operand" "r,L")))]
954   "TARGET_BARREL_SHIFT_ENABLED"
955   "@ 
956    sru      %0, %z1, %2
957    srui     %0, %z1, %2"
958   [(set_attr "type" "shift")]   
961 (define_insn "lshrsi3_1bit"
962   [(set (match_operand:SI 0 "register_operand" "=r")
963         (lshiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
964                      (match_operand:SI 2 "constant_M_operand" "M")))]
965   "!TARGET_BARREL_SHIFT_ENABLED"
966   "srui     %0, %z1, %2"
967   [(set_attr "type" "shift")]   
970 ;; ---------------------------------
971 ;;     function entry / exit 
972 ;; ---------------------------------
974 (define_expand "prologue"
975   [(const_int 1)]
976   ""
977   "
979   lm32_expand_prologue ();
980   DONE;
983 (define_expand "epilogue"
984   [(return)]
985   ""
986   "
988   lm32_expand_epilogue ();
989   DONE;
992 ;; ---------------------------------
993 ;;              nop 
994 ;; ---------------------------------
996 (define_insn "nop"  
997   [(const_int 0)]
998   ""
999   "nop"
1000   [(set_attr "type" "arith")]
1003 ;; ---------------------------------
1004 ;;             blockage 
1005 ;; ---------------------------------
1007 ;; used to stop the scheduler from 
1008 ;; scheduling code across certain boundaries
1010 (define_insn "blockage"
1011   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
1012   ""
1013   ""
1014   [(set_attr "length" "0")]