1 ;; Machine description for MorphoRISC1
2 ;; Copyright (C) 2005, 2007 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 3, 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 COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
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))])]
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
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" "")
166 (label_ref (match_operand 1 "" ""))
168 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
169 (unspec [(const_int 0)] UNSPEC_LOOP)]
172 [(set_attr "length" "0")])
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
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)]
185 [(set_attr "length" "4")
186 (set_attr "type" "branch")])
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" "")
197 (label_ref (match_operand 4 "" ""))
200 (plus:SI (match_dup 0)
202 (clobber (match_scratch:SI 5 ""))
203 (clobber (match_scratch:SI 6 ""))])]
204 "TARGET_MS1_16_003 || TARGET_MS2"
209 (define_expand "loadqi"
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)))
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" "")
223 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))
230 ;; operand 0 byte value to store
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"
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)))
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))))
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)))
253 ;; clear appropriate bits
254 (set (match_dup 2) (and:SI (match_dup 2) (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)))
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))
270 (define_expand "movqi"
271 [(set (match_operand:QI 0 "general_operand" "")
272 (match_operand:QI 1 "general_operand" ""))]
276 if (!reload_in_progress
278 && GET_CODE (operands[0]) == MEM
279 && GET_CODE (operands[1]) == MEM)
280 operands[1] = copy_to_mode_reg (QImode, operands[1]);
282 if ( (! TARGET_BYTE_ACCESS) && GET_CODE (operands[0]) == MEM)
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);
291 if ( GET_CODE (data) != REG )
292 data = copy_to_mode_reg (QImode, data);
294 if ( GET_CODE (address) != REG )
295 address = copy_to_mode_reg (SImode, address);
298 emit_insn (gen_storeqi (gen_lowpart (SImode, data), address,
299 scratch1, scratch2, scratch3));
300 mt_set_memflags (operands[0]);
307 if ( (! TARGET_BYTE_ACCESS) && GET_CODE (operands[1]) == MEM)
309 rtx scratch1 = gen_reg_rtx (SImode);
310 rtx data = operands[0];
311 rtx address = XEXP (operands[1], 0);
314 if ( GET_CODE (address) != REG )
315 address = copy_to_mode_reg (SImode, address);
318 emit_insn (gen_loadqi (gen_lowpart (SImode, data), address, scratch1));
319 mt_set_memflags (operands[1]);
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))
333 rtx data = operands[0];
334 rtx address = XEXP (operands[1], 0);
338 emit_insn (gen_movsi (gen_lowpart (SImode, data), address));
339 mt_set_memflags (operands[1]);
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"))]
351 && (!memory_operand (operands[0], QImode)
352 || !memory_operand (operands[1], QImode))"
358 [(set_attr "length" "4,4,4,4")
359 (set_attr "type" "arith,load,store,arith")])
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"))]
365 && (!memory_operand (operands[0], QImode)
366 || !memory_operand (operands[1], QImode))"
370 [(set_attr "length" "4,4")
371 (set_attr "type" "arith,arith")])
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
380 ;; operand 0 location of result
381 ;; operand 1 memory address
383 (define_expand "loadhi"
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)))
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" "")
396 ;; align 16-bit value
397 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))
403 ;; operand 0 byte value to store
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"
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)))
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))))
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)))
426 ;; clear appropriate bits
427 (set (match_dup 2) (and:SI (match_dup 2) (match_dup 4)))
429 ;; align 16-bit value
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)))
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))
443 (define_expand "movhi"
444 [(set (match_operand:HI 0 "general_operand" "")
445 (match_operand:HI 1 "general_operand" ""))]
449 if (!reload_in_progress
451 && GET_CODE (operands[0]) == MEM
452 && GET_CODE (operands[1]) == MEM)
453 operands[1] = copy_to_mode_reg (HImode, operands[1]);
455 if ( GET_CODE (operands[0]) == MEM)
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);
464 if (GET_CODE (data) != REG)
465 data = copy_to_mode_reg (HImode, data);
467 if (GET_CODE (address) != REG)
468 address = copy_to_mode_reg (SImode, address);
471 emit_insn (gen_storehi (gen_lowpart (SImode, data), address,
472 scratch1, scratch2, scratch3));
473 mt_set_memflags (operands[0]);
480 if ( GET_CODE (operands[1]) == MEM)
482 rtx scratch1 = gen_reg_rtx (SImode);
483 rtx data = operands[0];
484 rtx address = XEXP (operands[1], 0);
487 if (GET_CODE (address) != REG)
488 address = copy_to_mode_reg (SImode, address);
491 emit_insn (gen_loadhi (gen_lowpart (SImode, data), address,
493 mt_set_memflags (operands[1]);
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))
506 rtx data = operands[0];
507 rtx address = XEXP (operands[1], 0);
511 emit_insn (gen_movsi (gen_lowpart (SImode, data), address));
512 mt_set_memflags (operands[1]);
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)"
527 [(set_attr "length" "4,4")
528 (set_attr "type" "arith,arith")])
530 (define_expand "movsi"
531 [(set (match_operand:SI 0 "nonimmediate_operand" "")
532 (match_operand:SI 1 "general_operand" ""))]
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]);
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))
545 emit_insn (gen_movsi_high (operands[0], operands[1]));
546 emit_insn (gen_movsi_lo_sum (operands[0], operands[0], operands[1]));
552 (define_insn "movsi_high"
553 [(set (match_operand:SI 0 "register_operand" "=r")
554 (high:SI (match_operand:SI 1 "general_operand" "i")))]
558 return \"ldui\\t%0, %H1\";
560 [(set_attr "length" "4")
561 (set_attr "type" "arith")])
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")))]
571 return \"addui\\t%0, %1, %L2\";
573 [(set_attr "length" "4")
574 (set_attr "type" "arith")])
576 /* Take care of constants that don't fit in single instruction */
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)"
584 (high:SI (match_dup 1)))
586 (lo_sum:SI (match_dup 0)
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.
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))"
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")]
620 ;; Floating Point Moves
622 ;; Note - Patterns for SF mode moves are compulsory, but
623 ;; patterns for DF are optional, as GCC can synthesize them.
625 (define_expand "movsf"
626 [(set (match_operand:SF 0 "general_operand" "")
627 (match_operand:SF 1 "general_operand" ""))]
631 if (!reload_in_progress
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]);
638 /* Take care of reg <- SF constant */
639 if ( const_double_operand (operands[1], GET_MODE (operands[1]) ) )
641 emit_insn (gen_movsf_high (operands[0], operands[1]));
642 emit_insn (gen_movsf_lo_sum (operands[0], operands[0], operands[1]));
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" "")))]
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\";
662 [(set_attr "length" "4")
663 (set_attr "type" "arith")])
665 (define_insn "movsf_high"
666 [(set (match_operand:SF 0 "register_operand" "=r")
667 (high:SF (match_operand:SF 1 "const_double_operand" "")))]
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\";
679 [(set_attr "length" "4")
680 (set_attr "type" "arith")])
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)"
691 [(set_attr "length" "4,4,4")
692 (set_attr "type" "arith,load,store")]
695 (define_expand "movdf"
696 [(set (match_operand:DF 0 "general_operand" "")
697 (match_operand:DF 1 "general_operand" ""))]
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);
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))"
714 "(reload_completed || reload_in_progress)"
716 [(set (match_dup 2) (match_dup 3))
717 (set (match_dup 4) (match_dup 5))
721 /* figure out what precisely to put into operands 2, 3, 4, and 5 */
722 mt_split_words (SImode, DFmode, operands);
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.
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"
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);
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))
757 /* need to make sure address is already in register */
758 if ( GET_CODE (address) != REG )
759 address = force_operand (address, scratch2);
762 emit_insn (gen_loadqi (gen_lowpart (SImode, data), address, scratch1));
763 mt_set_memflags (operands[1]);
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"
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);
785 /* need to make sure address is already in register */
786 if ( GET_CODE (address) != REG )
787 address = force_operand (address, scratch4);
790 emit_insn (gen_storeqi (gen_lowpart (SImode, data), address,
791 scratch1, scratch2, scratch3));
792 mt_set_memflags (operands[0]);
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"))]
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);
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))
823 /* need to make sure address is already in register */
824 if ( GET_CODE (address) != REG )
825 address = force_operand (address, scratch2);
828 emit_insn (gen_loadhi (gen_lowpart (SImode, data), address,
830 mt_set_memflags (operands[1]);
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"))]
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);
852 /* need to make sure address is already in register */
853 if ( GET_CODE (address) != REG )
854 address = force_operand (address, scratch4);
857 emit_insn (gen_storehi (gen_lowpart (SImode, data), address,
858 scratch1, scratch2, scratch3));
859 mt_set_memflags (operands[0]);
867 ;; 32-bit Integer arithmetic
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")))]
878 [(set_attr "length" "4,4")
879 (set_attr "type" "arith,arith")])
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")))]
890 [(set_attr "length" "4,4")
891 (set_attr "type" "arith,arith")])
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")))]
901 [(set_attr "length" "4,4")
902 (set_attr "type" "arith,arith")])
905 ;; 32-bit Integer Shifts and Rotates
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")))]
916 [(set_attr "length" "4,4")
917 (set_attr "type" "arith,arith")])
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")))]
928 [(set_attr "length" "4,4")
929 (set_attr "type" "arith,arith")])
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")))]
940 [(set_attr "length" "4,4")
941 (set_attr "type" "arith,arith")])
944 ;; 32-Bit Integer Logical operations
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")))]
955 [(set_attr "length" "4,4")
956 (set_attr "type" "arith,arith")])
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")))]
967 [(set_attr "length" "4,4")
968 (set_attr "type" "arith,arith")])
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")))]
979 [(set_attr "length" "4,4")
980 (set_attr "type" "arith,arith")])
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")))]
989 [(set_attr "length" "4")
990 (set_attr "type" "arith")])
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"
1003 [(set_attr "length" "4,4")
1004 (set_attr "type" "arith,arith")])
1009 ;; Note, we store the operands in the comparison insns, and use them later
1010 ;; when generating the branch or scc operation.
1012 ;; First the routines called by the machine independent part of the compiler
1013 (define_expand "cmpsi"
1015 (compare (match_operand:SI 0 "register_operand" "")
1016 (match_operand:SI 1 "arith_operand" "")))]
1020 mt_compare_op0 = operands[0];
1021 mt_compare_op1 = operands[1];
1028 (define_expand "beq"
1029 [(use (match_operand 0 "" ""))]
1033 mt_emit_cbranch (EQ, operands[0], mt_compare_op0, mt_compare_op1);
1037 (define_expand "bne"
1038 [(use (match_operand 0 "" ""))]
1042 mt_emit_cbranch (NE, operands[0], mt_compare_op0, mt_compare_op1);
1046 (define_expand "bge"
1047 [(use (match_operand 0 "" ""))]
1051 mt_emit_cbranch (GE, operands[0], mt_compare_op0, mt_compare_op1);
1055 (define_expand "bgt"
1056 [(use (match_operand 0 "" ""))]
1060 mt_emit_cbranch (GT, operands[0], mt_compare_op0, mt_compare_op1);
1064 (define_expand "ble"
1065 [(use (match_operand 0 "" ""))]
1069 mt_emit_cbranch (LE, operands[0], mt_compare_op0, mt_compare_op1);
1073 (define_expand "blt"
1074 [(use (match_operand 0 "" ""))]
1078 mt_emit_cbranch (LT, operands[0], mt_compare_op0, mt_compare_op1);
1082 (define_expand "bgeu"
1083 [(use (match_operand 0 "" ""))]
1087 mt_emit_cbranch (GEU, operands[0], mt_compare_op0, mt_compare_op1);
1091 (define_expand "bgtu"
1092 [(use (match_operand 0 "" ""))]
1096 mt_emit_cbranch (GTU, operands[0], mt_compare_op0, mt_compare_op1);
1100 (define_expand "bleu"
1101 [(use (match_operand 0 "" ""))]
1105 mt_emit_cbranch (LEU, operands[0], mt_compare_op0, mt_compare_op1);
1109 (define_expand "bltu"
1110 [(use (match_operand 0 "" ""))]
1114 mt_emit_cbranch (LTU, operands[0], mt_compare_op0, mt_compare_op1);
1118 (define_expand "bunge"
1119 [(use (match_operand 0 "" ""))]
1123 mt_emit_cbranch (GEU, operands[0], mt_compare_op0, mt_compare_op1);
1127 (define_expand "bungt"
1128 [(use (match_operand 0 "" ""))]
1132 mt_emit_cbranch (GTU, operands[0], mt_compare_op0, mt_compare_op1);
1136 (define_expand "bunle"
1137 [(use (match_operand 0 "" ""))]
1141 mt_emit_cbranch (LEU, operands[0], mt_compare_op0, mt_compare_op1);
1145 (define_expand "bunlt"
1146 [(use (match_operand 0 "" ""))]
1150 mt_emit_cbranch (LTU, operands[0], mt_compare_op0, mt_compare_op1);
1154 (define_insn "*beq_true"
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 "" ""))
1161 "breq %z0, %z1, %l2%#"
1162 [(set_attr "length" "4")
1163 (set_attr "type" "branch")])
1165 (define_insn "*beq_false"
1167 (if_then_else (eq (match_operand:SI 0 "reg_or_0_operand" "rJ")
1168 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1170 (label_ref (match_operand 2 "" ""))))]
1172 "brne %z0, %z1, %l2%#"
1173 [(set_attr "length" "4")
1174 (set_attr "type" "branch")])
1177 (define_insn "*bne_true"
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 "" ""))
1184 "brne %z0, %z1, %l2%#"
1185 [(set_attr "length" "4")
1186 (set_attr "type" "branch")])
1188 (define_insn "*bne_false"
1190 (if_then_else (ne (match_operand:SI 0 "reg_or_0_operand" "rJ")
1191 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1193 (label_ref (match_operand 2 "" ""))))]
1195 "breq %z0, %z1, %l2%#"
1196 [(set_attr "length" "4")
1197 (set_attr "type" "branch")])
1199 (define_insn "*blt_true"
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 "" ""))
1206 "brlt %z0, %z1, %l2%#"
1207 [(set_attr "length" "4")
1208 (set_attr "type" "branch")])
1210 (define_insn "*blt_false"
1212 (if_then_else (lt (match_operand:SI 0 "reg_or_0_operand" "rJ")
1213 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1215 (label_ref (match_operand 2 "" ""))))]
1217 "brle %z1, %z0,%l2%#"
1218 [(set_attr "length" "4")
1219 (set_attr "type" "branch")])
1221 (define_insn "*ble_true"
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 "" ""))
1228 "brle %z0, %z1, %l2%#"
1229 [(set_attr "length" "4")
1230 (set_attr "type" "branch")])
1232 (define_insn "*ble_false"
1234 (if_then_else (le (match_operand:SI 0 "reg_or_0_operand" "rJ")
1235 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1237 (label_ref (match_operand 2 "" ""))))]
1239 "brlt %z1, %z0,%l2%#"
1240 [(set_attr "length" "4")
1241 (set_attr "type" "branch")])
1243 (define_insn "*bgt_true"
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 "" ""))
1250 "brlt %z1, %z0, %l2%#"
1251 [(set_attr "length" "4")
1252 (set_attr "type" "branch")])
1254 (define_insn "*bgt_false"
1256 (if_then_else (gt (match_operand:SI 0 "reg_or_0_operand" "rJ")
1257 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1259 (label_ref (match_operand 2 "" ""))))]
1261 "brle %z0, %z1, %l2%#"
1262 [(set_attr "length" "4")
1263 (set_attr "type" "branch")])
1265 (define_insn "*bge_true"
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 "" ""))
1272 "brle %z1, %z0,%l2%#"
1273 [(set_attr "length" "4")
1274 (set_attr "type" "branch")])
1276 (define_insn "*bge_false"
1278 (if_then_else (ge (match_operand:SI 0 "reg_or_0_operand" "rJ")
1279 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1281 (label_ref (match_operand 2 "" ""))))]
1283 "brlt %z0, %z1, %l2%#"
1284 [(set_attr "length" "4")
1285 (set_attr "type" "branch")])
1287 ;; No unsigned operators on Morpho mt. All the unsigned operations are
1288 ;; converted to the signed operations above.
1291 ;; Set flag operations
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
1297 ;; Call and branch instructions
1299 (define_expand "call"
1300 [(parallel [(call (mem:SI (match_operand:SI 0 "register_operand" ""))
1301 (match_operand 1 "" ""))
1302 (clobber (reg:SI 14))])]
1306 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
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))]
1316 [(set_attr "length" "4")
1317 (set_attr "type" "call")])
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))])]
1327 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
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))]
1339 [(set_attr "length" "4")
1340 (set_attr "type" "call")])
1342 ;; Subroutine return
1343 (define_insn "return_internal"
1349 [(set_attr "length" "4")
1350 (set_attr "type" "call")])
1353 (define_insn "return_interrupt_internal"
1359 [(set_attr "length" "4")
1360 (set_attr "type" "call")])
1362 ;; Subroutine return
1363 (define_insn "eh_return_internal"
1371 [(set_attr "length" "4")
1372 (set_attr "type" "call")])
1375 ;; Normal unconditional jump
1377 [(set (pc) (label_ref (match_operand 0 "" "")))]
1380 [(set_attr "length" "4")
1381 (set_attr "type" "branch")])
1383 ;; Indirect jump through a register
1384 (define_insn "indirect_jump"
1385 [(set (pc) (match_operand 0 "register_operand" "r"))]
1388 [(set_attr "length" "4")
1389 (set_attr "type" "call")])
1391 (define_insn "tablejump"
1392 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1393 (use (label_ref (match_operand 1 "" "")))]
1396 [(set_attr "length" "4")
1397 (set_attr "type" "call")])
1400 (define_expand "prologue"
1405 mt_expand_prologue ();
1409 (define_expand "epilogue"
1414 mt_expand_epilogue (NORMAL_EPILOGUE);
1419 (define_expand "eh_return"
1420 [(use (match_operand:SI 0 "register_operand" "r"))]
1424 mt_expand_eh_return (operands);
1429 (define_insn_and_split "eh_epilogue"
1430 [(unspec [(match_operand 0 "register_operand" "r")] 6)]
1435 "mt_emit_eh_epilogue (operands); DONE;"
1438 ;; No operation, needed in case the user uses -g but not -O.
1443 [(set_attr "length" "4")
1444 (set_attr "type" "arith")])
1446 ;; ::::::::::::::::::::
1448 ;; :: UNSPEC_VOLATILE usage
1450 ;; ::::::::::::::::::::
1453 ;; 1 Enable interrupts
1454 ;; 2 Disable interrupts
1457 ;; Pseudo instruction that prevents the scheduler from moving code above this
1459 (define_insn "blockage"
1460 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
1463 [(set_attr "length" "0")])
1465 ;; Trap instruction to allow usage of the __builtin_trap function
1467 [(trap_if (const_int 1) (const_int 0))
1468 (clobber (reg:SI 14))]
1471 [(set_attr "length" "4")
1472 (set_attr "type" "branch")])
1474 (define_expand "conditional_trap"
1475 [(trap_if (match_operator 0 "comparison_operator"
1478 (match_operand 1 "const_int_operand" ""))]
1482 operands[2] = mt_compare_op0;
1483 operands[3] = mt_compare_op1;
1486 ;; Templates to control handling of interrupts
1488 ;; Enable interrupts template
1490 [(unspec_volatile [(const_int 0)] UNSPEC_EI)]
1493 [(set_attr "length" "4")])
1495 ;; Enable interrupts template
1497 [(unspec_volatile [(const_int 0)] UNSPEC_DI)]
1500 [(set_attr "length" "4")])