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)
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
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))
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
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")
63 (define_bypass 2 "arith_access" "branch_access")
64 (define_bypass 3 "mem_access" "branch_access")
65 (define_bypass 3 "io_access" "branch_access")
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"
84 (ne (match_operand:SI 0 "nonimmediate_operand" "+r,*m")
86 (label_ref (match_operand 1 "" ""))
89 (plus:SI (match_dup 0)
91 (clobber (match_scratch:SI 2 "=X,&r"))
92 (clobber (match_scratch:SI 3 "=X,&r"))]
93 "TARGET_MS1_16_003 || TARGET_MS2"
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).
106 (ne (match_operand:SI 0 "memory_operand" "")
108 (label_ref (match_operand 1 "" ""))
111 (plus:SI (match_dup 0)
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))
123 (label_ref (match_dup 1))
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.
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" "")
137 (set (pc) (if_then_else
138 (ne (match_dup 0) (match_dup 1))
139 (label_ref (match_operand 2 "" ""))
141 "TARGET_MS1_16_003 || TARGET_MS2"
142 [(parallel [(set (pc)
144 (ne (match_dup 0) (const_int 0))
145 (label_ref (match_dup 2))
148 (plus:SI (match_dup 0) (const_int -1)))
150 (clobber (reg:SI 0))])]
156 (define_expand "loadqi"
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" "")
170 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))
177 ;; operand 0 byte value to store
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"
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))))
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)))
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)))
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))
217 (define_expand "movqi"
218 [(set (match_operand:QI 0 "general_operand" "")
219 (match_operand:QI 1 "general_operand" ""))]
223 if (!reload_in_progress
225 && GET_CODE (operands[0]) == MEM
226 && GET_CODE (operands[1]) == MEM)
227 operands[1] = copy_to_mode_reg (QImode, operands[1]);
229 if ( (! TARGET_BYTE_ACCESS) && GET_CODE (operands[0]) == MEM)
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);
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);
245 emit_insn (gen_storeqi (gen_lowpart (SImode, data), address,
246 scratch1, scratch2, scratch3));
247 mt_set_memflags (operands[0]);
254 if ( (! TARGET_BYTE_ACCESS) && GET_CODE (operands[1]) == MEM)
256 rtx scratch1 = gen_reg_rtx (SImode);
257 rtx data = operands[0];
258 rtx address = XEXP (operands[1], 0);
261 if ( GET_CODE (address) != REG )
262 address = copy_to_mode_reg (SImode, address);
265 emit_insn (gen_loadqi (gen_lowpart (SImode, data), address, scratch1));
266 mt_set_memflags (operands[1]);
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))
280 rtx data = operands[0];
281 rtx address = XEXP (operands[1], 0);
285 emit_insn (gen_movsi (gen_lowpart (SImode, data), address));
286 mt_set_memflags (operands[1]);
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"))]
298 && (!memory_operand (operands[0], QImode)
299 || !memory_operand (operands[1], QImode))"
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"))]
312 && (!memory_operand (operands[0], QImode)
313 || !memory_operand (operands[1], QImode))"
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
327 ;; operand 0 location of result
328 ;; operand 1 memory address
330 (define_expand "loadhi"
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" "")
343 ;; align 16-bit value
344 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))
350 ;; operand 0 byte value to store
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"
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))))
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
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)))
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))
390 (define_expand "movhi"
391 [(set (match_operand:HI 0 "general_operand" "")
392 (match_operand:HI 1 "general_operand" ""))]
396 if (!reload_in_progress
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)
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);
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);
418 emit_insn (gen_storehi (gen_lowpart (SImode, data), address,
419 scratch1, scratch2, scratch3));
420 mt_set_memflags (operands[0]);
427 if ( GET_CODE (operands[1]) == MEM)
429 rtx scratch1 = gen_reg_rtx (SImode);
430 rtx data = operands[0];
431 rtx address = XEXP (operands[1], 0);
434 if (GET_CODE (address) != REG)
435 address = copy_to_mode_reg (SImode, address);
438 emit_insn (gen_loadhi (gen_lowpart (SImode, data), address,
440 mt_set_memflags (operands[1]);
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))
453 rtx data = operands[0];
454 rtx address = XEXP (operands[1], 0);
458 emit_insn (gen_movsi (gen_lowpart (SImode, data), address));
459 mt_set_memflags (operands[1]);
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)"
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" ""))]
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))
492 emit_insn (gen_movsi_high (operands[0], operands[1]));
493 emit_insn (gen_movsi_lo_sum (operands[0], operands[0], operands[1]));
499 (define_insn "movsi_high"
500 [(set (match_operand:SI 0 "register_operand" "=r")
501 (high:SI (match_operand:SI 1 "general_operand" "i")))]
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")))]
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 */
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)"
531 (high:SI (match_dup 1)))
533 (lo_sum:SI (match_dup 0)
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))"
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" ""))]
578 if (!reload_in_progress
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]) ) )
588 emit_insn (gen_movsf_high (operands[0], operands[1]));
589 emit_insn (gen_movsf_lo_sum (operands[0], operands[0], operands[1]));
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" "")))]
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" "")))]
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)"
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" ""))]
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))"
661 "(reload_completed || reload_in_progress)"
663 [(set (match_dup 2) (match_dup 3))
664 (set (match_dup 4) (match_dup 5))
668 /* figure out what precisely to put into operands 2, 3, 4, and 5 */
669 mt_split_words (SImode, DFmode, operands);
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"
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);
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))
704 /* need to make sure address is already in register */
705 if ( GET_CODE (address) != REG )
706 address = force_operand (address, scratch2);
709 emit_insn (gen_loadqi (gen_lowpart (SImode, data), address, scratch1));
710 mt_set_memflags (operands[1]);
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"
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);
732 /* need to make sure address is already in register */
733 if ( GET_CODE (address) != REG )
734 address = force_operand (address, scratch4);
737 emit_insn (gen_storeqi (gen_lowpart (SImode, data), address,
738 scratch1, scratch2, scratch3));
739 mt_set_memflags (operands[0]);
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"))]
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);
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))
770 /* need to make sure address is already in register */
771 if ( GET_CODE (address) != REG )
772 address = force_operand (address, scratch2);
775 emit_insn (gen_loadhi (gen_lowpart (SImode, data), address,
777 mt_set_memflags (operands[1]);
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"))]
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);
799 /* need to make sure address is already in register */
800 if ( GET_CODE (address) != REG )
801 address = force_operand (address, scratch4);
804 emit_insn (gen_storehi (gen_lowpart (SImode, data), address,
805 scratch1, scratch2, scratch3));
806 mt_set_memflags (operands[0]);
814 ;; 32 bit Integer arithmetic
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")))]
825 [(set_attr "length" "4,4")
826 (set_attr "type" "arith,arith")])
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")))]
837 [(set_attr "length" "4,4")
838 (set_attr "type" "arith,arith")])
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")))]
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")))]
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")))]
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")))]
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")))]
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")))]
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")))]
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")))]
936 [(set_attr "length" "4")
937 (set_attr "type" "arith")])
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"
950 [(set_attr "length" "4,4")
951 (set_attr "type" "arith,arith")])
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"
962 (compare (match_operand:SI 0 "register_operand" "")
963 (match_operand:SI 1 "arith_operand" "")))]
967 mt_compare_op0 = operands[0];
968 mt_compare_op1 = operands[1];
976 [(use (match_operand 0 "" ""))]
980 mt_emit_cbranch (EQ, operands[0], mt_compare_op0, mt_compare_op1);
985 [(use (match_operand 0 "" ""))]
989 mt_emit_cbranch (NE, operands[0], mt_compare_op0, mt_compare_op1);
994 [(use (match_operand 0 "" ""))]
998 mt_emit_cbranch (GE, operands[0], mt_compare_op0, mt_compare_op1);
1002 (define_expand "bgt"
1003 [(use (match_operand 0 "" ""))]
1007 mt_emit_cbranch (GT, operands[0], mt_compare_op0, mt_compare_op1);
1011 (define_expand "ble"
1012 [(use (match_operand 0 "" ""))]
1016 mt_emit_cbranch (LE, operands[0], mt_compare_op0, mt_compare_op1);
1020 (define_expand "blt"
1021 [(use (match_operand 0 "" ""))]
1025 mt_emit_cbranch (LT, operands[0], mt_compare_op0, mt_compare_op1);
1029 (define_expand "bgeu"
1030 [(use (match_operand 0 "" ""))]
1034 mt_emit_cbranch (GEU, operands[0], mt_compare_op0, mt_compare_op1);
1038 (define_expand "bgtu"
1039 [(use (match_operand 0 "" ""))]
1043 mt_emit_cbranch (GTU, operands[0], mt_compare_op0, mt_compare_op1);
1047 (define_expand "bleu"
1048 [(use (match_operand 0 "" ""))]
1052 mt_emit_cbranch (LEU, operands[0], mt_compare_op0, mt_compare_op1);
1056 (define_expand "bltu"
1057 [(use (match_operand 0 "" ""))]
1061 mt_emit_cbranch (LTU, operands[0], mt_compare_op0, mt_compare_op1);
1065 (define_expand "bunge"
1066 [(use (match_operand 0 "" ""))]
1070 mt_emit_cbranch (GEU, operands[0], mt_compare_op0, mt_compare_op1);
1074 (define_expand "bungt"
1075 [(use (match_operand 0 "" ""))]
1079 mt_emit_cbranch (GTU, operands[0], mt_compare_op0, mt_compare_op1);
1083 (define_expand "bunle"
1084 [(use (match_operand 0 "" ""))]
1088 mt_emit_cbranch (LEU, operands[0], mt_compare_op0, mt_compare_op1);
1092 (define_expand "bunlt"
1093 [(use (match_operand 0 "" ""))]
1097 mt_emit_cbranch (LTU, operands[0], mt_compare_op0, mt_compare_op1);
1101 (define_insn "*beq_true"
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 "" ""))
1108 "breq %z0, %z1, %l2%#"
1109 [(set_attr "length" "4")
1110 (set_attr "type" "branch")])
1112 (define_insn "*beq_false"
1114 (if_then_else (eq (match_operand:SI 0 "reg_or_0_operand" "rJ")
1115 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1117 (label_ref (match_operand 2 "" ""))))]
1119 "brne %z0, %z1, %l2%#"
1120 [(set_attr "length" "4")
1121 (set_attr "type" "branch")])
1124 (define_insn "*bne_true"
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 "" ""))
1131 "brne %z0, %z1, %l2%#"
1132 [(set_attr "length" "4")
1133 (set_attr "type" "branch")])
1135 (define_insn "*bne_false"
1137 (if_then_else (ne (match_operand:SI 0 "reg_or_0_operand" "rJ")
1138 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1140 (label_ref (match_operand 2 "" ""))))]
1142 "breq %z0, %z1, %l2%#"
1143 [(set_attr "length" "4")
1144 (set_attr "type" "branch")])
1146 (define_insn "*blt_true"
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 "" ""))
1153 "brlt %z0, %z1, %l2%#"
1154 [(set_attr "length" "4")
1155 (set_attr "type" "branch")])
1157 (define_insn "*blt_false"
1159 (if_then_else (lt (match_operand:SI 0 "reg_or_0_operand" "rJ")
1160 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1162 (label_ref (match_operand 2 "" ""))))]
1164 "brle %z1, %z0,%l2%#"
1165 [(set_attr "length" "4")
1166 (set_attr "type" "branch")])
1168 (define_insn "*ble_true"
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 "" ""))
1175 "brle %z0, %z1, %l2%#"
1176 [(set_attr "length" "4")
1177 (set_attr "type" "branch")])
1179 (define_insn "*ble_false"
1181 (if_then_else (le (match_operand:SI 0 "reg_or_0_operand" "rJ")
1182 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1184 (label_ref (match_operand 2 "" ""))))]
1186 "brlt %z1, %z0,%l2%#"
1187 [(set_attr "length" "4")
1188 (set_attr "type" "branch")])
1190 (define_insn "*bgt_true"
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 "" ""))
1197 "brlt %z1, %z0, %l2%#"
1198 [(set_attr "length" "4")
1199 (set_attr "type" "branch")])
1201 (define_insn "*bgt_false"
1203 (if_then_else (gt (match_operand:SI 0 "reg_or_0_operand" "rJ")
1204 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1206 (label_ref (match_operand 2 "" ""))))]
1208 "brle %z0, %z1, %l2%#"
1209 [(set_attr "length" "4")
1210 (set_attr "type" "branch")])
1212 (define_insn "*bge_true"
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 "" ""))
1219 "brle %z1, %z0,%l2%#"
1220 [(set_attr "length" "4")
1221 (set_attr "type" "branch")])
1223 (define_insn "*bge_false"
1225 (if_then_else (ge (match_operand:SI 0 "reg_or_0_operand" "rJ")
1226 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1228 (label_ref (match_operand 2 "" ""))))]
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))])]
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))]
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))])]
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))]
1286 [(set_attr "length" "4")
1287 (set_attr "type" "call")])
1289 ;; Subroutine return
1290 (define_insn "return_internal"
1296 [(set_attr "length" "4")
1297 (set_attr "type" "call")])
1300 (define_insn "return_interrupt_internal"
1306 [(set_attr "length" "4")
1307 (set_attr "type" "call")])
1309 ;; Subroutine return
1310 (define_insn "eh_return_internal"
1318 [(set_attr "length" "4")
1319 (set_attr "type" "call")])
1322 ;; Normal unconditional jump
1324 [(set (pc) (label_ref (match_operand 0 "" "")))]
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"))]
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 "" "")))]
1343 [(set_attr "length" "4")
1344 (set_attr "type" "call")])
1347 (define_expand "prologue"
1352 mt_expand_prologue ();
1356 (define_expand "epilogue"
1361 mt_expand_epilogue (NORMAL_EPILOGUE);
1366 (define_expand "eh_return"
1367 [(use (match_operand:SI 0 "register_operand" "r"))]
1371 mt_expand_eh_return (operands);
1376 (define_insn_and_split "eh_epilogue"
1377 [(unspec [(match_operand 0 "register_operand" "r")] 6)]
1382 "mt_emit_eh_epilogue (operands); DONE;"
1385 ;; No operation, needed in case the user uses -g but not -O.
1390 [(set_attr "length" "4")
1391 (set_attr "type" "arith")])
1393 ;; ::::::::::::::::::::
1395 ;; :: UNSPEC_VOLATILE usage
1397 ;; ::::::::::::::::::::
1400 ;; 1 Enable interrupts
1401 ;; 2 Disable interrupts
1404 ;; Pseudo instruction that prevents the scheduler from moving code above this
1406 (define_insn "blockage"
1407 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
1410 [(set_attr "length" "0")])
1412 ;; Trap instruction to allow usage of the __builtin_trap function
1414 [(trap_if (const_int 1) (const_int 0))
1415 (clobber (reg:SI 14))]
1418 [(set_attr "length" "4")
1419 (set_attr "type" "branch")])
1421 (define_expand "conditional_trap"
1422 [(trap_if (match_operator 0 "comparison_operator"
1425 (match_operand 1 "const_int_operand" ""))]
1429 operands[2] = mt_compare_op0;
1430 operands[3] = mt_compare_op1;
1433 ;; Templates to control handling of interrupts
1435 ;; Enable interrupts template
1437 [(unspec_volatile [(const_int 0)] UNSPEC_EI)]
1440 [(set_attr "length" "4")])
1442 ;; Enable interrupts template
1444 [(unspec_volatile [(const_int 0)] UNSPEC_DI)]
1447 [(set_attr "length" "4")])