xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/fr30/fr30.md (revision d909946ca08dceb44d7d0f22ec9488679695d976)
1;; FR30 machine description.
2;; Copyright (C) 1998-2013 Free Software Foundation, Inc.
3;; Contributed by Cygnus Solutions.
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
21;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
22
23;;{{{ Attributes
24
25(define_attr "length" "" (const_int 2))
26
27;; Used to distinguish between small memory model targets and big mode targets.
28
29(define_attr "size" "small,big"
30  (const (if_then_else (symbol_ref "TARGET_SMALL_MODEL")
31		       (const_string "small")
32		       (const_string "big"))))
33
34
35;; Define an attribute to be used by the delay slot code.
36;; An instruction by default is considered to be 'delayable'
37;; that is, it can be placed into a delay slot, but it is not
38;; itself a delayed branch type instruction.  An instruction
39;; whose type is 'delayed' is one which has a delay slot, and
40;; an instruction whose delay_type is 'other' is one which does
41;; not have a delay slot, nor can it be placed into a delay slot.
42
43(define_attr "delay_type" "delayable,delayed,other" (const_string "delayable"))
44
45;;}}}
46;;{{{ Delay Slot Specifications
47
48(define_delay (eq_attr "delay_type" "delayed")
49  [(and (eq_attr "delay_type" "delayable")
50	(eq_attr "length" "2"))
51   (nil)
52   (nil)]
53)
54
55(include "predicates.md")
56(include "constraints.md")
57
58;;}}}
59;;{{{ Moves
60
61;;{{{ Comment
62
63;; Wrap moves in define_expand to prevent memory->memory moves from being
64;; generated at the RTL level, which generates better code for most machines
65;; which can't do mem->mem moves.
66
67;; If operand 0 is a `subreg' with mode M of a register whose own mode is wider
68;; than M, the effect of this instruction is to store the specified value in
69;; the part of the register that corresponds to mode M.  The effect on the rest
70;; of the register is undefined.
71
72;; This class of patterns is special in several ways.  First of all, each of
73;; these names *must* be defined, because there is no other way to copy a datum
74;; from one place to another.
75
76;; Second, these patterns are not used solely in the RTL generation pass.  Even
77;; the reload pass can generate move insns to copy values from stack slots into
78;; temporary registers.  When it does so, one of the operands is a hard
79;; register and the other is an operand that can need to be reloaded into a
80;; register.
81
82;; Therefore, when given such a pair of operands, the pattern must
83;; generate RTL which needs no reloading and needs no temporary
84;; registers--no registers other than the operands.  For example, if
85;; you support the pattern with a `define_expand', then in such a
86;; case the `define_expand' mustn't call `force_reg' or any other such
87;; function which might generate new pseudo registers.
88
89;; This requirement exists even for subword modes on a RISC machine
90;; where fetching those modes from memory normally requires several
91;; insns and some temporary registers.  Look in `spur.md' to see how
92;; the requirement can be satisfied.
93
94;; During reload a memory reference with an invalid address may be passed as an
95;; operand.  Such an address will be replaced with a valid address later in the
96;; reload pass.  In this case, nothing may be done with the address except to
97;; use it as it stands.  If it is copied, it will not be replaced with a valid
98;; address.  No attempt should be made to make such an address into a valid
99;; address and no routine (such as `change_address') that will do so may be
100;; called.  Note that `general_operand' will fail when applied to such an
101;; address.
102;;
103;; The global variable `reload_in_progress' (which must be explicitly declared
104;; if required) can be used to determine whether such special handling is
105;; required.
106;;
107;; The variety of operands that have reloads depends on the rest of
108;; the machine description, but typically on a RISC machine these can
109;; only be pseudo registers that did not get hard registers, while on
110;; other machines explicit memory references will get optional
111;; reloads.
112;;
113;; If a scratch register is required to move an object to or from memory, it
114;; can be allocated using `gen_reg_rtx' prior to reload.  But this is
115;; impossible during and after reload.  If there are cases needing scratch
116;; registers after reload, you must define `SECONDARY_INPUT_RELOAD_CLASS' and
117;; perhaps also `SECONDARY_OUTPUT_RELOAD_CLASS' to detect them, and provide
118;; patterns `reload_inM' or `reload_outM' to handle them.
119
120;; The constraints on a `moveM' must permit moving any hard register to any
121;; other hard register provided that `HARD_REGNO_MODE_OK' permits mode M in
122;; both registers and `REGISTER_MOVE_COST' applied to their classes returns a
123;; value of 2.
124
125;; It is obligatory to support floating point `moveM' instructions
126;; into and out of any registers that can hold fixed point values,
127;; because unions and structures (which have modes `SImode' or
128;; `DImode') can be in those registers and they may have floating
129;; point members.
130
131;; There may also be a need to support fixed point `moveM' instructions in and
132;; out of floating point registers.  Unfortunately, I have forgotten why this
133;; was so, and I don't know whether it is still true.  If `HARD_REGNO_MODE_OK'
134;; rejects fixed point values in floating point registers, then the constraints
135;; of the fixed point `moveM' instructions must be designed to avoid ever
136;; trying to reload into a floating point register.
137
138;;}}}
139;;{{{ Push and Pop
140
141;; Push a register onto the stack
142(define_insn "movsi_push"
143  [(set (mem:SI (pre_dec:SI (reg:SI 15)))
144	(match_operand:SI 0 "register_operand" "a"))]
145  ""
146  "st	%0, @-r15"
147)
148
149;; Pop a register off the stack
150(define_insn "movsi_pop"
151  [(set (match_operand:SI 0 "register_operand" "=a")
152	(mem:SI (post_inc:SI (reg:SI 15))))]
153  ""
154  "ld	@r15+, %0"
155)
156
157;;}}}
158;;{{{ 1 Byte Moves
159
160(define_expand "movqi"
161  [(set (match_operand:QI 0 "general_operand" "")
162	(match_operand:QI 1 "general_operand" ""))]
163  ""
164  "
165{
166  if (!reload_in_progress
167      && !reload_completed
168      && GET_CODE (operands[0]) == MEM
169      && (GET_CODE (operands[1]) == MEM
170         || immediate_operand (operands[1], QImode)))
171    operands[1] = copy_to_mode_reg (QImode, operands[1]);
172}")
173
174(define_insn "movqi_unsigned_register_load"
175  [(set (match_operand:SI 0 "register_operand"              "=r")
176	(zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
177  ""
178  "ldub	%1, %0"
179)
180
181(define_expand "movqi_signed_register_load"
182  [(set (match_operand:SI 0 "register_operand"               "")
183	(sign_extend:SI (match_operand:QI 1 "memory_operand" "")))]
184  ""
185  "
186  emit_insn (gen_movqi_unsigned_register_load (operands[0], operands[1]));
187  emit_insn (gen_extendqisi2 (operands[0], operands[0]));
188  DONE;
189  "
190)
191
192(define_insn "*movqi_internal"
193  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,red,m,r")
194	(match_operand:QI 1 "general_operand"       "i,red,r,rm"))]
195  ""
196  "@
197   ldi:8\\t#%A1, %0
198   mov  \\t%1, %0
199   stb  \\t%1, %0
200   ldub \\t%1, %0"
201)
202
203;;}}}
204;;{{{ 2 Byte Moves
205
206(define_expand "movhi"
207  [(set (match_operand:HI 0 "general_operand" "")
208	(match_operand:HI 1 "general_operand" ""))]
209  ""
210  "
211{
212  if (!reload_in_progress
213      && !reload_completed
214      && GET_CODE (operands[0]) == MEM
215      && (GET_CODE (operands[1]) == MEM
216	 || immediate_operand (operands[1], HImode)))
217    operands[1] = copy_to_mode_reg (HImode, operands[1]);
218}")
219
220(define_insn "movhi_unsigned_register_load"
221  [(set (match_operand:SI 0 "register_operand" "=r")
222	(zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
223  ""
224  "lduh	%1, %0"
225)
226
227(define_expand "movhi_signed_register_load"
228  [(set (match_operand:SI 0 "register_operand" "")
229	(sign_extend:SI (match_operand:HI 1 "memory_operand" "")))]
230  ""
231  "
232  emit_insn (gen_movhi_unsigned_register_load (operands[0], operands[1]));
233  emit_insn (gen_extendhisi2 (operands[0], operands[0]));
234  DONE;
235  "
236)
237
238(define_insn "*movhi_internal"
239  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,red,m,r")
240	(match_operand:HI 1 "general_operand"       "L,M,n,red,r,rm"))]
241  ""
242  "@
243   ldi:8 \\t#%1, %0
244   ldi:20\\t#%1, %0
245   ldi:32\\t#%1, %0
246   mov   \\t%1, %0
247   sth   \\t%1, %0
248   lduh  \\t%1, %0"
249  [(set_attr "length" "*,4,6,*,*,*")]
250)
251
252;;}}}
253;;{{{ 4 Byte Moves
254
255;; If the destination is a MEM and the source is a
256;; MEM or an CONST_INT move the source into a register.
257(define_expand "movsi"
258  [(set (match_operand:SI 0 "nonimmediate_operand" "")
259	(match_operand:SI 1 "general_operand" ""))]
260  ""
261  "{
262  if (!reload_in_progress
263      && !reload_completed
264      && GET_CODE(operands[0]) == MEM
265      && (GET_CODE (operands[1]) == MEM
266	  || immediate_operand (operands[1], SImode)))
267     operands[1] = copy_to_mode_reg (SImode, operands[1]);
268  }"
269)
270
271;; We can do some clever tricks when loading certain immediate
272;; values.  We implement these tricks as define_splits, rather
273;; than putting the code into the define_expand "movsi" above,
274;; because if we put them there, they will be evaluated at RTL
275;; generation time and then the combiner pass will come along
276;; and replace the multiple insns that have been generated with
277;; the original, slower, load insns.  (The combiner pass only
278;; cares about reducing the number of instructions, it does not
279;; care about instruction lengths or speeds).  Splits are
280;; evaluated after the combine pass and before the scheduling
281;; passes, so that they are the perfect place to put this
282;; intelligence.
283;;
284;; XXX we probably ought to implement these for QI and HI mode
285;; loads as well.
286
287;; If we are loading a small negative constant we can save space
288;; and time by loading the positive value and then sign extending it.
289(define_split
290  [(set (match_operand:SI 0 "register_operand"  "")
291	(match_operand:SI 1 "const_int_operand" ""))]
292   "INTVAL (operands[1]) <= -1 && INTVAL (operands[1]) >= -128
293    && (GET_CODE (operands[0]) != SUBREG
294	|| SCALAR_INT_MODE_P (GET_MODE (XEXP (operands[0], 0))))"
295   [(set (match_dup 0) (match_dup 1))
296    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
297   "{
298   operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
299   operands[2] = gen_lowpart (QImode, operands[0]);
300   }"
301)
302
303;; If we are loading a large negative constant, one which does
304;; not have any of its bottom 24 bit set, then we can save time
305;; and space by loading the byte value and shifting it into place.
306(define_split
307  [(set (match_operand:SI 0 "register_operand"  "")
308	(match_operand:SI 1 "const_int_operand" ""))]
309   "(INTVAL (operands[1]) < 0) && ((INTVAL (operands[1]) & 0x00ffffff) == 0)"
310   [(set (match_dup 0) (match_dup 2))
311    (parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 24)))
312	       (clobber (reg:CC 16))])]
313   "{
314   HOST_WIDE_INT val = INTVAL (operands[1]);
315   operands[2] = GEN_INT (val >> 24);
316   }"
317)
318
319;; If we are loading a large positive constant, one which has bits
320;; in the top byte set, but whose set bits all lie within an 8 bit
321;; range, then we can save time and space by loading the byte value
322;; and shifting it into place.
323(define_split
324  [(set (match_operand:SI 0 "register_operand"  "")
325	(match_operand:SI 1 "const_int_operand" ""))]
326   "(INTVAL (operands[1]) > 0x00ffffff)
327   && ((INTVAL (operands[1]) >> exact_log2 (INTVAL (operands[1]) & (- INTVAL (operands[1])))) < 0x100)"
328   [(set (match_dup 0) (match_dup 2))
329    (parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 3)))
330	       (clobber (reg:CC 16))])]
331   "{
332   HOST_WIDE_INT val = INTVAL (operands[1]);
333   int shift = exact_log2 (val & ( - val));
334   operands[2] = GEN_INT (val >> shift);
335   operands[3] = GEN_INT (shift);
336   }"
337)
338
339;; When TARGET_SMALL_MODEL is defined we assume that all symbolic
340;; values are addresses which will fit in 20 bits.
341
342(define_insn "movsi_internal"
343  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,red,V,r,m")
344	(match_operand:SI 1 "general_operand"       "L,M,n,i,rde,r,rm,r"))]
345  ""
346  "*
347  {
348    switch (which_alternative)
349    {
350    case 0: return   \"ldi:8 \\t#%1, %0\";
351    case 1: return   \"ldi:20\\t#%1, %0\";
352    case 2: return   \"ldi:32\\t#%1, %0\";
353    case 3: if (TARGET_SMALL_MODEL)
354	      return \"ldi:20\\t%1, %0\";
355            else
356	      return \"ldi:32\\t%1, %0\";
357    case 4: return   \"mov   \\t%1, %0\";
358    case 5: return   \"st    \\t%1, %0\";
359    case 6: return   \"ld    \\t%1, %0\";
360    case 7: return   \"st    \\t%1, %0\";
361    default: gcc_unreachable ();
362   }
363  }"
364  [(set (attr "length") (cond [(eq_attr "alternative" "1") (const_int 4)
365			       (eq_attr "alternative" "2") (const_int 6)
366			       (eq_attr "alternative" "3")
367			                (if_then_else (eq_attr "size" "small")
368						      (const_int 4)
369						      (const_int 6))]
370			      (const_int 2)))]
371)
372
373;;}}}
374;;{{{ 8 Byte Moves
375
376;; Note - the FR30 does not have an 8 byte load/store instruction
377;; but we have to support this pattern because some other patterns
378;; (e.g. muldisi2) can produce a DImode result.
379;; (This code is stolen from the M32R port.)
380
381(define_expand "movdi"
382  [(set (match_operand:DI 0 "nonimmediate_operand" "")
383        (match_operand:DI 1 "general_operand" ""))]
384  ""
385  "
386  /* Everything except mem = const or mem = mem can be done easily.  */
387
388  if (GET_CODE (operands[0]) == MEM)
389    operands[1] = force_reg (DImode, operands[1]);
390  "
391)
392
393;; We use an insn and a split so that we can generate
394;; RTL rather than text from fr30_move_double().
395
396(define_insn "*movdi_insn"
397  [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,m,r")
398        (match_operand:DI 1 "di_operand"               "r,m,r,nF"))]
399  "register_operand (operands[0], DImode) || register_operand (operands[1], DImode)"
400  "#"
401  [(set_attr "length" "4,8,12,12")]
402)
403
404(define_split
405  [(set (match_operand:DI 0 "nonimmediate_di_operand" "")
406        (match_operand:DI 1 "di_operand" ""))]
407  "reload_completed"
408  [(match_dup 2)]
409  "operands[2] = fr30_move_double (operands);"
410)
411
412;;}}}
413;;{{{ Load & Store Multiple Registers
414
415;; The load multiple and store multiple patterns are implemented
416;; as peepholes because the only time they are expected to occur
417;; is during function prologues and epilogues.
418
419(define_peephole
420  [(set (mem:SI (pre_dec:SI (reg:SI 15)))
421	(match_operand:SI 0 "high_register_operand" "h"))
422   (set (mem:SI (pre_dec:SI (reg:SI 15)))
423	(match_operand:SI 1 "high_register_operand" "h"))
424   (set (mem:SI (pre_dec:SI (reg:SI 15)))
425	(match_operand:SI 2 "high_register_operand" "h"))
426   (set (mem:SI (pre_dec:SI (reg:SI 15)))
427	(match_operand:SI 3 "high_register_operand" "h"))]
428  "fr30_check_multiple_regs (operands, 4, 1)"
429  "stm1	(%0, %1, %2, %3)"
430  [(set_attr "delay_type" "other")]
431)
432
433(define_peephole
434  [(set (mem:SI (pre_dec:SI (reg:SI 15)))
435	(match_operand:SI 0 "high_register_operand" "h"))
436   (set (mem:SI (pre_dec:SI (reg:SI 15)))
437	(match_operand:SI 1 "high_register_operand" "h"))
438   (set (mem:SI (pre_dec:SI (reg:SI 15)))
439	(match_operand:SI 2 "high_register_operand" "h"))]
440  "fr30_check_multiple_regs (operands, 3, 1)"
441  "stm1	(%0, %1, %2)"
442  [(set_attr "delay_type" "other")]
443)
444
445(define_peephole
446  [(set (mem:SI (pre_dec:SI (reg:SI 15)))
447	(match_operand:SI 0 "high_register_operand" "h"))
448   (set (mem:SI (pre_dec:SI (reg:SI 15)))
449	(match_operand:SI 1 "high_register_operand" "h"))]
450  "fr30_check_multiple_regs (operands, 2, 1)"
451  "stm1	(%0, %1)"
452  [(set_attr "delay_type" "other")]
453)
454
455(define_peephole
456  [(set (match_operand:SI 0 "high_register_operand" "h")
457	(mem:SI (post_inc:SI (reg:SI 15))))
458   (set (match_operand:SI 1 "high_register_operand" "h")
459	(mem:SI (post_inc:SI (reg:SI 15))))
460   (set (match_operand:SI 2 "high_register_operand" "h")
461	(mem:SI (post_inc:SI (reg:SI 15))))
462   (set (match_operand:SI 3 "high_register_operand" "h")
463	(mem:SI (post_inc:SI (reg:SI 15))))]
464  "fr30_check_multiple_regs (operands, 4, 0)"
465  "ldm1	(%0, %1, %2, %3)"
466  [(set_attr "delay_type" "other")]
467)
468
469(define_peephole
470  [(set (match_operand:SI 0 "high_register_operand" "h")
471	(mem:SI (post_inc:SI (reg:SI 15))))
472   (set (match_operand:SI 1 "high_register_operand" "h")
473	(mem:SI (post_inc:SI (reg:SI 15))))
474   (set (match_operand:SI 2 "high_register_operand" "h")
475	(mem:SI (post_inc:SI (reg:SI 15))))]
476  "fr30_check_multiple_regs (operands, 3, 0)"
477  "ldm1	(%0, %1, %2)"
478  [(set_attr "delay_type" "other")]
479)
480
481(define_peephole
482  [(set (match_operand:SI 0 "high_register_operand" "h")
483	(mem:SI (post_inc:SI (reg:SI 15))))
484   (set (match_operand:SI 1 "high_register_operand" "h")
485	(mem:SI (post_inc:SI (reg:SI 15))))]
486  "fr30_check_multiple_regs (operands, 2, 0)"
487  "ldm1	(%0, %1)"
488  [(set_attr "delay_type" "other")]
489)
490
491(define_peephole
492  [(set (mem:SI (pre_dec:SI (reg:SI 15)))
493	(match_operand:SI 0 "low_register_operand" "l"))
494   (set (mem:SI (pre_dec:SI (reg:SI 15)))
495	(match_operand:SI 1 "low_register_operand" "l"))
496   (set (mem:SI (pre_dec:SI (reg:SI 15)))
497	(match_operand:SI 2 "low_register_operand" "l"))
498   (set (mem:SI (pre_dec:SI (reg:SI 15)))
499	(match_operand:SI 3 "low_register_operand" "l"))]
500  "fr30_check_multiple_regs (operands, 4, 1)"
501  "stm0	(%0, %1, %2, %3)"
502  [(set_attr "delay_type" "other")]
503)
504
505(define_peephole
506  [(set (mem:SI (pre_dec:SI (reg:SI 15)))
507	(match_operand:SI 0 "low_register_operand" "l"))
508   (set (mem:SI (pre_dec:SI (reg:SI 15)))
509	(match_operand:SI 1 "low_register_operand" "l"))
510   (set (mem:SI (pre_dec:SI (reg:SI 15)))
511	(match_operand:SI 2 "low_register_operand" "l"))]
512  "fr30_check_multiple_regs (operands, 3, 1)"
513  "stm0	(%0, %1, %2)"
514  [(set_attr "delay_type" "other")]
515)
516
517(define_peephole
518  [(set (mem:SI (pre_dec:SI (reg:SI 15)))
519	(match_operand:SI 0 "low_register_operand" "l"))
520   (set (mem:SI (pre_dec:SI (reg:SI 15)))
521	(match_operand:SI 1 "low_register_operand" "l"))]
522  "fr30_check_multiple_regs (operands, 2, 1)"
523  "stm0	(%0, %1)"
524  [(set_attr "delay_type" "other")]
525)
526
527;;}}}
528;;{{{ Floating Point Moves
529
530;; Note - Patterns for SF mode moves are compulsory, but
531;; patterns for DF are optional, as GCC can synthesize them.
532
533(define_expand "movsf"
534  [(set (match_operand:SF 0 "general_operand" "")
535	(match_operand:SF 1 "general_operand" ""))]
536  ""
537  "{
538  if (!reload_in_progress && !reload_completed
539      && memory_operand (operands[0], SFmode)
540      && memory_operand (operands[1], SFmode))
541    operands[1] = copy_to_mode_reg (SFmode, operands[1]);
542  }"
543)
544
545(define_insn "*movsf_internal"
546  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,red,m,r")
547	(match_operand:SF 1 "general_operand"      "Fn,i,rde,r,rm"))]
548  ""
549  "*
550  {
551    switch (which_alternative)
552    {
553    case 0: return   \"ldi:32\\t%1, %0\";
554    case 1: if (TARGET_SMALL_MODEL)
555	      return \"ldi:20\\t%1, %0\";
556            else
557	      return \"ldi:32\\t%1, %0\";
558    case 2: return   \"mov   \\t%1, %0\";
559    case 3: return   \"st    \\t%1, %0\";
560    case 4: return   \"ld    \\t%1, %0\";
561    default: gcc_unreachable ();
562    }
563  }"
564  [(set (attr "length") (cond [(eq_attr "alternative" "0") (const_int 6)
565			       (eq_attr "alternative" "1")
566			                (if_then_else (eq_attr "size" "small")
567						      (const_int 4)
568						      (const_int 6))]
569			      (const_int 2)))]
570)
571
572(define_insn "*movsf_constant_store"
573  [(set (match_operand:SF 0 "memory_operand"    "=m")
574	(match_operand:SF 1 "immediate_operand" "F"))]
575  ""
576  "*
577  {
578  const char *    ldi_instr;
579  const char *    tmp_reg;
580  static char     buffer[100];
581
582  ldi_instr = fr30_const_double_is_zero (operands[1]) ? \"ldi:8\" : \"ldi:32\";
583
584  tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
585
586  sprintf (buffer, \"%s\\t#%%1, %s\\t;\\n\\tst\\t%s, %%0\\t; Created by movsf_constant_store\",
587    ldi_instr, tmp_reg, tmp_reg);
588
589  return buffer;
590  }"
591  [(set_attr "length" "8")]
592)
593
594;;}}}
595
596;;}}}
597;;{{{ Conversions
598
599;; Signed conversions from a smaller integer to a larger integer
600
601(define_insn "extendqisi2"
602  [(set (match_operand:SI 0 "register_operand"                "=r")
603	(sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
604  ""
605  "extsb	%0"
606)
607
608(define_insn "extendhisi2"
609  [(set (match_operand:SI 0 "register_operand"                "=r")
610	(sign_extend:SI (match_operand:HI 1 "register_operand" "0")))]
611  ""
612  "extsh	%0"
613)
614
615;; Unsigned conversions from a smaller integer to a larger integer
616
617(define_insn "zero_extendqisi2"
618  [(set (match_operand:SI 0 "register_operand"                "=r")
619	(zero_extend:SI (match_operand:QI 1 "register_operand" "0")))]
620  ""
621  "extub	%0"
622)
623
624(define_insn "zero_extendhisi2"
625  [(set (match_operand:SI 0 "register_operand"                "=r")
626	(zero_extend:SI (match_operand:HI 1 "register_operand" "0")))]
627  ""
628  "extuh	%0"
629)
630
631;;}}}
632;;{{{ Arithmetic
633
634;;{{{ Addition
635
636;; This is a special pattern just for adjusting the stack size.
637(define_insn "add_to_stack"
638  [(set (reg:SI 15)
639	(plus:SI (reg:SI 15)
640		 (match_operand:SI 0 "stack_add_operand" "i")))]
641  ""
642  "addsp	%0"
643)
644
645;; We need some trickery to be able to handle the addition of
646;; large (i.e. outside +/- 16) constants.  We need to be able to
647;; handle this because reload assumes that it can generate add
648;; instructions with arbitrary sized constants.
649(define_expand "addsi3"
650  [(set (match_operand:SI 0 "register_operand"           "")
651	(plus:SI (match_operand:SI 1 "register_operand"  "")
652		 (match_operand:SI 2 "nonmemory_operand" "")))]
653  ""
654  "{
655  if (   GET_CODE (operands[2]) == REG
656      || GET_CODE (operands[2]) == SUBREG)
657    emit_insn (gen_addsi_regs (operands[0], operands[1], operands[2]));
658  else if (GET_CODE (operands[2]) != CONST_INT)
659    emit_insn (gen_addsi_big_int (operands[0], operands[1], operands[2]));
660  else if (INTVAL (operands[2]) >= -16
661	   && INTVAL (operands[2]) <= 15
662	   && (!REG_P (operands[1])
663	       || !REGNO_PTR_FRAME_P (REGNO (operands[1]))
664	       || REGNO (operands[1]) == STACK_POINTER_REGNUM))
665    emit_insn (gen_addsi_small_int (operands[0], operands[1], operands[2]));
666  else
667    emit_insn (gen_addsi_big_int (operands[0], operands[1], operands[2]));
668  DONE;
669  }"
670)
671
672(define_insn "addsi_regs"
673  [(set (match_operand:SI 0 "register_operand"          "=r")
674	(plus:SI (match_operand:SI 1 "register_operand" "%0")
675		 (match_operand:SI 2 "register_operand"  "r")))]
676  ""
677  "addn	%2, %0"
678)
679
680;; Do not allow an eliminable register in the source register.  It
681;; might be eliminated in favor of the stack pointer, probably
682;; increasing the offset, and so rendering the instruction illegal.
683(define_insn "addsi_small_int"
684  [(set (match_operand:SI 0 "register_operand"              "=r,r")
685	(plus:SI (match_operand:SI 1 "register_operand"      "0,0")
686		 (match_operand:SI 2 "add_immediate_operand" "I,J")))]
687  "!REG_P (operands[1])
688   || !REGNO_PTR_FRAME_P (REGNO (operands[1]))
689   || REGNO (operands[1]) == STACK_POINTER_REGNUM"
690  "@
691   addn	%2, %0
692   addn2	%2, %0"
693)
694
695(define_expand "addsi_big_int"
696  [(set (match_operand:SI 0 "register_operand"           "")
697	(plus:SI (match_operand:SI 1 "register_operand"  "")
698		 (match_operand:SI 2 "immediate_operand" "")))]
699  ""
700  "{
701  /* Cope with the possibility that ops 0 and 1 are the same register.  */
702  if (rtx_equal_p (operands[0], operands[1]))
703    {
704      if (reload_in_progress || reload_completed)
705        {
706	  rtx reg = gen_rtx_REG (SImode, 0/*COMPILER_SCRATCH_REGISTER*/);
707
708	  emit_insn (gen_movsi (reg, operands[2]));
709	  emit_insn (gen_addsi_regs (operands[0], operands[0], reg));
710	}
711      else
712	{
713	  operands[2] = force_reg (SImode, operands[2]);
714	  emit_insn (gen_addsi_regs (operands[0], operands[0], operands[2]));
715	}
716    }
717  else
718    {
719      emit_insn (gen_movsi (operands[0], operands[2]));
720      emit_insn (gen_addsi_regs (operands[0], operands[0], operands[1]));
721    }
722  DONE;
723  }"
724)
725
726(define_insn "*addsi_for_reload"
727  [(set (match_operand:SI 0 "register_operand"         "=&r,r,r")
728	(plus:SI (match_operand:SI 1 "register_operand"  "r,r,r")
729		 (match_operand:SI 2 "immediate_operand" "L,M,n")))]
730  "reload_in_progress || reload_completed"
731  "@
732  ldi:8\\t#%2, %0  \\n\\taddn\\t%1, %0
733  ldi:20\\t#%2, %0 \\n\\taddn\\t%1, %0
734  ldi:32\\t#%2, %0 \\n\\taddn\\t%1, %0"
735  [(set_attr "length" "4,6,8")]
736)
737
738;;}}}
739;;{{{ Subtraction
740
741(define_insn "subsi3"
742  [(set (match_operand:SI 0 "register_operand"       "=r")
743	(minus:SI (match_operand:SI 1 "register_operand" "0")
744	          (match_operand:SI 2 "register_operand" "r")))]
745  ""
746  "subn	%2, %0"
747)
748
749;;}}}
750;;{{{ Multiplication
751
752;; Signed multiplication producing 64-bit results from 32-bit inputs
753(define_insn "mulsidi3"
754  [(set (match_operand:DI 0 "register_operand"                             "=r")
755	   (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
756		    (sign_extend:DI (match_operand:SI 2 "register_operand"  "r"))))
757   (clobber (reg:CC 16))]
758  ""
759  "mul	%2, %1\\n\\tmov\\tmdh, %0\\n\\tmov\\tmdl, %p0"
760  [(set_attr "length" "6")]
761)
762
763;; Unsigned multiplication producing 64-bit results from 32-bit inputs
764(define_insn "umulsidi3"
765  [(set (match_operand:DI 0 "register_operand"                             "=r")
766	   (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
767		    (zero_extend:DI (match_operand:SI 2 "register_operand"  "r"))))
768   (clobber (reg:CC 16))]
769  ""
770  "mulu	%2, %1\\n\\tmov\\tmdh, %0\\n\\tmov\\tmdl, %p0"
771  [(set_attr "length" "6")]
772)
773
774;; Signed multiplication producing 32-bit result from 16-bit inputs
775(define_insn "mulhisi3"
776  [(set (match_operand:SI 0 "register_operand"                             "=r")
777	   (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r"))
778		    (sign_extend:SI (match_operand:HI 2 "register_operand"  "r"))))
779   (clobber (reg:CC 16))]
780  ""
781  "mulh	%2, %1\\n\\tmov\\tmdl, %0"
782  [(set_attr "length" "4")]
783)
784
785;; Unsigned multiplication producing 32-bit result from 16-bit inputs
786(define_insn "umulhisi3"
787  [(set (match_operand:SI 0 "register_operand"                             "=r")
788	   (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%r"))
789		    (zero_extend:SI (match_operand:HI 2 "register_operand"  "r"))))
790   (clobber (reg:CC 16))]
791  ""
792  "muluh	%2, %1\\n\\tmov\\tmdl, %0"
793  [(set_attr "length" "4")]
794)
795
796;; Signed multiplication producing 32-bit result from 32-bit inputs
797(define_insn "mulsi3"
798  [(set (match_operand:SI 0 "register_operand"             "=r")
799	   (mult:SI (match_operand:SI 1 "register_operand" "%r")
800		    (match_operand:SI 2 "register_operand"  "r")))
801   (clobber (reg:CC 16))]
802  ""
803  "mul	%2, %1\\n\\tmov\\tmdl, %0"
804  [(set_attr "length" "4")]
805)
806
807;;}}}
808;;}}}
809;;{{{ Shifts
810
811;; Arithmetic Shift Left
812(define_insn "ashlsi3"
813  [(set (match_operand:SI 0 "register_operand"            "=r,r,r")
814	(ashift:SI (match_operand:SI 1 "register_operand"  "0,0,0")
815		   (match_operand:SI 2 "nonmemory_operand" "r,I,K")))
816   (clobber (reg:CC 16))]
817  ""
818  "@
819  lsl	%2, %0
820  lsl	%2, %0
821  lsl2	%x2, %0"
822)
823
824;; Arithmetic Shift Right
825(define_insn "ashrsi3"
826  [(set (match_operand:SI 0 "register_operand"              "=r,r,r")
827	(ashiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,0")
828		     (match_operand:SI 2 "nonmemory_operand" "r,I,K")))
829   (clobber (reg:CC 16))]
830  ""
831  "@
832  asr	%2, %0
833  asr	%2, %0
834  asr2	%x2, %0"
835)
836
837;; Logical Shift Right
838(define_insn "lshrsi3"
839  [(set (match_operand:SI 0 "register_operand"              "=r,r,r")
840	(lshiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,0")
841		     (match_operand:SI 2 "nonmemory_operand" "r,I,K")))
842   (clobber (reg:CC 16))]
843  ""
844  "@
845  lsr	%2, %0
846  lsr	%2, %0
847  lsr2	%x2, %0"
848)
849
850;;}}}
851;;{{{ Logical Operations
852
853;; Logical AND, 32-bit integers
854(define_insn "andsi3"
855  [(set (match_operand:SI 0 "register_operand"         "=r")
856	(and:SI (match_operand:SI 1 "register_operand" "%r")
857		(match_operand:SI 2 "register_operand"  "0")))
858   (clobber (reg:CC 16))]
859  ""
860  "and	%1, %0"
861)
862
863;; Inclusive OR, 32-bit integers
864(define_insn "iorsi3"
865  [(set (match_operand:SI 0 "register_operand"         "=r")
866	(ior:SI (match_operand:SI 1 "register_operand" "%r")
867		(match_operand:SI 2 "register_operand"  "0")))
868   (clobber (reg:CC 16))]
869  ""
870  "or	%1, %0"
871)
872
873;; Exclusive OR, 32-bit integers
874(define_insn "xorsi3"
875  [(set (match_operand:SI 0 "register_operand"         "=r")
876	(xor:SI (match_operand:SI 1 "register_operand" "%r")
877		(match_operand:SI 2 "register_operand"  "0")))
878   (clobber (reg:CC 16))]
879  ""
880  "eor	%1, %0"
881)
882
883;; One's complement, 32-bit integers
884(define_expand "one_cmplsi2"
885  [(set (match_operand:SI 0 "register_operand"         "")
886	(not:SI (match_operand:SI 1 "register_operand" "")))]
887  ""
888  "{
889  if (rtx_equal_p (operands[0], operands[1]))
890    {
891      if (reload_in_progress || reload_completed)
892        {
893	  rtx reg = gen_rtx_REG (SImode, 0/*COMPILER_SCRATCH_REGISTER*/);
894
895	  emit_insn (gen_movsi (reg, constm1_rtx));
896	  emit_insn (gen_xorsi3 (operands[0], operands[0], reg));
897	}
898      else
899	{
900	  rtx reg = gen_reg_rtx (SImode);
901
902	  emit_insn (gen_movsi (reg, constm1_rtx));
903	  emit_insn (gen_xorsi3 (operands[0], operands[0], reg));
904	}
905    }
906  else
907    {
908      emit_insn (gen_movsi_internal (operands[0], constm1_rtx));
909      emit_insn (gen_xorsi3 (operands[0], operands[1], operands[0]));
910    }
911  DONE;
912  }"
913)
914
915;;}}}
916;;{{{ Comparisons
917
918;; The actual comparisons, generated by the cbranch and/or cstore expanders
919
920(define_insn "*cmpsi_internal"
921  [(set (reg:CC 16)
922	(compare:CC (match_operand:SI 0 "register_operand"  "r,r,r")
923		    (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
924  ""
925  "@
926  cmp	%1, %0
927  cmp	%1, %0
928  cmp2	%1, %0"
929)
930
931;;}}}
932;;{{{ Branches
933
934;; Define_expands called by the machine independent part of the compiler
935;; to allocate a new comparison register
936
937(define_expand "cbranchsi4"
938  [(set (reg:CC 16)
939	(compare:CC (match_operand:SI 1 "register_operand"  "")
940		    (match_operand:SI 2 "nonmemory_operand" "")))
941   (set (pc)
942	(if_then_else (match_operator 0 "ordered_comparison_operator"
943		       [(reg:CC 16) (const_int 0)])
944		      (label_ref (match_operand 3 "" ""))
945		      (pc)))]
946  ""
947  ""
948)
949
950
951;; Actual branches.  We must allow for the (label_ref) and the (pc) to be
952;; swapped.  If they are swapped, it reverses the sense of the branch.
953
954;; This pattern matches the (branch-if-true) branches generated above.
955;; It generates two different instruction sequences depending upon how
956;; far away the destination is.
957
958;; The calculation for the instruction length is derived as follows:
959;; The branch instruction has a 9-bit signed displacement so we have
960;; this inequality for the displacement:
961;;
962;;               -256 <= pc < 256
963;; or
964;;	   -256 + 256 <= pc + 256 < 256 + 256
965;; i.e.
966;;		    0 <= pc + 256 < 512
967;;
968;; if we consider the displacement as an unsigned value, then negative
969;; displacements become very large positive displacements, and the
970;; inequality becomes:
971;;
972;;		pc + 256 < 512
973;;
974;; In order to allow for the fact that the real branch instruction works
975;; from pc + 2, we increase the offset to 258.
976;;
977;; Note - we do not have to worry about whether the branch is delayed or
978;; not, as branch shortening happens after delay slot reorganization.
979
980(define_insn "*branch_true"
981  [(set (pc)
982	(if_then_else (match_operator 0 "comparison_operator"
983				      [(reg:CC 16)
984				       (const_int 0)])
985		      (label_ref (match_operand 1 "" ""))
986		      (pc)))]
987  ""
988  "*
989  {
990    if (get_attr_length (insn) == 2)
991      return \"b%b0%#\\t%l1\";
992    else
993      {
994        static char   buffer [100];
995	const char *  tmp_reg;
996	const char *  ldi_insn;
997
998        tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
999
1000	ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";
1001
1002	/* The code produced here is, for say the EQ case:
1003
1004	       Bne  1f
1005	       LDI  <label>, r0
1006	       JMP  r0
1007	     1:                                         */
1008
1009	sprintf (buffer,
1010	  \"b%%B0\\t1f\\t;\\n\\t%s\\t%%l1, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\\n1:\",
1011	  ldi_insn, tmp_reg, tmp_reg);
1012
1013        return buffer;
1014    }
1015  }"
1016  [(set (attr "length") (if_then_else
1017			  (ltu
1018			    (plus
1019			      (minus
1020			        (match_dup 1)
1021				(pc))
1022			      (const_int 254))
1023			    (const_int 506))
1024			  (const_int 2)
1025			  (if_then_else (eq_attr "size" "small")
1026					(const_int 8)
1027					(const_int 10))))
1028   (set_attr "delay_type" "delayed")]
1029)
1030
1031
1032;; This pattern is a duplicate of the previous one, except that the
1033;; branch occurs if the test is false, so the %B operator is used.
1034(define_insn "*branch_false"
1035  [(set (pc)
1036	(if_then_else (match_operator 0 "comparison_operator"
1037				      [(reg:CC 16)
1038				       (const_int 0)])
1039		      (pc)
1040		      (label_ref (match_operand 1 "" ""))))]
1041  ""
1042  "*
1043  {
1044    if (get_attr_length (insn) == 2)
1045      return \"b%B0%#\\t%l1 \";
1046    else
1047      {
1048        static char   buffer [100];
1049	const char *  tmp_reg;
1050	const char *  ldi_insn;
1051
1052        tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
1053
1054	ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";
1055
1056	sprintf (buffer,
1057	  \"b%%b0\\t1f\\t;\\n\\t%s\\t%%l1, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\\n1:\",
1058	  ldi_insn, tmp_reg, tmp_reg);
1059
1060        return buffer;
1061      }
1062  }"
1063  [(set (attr "length") (if_then_else (ltu (plus (minus (match_dup 1) (pc))
1064						 (const_int 254))
1065					   (const_int 506))
1066				      (const_int 2)
1067				      (if_then_else (eq_attr "size" "small")
1068						    (const_int 8)
1069						    (const_int 10))))
1070   (set_attr "delay_type" "delayed")]
1071)
1072
1073;;}}}
1074;;{{{ Calls & Jumps
1075
1076;; Subroutine call instruction returning no value.  Operand 0 is the function
1077;; to call; operand 1 is the number of bytes of arguments pushed (in mode
1078;; `SImode', except it is normally a `const_int'); operand 2 is the number of
1079;; registers used as operands.
1080
1081(define_insn "call"
1082  [(call (match_operand 0 "call_operand" "Qm")
1083	 (match_operand 1 ""             "g"))
1084   (clobber (reg:SI 17))]
1085  ""
1086  "call%#\\t%0"
1087  [(set_attr "delay_type" "delayed")]
1088)
1089
1090;; Subroutine call instruction returning a value.  Operand 0 is the hard
1091;; register in which the value is returned.  There are three more operands, the
1092;; same as the three operands of the `call' instruction (but with numbers
1093;; increased by one).
1094
1095;; Subroutines that return `BLKmode' objects use the `call' insn.
1096
1097(define_insn "call_value"
1098  [(set (match_operand 0 "register_operand"  "=r")
1099	(call (match_operand 1 "call_operand" "Qm")
1100	      (match_operand 2 ""             "g")))
1101   (clobber (reg:SI 17))]
1102  ""
1103  "call%#\\t%1"
1104  [(set_attr "delay_type" "delayed")]
1105)
1106
1107;; Normal unconditional jump.
1108;; For a description of the computation of the length
1109;; attribute see the branch patterns above.
1110;;
1111;; Although this instruction really clobbers r0, flow
1112;; relies on jump being simplejump_p in several places
1113;; and as r0 is fixed, this doesn't change anything
1114(define_insn "jump"
1115  [(set (pc) (label_ref (match_operand 0 "" "")))]
1116  ""
1117  "*
1118  {
1119    if (get_attr_length (insn) == 2)
1120       return \"bra%#\\t%0\";
1121    else
1122      {
1123        static char   buffer [100];
1124	const char *  tmp_reg;
1125	const char *  ldi_insn;
1126
1127        tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
1128
1129	ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";
1130
1131	sprintf (buffer, \"%s\\t%%0, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\",
1132	  ldi_insn, tmp_reg, tmp_reg);
1133
1134        return buffer;
1135      }
1136  }"
1137  [(set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1138						(const_int 254))
1139					  (const_int 506))
1140				     (const_int 2)
1141				     (if_then_else (eq_attr "size" "small")
1142						   (const_int 6)
1143						   (const_int 8))))
1144   (set_attr "delay_type" "delayed")]
1145)
1146
1147;; Indirect jump through a register
1148(define_insn "indirect_jump"
1149  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "r"))]
1150  "GET_CODE (operands[0]) != MEM || GET_CODE (XEXP (operands[0], 0)) != PLUS"
1151  "jmp%#\\t@%0"
1152  [(set_attr "delay_type" "delayed")]
1153)
1154
1155(define_insn "tablejump"
1156  [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1157   (use (label_ref (match_operand 1 "" "")))]
1158  ""
1159  "jmp%#\\t@%0"
1160  [(set_attr "delay_type" "delayed")]
1161)
1162
1163;;}}}
1164;;{{{ Function Prologues and Epilogues
1165
1166;; Called after register allocation to add any instructions needed for the
1167;; prologue.  Using a prologue insn is favored compared to putting all of the
1168;; instructions in output_function_prologue(), since it allows the scheduler
1169;; to intermix instructions with the saves of the caller saved registers.  In
1170;; some cases, it might be necessary to emit a barrier instruction as the last
1171;; insn to prevent such scheduling.
1172(define_expand "prologue"
1173  [(clobber (const_int 0))]
1174  ""
1175  "{
1176  fr30_expand_prologue ();
1177  DONE;
1178  }"
1179)
1180
1181;; Called after register allocation to add any instructions needed for the
1182;; epilogue.  Using an epilogue insn is favored compared to putting all of the
1183;; instructions in output_function_epilogue(), since it allows the scheduler
1184;; to intermix instructions with the restores of the caller saved registers.
1185;; In some cases, it might be necessary to emit a barrier instruction as the
1186;; first insn to prevent such scheduling.
1187(define_expand "epilogue"
1188  [(return)]
1189  ""
1190  "{
1191  fr30_expand_epilogue ();
1192  DONE;
1193  }"
1194)
1195
1196(define_insn "return_from_func"
1197  [(return)
1198   (use (reg:SI 17))]
1199  "reload_completed"
1200  "ret%#"
1201  [(set_attr "delay_type" "delayed")]
1202)
1203
1204(define_insn "leave_func"
1205  [(set (reg:SI 15) (plus:SI (reg:SI 14) (const_int 4)))
1206   (set (reg:SI 14) (mem:SI (minus:SI (reg:SI 15) (const_int 4))))]
1207  "reload_completed"
1208  "leave"
1209)
1210
1211(define_expand "enter_func"
1212  [(parallel
1213  [(set (mem:SI (minus:SI (match_dup 1)
1214			  (const_int 4)))
1215	(match_dup 2))
1216   (set (match_dup 2)
1217	(minus:SI (match_dup 1)
1218		  (const_int 4)))
1219   (set (match_dup 1)
1220	(minus:SI (match_dup 1)
1221		  (match_operand:SI 0 "immediate_operand")))]
1222  )]
1223  ""
1224{
1225  operands[1] = stack_pointer_rtx;
1226  operands[2] = hard_frame_pointer_rtx;
1227})
1228
1229(define_insn "*enter_func"
1230  [(set (mem:SI (minus:SI (reg:SI 15)
1231			  (const_int 4)))
1232	(reg:SI 14))
1233   (set (reg:SI 14)
1234	(minus:SI (reg:SI 15)
1235		  (const_int 4)))
1236   (set (reg:SI 15)
1237	(minus:SI (reg:SI 15)
1238		  (match_operand 0 "immediate_operand" "i")))]
1239  "reload_completed"
1240  "enter	#%0"
1241  [(set_attr "delay_type" "other")]
1242)
1243
1244;;}}}
1245;;{{{ Miscellaneous
1246
1247;; No operation, needed in case the user uses -g but not -O.
1248(define_insn "nop"
1249  [(const_int 0)]
1250  ""
1251  "nop"
1252)
1253
1254;; Pseudo instruction that prevents the scheduler from moving code above this
1255;; point.
1256(define_insn "blockage"
1257  [(unspec_volatile [(const_int 0)] 0)]
1258  ""
1259  ""
1260  [(set_attr "length" "0")]
1261)
1262;;}}}
1263
1264;; Local Variables:
1265;; mode: md
1266;; folded-file: t
1267;; End:
1268