OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / config / mt / mt.md
1 ;; Machine description for MorphoRISC1
2 ;; Copyright (C) 2005, 2007 Free Software Foundation, Inc.
3 ;; Contributed by Red Hat, Inc.
4
5 ;; This file is part of GCC.
6
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 3, or (at your option)
10 ;; any later version.
11
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.
16
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
20 \f
21 ;; UNSPECs
22 (define_constants
23   [
24     (UNSPEC_BLOCKAGE 0)
25     (UNSPEC_EI 1)
26     (UNSPEC_DI 2)
27     (UNSPEC_LOOP 3)
28   ])
29
30 ;; Attributes
31 (define_attr "type" "branch,call,load,store,io,arith,complex,unknown"
32          (const_string "unknown") )
33
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'.
36
37 (define_attr "length" "" (const_int 4))
38
39 \f
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")
45
46 (define_insn_reservation "mem_access" 2
47   (ior (eq_attr "type" "load") (eq_attr "type" "store"))
48   "decode_unit+memory_unit*2")
49
50 (define_insn_reservation "io_access" 2
51   (eq_attr "type" "io")
52   "decode_unit+memory_unit*2")
53
54 (define_insn_reservation "branch_access" 2
55   (ior (eq_attr "type" "branch")
56        (eq_attr "type" "call"))
57   "decode_unit+branch_unit*2")
58
59 (define_insn_reservation "arith_access" 1
60   (eq_attr "type" "arith")
61   "decode_unit")
62
63 (define_bypass 2 "arith_access" "branch_access")
64 (define_bypass 3 "mem_access" "branch_access")
65 (define_bypass 3 "io_access" "branch_access")
66
67 \f
68 ;; Delay Slots
69
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.
75
76 (define_delay (ior (eq_attr "type" "branch")
77                    (eq_attr "type" "call"))
78                  [(eq_attr "type" "arith") (nil) (nil)])
79
80 \f
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")]
99 )
100
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   "")
126
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.
131
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   "")
152
153 \f
154 ;; Loop instructions.  ms2 has a low overhead looping instructions.
155 ;; these take a constant or register loop count and a loop length
156 ;; offset.  Unfortunately the loop can only be up to 256 instructions,
157 ;; We deal with longer loops by moving the loop end upwards.  To do
158 ;; otherwise would force us to to be very pessimistic right up until
159 ;; the end.
160
161 ;; This instruction is a placeholder to make the control flow explicit.
162 (define_insn "loop_end"
163   [(set (pc) (if_then_else
164                           (ne (match_operand:SI 0 "register_operand" "")
165                               (const_int 1))
166                           (label_ref (match_operand 1 "" ""))
167                           (pc)))
168    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
169    (unspec [(const_int 0)] UNSPEC_LOOP)]
170   "TARGET_MS2"
171   ";loop end %0,%l1"
172   [(set_attr "length" "0")])
173
174 ;; This is the real looping instruction.  It is placed just before the
175 ;; loop body.  We make it a branch insn, so it stays at the end of the
176 ;; block it is in.
177 (define_insn "loop_init"
178   [(set (match_operand:SI 0 "register_operand" "=r,r")
179         (match_operand:SI 1 "uns_arith_operand" "r,K"))
180    (unspec [(label_ref (match_operand 2 "" ""))] UNSPEC_LOOP)]
181   "TARGET_MS2"
182   "@
183    loop  %1,%l2 ;%0%#
184    loopi %1,%l2 ;%0%#"
185   [(set_attr "length" "4")
186    (set_attr "type" "branch")])
187
188 ; operand 0 is the loop count pseudo register
189 ; operand 1 is the number of loop iterations or 0 if it is unknown
190 ; operand 2 is the maximum number of loop iterations
191 ; operand 3 is the number of levels of enclosed loops
192 ; operand 4 is the label to jump to at the top of the loop
193 (define_expand "doloop_end"
194   [(parallel [(set (pc) (if_then_else
195                           (ne (match_operand:SI 0 "nonimmediate_operand" "")
196                               (const_int 0))
197                           (label_ref (match_operand 4 "" ""))
198                           (pc)))
199               (set (match_dup 0)
200                    (plus:SI (match_dup 0)
201                             (const_int -1)))
202               (clobber (match_scratch:SI 5 ""))
203               (clobber (match_scratch:SI 6 ""))])]
204   "TARGET_MS1_16_003 || TARGET_MS2"
205   {mt_add_loop ();})
206 \f
207 ;; Moves
208
209 (define_expand "loadqi"
210   [
211    ;; compute shift
212    (set (match_operand:SI 2 "register_operand" "")
213         (and:SI (match_dup 1) (const_int 3)))
214    (set (match_dup 2)   (xor:SI (match_dup 2) (const_int 3)))
215    (set (match_dup 2 )  (ashift:SI (match_dup 2) (const_int 3)))
216
217    ;; get word that contains byte
218    (set (match_operand:SI 0 "register_operand" "")
219         (mem:SI (and:SI (match_operand:SI 1 "register_operand" "")
220                         (const_int -3))))
221
222    ;; align byte
223    (set (match_dup 0)   (ashiftrt:SI (match_dup 0) (match_dup 2)))
224   ]
225   ""
226   "")
227
228
229 ;; storeqi
230 ;; operand 0 byte value to store
231 ;; operand 1 address
232 ;; operand 2 temp, word containing byte
233 ;; operand 3 temp, shift count
234 ;; operand 4 temp, mask, aligned and masked byte
235 ;; operand 5 (unused)
236 (define_expand "storeqi"
237   [
238    ;; compute shift
239    (set (match_operand:SI 3 "register_operand" "")
240         (and:SI (match_operand:SI 1 "register_operand" "") (const_int 3)))
241    (set (match_dup 3)   (xor:SI (match_dup 3) (const_int 3)))
242    (set (match_dup 3)   (ashift:SI (match_dup 3) (const_int 3)))
243
244    ;; get word that contains byte
245    (set (match_operand:SI 2 "register_operand" "")
246         (mem:SI (and:SI (match_dup 1) (const_int -3))))
247
248    ;; generate mask
249    (set (match_operand:SI 4 "register_operand" "") (const_int 255))
250    (set (match_dup 4) (ashift:SI (match_dup 4) (match_dup 3)))
251    (set (match_dup 4) (not:SI (match_dup 4)))
252
253    ;; clear appropriate bits
254    (set (match_dup 2) (and:SI (match_dup 2) (match_dup 4)))
255
256    ;; align byte
257    (set (match_dup 4)
258         (and:SI (match_operand:SI 0 "register_operand" "") (const_int 255)))
259    (set (match_dup 4) (ashift:SI (match_dup 4) (match_dup 3)))
260
261    ;; combine
262    (set (match_dup 2) (ior:SI (match_dup 4) (match_dup 2)))
263    ;; store updated word
264    (set (mem:SI (and:SI (match_dup 1) (const_int -3))) (match_dup 2))
265   ]
266   ""
267   "")
268
269
270 (define_expand "movqi"
271   [(set (match_operand:QI 0 "general_operand" "")
272         (match_operand:QI 1 "general_operand" ""))]
273   ""
274   "
275 {
276   if (!reload_in_progress
277       && !reload_completed
278       && GET_CODE (operands[0]) == MEM
279       && GET_CODE (operands[1]) == MEM)
280     operands[1] = copy_to_mode_reg (QImode, operands[1]);
281   
282   if ( (! TARGET_BYTE_ACCESS) && GET_CODE (operands[0]) == MEM)
283     {
284         rtx scratch1 = gen_reg_rtx (SImode);
285         rtx scratch2 = gen_reg_rtx (SImode);
286         rtx scratch3 = gen_reg_rtx (SImode);
287         rtx data     = operands[1];
288         rtx address  = XEXP (operands[0], 0);
289         rtx seq;
290
291         if ( GET_CODE (data) != REG )
292             data = copy_to_mode_reg (QImode, data);
293
294         if ( GET_CODE (address) != REG )
295           address = copy_to_mode_reg (SImode, address);
296
297         start_sequence ();
298         emit_insn (gen_storeqi (gen_lowpart (SImode, data), address,
299                                 scratch1, scratch2, scratch3));
300         mt_set_memflags (operands[0]);
301         seq = get_insns ();
302         end_sequence ();
303         emit_insn (seq);
304         DONE;
305     }
306
307   if ( (! TARGET_BYTE_ACCESS) && GET_CODE (operands[1]) == MEM)
308     {
309         rtx scratch1 = gen_reg_rtx (SImode);
310         rtx data = operands[0];
311         rtx address = XEXP (operands[1], 0);
312         rtx seq;
313
314         if ( GET_CODE (address) != REG )
315           address = copy_to_mode_reg (SImode, address);
316
317         start_sequence ();
318         emit_insn (gen_loadqi (gen_lowpart (SImode, data), address, scratch1));
319         mt_set_memflags (operands[1]);
320         seq = get_insns ();
321         end_sequence ();
322         emit_insn (seq);
323         DONE;
324     }
325
326    /* If the load is a pseudo register in a stack slot, some simplification
327       can be made because the loads are aligned */
328   if ( (! TARGET_BYTE_ACCESS) 
329         && (reload_in_progress && GET_CODE (operands[1]) == SUBREG
330           && GET_CODE (SUBREG_REG (operands[1])) == REG
331           && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
332     {
333         rtx data = operands[0];
334         rtx address = XEXP (operands[1], 0);
335         rtx seq;
336
337         start_sequence ();
338         emit_insn (gen_movsi (gen_lowpart (SImode, data), address));
339         mt_set_memflags (operands[1]);
340         seq = get_insns ();
341         end_sequence ();
342         emit_insn (seq);
343         DONE;
344     }
345 }")
346
347 (define_insn "*movqi_internal"
348   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r")
349         (match_operand:QI 1 "general_operand" "r,m,r,I"))]
350   "TARGET_BYTE_ACCESS
351     && (!memory_operand (operands[0], QImode)
352         || !memory_operand (operands[1], QImode))"
353   "@
354    or  %0, %1, %1
355    ldb %0, %1
356    stb %1, %0
357    addi %0, r0, %1"
358   [(set_attr "length" "4,4,4,4")
359    (set_attr "type" "arith,load,store,arith")])
360
361 (define_insn "*movqi_internal_nobyte"
362   [(set (match_operand:QI 0 "register_operand" "=r,r")
363         (match_operand:QI 1 "arith_operand" "r,I"))]
364   "!TARGET_BYTE_ACCESS
365     && (!memory_operand (operands[0], QImode)
366         || !memory_operand (operands[1], QImode))"
367   "@
368    or   %0, %1, %1
369    addi %0, r0, %1"
370   [(set_attr "length" "4,4")
371    (set_attr "type" "arith,arith")])
372
373
374 ;; The MorphoRISC does not have 16-bit loads and stores.
375 ;; These operations must be synthesized.  Note that the code
376 ;; for loadhi and storehi assumes that the least significant bits
377 ;; is ignored.
378
379 ;; loadhi
380 ;; operand 0 location of result
381 ;; operand 1 memory address
382 ;; operand 2 temp
383 (define_expand "loadhi"
384   [
385    ;; compute shift
386    (set (match_operand:SI 2 "register_operand" "")
387         (and:SI (match_dup 1) (const_int 2)))
388    (set (match_dup 2)   (xor:SI (match_dup 2) (const_int 2)))
389    (set (match_dup 2 )  (ashift:SI (match_dup 2) (const_int 3)))
390
391    ;; get word that contains the 16-bits
392    (set (match_operand:SI 0 "register_operand" "")
393         (mem:SI (and:SI (match_operand:SI 1 "register_operand" "")
394                         (const_int -3))))
395
396    ;; align 16-bit value
397    (set (match_dup 0)   (ashiftrt:SI (match_dup 0) (match_dup 2)))
398   ]
399   ""
400   "")
401
402 ;; storehi
403 ;; operand 0 byte value to store
404 ;; operand 1 address
405 ;; operand 2 temp, word containing byte
406 ;; operand 3 temp, shift count
407 ;; operand 4 temp, mask, aligned and masked byte
408 ;; operand 5 (unused)
409 (define_expand "storehi"
410   [
411    ;; compute shift
412    (set (match_operand:SI 3 "register_operand" "")
413         (and:SI (match_operand:SI 1 "register_operand" "") (const_int 2)))
414    (set (match_dup 3)   (xor:SI (match_dup 3) (const_int 2)))
415    (set (match_dup 3)   (ashift:SI (match_dup 3) (const_int 3)))
416
417    ;; get word that contains the 16-bits
418    (set (match_operand:SI 2 "register_operand" "")
419         (mem:SI (and:SI (match_dup 1) (const_int -3))))
420
421    ;; generate mask
422    (set (match_operand:SI 4 "register_operand" "") (const_int 65535))
423    (set (match_dup 4) (ashift:SI (match_dup 4) (match_dup 3)))
424    (set (match_dup 4) (not:SI (match_dup 4)))
425
426    ;; clear appropriate bits
427    (set (match_dup 2) (and:SI (match_dup 2) (match_dup 4)))
428
429    ;; align 16-bit value
430    (set (match_dup 4)
431         (and:SI (match_operand:SI 0 "register_operand" "") (const_int 65535)))
432    (set (match_dup 4) (ashift:SI (match_dup 4) (match_dup 3)))
433
434    ;; combine
435    (set (match_dup 2) (ior:SI (match_dup 4) (match_dup 2)))
436    ;; store updated word
437    (set (mem:SI (and:SI (match_dup 1) (const_int -3))) (match_dup 2))
438   ]
439   ""
440   "")
441
442
443 (define_expand "movhi"
444   [(set (match_operand:HI 0 "general_operand" "")
445         (match_operand:HI 1 "general_operand" ""))]
446   ""
447   "
448 {
449   if (!reload_in_progress
450       && !reload_completed
451       && GET_CODE (operands[0]) == MEM
452       && GET_CODE (operands[1]) == MEM)
453     operands[1] = copy_to_mode_reg (HImode, operands[1]);
454
455   if ( GET_CODE (operands[0]) == MEM)
456     {
457         rtx scratch1 = gen_reg_rtx (SImode);
458         rtx scratch2 = gen_reg_rtx (SImode);
459         rtx scratch3 = gen_reg_rtx (SImode);
460         rtx data     = operands[1];
461         rtx address  = XEXP (operands[0], 0);
462         rtx seq;
463
464         if (GET_CODE (data) != REG)
465           data = copy_to_mode_reg (HImode, data);
466
467         if (GET_CODE (address) != REG)
468           address = copy_to_mode_reg (SImode, address);
469
470         start_sequence ();
471         emit_insn (gen_storehi (gen_lowpart (SImode, data), address,
472                                 scratch1, scratch2, scratch3));
473         mt_set_memflags (operands[0]);
474         seq = get_insns ();
475         end_sequence ();
476         emit_insn (seq);
477         DONE;
478     }
479
480   if ( GET_CODE (operands[1]) == MEM)
481     {
482         rtx scratch1 = gen_reg_rtx (SImode);
483         rtx data     = operands[0];
484         rtx address  = XEXP (operands[1], 0);
485         rtx seq;
486
487         if (GET_CODE (address) != REG)
488             address = copy_to_mode_reg (SImode, address);
489
490         start_sequence ();
491         emit_insn (gen_loadhi (gen_lowpart (SImode, data), address,
492                                scratch1));
493         mt_set_memflags (operands[1]);
494         seq = get_insns ();
495         end_sequence ();
496         emit_insn (seq);
497         DONE;
498     }
499
500    /* If the load is a pseudo register in a stack slot, some simplification
501       can be made because the loads are aligned */
502   if ( (reload_in_progress && GET_CODE (operands[1]) == SUBREG
503           && GET_CODE (SUBREG_REG (operands[1])) == REG
504           && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
505     {
506         rtx data = operands[0];
507         rtx address = XEXP (operands[1], 0);
508         rtx seq;
509
510         start_sequence ();
511         emit_insn (gen_movsi (gen_lowpart (SImode, data), address));
512         mt_set_memflags (operands[1]);
513         seq = get_insns ();
514         end_sequence ();
515         emit_insn (seq);
516         DONE;
517     }
518 }")
519
520 (define_insn "*movhi_internal"
521   [(set (match_operand:HI 0 "register_operand" "=r,r")
522         (match_operand:HI 1 "arith_operand" "r,I"))]
523   "!memory_operand (operands[0], HImode) || !memory_operand (operands[1], HImode)"
524   "@
525   or    %0, %1, %1
526   addi  %0, r0, %1"
527   [(set_attr "length" "4,4")
528    (set_attr "type" "arith,arith")])
529
530 (define_expand "movsi"
531   [(set (match_operand:SI 0 "nonimmediate_operand" "")
532         (match_operand:SI 1 "general_operand" ""))]
533   ""
534   "
535 {
536   if (!reload_in_progress  && !reload_completed
537       && !register_operand (operands[0], SImode)
538       && !register_operand (operands[1], SImode))
539     operands[1] = copy_to_mode_reg (SImode, operands[1]);
540
541   /* Take care of constants that don't fit in single instruction */
542   if ( (reload_in_progress || reload_completed)
543    && !single_const_operand (operands[1], SImode))
544     {
545       emit_insn (gen_movsi_high (operands[0], operands[1]));
546       emit_insn (gen_movsi_lo_sum (operands[0], operands[0], operands[1]));
547       DONE;
548     }
549
550 }")
551
552 (define_insn "movsi_high"
553   [(set (match_operand:SI 0 "register_operand" "=r")
554         (high:SI (match_operand:SI 1 "general_operand" "i")))]
555   ""
556   "*
557 {
558   return \"ldui\\t%0, %H1\";
559 }"
560   [(set_attr "length" "4")
561    (set_attr "type" "arith")])
562
563
564 (define_insn "movsi_lo_sum"
565   [(set (match_operand:SI 0 "register_operand" "=r")
566         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
567                    (match_operand:SI 2 "general_operand" "i")))]
568   ""
569   "*
570 {
571   return \"addui\\t%0, %1, %L2\";
572 }"
573   [(set_attr "length" "4")
574    (set_attr "type" "arith")])
575
576 /* Take care of constants that don't fit in single instruction */
577 (define_split
578   [(set (match_operand:SI 0 "register_operand" "")
579         (match_operand:SI 1 "general_operand" ""))]
580   "(reload_in_progress || reload_completed)
581    && !single_const_operand (operands[1], SImode)"
582
583   [(set (match_dup 0 )
584         (high:SI (match_dup 1)))
585    (set (match_dup 0 )
586         (lo_sum:SI (match_dup 0)
587                    (match_dup 1)))]
588 )
589
590
591 ;; The last pattern in movsi (with two instructions)
592 ;; is really handled by the emit_insn's in movsi
593 ;; and the define_split above.  This provides additional
594 ;; instructions to fill delay slots.
595
596 ;; Note - it is best to only have one movsi pattern and to handle
597 ;; all the various contingencies by the use of alternatives.  This
598 ;; allows reload the greatest amount of flexibility (since reload will
599 ;; only choose amoungst alternatives for a selected insn, it will not
600 ;; replace the insn with another one).
601 (define_insn "*movsi_internal"
602   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,r")
603         (match_operand:SI 1 "general_operand"       "r,m,r,I,P,L,N,i"))]
604   "(!memory_operand (operands[0], SImode) || !memory_operand (operands[1], SImode))
605    && !((reload_in_progress || reload_completed)
606          && !single_const_operand (operands[1], SImode))"
607   "@
608   or     %0, %1, %1
609   ldw    %0, %1
610   stw    %1, %0
611   addi   %0, r0, %1
612   addui  %0, r0, %1
613   ldui   %0, %H1
614   nori   %0, r0, %N1
615   ldui   %0, %H1\;addui %0, %0, %L1"
616   [(set_attr "length" "4,4,4,4,4,4,4,8")
617    (set_attr "type" "arith,load,store,arith,arith,arith,arith,complex")]
618 )
619
620 ;; Floating Point Moves
621 ;;
622 ;; Note - Patterns for SF mode moves are compulsory, but
623 ;; patterns for DF are optional, as GCC can synthesize them.
624
625 (define_expand "movsf"
626   [(set (match_operand:SF 0 "general_operand" "")
627         (match_operand:SF 1 "general_operand" ""))]
628   ""
629   "
630 {
631   if (!reload_in_progress
632       && !reload_completed
633       && GET_CODE (operands[0]) == MEM
634       && (GET_CODE (operands[1]) == MEM
635          || GET_CODE (operands[1]) == CONST_DOUBLE))
636     operands[1] = copy_to_mode_reg (SFmode, operands[1]);
637
638   /* Take care of reg <- SF constant */
639   if ( const_double_operand (operands[1], GET_MODE (operands[1]) ) )
640     {
641       emit_insn (gen_movsf_high (operands[0], operands[1]));
642       emit_insn (gen_movsf_lo_sum (operands[0], operands[0], operands[1]));
643       DONE;
644     }
645 }")
646
647 (define_insn "movsf_lo_sum"
648   [(set (match_operand:SF 0 "register_operand" "=r")
649         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
650                    (match_operand:SF 2 "const_double_operand" "")))]
651   ""
652   "*
653 {
654   REAL_VALUE_TYPE r;
655   long i;
656
657   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
658   REAL_VALUE_TO_TARGET_SINGLE (r, i);
659   operands[2] = GEN_INT (i);
660   return \"addui\\t%0, %1, %L2\";
661 }"
662   [(set_attr "length" "4")
663    (set_attr "type" "arith")])
664
665 (define_insn "movsf_high"
666   [(set (match_operand:SF 0 "register_operand" "=r")
667         (high:SF (match_operand:SF 1 "const_double_operand" "")))]
668   ""
669   "*
670 {
671   REAL_VALUE_TYPE r;
672   long i;
673
674   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
675   REAL_VALUE_TO_TARGET_SINGLE (r, i);
676   operands[1] = GEN_INT (i);
677   return \"ldui\\t%0, %H1\";
678 }"
679   [(set_attr "length" "4")
680    (set_attr "type" "arith")])
681
682
683 (define_insn "*movsf_internal"
684   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
685         (match_operand:SF 1 "nonimmediate_operand" "r,m,r"))]
686   "!memory_operand (operands[0], SFmode) || !memory_operand (operands[1], SFmode)"
687   "@
688   or     %0, %1, %1
689   ldw    %0, %1
690   stw    %1, %0"
691   [(set_attr "length" "4,4,4")
692    (set_attr "type" "arith,load,store")]
693 )
694
695 (define_expand "movdf"
696   [(set (match_operand:DF 0 "general_operand" "")
697         (match_operand:DF 1 "general_operand" ""))]
698   ""
699   "
700 {
701   /* One of the ops has to be in a register or 0 */
702   if (!register_operand (operand0, DFmode)
703       && !reg_or_0_operand (operand1, DFmode))
704     operands[1] = copy_to_mode_reg (DFmode, operand1);
705 }")
706
707 (define_insn_and_split "*movdf_internal"
708   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,o")
709         (match_operand:DF 1 "general_operand"      "rim,r"))]
710   "! (memory_operand (operands[0], DFmode)
711          && memory_operand (operands[1], DFmode))"
712   "#"
713
714   "(reload_completed || reload_in_progress)"
715
716   [(set (match_dup 2) (match_dup 3))
717    (set (match_dup 4) (match_dup 5))
718   ]
719
720   "{
721     /* figure out what precisely to put into operands 2, 3, 4, and 5 */
722     mt_split_words (SImode, DFmode, operands);
723   }"
724 )
725
726 \f
727 ;; Reloads
728
729 ;; Like `movM', but used when a scratch register is required to move between
730 ;; operand 0 and operand 1.  Operand 2 describes the scratch register.  See the
731 ;; discussion of the `SECONDARY_RELOAD_CLASS' macro.
732
733 (define_expand "reload_inqi"
734   [(set (match_operand:QI 0 "register_operand" "=r")
735         (match_operand:QI 1 "memory_operand" "m"))
736    (clobber (match_operand:DI 2 "register_operand" "=&r"))]
737   "! TARGET_BYTE_ACCESS"
738   "
739 {
740   rtx scratch1 = gen_rtx_REG (SImode, REGNO (operands[2]));
741   rtx scratch2 = gen_rtx_REG (SImode, REGNO (operands[2])+1);
742   rtx data = operands[0];
743   rtx address = XEXP (operands[1], 0);
744   rtx swap, seq;
745
746   /* It is possible that the registers we got for scratch1
747      might coincide with that of operands[0].  gen_loadqi
748      requires operand0 and operand2 to be different registers.
749      The following statement ensure that is always the case. */
750   if (REGNO(operands[0]) == REGNO(scratch1))
751     {
752         swap = scratch1;
753         scratch1 = scratch2;
754         scratch2 = swap;
755     }
756
757   /* need to make sure address is already in register */
758   if ( GET_CODE (address) != REG )
759     address = force_operand (address, scratch2);
760
761   start_sequence ();
762   emit_insn (gen_loadqi (gen_lowpart (SImode, data), address, scratch1));
763   mt_set_memflags (operands[1]);
764   seq = get_insns ();
765   end_sequence ();
766   emit_insn (seq);
767   DONE;
768 }")
769
770 (define_expand "reload_outqi"
771   [(set (match_operand:QI 0 "memory_operand" "=m")
772         (match_operand:QI 1 "register_operand" "r"))
773    (clobber (match_operand:TI 2 "register_operand" "=&r"))]
774   "! TARGET_BYTE_ACCESS"
775   "
776 {
777   rtx scratch1 = gen_rtx_REG (SImode, REGNO (operands[2]));
778   rtx scratch2 = gen_rtx_REG (SImode, REGNO (operands[2])+1);
779   rtx scratch3 = gen_rtx_REG (SImode, REGNO (operands[2])+2);
780   rtx scratch4 = gen_rtx_REG (SImode, REGNO (operands[2])+3);
781   rtx data     = operands[1];
782   rtx address  = XEXP (operands[0], 0);
783   rtx seq;
784
785   /* need to make sure address is already in register */
786   if ( GET_CODE (address) != REG )
787     address = force_operand (address, scratch4);
788
789   start_sequence ();
790   emit_insn (gen_storeqi (gen_lowpart (SImode, data), address, 
791                           scratch1, scratch2, scratch3));
792   mt_set_memflags (operands[0]);
793   seq = get_insns ();
794   end_sequence ();
795   emit_insn (seq);
796   DONE;
797 }")
798
799 (define_expand "reload_inhi"
800   [(set (match_operand:HI 0 "register_operand" "=r")
801         (match_operand:HI 1 "memory_operand" "m"))
802    (clobber (match_operand:DI 2 "register_operand" "=&r"))]
803   ""
804   "
805 {
806   rtx scratch1 = gen_rtx_REG (SImode, REGNO (operands[2]));
807   rtx scratch2 = gen_rtx_REG (SImode, REGNO (operands[2])+1);
808   rtx data     = operands[0];
809   rtx address  = XEXP (operands[1], 0);
810   rtx swap, seq;
811
812   /* It is possible that the registers we got for scratch1
813      might coincide with that of operands[0].  gen_loadqi
814      requires operand0 and operand2 to be different registers.
815      The following statement ensure that is always the case. */
816   if (REGNO(operands[0]) == REGNO(scratch1))
817     {
818         swap = scratch1;
819         scratch1 = scratch2;
820         scratch2 = swap;
821     }
822
823   /* need to make sure address is already in register */
824   if ( GET_CODE (address) != REG )
825     address = force_operand (address, scratch2);
826
827   start_sequence ();
828   emit_insn (gen_loadhi (gen_lowpart (SImode, data), address,
829                          scratch1));
830   mt_set_memflags (operands[1]);
831   seq = get_insns ();
832   end_sequence ();
833   emit_insn (seq);
834   DONE;
835 }")
836
837 (define_expand "reload_outhi"
838   [(set (match_operand:HI 0 "memory_operand" "=m")
839         (match_operand:HI 1 "register_operand" "r"))
840    (clobber (match_operand:TI 2 "register_operand" "=&r"))]
841   ""
842   "
843 {
844   rtx scratch1 = gen_rtx_REG (SImode, REGNO (operands[2]));
845   rtx scratch2 = gen_rtx_REG (SImode, REGNO (operands[2])+1);
846   rtx scratch3 = gen_rtx_REG (SImode, REGNO (operands[2])+2);
847   rtx scratch4 = gen_rtx_REG (SImode, REGNO (operands[2])+3);
848   rtx data     = operands[1];
849   rtx address  = XEXP (operands[0], 0);
850   rtx seq;
851
852   /* need to make sure address is already in register */
853   if ( GET_CODE (address) != REG )
854     address = force_operand (address, scratch4);
855
856   start_sequence ();
857   emit_insn (gen_storehi (gen_lowpart (SImode, data), address,
858                           scratch1, scratch2, scratch3));
859   mt_set_memflags (operands[0]);
860   seq = get_insns ();
861   end_sequence ();
862   emit_insn (seq);
863   DONE;
864 }")
865
866 \f
867 ;; 32-bit Integer arithmetic
868
869 ;; Addition
870 (define_insn "addsi3"
871   [(set (match_operand:SI 0 "register_operand" "=r,r")
872         (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
873                  (match_operand:SI 2 "arith_operand" "r,I")))]
874   ""
875   "@
876   add %0, %1, %2
877   addi %0, %1, %2"
878   [(set_attr "length" "4,4")
879    (set_attr "type" "arith,arith")])
880
881 ;; Subtraction
882 (define_insn "subsi3"
883   [(set (match_operand:SI 0 "register_operand" "=r,r")
884         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ")
885                   (match_operand:SI 2 "arith_operand" "rJ,I")))]
886   ""
887   "@
888   sub %0, %z1, %z2
889   subi %0, %z1, %2"
890   [(set_attr "length" "4,4")
891    (set_attr "type" "arith,arith")])
892
893 ;;  Negation 
894 (define_insn "negsi2"
895   [(set (match_operand:SI 0 "register_operand" "=r,r")
896         (neg:SI (match_operand:SI 1 "arith_operand" "r,I")))]
897   ""
898   "@
899   sub  %0, r0, %1
900   subi  %0, r0, %1"
901   [(set_attr "length" "4,4")
902    (set_attr "type" "arith,arith")])
903
904 \f
905 ;; 32-bit Integer Shifts and Rotates
906
907 ;; Arithmetic Shift Left
908 (define_insn "ashlsi3"
909   [(set (match_operand:SI 0 "register_operand" "=r,r")
910         (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
911                    (match_operand:SI 2 "arith_operand" "r,K")))]
912   ""
913   "@
914   lsl %0, %1, %2
915   lsli %0, %1, %2"
916   [(set_attr "length" "4,4")
917    (set_attr "type" "arith,arith")])
918
919 ;; Arithmetic Shift Right
920 (define_insn "ashrsi3"
921   [(set (match_operand:SI 0 "register_operand" "=r,r")
922         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
923                      (match_operand:SI 2 "uns_arith_operand" "r,K")))]
924   ""
925   "@
926   asr %0, %1, %2
927   asri %0, %1, %2"
928   [(set_attr "length" "4,4")
929    (set_attr "type" "arith,arith")])
930
931 ;; Logical Shift Right
932 (define_insn "lshrsi3"
933   [(set (match_operand:SI 0 "register_operand" "=r,r")
934         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
935                      (match_operand:SI 2 "uns_arith_operand" "r,K")))]
936   ""
937   "@
938   lsr %0, %1, %2
939   lsri %0, %1, %2"
940   [(set_attr "length" "4,4")
941    (set_attr "type" "arith,arith")])
942
943 \f
944 ;; 32-Bit Integer Logical operations
945
946 ;; Logical AND, 32-bit integers
947 (define_insn "andsi3"
948   [(set (match_operand:SI 0 "register_operand" "=r,r")
949         (and:SI (match_operand:SI 1 "register_operand" "%r,r")
950                 (match_operand:SI 2 "uns_arith_operand" "r,K")))]
951   ""
952   "@
953   and %0, %1, %2
954   andi %0, %1, %2"
955   [(set_attr "length" "4,4")
956    (set_attr "type" "arith,arith")])
957
958 ;; Inclusive OR, 32-bit integers
959 (define_insn "iorsi3"
960   [(set (match_operand:SI 0 "register_operand" "=r,r")
961         (ior:SI (match_operand:SI 1 "register_operand" "%r,r")
962                 (match_operand:SI 2 "uns_arith_operand" "r,K")))]
963   ""
964   "@
965   or %0, %1, %2
966   ori %0, %1, %2"
967   [(set_attr "length" "4,4")
968    (set_attr "type" "arith,arith")])
969
970 ;; Exclusive OR, 32-bit integers
971 (define_insn "xorsi3"
972   [(set (match_operand:SI 0 "register_operand" "=r,r")
973         (xor:SI (match_operand:SI 1 "register_operand" "%r,r")
974                 (match_operand:SI 2 "uns_arith_operand" "r,K")))]
975   ""
976   "@
977   xor %0, %1, %2
978   xori %0, %1, %2"
979   [(set_attr "length" "4,4")
980    (set_attr "type" "arith,arith")])
981
982
983 ;; One's complement, 32-bit integers
984 (define_insn "one_cmplsi2"
985   [(set (match_operand:SI 0 "register_operand" "=r")
986         (not:SI (match_operand:SI 1 "register_operand" "r")))]
987   ""
988   "nor %0, %1, %1"
989   [(set_attr "length" "4")
990    (set_attr "type" "arith")])
991
992 \f
993 ;; Multiply
994
995 (define_insn "mulhisi3"
996   [(set (match_operand:SI 0 "register_operand" "=r,r")
997      (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r,r"))
998               (sign_extend:SI (match_operand:HI 2 "arith_operand" "r,I"))))]
999   "TARGET_MS1_16_003 || TARGET_MS2"
1000   "@
1001   mul %0, %1, %2
1002   muli %0, %1, %2"
1003   [(set_attr "length" "4,4")
1004    (set_attr "type" "arith,arith")])
1005
1006 \f
1007 ;; Comparisons
1008
1009 ;; Note, we store the operands in the comparison insns, and use them later
1010 ;; when generating the branch or scc operation.
1011
1012 ;; First the routines called by the machine independent part of the compiler
1013 (define_expand "cmpsi"
1014   [(set (cc0)
1015         (compare (match_operand:SI 0 "register_operand" "")
1016                  (match_operand:SI 1 "arith_operand" "")))]
1017   ""
1018   "
1019 {
1020   mt_compare_op0 = operands[0];
1021   mt_compare_op1 = operands[1];
1022   DONE;
1023 }")
1024
1025 \f
1026 ;; Branches
1027
1028 (define_expand "beq"
1029   [(use (match_operand 0 "" ""))]
1030   ""
1031   "
1032 {
1033   mt_emit_cbranch (EQ, operands[0], mt_compare_op0, mt_compare_op1);
1034   DONE;
1035 }")
1036
1037 (define_expand "bne"
1038   [(use (match_operand 0 "" ""))]
1039   ""
1040   "
1041 {
1042   mt_emit_cbranch (NE, operands[0], mt_compare_op0, mt_compare_op1);
1043   DONE;
1044 }")
1045
1046 (define_expand "bge"
1047   [(use (match_operand 0 "" ""))]
1048   ""
1049   "
1050 {
1051   mt_emit_cbranch (GE, operands[0], mt_compare_op0, mt_compare_op1);
1052   DONE;
1053 }")
1054
1055 (define_expand "bgt"
1056   [(use (match_operand 0 "" ""))]
1057   ""
1058   "
1059 {
1060   mt_emit_cbranch (GT, operands[0], mt_compare_op0, mt_compare_op1);
1061   DONE;
1062 }")
1063
1064 (define_expand "ble"
1065   [(use (match_operand 0 "" ""))]
1066   ""
1067   "
1068 {
1069   mt_emit_cbranch (LE, operands[0], mt_compare_op0, mt_compare_op1);
1070   DONE;
1071 }")
1072
1073 (define_expand "blt"
1074   [(use (match_operand 0 "" ""))]
1075   ""
1076   "
1077 {
1078   mt_emit_cbranch (LT, operands[0], mt_compare_op0, mt_compare_op1);
1079   DONE;
1080 }")
1081
1082 (define_expand "bgeu"
1083   [(use (match_operand 0 "" ""))]
1084   ""
1085   "
1086 {
1087   mt_emit_cbranch (GEU, operands[0], mt_compare_op0, mt_compare_op1);
1088   DONE;
1089 }")
1090
1091 (define_expand "bgtu"
1092   [(use (match_operand 0 "" ""))]
1093   ""
1094   "
1095 {
1096   mt_emit_cbranch (GTU, operands[0], mt_compare_op0, mt_compare_op1);
1097   DONE;
1098 }")
1099
1100 (define_expand "bleu"
1101   [(use (match_operand 0 "" ""))]
1102   ""
1103   "
1104 {
1105   mt_emit_cbranch (LEU, operands[0], mt_compare_op0, mt_compare_op1);
1106   DONE;
1107 }")
1108
1109 (define_expand "bltu"
1110   [(use (match_operand 0 "" ""))]
1111   ""
1112   "
1113 {
1114   mt_emit_cbranch (LTU, operands[0], mt_compare_op0, mt_compare_op1);
1115   DONE;
1116 }")
1117
1118 (define_expand "bunge"
1119   [(use (match_operand 0 "" ""))]
1120   ""
1121   "
1122 {
1123   mt_emit_cbranch (GEU, operands[0], mt_compare_op0, mt_compare_op1);
1124   DONE;
1125 }")
1126
1127 (define_expand "bungt"
1128   [(use (match_operand 0 "" ""))]
1129   ""
1130   "
1131 {
1132   mt_emit_cbranch (GTU, operands[0], mt_compare_op0, mt_compare_op1);
1133   DONE;
1134 }")
1135
1136 (define_expand "bunle"
1137   [(use (match_operand 0 "" ""))]
1138   ""
1139   "
1140 {
1141   mt_emit_cbranch (LEU, operands[0], mt_compare_op0, mt_compare_op1);
1142   DONE;
1143 }")
1144
1145 (define_expand "bunlt"
1146   [(use (match_operand 0 "" ""))]
1147   ""
1148   "
1149 {
1150   mt_emit_cbranch (LTU, operands[0], mt_compare_op0, mt_compare_op1);
1151   DONE;
1152 }")
1153
1154 (define_insn "*beq_true"
1155   [(set (pc)
1156         (if_then_else (eq (match_operand:SI 0 "reg_or_0_operand" "rJ")
1157                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1158                       (label_ref (match_operand 2 "" ""))
1159                       (pc)))]
1160   ""
1161   "breq %z0, %z1, %l2%#"
1162   [(set_attr "length" "4")
1163    (set_attr "type" "branch")])
1164
1165 (define_insn "*beq_false"
1166   [(set (pc)
1167         (if_then_else (eq (match_operand:SI 0 "reg_or_0_operand" "rJ")
1168                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1169                       (pc)
1170                       (label_ref (match_operand 2 "" ""))))]
1171   ""
1172   "brne %z0, %z1, %l2%#"
1173   [(set_attr "length" "4")
1174    (set_attr "type" "branch")])
1175
1176
1177 (define_insn "*bne_true"
1178   [(set (pc)
1179         (if_then_else (ne (match_operand:SI 0 "reg_or_0_operand" "rJ")
1180                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1181                       (label_ref (match_operand 2 "" ""))
1182                       (pc)))]
1183   ""
1184   "brne %z0, %z1, %l2%#"
1185   [(set_attr "length" "4")
1186    (set_attr "type" "branch")])
1187
1188 (define_insn "*bne_false"
1189   [(set (pc)
1190         (if_then_else (ne (match_operand:SI 0 "reg_or_0_operand" "rJ")
1191                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1192                       (pc)
1193                       (label_ref (match_operand 2 "" ""))))]
1194   ""
1195   "breq %z0, %z1, %l2%#"
1196   [(set_attr "length" "4")
1197    (set_attr "type" "branch")])
1198
1199 (define_insn "*blt_true"
1200   [(set (pc)
1201         (if_then_else (lt (match_operand:SI 0 "reg_or_0_operand" "rJ")
1202                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1203                       (label_ref (match_operand 2 "" ""))
1204                       (pc)))]
1205   ""
1206   "brlt %z0, %z1, %l2%#"
1207   [(set_attr "length" "4")
1208    (set_attr "type" "branch")])
1209
1210 (define_insn "*blt_false"
1211   [(set (pc)
1212         (if_then_else (lt (match_operand:SI 0 "reg_or_0_operand" "rJ")
1213                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1214                       (pc)
1215                       (label_ref (match_operand 2 "" ""))))]
1216   ""
1217   "brle %z1, %z0,%l2%#"
1218   [(set_attr "length" "4")
1219    (set_attr "type" "branch")])
1220
1221 (define_insn "*ble_true"
1222   [(set (pc)
1223         (if_then_else (le (match_operand:SI 0 "reg_or_0_operand" "rJ")
1224                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1225                       (label_ref (match_operand 2 "" ""))
1226                       (pc)))]
1227   ""
1228   "brle %z0, %z1, %l2%#"
1229   [(set_attr "length" "4")
1230    (set_attr "type" "branch")])
1231
1232 (define_insn "*ble_false"
1233   [(set (pc)
1234         (if_then_else (le (match_operand:SI 0 "reg_or_0_operand" "rJ")
1235                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1236                       (pc)
1237                       (label_ref (match_operand 2 "" ""))))]
1238   ""
1239   "brlt %z1, %z0,%l2%#"
1240   [(set_attr "length" "4")
1241    (set_attr "type" "branch")])
1242
1243 (define_insn "*bgt_true"
1244   [(set (pc)
1245         (if_then_else (gt (match_operand:SI 0 "reg_or_0_operand" "rJ")
1246                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1247                       (label_ref (match_operand 2 "" ""))
1248                       (pc)))]
1249   ""
1250   "brlt %z1, %z0, %l2%#"
1251   [(set_attr "length" "4")
1252    (set_attr "type" "branch")])
1253
1254 (define_insn "*bgt_false"
1255   [(set (pc)
1256         (if_then_else (gt (match_operand:SI 0 "reg_or_0_operand" "rJ")
1257                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1258                       (pc)
1259                       (label_ref (match_operand 2 "" ""))))]
1260   ""
1261   "brle %z0, %z1, %l2%#"
1262   [(set_attr "length" "4")
1263    (set_attr "type" "branch")])
1264
1265 (define_insn "*bge_true"
1266   [(set (pc)
1267         (if_then_else (ge (match_operand:SI 0 "reg_or_0_operand" "rJ")
1268                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1269                       (label_ref (match_operand 2 "" ""))
1270                       (pc)))]
1271   ""
1272   "brle %z1, %z0,%l2%#"
1273   [(set_attr "length" "4")
1274    (set_attr "type" "branch")])
1275
1276 (define_insn "*bge_false"
1277   [(set (pc)
1278         (if_then_else (ge (match_operand:SI 0 "reg_or_0_operand" "rJ")
1279                           (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1280                       (pc)
1281                       (label_ref (match_operand 2 "" ""))))]
1282   ""
1283   "brlt %z0, %z1, %l2%#"
1284   [(set_attr "length" "4")
1285    (set_attr "type" "branch")])
1286
1287 ;; No unsigned operators on Morpho mt.  All the unsigned operations are
1288 ;; converted to the signed operations above.
1289
1290 \f
1291 ;; Set flag operations
1292
1293 ;; "seq", "sne", "slt", "sle", "sgt", "sge", "sltu", "sleu",
1294 ;; "sgtu", and "sgeu" don't exist as regular instruction on the
1295 ;; mt, so these are not defined
1296
1297 ;; Call and branch instructions
1298
1299 (define_expand "call"
1300   [(parallel [(call (mem:SI (match_operand:SI 0 "register_operand" ""))
1301                             (match_operand 1 "" ""))
1302               (clobber (reg:SI 14))])]
1303   ""
1304   "
1305 {
1306     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
1307 }")
1308
1309 (define_insn "call_internal"
1310   [(call (mem:SI (match_operand 0 "register_operand" "r"))
1311          (match_operand 1 "" ""))
1312    ;; possibly add a clobber of the reg that gets the return address
1313    (clobber (reg:SI 14))]
1314   ""
1315   "jal r14, %0%#"
1316   [(set_attr "length" "4")
1317    (set_attr "type" "call")])
1318
1319 (define_expand "call_value"
1320   [(parallel [(set (match_operand 0 "register_operand" "")
1321                    (call (mem:SI (match_operand:SI 1 "register_operand" ""))
1322                                  (match_operand 2 "general_operand" "")))
1323               (clobber (reg:SI 14))])]
1324   ""
1325   "
1326 {
1327     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
1328 }")
1329
1330
1331 (define_insn "call_value_internal"
1332   [(set (match_operand 0 "register_operand" "=r")
1333         (call (mem:SI (match_operand 1 "register_operand" "r"))
1334               (match_operand 2 "" "")))
1335         ;; possibly add a clobber of the reg that gets the return address
1336         (clobber (reg:SI 14))]
1337   ""
1338   "jal r14, %1%#"
1339   [(set_attr "length" "4")
1340    (set_attr "type" "call")])
1341
1342 ;; Subroutine return
1343 (define_insn "return_internal"
1344   [(const_int 2)
1345    (return)
1346    (use (reg:SI 14))]
1347   ""
1348   "jal r0, r14%#"
1349   [(set_attr "length" "4")
1350    (set_attr "type" "call")])
1351
1352 ;; Interrupt return
1353 (define_insn "return_interrupt_internal"
1354   [(const_int 3)
1355    (return)
1356    (use (reg:SI 15))]
1357   ""
1358   "reti r15%#"
1359   [(set_attr "length" "4")
1360    (set_attr "type" "call")])
1361
1362 ;; Subroutine return
1363 (define_insn "eh_return_internal"
1364   [(return)
1365    (use (reg:SI 7))
1366    (use (reg:SI 8))
1367    (use (reg:SI 11))
1368    (use (reg:SI 10))]
1369   ""
1370   "jal r0, r11%#"
1371   [(set_attr "length" "4")
1372    (set_attr "type" "call")])
1373
1374
1375 ;; Normal unconditional jump
1376 (define_insn "jump"
1377   [(set (pc) (label_ref (match_operand 0 "" "")))]
1378   ""
1379   "jmp %l0%#"
1380   [(set_attr "length" "4")
1381    (set_attr "type" "branch")])
1382
1383 ;; Indirect jump through a register
1384 (define_insn "indirect_jump"
1385   [(set (pc) (match_operand 0 "register_operand" "r"))]
1386   ""
1387   "jal r0,%0%#"
1388   [(set_attr "length" "4")
1389    (set_attr "type" "call")])
1390
1391 (define_insn "tablejump"
1392   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1393    (use (label_ref (match_operand 1 "" "")))]
1394   ""
1395   "jal r0, %0%#"
1396   [(set_attr "length" "4")
1397    (set_attr "type" "call")])
1398
1399 \f
1400 (define_expand "prologue"
1401   [(const_int 1)]
1402   ""
1403   "
1404 {
1405   mt_expand_prologue ();
1406   DONE;
1407 }")
1408
1409 (define_expand "epilogue"
1410   [(const_int 2)]
1411   ""
1412   "
1413 {
1414   mt_expand_epilogue (NORMAL_EPILOGUE);
1415   DONE;
1416 }")
1417
1418
1419 (define_expand "eh_return"
1420   [(use (match_operand:SI 0 "register_operand" "r"))]
1421   ""
1422   "
1423 {
1424   mt_expand_eh_return (operands);
1425   DONE;
1426 }")
1427
1428
1429 (define_insn_and_split "eh_epilogue"
1430   [(unspec [(match_operand 0 "register_operand" "r")] 6)]
1431   ""
1432   "#"
1433   "reload_completed"
1434   [(const_int 1)]
1435   "mt_emit_eh_epilogue (operands); DONE;"
1436 )
1437 \f
1438 ;; No operation, needed in case the user uses -g but not -O.
1439 (define_insn "nop"
1440   [(const_int 0)]
1441   ""
1442   "nop"
1443   [(set_attr "length" "4")
1444    (set_attr "type" "arith")])
1445
1446 ;; ::::::::::::::::::::
1447 ;; ::
1448 ;; :: UNSPEC_VOLATILE usage
1449 ;; ::
1450 ;; ::::::::::::::::::::
1451 ;; 
1452 ;;      0       blockage
1453 ;;      1       Enable interrupts
1454 ;;      2       Disable interrupts
1455 ;;
1456
1457 ;; Pseudo instruction that prevents the scheduler from moving code above this
1458 ;; point.
1459 (define_insn "blockage"
1460   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
1461   ""
1462   ""
1463   [(set_attr "length" "0")])
1464
1465 ;; Trap instruction to allow usage of the __builtin_trap function
1466 (define_insn "trap"
1467   [(trap_if (const_int 1) (const_int 0))
1468    (clobber (reg:SI 14))]
1469   ""
1470   "si   r14%#"
1471   [(set_attr "length" "4")
1472    (set_attr "type" "branch")])
1473
1474 (define_expand "conditional_trap"
1475   [(trap_if (match_operator 0 "comparison_operator"
1476                             [(match_dup 2)
1477                              (match_dup 3)])
1478             (match_operand 1 "const_int_operand" ""))]
1479   ""
1480   "
1481 {
1482   operands[2] = mt_compare_op0;
1483   operands[3] = mt_compare_op1;
1484 }")
1485
1486 ;; Templates to control handling of interrupts
1487
1488 ;; Enable interrupts template
1489 (define_insn "ei"
1490   [(unspec_volatile [(const_int 0)] UNSPEC_EI)]
1491   ""
1492   "ei"
1493   [(set_attr "length" "4")])
1494
1495 ;; Enable interrupts template
1496 (define_insn "di"
1497   [(unspec_volatile [(const_int 0)] UNSPEC_DI)]
1498   ""
1499   "di"
1500   [(set_attr "length" "4")])