No empty .Rs/.Re
[netbsd-mini2440.git] / gnu / dist / gcc4 / gcc / config / mt / mt.md
blobc6f3cb39f1642e50f3c3de23cfd784b53109cbcc
1 ;; Machine description for MorphoRISC1
2 ;; Copyright (C) 2005 Free Software Foundation, Inc.
3 ;; Contributed by Red Hat, Inc.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
10 ;; any later version.
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING.  If not, write to the Free
19 ;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 ;; 02110-1301, USA.
22 ;; UNSPECs
23 (define_constants
24   [
25     (UNSPEC_BLOCKAGE 0)
26     (UNSPEC_EI 1)
27     (UNSPEC_DI 2)
28   ])
30 ;; Attributes
31 (define_attr "type" "branch,call,load,store,io,arith,complex,unknown"
32          (const_string "unknown") )
34 ;; If the attribute takes numeric values, no `enum' type will be defined and
35 ;; the function to obtain the attribute's value will return `int'.
37 (define_attr "length" "" (const_int 4))
40 ;; DFA scheduler.
41 (define_automaton "other")
42 (define_cpu_unit "decode_unit" "other")
43 (define_cpu_unit "memory_unit" "other")
44 (define_cpu_unit "branch_unit" "other")
46 (define_insn_reservation "mem_access" 2
47   (ior (eq_attr "type" "load") (eq_attr "type" "store"))
48   "decode_unit+memory_unit*2")
50 (define_insn_reservation "io_access" 2
51   (eq_attr "type" "io")
52   "decode_unit+memory_unit*2")
54 (define_insn_reservation "branch_access" 2
55   (ior (eq_attr "type" "branch")
56        (eq_attr "type" "call"))
57   "decode_unit+branch_unit*2")
59 (define_insn_reservation "arith_access" 1
60   (eq_attr "type" "arith")
61   "decode_unit")
63 (define_bypass 2 "arith_access" "branch_access")
64 (define_bypass 3 "mem_access" "branch_access")
65 (define_bypass 3 "io_access" "branch_access")
68 ;; Delay Slots
70 ;; The mt does not allow branches in the delay slot.
71 ;; The mt does not allow back to back memory or io instruction.
72 ;; The compiler does not know what the type of instruction is at
73 ;; the destination of the branch.  Thus, only type that will be acceptable
74 ;; (safe) is the arith type.
76 (define_delay (ior (eq_attr "type" "branch")
77                    (eq_attr "type" "call"))
78                  [(eq_attr "type" "arith") (nil) (nil)])
81 (define_insn "decrement_and_branch_until_zero"
82    [(set (pc)
83          (if_then_else
84           (ne (match_operand:SI 0 "nonimmediate_operand" "+r,*m")
85               (const_int 0))
86           (label_ref (match_operand 1 "" ""))
87           (pc)))
88     (set (match_dup 0)
89          (plus:SI (match_dup 0)
90                   (const_int -1)))
91     (clobber (match_scratch:SI 2 "=X,&r"))
92     (clobber (match_scratch:SI 3 "=X,&r"))]
93   "TARGET_MS1_16_003 || TARGET_MS2"
94   "@
95    dbnz\t%0, %l1%#
96    #"
97   [(set_attr "length" "4,16")
98    (set_attr "type" "branch,unknown")]
101 ;; Split the above to handle the case where operand 0 is in memory
102 ;; (a register that couldn't get a hard register).
103 (define_split
104   [(set (pc)
105         (if_then_else
106           (ne (match_operand:SI 0 "memory_operand" "")
107               (const_int 0))
108           (label_ref (match_operand 1 "" ""))
109           (pc)))
110     (set (match_dup 0)
111          (plus:SI (match_dup 0)
112                   (const_int -1)))
113     (clobber (match_scratch:SI 2 ""))
114     (clobber (match_scratch:SI 3 ""))]
115   "TARGET_MS1_16_003 || TARGET_MS2"
116   [(set (match_dup 2) (match_dup 0))
117    (set (match_dup 3) (plus:SI (match_dup 2) (const_int -1)))
118    (set (match_dup 0) (match_dup 3))
119    (set (pc)
120         (if_then_else
121          (ne (match_dup 2)
122              (const_int 0))
123          (label_ref (match_dup 1))
124          (pc)))]
125   "")
127 ;; This peephole is defined in the vain hope that it might actually trigger one
128 ;; day, although I have yet to find a test case that matches it.  The normal
129 ;; problem is that GCC likes to move the loading of the constant value -1 out
130 ;; of the loop, so it is not here to be matched.
132 (define_peephole2
133   [(set (match_operand:SI 0 "register_operand" "")
134         (plus:SI (match_dup 0) (const_int -1)))
135    (set (match_operand:SI 1 "register_operand" "")
136      (const_int -1))
137    (set (pc) (if_then_else
138                 (ne (match_dup 0) (match_dup 1))
139                 (label_ref (match_operand 2 "" ""))
140                 (pc)))]
141   "TARGET_MS1_16_003 || TARGET_MS2"
142   [(parallel [(set (pc)
143                    (if_then_else
144                       (ne (match_dup 0) (const_int 0))
145                       (label_ref (match_dup 2))
146                       (pc)))
147               (set (match_dup 0)
148                    (plus:SI (match_dup 0) (const_int -1)))
149               (clobber (reg:SI 0))
150               (clobber (reg:SI 0))])]
151   "")
154 ;; Moves
156 (define_expand "loadqi"
157   [
158    ;; compute shift
159    (set (match_operand:SI 2 "register_operand" "")
160         (and:SI (match_dup 1) (const_int 3)))
161    (set (match_dup 2)   (xor:SI (match_dup 2) (const_int 3)))
162    (set (match_dup 2 )  (ashift:SI (match_dup 2) (const_int 3)))
164    ;; get word that contains byte
165    (set (match_operand:SI 0 "register_operand" "")
166         (mem:SI (and:SI (match_operand:SI 1 "register_operand" "")
167                         (const_int -3))))
169    ;; align byte
170    (set (match_dup 0)   (ashiftrt:SI (match_dup 0) (match_dup 2)))
171   ]
172   ""
173   "")
176 ;; storeqi
177 ;; operand 0 byte value to store
178 ;; operand 1 address
179 ;; operand 2 temp, word containing byte
180 ;; operand 3 temp, shift count
181 ;; operand 4 temp, mask, aligned and masked byte
182 ;; operand 5 (unused)
183 (define_expand "storeqi"
184   [
185    ;; compute shift
186    (set (match_operand:SI 3 "register_operand" "")
187         (and:SI (match_operand:SI 1 "register_operand" "") (const_int 3)))
188    (set (match_dup 3)   (xor:SI (match_dup 3) (const_int 3)))
189    (set (match_dup 3)   (ashift:SI (match_dup 3) (const_int 3)))
191    ;; get word that contains byte
192    (set (match_operand:SI 2 "register_operand" "")
193         (mem:SI (and:SI (match_dup 1) (const_int -3))))
195    ;; generate mask
196    (set (match_operand:SI 4 "register_operand" "") (const_int 255))
197    (set (match_dup 4) (ashift:SI (match_dup 4) (match_dup 3)))
198    (set (match_dup 4) (not:SI (match_dup 4)))
200    ;; clear appropriate bits
201    (set (match_dup 2) (and:SI (match_dup 2) (match_dup 4)))
203    ;; align byte
204    (set (match_dup 4)
205         (and:SI (match_operand:SI 0 "register_operand" "") (const_int 255)))
206    (set (match_dup 4) (ashift:SI (match_dup 4) (match_dup 3)))
208    ;; combine
209    (set (match_dup 2) (ior:SI (match_dup 4) (match_dup 2)))
210    ;; store updated word
211    (set (mem:SI (and:SI (match_dup 1) (const_int -3))) (match_dup 2))
212   ]
213   ""
214   "")
217 (define_expand "movqi"
218   [(set (match_operand:QI 0 "general_operand" "")
219         (match_operand:QI 1 "general_operand" ""))]
220   ""
221   "
223   if (!reload_in_progress
224       && !reload_completed
225       && GET_CODE (operands[0]) == MEM
226       && GET_CODE (operands[1]) == MEM)
227     operands[1] = copy_to_mode_reg (QImode, operands[1]);
228   
229   if ( (! TARGET_BYTE_ACCESS) && GET_CODE (operands[0]) == MEM)
230     {
231         rtx scratch1 = gen_reg_rtx (SImode);
232         rtx scratch2 = gen_reg_rtx (SImode);
233         rtx scratch3 = gen_reg_rtx (SImode);
234         rtx data     = operands[1];
235         rtx address  = XEXP (operands[0], 0);
236         rtx seq;
238         if ( GET_CODE (data) != REG )
239             data = copy_to_mode_reg (QImode, data);
241         if ( GET_CODE (address) != REG )
242           address = copy_to_mode_reg (SImode, address);
244         start_sequence ();
245         emit_insn (gen_storeqi (gen_lowpart (SImode, data), address,
246                                 scratch1, scratch2, scratch3));
247         mt_set_memflags (operands[0]);
248         seq = get_insns ();
249         end_sequence ();
250         emit_insn (seq);
251         DONE;
252     }
254   if ( (! TARGET_BYTE_ACCESS) && GET_CODE (operands[1]) == MEM)
255     {
256         rtx scratch1 = gen_reg_rtx (SImode);
257         rtx data = operands[0];
258         rtx address = XEXP (operands[1], 0);
259         rtx seq;
261         if ( GET_CODE (address) != REG )
262           address = copy_to_mode_reg (SImode, address);
264         start_sequence ();
265         emit_insn (gen_loadqi (gen_lowpart (SImode, data), address, scratch1));
266         mt_set_memflags (operands[1]);
267         seq = get_insns ();
268         end_sequence ();
269         emit_insn (seq);
270         DONE;
271     }
273    /* If the load is a pseudo register in a stack slot, some simplification
274       can be made because the loads are aligned */
275   if ( (! TARGET_BYTE_ACCESS) 
276         && (reload_in_progress && GET_CODE (operands[1]) == SUBREG
277           && GET_CODE (SUBREG_REG (operands[1])) == REG
278           && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
279     {
280         rtx data = operands[0];
281         rtx address = XEXP (operands[1], 0);
282         rtx seq;
284         start_sequence ();
285         emit_insn (gen_movsi (gen_lowpart (SImode, data), address));
286         mt_set_memflags (operands[1]);
287         seq = get_insns ();
288         end_sequence ();
289         emit_insn (seq);
290         DONE;
291     }
294 (define_insn "*movqi_internal"
295   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r")
296         (match_operand:QI 1 "general_operand" "r,m,r,I"))]
297   "TARGET_BYTE_ACCESS
298     && (!memory_operand (operands[0], QImode)
299         || !memory_operand (operands[1], QImode))"
300   "@
301    or  %0, %1, %1
302    ldb %0, %1
303    stb %1, %0
304    addi %0, r0, %1"
305   [(set_attr "length" "4,4,4,4")
306    (set_attr "type" "arith,load,store,arith")])
308 (define_insn "*movqi_internal_nobyte"
309   [(set (match_operand:QI 0 "register_operand" "=r,r")
310         (match_operand:QI 1 "arith_operand" "r,I"))]
311   "!TARGET_BYTE_ACCESS
312     && (!memory_operand (operands[0], QImode)
313         || !memory_operand (operands[1], QImode))"
314   "@
315    or   %0, %1, %1
316    addi %0, r0, %1"
317   [(set_attr "length" "4,4")
318    (set_attr "type" "arith,arith")])
321 ;; The MorphoRISC does not have 16-bit loads and stores.
322 ;; These operations must be synthesized.  Note that the code
323 ;; for loadhi and storehi assumes that the least significant bits
324 ;; is ignored.
326 ;; loadhi
327 ;; operand 0 location of result
328 ;; operand 1 memory address
329 ;; operand 2 temp
330 (define_expand "loadhi"
331   [
332    ;; compute shift
333    (set (match_operand:SI 2 "register_operand" "")
334         (and:SI (match_dup 1) (const_int 2)))
335    (set (match_dup 2)   (xor:SI (match_dup 2) (const_int 2)))
336    (set (match_dup 2 )  (ashift:SI (match_dup 2) (const_int 3)))
338    ;; get word that contains the 16-bits
339    (set (match_operand:SI 0 "register_operand" "")
340         (mem:SI (and:SI (match_operand:SI 1 "register_operand" "")
341                         (const_int -3))))
343    ;; align 16-bit value
344    (set (match_dup 0)   (ashiftrt:SI (match_dup 0) (match_dup 2)))
345   ]
346   ""
347   "")
349 ;; storehi
350 ;; operand 0 byte value to store
351 ;; operand 1 address
352 ;; operand 2 temp, word containing byte
353 ;; operand 3 temp, shift count
354 ;; operand 4 temp, mask, aligned and masked byte
355 ;; operand 5 (unused)
356 (define_expand "storehi"
357   [
358    ;; compute shift
359    (set (match_operand:SI 3 "register_operand" "")
360         (and:SI (match_operand:SI 1 "register_operand" "") (const_int 2)))
361    (set (match_dup 3)   (xor:SI (match_dup 3) (const_int 2)))
362    (set (match_dup 3)   (ashift:SI (match_dup 3) (const_int 3)))
364    ;; get word that contains the 16-bits
365    (set (match_operand:SI 2 "register_operand" "")
366         (mem:SI (and:SI (match_dup 1) (const_int -3))))
368    ;; generate mask
369    (set (match_operand:SI 4 "register_operand" "") (const_int 65535))
370    (set (match_dup 4) (ashift:SI (match_dup 4) (match_dup 3)))
371    (set (match_dup 4) (not:SI (match_dup 4)))
373    ;; clear appropriate bits
374    (set (match_dup 2) (and:SI (match_dup 2) (match_dup 4)))
376    ;; align 16-bit value
377    (set (match_dup 4)
378         (and:SI (match_operand:SI 0 "register_operand" "") (const_int 65535)))
379    (set (match_dup 4) (ashift:SI (match_dup 4) (match_dup 3)))
381    ;; combine
382    (set (match_dup 2) (ior:SI (match_dup 4) (match_dup 2)))
383    ;; store updated word
384    (set (mem:SI (and:SI (match_dup 1) (const_int -3))) (match_dup 2))
385   ]
386   ""
387   "")
390 (define_expand "movhi"
391   [(set (match_operand:HI 0 "general_operand" "")
392         (match_operand:HI 1 "general_operand" ""))]
393   ""
394   "
396   if (!reload_in_progress
397       && !reload_completed
398       && GET_CODE (operands[0]) == MEM
399       && GET_CODE (operands[1]) == MEM)
400     operands[1] = copy_to_mode_reg (HImode, operands[1]);
402   if ( GET_CODE (operands[0]) == MEM)
403     {
404         rtx scratch1 = gen_reg_rtx (SImode);
405         rtx scratch2 = gen_reg_rtx (SImode);
406         rtx scratch3 = gen_reg_rtx (SImode);
407         rtx data     = operands[1];
408         rtx address  = XEXP (operands[0], 0);
409         rtx seq;
411         if (GET_CODE (data) != REG)
412           data = copy_to_mode_reg (HImode, data);
414         if (GET_CODE (address) != REG)
415           address = copy_to_mode_reg (SImode, address);
417         start_sequence ();
418         emit_insn (gen_storehi (gen_lowpart (SImode, data), address,
419                                 scratch1, scratch2, scratch3));
420         mt_set_memflags (operands[0]);
421         seq = get_insns ();
422         end_sequence ();
423         emit_insn (seq);
424         DONE;
425     }
427   if ( GET_CODE (operands[1]) == MEM)
428     {
429         rtx scratch1 = gen_reg_rtx (SImode);
430         rtx data     = operands[0];
431         rtx address  = XEXP (operands[1], 0);
432         rtx seq;
434         if (GET_CODE (address) != REG)
435             address = copy_to_mode_reg (SImode, address);
437         start_sequence ();
438         emit_insn (gen_loadhi (gen_lowpart (SImode, data), address,
439                                scratch1));
440         mt_set_memflags (operands[1]);
441         seq = get_insns ();
442         end_sequence ();
443         emit_insn (seq);
444         DONE;
445     }
447    /* If the load is a pseudo register in a stack slot, some simplification
448       can be made because the loads are aligned */
449   if ( (reload_in_progress && GET_CODE (operands[1]) == SUBREG
450           && GET_CODE (SUBREG_REG (operands[1])) == REG
451           && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
452     {
453         rtx data = operands[0];
454         rtx address = XEXP (operands[1], 0);
455         rtx seq;
457         start_sequence ();
458         emit_insn (gen_movsi (gen_lowpart (SImode, data), address));
459         mt_set_memflags (operands[1]);
460         seq = get_insns ();
461         end_sequence ();
462         emit_insn (seq);
463         DONE;
464     }
467 (define_insn "*movhi_internal"
468   [(set (match_operand:HI 0 "register_operand" "=r,r")
469         (match_operand:HI 1 "arith_operand" "r,I"))]
470   "!memory_operand (operands[0], HImode) || !memory_operand (operands[1], HImode)"
471   "@
472   or    %0, %1, %1
473   addi  %0, r0, %1"
474   [(set_attr "length" "4,4")
475    (set_attr "type" "arith,arith")])
477 (define_expand "movsi"
478   [(set (match_operand:SI 0 "nonimmediate_operand" "")
479         (match_operand:SI 1 "general_operand" ""))]
480   ""
481   "
483   if (!reload_in_progress  && !reload_completed
484       && !register_operand (operands[0], SImode)
485       && !register_operand (operands[1], SImode))
486     operands[1] = copy_to_mode_reg (SImode, operands[1]);
488   /* Take care of constants that don't fit in single instruction */
489   if ( (reload_in_progress || reload_completed)
490    && !single_const_operand (operands[1], SImode))
491     {
492       emit_insn (gen_movsi_high (operands[0], operands[1]));
493       emit_insn (gen_movsi_lo_sum (operands[0], operands[0], operands[1]));
494       DONE;
495     }
499 (define_insn "movsi_high"
500   [(set (match_operand:SI 0 "register_operand" "=r")
501         (high:SI (match_operand:SI 1 "general_operand" "i")))]
502   ""
503   "*
505   return \"ldui\\t%0, %H1\";
507   [(set_attr "length" "4")
508    (set_attr "type" "arith")])
511 (define_insn "movsi_lo_sum"
512   [(set (match_operand:SI 0 "register_operand" "=r")
513         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
514                    (match_operand:SI 2 "general_operand" "i")))]
515   ""
516   "*
518   return \"addui\\t%0, %1, %L2\";
520   [(set_attr "length" "4")
521    (set_attr "type" "arith")])
523 /* Take care of constants that don't fit in single instruction */
524 (define_split
525   [(set (match_operand:SI 0 "register_operand" "")
526         (match_operand:SI 1 "general_operand" ""))]
527   "(reload_in_progress || reload_completed)
528    && !single_const_operand (operands[1], SImode)"
530   [(set (match_dup 0 )
531         (high:SI (match_dup 1)))
532    (set (match_dup 0 )
533         (lo_sum:SI (match_dup 0)
534                    (match_dup 1)))]
538 ;; The last pattern in movsi (with two instructions)
539 ;; is really handled by the emit_insn's in movsi
540 ;; and the define_split above.  This provides additional
541 ;; instructions to fill delay slots.
543 ;; Note - it is best to only have one movsi pattern and to handle
544 ;; all the various contingencies by the use of alternatives.  This
545 ;; allows reload the greatest amount of flexibility (since reload will
546 ;; only choose amoungst alternatives for a selected insn, it will not
547 ;; replace the insn with another one).
548 (define_insn "*movsi_internal"
549   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,r")
550         (match_operand:SI 1 "general_operand"       "r,m,r,I,P,L,N,i"))]
551   "(!memory_operand (operands[0], SImode) || !memory_operand (operands[1], SImode))
552    && !((reload_in_progress || reload_completed)
553          && !single_const_operand (operands[1], SImode))"
554   "@
555   or     %0, %1, %1
556   ldw    %0, %1
557   stw    %1, %0
558   addi   %0, r0, %1
559   addui  %0, r0, %1
560   ldui   %0, %H1
561   nori   %0, r0, %N1
562   ldui   %0, %H1\;addui %0, %0, %L1"
563   [(set_attr "length" "4,4,4,4,4,4,4,8")
564    (set_attr "type" "arith,load,store,arith,arith,arith,arith,complex")]
567 ;; Floating Point Moves
569 ;; Note - Patterns for SF mode moves are compulsory, but
570 ;; patterns for DF are optional, as GCC can synthesize them.
572 (define_expand "movsf"
573   [(set (match_operand:SF 0 "general_operand" "")
574         (match_operand:SF 1 "general_operand" ""))]
575   ""
576   "
578   if (!reload_in_progress
579       && !reload_completed
580       && GET_CODE (operands[0]) == MEM
581       && (GET_CODE (operands[1]) == MEM
582          || GET_CODE (operands[1]) == CONST_DOUBLE))
583     operands[1] = copy_to_mode_reg (SFmode, operands[1]);
585   /* Take care of reg <- SF constant */
586   if ( const_double_operand (operands[1], GET_MODE (operands[1]) ) )
587     {
588       emit_insn (gen_movsf_high (operands[0], operands[1]));
589       emit_insn (gen_movsf_lo_sum (operands[0], operands[0], operands[1]));
590       DONE;
591     }
594 (define_insn "movsf_lo_sum"
595   [(set (match_operand:SF 0 "register_operand" "=r")
596         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
597                    (match_operand:SF 2 "const_double_operand" "")))]
598   ""
599   "*
601   REAL_VALUE_TYPE r;
602   long i;
604   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
605   REAL_VALUE_TO_TARGET_SINGLE (r, i);
606   operands[2] = GEN_INT (i);
607   return \"addui\\t%0, %1, %L2\";
609   [(set_attr "length" "4")
610    (set_attr "type" "arith")])
612 (define_insn "movsf_high"
613   [(set (match_operand:SF 0 "register_operand" "=r")
614         (high:SF (match_operand:SF 1 "const_double_operand" "")))]
615   ""
616   "*
618   REAL_VALUE_TYPE r;
619   long i;
621   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
622   REAL_VALUE_TO_TARGET_SINGLE (r, i);
623   operands[1] = GEN_INT (i);
624   return \"ldui\\t%0, %H1\";
626   [(set_attr "length" "4")
627    (set_attr "type" "arith")])
630 (define_insn "*movsf_internal"
631   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
632         (match_operand:SF 1 "nonimmediate_operand" "r,m,r"))]
633   "!memory_operand (operands[0], SFmode) || !memory_operand (operands[1], SFmode)"
634   "@
635   or     %0, %1, %1
636   ldw    %0, %1
637   stw    %1, %0"
638   [(set_attr "length" "4,4,4")
639    (set_attr "type" "arith,load,store")]
642 (define_expand "movdf"
643   [(set (match_operand:DF 0 "general_operand" "")
644         (match_operand:DF 1 "general_operand" ""))]
645   ""
646   "
648   /* One of the ops has to be in a register or 0 */
649   if (!register_operand (operand0, DFmode)
650       && !reg_or_0_operand (operand1, DFmode))
651     operands[1] = copy_to_mode_reg (DFmode, operand1);
654 (define_insn_and_split "*movdf_internal"
655   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,o")
656         (match_operand:DF 1 "general_operand"      "rim,r"))]
657   "! (memory_operand (operands[0], DFmode)
658          && memory_operand (operands[1], DFmode))"
659   "#"
661   "(reload_completed || reload_in_progress)"
663   [(set (match_dup 2) (match_dup 3))
664    (set (match_dup 4) (match_dup 5))
665   ]
667   "{
668     /* figure out what precisely to put into operands 2, 3, 4, and 5 */
669     mt_split_words (SImode, DFmode, operands);
670   }"
674 ;; Reloads
676 ;; Like `movM', but used when a scratch register is required to move between
677 ;; operand 0 and operand 1.  Operand 2 describes the scratch register.  See the
678 ;; discussion of the `SECONDARY_RELOAD_CLASS' macro.
680 (define_expand "reload_inqi"
681   [(set (match_operand:QI 0 "register_operand" "=r")
682         (match_operand:QI 1 "memory_operand" "m"))
683    (clobber (match_operand:DI 2 "register_operand" "=&r"))]
684   "! TARGET_BYTE_ACCESS"
685   "
687   rtx scratch1 = gen_rtx_REG (SImode, REGNO (operands[2]));
688   rtx scratch2 = gen_rtx_REG (SImode, REGNO (operands[2])+1);
689   rtx data = operands[0];
690   rtx address = XEXP (operands[1], 0);
691   rtx swap, seq;
693   /* It is possible that the registers we got for scratch1
694      might coincide with that of operands[0].  gen_loadqi
695      requires operand0 and operand2 to be different registers.
696      The following statement ensure that is always the case. */
697   if (REGNO(operands[0]) == REGNO(scratch1))
698     {
699         swap = scratch1;
700         scratch1 = scratch2;
701         scratch2 = swap;
702     }
704   /* need to make sure address is already in register */
705   if ( GET_CODE (address) != REG )
706     address = force_operand (address, scratch2);
708   start_sequence ();
709   emit_insn (gen_loadqi (gen_lowpart (SImode, data), address, scratch1));
710   mt_set_memflags (operands[1]);
711   seq = get_insns ();
712   end_sequence ();
713   emit_insn (seq);
714   DONE;
717 (define_expand "reload_outqi"
718   [(set (match_operand:QI 0 "memory_operand" "=m")
719         (match_operand:QI 1 "register_operand" "r"))
720    (clobber (match_operand:TI 2 "register_operand" "=&r"))]
721   "! TARGET_BYTE_ACCESS"
722   "
724   rtx scratch1 = gen_rtx_REG (SImode, REGNO (operands[2]));
725   rtx scratch2 = gen_rtx_REG (SImode, REGNO (operands[2])+1);
726   rtx scratch3 = gen_rtx_REG (SImode, REGNO (operands[2])+2);
727   rtx scratch4 = gen_rtx_REG (SImode, REGNO (operands[2])+3);
728   rtx data     = operands[1];
729   rtx address  = XEXP (operands[0], 0);
730   rtx seq;
732   /* need to make sure address is already in register */
733   if ( GET_CODE (address) != REG )
734     address = force_operand (address, scratch4);
736   start_sequence ();
737   emit_insn (gen_storeqi (gen_lowpart (SImode, data), address, 
738                           scratch1, scratch2, scratch3));
739   mt_set_memflags (operands[0]);
740   seq = get_insns ();
741   end_sequence ();
742   emit_insn (seq);
743   DONE;
746 (define_expand "reload_inhi"
747   [(set (match_operand:HI 0 "register_operand" "=r")
748         (match_operand:HI 1 "memory_operand" "m"))
749    (clobber (match_operand:DI 2 "register_operand" "=&r"))]
750   ""
751   "
753   rtx scratch1 = gen_rtx_REG (SImode, REGNO (operands[2]));
754   rtx scratch2 = gen_rtx_REG (SImode, REGNO (operands[2])+1);
755   rtx data     = operands[0];
756   rtx address  = XEXP (operands[1], 0);
757   rtx swap, seq;
759   /* It is possible that the registers we got for scratch1
760      might coincide with that of operands[0].  gen_loadqi
761      requires operand0 and operand2 to be different registers.
762      The following statement ensure that is always the case. */
763   if (REGNO(operands[0]) == REGNO(scratch1))
764     {
765         swap = scratch1;
766         scratch1 = scratch2;
767         scratch2 = swap;
768     }
770   /* need to make sure address is already in register */
771   if ( GET_CODE (address) != REG )
772     address = force_operand (address, scratch2);
774   start_sequence ();
775   emit_insn (gen_loadhi (gen_lowpart (SImode, data), address,
776                          scratch1));
777   mt_set_memflags (operands[1]);
778   seq = get_insns ();
779   end_sequence ();
780   emit_insn (seq);
781   DONE;
784 (define_expand "reload_outhi"
785   [(set (match_operand:HI 0 "memory_operand" "=m")
786         (match_operand:HI 1 "register_operand" "r"))
787    (clobber (match_operand:TI 2 "register_operand" "=&r"))]
788   ""
789   "
791   rtx scratch1 = gen_rtx_REG (SImode, REGNO (operands[2]));
792   rtx scratch2 = gen_rtx_REG (SImode, REGNO (operands[2])+1);
793   rtx scratch3 = gen_rtx_REG (SImode, REGNO (operands[2])+2);
794   rtx scratch4 = gen_rtx_REG (SImode, REGNO (operands[2])+3);
795   rtx data     = operands[1];
796   rtx address  = XEXP (operands[0], 0);
797   rtx seq;
799   /* need to make sure address is already in register */
800   if ( GET_CODE (address) != REG )
801     address = force_operand (address, scratch4);
803   start_sequence ();
804   emit_insn (gen_storehi (gen_lowpart (SImode, data), address,
805                           scratch1, scratch2, scratch3));
806   mt_set_memflags (operands[0]);
807   seq = get_insns ();
808   end_sequence ();
809   emit_insn (seq);
810   DONE;
814 ;; 32 bit Integer arithmetic
816 ;; Addition
817 (define_insn "addsi3"
818   [(set (match_operand:SI 0 "register_operand" "=r,r")
819         (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
820                  (match_operand:SI 2 "arith_operand" "r,I")))]
821   ""
822   "@
823   add %0, %1, %2
824   addi %0, %1, %2"
825   [(set_attr "length" "4,4")
826    (set_attr "type" "arith,arith")])
828 ;; Subtraction
829 (define_insn "subsi3"
830   [(set (match_operand:SI 0 "register_operand" "=r,r")
831         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ")
832                   (match_operand:SI 2 "arith_operand" "rJ,I")))]
833   ""
834   "@
835   sub %0, %z1, %z2
836   subi %0, %z1, %2"
837   [(set_attr "length" "4,4")
838    (set_attr "type" "arith,arith")])
840 ;;  Negation 
841 (define_insn "negsi2"
842   [(set (match_operand:SI 0 "register_operand" "=r,r")
843         (neg:SI (match_operand:SI 1 "arith_operand" "r,I")))]
844   ""
845   "@
846   sub  %0, r0, %1
847   subi  %0, r0, %1"
848   [(set_attr "length" "4,4")
849    (set_attr "type" "arith,arith")])
852 ;; 32 bit Integer Shifts and Rotates
854 ;; Arithmetic Shift Left
855 (define_insn "ashlsi3"
856   [(set (match_operand:SI 0 "register_operand" "=r,r")
857         (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
858                    (match_operand:SI 2 "arith_operand" "r,K")))]
859   ""
860   "@
861   lsl %0, %1, %2
862   lsli %0, %1, %2"
863   [(set_attr "length" "4,4")
864    (set_attr "type" "arith,arith")])
866 ;; Arithmetic Shift Right
867 (define_insn "ashrsi3"
868   [(set (match_operand:SI 0 "register_operand" "=r,r")
869         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
870                      (match_operand:SI 2 "uns_arith_operand" "r,K")))]
871   ""
872   "@
873   asr %0, %1, %2
874   asri %0, %1, %2"
875   [(set_attr "length" "4,4")
876    (set_attr "type" "arith,arith")])
878 ;; Logical Shift Right
879 (define_insn "lshrsi3"
880   [(set (match_operand:SI 0 "register_operand" "=r,r")
881         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
882                      (match_operand:SI 2 "uns_arith_operand" "r,K")))]
883   ""
884   "@
885   lsr %0, %1, %2
886   lsri %0, %1, %2"
887   [(set_attr "length" "4,4")
888    (set_attr "type" "arith,arith")])
891 ;; 32 Bit Integer Logical operations
893 ;; Logical AND, 32 bit integers
894 (define_insn "andsi3"
895   [(set (match_operand:SI 0 "register_operand" "=r,r")
896         (and:SI (match_operand:SI 1 "register_operand" "%r,r")
897                 (match_operand:SI 2 "uns_arith_operand" "r,K")))]
898   ""
899   "@
900   and %0, %1, %2
901   andi %0, %1, %2"
902   [(set_attr "length" "4,4")
903    (set_attr "type" "arith,arith")])
905 ;; Inclusive OR, 32 bit integers
906 (define_insn "iorsi3"
907   [(set (match_operand:SI 0 "register_operand" "=r,r")
908         (ior:SI (match_operand:SI 1 "register_operand" "%r,r")
909                 (match_operand:SI 2 "uns_arith_operand" "r,K")))]
910   ""
911   "@
912   or %0, %1, %2
913   ori %0, %1, %2"
914   [(set_attr "length" "4,4")
915    (set_attr "type" "arith,arith")])
917 ;; Exclusive OR, 32 bit integers
918 (define_insn "xorsi3"
919   [(set (match_operand:SI 0 "register_operand" "=r,r")
920         (xor:SI (match_operand:SI 1 "register_operand" "%r,r")
921                 (match_operand:SI 2 "uns_arith_operand" "r,K")))]
922   ""
923   "@
924   xor %0, %1, %2
925   xori %0, %1, %2"
926   [(set_attr "length" "4,4")
927    (set_attr "type" "arith,arith")])
930 ;; One's complement, 32 bit integers
931 (define_insn "one_cmplsi2"
932   [(set (match_operand:SI 0 "register_operand" "=r")
933         (not:SI (match_operand:SI 1 "register_operand" "r")))]
934   ""
935   "nor %0, %1, %1"
936   [(set_attr "length" "4")
937    (set_attr "type" "arith")])
940 ;; Multiply
942 (define_insn "mulhisi3"
943   [(set (match_operand:SI 0 "register_operand" "=r,r")
944      (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r,r"))
945               (sign_extend:SI (match_operand:HI 2 "arith_operand" "r,I"))))]
946   "TARGET_MS1_16_003 || TARGET_MS2"
947   "@
948   mul %0, %1, %2
949   muli %0, %1, %2"
950   [(set_attr "length" "4,4")
951    (set_attr "type" "arith,arith")])
954 ;; Comparisons
956 ;; Note, we store the operands in the comparison insns, and use them later
957 ;; when generating the branch or scc operation.
959 ;; First the routines called by the machine independent part of the compiler
960 (define_expand "cmpsi"
961   [(set (cc0)
962         (compare (match_operand:SI 0 "register_operand" "")
963                  (match_operand:SI 1 "arith_operand" "")))]
964   ""
965   "
967   mt_compare_op0 = operands[0];
968   mt_compare_op1 = operands[1];
969   DONE;
973 ;; Branches
975 (define_expand "beq"
976   [(use (match_operand 0 "" ""))]
977   ""
978   "
980   mt_emit_cbranch (EQ, operands[0], mt_compare_op0, mt_compare_op1);
981   DONE;
984 (define_expand "bne"
985   [(use (match_operand 0 "" ""))]
986   ""
987   "
989   mt_emit_cbranch (NE, operands[0], mt_compare_op0, mt_compare_op1);
990   DONE;
993 (define_expand "bge"
994   [(use (match_operand 0 "" ""))]
995   ""
996   "
998   mt_emit_cbranch (GE, operands[0], mt_compare_op0, mt_compare_op1);
999   DONE;
1002 (define_expand "bgt"
1003   [(use (match_operand 0 "" ""))]
1004   ""
1005   "
1007   mt_emit_cbranch (GT, operands[0], mt_compare_op0, mt_compare_op1);
1008   DONE;
1011 (define_expand "ble"
1012   [(use (match_operand 0 "" ""))]
1013   ""
1014   "
1016   mt_emit_cbranch (LE, operands[0], mt_compare_op0, mt_compare_op1);
1017   DONE;
1020 (define_expand "blt"
1021   [(use (match_operand 0 "" ""))]
1022   ""
1023   "
1025   mt_emit_cbranch (LT, operands[0], mt_compare_op0, mt_compare_op1);
1026   DONE;
1029 (define_expand "bgeu"
1030   [(use (match_operand 0 "" ""))]
1031   ""
1032   "
1034   mt_emit_cbranch (GEU, operands[0], mt_compare_op0, mt_compare_op1);
1035   DONE;
1038 (define_expand "bgtu"
1039   [(use (match_operand 0 "" ""))]
1040   ""
1041   "
1043   mt_emit_cbranch (GTU, operands[0], mt_compare_op0, mt_compare_op1);
1044   DONE;
1047 (define_expand "bleu"
1048   [(use (match_operand 0 "" ""))]
1049   ""
1050   "
1052   mt_emit_cbranch (LEU, operands[0], mt_compare_op0, mt_compare_op1);
1053   DONE;
1056 (define_expand "bltu"
1057   [(use (match_operand 0 "" ""))]
1058   ""
1059   "
1061   mt_emit_cbranch (LTU, operands[0], mt_compare_op0, mt_compare_op1);
1062   DONE;
1065 (define_expand "bunge"
1066   [(use (match_operand 0 "" ""))]
1067   ""
1068   "
1070   mt_emit_cbranch (GEU, operands[0], mt_compare_op0, mt_compare_op1);
1071   DONE;
1074 (define_expand "bungt"
1075   [(use (match_operand 0 "" ""))]
1076   ""
1077   "
1079   mt_emit_cbranch (GTU, operands[0], mt_compare_op0, mt_compare_op1);
1080   DONE;
1083 (define_expand "bunle"
1084   [(use (match_operand 0 "" ""))]
1085   ""
1086   "
1088   mt_emit_cbranch (LEU, operands[0], mt_compare_op0, mt_compare_op1);
1089   DONE;
1092 (define_expand "bunlt"
1093   [(use (match_operand 0 "" ""))]
1094   ""
1095   "
1097   mt_emit_cbranch (LTU, operands[0], mt_compare_op0, mt_compare_op1);
1098   DONE;
1101 (define_insn "*beq_true"
1102   [(set (pc)
1103         (if_then_else (eq (match_operand:SI 0 "reg_or_0_operand" "rJ")
1104                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1105                       (label_ref (match_operand 2 "" ""))
1106                       (pc)))]
1107   ""
1108   "breq %z0, %z1, %l2%#"
1109   [(set_attr "length" "4")
1110    (set_attr "type" "branch")])
1112 (define_insn "*beq_false"
1113   [(set (pc)
1114         (if_then_else (eq (match_operand:SI 0 "reg_or_0_operand" "rJ")
1115                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1116                       (pc)
1117                       (label_ref (match_operand 2 "" ""))))]
1118   ""
1119   "brne %z0, %z1, %l2%#"
1120   [(set_attr "length" "4")
1121    (set_attr "type" "branch")])
1124 (define_insn "*bne_true"
1125   [(set (pc)
1126         (if_then_else (ne (match_operand:SI 0 "reg_or_0_operand" "rJ")
1127                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1128                       (label_ref (match_operand 2 "" ""))
1129                       (pc)))]
1130   ""
1131   "brne %z0, %z1, %l2%#"
1132   [(set_attr "length" "4")
1133    (set_attr "type" "branch")])
1135 (define_insn "*bne_false"
1136   [(set (pc)
1137         (if_then_else (ne (match_operand:SI 0 "reg_or_0_operand" "rJ")
1138                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1139                       (pc)
1140                       (label_ref (match_operand 2 "" ""))))]
1141   ""
1142   "breq %z0, %z1, %l2%#"
1143   [(set_attr "length" "4")
1144    (set_attr "type" "branch")])
1146 (define_insn "*blt_true"
1147   [(set (pc)
1148         (if_then_else (lt (match_operand:SI 0 "reg_or_0_operand" "rJ")
1149                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1150                       (label_ref (match_operand 2 "" ""))
1151                       (pc)))]
1152   ""
1153   "brlt %z0, %z1, %l2%#"
1154   [(set_attr "length" "4")
1155    (set_attr "type" "branch")])
1157 (define_insn "*blt_false"
1158   [(set (pc)
1159         (if_then_else (lt (match_operand:SI 0 "reg_or_0_operand" "rJ")
1160                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1161                       (pc)
1162                       (label_ref (match_operand 2 "" ""))))]
1163   ""
1164   "brle %z1, %z0,%l2%#"
1165   [(set_attr "length" "4")
1166    (set_attr "type" "branch")])
1168 (define_insn "*ble_true"
1169   [(set (pc)
1170         (if_then_else (le (match_operand:SI 0 "reg_or_0_operand" "rJ")
1171                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1172                       (label_ref (match_operand 2 "" ""))
1173                       (pc)))]
1174   ""
1175   "brle %z0, %z1, %l2%#"
1176   [(set_attr "length" "4")
1177    (set_attr "type" "branch")])
1179 (define_insn "*ble_false"
1180   [(set (pc)
1181         (if_then_else (le (match_operand:SI 0 "reg_or_0_operand" "rJ")
1182                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1183                       (pc)
1184                       (label_ref (match_operand 2 "" ""))))]
1185   ""
1186   "brlt %z1, %z0,%l2%#"
1187   [(set_attr "length" "4")
1188    (set_attr "type" "branch")])
1190 (define_insn "*bgt_true"
1191   [(set (pc)
1192         (if_then_else (gt (match_operand:SI 0 "reg_or_0_operand" "rJ")
1193                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1194                       (label_ref (match_operand 2 "" ""))
1195                       (pc)))]
1196   ""
1197   "brlt %z1, %z0, %l2%#"
1198   [(set_attr "length" "4")
1199    (set_attr "type" "branch")])
1201 (define_insn "*bgt_false"
1202   [(set (pc)
1203         (if_then_else (gt (match_operand:SI 0 "reg_or_0_operand" "rJ")
1204                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1205                       (pc)
1206                       (label_ref (match_operand 2 "" ""))))]
1207   ""
1208   "brle %z0, %z1, %l2%#"
1209   [(set_attr "length" "4")
1210    (set_attr "type" "branch")])
1212 (define_insn "*bge_true"
1213   [(set (pc)
1214         (if_then_else (ge (match_operand:SI 0 "reg_or_0_operand" "rJ")
1215                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1216                       (label_ref (match_operand 2 "" ""))
1217                       (pc)))]
1218   ""
1219   "brle %z1, %z0,%l2%#"
1220   [(set_attr "length" "4")
1221    (set_attr "type" "branch")])
1223 (define_insn "*bge_false"
1224   [(set (pc)
1225         (if_then_else (ge (match_operand:SI 0 "reg_or_0_operand" "rJ")
1226                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1227                       (pc)
1228                       (label_ref (match_operand 2 "" ""))))]
1229   ""
1230   "brlt %z0, %z1, %l2%#"
1231   [(set_attr "length" "4")
1232    (set_attr "type" "branch")])
1234 ;; No unsigned operators on Morpho mt.  All the unsigned operations are
1235 ;; converted to the signed operations above.
1238 ;; Set flag operations
1240 ;; "seq", "sne", "slt", "sle", "sgt", "sge", "sltu", "sleu",
1241 ;; "sgtu", and "sgeu" don't exist as regular instruction on the
1242 ;; mt, so these are not defined
1244 ;; Call and branch instructions
1246 (define_expand "call"
1247   [(parallel [(call (mem:SI (match_operand:SI 0 "register_operand" ""))
1248                             (match_operand 1 "" ""))
1249               (clobber (reg:SI 14))])]
1250   ""
1251   "
1253     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
1256 (define_insn "call_internal"
1257   [(call (mem:SI (match_operand 0 "register_operand" "r"))
1258          (match_operand 1 "" ""))
1259    ;; possibly add a clobber of the reg that gets the return address
1260    (clobber (reg:SI 14))]
1261   ""
1262   "jal r14, %0%#"
1263   [(set_attr "length" "4")
1264    (set_attr "type" "call")])
1266 (define_expand "call_value"
1267   [(parallel [(set (match_operand 0 "register_operand" "")
1268                    (call (mem:SI (match_operand:SI 1 "register_operand" ""))
1269                                  (match_operand 2 "general_operand" "")))
1270               (clobber (reg:SI 14))])]
1271   ""
1272   "
1274     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
1278 (define_insn "call_value_internal"
1279   [(set (match_operand 0 "register_operand" "=r")
1280         (call (mem:SI (match_operand 1 "register_operand" "r"))
1281               (match_operand 2 "" "")))
1282         ;; possibly add a clobber of the reg that gets the return address
1283         (clobber (reg:SI 14))]
1284   ""
1285   "jal r14, %1%#"
1286   [(set_attr "length" "4")
1287    (set_attr "type" "call")])
1289 ;; Subroutine return
1290 (define_insn "return_internal"
1291   [(const_int 2)
1292    (return)
1293    (use (reg:SI 14))]
1294   ""
1295   "jal r0, r14%#"
1296   [(set_attr "length" "4")
1297    (set_attr "type" "call")])
1299 ;; Interrupt return
1300 (define_insn "return_interrupt_internal"
1301   [(const_int 3)
1302    (return)
1303    (use (reg:SI 15))]
1304   ""
1305   "reti r15%#"
1306   [(set_attr "length" "4")
1307    (set_attr "type" "call")])
1309 ;; Subroutine return
1310 (define_insn "eh_return_internal"
1311   [(return)
1312    (use (reg:SI 7))
1313    (use (reg:SI 8))
1314    (use (reg:SI 11))
1315    (use (reg:SI 10))]
1316   ""
1317   "jal r0, r11%#"
1318   [(set_attr "length" "4")
1319    (set_attr "type" "call")])
1322 ;; Normal unconditional jump
1323 (define_insn "jump"
1324   [(set (pc) (label_ref (match_operand 0 "" "")))]
1325   ""
1326   "jmp %l0%#"
1327   [(set_attr "length" "4")
1328    (set_attr "type" "branch")])
1330 ;; Indirect jump through a register
1331 (define_insn "indirect_jump"
1332   [(set (pc) (match_operand 0 "register_operand" "r"))]
1333   ""
1334   "jal r0,%0%#"
1335   [(set_attr "length" "4")
1336    (set_attr "type" "call")])
1338 (define_insn "tablejump"
1339   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1340    (use (label_ref (match_operand 1 "" "")))]
1341   ""
1342   "jal r0, %0%#"
1343   [(set_attr "length" "4")
1344    (set_attr "type" "call")])
1347 (define_expand "prologue"
1348   [(const_int 1)]
1349   ""
1350   "
1352   mt_expand_prologue ();
1353   DONE;
1356 (define_expand "epilogue"
1357   [(const_int 2)]
1358   ""
1359   "
1361   mt_expand_epilogue (NORMAL_EPILOGUE);
1362   DONE;
1366 (define_expand "eh_return"
1367   [(use (match_operand:SI 0 "register_operand" "r"))]
1368   ""
1369   "
1371   mt_expand_eh_return (operands);
1372   DONE;
1376 (define_insn_and_split "eh_epilogue"
1377   [(unspec [(match_operand 0 "register_operand" "r")] 6)]
1378   ""
1379   "#"
1380   "reload_completed"
1381   [(const_int 1)]
1382   "mt_emit_eh_epilogue (operands); DONE;"
1385 ;; No operation, needed in case the user uses -g but not -O.
1386 (define_insn "nop"
1387   [(const_int 0)]
1388   ""
1389   "nop"
1390   [(set_attr "length" "4")
1391    (set_attr "type" "arith")])
1393 ;; ::::::::::::::::::::
1394 ;; ::
1395 ;; :: UNSPEC_VOLATILE usage
1396 ;; ::
1397 ;; ::::::::::::::::::::
1398 ;; 
1399 ;;      0       blockage
1400 ;;      1       Enable interrupts
1401 ;;      2       Disable interrupts
1404 ;; Pseudo instruction that prevents the scheduler from moving code above this
1405 ;; point.
1406 (define_insn "blockage"
1407   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
1408   ""
1409   ""
1410   [(set_attr "length" "0")])
1412 ;; Trap instruction to allow usage of the __builtin_trap function
1413 (define_insn "trap"
1414   [(trap_if (const_int 1) (const_int 0))
1415    (clobber (reg:SI 14))]
1416   ""
1417   "si   r14%#"
1418   [(set_attr "length" "4")
1419    (set_attr "type" "branch")])
1421 (define_expand "conditional_trap"
1422   [(trap_if (match_operator 0 "comparison_operator"
1423                             [(match_dup 2)
1424                              (match_dup 3)])
1425             (match_operand 1 "const_int_operand" ""))]
1426   ""
1427   "
1429   operands[2] = mt_compare_op0;
1430   operands[3] = mt_compare_op1;
1433 ;; Templates to control handling of interrupts
1435 ;; Enable interrupts template
1436 (define_insn "ei"
1437   [(unspec_volatile [(const_int 0)] UNSPEC_EI)]
1438   ""
1439   "ei"
1440   [(set_attr "length" "4")])
1442 ;; Enable interrupts template
1443 (define_insn "di"
1444   [(unspec_volatile [(const_int 0)] UNSPEC_DI)]
1445   ""
1446   "di"
1447   [(set_attr "length" "4")])