* flags.h: New variables align_loops, align_loops_log,
[official-gcc.git] / gcc / config / mips / mips.md
blob7b860edc652671b7c158f6e1793012840916eea7
1 ;;  Mips.md          Machine Description for MIPS based processors
2 ;;  Contributed by   A. Lichnewsky, lich@inria.inria.fr
3 ;;  Changes by       Michael Meissner, meissner@osf.org
4 ;;  64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
5 ;;  Brendan Eich, brendan@microunity.com.
6 ;;  Copyright (C) 1989, 90-98, 1999 Free Software Foundation, Inc.
8 ;; This file is part of GNU CC.
10 ;; GNU CC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
15 ;; GNU CC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU CC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
25 ;; ??? Currently does not have define_function_unit support for the R8000.
26 ;; Must include new entries for fmadd in addition to existing entries.
30 ;; ....................
32 ;;      Attributes
34 ;; ....................
36 ;; Classification of each insn.
37 ;; branch       conditional branch
38 ;; jump         unconditional jump
39 ;; call         unconditional call
40 ;; load         load instruction(s)
41 ;; store        store instruction(s)
42 ;; move         data movement within same register set
43 ;; xfer         transfer to/from coprocessor
44 ;; hilo         transfer of hi/lo registers
45 ;; arith        integer arithmetic instruction
46 ;; darith       double precision integer arithmetic instructions
47 ;; imul         integer multiply
48 ;; idiv         integer divide
49 ;; icmp         integer compare
50 ;; fadd         floating point add/subtract
51 ;; fmul         floating point multiply
52 ;; fmadd        floating point multiply-add
53 ;; fdiv         floating point divide
54 ;; fabs         floating point absolute value
55 ;; fneg         floating point negation
56 ;; fcmp         floating point compare
57 ;; fcvt         floating point convert
58 ;; fsqrt        floating point square root
59 ;; multi        multiword sequence (or user asm statements)
60 ;; nop          no operation
62 (define_attr "type"
63   "unknown,branch,jump,call,load,store,move,xfer,hilo,arith,darith,imul,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,multi,nop"
64   (const_string "unknown"))
66 ;; Main data type used by the insn
67 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown"))
69 ;; Length (in # of bytes).  A conditional branch is allowed only to a
70 ;; location within a signed 18-bit offset of the delay slot.  If that
71 ;; provides too smal a range, we use the `j' instruction.  This
72 ;; instruction takes a 28-bit value, but that value is not an offset.
73 ;; Instead, it's bitwise-ored with the high-order four bits of the
74 ;; instruction in the delay slot, which means it cannot be used to
75 ;; cross a 256MB boundary.  We could fall back back on the jr,
76 ;; instruction which allows full access to the entire address space,
77 ;; but we do not do so at present.
79 (define_attr "length" "" 
80    (cond [(eq_attr "type" "branch")
81           (cond [(lt (abs (minus (match_dup 1) (plus (pc) (const_int 4))))
82                      (const_int 131072))
83                  (const_int 4)]
84                  (const_int 12))]
85           (const_int 4)))
87 ;; Attribute describing the processor.  This attribute must match exactly
88 ;; with the processor_type enumeration in mips.h.
90 ;; Attribute describing the processor
91 ;; (define_attr "cpu" "default,r3000,r6000,r4000"
92 ;;   (const
93 ;;    (cond [(eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R3000"))   (const_string "r3000")
94 ;;           (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R4000"))   (const_string "r4000")
95 ;;           (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R6000"))   (const_string "r6000")]
96 ;;          (const_string "default"))))
98 ;; ??? Fix everything that tests this attribute.
99 (define_attr "cpu"
100   "default,r3000,r3900,r6000,r4000,r4100,r4300,r4600,r4650,r5000,r8000"
101   (const (symbol_ref "mips_cpu_attr")))
103 ;; Does the instruction have a mandatory delay slot?
104 ;;   The 3900, is (mostly) mips1, but does not have a mandatory load delay
105 ;;   slot. 
106 (define_attr "dslot" "no,yes"
107   (if_then_else (ior (eq_attr "type" "branch,jump,call,xfer,hilo,fcmp")
108                      (and (eq_attr "type" "load")
109                           (and (eq (symbol_ref "mips_isa") (const_int 1))
110                                (and (eq (symbol_ref "mips16") (const_int 0))
111                                     (eq_attr "cpu" "!r3900")))))
112                 (const_string "yes")
113                 (const_string "no")))
115 ;; Attribute defining whether or not we can use the branch-likely instructions
117 (define_attr "branch_likely" "no,yes"
118   (const
119    (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
120                  (const_string "yes")
121                  (const_string "no"))))
124 ;; Describe a user's asm statement.
125 (define_asm_attributes
126   [(set_attr "type" "multi")])
128 ;; whether or not generating calls to position independent functions
129 (define_attr "abicalls" "no,yes"
130   (const (symbol_ref "mips_abicalls_attr")))
134 ;; .........................
136 ;;      Delay slots, can't describe load/fcmp/xfer delay slots here
138 ;; .........................
140 (define_delay (and (eq_attr "type" "branch")
141                    (eq (symbol_ref "mips16") (const_int 0)))
142   [(and (eq_attr "dslot" "no") (eq_attr "length" "4"))
143    (nil)
144    (and (eq_attr "branch_likely" "yes") (and (eq_attr "dslot" "no") (eq_attr "length" "4")))])
146 (define_delay (eq_attr "type" "jump")
147   [(and (eq_attr "dslot" "no") (eq_attr "length" "4"))
148    (nil)
149    (nil)])
151 (define_delay (and (eq_attr "type" "call") (eq_attr "abicalls" "no"))
152   [(and (eq_attr "dslot" "no") (eq_attr "length" "4"))
153    (nil)
154    (nil)])
158 ;; .........................
160 ;;      Functional units
162 ;; .........................
164 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
165 ;                       TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
167 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
169 (define_function_unit "memory" 1 0
170   (and (eq_attr "type" "load")
171        (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
172   3 0)
174 (define_function_unit "memory" 1 0
175   (and (eq_attr "type" "load")
176        (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
177   2 0)
179 (define_function_unit "memory"   1 0 (eq_attr "type" "store") 1 0)
181 (define_function_unit "memory"   1 0 (eq_attr "type" "xfer") 2 0)
183 (define_function_unit "imuldiv"  1 0
184   (eq_attr "type" "hilo")
185   1 3)
187 (define_function_unit "imuldiv"  1 0
188   (and (eq_attr "type" "imul")
189        (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
190   17 17)
192 ;; On them mips16, we want to stronly discourage a mult from appearing
193 ;; after an mflo, since that requires explicit nop instructions.  We
194 ;; do this by pretending that mflo ties up the function unit for long
195 ;; enough that the scheduler will ignore load stalls and the like when
196 ;; selecting instructions to between the two instructions.
198 (define_function_unit "imuldiv" 1 0
199   (and (eq_attr "type" "hilo") (ne (symbol_ref "mips16") (const_int 0)))
200   1 5)
202 (define_function_unit "imuldiv"  1 0
203   (and (eq_attr "type" "imul") (eq_attr "cpu" "r3000,r3900"))
204   12 12)
206 (define_function_unit "imuldiv"  1 0
207   (and (eq_attr "type" "imul") (eq_attr "cpu" "r4000,r4600"))
208   10 10)
210 (define_function_unit "imuldiv"  1 0
211   (and (eq_attr "type" "imul") (eq_attr "cpu" "r4650"))
212   4 4)
214 (define_function_unit "imuldiv"  1 0
215   (and (eq_attr "type" "imul")
216        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
217   1 1)
219 (define_function_unit "imuldiv"  1 0
220   (and (eq_attr "type" "imul")
221        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
222   4 4)
224 (define_function_unit "imuldiv"  1 0
225   (and (eq_attr "type" "imul")
226        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000")))
227   5 5)
229 (define_function_unit "imuldiv"  1 0
230   (and (eq_attr "type" "imul")
231        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
232   8 8)
234 (define_function_unit "imuldiv"  1 0
235   (and (eq_attr "type" "imul")
236        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
237   9 9)
239 (define_function_unit "imuldiv"  1 0
240   (and (eq_attr "type" "idiv")
241        (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
242   38 38)
244 (define_function_unit "imuldiv"  1 0
245   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000,r3900"))
246   35 35)
248 (define_function_unit "imuldiv"  1 0
249   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
250   42 42)
252 (define_function_unit "imuldiv"  1 0
253   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
254   36 36)
256 (define_function_unit "imuldiv"  1 0
257   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
258   69 69)
260 (define_function_unit "imuldiv" 1 0
261   (and (eq_attr "type" "idiv")
262        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
263   35 35)
265 (define_function_unit "imuldiv" 1 0
266   (and (eq_attr "type" "idiv")
267        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
268   67 67)
270 (define_function_unit "imuldiv" 1 0
271   (and (eq_attr "type" "idiv")
272        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
273   37 37)
275 (define_function_unit "imuldiv" 1 0
276   (and (eq_attr "type" "idiv")
277        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
278   69 69)
280 (define_function_unit "imuldiv" 1 0
281   (and (eq_attr "type" "idiv")
282        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000")))
283   36 36)
285 (define_function_unit "imuldiv" 1 0
286   (and (eq_attr "type" "idiv")
287        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
288   68 68)
290 ;; The R4300 does *NOT* have a separate Floating Point Unit, instead
291 ;; the FP hardware is part of the normal ALU circuitry.  This means FP
292 ;; instructions affect the pipe-line, and no functional unit
293 ;; parallelism can occur on R4300 processors.  To force GCC into coding
294 ;; for only a single functional unit, we force the R4300 FP
295 ;; instructions to be processed in the "imuldiv" unit.
297 (define_function_unit "adder" 1 1
298   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
299   3 0)
301 (define_function_unit "adder" 1 1
302   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r3900,r6000"))
303   2 0)
305 (define_function_unit "adder" 1 1
306   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000"))
307   1 0)
309 (define_function_unit "adder" 1 1
310   (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
311   4 0)
313 (define_function_unit "adder" 1 1
314   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000,r3900"))
315   2 0)
317 (define_function_unit "adder" 1 1
318   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
319   3 0)
321 (define_function_unit "adder" 1 1
322   (and (eq_attr "type" "fabs,fneg")
323        (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000"))
324   2 0)
326 (define_function_unit "adder" 1 1
327   (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r3900,r4600,r4650,r5000"))
328   1 0)
330 (define_function_unit "mult" 1 1
331   (and (eq_attr "type" "fmul")
332        (and (eq_attr "mode" "SF")
333             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
334   7 0)
336 (define_function_unit "mult" 1 1
337   (and (eq_attr "type" "fmul")
338        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900,r5000")))
339   4 0)
341 (define_function_unit "mult" 1 1
342   (and (eq_attr "type" "fmul")
343        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
344   5 0)
346 (define_function_unit "mult" 1 1
347   (and (eq_attr "type" "fmul")
348        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
349   8 0)
351 (define_function_unit "mult" 1 1
352   (and (eq_attr "type" "fmul")
353        (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")))
354   8 0)
356 (define_function_unit "mult" 1 1
357   (and (eq_attr "type" "fmul")
358        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900,r5000")))
359   5 0)
361 (define_function_unit "mult" 1 1
362   (and (eq_attr "type" "fmul")
363        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
364   6 0)
366 (define_function_unit "divide" 1 1
367   (and (eq_attr "type" "fdiv")
368        (and (eq_attr "mode" "SF")
369             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
370   23 0)
372 (define_function_unit "divide" 1 1
373   (and (eq_attr "type" "fdiv")
374        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900")))
375   12 0)
377 (define_function_unit "divide" 1 1
378   (and (eq_attr "type" "fdiv")
379        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
380   15 0)
382 (define_function_unit "divide" 1 1
383   (and (eq_attr "type" "fdiv")
384        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
385   32 0)
387 (define_function_unit "divide" 1 1
388   (and (eq_attr "type" "fdiv")
389        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
390   21 0)
392 (define_function_unit "divide" 1 1
393   (and (eq_attr "type" "fdiv")
394        (and (eq_attr "mode" "DF")
395             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300")))
396   36 0)
398 (define_function_unit "divide" 1 1
399   (and (eq_attr "type" "fdiv")
400        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900")))
401   19 0)
403 (define_function_unit "divide" 1 1
404   (and (eq_attr "type" "fdiv")
405        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
406   16 0)
408 (define_function_unit "divide" 1 1
409   (and (eq_attr "type" "fdiv")
410        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
411   61 0)
413 ;;; ??? Is this number right?
414 (define_function_unit "divide" 1 1
415   (and (eq_attr "type" "fsqrt")
416        (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
417   54 0)
419 (define_function_unit "divide" 1 1
420   (and (eq_attr "type" "fsqrt")
421        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
422   31 0)
424 (define_function_unit "divide" 1 1
425   (and (eq_attr "type" "fsqrt")
426        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
427   21 0)
429 ;;; ??? Is this number right?
430 (define_function_unit "divide" 1 1
431   (and (eq_attr "type" "fsqrt")
432        (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
433   112 0)
435 (define_function_unit "divide" 1 1
436   (and (eq_attr "type" "fsqrt")
437        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
438   60 0)
440 (define_function_unit "divide" 1 1
441   (and (eq_attr "type" "fsqrt")
442        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000")))
443   36 0)
445 ;; R4300 FP instruction classes treated as part of the "imuldiv"
446 ;; functional unit:
448 (define_function_unit "imuldiv" 1 0
449   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
450   3 3)
452 (define_function_unit "imuldiv" 1 0
453   (and (eq_attr "type" "fcmp,fabs,fneg") (eq_attr "cpu" "r4300"))
454   1 1)
456 (define_function_unit "imuldiv" 1 0
457   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
458   5 5)
459 (define_function_unit "imuldiv" 1 0
460   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
461   8 8)
463 (define_function_unit "imuldiv" 1 0
464   (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
465        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
466   29 29)
467 (define_function_unit "imuldiv" 1 0
468   (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
469        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
470   58 58)
472 ;; The following functional units do not use the cpu type, and use
473 ;; much less memory in genattrtab.c.
475 ;; (define_function_unit "memory"   1 0 (eq_attr "type" "load")                                3 0)
476 ;; (define_function_unit "memory"   1 0 (eq_attr "type" "store")                               1 0)
477 ;;       
478 ;; (define_function_unit "fp_comp"  1 0 (eq_attr "type" "fcmp")                                2 0)
479 ;;       
480 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer")                                2 0)
481 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo")                                3 0)
482 ;;   
483 ;; (define_function_unit "imuldiv"  1 1 (eq_attr "type" "imul")                               17 0)
484 ;; (define_function_unit "imuldiv"  1 1 (eq_attr "type" "idiv")                               38 0)
485 ;;   
486 ;; (define_function_unit "adder"    1 1 (eq_attr "type" "fadd")                                4 0)
487 ;; (define_function_unit "adder"    1 1 (eq_attr "type" "fabs,fneg")                           2 0)
488 ;;   
489 ;; (define_function_unit "mult"     1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF"))    7 0)
490 ;; (define_function_unit "mult"     1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF"))    8 0)
491 ;;   
492 ;; (define_function_unit "divide"   1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF"))   23 0)
493 ;; (define_function_unit "divide"   1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF"))   36 0)
494 ;; 
495 ;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF"))  54 0)
496 ;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0)
500 ;;  ....................
502 ;;      ADDITION
504 ;;  ....................
507 (define_insn "adddf3"
508   [(set (match_operand:DF 0 "register_operand" "=f")
509         (plus:DF (match_operand:DF 1 "register_operand" "f")
510                  (match_operand:DF 2 "register_operand" "f")))]
511   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
512   "add.d\\t%0,%1,%2"
513   [(set_attr "type"     "fadd")
514    (set_attr "mode"     "DF")])
516 (define_insn "addsf3"
517   [(set (match_operand:SF 0 "register_operand" "=f")
518         (plus:SF (match_operand:SF 1 "register_operand" "f")
519                  (match_operand:SF 2 "register_operand" "f")))]
520   "TARGET_HARD_FLOAT"
521   "add.s\\t%0,%1,%2"
522   [(set_attr "type"     "fadd")
523    (set_attr "mode"     "SF")])
525 (define_expand "addsi3"
526   [(set (match_operand:SI 0 "register_operand" "=d")
527         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
528                  (match_operand:SI 2 "arith_operand" "dI")))]
529   ""
530   "
532   /* The mips16 assembler handles -32768 correctly, and so does gas,
533      but some other MIPS assemblers think that -32768 needs to be
534      loaded into a register before it can be added in.  */
535   if (! TARGET_MIPS16
536       && ! TARGET_GAS
537       && GET_CODE (operands[2]) == CONST_INT
538       && INTVAL (operands[2]) == -32768)
539     operands[2] = force_reg (SImode, operands[2]);
542 (define_insn "addsi3_internal"
543   [(set (match_operand:SI 0 "register_operand" "=d")
544         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
545                  (match_operand:SI 2 "arith_operand" "dI")))]
546   "! TARGET_MIPS16
547    && (TARGET_GAS
548        || GET_CODE (operands[2]) != CONST_INT
549        || INTVAL (operands[2]) != -32768)"
550   "addu\\t%0,%z1,%2"
551   [(set_attr "type"     "arith")
552    (set_attr "mode"     "SI")])
554 ;; For the mips16, we need to recognize stack pointer additions
555 ;; explicitly, since we don't have a constraint for $sp.  These insns
556 ;; will be generated by the save_restore_insns functions.
558 (define_insn ""
559   [(set (reg:SI 29)
560         (plus:SI (reg:SI 29)
561                  (match_operand:SI 0 "small_int" "I")))]
562   "TARGET_MIPS16"
563   "addu\\t%$,%$,%0"
564   [(set_attr "type"     "arith")
565    (set_attr "mode"     "SI")
566    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
567                                       (const_int 4)
568                                       (const_int 8)))])
570 (define_insn ""
571   [(set (match_operand:SI 0 "register_operand" "=d")
572         (plus:SI (reg:SI 29)
573                  (match_operand:SI 1 "small_int" "I")))]
574   "TARGET_MIPS16"
575   "addu\\t%0,%$,%1"
576   [(set_attr "type"     "arith")
577    (set_attr "mode"     "SI")
578    (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4" "")
579                                       (const_int 4)
580                                       (const_int 8)))])
582 (define_insn ""
583   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
584         (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
585                  (match_operand:SI 2 "arith_operand" "IQ,O,d")))]
586   "TARGET_MIPS16
587    && (GET_CODE (operands[1]) != REG
588        || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
589        || M16_REG_P (REGNO (operands[1]))
590        || REGNO (operands[1]) == ARG_POINTER_REGNUM
591        || REGNO (operands[1]) == FRAME_POINTER_REGNUM
592        || REGNO (operands[1]) == STACK_POINTER_REGNUM)
593    && (GET_CODE (operands[2]) != REG
594        || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
595        || M16_REG_P (REGNO (operands[2]))
596        || REGNO (operands[2]) == ARG_POINTER_REGNUM
597        || REGNO (operands[2]) == FRAME_POINTER_REGNUM
598        || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
599   "*
601   if (REGNO (operands[0]) == REGNO (operands[1]))
602     return \"addu\\t%0,%2\";
603   return \"addu\\t%0,%1,%2\";
605   [(set_attr "type"     "arith")
606    (set_attr "mode"     "SI")
607    (set_attr_alternative "length"
608                 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
609                                (const_int 4)
610                                (const_int 8))
611                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
612                                (const_int 4)
613                                (const_int 8))
614                  (const_int 4)])])
617 ;; On the mips16, we can sometimes split an add of a constant which is
618 ;; a 4 byte instruction into two adds which are both 2 byte
619 ;; instructions.  There are two cases: one where we are adding a
620 ;; constant plus a register to another register, and one where we are
621 ;; simply adding a constant to a register.
623 (define_split
624   [(set (match_operand:SI 0 "register_operand" "")
625         (plus:SI (match_dup 0)
626                  (match_operand:SI 1 "const_int_operand" "")))]
627   "TARGET_MIPS16 && reload_completed
628    && GET_CODE (operands[0]) == REG
629    && M16_REG_P (REGNO (operands[0]))
630    && GET_CODE (operands[1]) == CONST_INT
631    && ((INTVAL (operands[1]) > 0x7f
632         && INTVAL (operands[1]) <= 0x7f + 0x7f)
633        || (INTVAL (operands[1]) < - 0x80
634            && INTVAL (operands[1]) >= - 0x80 - 0x80))"
635   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
636    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
637   "
639   HOST_WIDE_INT val = INTVAL (operands[1]);
641   if (val >= 0)
642     {
643       operands[1] = GEN_INT (0x7f);
644       operands[2] = GEN_INT (val - 0x7f);
645     }
646   else
647     {
648       operands[1] = GEN_INT (- 0x80);
649       operands[2] = GEN_INT (val + 0x80);
650     }
653 (define_split
654   [(set (match_operand:SI 0 "register_operand" "")
655         (plus:SI (match_operand:SI 1 "register_operand" "")
656                  (match_operand:SI 2 "const_int_operand" "")))]
657   "TARGET_MIPS16 && reload_completed
658    && GET_CODE (operands[0]) == REG
659    && M16_REG_P (REGNO (operands[0]))
660    && GET_CODE (operands[1]) == REG
661    && M16_REG_P (REGNO (operands[1]))
662    && REGNO (operands[0]) != REGNO (operands[1])
663    && GET_CODE (operands[2]) == CONST_INT
664    && ((INTVAL (operands[2]) > 0x7
665         && INTVAL (operands[2]) <= 0x7 + 0x7f)
666        || (INTVAL (operands[2]) < - 0x8
667            && INTVAL (operands[2]) >= - 0x8 - 0x80))"
668   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
669    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
670   "
672   HOST_WIDE_INT val = INTVAL (operands[2]);
674   if (val >= 0)
675     {
676       operands[2] = GEN_INT (0x7);
677       operands[3] = GEN_INT (val - 0x7);
678     }
679   else
680     {
681       operands[2] = GEN_INT (- 0x8);
682       operands[3] = GEN_INT (val + 0x8);
683     }
686 (define_expand "adddi3"
687   [(parallel [(set (match_operand:DI 0 "register_operand" "")
688                    (plus:DI (match_operand:DI 1 "se_register_operand" "")
689                             (match_operand:DI 2 "se_arith_operand" "")))
690               (clobber (match_dup 3))])]
691   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
692   "
694   /* The mips16 assembler handles -32768 correctly, and so does gas,
695      but some other MIPS assemblers think that -32768 needs to be
696      loaded into a register before it can be added in.  */
697   if (! TARGET_MIPS16
698       && ! TARGET_GAS
699       && GET_CODE (operands[2]) == CONST_INT
700       && INTVAL (operands[2]) == -32768)
701     operands[2] = force_reg (DImode, operands[2]);
703   if (TARGET_64BIT)
704     {
705       emit_insn (gen_adddi3_internal_3 (operands[0], operands[1],
706                                         operands[2]));
707       DONE;
708     }
710   operands[3] = gen_reg_rtx (SImode);
713 (define_insn "adddi3_internal_1"
714   [(set (match_operand:DI 0 "register_operand" "=d,&d")
715         (plus:DI (match_operand:DI 1 "register_operand" "0,d")
716                  (match_operand:DI 2 "register_operand" "d,d")))
717    (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
718   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
719   "*
721   return (REGNO (operands[0]) == REGNO (operands[1])
722           && REGNO (operands[0]) == REGNO (operands[2]))
723     ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\"
724     : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\";
726   [(set_attr "type"     "darith")
727    (set_attr "mode"     "DI")
728    (set_attr "length"   "16")])
730 (define_split
731   [(set (match_operand:DI 0 "register_operand" "")
732         (plus:DI (match_operand:DI 1 "register_operand" "")
733                  (match_operand:DI 2 "register_operand" "")))
734    (clobber (match_operand:SI 3 "register_operand" ""))]
735   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
736    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
737    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
738    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
739    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
740    && (REGNO (operands[0]) != REGNO (operands[1])
741        || REGNO (operands[0]) != REGNO (operands[2]))"
743   [(set (subreg:SI (match_dup 0) 0)
744         (plus:SI (subreg:SI (match_dup 1) 0)
745                  (subreg:SI (match_dup 2) 0)))
747    (set (match_dup 3)
748         (ltu:SI (subreg:SI (match_dup 0) 0)
749                 (subreg:SI (match_dup 2) 0)))
751    (set (subreg:SI (match_dup 0) 1)
752         (plus:SI (subreg:SI (match_dup 1) 1)
753                  (subreg:SI (match_dup 2) 1)))
755    (set (subreg:SI (match_dup 0) 1)
756         (plus:SI (subreg:SI (match_dup 0) 1)
757                  (match_dup 3)))]
758   "")
760 (define_split
761   [(set (match_operand:DI 0 "register_operand" "")
762         (plus:DI (match_operand:DI 1 "register_operand" "")
763                  (match_operand:DI 2 "register_operand" "")))
764    (clobber (match_operand:SI 3 "register_operand" ""))]
765   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
766    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
767    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
768    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
769    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
770    && (REGNO (operands[0]) != REGNO (operands[1])
771        || REGNO (operands[0]) != REGNO (operands[2]))"
773   [(set (subreg:SI (match_dup 0) 1)
774         (plus:SI (subreg:SI (match_dup 1) 1)
775                  (subreg:SI (match_dup 2) 1)))
777    (set (match_dup 3)
778         (ltu:SI (subreg:SI (match_dup 0) 1)
779                 (subreg:SI (match_dup 2) 1)))
781    (set (subreg:SI (match_dup 0) 0)
782         (plus:SI (subreg:SI (match_dup 1) 0)
783                  (subreg:SI (match_dup 2) 0)))
785    (set (subreg:SI (match_dup 0) 0)
786         (plus:SI (subreg:SI (match_dup 0) 0)
787                  (match_dup 3)))]
788   "")
790 (define_insn "adddi3_internal_2"
791   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
792         (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d")
793                  (match_operand:DI 2 "small_int" "P,J,N")))
794    (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
795   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
796    && (TARGET_GAS
797        || GET_CODE (operands[2]) != CONST_INT
798        || INTVAL (operands[2]) != -32768)"
799   "@
800    addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3
801    move\\t%L0,%L1\;move\\t%M0,%M1
802    subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3"
803   [(set_attr "type"     "darith")
804    (set_attr "mode"     "DI")
805    (set_attr "length"   "12,8,16")])
807 (define_split
808   [(set (match_operand:DI 0 "register_operand" "")
809         (plus:DI (match_operand:DI 1 "register_operand" "")
810                  (match_operand:DI 2 "small_int" "")))
811    (clobber (match_operand:SI 3 "register_operand" "=d"))]
812   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
813    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
814    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
815    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
816    && INTVAL (operands[2]) > 0"
818   [(set (subreg:SI (match_dup 0) 0)
819         (plus:SI (subreg:SI (match_dup 1) 0)
820                  (match_dup 2)))
822    (set (match_dup 3)
823         (ltu:SI (subreg:SI (match_dup 0) 0)
824                 (match_dup 2)))
826    (set (subreg:SI (match_dup 0) 1)
827         (plus:SI (subreg:SI (match_dup 1) 1)
828                  (match_dup 3)))]
829   "")
831 (define_split
832   [(set (match_operand:DI 0 "register_operand" "")
833         (plus:DI (match_operand:DI 1 "register_operand" "")
834                  (match_operand:DI 2 "small_int" "")))
835    (clobber (match_operand:SI 3 "register_operand" "=d"))]
836   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
837    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
838    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
839    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
840    && INTVAL (operands[2]) > 0"
842   [(set (subreg:SI (match_dup 0) 1)
843         (plus:SI (subreg:SI (match_dup 1) 1)
844                  (match_dup 2)))
846    (set (match_dup 3)
847         (ltu:SI (subreg:SI (match_dup 0) 1)
848                 (match_dup 2)))
850    (set (subreg:SI (match_dup 0) 0)
851         (plus:SI (subreg:SI (match_dup 1) 0)
852                  (match_dup 3)))]
853   "")
855 (define_insn "adddi3_internal_3"
856   [(set (match_operand:DI 0 "register_operand" "=d")
857         (plus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
858                  (match_operand:DI 2 "se_arith_operand" "dI")))]
859   "TARGET_64BIT
860    && !TARGET_MIPS16
861    && (TARGET_GAS
862        || GET_CODE (operands[2]) != CONST_INT
863        || INTVAL (operands[2]) != -32768)"
864   "*
866   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
867     ? \"dsubu\\t%0,%z1,%n2\"
868     : \"daddu\\t%0,%z1,%2\";
870   [(set_attr "type"     "darith")
871    (set_attr "mode"     "DI")])
873 ;; For the mips16, we need to recognize stack pointer additions
874 ;; explicitly, since we don't have a constraint for $sp.  These insns
875 ;; will be generated by the save_restore_insns functions.
877 (define_insn ""
878   [(set (reg:DI 29)
879         (plus:DI (reg:DI 29)
880                  (match_operand:DI 0 "small_int" "I")))]
881   "TARGET_MIPS16 && TARGET_64BIT"
882   "daddu\\t%$,%$,%0"
883   [(set_attr "type"     "arith")
884    (set_attr "mode"     "DI")
885    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
886                                       (const_int 4)
887                                       (const_int 8)))])
889 (define_insn ""
890   [(set (match_operand:DI 0 "register_operand" "=d")
891         (plus:DI (reg:DI 29)
892                  (match_operand:DI 1 "small_int" "I")))]
893   "TARGET_MIPS16 && TARGET_64BIT"
894   "daddu\\t%0,%$,%1"
895   [(set_attr "type"     "arith")
896    (set_attr "mode"     "DI")
897    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4" "")
898                                       (const_int 4)
899                                       (const_int 8)))])
901 (define_insn ""
902   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
903         (plus:DI (match_operand:DI 1 "register_operand" "0,d,d")
904                  (match_operand:DI 2 "arith_operand" "IQ,O,d")))]
905   "TARGET_MIPS16 && TARGET_64BIT
906    && (GET_CODE (operands[1]) != REG
907        || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
908        || M16_REG_P (REGNO (operands[1]))
909        || REGNO (operands[1]) == ARG_POINTER_REGNUM
910        || REGNO (operands[1]) == FRAME_POINTER_REGNUM
911        || REGNO (operands[1]) == STACK_POINTER_REGNUM)
912    && (GET_CODE (operands[2]) != REG
913        || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
914        || M16_REG_P (REGNO (operands[2]))
915        || REGNO (operands[2]) == ARG_POINTER_REGNUM
916        || REGNO (operands[2]) == FRAME_POINTER_REGNUM
917        || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
918   "*
920   if (REGNO (operands[0]) == REGNO (operands[1]))
921     return \"daddu\\t%0,%2\";
922   return \"daddu\\t%0,%1,%2\";
924   [(set_attr "type"     "arith")
925    (set_attr "mode"     "DI")
926    (set_attr_alternative "length"
927                 [(if_then_else (match_operand:VOID 2 "m16_simm5_1" "")
928                                (const_int 4)
929                                (const_int 8))
930                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
931                                (const_int 4)
932                                (const_int 8))
933                  (const_int 4)])])
936 ;; On the mips16, we can sometimes split an add of a constant which is
937 ;; a 4 byte instruction into two adds which are both 2 byte
938 ;; instructions.  There are two cases: one where we are adding a
939 ;; constant plus a register to another register, and one where we are
940 ;; simply adding a constant to a register.
942 (define_split
943   [(set (match_operand:DI 0 "register_operand" "")
944         (plus:DI (match_dup 0)
945                  (match_operand:DI 1 "const_int_operand" "")))]
946   "TARGET_MIPS16 && TARGET_64BIT && reload_completed
947    && GET_CODE (operands[0]) == REG
948    && M16_REG_P (REGNO (operands[0]))
949    && GET_CODE (operands[1]) == CONST_INT
950    && ((INTVAL (operands[1]) > 0xf
951         && INTVAL (operands[1]) <= 0xf + 0xf)
952        || (INTVAL (operands[1]) < - 0x10
953            && INTVAL (operands[1]) >= - 0x10 - 0x10))"
954   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
955    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
956   "
958   HOST_WIDE_INT val = INTVAL (operands[1]);
960   if (val >= 0)
961     {
962       operands[1] = GEN_INT (0xf);
963       operands[2] = GEN_INT (val - 0xf);
964     }
965   else
966     {
967       operands[1] = GEN_INT (- 0x10);
968       operands[2] = GEN_INT (val + 0x10);
969     }
972 (define_split
973   [(set (match_operand:DI 0 "register_operand" "")
974         (plus:DI (match_operand:DI 1 "register_operand" "")
975                  (match_operand:DI 2 "const_int_operand" "")))]
976   "TARGET_MIPS16 && TARGET_64BIT && reload_completed
977    && GET_CODE (operands[0]) == REG
978    && M16_REG_P (REGNO (operands[0]))
979    && GET_CODE (operands[1]) == REG
980    && M16_REG_P (REGNO (operands[1]))
981    && REGNO (operands[0]) != REGNO (operands[1])
982    && GET_CODE (operands[2]) == CONST_INT
983    && ((INTVAL (operands[2]) > 0x7
984         && INTVAL (operands[2]) <= 0x7 + 0xf)
985        || (INTVAL (operands[2]) < - 0x8
986            && INTVAL (operands[2]) >= - 0x8 - 0x10))"
987   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
988    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
989   "
991   HOST_WIDE_INT val = INTVAL (operands[2]);
993   if (val >= 0)
994     {
995       operands[2] = GEN_INT (0x7);
996       operands[3] = GEN_INT (val - 0x7);
997     }
998   else
999     {
1000       operands[2] = GEN_INT (- 0x8);
1001       operands[3] = GEN_INT (val + 0x8);
1002     }
1005 (define_insn "addsi3_internal_2"
1006   [(set (match_operand:DI 0 "register_operand" "=d")
1007         (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1008                                  (match_operand:SI 2 "arith_operand" "dI"))))]
1009   "TARGET_64BIT
1010    && !TARGET_MIPS16
1011    && (TARGET_GAS
1012        || GET_CODE (operands[2]) != CONST_INT
1013        || INTVAL (operands[2]) != -32768)"
1014   "*
1016   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1017     ? \"subu\\t%0,%z1,%n2\"
1018     : \"addu\\t%0,%z1,%2\";
1020   [(set_attr "type"     "arith")
1021    (set_attr "mode"     "SI")])
1023 (define_insn ""
1024   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1025         (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1026                                  (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1027   "TARGET_MIPS16 && TARGET_64BIT"
1028   "*
1030   if (REGNO (operands[0]) == REGNO (operands[1]))
1031     return \"addu\\t%0,%2\";
1032   return \"addu\\t%0,%1,%2\";
1034   [(set_attr "type"     "arith")
1035    (set_attr "mode"     "SI")
1036    (set_attr_alternative "length"
1037                 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
1038                                (const_int 4)
1039                                (const_int 8))
1040                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
1041                                (const_int 4)
1042                                (const_int 8))
1043                  (const_int 4)])])
1047 ;;  ....................
1049 ;;      SUBTRACTION
1051 ;;  ....................
1054 (define_insn "subdf3"
1055   [(set (match_operand:DF 0 "register_operand" "=f")
1056         (minus:DF (match_operand:DF 1 "register_operand" "f")
1057                   (match_operand:DF 2 "register_operand" "f")))]
1058   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1059   "sub.d\\t%0,%1,%2"
1060   [(set_attr "type"     "fadd")
1061    (set_attr "mode"     "DF")])
1063 (define_insn "subsf3"
1064   [(set (match_operand:SF 0 "register_operand" "=f")
1065         (minus:SF (match_operand:SF 1 "register_operand" "f")
1066                   (match_operand:SF 2 "register_operand" "f")))]
1067   "TARGET_HARD_FLOAT"
1068   "sub.s\\t%0,%1,%2"
1069   [(set_attr "type"     "fadd")
1070    (set_attr "mode"     "SF")])
1072 (define_expand "subsi3"
1073   [(set (match_operand:SI 0 "register_operand" "=d")
1074         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1075                   (match_operand:SI 2 "arith_operand" "dI")))]
1076   ""
1077   "
1079   if (GET_CODE (operands[2]) == CONST_INT
1080       && (INTVAL (operands[2]) == -32768
1081           || (TARGET_MIPS16
1082               && INTVAL (operands[2]) == -0x4000)))
1083     operands[2] = force_reg (SImode, operands[2]);
1086 (define_insn "subsi3_internal"
1087   [(set (match_operand:SI 0 "register_operand" "=d")
1088         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1089                   (match_operand:SI 2 "arith_operand" "dI")))]
1090   "!TARGET_MIPS16
1091    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1092   "subu\\t%0,%z1,%2"
1093   [(set_attr "type"     "arith")
1094    (set_attr "mode"     "SI")])
1096 ;; For the mips16, we need to recognize stack pointer subtractions
1097 ;; explicitly, since we don't have a constraint for $sp.  These insns
1098 ;; will be generated by the save_restore_insns functions.
1100 (define_insn ""
1101   [(set (reg:SI 29)
1102         (minus:SI (reg:SI 29)
1103                   (match_operand:SI 0 "small_int" "I")))]
1104   "TARGET_MIPS16
1105    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1106   "addu\\t%$,%$,%n0"
1107   [(set_attr "type"     "arith")
1108    (set_attr "mode"     "SI")
1109    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1110                                       (const_int 4)
1111                                       (const_int 8)))])
1113 (define_insn ""
1114   [(set (match_operand:SI 0 "register_operand" "=d")
1115         (minus:SI (reg:SI 29)
1116                   (match_operand:SI 1 "small_int" "I")))]
1117   "TARGET_MIPS16
1118    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1119   "addu\\t%0,%$,%n1"
1120   [(set_attr "type"     "arith")
1121    (set_attr "mode"     "SI")
1122    (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_nuimm8_4" "")
1123                                       (const_int 4)
1124                                       (const_int 8)))])
1127 (define_insn ""
1128   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
1129         (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1130                   (match_operand:SI 2 "arith_operand" "I,O,d")))]
1131   "TARGET_MIPS16
1132    && (GET_CODE (operands[2]) != CONST_INT
1133        || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1134   "*
1136   if (REGNO (operands[0]) == REGNO (operands[1]))
1137     return \"subu\\t%0,%2\";
1138   return \"subu\\t%0,%1,%2\";
1140   [(set_attr "type"     "arith")
1141    (set_attr "mode"     "SI")
1142    (set_attr_alternative "length"
1143                 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1144                                (const_int 4)
1145                                (const_int 8))
1146                  (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1147                                (const_int 4)
1148                                (const_int 8))
1149                  (const_int 4)])])
1151 ;; On the mips16, we can sometimes split an subtract of a constant
1152 ;; which is a 4 byte instruction into two adds which are both 2 byte
1153 ;; instructions.  There are two cases: one where we are setting a
1154 ;; register to a register minus a constant, and one where we are
1155 ;; simply subtracting a constant from a register.
1157 (define_split
1158   [(set (match_operand:SI 0 "register_operand" "")
1159         (minus:SI (match_dup 0)
1160                   (match_operand:SI 1 "const_int_operand" "")))]
1161   "TARGET_MIPS16 && reload_completed
1162    && GET_CODE (operands[0]) == REG
1163    && M16_REG_P (REGNO (operands[0]))
1164    && GET_CODE (operands[1]) == CONST_INT
1165    && ((INTVAL (operands[1]) > 0x80
1166         && INTVAL (operands[1]) <= 0x80 + 0x80)
1167        || (INTVAL (operands[1]) < - 0x7f
1168            && INTVAL (operands[1]) >= - 0x7f - 0x7f))"
1169   [(set (match_dup 0) (minus:SI (match_dup 0) (match_dup 1)))
1170    (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))]
1171   "
1173   HOST_WIDE_INT val = INTVAL (operands[1]);
1175   if (val >= 0)
1176     {
1177       operands[1] = GEN_INT (0x80);
1178       operands[2] = GEN_INT (val - 0x80);
1179     }
1180   else
1181     {
1182       operands[1] = GEN_INT (- 0x7f);
1183       operands[2] = GEN_INT (val + 0x7f);
1184     }
1187 (define_split
1188   [(set (match_operand:SI 0 "register_operand" "")
1189         (minus:SI (match_operand:SI 1 "register_operand" "")
1190                   (match_operand:SI 2 "const_int_operand" "")))]
1191   "TARGET_MIPS16 && reload_completed
1192    && GET_CODE (operands[0]) == REG
1193    && M16_REG_P (REGNO (operands[0]))
1194    && GET_CODE (operands[1]) == REG
1195    && M16_REG_P (REGNO (operands[1]))
1196    && REGNO (operands[0]) != REGNO (operands[1])
1197    && GET_CODE (operands[2]) == CONST_INT
1198    && ((INTVAL (operands[2]) > 0x8
1199         && INTVAL (operands[2]) <= 0x8 + 0x80)
1200        || (INTVAL (operands[2]) < - 0x7
1201            && INTVAL (operands[2]) >= - 0x7 - 0x7f))"
1202   [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
1203    (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 3)))]
1204   "
1206   HOST_WIDE_INT val = INTVAL (operands[2]);
1208   if (val >= 0)
1209     {
1210       operands[2] = GEN_INT (0x8);
1211       operands[3] = GEN_INT (val - 0x8);
1212     }
1213   else
1214     {
1215       operands[2] = GEN_INT (- 0x7);
1216       operands[3] = GEN_INT (val + 0x7);
1217     }
1220 (define_expand "subdi3"
1221   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
1222                    (minus:DI (match_operand:DI 1 "se_register_operand" "d")
1223                              (match_operand:DI 2 "se_register_operand" "d")))
1224               (clobber (match_dup 3))])]
1225   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
1226   "
1228   if (TARGET_64BIT)
1229     {
1230       emit_insn (gen_subdi3_internal_3 (operands[0], operands[1],
1231                                         operands[2]));
1232       DONE;
1233     }
1235   operands[3] = gen_reg_rtx (SImode);
1238 (define_insn "subdi3_internal"
1239   [(set (match_operand:DI 0 "register_operand" "=d")
1240         (minus:DI (match_operand:DI 1 "register_operand" "d")
1241                   (match_operand:DI 2 "register_operand" "d")))
1242    (clobber (match_operand:SI 3 "register_operand" "=d"))]
1243   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
1244   "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3"
1245   [(set_attr "type"     "darith")
1246    (set_attr "mode"     "DI")
1247    (set_attr "length"   "16")])
1249 (define_split
1250   [(set (match_operand:DI 0 "register_operand" "")
1251         (minus:DI (match_operand:DI 1 "register_operand" "")
1252                   (match_operand:DI 2 "register_operand" "")))
1253    (clobber (match_operand:SI 3 "register_operand" ""))]
1254   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1255    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1256    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1257    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1258    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1260   [(set (match_dup 3)
1261         (ltu:SI (subreg:SI (match_dup 1) 0)
1262                 (subreg:SI (match_dup 2) 0)))
1264    (set (subreg:SI (match_dup 0) 0)
1265         (minus:SI (subreg:SI (match_dup 1) 0)
1266                   (subreg:SI (match_dup 2) 0)))
1268    (set (subreg:SI (match_dup 0) 1)
1269         (minus:SI (subreg:SI (match_dup 1) 1)
1270                   (subreg:SI (match_dup 2) 1)))
1272    (set (subreg:SI (match_dup 0) 1)
1273         (minus:SI (subreg:SI (match_dup 0) 1)
1274                   (match_dup 3)))]
1275   "")
1277 (define_split
1278   [(set (match_operand:DI 0 "register_operand" "")
1279         (minus:DI (match_operand:DI 1 "register_operand" "")
1280                   (match_operand:DI 2 "register_operand" "")))
1281    (clobber (match_operand:SI 3 "register_operand" ""))]
1282   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1283    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1284    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1285    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1286    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1288   [(set (match_dup 3)
1289         (ltu:SI (subreg:SI (match_dup 1) 1)
1290                 (subreg:SI (match_dup 2) 1)))
1292    (set (subreg:SI (match_dup 0) 1)
1293         (minus:SI (subreg:SI (match_dup 1) 1)
1294                   (subreg:SI (match_dup 2) 1)))
1296    (set (subreg:SI (match_dup 0) 0)
1297         (minus:SI (subreg:SI (match_dup 1) 0)
1298                   (subreg:SI (match_dup 2) 0)))
1300    (set (subreg:SI (match_dup 0) 0)
1301         (minus:SI (subreg:SI (match_dup 0) 0)
1302                   (match_dup 3)))]
1303   "")
1305 (define_insn "subdi3_internal_2"
1306   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1307         (minus:DI (match_operand:DI 1 "register_operand" "d,d,d")
1308                   (match_operand:DI 2 "small_int" "P,J,N")))
1309    (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
1310   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1311    && INTVAL (operands[2]) != -32768"
1312   "@
1313    sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3
1314    move\\t%L0,%L1\;move\\t%M0,%M1
1315    sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3"
1316   [(set_attr "type"     "darith")
1317    (set_attr "mode"     "DI")
1318    (set_attr "length"   "12,8,16")])
1320 (define_split
1321   [(set (match_operand:DI 0 "register_operand" "")
1322         (minus:DI (match_operand:DI 1 "register_operand" "")
1323                   (match_operand:DI 2 "small_int" "")))
1324    (clobber (match_operand:SI 3 "register_operand" ""))]
1325   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1326    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1327    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1328    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1329    && INTVAL (operands[2]) > 0"
1331   [(set (match_dup 3)
1332         (ltu:SI (subreg:SI (match_dup 1) 0)
1333                 (match_dup 2)))
1335    (set (subreg:SI (match_dup 0) 0)
1336         (minus:SI (subreg:SI (match_dup 1) 0)
1337                   (match_dup 2)))
1339    (set (subreg:SI (match_dup 0) 1)
1340         (minus:SI (subreg:SI (match_dup 1) 1)
1341                   (match_dup 3)))]
1342   "")
1344 (define_split
1345   [(set (match_operand:DI 0 "register_operand" "")
1346         (minus:DI (match_operand:DI 1 "register_operand" "")
1347                   (match_operand:DI 2 "small_int" "")))
1348    (clobber (match_operand:SI 3 "register_operand" ""))]
1349   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1350    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1351    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1352    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1353    && INTVAL (operands[2]) > 0"
1355   [(set (match_dup 3)
1356         (ltu:SI (subreg:SI (match_dup 1) 1)
1357                 (match_dup 2)))
1359    (set (subreg:SI (match_dup 0) 1)
1360         (minus:SI (subreg:SI (match_dup 1) 1)
1361                   (match_dup 2)))
1363    (set (subreg:SI (match_dup 0) 0)
1364         (minus:SI (subreg:SI (match_dup 1) 0)
1365                   (match_dup 3)))]
1366   "")
1368 (define_insn "subdi3_internal_3"
1369   [(set (match_operand:DI 0 "register_operand" "=d")
1370         (minus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
1371                   (match_operand:DI 2 "se_arith_operand" "dI")))]
1372   "TARGET_64BIT && !TARGET_MIPS16
1373    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1374   "*
1376   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1377     ? \"daddu\\t%0,%z1,%n2\"
1378     : \"dsubu\\t%0,%z1,%2\";
1380   [(set_attr "type"     "darith")
1381    (set_attr "mode"     "DI")])
1383 ;; For the mips16, we need to recognize stack pointer subtractions
1384 ;; explicitly, since we don't have a constraint for $sp.  These insns
1385 ;; will be generated by the save_restore_insns functions.
1387 (define_insn ""
1388   [(set (reg:DI 29)
1389         (minus:DI (reg:DI 29)
1390                   (match_operand:DI 0 "small_int" "I")))]
1391   "TARGET_MIPS16
1392    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1393   "daddu\\t%$,%$,%n0"
1394   [(set_attr "type"     "arith")
1395    (set_attr "mode"     "DI")
1396    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1397                                       (const_int 4)
1398                                       (const_int 8)))])
1400 (define_insn ""
1401   [(set (match_operand:DI 0 "register_operand" "=d")
1402         (minus:DI (reg:DI 29)
1403                   (match_operand:DI 1 "small_int" "I")))]
1404   "TARGET_MIPS16
1405    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1406   "daddu\\t%0,%$,%n1"
1407   [(set_attr "type"     "arith")
1408    (set_attr "mode"     "DI")
1409    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nuimm5_4" "")
1410                                       (const_int 4)
1411                                       (const_int 8)))])
1413 (define_insn ""
1414   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1415         (minus:DI (match_operand:DI 1 "register_operand" "0,d,d")
1416                   (match_operand:DI 2 "arith_operand" "I,O,d")))]
1417   "TARGET_MIPS16
1418    && (GET_CODE (operands[2]) != CONST_INT
1419        || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1420   "*
1422   if (REGNO (operands[0]) == REGNO (operands[1]))
1423     return \"dsubu\\t%0,%2\";
1424   return \"dsubu\\t%0,%1,%2\";
1426   [(set_attr "type"     "arith")
1427    (set_attr "mode"     "DI")
1428    (set_attr_alternative "length"
1429                 [(if_then_else (match_operand:VOID 2 "m16_nsimm5_1" "")
1430                                (const_int 4)
1431                                (const_int 8))
1432                  (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1433                                (const_int 4)
1434                                (const_int 8))
1435                  (const_int 4)])])
1437 ;; On the mips16, we can sometimes split an add of a constant which is
1438 ;; a 4 byte instruction into two adds which are both 2 byte
1439 ;; instructions.  There are two cases: one where we are adding a
1440 ;; constant plus a register to another register, and one where we are
1441 ;; simply adding a constant to a register.
1443 (define_split
1444   [(set (match_operand:DI 0 "register_operand" "")
1445         (minus:DI (match_dup 0)
1446                   (match_operand:DI 1 "const_int_operand" "")))]
1447   "TARGET_MIPS16 && TARGET_64BIT && reload_completed
1448    && GET_CODE (operands[0]) == REG
1449    && M16_REG_P (REGNO (operands[0]))
1450    && GET_CODE (operands[1]) == CONST_INT
1451    && ((INTVAL (operands[1]) > 0x10
1452         && INTVAL (operands[1]) <= 0x10 + 0x10)
1453        || (INTVAL (operands[1]) < - 0xf
1454            && INTVAL (operands[1]) >= - 0xf - 0xf))"
1455   [(set (match_dup 0) (minus:DI (match_dup 0) (match_dup 1)))
1456    (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))]
1457   "
1459   HOST_WIDE_INT val = INTVAL (operands[1]);
1461   if (val >= 0)
1462     {
1463       operands[1] = GEN_INT (0xf);
1464       operands[2] = GEN_INT (val - 0xf);
1465     }
1466   else
1467     {
1468       operands[1] = GEN_INT (- 0x10);
1469       operands[2] = GEN_INT (val + 0x10);
1470     }
1473 (define_split
1474   [(set (match_operand:DI 0 "register_operand" "")
1475         (minus:DI (match_operand:DI 1 "register_operand" "")
1476                   (match_operand:DI 2 "const_int_operand" "")))]
1477   "TARGET_MIPS16 && TARGET_64BIT && reload_completed
1478    && GET_CODE (operands[0]) == REG
1479    && M16_REG_P (REGNO (operands[0]))
1480    && GET_CODE (operands[1]) == REG
1481    && M16_REG_P (REGNO (operands[1]))
1482    && REGNO (operands[0]) != REGNO (operands[1])
1483    && GET_CODE (operands[2]) == CONST_INT
1484    && ((INTVAL (operands[2]) > 0x8
1485         && INTVAL (operands[2]) <= 0x8 + 0x10)
1486        || (INTVAL (operands[2]) < - 0x7
1487            && INTVAL (operands[2]) >= - 0x7 - 0xf))"
1488   [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))
1489    (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 3)))]
1490   "
1492   HOST_WIDE_INT val = INTVAL (operands[2]);
1494   if (val >= 0)
1495     {
1496       operands[2] = GEN_INT (0x8);
1497       operands[3] = GEN_INT (val - 0x8);
1498     }
1499   else
1500     {
1501       operands[2] = GEN_INT (- 0x7);
1502       operands[3] = GEN_INT (val + 0x7);
1503     }
1506 (define_insn "subsi3_internal_2"
1507   [(set (match_operand:DI 0 "register_operand" "=d")
1508         (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1509                                   (match_operand:SI 2 "arith_operand" "dI"))))]
1510   "TARGET_64BIT && !TARGET_MIPS16
1511    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1512   "*
1514   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1515     ? \"addu\\t%0,%z1,%n2\"
1516     : \"subu\\t%0,%z1,%2\";
1518   [(set_attr "type"     "arith")
1519    (set_attr "mode"     "DI")])
1521 (define_insn ""
1522   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1523         (sign_extend:DI (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1524                                   (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1525   "TARGET_64BIT && TARGET_MIPS16
1526    && (GET_CODE (operands[2]) != CONST_INT
1527        || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1528   "*
1530   if (REGNO (operands[0]) == REGNO (operands[1]))
1531     return \"subu\\t%0,%2\";
1532   return \"subu\\t%0,%1,%2\";
1534   [(set_attr "type"     "arith")
1535    (set_attr "mode"     "SI")
1536    (set_attr_alternative "length"
1537                 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1538                                (const_int 4)
1539                                (const_int 8))
1540                  (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1541                                (const_int 4)
1542                                (const_int 8))
1543                  (const_int 4)])])
1544   
1548 ;;  ....................
1550 ;;      MULTIPLICATION
1552 ;;  ....................
1555 ;; Early Vr4300 silicon has a CPU bug where multiplies with certain
1556 ;; operands may corrupt immediately following multiplies. This is a
1557 ;; simple fix to insert NOPs.
1559 (define_expand "muldf3"
1560   [(set (match_operand:DF 0 "register_operand" "=f")
1561         (mult:DF (match_operand:DF 1 "register_operand" "f")
1562                  (match_operand:DF 2 "register_operand" "f")))]
1563   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1564   "
1566   if (mips_cpu != PROCESSOR_R4300)
1567     emit_insn (gen_muldf3_internal (operands[0], operands[1], operands[2]));
1568   else
1569     emit_insn (gen_muldf3_r4300 (operands[0], operands[1], operands[2]));
1570   DONE;
1573 (define_insn "muldf3_internal"
1574   [(set (match_operand:DF 0 "register_operand" "=f")
1575         (mult:DF (match_operand:DF 1 "register_operand" "f")
1576                  (match_operand:DF 2 "register_operand" "f")))]
1577   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && mips_cpu != PROCESSOR_R4300"
1578   "mul.d\\t%0,%1,%2"
1579   [(set_attr "type"     "fmul")
1580    (set_attr "mode"     "DF")])
1582 (define_insn "muldf3_r4300"
1583   [(set (match_operand:DF 0 "register_operand" "=f")
1584         (mult:DF (match_operand:DF 1 "register_operand" "f")
1585                  (match_operand:DF 2 "register_operand" "f")))]
1586   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && mips_cpu == PROCESSOR_R4300"
1587   "*
1589   output_asm_insn (\"mul.d\\t%0,%1,%2\", operands);
1590   if (TARGET_4300_MUL_FIX)
1591     output_asm_insn (\"nop\", operands);
1592   return \"\";
1594   [(set_attr "type"     "fmul")
1595    (set_attr "mode"     "DF")
1596    (set_attr "length"   "8")])  ;; mul.d + nop
1598 (define_expand "mulsf3"
1599   [(set (match_operand:SF 0 "register_operand" "=f")
1600         (mult:SF (match_operand:SF 1 "register_operand" "f")
1601                  (match_operand:SF 2 "register_operand" "f")))]
1602   "TARGET_HARD_FLOAT"
1603   "
1605   if (mips_cpu != PROCESSOR_R4300)
1606     emit_insn( gen_mulsf3_internal (operands[0], operands[1], operands[2]));
1607   else
1608     emit_insn( gen_mulsf3_r4300 (operands[0], operands[1], operands[2]));
1609   DONE;
1612 (define_insn "mulsf3_internal"
1613   [(set (match_operand:SF 0 "register_operand" "=f")
1614         (mult:SF (match_operand:SF 1 "register_operand" "f")
1615                  (match_operand:SF 2 "register_operand" "f")))]
1616   "TARGET_HARD_FLOAT && mips_cpu != PROCESSOR_R4300"
1617   "mul.s\\t%0,%1,%2"
1618   [(set_attr "type"     "fmul")
1619    (set_attr "mode"     "SF")])
1621 (define_insn "mulsf3_r4300"
1622   [(set (match_operand:SF 0 "register_operand" "=f")
1623         (mult:SF (match_operand:SF 1 "register_operand" "f")
1624                  (match_operand:SF 2 "register_operand" "f")))]
1625   "TARGET_HARD_FLOAT && mips_cpu == PROCESSOR_R4300"
1626   "*
1628   output_asm_insn (\"mul.s\\t%0,%1,%2\", operands);
1629   if (TARGET_4300_MUL_FIX)
1630     output_asm_insn (\"nop\", operands);
1631   return \"\";
1633   [(set_attr "type"     "fmul")
1634    (set_attr "mode"     "SF")
1635    (set_attr "length"   "8")])  ;; mul.s + nop
1638 ;; ??? The R4000 (only) has a cpu bug.  If a double-word shift executes while
1639 ;; a multiply is in progress, it may give an incorrect result.  Avoid
1640 ;; this by keeping the mflo with the mult on the R4000.
1642 (define_expand "mulsi3"
1643   [(set (match_operand:SI 0 "register_operand" "=l")
1644         (mult:SI (match_operand:SI 1 "register_operand" "d")
1645                  (match_operand:SI 2 "register_operand" "d")))
1646    (clobber (match_scratch:SI 3 "=h"))
1647    (clobber (match_scratch:SI 4 "=a"))]
1648   ""
1649   "
1651   if (HAVE_mulsi3_mult3)
1652     emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1653   else if (mips_cpu != PROCESSOR_R4000 || TARGET_MIPS16)
1654     emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1655   else
1656     emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1657   DONE;
1660 (define_insn "mulsi3_mult3"
1661   [(set (match_operand:SI 0 "register_operand" "=d,l")
1662         (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1663                  (match_operand:SI 2 "register_operand" "d,d")))
1664    (clobber (match_scratch:SI 3 "=h,h"))
1665    (clobber (match_scratch:SI 4 "=l,X"))
1666    (clobber (match_scratch:SI 5 "=a,a"))]
1667   "GENERATE_MULT3
1668    || TARGET_MAD"
1669   "*
1671   if (which_alternative == 1)
1672     return \"mult\\t%1,%2\";
1673   if (TARGET_MAD)
1674     return \"mul\\t%0,%1,%2\";
1675   return \"mult\\t%0,%1,%2\";
1677   [(set_attr "type"     "imul")
1678    (set_attr "mode"     "SI")])
1680 (define_insn "mulsi3_internal"
1681   [(set (match_operand:SI 0 "register_operand" "=l")
1682         (mult:SI (match_operand:SI 1 "register_operand" "d")
1683                  (match_operand:SI 2 "register_operand" "d")))
1684    (clobber (match_scratch:SI 3 "=h"))
1685    (clobber (match_scratch:SI 4 "=a"))]
1686   "mips_cpu != PROCESSOR_R4000 || TARGET_MIPS16"
1687   "mult\\t%1,%2"
1688   [(set_attr "type"     "imul")
1689    (set_attr "mode"     "SI")])
1691 (define_insn "mulsi3_r4000"
1692   [(set (match_operand:SI 0 "register_operand" "=d")
1693         (mult:SI (match_operand:SI 1 "register_operand" "d")
1694                  (match_operand:SI 2 "register_operand" "d")))
1695    (clobber (match_scratch:SI 3 "=h"))
1696    (clobber (match_scratch:SI 4 "=l"))
1697    (clobber (match_scratch:SI 5 "=a"))]
1698   "mips_cpu == PROCESSOR_R4000 && !TARGET_MIPS16"
1699   "*
1701   rtx xoperands[10];
1703   xoperands[0] = operands[0];
1704   xoperands[1] = gen_rtx (REG, SImode, LO_REGNUM);
1706   output_asm_insn (\"mult\\t%1,%2\", operands);
1707   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1708   return \"\";
1710   [(set_attr "type"     "imul")
1711    (set_attr "mode"     "SI")
1712    (set_attr "length"   "12")])         ;; mult + mflo + delay
1714 ;; Multiply-accumulate patterns
1716 ;; For processors that can copy the output to a general register:
1718 ;; The all-d alternative is needed because the combiner will find this
1719 ;; pattern and then register alloc/reload will move registers around to
1720 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1722 ;; The last alternative should be made slightly less desirable, but adding
1723 ;; "?" to the constraint is too strong, and causes values to be loaded into
1724 ;; LO even when that's more costly.  For now, using "*d" mostly does the
1725 ;; trick.
1726 (define_insn "*mul_acc_si"
1727   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1728         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1729                           (match_operand:SI 2 "register_operand" "d,d,d"))
1730                  (match_operand:SI 3 "register_operand" "0,l,*d")))
1731    (clobber (match_scratch:SI 4 "=h,h,h"))
1732    (clobber (match_scratch:SI 5 "=X,3,l"))
1733    (clobber (match_scratch:SI 6 "=a,a,a"))
1734    (clobber (match_scratch:SI 7 "=X,X,d"))]
1735   "TARGET_MIPS3900
1736    && !TARGET_MIPS16"
1737   "*
1739   static const char *const madd[] = { \"madd\\t%1,%2\", \"madd\\t%0,%1,%2\" };
1740   if (which_alternative == 2)
1741     return \"#\";
1742   return madd[which_alternative];
1744   [(set_attr "type"     "imul,imul,multi")
1745    (set_attr "mode"     "SI")
1746    (set_attr "length"   "4,4,8")])
1748 ;; Split the above insn if we failed to get LO allocated.
1749 (define_split
1750   [(set (match_operand:SI 0 "register_operand" "")
1751         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1752                           (match_operand:SI 2 "register_operand" ""))
1753                  (match_operand:SI 3 "register_operand" "")))
1754    (clobber (match_scratch:SI 4 ""))
1755    (clobber (match_scratch:SI 5 ""))
1756    (clobber (match_scratch:SI 6 ""))
1757    (clobber (match_scratch:SI 7 ""))]
1758   "reload_completed && GP_REG_P (true_regnum (operands[0])) && GP_REG_P (true_regnum (operands[3]))"
1759   [(parallel [(set (match_dup 7)
1760                    (mult:SI (match_dup 1) (match_dup 2)))
1761               (clobber (match_dup 4))
1762               (clobber (match_dup 5))
1763               (clobber (match_dup 6))])
1764    (set (match_dup 0) (plus:SI (match_dup 7) (match_dup 3)))]
1765   "")
1767 (define_split
1768   [(set (match_operand:SI 0 "register_operand" "")
1769         (minus:SI (match_operand:SI 1 "register_operand" "")
1770                   (mult:SI (match_operand:SI 2 "register_operand" "")
1771                            (match_operand:SI 3 "register_operand" ""))))
1772    (clobber (match_scratch:SI 4 ""))
1773    (clobber (match_scratch:SI 5 ""))
1774    (clobber (match_scratch:SI 6 ""))
1775    (clobber (match_scratch:SI 7 ""))]
1776   "reload_completed && GP_REG_P (true_regnum (operands[0])) && GP_REG_P (true_regnum (operands[1]))"
1777   [(parallel [(set (match_dup 7)
1778                    (mult:SI (match_dup 2) (match_dup 3)))
1779               (clobber (match_dup 4))
1780               (clobber (match_dup 5))
1781               (clobber (match_dup 6))])
1782    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))]
1783   "")
1785 (define_expand "muldi3"
1786   [(set (match_operand:DI 0 "register_operand" "=l")
1787         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1788                  (match_operand:DI 2 "register_operand" "d")))
1789    (clobber (match_scratch:DI 3 "=h"))
1790    (clobber (match_scratch:DI 4 "=a"))]
1791   "TARGET_64BIT"
1793   "
1795   if (GENERATE_MULT3 || mips_cpu == PROCESSOR_R4000 || TARGET_MIPS16)
1796     emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2]));
1797   else
1798     emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1799   DONE;
1802 ;; Don't accept both operands using se_register_operand, because if
1803 ;; both operands are sign extended we would prefer to use mult in the
1804 ;; mulsidi3 pattern.  Commutativity should permit either operand to be
1805 ;; sign extended.
1807 (define_insn "muldi3_internal"
1808   [(set (match_operand:DI 0 "register_operand" "=l")
1809         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1810                  (match_operand:DI 2 "register_operand" "d")))
1811    (clobber (match_scratch:DI 3 "=h"))
1812    (clobber (match_scratch:DI 4 "=a"))]
1813   "TARGET_64BIT && mips_cpu != PROCESSOR_R4000 && !TARGET_MIPS16"
1814   "dmult\\t%1,%2"
1815   [(set_attr "type"     "imul")
1816    (set_attr "mode"     "DI")])
1818 (define_insn "muldi3_internal2"
1819   [(set (match_operand:DI 0 "register_operand" "=d")
1820         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1821                  (match_operand:DI 2 "register_operand" "d")))
1822    (clobber (match_scratch:DI 3 "=h"))
1823    (clobber (match_scratch:DI 4 "=l"))
1824    (clobber (match_scratch:DI 5 "=a"))]
1825   "TARGET_64BIT && (GENERATE_MULT3 || mips_cpu == PROCESSOR_R4000 || TARGET_MIPS16)"
1826   "*
1828   if (GENERATE_MULT3)
1829     output_asm_insn (\"dmult\\t%0,%1,%2\", operands);
1830   else 
1831     {
1832     rtx xoperands[10];
1834     xoperands[0] = operands[0];
1835     xoperands[1] = gen_rtx (REG, DImode, LO_REGNUM);
1837     output_asm_insn (\"dmult\\t%1,%2\", operands);
1838     output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1839     }
1840   return \"\";
1842   [(set_attr "type"     "imul")
1843    (set_attr "mode"     "DI")
1844    (set (attr "length")
1845         (if_then_else (ne (symbol_ref "GENERATE_MULT3") (const_int 0))
1846                        (const_int 4)
1847                        (const_int 12)))])       ;; mult + mflo + delay
1849 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1851 (define_expand "mulsidi3"
1852   [(set (match_operand:DI 0 "register_operand" "=x")
1853         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1854                  (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1855   ""
1856   "
1858   rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx);
1859   if (TARGET_64BIT)
1860     emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
1861                                    dummy, dummy));
1862   else
1863     emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2],
1864                                       dummy, dummy));
1865   DONE;
1868 (define_expand "umulsidi3"
1869   [(set (match_operand:DI 0 "register_operand" "=x")
1870         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1871                  (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1872   ""
1873   "
1875   rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx);
1876   if (TARGET_64BIT)
1877     emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
1878                                    dummy, dummy));
1879   else
1880     emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2],
1881                                       dummy, dummy));
1882   DONE;
1885 (define_insn "mulsidi3_internal"
1886   [(set (match_operand:DI 0 "register_operand" "=x")
1887         (mult:DI (match_operator:DI 3 "extend_operator"
1888                                     [(match_operand:SI 1 "register_operand" "d")])
1889                  (match_operator:DI 4 "extend_operator"
1890                                     [(match_operand:SI 2 "register_operand" "d")])))
1891    (clobber (match_scratch:SI 5 "=a"))]
1892   "!TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])"
1893   "*
1895   if (GET_CODE (operands[3]) == SIGN_EXTEND)
1896     return \"mult\\t%1,%2\";
1897   return \"multu\\t%1,%2\";
1899   [(set_attr "type"     "imul")
1900    (set_attr "mode"     "SI")])
1902 (define_insn "mulsidi3_64bit"
1903   [(set (match_operand:DI 0 "register_operand" "=a")
1904         (mult:DI (match_operator:DI 3 "extend_operator"
1905                                     [(match_operand:SI 1 "register_operand" "d")])
1906                  (match_operator:DI 4 "extend_operator"
1907                                     [(match_operand:SI 2 "register_operand" "d")])))
1908    (clobber (match_scratch:DI 5 "=l"))
1909    (clobber (match_scratch:DI 6 "=h"))]
1910   "TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])"
1911   "*
1913   if (GET_CODE (operands[3]) == SIGN_EXTEND)
1914     return \"mult\\t%1,%2\";
1915   return \"multu\\t%1,%2\";
1917   [(set_attr "type"     "imul")
1918    (set_attr "mode"     "SI")])
1920 ;; _highpart patterns
1921 (define_expand "smulsi3_highpart"
1922   [(set (match_operand:SI 0 "register_operand" "=h")
1923         (truncate:SI
1924          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1925                                (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
1926                       (const_int 32))))]
1927   ""
1928   "
1930   rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx);
1931   rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx);
1932 #ifndef NO_MD_PROTOTYPES
1933   rtx (*genfn) PROTO((rtx, rtx, rtx, rtx, rtx, rtx));
1934 #else
1935   rtx (*genfn) ();
1936 #endif
1937   genfn = gen_xmulsi3_highpart_internal;
1938   emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
1939                        dummy, dummy2));
1940   DONE;
1943 (define_expand "umulsi3_highpart"
1944   [(set (match_operand:SI 0 "register_operand" "=h")
1945         (truncate:SI
1946          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1947                                (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
1948                       (const_int 32))))]
1949   ""
1950   "
1952   rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx);
1953   rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx);
1954 #ifndef NO_MD_PROTOTYPES
1955   rtx (*genfn) PROTO((rtx, rtx, rtx, rtx, rtx, rtx));
1956 #else
1957   rtx (*genfn) ();
1958 #endif
1959   genfn = gen_xmulsi3_highpart_internal;
1960   emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
1961                        dummy, dummy2));
1962   DONE;
1965 (define_insn "xmulsi3_highpart_internal"
1966   [(set (match_operand:SI 0 "register_operand" "=h")
1967         (truncate:SI
1968          (match_operator:DI 5 "highpart_shift_operator"
1969                             [(mult:DI (match_operator:DI 3 "extend_operator"
1970                                                          [(match_operand:SI 1 "register_operand" "d")])
1971                                       (match_operator:DI 4 "extend_operator"
1972                                                          [(match_operand:SI 2 "register_operand" "d")]))
1973                              (const_int 32)])))
1974    (clobber (match_scratch:SI 6 "=l"))
1975    (clobber (match_scratch:SI 7 "=a"))]
1976   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
1977   "*
1979   if (GET_CODE (operands[3]) == SIGN_EXTEND)
1980     return \"mult\\t%1,%2\";
1981   else
1982     return \"multu\\t%1,%2\";
1984   [(set_attr "type"     "imul")
1985    (set_attr "mode"     "SI")])
1987 (define_insn "smuldi3_highpart"
1988   [(set (match_operand:DI 0 "register_operand" "=h")
1989         (truncate:DI
1990          (lshiftrt:TI (mult:TI (sign_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
1991                                (sign_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
1992                       (const_int 64))))
1993    (clobber (match_scratch:DI 3 "=l"))
1994    (clobber (match_scratch:DI 4 "=a"))]
1995   "TARGET_64BIT"
1996   "dmult\\t%1,%2"
1997   [(set_attr "type"     "imul")
1998    (set_attr "mode"     "DI")])
2000 (define_insn "umuldi3_highpart"
2001   [(set (match_operand:DI 0 "register_operand" "=h")
2002         (truncate:DI
2003          (lshiftrt:TI (mult:TI (zero_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
2004                                (zero_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
2005                       (const_int 64))))
2006    (clobber (match_scratch:DI 3 "=l"))
2007    (clobber (match_scratch:DI 4 "=a"))]
2008   "TARGET_64BIT"
2009   "dmultu\\t%1,%2"
2010   [(set_attr "type"     "imul")
2011    (set_attr "mode"     "DI")])
2013 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
2014 ;; instruction.  The HI/LO registers are used as a 64 bit accumulator.
2016 (define_insn "madsi"
2017   [(set (match_operand:SI 0 "register_operand" "+l")
2018         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
2019                           (match_operand:SI 2 "register_operand" "d"))
2020                  (match_dup 0)))
2021    (clobber (match_scratch:SI 3 "=h"))
2022    (clobber (match_scratch:SI 4 "=a"))]
2023   "TARGET_MAD"
2024   "mad\\t%1,%2"
2025   [(set_attr "type"     "imul")
2026    (set_attr "mode"     "SI")])
2028 (define_insn "*mul_acc_di"
2029   [(set (match_operand:DI 0 "register_operand" "+x")
2030         (plus:DI (mult:DI (match_operator:DI 3 "extend_operator"
2031                            [(match_operand:SI 1 "register_operand" "d")])
2032                           (match_operator:DI 4 "extend_operator"
2033                            [(match_operand:SI 2 "register_operand" "d")]))
2034                  (match_dup 0)))
2035    (clobber (match_scratch:SI 5 "=a"))]
2036   "TARGET_MAD
2037    && ! TARGET_64BIT
2038    && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2039   "*
2041   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2042     return \"mad\\t%1,%2\";
2043   else
2044     return \"madu\\t%1,%2\";
2046   [(set_attr "type"     "imul")
2047    (set_attr "mode"     "SI")])
2049 (define_insn "*mul_acc_64bit_di"
2050   [(set (match_operand:DI 0 "register_operand" "+a")
2051         (plus:DI (mult:DI (match_operator:DI 3 "extend_operator"
2052                            [(match_operand:SI 1 "register_operand" "d")])
2053                           (match_operator:DI 4 "extend_operator"
2054                            [(match_operand:SI 2 "register_operand" "d")]))
2055                  (match_dup 0)))
2056    (clobber (match_scratch:SI 5 "=h"))
2057    (clobber (match_scratch:SI 6 "=l"))]
2058   "TARGET_MAD
2059    && TARGET_64BIT
2060    && GET_CODE (operands[3]) == GET_CODE (operands[4])"
2061   "*
2063   if (GET_CODE (operands[3]) == SIGN_EXTEND)
2064     return \"mad\\t%1,%2\";
2065   else
2066     return \"madu\\t%1,%2\";
2068   [(set_attr "type"     "imul")
2069    (set_attr "mode"     "SI")])
2071 ;; Floating point multiply accumulate instructions.
2073 (define_insn ""
2074   [(set (match_operand:DF 0 "register_operand" "=f")
2075         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2076                           (match_operand:DF 2 "register_operand" "f"))
2077                  (match_operand:DF 3 "register_operand" "f")))]
2078   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2079   "madd.d\\t%0,%3,%1,%2"
2080   [(set_attr "type"     "fmadd")
2081    (set_attr "mode"     "DF")])
2083 (define_insn ""
2084   [(set (match_operand:SF 0 "register_operand" "=f")
2085         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2086                           (match_operand:SF 2 "register_operand" "f"))
2087                  (match_operand:SF 3 "register_operand" "f")))]
2088   "mips_isa >= 4 && TARGET_HARD_FLOAT"
2089   "madd.s\\t%0,%3,%1,%2"
2090   [(set_attr "type"     "fmadd")
2091    (set_attr "mode"     "SF")])
2093 (define_insn ""
2094   [(set (match_operand:DF 0 "register_operand" "=f")
2095         (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2096                            (match_operand:DF 2 "register_operand" "f"))
2097                   (match_operand:DF 3 "register_operand" "f")))]
2098   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2099   "msub.d\\t%0,%3,%1,%2"
2100   [(set_attr "type"     "fmadd")
2101    (set_attr "mode"     "DF")])
2103 (define_insn ""
2104   [(set (match_operand:SF 0 "register_operand" "=f")
2105         (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2106                            (match_operand:SF 2 "register_operand" "f"))
2107                   (match_operand:SF 3 "register_operand" "f")))]
2108                   
2109   "mips_isa >= 4 && TARGET_HARD_FLOAT"
2110   "msub.s\\t%0,%3,%1,%2"
2111   [(set_attr "type"     "fmadd")
2112    (set_attr "mode"     "SF")])
2114 (define_insn ""
2115   [(set (match_operand:DF 0 "register_operand" "=f")
2116         (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2117                                   (match_operand:DF 2 "register_operand" "f"))
2118                          (match_operand:DF 3 "register_operand" "f"))))]
2119   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2120   "nmadd.d\\t%0,%3,%1,%2"
2121   [(set_attr "type"     "fmadd")
2122    (set_attr "mode"     "DF")])
2124 (define_insn ""
2125   [(set (match_operand:SF 0 "register_operand" "=f")
2126         (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2127                                   (match_operand:SF 2 "register_operand" "f"))
2128                          (match_operand:SF 3 "register_operand" "f"))))]
2129   "mips_isa >= 4 && TARGET_HARD_FLOAT"
2130   "nmadd.s\\t%0,%3,%1,%2"
2131   [(set_attr "type"     "fmadd")
2132    (set_attr "mode"     "SF")])
2134 (define_insn ""
2135   [(set (match_operand:DF 0 "register_operand" "=f")
2136         (minus:DF (match_operand:DF 1 "register_operand" "f")
2137                   (mult:DF (match_operand:DF 2 "register_operand" "f")
2138                            (match_operand:DF 3 "register_operand" "f"))))]
2139   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2140   "nmsub.d\\t%0,%1,%2,%3"
2141   [(set_attr "type"     "fmadd")
2142    (set_attr "mode"     "DF")])
2144 (define_insn ""
2145   [(set (match_operand:SF 0 "register_operand" "=f")
2146         (minus:SF (match_operand:SF 1 "register_operand" "f")
2147                   (mult:SF (match_operand:SF 2 "register_operand" "f")
2148                            (match_operand:SF 3 "register_operand" "f"))))]
2149   "mips_isa >= 4 && TARGET_HARD_FLOAT"
2150   "nmsub.s\\t%0,%1,%2,%3"
2151   [(set_attr "type"     "fmadd")
2152    (set_attr "mode"     "SF")])
2155 ;;  ....................
2157 ;;      DIVISION and REMAINDER
2159 ;;  ....................
2162 (define_insn "divdf3"
2163   [(set (match_operand:DF 0 "register_operand" "=f")
2164         (div:DF (match_operand:DF 1 "register_operand" "f")
2165                 (match_operand:DF 2 "register_operand" "f")))]
2166   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2167   "div.d\\t%0,%1,%2"
2168   [(set_attr "type"     "fdiv")
2169    (set_attr "mode"     "DF")])
2171 (define_insn "divsf3"
2172   [(set (match_operand:SF 0 "register_operand" "=f")
2173         (div:SF (match_operand:SF 1 "register_operand" "f")
2174                 (match_operand:SF 2 "register_operand" "f")))]
2175   "TARGET_HARD_FLOAT"
2176   "div.s\\t%0,%1,%2"
2177   [(set_attr "type"     "fdiv")
2178    (set_attr "mode"     "SF")])
2180 (define_insn ""
2181   [(set (match_operand:DF 0 "register_operand" "=f")
2182         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2183                 (match_operand:DF 2 "register_operand" "f")))]
2184   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_fast_math"
2185   "recip.d\\t%0,%2"
2186   [(set_attr "type"     "fdiv")
2187    (set_attr "mode"     "DF")])
2189 (define_insn ""
2190   [(set (match_operand:SF 0 "register_operand" "=f")
2191         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2192                 (match_operand:SF 2 "register_operand" "f")))]
2193   "mips_isa >= 4 && TARGET_HARD_FLOAT && flag_fast_math"
2194   "recip.s\\t%0,%2"
2195   [(set_attr "type"     "fdiv")
2196    (set_attr "mode"     "SF")])
2198 ;; If optimizing, prefer the divmod functions over separate div and
2199 ;; mod functions, since this will allow using one instruction for both
2200 ;; the quotient and remainder.  At present, the divmod is not moved out
2201 ;; of loops if it is constant within the loop, so allow -mdebugc to
2202 ;; use the old method of doing things.
2204 ;; 64 is the multiply/divide hi register
2205 ;; 65 is the multiply/divide lo register
2207 ;; ??? We can't accept constants here, because the MIPS assembler will replace
2208 ;; a divide by power of 2 with a shift, and then the remainder is no longer
2209 ;; available.
2211 (define_expand "divmodsi4"
2212   [(set (match_operand:SI 0 "register_operand" "=d")
2213         (div:SI (match_operand:SI 1 "register_operand" "d")
2214                 (match_operand:SI 2 "register_operand" "d")))
2215    (set (match_operand:SI 3 "register_operand" "=d")
2216         (mod:SI (match_dup 1)
2217                 (match_dup 2)))
2218    (clobber (match_scratch:SI 4 "=l"))
2219    (clobber (match_scratch:SI 5 "=h"))
2220    (clobber (match_scratch:SI 6 "=a"))]
2221   "optimize"
2222   "
2224   emit_insn (gen_divmodsi4_internal (operands[0], operands[1], operands[2],
2225              operands[3]));
2226   if (!TARGET_NO_CHECK_ZERO_DIV)
2227     {
2228       emit_insn (gen_div_trap (operands[2],
2229                                GEN_INT (0),
2230                                GEN_INT (0x7)));
2231     }
2232   if (TARGET_CHECK_RANGE_DIV)
2233     {
2234       emit_insn (gen_div_trap (operands[2],
2235                                copy_to_mode_reg (SImode, GEN_INT (-1)),
2236                                GEN_INT (0x6)));
2237       emit_insn (gen_div_trap (operands[2],
2238                                copy_to_mode_reg (SImode, GEN_INT (0x80000000)),
2239                                GEN_INT (0x6)));
2240     }
2241   
2242   DONE;
2245 (define_insn "divmodsi4_internal"
2246   [(set (match_operand:SI 0 "register_operand" "=l")
2247         (div:SI (match_operand:SI 1 "register_operand" "d")
2248                 (match_operand:SI 2 "register_operand" "d")))
2249    (set (match_operand:SI 3 "register_operand" "=h")
2250         (mod:SI (match_dup 1)
2251                 (match_dup 2)))
2252    (clobber (match_scratch:SI 6 "=a"))]
2253   "optimize"
2254   "div\\t$0,%1,%2"
2255   [(set_attr "type"     "idiv")
2256    (set_attr "mode"     "SI")])
2258 (define_expand "divmoddi4"
2259   [(set (match_operand:DI 0 "register_operand" "=d")
2260         (div:DI (match_operand:DI 1 "se_register_operand" "d")
2261                 (match_operand:DI 2 "se_register_operand" "d")))
2262    (set (match_operand:DI 3 "register_operand" "=d")
2263         (mod:DI (match_dup 1)
2264                 (match_dup 2)))
2265    (clobber (match_scratch:DI 4 "=l"))
2266    (clobber (match_scratch:DI 5 "=h"))
2267    (clobber (match_scratch:DI 6 "=a"))]
2268   "TARGET_64BIT && optimize"
2269   "
2271   emit_insn (gen_divmoddi4_internal (operands[0], operands[1], operands[2],
2272              operands[3]));
2273   if (!TARGET_NO_CHECK_ZERO_DIV)
2274     {
2275       emit_insn (gen_div_trap (operands[2],
2276                                GEN_INT (0),
2277                                GEN_INT (0x7)));
2278     }
2279   if (TARGET_CHECK_RANGE_DIV)
2280     {
2281       emit_insn (gen_div_trap (operands[2],
2282                                copy_to_mode_reg (DImode, GEN_INT (-1)),
2283                                GEN_INT (0x6)));
2284       emit_insn (gen_div_trap (operands[2],
2285                                copy_to_mode_reg (DImode, GEN_INT (0x80000000)),
2286                                GEN_INT (0x6)));
2287     }
2288   
2289   DONE;
2292 (define_insn "divmoddi4_internal"
2293   [(set (match_operand:DI 0 "register_operand" "=l")
2294         (div:DI (match_operand:DI 1 "se_register_operand" "d")
2295                 (match_operand:DI 2 "se_register_operand" "d")))
2296    (set (match_operand:DI 3 "register_operand" "=h")
2297         (mod:DI (match_dup 1)
2298                 (match_dup 2)))
2299    (clobber (match_scratch:DI 6 "=a"))]
2300   "TARGET_64BIT && optimize"
2301   "ddiv\\t$0,%1,%2"
2302   [(set_attr "type"     "idiv")
2303    (set_attr "mode"     "SI")])
2305 (define_expand "udivmodsi4"
2306   [(set (match_operand:SI 0 "register_operand" "=d")
2307         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2308                  (match_operand:SI 2 "register_operand" "d")))
2309    (set (match_operand:SI 3 "register_operand" "=d")
2310         (umod:SI (match_dup 1)
2311                  (match_dup 2)))
2312    (clobber (match_scratch:SI 4 "=l"))
2313    (clobber (match_scratch:SI 5 "=h"))
2314    (clobber (match_scratch:SI 6 "=a"))]
2315   "optimize"
2316   "
2318   emit_insn (gen_udivmodsi4_internal (operands[0], operands[1], operands[2],
2319                                       operands[3]));
2320   if (!TARGET_NO_CHECK_ZERO_DIV)
2321     {
2322       emit_insn (gen_div_trap (operands[2],
2323                                GEN_INT (0),
2324                                GEN_INT (0x7)));
2325     }
2326   
2327   DONE;
2330 (define_insn "udivmodsi4_internal"
2331   [(set (match_operand:SI 0 "register_operand" "=l")
2332         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2333                  (match_operand:SI 2 "register_operand" "d")))
2334    (set (match_operand:SI 3 "register_operand" "=h")
2335         (umod:SI (match_dup 1)
2336                  (match_dup 2)))
2337    (clobber (match_scratch:SI 6 "=a"))]
2338   "optimize"
2339   "divu\\t$0,%1,%2"
2340   [(set_attr "type"     "idiv")
2341    (set_attr "mode"     "SI")])
2343 (define_expand "udivmoddi4"
2344   [(set (match_operand:DI 0 "register_operand" "=d")
2345         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2346                  (match_operand:DI 2 "se_register_operand" "d")))
2347    (set (match_operand:DI 3 "register_operand" "=d")
2348         (umod:DI (match_dup 1)
2349                  (match_dup 2)))
2350    (clobber (match_scratch:DI 4 "=l"))
2351    (clobber (match_scratch:DI 5 "=h"))
2352    (clobber (match_scratch:DI 6 "=a"))]
2353   "TARGET_64BIT && optimize"
2354   "
2356   emit_insn (gen_udivmoddi4_internal (operands[0], operands[1], operands[2],
2357                                       operands[3]));
2358   if (!TARGET_NO_CHECK_ZERO_DIV)
2359     {
2360       emit_insn (gen_div_trap (operands[2],
2361                                GEN_INT (0),
2362                                GEN_INT (0x7)));
2363     }
2364   
2365   DONE;
2368 (define_insn "udivmoddi4_internal"
2369   [(set (match_operand:DI 0 "register_operand" "=l")
2370         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2371                  (match_operand:DI 2 "se_register_operand" "d")))
2372    (set (match_operand:DI 3 "register_operand" "=h")
2373         (umod:DI (match_dup 1)
2374                  (match_dup 2)))
2375    (clobber (match_scratch:DI 6 "=a"))]
2376   "TARGET_64BIT && optimize"
2377   "ddivu\\t$0,%1,%2"
2378   [(set_attr "type"     "idiv")
2379    (set_attr "mode"     "SI")])
2381 ;; Division trap
2383 (define_expand "div_trap"
2384   [(trap_if (eq (match_operand 0 "register_operand" "d")
2385                 (match_operand 1 "true_reg_or_0_operand" "dJ"))
2386             (match_operand 2 "immediate_operand" ""))]
2387   ""
2388   "
2390   if (TARGET_MIPS16)
2391     emit_insn (gen_div_trap_mips16 (operands[0],operands[1],operands[2]));
2392   else
2393     emit_insn (gen_div_trap_normal (operands[0],operands[1],operands[2]));
2394   DONE;
2397 (define_insn "div_trap_normal"
2398   [(trap_if (eq (match_operand 0 "register_operand" "d")
2399                 (match_operand 1 "true_reg_or_0_operand" "dJ"))
2400             (match_operand 2 "immediate_operand" ""))]
2401   "!TARGET_MIPS16"
2402   "*
2404   rtx link;
2405   int have_dep_anti = 0;
2407   /* For divmod if one division is not needed then we don't need an extra
2408      divide by zero trap, which is anti dependent on previous trap */
2409   for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
2411     if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
2412         && GET_CODE (XEXP (link, 0)) == INSN
2413         && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
2414         && REGNO (operands[1]) == 0)
2415       have_dep_anti = 1;
2416   if (! have_dep_anti)
2417     {
2418       if (GENERATE_BRANCHLIKELY)
2419         {
2420           if (GET_CODE (operands[1]) == CONST_INT)
2421             return \"%(beql\\t%0,$0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2422           else
2423             return \"%(beql\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2424         }
2425       else
2426         {
2427           if (GET_CODE (operands[1]) == CONST_INT)
2428             return \"%(bne\\t%0,$0,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
2429           else
2430             return \"%(bne\\t%0,%1,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
2431         }
2432     }
2433   return \"\";
2435   [(set_attr "type" "unknown")
2436    (set_attr "length" "12")])
2439 ;; The mips16 bne insns is a macro which uses reg 24 as an intermediate.
2441 (define_insn "div_trap_mips16"
2442   [(trap_if (eq (match_operand 0 "register_operand" "d")
2443                 (match_operand 1 "true_reg_or_0_operand" "dJ"))
2444             (match_operand 2 "immediate_operand" ""))
2445    (clobber (reg:SI 24))]
2446   "TARGET_MIPS16"
2447   "*
2449   rtx link;
2450   int have_dep_anti = 0;
2452   /* For divmod if one division is not needed then we don't need an extra
2453      divide by zero trap, which is anti dependent on previous trap */
2454   for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
2456     if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link)
2457         && GET_CODE (XEXP (link, 0)) == INSN
2458         && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF
2459         && REGNO (operands[1]) == 0)
2460       have_dep_anti = 1;
2461   if (! have_dep_anti)
2462     {
2463       /* No branch delay slots on mips16. */ 
2464       if (GET_CODE (operands[1]) == CONST_INT)
2465         return \"%(bnez\\t%0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2466       else
2467         return \"%(bne\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
2468     }
2469   return \"\";
2471   [(set_attr "type" "unknown")
2472    (set_attr "length" "12")])
2474 (define_expand "divsi3"
2475   [(set (match_operand:SI 0 "register_operand" "=l")
2476         (div:SI (match_operand:SI 1 "register_operand" "d")
2477                 (match_operand:SI 2 "register_operand" "d")))
2478    (clobber (match_scratch:SI 3 "=h"))
2479    (clobber (match_scratch:SI 4 "=a"))]
2480   "!optimize"
2481   "
2483   emit_insn (gen_divsi3_internal (operands[0], operands[1], operands[2]));
2484   if (!TARGET_NO_CHECK_ZERO_DIV)
2485     {
2486       emit_insn (gen_div_trap (operands[2],
2487                                GEN_INT (0),
2488                                GEN_INT (0x7)));
2489     }
2490   if (TARGET_CHECK_RANGE_DIV)
2491     {
2492       emit_insn (gen_div_trap (operands[2],
2493                                copy_to_mode_reg (SImode, GEN_INT (-1)),
2494                                GEN_INT (0x6)));
2495       emit_insn (gen_div_trap (operands[2],
2496                                copy_to_mode_reg (SImode, GEN_INT (0x80000000)),
2497                                GEN_INT (0x6)));
2498     }
2499   
2500   DONE;
2503 (define_insn "divsi3_internal"
2504   [(set (match_operand:SI 0 "register_operand" "=l")
2505         (div:SI (match_operand:SI 1 "register_operand" "d")
2506                 (match_operand:SI 2 "nonmemory_operand" "di")))
2507    (clobber (match_scratch:SI 3 "=h"))
2508    (clobber (match_scratch:SI 4 "=a"))]
2509   "!optimize"
2510   "div\\t$0,%1,%2"
2511   [(set_attr "type"     "idiv")
2512    (set_attr "mode"     "SI")])
2514 (define_expand "divdi3"
2515   [(set (match_operand:DI 0 "register_operand" "=l")
2516         (div:DI (match_operand:DI 1 "se_register_operand" "d")
2517                 (match_operand:DI 2 "se_register_operand" "d"))) 
2518    (clobber (match_scratch:DI 3 "=h"))
2519    (clobber (match_scratch:DI 4 "=a"))]
2520   "TARGET_64BIT && !optimize"
2521   "
2523   emit_insn (gen_divdi3_internal (operands[0], operands[1], operands[2]));
2524   if (!TARGET_NO_CHECK_ZERO_DIV)
2525     {
2526       emit_insn (gen_div_trap (operands[2],
2527                                GEN_INT (0),
2528                                GEN_INT (0x7)));
2529     }
2530   if (TARGET_CHECK_RANGE_DIV)
2531     {
2532       emit_insn (gen_div_trap (operands[2],
2533                                copy_to_mode_reg (DImode, GEN_INT (-1)),
2534                                GEN_INT (0x6)));
2535       emit_insn (gen_div_trap (operands[2],
2536                                copy_to_mode_reg (DImode, GEN_INT (0x80000000)),
2537                                GEN_INT (0x6)));
2538     }
2539   
2540   DONE;
2543 (define_insn "divdi3_internal"
2544   [(set (match_operand:DI 0 "register_operand" "=l")
2545         (div:DI (match_operand:DI 1 "se_register_operand" "d")
2546                 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2547    (clobber (match_scratch:SI 3 "=h"))
2548    (clobber (match_scratch:SI 4 "=a"))]
2549   "TARGET_64BIT && !optimize"
2550   "ddiv\\t$0,%1,%2"
2551   [(set_attr "type"     "idiv")
2552    (set_attr "mode"     "DI")])
2554 (define_expand "modsi3"
2555   [(set (match_operand:SI 0 "register_operand" "=h")
2556         (mod:SI (match_operand:SI 1 "register_operand" "d")
2557                 (match_operand:SI 2 "register_operand" "d")))
2558    (clobber (match_scratch:SI 3 "=l"))
2559    (clobber (match_scratch:SI 4 "=a"))]
2560   "!optimize"
2561   "
2563   emit_insn (gen_modsi3_internal (operands[0], operands[1], operands[2]));
2564   if (!TARGET_NO_CHECK_ZERO_DIV)
2565     {
2566       emit_insn (gen_div_trap (operands[2],
2567                                GEN_INT (0),
2568                                GEN_INT (0x7)));
2569     }
2570   if (TARGET_CHECK_RANGE_DIV)
2571     {
2572       emit_insn (gen_div_trap (operands[2],
2573                                copy_to_mode_reg (SImode, GEN_INT (-1)),
2574                                GEN_INT (0x6)));
2575       emit_insn (gen_div_trap (operands[2],
2576                                copy_to_mode_reg (SImode, GEN_INT (0x80000000)),
2577                                GEN_INT (0x6)));
2578     }
2579   
2580   DONE;
2583 (define_insn "modsi3_internal"
2584   [(set (match_operand:SI 0 "register_operand" "=h")
2585         (mod:SI (match_operand:SI 1 "register_operand" "d")
2586                 (match_operand:SI 2 "nonmemory_operand" "di")))
2587    (clobber (match_scratch:SI 3 "=l"))
2588    (clobber (match_scratch:SI 4 "=a"))]
2589   "!optimize"
2590   "div\\t$0,%1,%2"
2591   [(set_attr "type"     "idiv")
2592    (set_attr "mode"     "SI")])
2594 (define_expand "moddi3"
2595   [(set (match_operand:DI 0 "register_operand" "=h")
2596         (mod:DI (match_operand:DI 1 "se_register_operand" "d")
2597                 (match_operand:DI 2 "se_register_operand" "d")))
2598    (clobber (match_scratch:DI 3 "=l"))
2599    (clobber (match_scratch:DI 4 "=a"))]
2600   "TARGET_64BIT && !optimize"
2601   "
2603   emit_insn (gen_moddi3_internal (operands[0], operands[1], operands[2]));
2604   if (!TARGET_NO_CHECK_ZERO_DIV)
2605     {
2606       emit_insn (gen_div_trap (operands[2],
2607                                GEN_INT (0),
2608                                GEN_INT (0x7)));
2609     }
2610   if (TARGET_CHECK_RANGE_DIV)
2611     {
2612       emit_insn (gen_div_trap (operands[2],
2613                                copy_to_mode_reg (DImode, GEN_INT (-1)),
2614                                GEN_INT (0x6)));
2615       emit_insn (gen_div_trap (operands[2],
2616                                copy_to_mode_reg (DImode, GEN_INT (0x80000000)),
2617                                GEN_INT (0x6)));
2618     }
2619   
2620   DONE;
2623 (define_insn "moddi3_internal"
2624   [(set (match_operand:DI 0 "register_operand" "=h")
2625         (mod:DI (match_operand:DI 1 "se_register_operand" "d")
2626                 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2627    (clobber (match_scratch:SI 3 "=l"))
2628    (clobber (match_scratch:SI 4 "=a"))]
2629   "TARGET_64BIT && !optimize"
2630   "ddiv\\t$0,%1,%2"
2631   [(set_attr "type"     "idiv")
2632    (set_attr "mode"     "DI")])
2634 (define_expand "udivsi3"
2635   [(set (match_operand:SI 0 "register_operand" "=l")
2636         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2637                  (match_operand:SI 2 "register_operand" "d")))
2638    (clobber (match_scratch:SI 3 "=h"))
2639    (clobber (match_scratch:SI 4 "=a"))]
2640   "!optimize"
2641   "
2643   emit_insn (gen_udivsi3_internal (operands[0], operands[1], operands[2]));
2644   if (!TARGET_NO_CHECK_ZERO_DIV)
2645     {
2646       emit_insn (gen_div_trap (operands[2],
2647                                GEN_INT (0),
2648                                GEN_INT (0x7)));
2649     }
2650   
2651   DONE;
2654 (define_insn "udivsi3_internal"
2655   [(set (match_operand:SI 0 "register_operand" "=l")
2656         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2657                  (match_operand:SI 2 "nonmemory_operand" "di")))
2658    (clobber (match_scratch:SI 3 "=h"))
2659    (clobber (match_scratch:SI 4 "=a"))]
2660   "!optimize"
2661   "divu\\t$0,%1,%2"
2662   [(set_attr "type"     "idiv")
2663    (set_attr "mode"     "SI")])
2665 (define_expand "udivdi3"
2666   [(set (match_operand:DI 0 "register_operand" "=l")
2667         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2668                  (match_operand:DI 2 "se_register_operand" "di")))
2669    (clobber (match_scratch:DI 3 "=h"))
2670    (clobber (match_scratch:DI 4 "=a"))]
2671   "TARGET_64BIT && !optimize"
2672   "
2674   emit_insn (gen_udivdi3_internal (operands[0], operands[1], operands[2]));
2675   if (!TARGET_NO_CHECK_ZERO_DIV)
2676     {
2677       emit_insn (gen_div_trap (operands[2],
2678                                GEN_INT (0),
2679                                GEN_INT (0x7)));
2680     }
2681   
2682   DONE;
2685 (define_insn "udivdi3_internal"
2686   [(set (match_operand:DI 0 "register_operand" "=l")
2687         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2688                  (match_operand:DI 2 "se_nonmemory_operand" "di")))
2689    (clobber (match_scratch:SI 3 "=h"))
2690    (clobber (match_scratch:SI 4 "=a"))]
2691   "TARGET_64BIT && !optimize"
2692   "ddivu\\t$0,%1,%2"
2693   [(set_attr "type"     "idiv")
2694    (set_attr "mode"     "DI")])
2696 (define_expand "umodsi3"
2697   [(set (match_operand:SI 0 "register_operand" "=h")
2698         (umod:SI (match_operand:SI 1 "register_operand" "d")
2699                  (match_operand:SI 2 "register_operand" "d")))
2700    (clobber (match_scratch:SI 3 "=l"))
2701    (clobber (match_scratch:SI 4 "=a"))]
2702   "!optimize"
2703   "
2705   emit_insn (gen_umodsi3_internal (operands[0], operands[1], operands[2]));
2706   if (!TARGET_NO_CHECK_ZERO_DIV)
2707     {
2708       emit_insn (gen_div_trap (operands[2],
2709                                GEN_INT (0),
2710                                GEN_INT (0x7)));
2711     }
2712   
2713   DONE;
2716 (define_insn "umodsi3_internal"
2717   [(set (match_operand:SI 0 "register_operand" "=h")
2718         (umod:SI (match_operand:SI 1 "register_operand" "d")
2719                  (match_operand:SI 2 "nonmemory_operand" "di")))
2720    (clobber (match_scratch:SI 3 "=l"))
2721    (clobber (match_scratch:SI 4 "=a"))]
2722   "!optimize"
2723   "divu\\t$0,%1,%2"
2724   [(set_attr "type"     "idiv")
2725    (set_attr "mode"     "SI")])
2727 (define_expand "umoddi3"
2728   [(set (match_operand:DI 0 "register_operand" "=h")
2729         (umod:DI (match_operand:DI 1 "se_register_operand" "d")
2730                  (match_operand:DI 2 "se_register_operand" "di")))
2731    (clobber (match_scratch:DI 3 "=l"))
2732    (clobber (match_scratch:DI 4 "=a"))]
2733   "TARGET_64BIT && !optimize"
2734   "
2736   emit_insn (gen_umoddi3_internal (operands[0], operands[1], operands[2]));
2737   if (!TARGET_NO_CHECK_ZERO_DIV)
2738     {
2739       emit_insn (gen_div_trap (operands[2],
2740                                GEN_INT (0),
2741                                GEN_INT (0x7)));
2742     }
2743   
2744   DONE;
2747 (define_insn "umoddi3_internal"
2748   [(set (match_operand:DI 0 "register_operand" "=h")
2749         (umod:DI (match_operand:DI 1 "se_register_operand" "d")
2750                  (match_operand:DI 2 "se_nonmemory_operand" "di")))
2751    (clobber (match_scratch:SI 3 "=l"))
2752    (clobber (match_scratch:SI 4 "=a"))]
2753   "TARGET_64BIT && !optimize"
2754   "ddivu\\t$0,%1,%2"
2755   [(set_attr "type"     "idiv")
2756    (set_attr "mode"     "DI")])
2759 ;;  ....................
2761 ;;      SQUARE ROOT
2763 ;;  ....................
2765 (define_insn "sqrtdf2"
2766   [(set (match_operand:DF 0 "register_operand" "=f")
2767         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2768   "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
2769   "sqrt.d\\t%0,%1"
2770   [(set_attr "type"     "fsqrt")
2771    (set_attr "mode"     "DF")])
2773 (define_insn "sqrtsf2"
2774   [(set (match_operand:SF 0 "register_operand" "=f")
2775         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2776   "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
2777   "sqrt.s\\t%0,%1"
2778   [(set_attr "type"     "fsqrt")
2779    (set_attr "mode"     "SF")])
2781 (define_insn ""
2782   [(set (match_operand:DF 0 "register_operand" "=f")
2783         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2784                 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
2785   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_fast_math"
2786   "rsqrt.d\\t%0,%2"
2787   [(set_attr "type"     "fsqrt")
2788    (set_attr "mode"     "DF")])
2790 (define_insn ""
2791   [(set (match_operand:SF 0 "register_operand" "=f")
2792         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2793                 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
2794   "mips_isa >= 4 && TARGET_HARD_FLOAT && flag_fast_math"
2795   "rsqrt.s\\t%0,%2"
2796   [(set_attr "type"     "fsqrt")
2797    (set_attr "mode"     "SF")])
2801 ;;  ....................
2803 ;;      ABSOLUTE VALUE
2805 ;;  ....................
2807 ;; Do not use the integer abs macro instruction, since that signals an
2808 ;; exception on -2147483648 (sigh).
2810 (define_insn "abssi2"
2811   [(set (match_operand:SI 0 "register_operand" "=d")
2812         (abs:SI (match_operand:SI 1 "register_operand" "d")))]
2813   "!TARGET_MIPS16"
2814   "*
2816   dslots_jump_total++;
2817   dslots_jump_filled++;
2818   operands[2] = const0_rtx;
2820   if (REGNO (operands[0]) == REGNO (operands[1]))
2821     {
2822       if (GENERATE_BRANCHLIKELY)
2823         return \"%(bltzl\\t%1,1f\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
2824       else
2825         return \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n%~1:\";
2826     }     
2827   else
2828     return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
2830   [(set_attr "type"     "multi")
2831    (set_attr "mode"     "SI")
2832    (set_attr "length"   "12")])
2834 (define_insn "absdi2"
2835   [(set (match_operand:DI 0 "register_operand" "=d")
2836         (abs:DI (match_operand:DI 1 "se_register_operand" "d")))]
2837   "TARGET_64BIT && !TARGET_MIPS16"
2838   "*
2840   dslots_jump_total++;
2841   dslots_jump_filled++;
2842   operands[2] = const0_rtx;
2844   if (REGNO (operands[0]) == REGNO (operands[1]))
2845     return \"%(bltzl\\t%1,1f\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
2846   else
2847     return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
2849   [(set_attr "type"     "multi")
2850    (set_attr "mode"     "DI")
2851    (set_attr "length"   "12")])
2853 (define_insn "absdf2"
2854   [(set (match_operand:DF 0 "register_operand" "=f")
2855         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
2856   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2857   "abs.d\\t%0,%1"
2858   [(set_attr "type"     "fabs")
2859    (set_attr "mode"     "DF")])
2861 (define_insn "abssf2"
2862   [(set (match_operand:SF 0 "register_operand" "=f")
2863         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2864   "TARGET_HARD_FLOAT"
2865   "abs.s\\t%0,%1"
2866   [(set_attr "type"     "fabs")
2867    (set_attr "mode"     "SF")])
2871 ;;  ....................
2873 ;;      FIND FIRST BIT INSTRUCTION
2875 ;;  ....................
2878 (define_insn "ffssi2"
2879   [(set (match_operand:SI 0 "register_operand" "=&d")
2880         (ffs:SI (match_operand:SI 1 "register_operand" "d")))
2881    (clobber (match_scratch:SI 2 "=&d"))
2882    (clobber (match_scratch:SI 3 "=&d"))]
2883   "!TARGET_MIPS16"
2884   "*
2886   dslots_jump_total += 2;
2887   dslots_jump_filled += 2;
2888   operands[4] = const0_rtx;
2890   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2891     return \"%(\\
2892 move\\t%0,%z4\\n\\
2893 \\tbeq\\t%1,%z4,2f\\n\\
2894 %~1:\\tand\\t%2,%1,0x0001\\n\\
2895 \\taddu\\t%0,%0,1\\n\\
2896 \\tbeq\\t%2,%z4,1b\\n\\
2897 \\tsrl\\t%1,%1,1\\n\\
2898 %~2:%)\";
2900   return \"%(\\
2901 move\\t%0,%z4\\n\\
2902 \\tmove\\t%3,%1\\n\\
2903 \\tbeq\\t%3,%z4,2f\\n\\
2904 %~1:\\tand\\t%2,%3,0x0001\\n\\
2905 \\taddu\\t%0,%0,1\\n\\
2906 \\tbeq\\t%2,%z4,1b\\n\\
2907 \\tsrl\\t%3,%3,1\\n\\
2908 %~2:%)\";
2910   [(set_attr "type"     "multi")
2911    (set_attr "mode"     "SI")
2912    (set_attr "length"   "12")])
2914 (define_insn "ffsdi2"
2915   [(set (match_operand:DI 0 "register_operand" "=&d")
2916         (ffs:DI (match_operand:DI 1 "se_register_operand" "d")))
2917    (clobber (match_scratch:DI 2 "=&d"))
2918    (clobber (match_scratch:DI 3 "=&d"))]
2919   "TARGET_64BIT && !TARGET_MIPS16"
2920   "*
2922   dslots_jump_total += 2;
2923   dslots_jump_filled += 2;
2924   operands[4] = const0_rtx;
2926   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2927     return \"%(\\
2928 move\\t%0,%z4\\n\\
2929 \\tbeq\\t%1,%z4,2f\\n\\
2930 %~1:\\tand\\t%2,%1,0x0001\\n\\
2931 \\tdaddu\\t%0,%0,1\\n\\
2932 \\tbeq\\t%2,%z4,1b\\n\\
2933 \\tdsrl\\t%1,%1,1\\n\\
2934 %~2:%)\";
2936   return \"%(\\
2937 move\\t%0,%z4\\n\\
2938 \\tmove\\t%3,%1\\n\\
2939 \\tbeq\\t%3,%z4,2f\\n\\
2940 %~1:\\tand\\t%2,%3,0x0001\\n\\
2941 \\tdaddu\\t%0,%0,1\\n\\
2942 \\tbeq\\t%2,%z4,1b\\n\\
2943 \\tdsrl\\t%3,%3,1\\n\\
2944 %~2:%)\";
2946   [(set_attr "type"     "multi")
2947    (set_attr "mode"     "DI")
2948    (set_attr "length"   "24")])
2952 ;;  ....................
2954 ;;      NEGATION and ONE'S COMPLEMENT
2956 ;;  ....................
2958 (define_insn "negsi2"
2959   [(set (match_operand:SI 0 "register_operand" "=d")
2960         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2961   ""
2962   "*
2964   if (TARGET_MIPS16)
2965     return \"neg\\t%0,%1\";
2966   operands[2] = const0_rtx;
2967   return \"subu\\t%0,%z2,%1\";
2969   [(set_attr "type"     "arith")
2970    (set_attr "mode"     "SI")])
2972 (define_expand "negdi2"
2973   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
2974                    (neg:DI (match_operand:DI 1 "se_register_operand" "d")))
2975               (clobber (match_dup 2))])]
2976   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
2977   "
2979   if (TARGET_64BIT)
2980     {
2981       emit_insn (gen_negdi2_internal_2 (operands[0], operands[1]));
2982       DONE;
2983     }
2985   operands[2] = gen_reg_rtx (SImode);
2988 (define_insn "negdi2_internal"
2989   [(set (match_operand:DI 0 "register_operand" "=d")
2990         (neg:DI (match_operand:DI 1 "register_operand" "d")))
2991    (clobber (match_operand:SI 2 "register_operand" "=d"))]
2992   "! TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
2993   "*
2995   operands[3] = const0_rtx;
2996   return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\";
2998   [(set_attr "type"     "darith")
2999    (set_attr "mode"     "DI")
3000    (set_attr "length"   "16")])
3002 (define_insn "negdi2_internal_2"
3003   [(set (match_operand:DI 0 "register_operand" "=d")
3004         (neg:DI (match_operand:DI 1 "se_register_operand" "d")))]
3005   "TARGET_64BIT && !TARGET_MIPS16"
3006   "*
3008   operands[2] = const0_rtx;
3009   return \"dsubu\\t%0,%z2,%1\";
3011   [(set_attr "type"     "arith")
3012    (set_attr "mode"     "DI")])
3014 (define_insn "negdf2"
3015   [(set (match_operand:DF 0 "register_operand" "=f")
3016         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
3017   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3018   "neg.d\\t%0,%1"
3019   [(set_attr "type"     "fneg")
3020    (set_attr "mode"     "DF")])
3022 (define_insn "negsf2"
3023   [(set (match_operand:SF 0 "register_operand" "=f")
3024         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
3025   "TARGET_HARD_FLOAT"
3026   "neg.s\\t%0,%1"
3027   [(set_attr "type"     "fneg")
3028    (set_attr "mode"     "SF")])
3030 (define_insn "one_cmplsi2"
3031   [(set (match_operand:SI 0 "register_operand" "=d")
3032         (not:SI (match_operand:SI 1 "register_operand" "d")))]
3033   ""
3034   "*
3036   if (TARGET_MIPS16)
3037     return \"not\\t%0,%1\";
3038   operands[2] = const0_rtx;
3039   return \"nor\\t%0,%z2,%1\";
3041   [(set_attr "type"     "arith")
3042    (set_attr "mode"     "SI")])
3044 (define_insn "one_cmpldi2"
3045   [(set (match_operand:DI 0 "register_operand" "=d")
3046         (not:DI (match_operand:DI 1 "se_register_operand" "d")))]
3047   ""
3048   "*
3050   if (TARGET_MIPS16)
3051     {
3052       if (TARGET_64BIT)
3053         return \"not\\t%0,%1\";
3054       return \"not\\t%M0,%M1\;not\\t%L0,%L1\";
3055     }
3056   operands[2] = const0_rtx;
3057   if (TARGET_64BIT)
3058     return \"nor\\t%0,%z2,%1\";
3059   return \"nor\\t%M0,%z2,%M1\;nor\\t%L0,%z2,%L1\";
3061   [(set_attr "type"     "darith")
3062    (set_attr "mode"     "DI")
3063    (set (attr "length")
3064         (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3065                        (const_int 4)
3066                        (const_int 8)))])
3068 (define_split
3069   [(set (match_operand:DI 0 "register_operand" "")
3070         (not:DI (match_operand:DI 1 "register_operand" "")))]
3071   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3072    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3073    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
3075   [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0)))
3076    (set (subreg:SI (match_dup 0) 1) (not:SI (subreg:SI (match_dup 1) 1)))]
3077   "")
3081 ;;  ....................
3083 ;;      LOGICAL
3085 ;;  ....................
3088 ;; Many of these instructions uses trivial define_expands, because we
3089 ;; want to use a different set of constraints when TARGET_MIPS16.
3091 (define_expand "andsi3"
3092   [(set (match_operand:SI 0 "register_operand" "=d,d")
3093         (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3094                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3095   ""
3096   "
3098   if (TARGET_MIPS16)
3099     operands[2] = force_reg (SImode, operands[2]);
3102 (define_insn ""
3103   [(set (match_operand:SI 0 "register_operand" "=d,d")
3104         (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3105                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3106   "!TARGET_MIPS16"
3107   "@
3108    and\\t%0,%1,%2
3109    andi\\t%0,%1,%x2"
3110   [(set_attr "type"     "arith")
3111    (set_attr "mode"     "SI")])
3113 (define_insn ""
3114   [(set (match_operand:SI 0 "register_operand" "=d")
3115         (and:SI (match_operand:SI 1 "register_operand" "%0")
3116                 (match_operand:SI 2 "register_operand" "d")))]
3117   "TARGET_MIPS16"
3118   "and\\t%0,%2"
3119   [(set_attr "type"     "arith")
3120    (set_attr "mode"     "SI")])
3122 (define_expand "anddi3"
3123   [(set (match_operand:DI 0 "register_operand" "=d")
3124         (and:DI (match_operand:DI 1 "se_register_operand" "d")
3125                 (match_operand:DI 2 "se_register_operand" "d")))]
3126   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3127   "
3129   if (TARGET_MIPS16)
3130     operands[2] = force_reg (DImode, operands[2]);
3133 (define_insn ""
3134   [(set (match_operand:DI 0 "register_operand" "=d")
3135         (and:DI (match_operand:DI 1 "se_register_operand" "d")
3136                 (match_operand:DI 2 "se_register_operand" "d")))]
3137   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3138   "*
3140   if (TARGET_64BIT)
3141     return \"and\\t%0,%1,%2\";
3142   return \"and\\t%M0,%M1,%M2\;and\\t%L0,%L1,%L2\";
3144   [(set_attr "type"     "darith")
3145    (set_attr "mode"     "DI")
3146    (set (attr "length")
3147         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3148                        (const_int 4)
3149                        (const_int 8)))])
3151 (define_insn ""
3152   [(set (match_operand:DI 0 "register_operand" "=d")
3153         (and:DI (match_operand:DI 1 "se_register_operand" "0")
3154                 (match_operand:DI 2 "se_register_operand" "d")))]
3155   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
3156   "*
3158   if (TARGET_64BIT)
3159     return \"and\\t%0,%2\";
3160   return \"and\\t%M0,%M2\;and\\t%L0,%L2\";
3162   [(set_attr "type"     "darith")
3163    (set_attr "mode"     "DI")
3164    (set (attr "length")
3165         (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3166                        (const_int 4)
3167                        (const_int 8)))])
3169 (define_split
3170   [(set (match_operand:DI 0 "register_operand" "")
3171         (and:DI (match_operand:DI 1 "register_operand" "")
3172                 (match_operand:DI 2 "register_operand" "")))]
3173   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3174    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3175    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3176    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3178   [(set (subreg:SI (match_dup 0) 0) (and:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3179    (set (subreg:SI (match_dup 0) 1) (and:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
3180   "")
3182 (define_insn "anddi3_internal1"
3183   [(set (match_operand:DI 0 "register_operand" "=d,d")
3184         (and:DI (match_operand:DI 1 "se_register_operand" "%d,d")
3185                 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
3186   "TARGET_64BIT && !TARGET_MIPS16"
3187   "@
3188    and\\t%0,%1,%2
3189    andi\\t%0,%1,%x2"
3190   [(set_attr "type"     "arith")
3191    (set_attr "mode"     "DI")])
3193 (define_expand "iorsi3"
3194   [(set (match_operand:SI 0 "register_operand" "=d,d")
3195         (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3196                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3197   ""
3198   "
3200   if (TARGET_MIPS16)
3201     operands[2] = force_reg (SImode, operands[2]);
3204 (define_insn ""
3205   [(set (match_operand:SI 0 "register_operand" "=d,d")
3206         (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3207                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3208   "!TARGET_MIPS16"
3209   "@
3210    or\\t%0,%1,%2
3211    ori\\t%0,%1,%x2"
3212   [(set_attr "type"     "arith")
3213    (set_attr "mode"     "SI")])
3215 (define_insn ""
3216   [(set (match_operand:SI 0 "register_operand" "=d")
3217         (ior:SI (match_operand:SI 1 "register_operand" "%0")
3218                 (match_operand:SI 2 "register_operand" "d")))]
3219   "TARGET_MIPS16"
3220   "or\\t%0,%2"
3221   [(set_attr "type"     "arith")
3222    (set_attr "mode"     "SI")])
3224 ;;; ??? There is no iordi3 pattern which accepts 'K' constants when
3225 ;;; TARGET_64BIT
3227 (define_expand "iordi3"
3228   [(set (match_operand:DI 0 "register_operand" "=d")
3229         (ior:DI (match_operand:DI 1 "se_register_operand" "d")
3230                 (match_operand:DI 2 "se_register_operand" "d")))]
3231   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3232   "")
3234 (define_insn ""
3235   [(set (match_operand:DI 0 "register_operand" "=d")
3236         (ior:DI (match_operand:DI 1 "se_register_operand" "d")
3237                 (match_operand:DI 2 "se_register_operand" "d")))]
3238   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3239   "*
3241   if (TARGET_64BIT)
3242     return \"or\\t%0,%1,%2\";
3243   return \"or\\t%M0,%M1,%M2\;or\\t%L0,%L1,%L2\";
3245   [(set_attr "type"     "darith")
3246    (set_attr "mode"     "DI")
3247    (set (attr "length")
3248         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3249                        (const_int 4)
3250                        (const_int 8)))])
3252 (define_insn ""
3253   [(set (match_operand:DI 0 "register_operand" "=d")
3254         (ior:DI (match_operand:DI 1 "se_register_operand" "0")
3255                 (match_operand:DI 2 "se_register_operand" "d")))]
3256   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
3257   "*
3259   if (TARGET_64BIT)
3260     return \"or\\t%0,%2\";
3261   return \"or\\t%M0,%M2\;or\\t%L0,%L2\";
3263   [(set_attr "type"     "darith")
3264    (set_attr "mode"     "DI")
3265    (set (attr "length")
3266         (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
3267                        (const_int 4)
3268                        (const_int 8)))])
3270 (define_split
3271   [(set (match_operand:DI 0 "register_operand" "")
3272         (ior:DI (match_operand:DI 1 "register_operand" "")
3273                 (match_operand:DI 2 "register_operand" "")))]
3274   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3275    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3276    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3277    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3279   [(set (subreg:SI (match_dup 0) 0) (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3280    (set (subreg:SI (match_dup 0) 1) (ior:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
3281   "")
3283 (define_expand "xorsi3"
3284   [(set (match_operand:SI 0 "register_operand" "=d,d")
3285         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3286                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3287   ""
3288   "")
3290 (define_insn ""
3291   [(set (match_operand:SI 0 "register_operand" "=d,d")
3292         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3293                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3294   "!TARGET_MIPS16"
3295   "@
3296    xor\\t%0,%1,%2
3297    xori\\t%0,%1,%x2"
3298   [(set_attr "type"     "arith")
3299    (set_attr "mode"     "SI")])
3301 (define_insn ""
3302   [(set (match_operand:SI 0 "register_operand" "=d,t,t")
3303         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
3304                 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
3305   "TARGET_MIPS16"
3306   "@
3307    xor\\t%0,%2
3308    cmpi\\t%1,%2
3309    cmp\\t%1,%2"
3310   [(set_attr "type"     "arith")
3311    (set_attr "mode"     "SI")
3312    (set_attr_alternative "length"
3313                 [(const_int 4)
3314                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3315                                (const_int 4)
3316                                (const_int 8))
3317                  (const_int 4)])])
3319 ;; ??? If delete the 32-bit long long patterns, then could merge this with
3320 ;; the following xordi3_internal pattern.
3321 (define_expand "xordi3"
3322   [(set (match_operand:DI 0 "register_operand" "=d")
3323         (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3324                 (match_operand:DI 2 "se_register_operand" "d")))]
3325   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3326   "")
3328 (define_insn ""
3329   [(set (match_operand:DI 0 "register_operand" "=d")
3330         (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3331                 (match_operand:DI 2 "se_register_operand" "d")))]
3332   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3333   "*
3335   if (TARGET_64BIT)
3336     return \"xor\\t%0,%1,%2\";
3337   return \"xor\\t%M0,%M1,%M2\;xor\\t%L0,%L1,%L2\";
3339   [(set_attr "type"     "darith")
3340    (set_attr "mode"     "DI")
3341    (set (attr "length")
3342         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3343                        (const_int 4)
3344                        (const_int 8)))])
3346 (define_insn ""
3347   [(set (match_operand:DI 0 "register_operand" "=d")
3348         (xor:DI (match_operand:DI 1 "se_register_operand" "0")
3349                 (match_operand:DI 2 "se_register_operand" "d")))]
3350   "!TARGET_64BIT && TARGET_MIPS16"
3351   "xor\\t%M0,%M2\;xor\\t%L0,%L2"
3352   [(set_attr "type"     "darith")
3353    (set_attr "mode"     "DI")
3354    (set_attr "length"   "8")])
3356 (define_insn ""
3357   [(set (match_operand:DI 0 "register_operand" "=d,t,t")
3358         (xor:DI (match_operand:DI 1 "se_register_operand" "%0,d,d")
3359                 (match_operand:DI 2 "se_uns_arith_operand" "d,K,d")))]
3360   "TARGET_64BIT && TARGET_MIPS16"
3361   "@
3362    xor\\t%0,%2
3363    cmpi\\t%1,%2
3364    cmp\\t%1,%2"
3365   [(set_attr "type"     "arith")
3366    (set_attr "mode"     "DI")
3367    (set_attr_alternative "length"
3368                 [(const_int 4)
3369                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3370                                (const_int 4)
3371                                (const_int 8))
3372                  (const_int 4)])])
3374 (define_split
3375   [(set (match_operand:DI 0 "register_operand" "")
3376         (xor:DI (match_operand:DI 1 "register_operand" "")
3377                 (match_operand:DI 2 "register_operand" "")))]
3378   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3379    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3380    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3381    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3383   [(set (subreg:SI (match_dup 0) 0) (xor:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3384    (set (subreg:SI (match_dup 0) 1) (xor:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
3385   "")
3387 (define_insn "xordi3_immed"
3388   [(set (match_operand:DI 0 "register_operand" "=d")
3389         (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3390                 (match_operand:DI 2 "se_uns_arith_operand" "K")))]
3391   "TARGET_64BIT && !TARGET_MIPS16"
3392   "xori\\t%0,%1,%x2"
3393   [(set_attr "type"     "arith")
3394    (set_attr "mode"     "DI")])
3396 (define_insn "*norsi3"
3397   [(set (match_operand:SI 0 "register_operand" "=d")
3398         (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
3399                 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
3400   "!TARGET_MIPS16"
3401   "nor\\t%0,%z1,%z2"
3402   [(set_attr "type"     "arith")
3403    (set_attr "mode"     "SI")])
3405 (define_insn "*nordi3"
3406   [(set (match_operand:DI 0 "register_operand" "=d")
3407         (and:DI (not:DI (match_operand:DI 1 "se_register_operand" "d"))
3408                 (not:DI (match_operand:DI 2 "se_register_operand" "d"))))]
3409   "!TARGET_MIPS16"
3410   "*
3412   if (TARGET_64BIT)
3413     return \"nor\\t%0,%z1,%z2\";
3414   return \"nor\\t%M0,%M1,%M2\;nor\\t%L0,%L1,%L2\";
3416   [(set_attr "type"     "darith")
3417    (set_attr "mode"     "DI")
3418    (set (attr "length")
3419         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3420                        (const_int 4)
3421                        (const_int 8)))])
3423 (define_split
3424   [(set (match_operand:DI 0 "register_operand" "")
3425         (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
3426                 (not:DI (match_operand:DI 2 "register_operand" ""))))]
3427   "reload_completed && !TARGET_MIPS16 && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3428    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3429    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3430    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3432   [(set (subreg:SI (match_dup 0) 0) (and:SI (not:SI (subreg:SI (match_dup 1) 0)) (not:SI (subreg:SI (match_dup 2) 0))))
3433    (set (subreg:SI (match_dup 0) 1) (and:SI (not:SI (subreg:SI (match_dup 1) 1)) (not:SI (subreg:SI (match_dup 2) 1))))]
3434   "")
3437 ;;  ....................
3439 ;;      TRUNCATION
3441 ;;  ....................
3443 (define_insn "truncdfsf2"
3444   [(set (match_operand:SF 0 "register_operand" "=f")
3445         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3446   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3447   "cvt.s.d\\t%0,%1"
3448   [(set_attr "type"     "fcvt")
3449    (set_attr "mode"     "SF")])
3451 (define_insn "truncdisi2"
3452   [(set (match_operand:SI 0 "register_operand" "=d")
3453         (truncate:SI (match_operand:DI 1 "se_register_operand" "d")))]
3454   "TARGET_64BIT"
3455   "*
3457   if (TARGET_MIPS16)
3458     return \"dsll\\t%0,%1,32\;dsra\\t%0,32\";
3459   return \"dsll\\t%0,%1,32\;dsra\\t%0,%0,32\";
3461   [(set_attr "type"     "darith")
3462    (set_attr "mode"     "SI")
3463    (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3464                                       (const_int 8)
3465                                       (const_int 16)))])
3467 (define_insn "truncdihi2"
3468   [(set (match_operand:HI 0 "register_operand" "=d")
3469         (truncate:HI (match_operand:DI 1 "se_register_operand" "d")))]
3470   "TARGET_64BIT"
3471   "*
3473   if (TARGET_MIPS16)
3474     return \"dsll\\t%0,%1,48\;dsra\\t%0,48\";
3475   return \"andi\\t%0,%1,0xffff\";
3477   [(set_attr "type"     "darith")
3478    (set_attr "mode"     "HI")
3479    (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3480                                       (const_int 4)
3481                                       (const_int 16)))])
3482 (define_insn "truncdiqi2"
3483   [(set (match_operand:QI 0 "register_operand" "=d")
3484         (truncate:QI (match_operand:DI 1 "se_register_operand" "d")))]
3485   "TARGET_64BIT"
3486   "*
3488   if (TARGET_MIPS16)
3489     return \"dsll\\t%0,%1,56\;dsra\\t%0,56\";
3490   return \"andi\\t%0,%1,0x00ff\"; 
3492   [(set_attr "type"     "darith")
3493    (set_attr "mode"     "QI")
3494    (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3495                                       (const_int 4)
3496                                       (const_int 16)))])
3498 ;; Combiner patterns to optimize shift/truncate combinations.
3499 (define_insn ""
3500   [(set (match_operand:SI 0 "register_operand" "=d")
3501         (truncate:SI (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
3502                                   (match_operand:DI 2 "small_int" "I"))))]
3503   "TARGET_64BIT && !TARGET_MIPS16"
3504   "*
3506   int shift_amt = INTVAL (operands[2]) & 0x3f;
3508   if (shift_amt < 32)
3509     {
3510       operands[2] = GEN_INT (32 - shift_amt);
3511       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3512     }
3513   else
3514     {
3515       operands[2] = GEN_INT (shift_amt);
3516       return \"dsra\\t%0,%1,%2\";
3517     }
3519   [(set_attr "type"     "darith")
3520    (set_attr "mode"     "SI")
3521    (set_attr "length"   "8")])
3522         
3523 (define_insn ""
3524   [(set (match_operand:SI 0 "register_operand" "=d")
3525         (truncate:SI (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
3526                                   (match_operand:DI 2 "small_int" "I"))))]
3527   "TARGET_64BIT && !TARGET_MIPS16"
3528   "*
3530   int shift_amt = INTVAL (operands[2]) & 0x3f;
3532   if (shift_amt < 32)
3533     {
3534       operands[2] = GEN_INT (32 - shift_amt);
3535       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3536     }
3537   else if (shift_amt == 32)
3538     return \"dsra\\t%0,%1,32\";
3539   else
3540     {
3541       operands[2] = GEN_INT (shift_amt);
3542       return \"dsrl\\t%0,%1,%2\";
3543     }
3545   [(set_attr "type"     "darith")
3546    (set_attr "mode"     "SI")
3547    (set_attr "length"   "8")])
3549 (define_insn ""
3550   [(set (match_operand:SI 0 "register_operand" "=d")
3551         (truncate:SI (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
3552                                 (match_operand:DI 2 "small_int" "I"))))]
3553   "TARGET_64BIT"
3554   "*
3556   int shift_amt = INTVAL (operands[2]) & 0x3f;
3558   if (shift_amt < 32)
3559     {
3560       operands[2] = GEN_INT (32 + shift_amt);
3561       if (TARGET_MIPS16)
3562         return \"dsll\\t%0,%1,%2\;dsra\\t%0,32\";
3563       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3564     }
3565   else
3566     return \"move\\t%0,%.\";
3568   [(set_attr "type"     "darith")
3569    (set_attr "mode"     "SI")
3570    (set_attr "length"   "8")])
3572 ;; Combiner patterns to optimize truncate/zero_extend combinations.
3574 (define_insn ""
3575   [(set (match_operand:SI 0 "register_operand" "=d")
3576         (zero_extend:SI (truncate:HI
3577                          (match_operand:DI 1 "se_register_operand" "d"))))]
3578   "TARGET_64BIT && !TARGET_MIPS16"
3579   "andi\\t%0,%1,0xffff"
3580   [(set_attr "type"     "darith")
3581    (set_attr "mode"     "SI")])
3583 (define_insn ""
3584   [(set (match_operand:SI 0 "register_operand" "=d")
3585         (zero_extend:SI (truncate:QI
3586                          (match_operand:DI 1 "se_register_operand" "d"))))]
3587   "TARGET_64BIT && !TARGET_MIPS16"
3588   "andi\\t%0,%1,0xff"
3589   [(set_attr "type"     "darith")
3590    (set_attr "mode"     "SI")])
3592 (define_insn ""
3593   [(set (match_operand:HI 0 "register_operand" "=d")
3594         (zero_extend:HI (truncate:QI
3595                          (match_operand:DI 1 "se_register_operand" "d"))))]
3596   "TARGET_64BIT && !TARGET_MIPS16"
3597   "andi\\t%0,%1,0xff"
3598   [(set_attr "type"     "darith")
3599    (set_attr "mode"     "HI")])
3602 ;;  ....................
3604 ;;      ZERO EXTENSION
3606 ;;  ....................
3608 ;; Extension insns.
3609 ;; Those for integer source operand are ordered widest source type first.
3611 (define_expand "zero_extendsidi2"
3612   [(set (match_operand:DI 0 "register_operand" "")
3613         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3614   "TARGET_64BIT"
3615   "
3617   if (optimize && GET_CODE (operands[1]) == MEM)
3618     operands[1] = force_not_mem (operands[1]);
3620   if (GET_CODE (operands[1]) != MEM)
3621     {
3622       rtx op1   = gen_lowpart (DImode, operands[1]);
3623       rtx temp  = gen_reg_rtx (DImode);
3624       rtx shift = GEN_INT (32);
3626       emit_insn (gen_ashldi3 (temp, op1, shift));
3627       emit_insn (gen_lshrdi3 (operands[0], temp, shift));
3628       DONE;
3629     }
3632 (define_insn "zero_extendsidi2_internal"
3633   [(set (match_operand:DI 0 "register_operand" "=d,d")
3634         (zero_extend:DI (match_operand:SI 1 "memory_operand" "R,m")))]
3635   "TARGET_64BIT"
3636   "* return mips_move_1word (operands, insn, TRUE);"
3637   [(set_attr "type"     "load")
3638    (set_attr "mode"     "DI")
3639    (set_attr "length"   "4,8")])
3641 (define_expand "zero_extendhisi2"
3642   [(set (match_operand:SI 0 "register_operand" "")
3643         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3644   ""
3645   "
3647   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3648     {
3649       rtx op = gen_lowpart (SImode, operands[1]);
3650       rtx temp = force_reg (SImode, GEN_INT (0xffff));
3652       emit_insn (gen_andsi3 (operands[0], op, temp));
3653       DONE;
3654     }
3657 (define_insn ""
3658   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
3659         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
3660   "!TARGET_MIPS16"
3661   "*
3663   if (which_alternative == 0)
3664     return \"andi\\t%0,%1,0xffff\";
3665   else
3666     return mips_move_1word (operands, insn, TRUE);
3668   [(set_attr "type"     "arith,load,load")
3669    (set_attr "mode"     "SI")
3670    (set_attr "length"   "4,4,8")])
3672 (define_insn ""
3673   [(set (match_operand:SI 0 "register_operand" "=d,d")
3674         (zero_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
3675   "TARGET_MIPS16"
3676   "* return mips_move_1word (operands, insn, TRUE);"
3677   [(set_attr "type"     "load,load")
3678    (set_attr "mode"     "SI")
3679    (set_attr "length"   "4,8")])
3681 (define_expand "zero_extendhidi2"
3682   [(set (match_operand:DI 0 "register_operand" "")
3683         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
3684   "TARGET_64BIT"
3685   "
3687   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3688     {
3689       rtx op = gen_lowpart (DImode, operands[1]);
3690       rtx temp = force_reg (DImode, GEN_INT (0xffff));
3692       emit_insn (gen_anddi3 (operands[0], op, temp));
3693       DONE;
3694     }
3697 (define_insn ""
3698   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
3699         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
3700   "TARGET_64BIT && !TARGET_MIPS16"
3701   "*
3703   if (which_alternative == 0)
3704     return \"andi\\t%0,%1,0xffff\";
3705   else
3706     return mips_move_1word (operands, insn, TRUE);
3708   [(set_attr "type"     "arith,load,load")
3709    (set_attr "mode"     "DI")
3710    (set_attr "length"   "4,4,8")])
3712 (define_insn ""
3713   [(set (match_operand:DI 0 "register_operand" "=d,d")
3714         (zero_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
3715   "TARGET_64BIT && TARGET_MIPS16"
3716   "* return mips_move_1word (operands, insn, TRUE);"
3717   [(set_attr "type"     "load,load")
3718    (set_attr "mode"     "DI")
3719    (set_attr "length"   "4,8")])
3721 (define_expand "zero_extendqihi2"
3722   [(set (match_operand:HI 0 "register_operand" "")
3723         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3724   ""
3725   "
3727   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3728     {
3729       rtx op0 = gen_lowpart (SImode, operands[0]);
3730       rtx op1 = gen_lowpart (SImode, operands[1]);
3731       rtx temp = force_reg (SImode, GEN_INT (0xff));
3733       emit_insn (gen_andsi3 (op0, op1, temp));
3734       DONE;
3735     }
3738 (define_insn ""
3739   [(set (match_operand:HI 0 "register_operand" "=d,d,d")
3740         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
3741   "!TARGET_MIPS16"
3742   "*
3744   if (which_alternative == 0)
3745     return \"andi\\t%0,%1,0x00ff\";
3746   else
3747     return mips_move_1word (operands, insn, TRUE);
3749   [(set_attr "type"     "arith,load,load")
3750    (set_attr "mode"     "HI")
3751    (set_attr "length"   "4,4,8")])
3753 (define_insn ""
3754   [(set (match_operand:HI 0 "register_operand" "=d,d")
3755         (zero_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
3756   "TARGET_MIPS16"
3757   "* return mips_move_1word (operands, insn, TRUE);"
3758   [(set_attr "type"     "load,load")
3759    (set_attr "mode"     "HI")
3760    (set_attr "length"   "4,8")])
3762 (define_expand "zero_extendqisi2"
3763   [(set (match_operand:SI 0 "register_operand" "")
3764         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3765   ""
3766   "
3768   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3769     {
3770       rtx op = gen_lowpart (SImode, operands[1]);
3771       rtx temp = force_reg (SImode, GEN_INT (0xff));
3773       emit_insn (gen_andsi3 (operands[0], op, temp));
3774       DONE;
3775     }
3778 (define_insn ""
3779   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
3780         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
3781   "!TARGET_MIPS16"
3782   "*
3784   if (which_alternative == 0)
3785     return \"andi\\t%0,%1,0x00ff\";
3786   else
3787     return mips_move_1word (operands, insn, TRUE);
3789   [(set_attr "type"     "arith,load,load")
3790    (set_attr "mode"     "SI")
3791    (set_attr "length"   "4,4,8")])
3793 (define_insn ""
3794   [(set (match_operand:SI 0 "register_operand" "=d,d")
3795         (zero_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
3796   "TARGET_MIPS16"
3797   "* return mips_move_1word (operands, insn, TRUE);"
3798   [(set_attr "type"     "load,load")
3799    (set_attr "mode"     "SI")
3800    (set_attr "length"   "4,8")])
3802 (define_expand "zero_extendqidi2"
3803   [(set (match_operand:DI 0 "register_operand" "")
3804         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
3805   "TARGET_64BIT"
3806   "
3808   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3809     {
3810       rtx op = gen_lowpart (DImode, operands[1]);
3811       rtx temp = force_reg (DImode, GEN_INT (0xff));
3813       emit_insn (gen_anddi3 (operands[0], op, temp));
3814       DONE;
3815     }
3818 (define_insn ""
3819   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
3820         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
3821   "TARGET_64BIT && !TARGET_MIPS16"
3822   "*
3824   if (which_alternative == 0)
3825     return \"andi\\t%0,%1,0x00ff\";
3826   else
3827     return mips_move_1word (operands, insn, TRUE);
3829   [(set_attr "type"     "arith,load,load")
3830    (set_attr "mode"     "DI")
3831    (set_attr "length"   "4,4,8")])
3833 ;; These can be created when a paradoxical subreg operand with an implicit
3834 ;; sign_extend operator is reloaded.  Because of the subreg, this is really
3835 ;; a zero extend.
3836 ;; ??? It might be possible to eliminate the need for these patterns by adding
3837 ;; more support to reload for implicit sign_extend operators.
3838 (define_insn "*paradoxical_extendhidi2"
3839   [(set (match_operand:DI 0 "register_operand" "=d,d")
3840         (sign_extend:DI
3841          (subreg:SI (match_operand:HI 1 "memory_operand" "R,m") 0)))]
3842   "TARGET_64BIT"
3843   "*
3845   return mips_move_1word (operands, insn, TRUE);
3847   [(set_attr "type"     "load,load")
3848    (set_attr "mode"     "DI")
3849    (set_attr "length"   "4,8")])
3851 (define_insn ""
3852   [(set (match_operand:DI 0 "register_operand" "=d,d")
3853         (zero_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
3854   "TARGET_64BIT && TARGET_MIPS16"
3855   "* return mips_move_1word (operands, insn, TRUE);"
3856   [(set_attr "type"     "load,load")
3857    (set_attr "mode"     "DI")
3858    (set_attr "length"   "4,8")])
3861 ;;  ....................
3863 ;;      SIGN EXTENSION
3865 ;;  ....................
3867 ;; Extension insns.
3868 ;; Those for integer source operand are ordered widest source type first.
3870 ;; In 64 bit mode, 32 bit values in general registers are always
3871 ;; correctly sign extended.  That means that if the target is a
3872 ;; general register, we can sign extend from SImode to DImode just by
3873 ;; doing a move.
3875 (define_insn "extendsidi2"
3876   [(set (match_operand:DI 0 "register_operand" "=d,y,d,*d,d,d")
3877         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,d,y,*x,R,m")))]
3878   "TARGET_64BIT"
3879   "* return mips_move_1word (operands, insn, FALSE);"
3880   [(set_attr "type"     "move,move,move,hilo,load,load")
3881    (set_attr "mode"     "DI")
3882    (set_attr "length"   "4,4,4,4,4,8")])
3884 ;; These patterns originally accepted general_operands, however, slightly
3885 ;; better code is generated by only accepting register_operands, and then
3886 ;; letting combine generate the lh and lb insns.
3888 (define_expand "extendhidi2"
3889   [(set (match_operand:DI 0 "register_operand" "")
3890         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
3891   "TARGET_64BIT"
3892   "
3894   if (optimize && GET_CODE (operands[1]) == MEM)
3895     operands[1] = force_not_mem (operands[1]);
3897   if (GET_CODE (operands[1]) != MEM)
3898     {
3899       rtx op1   = gen_lowpart (DImode, operands[1]);
3900       rtx temp  = gen_reg_rtx (DImode);
3901       rtx shift = GEN_INT (48);
3903       emit_insn (gen_ashldi3 (temp, op1, shift));
3904       emit_insn (gen_ashrdi3 (operands[0], temp, shift));
3905       DONE;
3906     }
3909 (define_insn "extendhidi2_internal"
3910   [(set (match_operand:DI 0 "register_operand" "=d,d")
3911         (sign_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
3912   "TARGET_64BIT"
3913   "* return mips_move_1word (operands, insn, FALSE);"
3914   [(set_attr "type"     "load")
3915    (set_attr "mode"     "DI")
3916    (set_attr "length"   "4,8")])
3918 (define_expand "extendhisi2"
3919   [(set (match_operand:SI 0 "register_operand" "")
3920         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3921   ""
3922   "
3924   if (optimize && GET_CODE (operands[1]) == MEM)
3925     operands[1] = force_not_mem (operands[1]);
3927   if (GET_CODE (operands[1]) != MEM)
3928     {
3929       rtx op1   = gen_lowpart (SImode, operands[1]);
3930       rtx temp  = gen_reg_rtx (SImode);
3931       rtx shift = GEN_INT (16);
3933       emit_insn (gen_ashlsi3 (temp, op1, shift));
3934       emit_insn (gen_ashrsi3 (operands[0], temp, shift));
3935       DONE;
3936     }
3939 (define_insn "extendhisi2_internal"
3940   [(set (match_operand:SI 0 "register_operand" "=d,d")
3941         (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
3942   ""
3943   "* return mips_move_1word (operands, insn, FALSE);"
3944   [(set_attr "type"     "load")
3945    (set_attr "mode"     "SI")
3946    (set_attr "length"   "4,8")])
3948 (define_expand "extendqihi2"
3949   [(set (match_operand:HI 0 "register_operand" "")
3950         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3951   ""
3952   "
3954   if (optimize && GET_CODE (operands[1]) == MEM)
3955     operands[1] = force_not_mem (operands[1]);
3957   if (GET_CODE (operands[1]) != MEM)
3958     {
3959       rtx op0   = gen_lowpart (SImode, operands[0]);
3960       rtx op1   = gen_lowpart (SImode, operands[1]);
3961       rtx temp  = gen_reg_rtx (SImode);
3962       rtx shift = GEN_INT (24);
3964       emit_insn (gen_ashlsi3 (temp, op1, shift));
3965       emit_insn (gen_ashrsi3 (op0, temp, shift));
3966       DONE;
3967     }
3970 (define_insn "extendqihi2_internal"
3971   [(set (match_operand:HI 0 "register_operand" "=d,d")
3972         (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
3973   ""
3974   "* return mips_move_1word (operands, insn, FALSE);"
3975   [(set_attr "type"     "load")
3976    (set_attr "mode"     "SI")
3977    (set_attr "length"   "4,8")])
3980 (define_expand "extendqisi2"
3981   [(set (match_operand:SI 0 "register_operand" "")
3982         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3983   ""
3984   "
3986   if (optimize && GET_CODE (operands[1]) == MEM)
3987     operands[1] = force_not_mem (operands[1]);
3989   if (GET_CODE (operands[1]) != MEM)
3990     {
3991       rtx op1   = gen_lowpart (SImode, operands[1]);
3992       rtx temp  = gen_reg_rtx (SImode);
3993       rtx shift = GEN_INT (24);
3995       emit_insn (gen_ashlsi3 (temp, op1, shift));
3996       emit_insn (gen_ashrsi3 (operands[0], temp, shift));
3997       DONE;
3998     }
4001 (define_insn "extendqisi2_insn"
4002   [(set (match_operand:SI 0 "register_operand" "=d,d")
4003         (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
4004   ""
4005   "* return mips_move_1word (operands, insn, FALSE);"
4006   [(set_attr "type"     "load")
4007    (set_attr "mode"     "SI")
4008    (set_attr "length"   "4,8")])
4010 (define_expand "extendqidi2"
4011   [(set (match_operand:DI 0 "register_operand" "")
4012         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
4013   "TARGET_64BIT"
4014   "
4016   if (optimize && GET_CODE (operands[1]) == MEM)
4017     operands[1] = force_not_mem (operands[1]);
4019   if (GET_CODE (operands[1]) != MEM)
4020     {
4021       rtx op1   = gen_lowpart (DImode, operands[1]);
4022       rtx temp  = gen_reg_rtx (DImode);
4023       rtx shift = GEN_INT (56);
4025       emit_insn (gen_ashldi3 (temp, op1, shift));
4026       emit_insn (gen_ashrdi3 (operands[0], temp, shift));
4027       DONE;
4028     }
4031 (define_insn "extendqidi2_insn"
4032   [(set (match_operand:DI 0 "register_operand" "=d,d")
4033         (sign_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
4034   "TARGET_64BIT"
4035   "* return mips_move_1word (operands, insn, FALSE);"
4036   [(set_attr "type"     "load")
4037    (set_attr "mode"     "DI")
4038    (set_attr "length"   "4,8")])
4041 (define_insn "extendsfdf2"
4042   [(set (match_operand:DF 0 "register_operand" "=f")
4043         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
4044   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4045   "cvt.d.s\\t%0,%1"
4046   [(set_attr "type"     "fcvt")
4047    (set_attr "mode"     "DF")])
4052 ;;  ....................
4054 ;;      CONVERSIONS
4056 ;;  ....................
4058 ;; The SImode scratch register can not be shared with address regs used for
4059 ;; operand zero, because then the address in the move instruction will be
4060 ;; clobbered.  We mark the scratch register as early clobbered to prevent this.
4062 ;; We need the ?X in alternative 1 so that it will be choosen only if the
4063 ;; destination is a floating point register.  Otherwise, alternative 1 can
4064 ;; have lower cost than alternative 0 (because there is one less loser), and
4065 ;; can be choosen when it won't work (because integral reloads into FP
4066 ;; registers are not supported).
4068 (define_insn "fix_truncdfsi2"
4069   [(set (match_operand:SI 0 "general_operand" "=d,*f,R,To")
4070         (fix:SI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
4071    (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
4072    (clobber (match_scratch:DF 3 "=f,?*X,f,f"))]
4073   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4074   "*
4076   rtx xoperands[10];
4078   if (which_alternative == 1)
4079     return \"trunc.w.d %0,%1,%2\";
4081   output_asm_insn (\"trunc.w.d %3,%1,%2\", operands);
4083   xoperands[0] = operands[0];
4084   xoperands[1] = operands[3];
4085   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
4086   return \"\";
4088   [(set_attr "type"     "fcvt")
4089    (set_attr "mode"     "DF")
4090    (set_attr "length"   "44,36,40,44")])
4093 (define_insn "fix_truncsfsi2"
4094   [(set (match_operand:SI 0 "general_operand" "=d,*f,R,To")
4095         (fix:SI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
4096    (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
4097    (clobber (match_scratch:SF 3 "=f,?*X,f,f"))]
4098   "TARGET_HARD_FLOAT"
4099   "*
4101   rtx xoperands[10];
4103   if (which_alternative == 1)
4104     return \"trunc.w.s %0,%1,%2\";
4106   output_asm_insn (\"trunc.w.s %3,%1,%2\", operands);
4108   xoperands[0] = operands[0];
4109   xoperands[1] = operands[3];
4110   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
4111   return \"\";
4113   [(set_attr "type"     "fcvt")
4114    (set_attr "mode"     "SF")
4115    (set_attr "length"   "44,36,40,44")])
4118 ;;; ??? trunc.l.d is mentioned in the appendix of the 1993 r4000/r4600 manuals
4119 ;;; but not in the chapter that describes the FPU.  It is not mentioned at all
4120 ;;; in the 1991 manuals.  The r4000 at Cygnus does not have this instruction.
4122 ;;; Deleting this means that we now need two libgcc2.a libraries.  One for
4123 ;;; the 32 bit calling convention and one for the 64 bit calling convention.
4125 ;;; If this is disabled, then fixuns_truncdfdi2 must be disabled also.
4127 (define_insn "fix_truncdfdi2"
4128   [(set (match_operand:DI 0 "general_operand" "=d,*f,R,To")
4129         (fix:DI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
4130    (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
4131   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4132   "*
4134   rtx xoperands[10];
4136   if (which_alternative == 1)
4137     return \"trunc.l.d %0,%1\";
4139   output_asm_insn (\"trunc.l.d %2,%1\", operands);
4141   xoperands[0] = operands[0];
4142   xoperands[1] = operands[2];
4143   output_asm_insn (mips_move_2words (xoperands, insn, FALSE), xoperands);
4144   return \"\";
4146   [(set_attr "type"     "fcvt")
4147    (set_attr "mode"     "DF")
4148    (set_attr "length"   "8,4,8,12")])
4151 ;;; ??? trunc.l.s is mentioned in the appendix of the 1993 r4000/r4600 manuals
4152 ;;; but not in the chapter that describes the FPU.  It is not mentioned at all
4153 ;;; in the 1991 manuals.  The r4000 at Cygnus does not have this instruction.
4154 (define_insn "fix_truncsfdi2"
4155   [(set (match_operand:DI 0 "general_operand" "=d,*f,R,To")
4156         (fix:DI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
4157    (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
4158   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4159   "*
4161   rtx xoperands[10];
4163   if (which_alternative == 1)
4164     return \"trunc.l.s %0,%1\";
4166   output_asm_insn (\"trunc.l.s %2,%1\", operands);
4168   xoperands[0] = operands[0];
4169   xoperands[1] = operands[2];
4170   output_asm_insn (mips_move_2words (xoperands, insn, FALSE), xoperands);
4171   return \"\";
4173   [(set_attr "type"     "fcvt")
4174    (set_attr "mode"     "SF")
4175    (set_attr "length"   "8,4,8,12")])
4178 (define_insn "floatsidf2"
4179   [(set (match_operand:DF 0 "register_operand" "=f,f,f")
4180         (float:DF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
4181   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4182   "*
4184   dslots_load_total++;
4185   if (GET_CODE (operands[1]) == MEM)
4186     return \"l.s\\t%0,%1%#\;cvt.d.w\\t%0,%0\";
4188   return \"mtc1\\t%1,%0%#\;cvt.d.w\\t%0,%0\";
4190   [(set_attr "type"     "fcvt")
4191    (set_attr "mode"     "DF")
4192    (set_attr "length"   "12,16,12")])
4195 (define_insn "floatdidf2"
4196   [(set (match_operand:DF 0 "register_operand" "=f,f,f")
4197         (float:DF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
4198   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4199   "*
4201   dslots_load_total++;
4202   if (GET_CODE (operands[1]) == MEM)
4203     return \"l.d\\t%0,%1%#\;cvt.d.l\\t%0,%0\";
4205   return \"dmtc1\\t%1,%0%#\;cvt.d.l\\t%0,%0\";
4207   [(set_attr "type"     "fcvt")
4208    (set_attr "mode"     "DF")
4209    (set_attr "length"   "12,16,12")])
4212 (define_insn "floatsisf2"
4213   [(set (match_operand:SF 0 "register_operand" "=f,f,f")
4214         (float:SF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
4215   "TARGET_HARD_FLOAT"
4216   "*
4218   dslots_load_total++;
4219   if (GET_CODE (operands[1]) == MEM)
4220     return \"l.s\\t%0,%1%#\;cvt.s.w\\t%0,%0\";
4222   return \"mtc1\\t%1,%0%#\;cvt.s.w\\t%0,%0\";
4224   [(set_attr "type"     "fcvt")
4225    (set_attr "mode"     "SF")
4226    (set_attr "length"   "12,16,12")])
4229 (define_insn "floatdisf2"
4230   [(set (match_operand:SF 0 "register_operand" "=f,f,f")
4231         (float:SF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
4232   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4233   "*
4235   dslots_load_total++;
4236   if (GET_CODE (operands[1]) == MEM)
4237     return \"l.d\\t%0,%1%#\;cvt.s.l\\t%0,%0\";
4239   return \"dmtc1\\t%1,%0%#\;cvt.s.l\\t%0,%0\";
4241   [(set_attr "type"     "fcvt")
4242    (set_attr "mode"     "SF")
4243    (set_attr "length"   "12,16,12")])
4246 (define_expand "fixuns_truncdfsi2"
4247   [(set (match_operand:SI 0 "register_operand" "")
4248         (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
4249   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4250   "
4252   rtx reg1 = gen_reg_rtx (DFmode);
4253   rtx reg2 = gen_reg_rtx (DFmode);
4254   rtx reg3 = gen_reg_rtx (SImode);
4255   rtx label1 = gen_label_rtx ();
4256   rtx label2 = gen_label_rtx ();
4257   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
4259   if (reg1)                     /* turn off complaints about unreached code */
4260     {
4261       emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
4262       do_pending_stack_adjust ();
4264       emit_insn (gen_cmpdf (operands[1], reg1));
4265       emit_jump_insn (gen_bge (label1));
4267       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
4268       emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
4269                                gen_rtx (LABEL_REF, VOIDmode, label2)));
4270       emit_barrier ();
4272       emit_label (label1);
4273       emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1));
4274       emit_move_insn (reg3, GEN_INT (0x80000000));
4276       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
4277       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4279       emit_label (label2);
4281       /* allow REG_NOTES to be set on last insn (labels don't have enough
4282          fields, and can't be used for REG_NOTES anyway).  */
4283       emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
4284       DONE;
4285     }
4289 (define_expand "fixuns_truncdfdi2"
4290   [(set (match_operand:DI 0 "register_operand" "")
4291         (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
4292   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4293   "
4295   rtx reg1 = gen_reg_rtx (DFmode);
4296   rtx reg2 = gen_reg_rtx (DFmode);
4297   rtx reg3 = gen_reg_rtx (DImode);
4298   rtx label1 = gen_label_rtx ();
4299   rtx label2 = gen_label_rtx ();
4300   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
4302   if (reg1)                     /* turn off complaints about unreached code */
4303     {
4304       emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
4305       do_pending_stack_adjust ();
4307       emit_insn (gen_cmpdf (operands[1], reg1));
4308       emit_jump_insn (gen_bge (label1));
4310       emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
4311       emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
4312                                gen_rtx (LABEL_REF, VOIDmode, label2)));
4313       emit_barrier ();
4315       emit_label (label1);
4316       emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1));
4317       emit_move_insn (reg3, GEN_INT (0x80000000));
4318       emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4320       emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
4321       emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4323       emit_label (label2);
4325       /* allow REG_NOTES to be set on last insn (labels don't have enough
4326          fields, and can't be used for REG_NOTES anyway).  */
4327       emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
4328       DONE;
4329     }
4333 (define_expand "fixuns_truncsfsi2"
4334   [(set (match_operand:SI 0 "register_operand" "")
4335         (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
4336   "TARGET_HARD_FLOAT"
4337   "
4339   rtx reg1 = gen_reg_rtx (SFmode);
4340   rtx reg2 = gen_reg_rtx (SFmode);
4341   rtx reg3 = gen_reg_rtx (SImode);
4342   rtx label1 = gen_label_rtx ();
4343   rtx label2 = gen_label_rtx ();
4344   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
4346   if (reg1)                     /* turn off complaints about unreached code */
4347     {
4348       emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
4349       do_pending_stack_adjust ();
4351       emit_insn (gen_cmpsf (operands[1], reg1));
4352       emit_jump_insn (gen_bge (label1));
4354       emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
4355       emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
4356                                gen_rtx (LABEL_REF, VOIDmode, label2)));
4357       emit_barrier ();
4359       emit_label (label1);
4360       emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1));
4361       emit_move_insn (reg3, GEN_INT (0x80000000));
4363       emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
4364       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4366       emit_label (label2);
4368       /* allow REG_NOTES to be set on last insn (labels don't have enough
4369          fields, and can't be used for REG_NOTES anyway).  */
4370       emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
4371       DONE;
4372     }
4376 (define_expand "fixuns_truncsfdi2"
4377   [(set (match_operand:DI 0 "register_operand" "")
4378         (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
4379   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4380   "
4382   rtx reg1 = gen_reg_rtx (SFmode);
4383   rtx reg2 = gen_reg_rtx (SFmode);
4384   rtx reg3 = gen_reg_rtx (DImode);
4385   rtx label1 = gen_label_rtx ();
4386   rtx label2 = gen_label_rtx ();
4387   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
4389   if (reg1)                     /* turn off complaints about unreached code */
4390     {
4391       emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
4392       do_pending_stack_adjust ();
4394       emit_insn (gen_cmpsf (operands[1], reg1));
4395       emit_jump_insn (gen_bge (label1));
4397       emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
4398       emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
4399                                gen_rtx (LABEL_REF, VOIDmode, label2)));
4400       emit_barrier ();
4402       emit_label (label1);
4403       emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1));
4404       emit_move_insn (reg3, GEN_INT (0x80000000));
4405       emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4407       emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
4408       emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4410       emit_label (label2);
4412       /* allow REG_NOTES to be set on last insn (labels don't have enough
4413          fields, and can't be used for REG_NOTES anyway).  */
4414       emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
4415       DONE;
4416     }
4421 ;;  ....................
4423 ;;      DATA MOVEMENT
4425 ;;  ....................
4427 ;; Bit field extract patterns which use lwl/lwr.
4429 ;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
4430 ;; It isn't clear whether this will give better code.
4432 ;; Only specify the mode operand 1, the rest are assumed to be word_mode.
4433 (define_expand "extv"
4434   [(set (match_operand 0 "register_operand" "")
4435         (sign_extract (match_operand:QI 1 "memory_operand" "")
4436                       (match_operand 2 "immediate_operand" "")
4437                       (match_operand 3 "immediate_operand" "")))]
4438   "!TARGET_MIPS16"
4439   "
4441   /* If the field does not start on a byte boundary, then fail.  */
4442   if (INTVAL (operands[3]) % 8 != 0) 
4443     FAIL;
4445   /* MIPS I and MIPS II can only handle a 32bit field.  */
4446   if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
4447     FAIL;
4449   /* MIPS III and MIPS IV can handle both 32bit and 64bit fields.  */
4450   if (TARGET_64BIT
4451       && INTVAL (operands[2]) != 64
4452       && INTVAL (operands[2]) != 32)
4453     FAIL;
4455   /* This can happen for a 64 bit target, when extracting a value from
4456      a 64 bit union member.  extract_bit_field doesn't verify that our
4457      source matches the predicate, so we force it to be a MEM here.  */
4458   if (GET_CODE (operands[1]) != MEM)
4459     FAIL;
4461   /* Change the mode to BLKmode for aliasing purposes.  */
4462   operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
4464   /* Otherwise, emit a l[wd]l/l[wd]r pair to load the value.  */
4465   if (INTVAL (operands[2]) == 64)
4466     emit_insn (gen_movdi_uld (operands[0], operands[1]));
4467   else
4468     {
4469       if (TARGET_64BIT)
4470         {
4471           operands[0] = gen_lowpart (SImode, operands[0]);
4472           if (operands[0] == NULL_RTX)
4473             FAIL;
4474         }
4475       emit_insn (gen_movsi_ulw (operands[0], operands[1]));
4476     }
4477   DONE;
4480 ;; Only specify the mode operand 1, the rest are assumed to be word_mode.
4481 (define_expand "extzv"
4482   [(set (match_operand 0 "register_operand" "")
4483         (zero_extract (match_operand:QI 1 "memory_operand" "")
4484                       (match_operand 2 "immediate_operand" "")
4485                       (match_operand 3 "immediate_operand" "")))]
4486   "!TARGET_MIPS16"
4487   "
4489   /* If the field does not start on a byte boundary, then fail.  */
4490   if (INTVAL (operands[3]) % 8 != 0) 
4491     FAIL;
4493   /* MIPS I and MIPS II can only handle a 32bit field.  */
4494   if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
4495     FAIL;
4497   /* MIPS III and MIPS IV can handle both 32bit and 64bit fields.  */
4498   if (TARGET_64BIT
4499       && INTVAL (operands[2]) != 64
4500       && INTVAL (operands[2]) != 32)
4501     FAIL;
4503   /* This can happen for a 64 bit target, when extracting a value from
4504      a 64 bit union member.  extract_bit_field doesn't verify that our
4505      source matches the predicate, so we force it to be a MEM here.  */
4506   if (GET_CODE (operands[1]) != MEM)
4507     FAIL;
4509   /* Change the mode to BLKmode for aliasing purposes.  */
4510   operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
4512   /* Otherwise, emit a lwl/lwr pair to load the value.  */
4513   if (INTVAL (operands[2]) == 64)
4514     emit_insn (gen_movdi_uld (operands[0], operands[1]));
4515   else
4516     {
4517       if (TARGET_64BIT)
4518         {
4519           operands[0] = gen_lowpart (SImode, operands[0]);
4520           if (operands[0] == NULL_RTX)
4521             FAIL;
4522         }
4523       emit_insn (gen_movsi_ulw (operands[0], operands[1]));
4524     }
4525   DONE;
4528 ;; Only specify the mode operands 0, the rest are assumed to be word_mode.
4529 (define_expand "insv"
4530   [(set (zero_extract (match_operand:QI 0 "memory_operand" "")
4531                       (match_operand 1 "immediate_operand" "")
4532                       (match_operand 2 "immediate_operand" ""))
4533         (match_operand 3 "register_operand" ""))]
4534   "!TARGET_MIPS16"
4535   "
4537   /* If the field does not start on a byte boundary, then fail.  */
4538   if (INTVAL (operands[2]) % 8 != 0) 
4539     FAIL;
4541   /* MIPS I and MIPS II can only handle a 32bit field.  */
4542   if (!TARGET_64BIT && INTVAL (operands[1]) != 32)
4543     FAIL;
4545   /* MIPS III and MIPS IV can handle both 32bit and 64bit fields.  */
4546   if (TARGET_64BIT
4547       && INTVAL (operands[1]) != 64
4548       && INTVAL (operands[1]) != 32)
4549     FAIL;
4551   /* This can happen for a 64 bit target, when storing into a 32 bit union
4552      member.  store_bit_field doesn't verify that our target matches the
4553      predicate, so we force it to be a MEM here.  */
4554   if (GET_CODE (operands[0]) != MEM)
4555     FAIL;
4557   /* Change the mode to BLKmode for aliasing purposes.  */
4558   operands[0] = change_address (operands[0], BLKmode, XEXP (operands[0], 0));
4560   /* Otherwise, emit a s[wd]l/s[wd]r pair to load the value.  */
4561   if (INTVAL (operands[1]) == 64)
4562     emit_insn (gen_movdi_usd (operands[0], operands[3]));
4563   else
4564     {
4565       if (TARGET_64BIT)
4566         {
4567           operands[3] = gen_lowpart (SImode, operands[3]);
4568           if (operands[3] == NULL_RTX)
4569             FAIL;
4570         }
4571       emit_insn (gen_movsi_usw (operands[0], operands[3]));
4572     }
4573   DONE;
4576 ;; unaligned word moves generated by the bit field patterns
4578 (define_insn "movsi_ulw"
4579   [(set (match_operand:SI 0 "register_operand" "=&d,&d")
4580         (unspec:SI [(match_operand:BLK 1 "general_operand" "R,o")] 0))]
4581   "!TARGET_MIPS16"
4582   "*
4584   rtx offset = const0_rtx;
4585   rtx addr = XEXP (operands[1], 0);
4586   rtx mem_addr = eliminate_constant_term (addr, &offset);
4587   const char *ret;
4589   if (TARGET_STATS)
4590     mips_count_memory_refs (operands[1], 2);
4592   /* The stack/frame pointers are always aligned, so we can convert
4593      to the faster lw if we are referencing an aligned stack location.  */
4595   if ((INTVAL (offset) & 3) == 0
4596       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4597     ret = \"lw\\t%0,%1\";
4598   else
4599     ret = \"ulw\\t%0,%1\";
4601   return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
4603   [(set_attr "type"     "load,load")
4604    (set_attr "mode"     "SI")
4605    (set_attr "length"   "8,16")])
4607 (define_insn "movsi_usw"
4608   [(set (match_operand:BLK 0 "memory_operand" "=R,o")
4609         (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")] 1))]
4610   "!TARGET_MIPS16"
4611   "*
4613   rtx offset = const0_rtx;
4614   rtx addr = XEXP (operands[0], 0);
4615   rtx mem_addr = eliminate_constant_term (addr, &offset);
4617   if (TARGET_STATS)
4618     mips_count_memory_refs (operands[0], 2);
4620   /* The stack/frame pointers are always aligned, so we can convert
4621      to the faster sw if we are referencing an aligned stack location.  */
4623   if ((INTVAL (offset) & 3) == 0
4624       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4625     return \"sw\\t%1,%0\";
4627   return \"usw\\t%z1,%0\";
4629   [(set_attr "type"     "store")
4630    (set_attr "mode"     "SI")
4631    (set_attr "length"   "8,16")])
4633 ;; Bit field extract patterns which use ldl/ldr.
4635 ;; unaligned double word moves generated by the bit field patterns
4637 (define_insn "movdi_uld"
4638   [(set (match_operand:DI 0 "register_operand" "=&d,&d")
4639         (unspec:DI [(match_operand:BLK 1 "general_operand" "R,o")] 0))]
4640   ""
4641   "*
4643   rtx offset = const0_rtx;
4644   rtx addr = XEXP (operands[1], 0);
4645   rtx mem_addr = eliminate_constant_term (addr, &offset);
4646   const char *ret;
4648   if (TARGET_STATS)
4649     mips_count_memory_refs (operands[1], 2);
4651   /* The stack/frame pointers are always aligned, so we can convert
4652      to the faster lw if we are referencing an aligned stack location.  */
4654   if ((INTVAL (offset) & 7) == 0
4655       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4656     ret = \"ld\\t%0,%1\";
4657   else
4658     ret = \"uld\\t%0,%1\";
4660   return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
4662   [(set_attr "type"     "load,load")
4663    (set_attr "mode"     "SI")
4664    (set_attr "length"   "8,16")])
4666 (define_insn "movdi_usd"
4667   [(set (match_operand:BLK 0 "memory_operand" "=R,o")
4668         (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")] 1))]
4669   ""
4670   "*
4672   rtx offset = const0_rtx;
4673   rtx addr = XEXP (operands[0], 0);
4674   rtx mem_addr = eliminate_constant_term (addr, &offset);
4676   if (TARGET_STATS)
4677     mips_count_memory_refs (operands[0], 2);
4679   /* The stack/frame pointers are always aligned, so we can convert
4680      to the faster sw if we are referencing an aligned stack location.  */
4682   if ((INTVAL (offset) & 7) == 0
4683       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4684     return \"sd\\t%1,%0\";
4686   return \"usd\\t%z1,%0\";
4688   [(set_attr "type"     "store")
4689    (set_attr "mode"     "SI")
4690    (set_attr "length"   "8,16")])
4692 ;; These two patterns support loading addresses with two instructions instead
4693 ;; of using the macro instruction la.
4695 ;; ??? mips_move_1word has support for HIGH, so this pattern may be
4696 ;; unnecessary.
4698 (define_insn "high"
4699   [(set (match_operand:SI 0 "register_operand" "=r")
4700         (high:SI (match_operand:SI 1 "immediate_operand" "")))]
4701   "mips_split_addresses && !TARGET_MIPS16"
4702   "lui\\t%0,%%hi(%1) # high"
4703   [(set_attr "type"     "move")])
4705 (define_insn "low"
4706   [(set (match_operand:SI 0 "register_operand" "=r")
4707         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
4708                    (match_operand:SI 2 "immediate_operand" "")))]
4709   "mips_split_addresses && !TARGET_MIPS16"
4710   "addiu\\t%0,%1,%%lo(%2) # low"
4711   [(set_attr "type"     "arith")
4712    (set_attr "mode"     "SI")])
4714 ;; 64-bit integer moves
4716 ;; Unlike most other insns, the move insns can't be split with
4717 ;; different predicates, because register spilling and other parts of
4718 ;; the compiler, have memoized the insn number already.
4720 (define_expand "movdi"
4721   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4722         (match_operand:DI 1 "general_operand" ""))]
4723   ""
4724   "
4726   if (mips_split_addresses && mips_check_split (operands[1], DImode))
4727     {
4728       enum machine_mode mode = GET_MODE (operands[0]);
4729       rtx tem = ((reload_in_progress | reload_completed)
4730                  ? operands[0] : gen_reg_rtx (mode));
4732       emit_insn (gen_rtx (SET, VOIDmode, tem,
4733                           gen_rtx (HIGH, mode, operands[1])));
4735       operands[1] = gen_rtx (LO_SUM, mode, tem, operands[1]);
4736     }
4738   /* If we are generating embedded PIC code, and we are referring to a
4739      symbol in the .text section, we must use an offset from the start
4740      of the function.  */
4741   if (TARGET_EMBEDDED_PIC
4742       && (GET_CODE (operands[1]) == LABEL_REF
4743           || (GET_CODE (operands[1]) == SYMBOL_REF
4744               && ! SYMBOL_REF_FLAG (operands[1]))))
4745     {
4746       rtx temp;
4748       temp = embedded_pic_offset (operands[1]);
4749       temp = gen_rtx (PLUS, Pmode, embedded_pic_fnaddr_rtx,
4750                       force_reg (DImode, temp));
4751       emit_move_insn (operands[0], force_reg (DImode, temp));
4752       DONE;
4753     }
4755   /* If operands[1] is a constant address illegal for pic, then we need to
4756      handle it just like LEGITIMIZE_ADDRESS does.  */
4757   if (flag_pic && pic_address_needs_scratch (operands[1]))
4758     {
4759       rtx temp = force_reg (DImode, XEXP (XEXP (operands[1], 0), 0));
4760       rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
4762       if (! SMALL_INT (temp2))
4763         temp2 = force_reg (DImode, temp2);
4765       emit_move_insn (operands[0], gen_rtx (PLUS, DImode, temp, temp2));
4766       DONE;
4767     }
4769   /* On the mips16, we can handle a GP relative reference by adding in
4770      $gp.  We need to check the name to see whether this is a string
4771      constant.  */
4772   if (TARGET_MIPS16
4773       && register_operand (operands[0], DImode)
4774       && GET_CODE (operands[1]) == SYMBOL_REF
4775       && SYMBOL_REF_FLAG (operands[1]))
4776     {
4777       char *name = XSTR (operands[1], 0);
4779       if (name[0] != '*'
4780           || strncmp (name + 1, LOCAL_LABEL_PREFIX,
4781                       sizeof LOCAL_LABEL_PREFIX - 1) != 0)
4782         {
4783           rtx base_reg;
4785           if (reload_in_progress || reload_completed)
4786             {
4787               /* In movsi we use the constant table here.  However, in
4788                  this case, we're better off copying $28 into a
4789                  register and adding, because the constant table entry
4790                  would be 8 bytes.  */
4791               base_reg = operands[0];
4792               emit_move_insn (base_reg,
4793                               gen_rtx (CONST, DImode,
4794                                        gen_rtx (REG, DImode,
4795                                                 GP_REG_FIRST + 28)));
4796             }
4797           else
4798             {
4799               base_reg = gen_reg_rtx (Pmode);
4800               emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
4801             }
4803           emit_move_insn (operands[0],
4804                           gen_rtx (PLUS, Pmode, base_reg,
4805                                    mips16_gp_offset (operands[1])));
4806           DONE;
4807         }
4808     }
4810   if ((reload_in_progress | reload_completed) == 0
4811       && !register_operand (operands[0], DImode)
4812       && !register_operand (operands[1], DImode)
4813       && (TARGET_MIPS16
4814           || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
4815                && operands[1] != CONST0_RTX (DImode))))
4816     {
4817       rtx temp = force_reg (DImode, operands[1]);
4818       emit_move_insn (operands[0], temp);
4819       DONE;
4820     }
4823 ;; For mips16, we need a special case to handle storing $31 into
4824 ;; memory, since we don't have a constraint to match $31.  This
4825 ;; instruction can be generated by save_restore_insns.
4827 (define_insn ""
4828   [(set (match_operand:DI 0 "memory_operand" "R,m")
4829         (reg:DI 31))]
4830   "TARGET_MIPS16 && TARGET_64BIT"
4831   "*
4833   operands[1] = gen_rtx (REG, DImode, 31);
4834   return mips_move_2words (operands, insn);
4836   [(set_attr "type"     "store")
4837    (set_attr "mode"     "DI")
4838    (set_attr "length"   "4,8")])
4840 (define_insn "movdi_internal"
4841   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*x,*d,*x")
4842         (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,J,*x,*d"))]
4843   "!TARGET_64BIT && !TARGET_MIPS16
4844    && (register_operand (operands[0], DImode)
4845        || register_operand (operands[1], DImode)
4846        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
4847        || operands[1] == CONST0_RTX (DImode))"
4848   "* return mips_move_2words (operands, insn); "
4849   [(set_attr "type"     "move,arith,load,load,store,store,hilo,hilo,hilo")
4850    (set_attr "mode"     "DI")
4851    (set_attr "length"   "8,16,8,16,8,16,8,8,8")])
4853 (define_insn ""
4854   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,To,*d")
4855         (match_operand:DI 1 "general_operand" "d,d,y,K,N,R,To,d,d,*x"))]
4856   "!TARGET_64BIT && TARGET_MIPS16
4857    && (register_operand (operands[0], DImode)
4858        || register_operand (operands[1], DImode))"
4859   "* return mips_move_2words (operands, insn);"
4860   [(set_attr "type"     "move,move,move,arith,arith,load,load,store,store,hilo")
4861    (set_attr "mode"     "DI")
4862    (set_attr "length"   "8,8,8,8,12,8,16,8,16,8")])
4864 (define_split
4865   [(set (match_operand:DI 0 "register_operand" "")
4866         (match_operand:DI 1 "register_operand" ""))]
4867   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4868    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
4869    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
4871   [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
4872    (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
4873   "")
4875 (define_insn "movdi_internal2"
4876   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*x,*d,*x,*a")
4877         (match_operand:DI 1 "movdi_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,J,*x,*d,*J"))]
4878   "TARGET_64BIT && !TARGET_MIPS16
4879    && (register_operand (operands[0], DImode)
4880        || se_register_operand (operands[1], DImode)
4881        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
4882        || operands[1] == CONST0_RTX (DImode))"
4883   "* return mips_move_2words (operands, insn); "
4884   [(set_attr "type"     "move,load,arith,arith,load,load,store,store,hilo,hilo,hilo,hilo")
4885    (set_attr "mode"     "DI")
4886    (set_attr "length"   "4,8,4,8,4,8,4,8,4,4,4,8")])
4888 (define_insn ""
4889   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,R,m,*d")
4890         (match_operand:DI 1 "movdi_operand" "d,d,y,K,N,s,R,m,d,d,*x"))]
4891   "TARGET_64BIT && TARGET_MIPS16
4892    && (register_operand (operands[0], DImode)
4893        || se_register_operand (operands[1], DImode))"
4894   "* return mips_move_2words (operands, insn);"
4895   [(set_attr "type"     "move,move,move,arith,arith,arith,load,load,store,store,hilo")
4896    (set_attr "mode"     "DI")
4897    (set_attr_alternative "length"
4898                 [(const_int 4)
4899                  (const_int 4)
4900                  (const_int 4)
4901                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
4902                                (const_int 4)
4903                                (const_int 8))
4904                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
4905                                (const_int 8)
4906                                (const_int 12))
4907                  (if_then_else (match_operand:VOID 1 "m16_usym5_4" "")
4908                                (const_int 4)
4909                                (const_int 8))
4910                  (const_int 4)
4911                  (const_int 8)
4912                  (const_int 4)
4913                  (const_int 8)
4914                  (const_int 4)])])
4916 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
4917 ;; when the original load is a 4 byte instruction but the add and the
4918 ;; load are 2 2 byte instructions.
4920 (define_split
4921   [(set (match_operand:DI 0 "register_operand" "")
4922         (mem:DI (plus:DI (match_dup 0)
4923                          (match_operand:DI 1 "const_int_operand" ""))))]
4924   "TARGET_64BIT && TARGET_MIPS16 && reload_completed
4925    && GET_CODE (operands[0]) == REG
4926    && M16_REG_P (REGNO (operands[0]))
4927    && GET_CODE (operands[1]) == CONST_INT
4928    && ((INTVAL (operands[1]) < 0
4929         && INTVAL (operands[1]) >= -0x10)
4930        || (INTVAL (operands[1]) >= 32 * 8
4931            && INTVAL (operands[1]) <= 31 * 8 + 0x8)
4932        || (INTVAL (operands[1]) >= 0
4933            && INTVAL (operands[1]) < 32 * 8
4934            && (INTVAL (operands[1]) & 7) != 0))"
4935   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
4936    (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
4937   "
4939   HOST_WIDE_INT val = INTVAL (operands[1]);
4941   if (val < 0)
4942     operands[2] = GEN_INT (0);
4943   else if (val >= 32 * 8)
4944     {
4945       int off = val & 7;
4947       operands[1] = GEN_INT (0x8 + off);
4948       operands[2] = GEN_INT (val - off - 0x8);
4949     }
4950   else
4951     {
4952       int off = val & 7;
4954       operands[1] = GEN_INT (off);
4955       operands[2] = GEN_INT (val - off);
4956     }
4959 ;; Handle input reloads in DImode.
4960 ;; This is mainly to handle reloading HILO_REGNUM.  Note that we may
4961 ;; see it as the source or the destination, depending upon which way
4962 ;; reload handles the instruction.
4963 ;; Making the second operand TImode is a trick.  The compiler may
4964 ;; reuse the same register for operand 0 and operand 2.  Using TImode
4965 ;; gives us two registers, so we can always use the one which is not
4966 ;; used.
4968 (define_expand "reload_indi"
4969   [(set (match_operand:DI 0 "register_operand" "=b")
4970         (match_operand:DI 1 "" "b"))
4971    (clobber (match_operand:TI 2 "register_operand" "=&d"))]
4972   "TARGET_64BIT"
4973   "
4975   rtx scratch = gen_rtx (REG, DImode,
4976                          (REGNO (operands[0]) == REGNO (operands[2]) 
4977                           ? REGNO (operands[2]) + 1
4978                           : REGNO (operands[2])));
4980   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
4981     {
4982       if (GET_CODE (operands[1]) == MEM)
4983         {
4984           rtx memword, offword, hiword, loword;
4985           rtx addr = find_replacement (&XEXP (operands[1], 0));
4986           rtx op1 = change_address (operands[1], VOIDmode, addr);
4988           scratch = gen_rtx (REG, SImode, REGNO (scratch));
4989           memword = change_address (op1, SImode, NULL_RTX);
4990           offword = change_address (adj_offsettable_operand (op1, 4),
4991                                     SImode, NULL_RTX);
4992           if (BYTES_BIG_ENDIAN)
4993             {
4994               hiword = memword;
4995               loword = offword;
4996             }
4997           else
4998             {
4999               hiword = offword;
5000               loword = memword;
5001             }
5002           emit_move_insn (scratch, hiword);
5003           emit_move_insn (gen_rtx (REG, SImode, 64), scratch);
5004           emit_move_insn (scratch, loword);
5005           emit_move_insn (gen_rtx (REG, SImode, 65), scratch);
5006           emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
5007         }
5008       else
5009         {
5010           emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
5011           emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
5012           emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5013           emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5014           emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
5015           emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
5016         }
5017       DONE;
5018     }
5019   if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5020     {
5021       emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5022       emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5023       emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5024       emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
5025       emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5026       emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
5027       emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
5028       DONE;
5029     }
5030   /* This handles moves between a float register and HI/LO.  */
5031   emit_move_insn (scratch, operands[1]);
5032   emit_move_insn (operands[0], scratch);
5033   DONE;
5036 ;; Handle output reloads in DImode.
5038 ;; Reloading HILO_REG in MIPS16 mode requires two scratch registers, so we
5039 ;; use a TImode scratch reg.
5041 (define_expand "reload_outdi"
5042   [(set (match_operand:DI 0 "" "=b")
5043         (match_operand:DI 1 "se_register_operand" "b"))
5044    (clobber (match_operand:TI 2 "register_operand" "=&d"))]
5045   "TARGET_64BIT"
5046   "
5048   rtx scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
5050   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5051     {
5052       emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
5053       emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
5054       emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
5055       emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
5056       emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
5057       emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
5058       DONE;
5059     }
5060   if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
5061     {
5062       if (GET_CODE (operands[0]) == MEM)
5063         {
5064           rtx scratch, memword, offword, hiword, loword;
5065           rtx addr = find_replacement (&XEXP (operands[0], 0));
5066           rtx op0 = change_address (operands[0], VOIDmode, addr);
5068           scratch = gen_rtx (REG, SImode, REGNO (operands[2]));
5069           memword = change_address (op0, SImode, NULL_RTX);
5070           offword = change_address (adj_offsettable_operand (op0, 4),
5071                                     SImode, NULL_RTX);
5072           if (BYTES_BIG_ENDIAN)
5073             {
5074               hiword = memword;
5075               loword = offword;
5076             }
5077           else
5078             {
5079               hiword = offword;
5080               loword = memword;
5081             }
5082           emit_move_insn (scratch, gen_rtx (REG, SImode, 64));
5083           emit_move_insn (hiword, scratch);
5084           emit_move_insn (scratch, gen_rtx (REG, SImode, 65));
5085           emit_move_insn (loword, scratch);
5086           emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
5087         }
5088       else if (TARGET_MIPS16 && ! M16_REG_P (REGNO (operands[0])))
5089         {
5090           /* Handle the case where operand[0] is not a 'd' register,
5091              and hence we can not directly move from the HILO register
5092              into it.  */
5093           rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5094           emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5095           emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5096           emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5097           emit_insn (gen_movdi (scratch2, gen_rtx (REG, DImode, 64)));
5098           emit_insn (gen_ashldi3 (scratch2, scratch2, GEN_INT (32)));
5099           emit_insn (gen_iordi3 (scratch, scratch, scratch2));
5100           emit_insn (gen_movdi (operands[0], scratch));
5101           emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
5102         }
5103       else
5104         {
5105           emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
5106           emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
5107           emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
5108           emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
5109           emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5110           emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
5111           emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
5112         }
5113       DONE;
5114     }
5115   /* This handles moves between a float register and HI/LO.  */
5116   emit_move_insn (scratch, operands[1]);
5117   emit_move_insn (operands[0], scratch);
5118   DONE;
5121 ;; 32-bit Integer moves
5123 (define_split
5124   [(set (match_operand:SI 0 "register_operand" "")
5125         (match_operand:SI 1 "large_int" ""))]
5126   "!TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
5127   [(set (match_dup 0)
5128         (match_dup 2))
5129    (set (match_dup 0)
5130         (ior:SI (match_dup 0)
5131                 (match_dup 3)))]
5132   "
5134   operands[2] = GEN_INT (INTVAL (operands[1]) & 0xffff0000);
5135   operands[3] = GEN_INT (INTVAL (operands[1]) & 0x0000ffff);
5138 ;; Unlike most other insns, the move insns can't be split with
5139 ;; different predicates, because register spilling and other parts of
5140 ;; the compiler, have memoized the insn number already.
5142 (define_expand "movsi"
5143   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5144         (match_operand:SI 1 "general_operand" ""))]
5145   ""
5146   "
5148   if (mips_split_addresses && mips_check_split (operands[1], SImode))
5149     {
5150       enum machine_mode mode = GET_MODE (operands[0]);
5151       rtx tem = ((reload_in_progress | reload_completed)
5152                  ? operands[0] : gen_reg_rtx (mode));
5154       emit_insn (gen_rtx (SET, VOIDmode, tem,
5155                           gen_rtx (HIGH, mode, operands[1])));
5157       operands[1] = gen_rtx (LO_SUM, mode, tem, operands[1]);
5158     }
5160   /* If we are generating embedded PIC code, and we are referring to a
5161      symbol in the .text section, we must use an offset from the start
5162      of the function.  */
5163   if (TARGET_EMBEDDED_PIC
5164       && (GET_CODE (operands[1]) == LABEL_REF
5165           || (GET_CODE (operands[1]) == SYMBOL_REF
5166               && ! SYMBOL_REF_FLAG (operands[1]))))
5167     {
5168       rtx temp;
5170       temp = embedded_pic_offset (operands[1]);
5171       temp = gen_rtx (PLUS, Pmode, embedded_pic_fnaddr_rtx,
5172                       force_reg (SImode, temp));
5173       emit_move_insn (operands[0], force_reg (SImode, temp));
5174       DONE;
5175     }
5177   /* If operands[1] is a constant address invalid for pic, then we need to
5178      handle it just like LEGITIMIZE_ADDRESS does.  */
5179   if (flag_pic && pic_address_needs_scratch (operands[1]))
5180     {
5181       rtx temp = force_reg (SImode, XEXP (XEXP (operands[1], 0), 0));
5182       rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
5184       if (! SMALL_INT (temp2))
5185         temp2 = force_reg (SImode, temp2);
5187       emit_move_insn (operands[0], gen_rtx (PLUS, SImode, temp, temp2));
5188       DONE;
5189     }
5191   /* On the mips16, we can handle a GP relative reference by adding in
5192      $gp.  We need to check the name to see whether this is a string
5193      constant.  */
5194   if (TARGET_MIPS16
5195       && register_operand (operands[0], SImode)
5196       && GET_CODE (operands[1]) == SYMBOL_REF
5197       && SYMBOL_REF_FLAG (operands[1]))
5198     {
5199       char *name = XSTR (operands[1], 0);
5201       if (name[0] != '*'
5202           || strncmp (name + 1, LOCAL_LABEL_PREFIX,
5203                       sizeof LOCAL_LABEL_PREFIX - 1) != 0)
5204         {
5205           rtx base_reg;
5207           if (reload_in_progress || reload_completed)
5208             {
5209               /* We need to reload this address.  In this case we
5210                  aren't going to have a chance to combine loading the
5211                  address with the load or store.  That means that we
5212                  can either generate a 2 byte move followed by a 4
5213                  byte addition, or a 2 byte load with a 4 byte entry
5214                  in the constant table.  Since the entry in the
5215                  constant table might be shared, we're better off, on
5216                  average, loading the address from the constant table.  */
5217               emit_move_insn (operands[0],
5218                               force_const_mem (SImode, operands[1]));
5219               DONE;
5220             }
5222           base_reg = gen_reg_rtx (Pmode);
5223           emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
5225           emit_move_insn (operands[0],
5226                           gen_rtx (PLUS, Pmode, base_reg,
5227                                    mips16_gp_offset (operands[1])));
5228           DONE;
5229         }
5230     }
5232   if ((reload_in_progress | reload_completed) == 0
5233       && !register_operand (operands[0], SImode)
5234       && !register_operand (operands[1], SImode)
5235       && (TARGET_MIPS16
5236           || GET_CODE (operands[1]) != CONST_INT
5237           || INTVAL (operands[1]) != 0))
5238     {
5239       rtx temp = force_reg (SImode, operands[1]);
5240       emit_move_insn (operands[0], temp);
5241       DONE;
5242     }
5245 ;; For mips16, we need a special case to handle storing $31 into
5246 ;; memory, since we don't have a constraint to match $31.  This
5247 ;; instruction can be generated by save_restore_insns.
5249 (define_insn ""
5250   [(set (match_operand:SI 0 "memory_operand" "R,m")
5251         (reg:SI 31))]
5252   "TARGET_MIPS16"
5253   "*
5255   operands[1] = gen_rtx (REG, SImode, 31);
5256   return mips_move_1word (operands, insn, FALSE);
5258   [(set_attr "type"     "store")
5259    (set_attr "mode"     "SI")
5260    (set_attr "length"   "4,8")])
5262 ;; The difference between these two is whether or not ints are allowed
5263 ;; in FP registers (off by default, use -mdebugh to enable).
5265 (define_insn "movsi_internal1"
5266   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*f*z,*f,*f,*f,*R,*m,*x,*x,*d,*d")
5267         (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*f*z,*d,*f,*R,*m,*f,*f,J,*d,*x,*a"))]
5268   "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5269    && (register_operand (operands[0], SImode)
5270        || register_operand (operands[1], SImode)
5271        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5272   "* return mips_move_1word (operands, insn, FALSE);"
5273   [(set_attr "type"     "move,load,arith,arith,load,load,store,store,xfer,xfer,move,load,load,store,store,hilo,hilo,hilo,hilo")
5274    (set_attr "mode"     "SI")
5275    (set_attr "length"   "4,8,4,8,4,8,4,8,4,4,4,4,8,4,8,4,4,4,4")])
5277 (define_insn "movsi_internal2"
5278   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*z,*x,*d,*x,*d")
5279         (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,J,*x,*d,*a"))]
5280   "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5281    && (register_operand (operands[0], SImode)
5282        || register_operand (operands[1], SImode)
5283        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5284   "* return mips_move_1word (operands, insn, FALSE);"
5285   [(set_attr "type"     "move,load,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo,hilo,hilo")
5286    (set_attr "mode"     "SI")
5287    (set_attr "length"   "4,8,4,8,4,8,4,8,4,4,4,4,4,4")])
5289 ;; This is the mips16 movsi instruction.  We accept a small integer as
5290 ;; the source if the destination is a GP memory reference.  This is
5291 ;; because we want the combine pass to turn adding a GP reference to a
5292 ;; register into a direct GP reference, but the combine pass will pass
5293 ;; in the source as a constant if it finds an equivalent one.  If the
5294 ;; instruction is recognized, reload will force the constant back out
5295 ;; into a register.
5297 (define_insn ""
5298   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,d,R,m,*d,*d")
5299         (match_operand:SI 1 "move_operand" "d,d,y,S,K,N,s,R,m,d,d,*x,*a"))]
5300   "TARGET_MIPS16
5301    && (register_operand (operands[0], SImode)
5302        || register_operand (operands[1], SImode)
5303        || (GET_CODE (operands[0]) == MEM
5304            && GET_CODE (XEXP (operands[0], 0)) == PLUS
5305            && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST
5306            && mips16_gp_offset_p (XEXP (XEXP (operands[0], 0), 1))
5307            && GET_CODE (operands[1]) == CONST_INT
5308            && (SMALL_INT (operands[1])
5309                || SMALL_INT_UNSIGNED (operands[1]))))"
5310   "* return mips_move_1word (operands, insn, FALSE);"
5311   [(set_attr "type"     "move,move,move,load,arith,arith,arith,load,load,store,store,hilo,hilo")
5312    (set_attr "mode"     "SI")
5313    (set_attr_alternative "length"
5314                 [(const_int 4)
5315                  (const_int 4)
5316                  (const_int 4)
5317                  (const_int 8)
5318                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5319                                (const_int 4)
5320                                (const_int 8))
5321                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5322                                (const_int 8)
5323                                (const_int 12))
5324                  (if_then_else (match_operand:VOID 1 "m16_usym8_4" "")
5325                                (const_int 4)
5326                                (const_int 8))
5327                  (const_int 4)
5328                  (const_int 8)
5329                  (const_int 4)
5330                  (const_int 8)
5331                  (const_int 4)
5332                  (const_int 4)])])
5334 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
5335 ;; when the original load is a 4 byte instruction but the add and the
5336 ;; load are 2 2 byte instructions.
5338 (define_split
5339   [(set (match_operand:SI 0 "register_operand" "")
5340         (mem:SI (plus:SI (match_dup 0)
5341                          (match_operand:SI 1 "const_int_operand" ""))))]
5342   "TARGET_MIPS16 && reload_completed
5343    && GET_CODE (operands[0]) == REG
5344    && M16_REG_P (REGNO (operands[0]))
5345    && GET_CODE (operands[1]) == CONST_INT
5346    && ((INTVAL (operands[1]) < 0
5347         && INTVAL (operands[1]) >= -0x80)
5348        || (INTVAL (operands[1]) >= 32 * 4
5349            && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
5350        || (INTVAL (operands[1]) >= 0
5351            && INTVAL (operands[1]) < 32 * 4
5352            && (INTVAL (operands[1]) & 3) != 0))"
5353   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5354    (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
5355   "
5357   HOST_WIDE_INT val = INTVAL (operands[1]);
5359   if (val < 0)
5360     operands[2] = GEN_INT (0);
5361   else if (val >= 32 * 4)
5362     {
5363       int off = val & 3;
5365       operands[1] = GEN_INT (0x7c + off);
5366       operands[2] = GEN_INT (val - off - 0x7c);
5367     }
5368   else
5369     {
5370       int off = val & 3;
5372       operands[1] = GEN_INT (off);
5373       operands[2] = GEN_INT (val - off);
5374     }
5377 ;; On the mips16, we can split a load of certain constants into a load
5378 ;; and an add.  This turns a 4 byte instruction into 2 2 byte
5379 ;; instructions.
5381 (define_split
5382   [(set (match_operand:SI 0 "register_operand" "")
5383         (match_operand:SI 1 "const_int_operand" ""))]
5384   "TARGET_MIPS16 && reload_completed
5385    && GET_CODE (operands[0]) == REG
5386    && M16_REG_P (REGNO (operands[0]))
5387    && GET_CODE (operands[1]) == CONST_INT
5388    && INTVAL (operands[1]) >= 0x100
5389    && INTVAL (operands[1]) <= 0xff + 0x7f"
5390   [(set (match_dup 0) (match_dup 1))
5391    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
5392   "
5394   int val = INTVAL (operands[1]);
5396   operands[1] = GEN_INT (0xff);
5397   operands[2] = GEN_INT (val - 0xff);
5400 ;; On the mips16, we can split a load of a negative constant into a
5401 ;; load and a neg.  That's what mips_move_1word will generate anyhow.
5403 (define_split
5404   [(set (match_operand:SI 0 "register_operand" "")
5405         (match_operand:SI 1 "const_int_operand" ""))]
5406   "TARGET_MIPS16 && reload_completed
5407    && GET_CODE (operands[0]) == REG
5408    && M16_REG_P (REGNO (operands[0]))
5409    && GET_CODE (operands[1]) == CONST_INT
5410    && INTVAL (operands[1]) < 0
5411    && INTVAL (operands[1]) > - 0x8000"
5412   [(set (match_dup 0) (match_dup 1))
5413    (set (match_dup 0) (neg:SI (match_dup 0)))]
5414   "
5416   operands[1] = GEN_INT (- INTVAL (operands[1]));
5419 ;; Reload HILO_REGNUM in SI mode.  This needs a scratch register in
5420 ;; order to set the sign bit correctly in the HI register.
5422 (define_expand "reload_outsi"
5423   [(set (match_operand:SI 0 "general_operand" "=b")
5424         (match_operand:SI 1 "register_operand" "b"))
5425    (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5426   "TARGET_64BIT || TARGET_MIPS16"
5427   "
5429   if (TARGET_64BIT
5430       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
5431     {
5432       emit_insn (gen_movsi (gen_rtx (REG, SImode, 65), operands[1]));
5433       emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31)));
5434       emit_insn (gen_movsi (gen_rtx (REG, SImode, 64), operands[2]));
5435       emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
5436       DONE;
5437     }
5438   /* Use a mult to reload LO on mips16.  ??? This is hideous.  */
5439   if (TARGET_MIPS16
5440       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5441     {
5442       emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5443       /* This is gen_mulsi3_internal, but we need to fill in the
5444          scratch registers.  */
5445       emit_insn (gen_rtx (PARALLEL, VOIDmode,
5446                           gen_rtvec (3,
5447                                      gen_rtx (SET, VOIDmode,
5448                                               operands[0],
5449                                               gen_rtx (MULT, SImode,
5450                                                        operands[1],
5451                                                        operands[2])),
5452                                      gen_rtx (CLOBBER, VOIDmode,
5453                                               gen_rtx (REG, SImode, 64)),
5454                                      gen_rtx (CLOBBER, VOIDmode,
5455                                               gen_rtx (REG, SImode, 66)))));
5456       DONE;
5457     }
5458   /* FIXME: I don't know how to get a value into the HI register.  */
5459   if (GET_CODE (operands[0]) == REG
5460       && (TARGET_MIPS16 ? M16_REG_P (REGNO (operands[0]))
5461           : GP_REG_P (REGNO (operands[0]))))
5462     {
5463       emit_move_insn (operands[0], operands[1]);
5464       DONE;
5465     }
5466   /* This handles moves between a float register and HI/LO.  */
5467   emit_move_insn (operands[2], operands[1]);
5468   emit_move_insn (operands[0], operands[2]);
5469   DONE;
5472 ;; Reload a value into HI or LO.  There is no mthi or mtlo on mips16,
5473 ;; so we use a mult.  ??? This is hideous, and we ought to figure out
5474 ;; something better.
5476 ;; We use no predicate for operand1, because it may be a PLUS, and there
5477 ;; is no convenient predicate for that.
5479 (define_expand "reload_insi"
5480   [(set (match_operand:SI 0 "register_operand" "=b")
5481         (match_operand:SI 1 "" "b"))
5482    (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5483   "TARGET_MIPS16"
5484   "
5486   if (TARGET_MIPS16
5487       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5488     {
5489       emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5490       /* This is gen_mulsi3_internal, but we need to fill in the
5491          scratch registers.  */
5492       emit_insn (gen_rtx (PARALLEL, VOIDmode,
5493                           gen_rtvec (3,
5494                                      gen_rtx (SET, VOIDmode,
5495                                               operands[0],
5496                                               gen_rtx (MULT, SImode,
5497                                                        operands[1],
5498                                                        operands[2])),
5499                                      gen_rtx (CLOBBER, VOIDmode,
5500                                               gen_rtx (REG, SImode, 64)),
5501                                      gen_rtx (CLOBBER, VOIDmode,
5502                                               gen_rtx (REG, SImode, 66)))));
5503       DONE;
5504     }
5506   /* If this is a plus, then this must be an add of the stack pointer against
5507      either a hard register or a pseudo.  */
5508   if (TARGET_MIPS16 && GET_CODE (operands[1]) == PLUS)
5509     {
5510       rtx plus_op;
5512       if (XEXP (operands[1], 0) == stack_pointer_rtx)
5513         plus_op = XEXP (operands[1], 1);
5514       else if (XEXP (operands[1], 1) == stack_pointer_rtx)
5515         plus_op = XEXP (operands[1], 0);
5516       else
5517         abort ();
5519       /* We should have a register now.  */
5520       if (GET_CODE (plus_op) != REG)
5521         abort ();
5523       if (REGNO (plus_op) < FIRST_PSEUDO_REGISTER)
5524         {
5525           /* We have to have at least one temporary register which is not
5526              overlapping plus_op.  */
5527           if (! rtx_equal_p (plus_op, operands[0]))
5528             {
5529               emit_move_insn (operands[0], stack_pointer_rtx);
5530               emit_insn (gen_addsi3 (operands[0], operands[0], plus_op));
5531             }
5532           else if (! rtx_equal_p (plus_op, operands[2]))
5533             {
5534               emit_move_insn (operands[2], stack_pointer_rtx);
5535               emit_insn (gen_addsi3 (operands[0], plus_op, operands[2]));
5536             }
5537           else
5538             abort ();
5539         }
5540       else
5541         {
5542           /* We need two registers in this case.  */
5543           if (! rtx_equal_p (operands[0], operands[2]))
5544             {
5545               emit_move_insn (operands[0], stack_pointer_rtx);
5546               emit_move_insn (operands[2], plus_op);
5547               emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
5548             }
5549           else
5550             abort ();
5551         }
5552       DONE;
5553     }
5555   /* FIXME: I don't know how to get a value into the HI register.  */
5556   emit_move_insn (operands[0], operands[1]);
5557   DONE;
5560 ;; This insn handles moving CCmode values.  It's really just a
5561 ;; slightly simplified copy of movsi_internal2, with additional cases
5562 ;; to move a condition register to a general register and to move
5563 ;; between the general registers and the floating point registers.
5565 (define_insn "movcc"
5566   [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*d,*R,*m,*d,*f,*f,*f,*f,*R,*m")
5567         (match_operand:CC 1 "general_operand" "z,*d,*R,*m,*d,*d,*f,*d,*f,*R,*m,*f,*f"))]
5568   "mips_isa >= 4 && TARGET_HARD_FLOAT"
5569   "* return mips_move_1word (operands, insn, FALSE);"
5570   [(set_attr "type"     "move,move,load,load,store,store,xfer,xfer,move,load,load,store,store")
5571    (set_attr "mode"     "SI")
5572    (set_attr "length"   "8,4,4,8,4,8,4,4,4,4,8,4,8")])
5574 ;; Reload condition code registers.  These need scratch registers.
5576 (define_expand "reload_incc"
5577   [(set (match_operand:CC 0 "register_operand" "=z")
5578         (match_operand:CC 1 "general_operand" "z"))
5579    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
5580   "mips_isa >= 4 && TARGET_HARD_FLOAT"
5581   "
5583   rtx source;
5584   rtx fp1, fp2;
5586   /* This is called when are copying some value into a condition code
5587      register.  Operand 0 is the condition code register.  Operand 1
5588      is the source.  Operand 2 is a scratch register; we use TFmode
5589      because we actually need two floating point registers.  */
5590   if (! ST_REG_P (true_regnum (operands[0]))
5591       || ! FP_REG_P (true_regnum (operands[2])))
5592     abort ();
5594   /* We need to get the source in SFmode so that the insn is
5595      recognized.  */
5596   if (GET_CODE (operands[1]) == MEM)
5597     source = change_address (operands[1], SFmode, NULL_RTX);
5598   else if (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG)
5599     source = gen_rtx (REG, SFmode, true_regnum (operands[1]));
5600   else
5601     source = operands[1];
5603   fp1 = gen_rtx (REG, SFmode, REGNO (operands[2]));
5604   fp2 = gen_rtx (REG, SFmode, REGNO (operands[2]) + 1);
5606   emit_insn (gen_move_insn (fp1, source));
5607   emit_insn (gen_move_insn (fp2, gen_rtx (REG, SFmode, 0)));
5608   emit_insn (gen_rtx (SET, VOIDmode, operands[0],
5609                       gen_rtx (LT, CCmode, fp2, fp1)));
5611   DONE;
5614 (define_expand "reload_outcc"
5615   [(set (match_operand:CC 0 "general_operand" "=z")
5616         (match_operand:CC 1 "register_operand" "z"))
5617    (clobber (match_operand:CC 2 "register_operand" "=&d"))]
5618   "mips_isa >= 4 && TARGET_HARD_FLOAT"
5619   "
5621   /* This is called when we are copying a condition code register out
5622      to save it somewhere.  Operand 0 should be the location we are
5623      going to save it to.  Operand 1 should be the condition code
5624      register.  Operand 2 should be a scratch general purpose register
5625      created for us by reload.  The mips_secondary_reload_class
5626      function should have told reload that we don't need a scratch
5627      register if the destination is a general purpose register anyhow.  */
5628   if (ST_REG_P (true_regnum (operands[0]))
5629       || GP_REG_P (true_regnum (operands[0]))
5630       || ! ST_REG_P (true_regnum (operands[1]))
5631       || ! GP_REG_P (true_regnum (operands[2])))
5632     abort ();
5634   /* All we have to do is copy the value from the condition code to
5635      the data register, which movcc can handle, and then store the
5636      value into the real final destination.  */
5637   emit_insn (gen_move_insn (operands[2], operands[1]));
5638   emit_insn (gen_move_insn (operands[0], operands[2]));
5640   DONE;
5643 ;; MIPS4 supports loading and storing a floating point register from
5644 ;; the sum of two general registers.  We use two versions for each of
5645 ;; these four instructions: one where the two general registers are
5646 ;; SImode, and one where they are DImode.  This is because general
5647 ;; registers will be in SImode when they hold 32 bit values, but,
5648 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
5649 ;; instructions will still work correctly.
5651 ;; ??? Perhaps it would be better to support these instructions by
5652 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends.  However, since
5653 ;; these instructions can only be used to load and store floating
5654 ;; point registers, that would probably cause trouble in reload.
5656 (define_insn ""
5657   [(set (match_operand:SF 0 "register_operand" "=f")
5658         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5659                          (match_operand:SI 2 "register_operand" "d"))))]
5660   "mips_isa >= 4 && TARGET_HARD_FLOAT"
5661   "lwxc1\\t%0,%1(%2)"
5662   [(set_attr "type"     "load")
5663    (set_attr "mode"     "SF")])
5665 (define_insn ""
5666   [(set (match_operand:SF 0 "register_operand" "=f")
5667         (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5668                          (match_operand:DI 2 "se_register_operand" "d"))))]
5669   "mips_isa >= 4 && TARGET_HARD_FLOAT"
5670   "lwxc1\\t%0,%1(%2)"
5671   [(set_attr "type"     "load")
5672    (set_attr "mode"     "SF")])
5674 (define_insn ""
5675   [(set (match_operand:DF 0 "register_operand" "=f")
5676         (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5677                          (match_operand:SI 2 "register_operand" "d"))))]
5678   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5679   "ldxc1\\t%0,%1(%2)"
5680   [(set_attr "type"     "load")
5681    (set_attr "mode"     "DF")])
5683 (define_insn ""
5684   [(set (match_operand:DF 0 "register_operand" "=f")
5685         (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5686                          (match_operand:DI 2 "se_register_operand" "d"))))]
5687   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5688   "ldxc1\\t%0,%1(%2)"
5689   [(set_attr "type"     "load")
5690    (set_attr "mode"     "DF")])
5692 (define_insn ""
5693   [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5694                          (match_operand:SI 2 "register_operand" "d")))
5695         (match_operand:SF 0 "register_operand" "=f"))]
5696   "mips_isa >= 4 && TARGET_HARD_FLOAT"
5697   "swxc1\\t%0,%1(%2)"
5698   [(set_attr "type"     "store")
5699    (set_attr "mode"     "SF")])
5701 (define_insn ""
5702   [(set (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5703                          (match_operand:DI 2 "se_register_operand" "d")))
5704         (match_operand:SF 0 "register_operand" "=f"))]
5705   "mips_isa >= 4 && TARGET_HARD_FLOAT"
5706   "swxc1\\t%0,%1(%2)"
5707   [(set_attr "type"     "store")
5708    (set_attr "mode"     "SF")])
5710 (define_insn ""
5711   [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5712                          (match_operand:SI 2 "register_operand" "d")))
5713         (match_operand:DF 0 "register_operand" "=f"))]
5714   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5715   "sdxc1\\t%0,%1(%2)"
5716   [(set_attr "type"     "store")
5717    (set_attr "mode"     "DF")])
5719 (define_insn ""
5720   [(set (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5721                          (match_operand:DI 2 "se_register_operand" "d")))
5722         (match_operand:DF 0 "register_operand" "=f"))]
5723   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5724   "sdxc1\\t%0,%1(%2)"
5725   [(set_attr "type"     "store")
5726    (set_attr "mode"     "DF")])
5728 ;; 16-bit Integer moves
5730 ;; Unlike most other insns, the move insns can't be split with
5731 ;; different predicates, because register spilling and other parts of
5732 ;; the compiler, have memoized the insn number already.
5733 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
5735 (define_expand "movhi"
5736   [(set (match_operand:HI 0 "nonimmediate_operand" "")
5737         (match_operand:HI 1 "general_operand" ""))]
5738   ""
5739   "
5741   if ((reload_in_progress | reload_completed) == 0
5742       && !register_operand (operands[0], HImode)
5743       && !register_operand (operands[1], HImode)
5744       && (TARGET_MIPS16
5745           || (GET_CODE (operands[1]) != CONST_INT
5746           || INTVAL (operands[1]) != 0)))
5747     {
5748       rtx temp = force_reg (HImode, operands[1]);
5749       emit_move_insn (operands[0], temp);
5750       DONE;
5751     }
5754 ;; The difference between these two is whether or not ints are allowed
5755 ;; in FP registers (off by default, use -mdebugh to enable).
5757 (define_insn "movhi_internal1"
5758   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f*z,*x,*d")
5759         (match_operand:HI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
5760   "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5761    && (register_operand (operands[0], HImode)
5762        || register_operand (operands[1], HImode)
5763        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5764   "* return mips_move_1word (operands, insn, TRUE);"
5765   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
5766    (set_attr "mode"     "HI")
5767    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4,4")])
5769 (define_insn "movhi_internal2"
5770   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
5771         (match_operand:HI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
5772   "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5773    && (register_operand (operands[0], HImode)
5774        || register_operand (operands[1], HImode)
5775        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5776   "* return mips_move_1word (operands, insn, TRUE);"
5777   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
5778    (set_attr "mode"     "HI")
5779    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4")])
5781 (define_insn ""
5782   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
5783         (match_operand:HI 1 "general_operand"      "d,d,y,K,N,R,m,d,d,*x"))]
5784   "TARGET_MIPS16
5785    && (register_operand (operands[0], HImode)
5786        || register_operand (operands[1], HImode))"
5787   "* return mips_move_1word (operands, insn, TRUE);"
5788   [(set_attr "type"     "move,move,move,arith,arith,load,load,store,store,hilo")
5789    (set_attr "mode"     "HI")
5790    (set_attr_alternative "length"
5791                 [(const_int 4)
5792                  (const_int 4)
5793                  (const_int 4)
5794                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5795                                (const_int 4)
5796                                (const_int 8))
5797                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5798                                (const_int 8)
5799                                (const_int 12))
5800                  (const_int 4)
5801                  (const_int 8)
5802                  (const_int 4)
5803                  (const_int 8)
5804                  (const_int 4)])])
5807 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
5808 ;; when the original load is a 4 byte instruction but the add and the
5809 ;; load are 2 2 byte instructions.
5811 (define_split
5812   [(set (match_operand:HI 0 "register_operand" "")
5813         (mem:HI (plus:SI (match_dup 0)
5814                          (match_operand:SI 1 "const_int_operand" ""))))]
5815   "TARGET_MIPS16 && reload_completed
5816    && GET_CODE (operands[0]) == REG
5817    && M16_REG_P (REGNO (operands[0]))
5818    && GET_CODE (operands[1]) == CONST_INT
5819    && ((INTVAL (operands[1]) < 0
5820         && INTVAL (operands[1]) >= -0x80)
5821        || (INTVAL (operands[1]) >= 32 * 2
5822            && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
5823        || (INTVAL (operands[1]) >= 0
5824            && INTVAL (operands[1]) < 32 * 2
5825            && (INTVAL (operands[1]) & 1) != 0))"
5826   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5827    (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
5828   "
5830   HOST_WIDE_INT val = INTVAL (operands[1]);
5832   if (val < 0)
5833     operands[2] = GEN_INT (0);
5834   else if (val >= 32 * 2)
5835     {
5836       int off = val & 1;
5838       operands[1] = GEN_INT (0x7e + off);
5839       operands[2] = GEN_INT (val - off - 0x7e);
5840     }
5841   else
5842     {
5843       int off = val & 1;
5845       operands[1] = GEN_INT (off);
5846       operands[2] = GEN_INT (val - off);
5847     }
5850 ;; 8-bit Integer moves
5852 ;; Unlike most other insns, the move insns can't be split with
5853 ;; different predicates, because register spilling and other parts of
5854 ;; the compiler, have memoized the insn number already.
5855 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
5857 (define_expand "movqi"
5858   [(set (match_operand:QI 0 "nonimmediate_operand" "")
5859         (match_operand:QI 1 "general_operand" ""))]
5860   ""
5861   "
5863   if ((reload_in_progress | reload_completed) == 0
5864       && !register_operand (operands[0], QImode)
5865       && !register_operand (operands[1], QImode)
5866       && (TARGET_MIPS16
5867           || (GET_CODE (operands[1]) != CONST_INT
5868           || INTVAL (operands[1]) != 0)))
5869     {
5870       rtx temp = force_reg (QImode, operands[1]);
5871       emit_move_insn (operands[0], temp);
5872       DONE;
5873     }
5876 ;; The difference between these two is whether or not ints are allowed
5877 ;; in FP registers (off by default, use -mdebugh to enable).
5879 (define_insn "movqi_internal1"
5880   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
5881         (match_operand:QI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
5882   "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5883    && (register_operand (operands[0], QImode)
5884        || register_operand (operands[1], QImode)
5885        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5886   "* return mips_move_1word (operands, insn, TRUE);"
5887   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
5888    (set_attr "mode"     "QI")
5889    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4,4")])
5891 (define_insn "movqi_internal2"
5892   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
5893         (match_operand:QI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
5894   "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5895    && (register_operand (operands[0], QImode)
5896        || register_operand (operands[1], QImode)
5897        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5898   "* return mips_move_1word (operands, insn, TRUE);"
5899   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
5900    (set_attr "mode"     "QI")
5901    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4")])
5903 (define_insn ""
5904   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
5905         (match_operand:QI 1 "general_operand"      "d,d,y,K,N,R,m,d,d,*x"))]
5906   "TARGET_MIPS16
5907    && (register_operand (operands[0], QImode)
5908        || register_operand (operands[1], QImode))"
5909   "* return mips_move_1word (operands, insn, TRUE);"
5910   [(set_attr "type"     "move,move,move,arith,arith,load,load,store,store,hilo")
5911    (set_attr "mode"     "QI")
5912    (set_attr_alternative "length"
5913                 [(const_int 4)
5914                  (const_int 4)
5915                  (const_int 4)
5916                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5917                                (const_int 4)
5918                                (const_int 8))
5919                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5920                                (const_int 8)
5921                                (const_int 12))
5922                  (const_int 4)
5923                  (const_int 8)
5924                  (const_int 4)
5925                  (const_int 8)
5926                  (const_int 4)])])
5929 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
5930 ;; when the original load is a 4 byte instruction but the add and the
5931 ;; load are 2 2 byte instructions.
5933 (define_split
5934   [(set (match_operand:QI 0 "register_operand" "")
5935         (mem:QI (plus:SI (match_dup 0)
5936                          (match_operand:SI 1 "const_int_operand" ""))))]
5937   "TARGET_MIPS16 && reload_completed
5938    && GET_CODE (operands[0]) == REG
5939    && M16_REG_P (REGNO (operands[0]))
5940    && GET_CODE (operands[1]) == CONST_INT
5941    && ((INTVAL (operands[1]) < 0
5942         && INTVAL (operands[1]) >= -0x80)
5943        || (INTVAL (operands[1]) >= 32
5944            && INTVAL (operands[1]) <= 31 + 0x7f))"
5945   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5946    (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
5947   "
5949   HOST_WIDE_INT val = INTVAL (operands[1]);
5951   if (val < 0)
5952     operands[2] = GEN_INT (0);
5953   else
5954     {
5955       operands[1] = GEN_INT (0x7f);
5956       operands[2] = GEN_INT (val - 0x7f);
5957     }
5960 ;; 32-bit floating point moves
5962 (define_expand "movsf"
5963   [(set (match_operand:SF 0 "nonimmediate_operand" "")
5964         (match_operand:SF 1 "general_operand" ""))]
5965   ""
5966   "
5968   if ((reload_in_progress | reload_completed) == 0
5969       && !register_operand (operands[0], SFmode)
5970       && !register_operand (operands[1], SFmode)
5971       && (TARGET_MIPS16
5972           || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
5973                && operands[1] != CONST0_RTX (SFmode))))
5974     {
5975       rtx temp = force_reg (SFmode, operands[1]);
5976       emit_move_insn (operands[0], temp);
5977       DONE;
5978     }
5981 (define_insn "movsf_internal1"
5982   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m")
5983         (match_operand:SF 1 "general_operand" "f,G,R,Fm,fG,fG,*d,*f,*G*d,*R,*F*m,*d,*d"))]
5984   "TARGET_HARD_FLOAT
5985    && (register_operand (operands[0], SFmode)
5986        || register_operand (operands[1], SFmode)
5987        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5988        || operands[1] == CONST0_RTX (SFmode))"
5989   "* return mips_move_1word (operands, insn, FALSE);"
5990   [(set_attr "type"     "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store")
5991    (set_attr "mode"     "SF")
5992    (set_attr "length"   "4,4,4,8,4,8,4,4,4,4,8,4,8")])
5995 (define_insn "movsf_internal2"
5996   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,R,m")
5997         (match_operand:SF 1 "general_operand" "      Gd,R,Fm,d,d"))]
5998   "TARGET_SOFT_FLOAT && !TARGET_MIPS16
5999    && (register_operand (operands[0], SFmode)
6000        || register_operand (operands[1], SFmode)
6001        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6002        || operands[1] == CONST0_RTX (SFmode))"
6003   "* return mips_move_1word (operands, insn, FALSE);"
6004   [(set_attr "type"     "move,load,load,store,store")
6005    (set_attr "mode"     "SF")
6006    (set_attr "length"   "4,4,8,4,8")])
6008 (define_insn ""
6009   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,d,R,m")
6010         (match_operand:SF 1 "general_operand"      "d,d,y,R,Fm,d,d"))]
6011   "TARGET_MIPS16
6012    && (register_operand (operands[0], SFmode)
6013        || register_operand (operands[1], SFmode))"
6014   "* return mips_move_1word (operands, insn, FALSE);"
6015   [(set_attr "type"     "move,move,move,load,load,store,store")
6016    (set_attr "mode"     "SF")
6017    (set_attr "length"   "4,4,4,4,8,4,8")])
6020 ;; 64-bit floating point moves
6022 (define_expand "movdf"
6023   [(set (match_operand:DF 0 "nonimmediate_operand" "")
6024         (match_operand:DF 1 "general_operand" ""))]
6025   ""
6026   "
6028   if ((reload_in_progress | reload_completed) == 0
6029       && !register_operand (operands[0], DFmode)
6030       && !register_operand (operands[1], DFmode)
6031       && (TARGET_MIPS16
6032           || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
6033                && operands[1] != CONST0_RTX (DFmode))))
6034     {
6035       rtx temp = force_reg (DFmode, operands[1]);
6036       emit_move_insn (operands[0], temp);
6037       DONE;
6038     }
6041 (define_insn "movdf_internal1"
6042   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,To,f,*f,*d,*d,*d,*d,*R,*T")
6043         (match_operand:DF 1 "general_operand" "f,R,To,fG,fG,F,*d,*f,*d*G,*R,*T*F,*d,*d"))]
6044   "TARGET_HARD_FLOAT && !(TARGET_FLOAT64 && !TARGET_64BIT)
6045    && TARGET_DOUBLE_FLOAT
6046    && (register_operand (operands[0], DFmode)
6047        || register_operand (operands[1], DFmode)
6048        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6049        || operands[1] == CONST0_RTX (DFmode))"
6050   "* return mips_move_2words (operands, insn); "
6051   [(set_attr "type"     "move,load,load,store,store,load,xfer,xfer,move,load,load,store,store")
6052    (set_attr "mode"     "DF")
6053    (set_attr "length"   "4,8,16,8,16,16,8,8,8,8,16,8,16")])
6055 (define_insn "movdf_internal1a"
6056   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,R,R,To,To,f,*d,*d,*d,*To,*R")
6057         (match_operand:DF 1 "general_operand"      " f,To,f,G,f,G,F,*F,*To,*R,*d,*d"))]
6058   "TARGET_HARD_FLOAT && (TARGET_FLOAT64 && !TARGET_64BIT)
6059    && TARGET_DOUBLE_FLOAT
6060    && (register_operand (operands[0], DFmode)
6061        || register_operand (operands[1], DFmode)
6062        || (GET_CODE (operands [0]) == MEM
6063            && ((GET_CODE (operands[1]) == CONST_INT
6064                 && INTVAL (operands[1]) == 0)
6065                || operands[1] == CONST0_RTX (DFmode))))"
6066   "* return mips_move_2words (operands, insn); "
6067   [(set_attr "type"     "move,load,store,store,store,store,load,load,load,load,store,store")
6068    (set_attr "mode"     "DF")
6069    (set_attr "length"   "4,8,4,4,8,8,8,8,8,4,8,4")])
6071 (define_insn "movdf_internal2"
6072   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,R,To")
6073         (match_operand:DF 1 "general_operand" "dG,R,ToF,d,d"))]
6074   "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
6075    && (register_operand (operands[0], DFmode)
6076        || register_operand (operands[1], DFmode)
6077        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
6078        || operands[1] == CONST0_RTX (DFmode))"
6079   "* return mips_move_2words (operands, insn); "
6080   [(set_attr "type"     "move,load,load,store,store")
6081    (set_attr "mode"     "DF")
6082    (set_attr "length"   "8,8,16,8,16")])
6084 (define_insn ""
6085   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,d,R,To")
6086         (match_operand:DF 1 "general_operand" "d,d,y,R,ToF,d,d"))]
6087   "TARGET_MIPS16
6088    && (register_operand (operands[0], DFmode)
6089        || register_operand (operands[1], DFmode))"
6090   "* return mips_move_2words (operands, insn);"
6091   [(set_attr "type"     "move,move,move,load,load,store,store")
6092    (set_attr "mode"     "DF")
6093    (set_attr "length"   "8,8,8,8,16,8,16")])
6095 (define_split
6096   [(set (match_operand:DF 0 "register_operand" "")
6097         (match_operand:DF 1 "register_operand" ""))]
6098   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
6099    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
6100    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
6101   [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
6102    (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
6103   "")
6105 ;; Instructions to load the global pointer register.
6106 ;; This is volatile to make sure that the scheduler won't move any symbol_ref
6107 ;; uses in front of it.  All symbol_refs implicitly use the gp reg.
6109 (define_insn "loadgp"
6110   [(set (reg:DI 28)
6111         (unspec_volatile:DI [(match_operand:DI 0 "address_operand" "")
6112                              (match_operand:DI 1 "register_operand" "")] 2))
6113    (clobber (reg:DI 1))]
6114   ""
6115   "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%a0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%a0)))\\n\\tdaddu\\t$gp,$1,%1%]"
6116   [(set_attr "type"     "move")
6117    (set_attr "mode"     "DI")
6118    (set_attr "length"   "12")])
6120 ;; Block moves, see mips.c for more details.
6121 ;; Argument 0 is the destination
6122 ;; Argument 1 is the source
6123 ;; Argument 2 is the length
6124 ;; Argument 3 is the alignment
6126 (define_expand "movstrsi"
6127   [(parallel [(set (match_operand:BLK 0 "general_operand" "")
6128                    (match_operand:BLK 1 "general_operand" ""))
6129               (use (match_operand:SI 2 "arith32_operand" ""))
6130               (use (match_operand:SI 3 "immediate_operand" ""))])]
6131   "!TARGET_MIPS16"
6132   "
6134   if (operands[0])              /* avoid unused code messages */
6135     {
6136       expand_block_move (operands);
6137       DONE;
6138     }
6141 ;; Insn generated by block moves
6143 (define_insn "movstrsi_internal"
6144   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6145         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6146    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6147    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6148    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6149    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6150    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6151    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6152    (use (const_int 0))]                                 ;; normal block move
6153   ""
6154   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6155   [(set_attr "type"     "store")
6156    (set_attr "mode"     "none")
6157    (set_attr "length"   "80")])
6159 ;; We need mips16 versions, because an offset from the stack pointer
6160 ;; is not offsettable, since the stack pointer can only handle 4 and 8
6161 ;; byte loads.
6163 (define_insn ""
6164   [(set (match_operand:BLK 0 "memory_operand" "=d")     ;; destination
6165         (match_operand:BLK 1 "memory_operand" "d"))     ;; source
6166    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6167    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6168    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6169    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6170    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6171    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6172    (use (const_int 0))]                                 ;; normal block move
6173   "TARGET_MIPS16"
6174   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6175   [(set_attr "type"     "multi")
6176    (set_attr "mode"     "none")
6177    (set_attr "length"   "80")])
6179 (define_insn ""
6180   [(set (match_operand:BLK 0 "memory_operand" "=d")     ;; destination
6181         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6182    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6183    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6184    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6185    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6186    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6187    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6188    (use (const_int 0))]                                 ;; normal block move
6189   "TARGET_MIPS16"
6190   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6191   [(set_attr "type"     "multi")
6192    (set_attr "mode"     "none")
6193    (set_attr "length"   "80")])
6195 (define_insn ""
6196   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6197         (match_operand:BLK 1 "memory_operand" "d"))     ;; source
6198    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6199    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6200    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6201    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6202    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6203    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6204    (use (const_int 0))]                                 ;; normal block move
6205   "TARGET_MIPS16"
6206   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
6207   [(set_attr "type"     "multi")
6208    (set_attr "mode"     "none")
6209    (set_attr "length"   "80")])
6211 ;; Split a block move into 2 parts, the first part is everything
6212 ;; except for the last move, and the second part is just the last
6213 ;; store, which is exactly 1 instruction (ie, not a usw), so it can
6214 ;; fill a delay slot.  This also prevents a bug in delayed branches
6215 ;; from showing up, which reuses one of the registers in our clobbers.
6217 (define_split
6218   [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
6219         (mem:BLK (match_operand:SI 1 "register_operand" "")))
6220    (clobber (match_operand:SI 4 "register_operand" ""))
6221    (clobber (match_operand:SI 5 "register_operand" ""))
6222    (clobber (match_operand:SI 6 "register_operand" ""))
6223    (clobber (match_operand:SI 7 "register_operand" ""))
6224    (use (match_operand:SI 2 "small_int" ""))
6225    (use (match_operand:SI 3 "small_int" ""))
6226    (use (const_int 0))]
6228   "reload_completed && !TARGET_DEBUG_D_MODE && INTVAL (operands[2]) > 0"
6230   ;; All but the last move
6231   [(parallel [(set (mem:BLK (match_dup 0))
6232                    (mem:BLK (match_dup 1)))
6233               (clobber (match_dup 4))
6234               (clobber (match_dup 5))
6235               (clobber (match_dup 6))
6236               (clobber (match_dup 7))
6237               (use (match_dup 2))
6238               (use (match_dup 3))
6239               (use (const_int 1))])
6241    ;; The last store, so it can fill a delay slot
6242    (parallel [(set (mem:BLK (match_dup 0))
6243                    (mem:BLK (match_dup 1)))
6244               (clobber (match_dup 4))
6245               (clobber (match_dup 5))
6246               (clobber (match_dup 6))
6247               (clobber (match_dup 7))
6248               (use (match_dup 2))
6249               (use (match_dup 3))
6250               (use (const_int 2))])]
6252   "")
6254 (define_insn "movstrsi_internal2"
6255   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
6256         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
6257    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6258    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6259    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6260    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6261    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6262    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6263    (use (const_int 1))]                                 ;; all but last store
6264   ""
6265   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6266   [(set_attr "type"     "store")
6267    (set_attr "mode"     "none")
6268    (set_attr "length"   "80")])
6270 (define_insn ""
6271   [(set (match_operand:BLK 0 "memory_operand" "=d")     ;; destination
6272         (match_operand:BLK 1 "memory_operand" "d"))     ;; source
6273    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6274    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6275    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6276    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6277    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6278    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6279    (use (const_int 1))]                                 ;; all but last store
6280   "TARGET_MIPS16"
6281   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
6282   [(set_attr "type"     "multi")
6283    (set_attr "mode"     "none")
6284    (set_attr "length"   "80")])
6286 (define_insn "movstrsi_internal3"
6287   [(set (match_operand:BLK 0 "memory_operand" "=Ro")    ;; destination
6288         (match_operand:BLK 1 "memory_operand" "Ro"))    ;; source
6289    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6290    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6291    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6292    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6293    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6294    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6295    (use (const_int 2))]                                 ;; just last store of block move
6296   ""
6297   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
6298   [(set_attr "type"     "store")
6299    (set_attr "mode"     "none")])
6301 (define_insn ""
6302   [(set (match_operand:BLK 0 "memory_operand" "=d")     ;; destination
6303         (match_operand:BLK 1 "memory_operand" "d"))     ;; source
6304    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
6305    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
6306    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
6307    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
6308    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
6309    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
6310    (use (const_int 2))]                                 ;; just last store of block move
6311   "TARGET_MIPS16"
6312   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
6313   [(set_attr "type"     "store")
6314    (set_attr "mode"     "none")])
6318 ;;  ....................
6320 ;;      SHIFTS
6322 ;;  ....................
6324 ;; Many of these instructions uses trivial define_expands, because we
6325 ;; want to use a different set of constraints when TARGET_MIPS16.
6327 (define_expand "ashlsi3"
6328   [(set (match_operand:SI 0 "register_operand" "=d")
6329         (ashift:SI (match_operand:SI 1 "register_operand" "d")
6330                    (match_operand:SI 2 "arith_operand" "dI")))]
6331   ""
6332   "
6334   /* On the mips16, a shift of more than 8 is a four byte instruction,
6335      so, for a shift between 8 and 16, it is just as fast to do two
6336      shifts of 8 or less.  If there is a lot of shifting going on, we
6337      may win in CSE.  Otherwise combine will put the shifts back
6338      together again.  This can be called by function_arg, so we must
6339      be careful not to allocate a new register if we've reached the
6340      reload pass.  */
6341   if (TARGET_MIPS16
6342       && optimize
6343       && GET_CODE (operands[2]) == CONST_INT
6344       && INTVAL (operands[2]) > 8
6345       && INTVAL (operands[2]) <= 16
6346       && ! reload_in_progress
6347       && ! reload_completed)
6348     {
6349       rtx temp = gen_reg_rtx (SImode);
6351       emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
6352       emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
6353                                         GEN_INT (INTVAL (operands[2]) - 8)));
6354       DONE;
6355     }
6358 (define_insn "ashlsi3_internal1"
6359   [(set (match_operand:SI 0 "register_operand" "=d")
6360         (ashift:SI (match_operand:SI 1 "register_operand" "d")
6361                    (match_operand:SI 2 "arith_operand" "dI")))]
6362   "!TARGET_MIPS16"
6363   "*
6365   if (GET_CODE (operands[2]) == CONST_INT)
6366     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6368   return \"sll\\t%0,%1,%2\";
6370   [(set_attr "type"     "arith")
6371    (set_attr "mode"     "SI")])
6373 (define_insn "ashlsi3_internal2"
6374   [(set (match_operand:SI 0 "register_operand" "=d,d")
6375         (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
6376                    (match_operand:SI 2 "arith_operand" "d,I")))]
6377   "TARGET_MIPS16"
6378   "*
6380   if (which_alternative == 0)
6381     return \"sll\\t%0,%2\";
6383   if (GET_CODE (operands[2]) == CONST_INT)
6384     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6386   return \"sll\\t%0,%1,%2\";
6388   [(set_attr "type"     "arith")
6389    (set_attr "mode"     "SI")
6390    (set_attr_alternative "length"
6391                 [(const_int 4)
6392                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6393                                (const_int 4)
6394                                (const_int 8))])])
6396 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6398 (define_split
6399   [(set (match_operand:SI 0 "register_operand" "")
6400         (ashift:SI (match_operand:SI 1 "register_operand" "")
6401                    (match_operand:SI 2 "const_int_operand" "")))]
6402   "TARGET_MIPS16
6403    && reload_completed
6404    && GET_CODE (operands[2]) == CONST_INT
6405    && INTVAL (operands[2]) > 8
6406    && INTVAL (operands[2]) <= 16"
6407   [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
6408    (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
6411   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6414 (define_expand "ashldi3"
6415   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6416                    (ashift:DI (match_operand:DI 1 "se_register_operand" "")
6417                               (match_operand:SI 2 "arith_operand" "")))
6418               (clobber (match_dup  3))])]
6419   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6420   "
6422   if (TARGET_64BIT)
6423     {
6424       /* On the mips16, a shift of more than 8 is a four byte
6425          instruction, so, for a shift between 8 and 16, it is just as
6426          fast to do two shifts of 8 or less.  If there is a lot of
6427          shifting going on, we may win in CSE.  Otherwise combine will
6428          put the shifts back together again.  This can be called by
6429          function_arg, so we must be careful not to allocate a new
6430          register if we've reached the reload pass.  */
6431       if (TARGET_MIPS16
6432           && optimize
6433           && GET_CODE (operands[2]) == CONST_INT
6434           && INTVAL (operands[2]) > 8
6435           && INTVAL (operands[2]) <= 16
6436           && ! reload_in_progress
6437           && ! reload_completed)
6438         {
6439           rtx temp = gen_reg_rtx (DImode);
6441           emit_insn (gen_ashldi3_internal4 (temp, operands[1], GEN_INT (8)));
6442           emit_insn (gen_ashldi3_internal4 (operands[0], temp,
6443                                             GEN_INT (INTVAL (operands[2]) - 8)));
6444           DONE;
6445         }
6447       emit_insn (gen_ashldi3_internal4 (operands[0], operands[1],
6448                                         operands[2]));
6449       DONE;
6450     }
6452   operands[3] = gen_reg_rtx (SImode);
6456 (define_insn "ashldi3_internal"
6457   [(set (match_operand:DI 0 "register_operand" "=&d")
6458         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6459                    (match_operand:SI 2 "register_operand" "d")))
6460    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6461   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
6462   "* 
6464   operands[4] = const0_rtx;
6465   dslots_jump_total += 3;
6466   dslots_jump_filled += 2;
6468   return \"sll\\t%3,%2,26\\n\\
6469 \\tbgez\\t%3,1f\\n\\
6470 \\tsll\\t%M0,%L1,%2\\n\\
6471 \\t%(b\\t3f\\n\\
6472 \\tmove\\t%L0,%z4%)\\n\\
6473 \\n\\
6474 %~1:\\n\\
6475 \\t%(beq\\t%3,%z4,2f\\n\\
6476 \\tsll\\t%M0,%M1,%2%)\\n\\
6477 \\n\\
6478 \\tsubu\\t%3,%z4,%2\\n\\
6479 \\tsrl\\t%3,%L1,%3\\n\\
6480 \\tor\\t%M0,%M0,%3\\n\\
6481 %~2:\\n\\
6482 \\tsll\\t%L0,%L1,%2\\n\\
6483 %~3:\";
6485   [(set_attr "type"     "darith")
6486    (set_attr "mode"     "SI")
6487    (set_attr "length"   "48")])
6490 (define_insn "ashldi3_internal2"
6491   [(set (match_operand:DI 0 "register_operand" "=d")
6492         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6493                    (match_operand:SI 2 "small_int" "IJK")))
6494    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6495   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6496    && (INTVAL (operands[2]) & 32) != 0"
6497   "*
6499   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6500   operands[4] = const0_rtx;
6501   return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\";
6503   [(set_attr "type"     "darith")
6504    (set_attr "mode"     "DI")
6505    (set_attr "length"   "8")])
6508 (define_split
6509   [(set (match_operand:DI 0 "register_operand" "")
6510         (ashift:DI (match_operand:DI 1 "register_operand" "")
6511                    (match_operand:SI 2 "small_int" "")))
6512    (clobber (match_operand:SI 3 "register_operand" ""))]
6513   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6514    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6515    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6516    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6517    && (INTVAL (operands[2]) & 32) != 0"
6519   [(set (subreg:SI (match_dup 0) 1) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
6520    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
6522   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6525 (define_split
6526   [(set (match_operand:DI 0 "register_operand" "")
6527         (ashift:DI (match_operand:DI 1 "register_operand" "")
6528                    (match_operand:SI 2 "small_int" "")))
6529    (clobber (match_operand:SI 3 "register_operand" ""))]
6530   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6531    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6532    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6533    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6534    && (INTVAL (operands[2]) & 32) != 0"
6536   [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
6537    (set (subreg:SI (match_dup 0) 1) (const_int 0))]
6539   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6542 (define_insn "ashldi3_internal3"
6543   [(set (match_operand:DI 0 "register_operand" "=d")
6544         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6545                    (match_operand:SI 2 "small_int" "IJK")))
6546    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6547   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6548    && (INTVAL (operands[2]) & 63) < 32
6549    && (INTVAL (operands[2]) & 63) != 0"
6550   "*
6552   int amount = INTVAL (operands[2]);
6554   operands[2] = GEN_INT ((amount & 31));
6555   operands[4] = const0_rtx;
6556   operands[5] = GEN_INT (((-amount) & 31));
6558   return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\";
6560   [(set_attr "type"     "darith")
6561    (set_attr "mode"     "DI")
6562    (set_attr "length"   "16")])
6565 (define_split
6566   [(set (match_operand:DI 0 "register_operand" "")
6567         (ashift:DI (match_operand:DI 1 "register_operand" "")
6568                    (match_operand:SI 2 "small_int" "")))
6569    (clobber (match_operand:SI 3 "register_operand" ""))]
6570   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6571    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6572    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6573    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6574    && (INTVAL (operands[2]) & 63) < 32
6575    && (INTVAL (operands[2]) & 63) != 0"
6577   [(set (subreg:SI (match_dup 0) 1)
6578         (ashift:SI (subreg:SI (match_dup 1) 1)
6579                    (match_dup 2)))
6581    (set (match_dup 3)
6582         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6583                      (match_dup 4)))
6585    (set (subreg:SI (match_dup 0) 1)
6586         (ior:SI (subreg:SI (match_dup 0) 1)
6587                 (match_dup 3)))
6589    (set (subreg:SI (match_dup 0) 0)
6590         (ashift:SI (subreg:SI (match_dup 1) 0)
6591                    (match_dup 2)))]
6592   "
6594   int amount = INTVAL (operands[2]);
6595   operands[2] = GEN_INT ((amount & 31));
6596   operands[4] = GEN_INT (((-amount) & 31));
6600 (define_split
6601   [(set (match_operand:DI 0 "register_operand" "")
6602         (ashift:DI (match_operand:DI 1 "register_operand" "")
6603                    (match_operand:SI 2 "small_int" "")))
6604    (clobber (match_operand:SI 3 "register_operand" ""))]
6605   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6606    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6607    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6608    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6609    && (INTVAL (operands[2]) & 63) < 32
6610    && (INTVAL (operands[2]) & 63) != 0"
6612   [(set (subreg:SI (match_dup 0) 0)
6613         (ashift:SI (subreg:SI (match_dup 1) 0)
6614                    (match_dup 2)))
6616    (set (match_dup 3)
6617         (lshiftrt:SI (subreg:SI (match_dup 1) 1)
6618                      (match_dup 4)))
6620    (set (subreg:SI (match_dup 0) 0)
6621         (ior:SI (subreg:SI (match_dup 0) 0)
6622                 (match_dup 3)))
6624    (set (subreg:SI (match_dup 0) 1)
6625         (ashift:SI (subreg:SI (match_dup 1) 1)
6626                    (match_dup 2)))]
6627   "
6629   int amount = INTVAL (operands[2]);
6630   operands[2] = GEN_INT ((amount & 31));
6631   operands[4] = GEN_INT (((-amount) & 31));
6635 (define_insn "ashldi3_internal4"
6636   [(set (match_operand:DI 0 "register_operand" "=d")
6637         (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
6638                    (match_operand:SI 2 "arith_operand" "dI")))]
6639   "TARGET_64BIT && !TARGET_MIPS16"
6640   "*
6642   if (GET_CODE (operands[2]) == CONST_INT)
6643     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6645   return \"dsll\\t%0,%1,%2\";
6647   [(set_attr "type"     "arith")
6648    (set_attr "mode"     "DI")])
6650 (define_insn ""
6651   [(set (match_operand:DI 0 "register_operand" "=d,d")
6652         (ashift:DI (match_operand:DI 1 "se_register_operand" "0,d")
6653                    (match_operand:SI 2 "arith_operand" "d,I")))]
6654   "TARGET_64BIT && TARGET_MIPS16"
6655   "*
6657   if (which_alternative == 0)
6658     return \"dsll\\t%0,%2\";
6660   if (GET_CODE (operands[2]) == CONST_INT)
6661     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6663   return \"dsll\\t%0,%1,%2\";
6665   [(set_attr "type"     "arith")
6666    (set_attr "mode"     "DI")
6667    (set_attr_alternative "length"
6668                 [(const_int 4)
6669                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6670                                (const_int 4)
6671                                (const_int 8))])])
6674 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6676 (define_split
6677   [(set (match_operand:DI 0 "register_operand" "")
6678         (ashift:DI (match_operand:DI 1 "register_operand" "")
6679                    (match_operand:SI 2 "const_int_operand" "")))]
6680   "TARGET_MIPS16 && TARGET_64BIT
6681    && reload_completed
6682    && GET_CODE (operands[2]) == CONST_INT
6683    && INTVAL (operands[2]) > 8
6684    && INTVAL (operands[2]) <= 16"
6685   [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
6686    (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
6689   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6692 (define_expand "ashrsi3"
6693   [(set (match_operand:SI 0 "register_operand" "=d")
6694         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6695                      (match_operand:SI 2 "arith_operand" "dI")))]
6696   ""
6697   "
6699   /* On the mips16, a shift of more than 8 is a four byte instruction,
6700      so, for a shift between 8 and 16, it is just as fast to do two
6701      shifts of 8 or less.  If there is a lot of shifting going on, we
6702      may win in CSE.  Otherwise combine will put the shifts back
6703      together again.  */
6704   if (TARGET_MIPS16
6705       && optimize
6706       && GET_CODE (operands[2]) == CONST_INT
6707       && INTVAL (operands[2]) > 8
6708       && INTVAL (operands[2]) <= 16)
6709     {
6710       rtx temp = gen_reg_rtx (SImode);
6712       emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
6713       emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
6714                                         GEN_INT (INTVAL (operands[2]) - 8)));
6715       DONE;
6716     }
6719 (define_insn "ashrsi3_internal1"
6720   [(set (match_operand:SI 0 "register_operand" "=d")
6721         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6722                      (match_operand:SI 2 "arith_operand" "dI")))]
6723   "!TARGET_MIPS16"
6724   "*
6726   if (GET_CODE (operands[2]) == CONST_INT)
6727     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6729   return \"sra\\t%0,%1,%2\";
6731   [(set_attr "type"     "arith")
6732    (set_attr "mode"     "SI")])
6734 (define_insn "ashrsi3_internal2"
6735   [(set (match_operand:SI 0 "register_operand" "=d,d")
6736         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
6737                      (match_operand:SI 2 "arith_operand" "d,I")))]
6738   "TARGET_MIPS16"
6739   "*
6741   if (which_alternative == 0)
6742     return \"sra\\t%0,%2\";
6744   if (GET_CODE (operands[2]) == CONST_INT)
6745     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6747   return \"sra\\t%0,%1,%2\";
6749   [(set_attr "type"     "arith")
6750    (set_attr "mode"     "SI")
6751    (set_attr_alternative "length"
6752                 [(const_int 4)
6753                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6754                                (const_int 4)
6755                                (const_int 8))])])
6758 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6760 (define_split
6761   [(set (match_operand:SI 0 "register_operand" "")
6762         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
6763                      (match_operand:SI 2 "const_int_operand" "")))]
6764   "TARGET_MIPS16
6765    && reload_completed
6766    && GET_CODE (operands[2]) == CONST_INT
6767    && INTVAL (operands[2]) > 8
6768    && INTVAL (operands[2]) <= 16"
6769   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
6770    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
6773   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6776 (define_expand "ashrdi3"
6777   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6778                    (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "")
6779                                 (match_operand:SI 2 "arith_operand" "")))
6780               (clobber (match_dup  3))])]
6781   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6782   "
6784   if (TARGET_64BIT)
6785     {
6786       /* On the mips16, a shift of more than 8 is a four byte
6787          instruction, so, for a shift between 8 and 16, it is just as
6788          fast to do two shifts of 8 or less.  If there is a lot of
6789          shifting going on, we may win in CSE.  Otherwise combine will
6790          put the shifts back together again.  */
6791       if (TARGET_MIPS16
6792           && optimize
6793           && GET_CODE (operands[2]) == CONST_INT
6794           && INTVAL (operands[2]) > 8
6795           && INTVAL (operands[2]) <= 16)
6796         {
6797           rtx temp = gen_reg_rtx (DImode);
6799           emit_insn (gen_ashrdi3_internal4 (temp, operands[1], GEN_INT (8)));
6800           emit_insn (gen_ashrdi3_internal4 (operands[0], temp,
6801                                             GEN_INT (INTVAL (operands[2]) - 8)));
6802           DONE;
6803         }
6805       emit_insn (gen_ashrdi3_internal4 (operands[0], operands[1],
6806                                         operands[2]));
6807       DONE;
6808     }
6810   operands[3] = gen_reg_rtx (SImode);
6814 (define_insn "ashrdi3_internal"
6815   [(set (match_operand:DI 0 "register_operand" "=&d")
6816         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
6817                      (match_operand:SI 2 "register_operand" "d")))
6818    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6819   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
6820   "* 
6822   operands[4] = const0_rtx;
6823   dslots_jump_total += 3;
6824   dslots_jump_filled += 2;
6826   return \"sll\\t%3,%2,26\\n\\
6827 \\tbgez\\t%3,1f\\n\\
6828 \\tsra\\t%L0,%M1,%2\\n\\
6829 \\t%(b\\t3f\\n\\
6830 \\tsra\\t%M0,%M1,31%)\\n\\
6831 \\n\\
6832 %~1:\\n\\
6833 \\t%(beq\\t%3,%z4,2f\\n\\
6834 \\tsrl\\t%L0,%L1,%2%)\\n\\
6835 \\n\\
6836 \\tsubu\\t%3,%z4,%2\\n\\
6837 \\tsll\\t%3,%M1,%3\\n\\
6838 \\tor\\t%L0,%L0,%3\\n\\
6839 %~2:\\n\\
6840 \\tsra\\t%M0,%M1,%2\\n\\
6841 %~3:\";
6843   [(set_attr "type"     "darith")
6844    (set_attr "mode"     "DI")
6845    (set_attr "length"   "48")])
6848 (define_insn "ashrdi3_internal2"
6849   [(set (match_operand:DI 0 "register_operand" "=d")
6850         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
6851                      (match_operand:SI 2 "small_int" "IJK")))
6852    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6853   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
6854   "*
6856   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6857   return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\";
6859   [(set_attr "type"     "darith")
6860    (set_attr "mode"     "DI")
6861    (set_attr "length"   "8")])
6864 (define_split
6865   [(set (match_operand:DI 0 "register_operand" "")
6866         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6867                      (match_operand:SI 2 "small_int" "")))
6868    (clobber (match_operand:SI 3 "register_operand" ""))]
6869   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
6870    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6871    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6872    && (INTVAL (operands[2]) & 32) != 0"
6874   [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
6875    (set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (const_int 31)))]
6877   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6880 (define_split
6881   [(set (match_operand:DI 0 "register_operand" "")
6882         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6883                      (match_operand:SI 2 "small_int" "")))
6884    (clobber (match_operand:SI 3 "register_operand" ""))]
6885   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
6886    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6887    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6888    && (INTVAL (operands[2]) & 32) != 0"
6890   [(set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
6891    (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
6893   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
6896 (define_insn "ashrdi3_internal3"
6897   [(set (match_operand:DI 0 "register_operand" "=d")
6898         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
6899                      (match_operand:SI 2 "small_int" "IJK")))
6900    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6901   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6902    && (INTVAL (operands[2]) & 63) < 32
6903    && (INTVAL (operands[2]) & 63) != 0"
6904   "*
6906   int amount = INTVAL (operands[2]);
6908   operands[2] = GEN_INT ((amount & 31));
6909   operands[4] = GEN_INT (((-amount) & 31));
6911   return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\";
6913   [(set_attr "type"     "darith")
6914    (set_attr "mode"     "DI")
6915    (set_attr "length"   "16")])
6918 (define_split
6919   [(set (match_operand:DI 0 "register_operand" "")
6920         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6921                      (match_operand:SI 2 "small_int" "")))
6922    (clobber (match_operand:SI 3 "register_operand" ""))]
6923   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6924    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6925    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6926    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6927    && (INTVAL (operands[2]) & 63) < 32
6928    && (INTVAL (operands[2]) & 63) != 0"
6930   [(set (subreg:SI (match_dup 0) 0)
6931         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6932                      (match_dup 2)))
6934    (set (match_dup 3)
6935         (ashift:SI (subreg:SI (match_dup 1) 1)
6936                    (match_dup 4)))
6938    (set (subreg:SI (match_dup 0) 0)
6939         (ior:SI (subreg:SI (match_dup 0) 0)
6940                 (match_dup 3)))
6942    (set (subreg:SI (match_dup 0) 1)
6943         (ashiftrt:SI (subreg:SI (match_dup 1) 1)
6944                      (match_dup 2)))]
6945   "
6947   int amount = INTVAL (operands[2]);
6948   operands[2] = GEN_INT ((amount & 31));
6949   operands[4] = GEN_INT (((-amount) & 31));
6953 (define_split
6954   [(set (match_operand:DI 0 "register_operand" "")
6955         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6956                      (match_operand:SI 2 "small_int" "")))
6957    (clobber (match_operand:SI 3 "register_operand" ""))]
6958   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6959    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6960    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6961    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6962    && (INTVAL (operands[2]) & 63) < 32
6963    && (INTVAL (operands[2]) & 63) != 0"
6965   [(set (subreg:SI (match_dup 0) 1)
6966         (lshiftrt:SI (subreg:SI (match_dup 1) 1)
6967                      (match_dup 2)))
6969    (set (match_dup 3)
6970         (ashift:SI (subreg:SI (match_dup 1) 0)
6971                    (match_dup 4)))
6973    (set (subreg:SI (match_dup 0) 1)
6974         (ior:SI (subreg:SI (match_dup 0) 1)
6975                 (match_dup 3)))
6977    (set (subreg:SI (match_dup 0) 0)
6978         (ashiftrt:SI (subreg:SI (match_dup 1) 0)
6979                      (match_dup 2)))]
6980   "
6982   int amount = INTVAL (operands[2]);
6983   operands[2] = GEN_INT ((amount & 31));
6984   operands[4] = GEN_INT (((-amount) & 31));
6988 (define_insn "ashrdi3_internal4"
6989   [(set (match_operand:DI 0 "register_operand" "=d")
6990         (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
6991                      (match_operand:SI 2 "arith_operand" "dI")))]
6992   "TARGET_64BIT && !TARGET_MIPS16"
6993   "*
6995   if (GET_CODE (operands[2]) == CONST_INT)
6996     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6998   return \"dsra\\t%0,%1,%2\";
7000   [(set_attr "type"     "arith")
7001    (set_attr "mode"     "DI")])
7003 (define_insn ""
7004   [(set (match_operand:DI 0 "register_operand" "=d,d")
7005         (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
7006                      (match_operand:SI 2 "arith_operand" "d,I")))]
7007   "TARGET_64BIT && TARGET_MIPS16"
7008   "*
7010   if (GET_CODE (operands[2]) == CONST_INT)
7011     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7013   return \"dsra\\t%0,%2\";
7015   [(set_attr "type"     "arith")
7016    (set_attr "mode"     "DI")
7017    (set_attr_alternative "length"
7018                 [(const_int 4)
7019                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7020                                (const_int 4)
7021                                (const_int 8))])])
7023 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7025 (define_split
7026   [(set (match_operand:DI 0 "register_operand" "")
7027         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
7028                      (match_operand:SI 2 "const_int_operand" "")))]
7029   "TARGET_MIPS16 && TARGET_64BIT
7030    && reload_completed
7031    && GET_CODE (operands[2]) == CONST_INT
7032    && INTVAL (operands[2]) > 8
7033    && INTVAL (operands[2]) <= 16"
7034   [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
7035    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
7038   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7041 (define_expand "lshrsi3"
7042   [(set (match_operand:SI 0 "register_operand" "=d")
7043         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7044                      (match_operand:SI 2 "arith_operand" "dI")))]
7045   ""
7046   "
7048   /* On the mips16, a shift of more than 8 is a four byte instruction,
7049      so, for a shift between 8 and 16, it is just as fast to do two
7050      shifts of 8 or less.  If there is a lot of shifting going on, we
7051      may win in CSE.  Otherwise combine will put the shifts back
7052      together again.  */
7053   if (TARGET_MIPS16
7054       && optimize
7055       && GET_CODE (operands[2]) == CONST_INT
7056       && INTVAL (operands[2]) > 8
7057       && INTVAL (operands[2]) <= 16)
7058     {
7059       rtx temp = gen_reg_rtx (SImode);
7061       emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
7062       emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
7063                                         GEN_INT (INTVAL (operands[2]) - 8)));
7064       DONE;
7065     }
7068 (define_insn "lshrsi3_internal1"
7069   [(set (match_operand:SI 0 "register_operand" "=d")
7070         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
7071                      (match_operand:SI 2 "arith_operand" "dI")))]
7072   "!TARGET_MIPS16"
7073   "*
7075   if (GET_CODE (operands[2]) == CONST_INT)
7076     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7078   return \"srl\\t%0,%1,%2\";
7080   [(set_attr "type"     "arith")
7081    (set_attr "mode"     "SI")])
7083 (define_insn "lshrsi3_internal2"
7084   [(set (match_operand:SI 0 "register_operand" "=d,d")
7085         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
7086                      (match_operand:SI 2 "arith_operand" "d,I")))]
7087   "TARGET_MIPS16"
7088   "*
7090   if (which_alternative == 0)
7091     return \"srl\\t%0,%2\";
7093   if (GET_CODE (operands[2]) == CONST_INT)
7094     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7096   return \"srl\\t%0,%1,%2\";
7098   [(set_attr "type"     "arith")
7099    (set_attr "mode"     "SI")
7100    (set_attr_alternative "length"
7101                 [(const_int 4)
7102                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7103                                (const_int 4)
7104                                (const_int 8))])])
7107 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7109 (define_split
7110   [(set (match_operand:SI 0 "register_operand" "")
7111         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
7112                      (match_operand:SI 2 "const_int_operand" "")))]
7113   "TARGET_MIPS16
7114    && reload_completed
7115    && GET_CODE (operands[2]) == CONST_INT
7116    && INTVAL (operands[2]) > 8
7117    && INTVAL (operands[2]) <= 16"
7118   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
7119    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7122   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7125 ;; If we load a byte on the mips16 as a bitfield, the resulting
7126 ;; sequence of instructions is too complicated for combine, because it
7127 ;; involves four instructions: a load, a shift, a constant load into a
7128 ;; register, and an and (the key problem here is that the mips16 does
7129 ;; not have and immediate).  We recognize a shift of a load in order
7130 ;; to make it simple enough for combine to understand.
7132 (define_insn ""
7133   [(set (match_operand:SI 0 "register_operand" "=d,d")
7134         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "R,m")
7135                      (match_operand:SI 2 "immediate_operand" "I,I")))]
7136   "TARGET_MIPS16"
7137   "lw\\t%0,%1\;srl\\t%0,%2"
7138   [(set_attr "type"     "load")
7139    (set_attr "mode"     "SI")
7140    (set_attr_alternative "length"
7141                 [(if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7142                                (const_int 8)
7143                                (const_int 12))
7144                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7145                                (const_int 12)
7146                                (const_int 16))])])
7148 (define_split
7149   [(set (match_operand:SI 0 "register_operand" "")
7150         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "")
7151                      (match_operand:SI 2 "immediate_operand" "")))]
7152   "TARGET_MIPS16"
7153   [(set (match_dup 0) (match_dup 1))
7154    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
7155   "")
7157 (define_expand "lshrdi3"
7158   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7159                    (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "")
7160                                 (match_operand:SI 2 "arith_operand" "")))
7161               (clobber (match_dup  3))])]
7162   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
7163   "
7165   if (TARGET_64BIT)
7166     {
7167       /* On the mips16, a shift of more than 8 is a four byte
7168          instruction, so, for a shift between 8 and 16, it is just as
7169          fast to do two shifts of 8 or less.  If there is a lot of
7170          shifting going on, we may win in CSE.  Otherwise combine will
7171          put the shifts back together again.  */
7172       if (TARGET_MIPS16
7173           && optimize
7174           && GET_CODE (operands[2]) == CONST_INT
7175           && INTVAL (operands[2]) > 8
7176           && INTVAL (operands[2]) <= 16)
7177         {
7178           rtx temp = gen_reg_rtx (DImode);
7180           emit_insn (gen_lshrdi3_internal4 (temp, operands[1], GEN_INT (8)));
7181           emit_insn (gen_lshrdi3_internal4 (operands[0], temp,
7182                                             GEN_INT (INTVAL (operands[2]) - 8)));
7183           DONE;
7184         }
7186       emit_insn (gen_lshrdi3_internal4 (operands[0], operands[1],
7187                                         operands[2]));
7188       DONE;
7189     }
7191   operands[3] = gen_reg_rtx (SImode);
7195 (define_insn "lshrdi3_internal"
7196   [(set (match_operand:DI 0 "register_operand" "=&d")
7197         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7198                      (match_operand:SI 2 "register_operand" "d")))
7199    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7200   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
7201   "* 
7203   operands[4] = const0_rtx;
7204   dslots_jump_total += 3;
7205   dslots_jump_filled += 2;
7207   return \"sll\\t%3,%2,26\\n\\
7208 \\tbgez\\t%3,1f\\n\\
7209 \\tsrl\\t%L0,%M1,%2\\n\\
7210 \\t%(b\\t3f\\n\\
7211 \\tmove\\t%M0,%z4%)\\n\\
7212 \\n\\
7213 %~1:\\n\\
7214 \\t%(beq\\t%3,%z4,2f\\n\\
7215 \\tsrl\\t%L0,%L1,%2%)\\n\\
7216 \\n\\
7217 \\tsubu\\t%3,%z4,%2\\n\\
7218 \\tsll\\t%3,%M1,%3\\n\\
7219 \\tor\\t%L0,%L0,%3\\n\\
7220 %~2:\\n\\
7221 \\tsrl\\t%M0,%M1,%2\\n\\
7222 %~3:\";
7224   [(set_attr "type"     "darith")
7225    (set_attr "mode"     "DI")
7226    (set_attr "length"   "48")])
7229 (define_insn "lshrdi3_internal2"
7230   [(set (match_operand:DI 0 "register_operand" "=d")
7231         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7232                      (match_operand:SI 2 "small_int" "IJK")))
7233    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7234   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7235    && (INTVAL (operands[2]) & 32) != 0"
7236   "*
7238   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7239   operands[4] = const0_rtx;
7240   return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\";
7242   [(set_attr "type"     "darith")
7243    (set_attr "mode"     "DI")
7244    (set_attr "length"   "8")])
7247 (define_split
7248   [(set (match_operand:DI 0 "register_operand" "")
7249         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7250                      (match_operand:SI 2 "small_int" "")))
7251    (clobber (match_operand:SI 3 "register_operand" ""))]
7252   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7253    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7254    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7255    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7256    && (INTVAL (operands[2]) & 32) != 0"
7258   [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
7259    (set (subreg:SI (match_dup 0) 1) (const_int 0))]
7261   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7264 (define_split
7265   [(set (match_operand:DI 0 "register_operand" "")
7266         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7267                      (match_operand:SI 2 "small_int" "")))
7268    (clobber (match_operand:SI 3 "register_operand" ""))]
7269   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7270    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7271    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7272    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7273    && (INTVAL (operands[2]) & 32) != 0"
7275   [(set (subreg:SI (match_dup 0) 1) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
7276    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
7278   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
7281 (define_insn "lshrdi3_internal3"
7282   [(set (match_operand:DI 0 "register_operand" "=d")
7283         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
7284                    (match_operand:SI 2 "small_int" "IJK")))
7285    (clobber (match_operand:SI 3 "register_operand" "=d"))]
7286   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7287    && (INTVAL (operands[2]) & 63) < 32
7288    && (INTVAL (operands[2]) & 63) != 0"
7289   "*
7291   int amount = INTVAL (operands[2]);
7293   operands[2] = GEN_INT ((amount & 31));
7294   operands[4] = GEN_INT (((-amount) & 31));
7296   return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\";
7298   [(set_attr "type"     "darith")
7299    (set_attr "mode"     "DI")
7300    (set_attr "length"   "16")])
7303 (define_split
7304   [(set (match_operand:DI 0 "register_operand" "")
7305         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7306                      (match_operand:SI 2 "small_int" "")))
7307    (clobber (match_operand:SI 3 "register_operand" ""))]
7308   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
7309    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7310    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7311    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7312    && (INTVAL (operands[2]) & 63) < 32
7313    && (INTVAL (operands[2]) & 63) != 0"
7315   [(set (subreg:SI (match_dup 0) 0)
7316         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7317                      (match_dup 2)))
7319    (set (match_dup 3)
7320         (ashift:SI (subreg:SI (match_dup 1) 1)
7321                    (match_dup 4)))
7323    (set (subreg:SI (match_dup 0) 0)
7324         (ior:SI (subreg:SI (match_dup 0) 0)
7325                 (match_dup 3)))
7327    (set (subreg:SI (match_dup 0) 1)
7328         (lshiftrt:SI (subreg:SI (match_dup 1) 1)
7329                      (match_dup 2)))]
7330   "
7332   int amount = INTVAL (operands[2]);
7333   operands[2] = GEN_INT ((amount & 31));
7334   operands[4] = GEN_INT (((-amount) & 31));
7338 (define_split
7339   [(set (match_operand:DI 0 "register_operand" "")
7340         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7341                      (match_operand:SI 2 "small_int" "")))
7342    (clobber (match_operand:SI 3 "register_operand" ""))]
7343   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
7344    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
7345    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
7346    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
7347    && (INTVAL (operands[2]) & 63) < 32
7348    && (INTVAL (operands[2]) & 63) != 0"
7350   [(set (subreg:SI (match_dup 0) 1)
7351         (lshiftrt:SI (subreg:SI (match_dup 1) 1)
7352                      (match_dup 2)))
7354    (set (match_dup 3)
7355         (ashift:SI (subreg:SI (match_dup 1) 0)
7356                    (match_dup 4)))
7358    (set (subreg:SI (match_dup 0) 1)
7359         (ior:SI (subreg:SI (match_dup 0) 1)
7360                 (match_dup 3)))
7362    (set (subreg:SI (match_dup 0) 0)
7363         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
7364                      (match_dup 2)))]
7365   "
7367   int amount = INTVAL (operands[2]);
7368   operands[2] = GEN_INT ((amount & 31));
7369   operands[4] = GEN_INT (((-amount) & 31));
7373 (define_insn "lshrdi3_internal4"
7374   [(set (match_operand:DI 0 "register_operand" "=d")
7375         (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
7376                      (match_operand:SI 2 "arith_operand" "dI")))]
7377   "TARGET_64BIT && !TARGET_MIPS16"
7378   "*
7380   if (GET_CODE (operands[2]) == CONST_INT)
7381     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7383   return \"dsrl\\t%0,%1,%2\";
7385   [(set_attr "type"     "arith")
7386    (set_attr "mode"     "DI")])
7388 (define_insn ""
7389   [(set (match_operand:DI 0 "register_operand" "=d,d")
7390         (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
7391                      (match_operand:SI 2 "arith_operand" "d,I")))]
7392   "TARGET_64BIT && TARGET_MIPS16"
7393   "*
7395   if (GET_CODE (operands[2]) == CONST_INT)
7396     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7398   return \"dsrl\\t%0,%2\";
7400   [(set_attr "type"     "arith")
7401    (set_attr "mode"     "DI")
7402    (set_attr_alternative "length"
7403                 [(const_int 4)
7404                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
7405                                (const_int 4)
7406                                (const_int 8))])])
7408 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
7410 (define_split
7411   [(set (match_operand:DI 0 "register_operand" "")
7412         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
7413                      (match_operand:SI 2 "const_int_operand" "")))]
7414   "TARGET_MIPS16
7415    && reload_completed
7416    && GET_CODE (operands[2]) == CONST_INT
7417    && INTVAL (operands[2]) > 8
7418    && INTVAL (operands[2]) <= 16"
7419   [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
7420    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
7423   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
7428 ;;  ....................
7430 ;;      COMPARISONS
7432 ;;  ....................
7434 ;; Flow here is rather complex:
7436 ;;  1)  The cmp{si,di,sf,df} routine is called.  It deposits the
7437 ;;      arguments into the branch_cmp array, and the type into
7438 ;;      branch_type.  No RTL is generated.
7440 ;;  2)  The appropriate branch define_expand is called, which then
7441 ;;      creates the appropriate RTL for the comparison and branch.
7442 ;;      Different CC modes are used, based on what type of branch is
7443 ;;      done, so that we can constrain things appropriately.  There
7444 ;;      are assumptions in the rest of GCC that break if we fold the
7445 ;;      operands into the branchs for integer operations, and use cc0
7446 ;;      for floating point, so we use the fp status register instead.
7447 ;;      If needed, an appropriate temporary is created to hold the
7448 ;;      of the integer compare.
7450 (define_expand "cmpsi"
7451   [(set (cc0)
7452         (compare:CC (match_operand:SI 0 "register_operand" "")
7453                     (match_operand:SI 1 "arith_operand" "")))]
7454   ""
7455   "
7457   if (operands[0])              /* avoid unused code message */
7458     {
7459       branch_cmp[0] = operands[0];
7460       branch_cmp[1] = operands[1];
7461       branch_type = CMP_SI;
7462       DONE;
7463     }
7466 (define_expand "tstsi"
7467   [(set (cc0)
7468         (match_operand:SI 0 "register_operand" ""))]
7469   ""
7470   "
7472   if (operands[0])              /* avoid unused code message */
7473     {
7474       branch_cmp[0] = operands[0];
7475       branch_cmp[1] = const0_rtx;
7476       branch_type = CMP_SI;
7477       DONE;
7478     }
7481 (define_expand "cmpdi"
7482   [(set (cc0)
7483         (compare:CC (match_operand:DI 0 "se_register_operand" "")
7484                     (match_operand:DI 1 "se_arith_operand" "")))]
7485   "TARGET_64BIT"
7486   "
7488   if (operands[0])              /* avoid unused code message */
7489     {
7490       branch_cmp[0] = operands[0];
7491       branch_cmp[1] = operands[1];
7492       branch_type = CMP_DI;
7493       DONE;
7494     }
7497 (define_expand "tstdi"
7498   [(set (cc0)
7499         (match_operand:DI 0 "se_register_operand" ""))]
7500   "TARGET_64BIT"
7501   "
7503   if (operands[0])              /* avoid unused code message */
7504     {
7505       branch_cmp[0] = operands[0];
7506       branch_cmp[1] = const0_rtx;
7507       branch_type = CMP_DI;
7508       DONE;
7509     }
7512 (define_expand "cmpdf"
7513   [(set (cc0)
7514         (compare:CC (match_operand:DF 0 "register_operand" "")
7515                     (match_operand:DF 1 "register_operand" "")))]
7516   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7517   "
7519   if (operands[0])              /* avoid unused code message */
7520     {
7521       branch_cmp[0] = operands[0];
7522       branch_cmp[1] = operands[1];
7523       branch_type = CMP_DF;
7524       DONE;
7525     }
7528 (define_expand "cmpsf"
7529   [(set (cc0)
7530         (compare:CC (match_operand:SF 0 "register_operand" "")
7531                     (match_operand:SF 1 "register_operand" "")))]
7532   "TARGET_HARD_FLOAT"
7533   "
7535   if (operands[0])              /* avoid unused code message */
7536     {
7537       branch_cmp[0] = operands[0];
7538       branch_cmp[1] = operands[1];
7539       branch_type = CMP_SF;
7540       DONE;
7541     }
7546 ;;  ....................
7548 ;;      CONDITIONAL BRANCHES
7550 ;;  ....................
7552 ;; Conditional branches on floating-point equality tests.
7554 (define_insn "branch_fp"
7555   [(set (pc)
7556         (if_then_else 
7557          (match_operator:CC 0 "cmp_op"
7558                             [(match_operand:CC 2 "register_operand" "z")
7559                              (const_int 0)])
7560          (label_ref (match_operand 1 "" ""))
7561          (pc)))]
7562   "TARGET_HARD_FLOAT"
7563   "*
7565   return mips_output_conditional_branch (insn,
7566                                          operands,
7567                                          /*two_operands_p=*/0,
7568                                          /*float_p=*/1,
7569                                          /*inverted_p=*/0,
7570                                          get_attr_length (insn));
7572   [(set_attr "type"     "branch")
7573    (set_attr "mode"     "none")])
7575 (define_insn "branch_fp_inverted"
7576   [(set (pc)
7577         (if_then_else 
7578          (match_operator:CC 0 "cmp_op"
7579                             [(match_operand:CC 2 "register_operand" "z")
7580                              (const_int 0)])
7581          (pc)
7582          (label_ref (match_operand 1 "" ""))))]
7583   "TARGET_HARD_FLOAT"
7584   "*
7586   return mips_output_conditional_branch (insn,
7587                                          operands,
7588                                          /*two_operands_p=*/0,
7589                                          /*float_p=*/1,
7590                                          /*inverted_p=*/1,
7591                                          get_attr_length (insn));
7593   [(set_attr "type"     "branch")
7594    (set_attr "mode"     "none")])
7596 ;; Conditional branches on comparisons with zero.
7598 (define_insn "branch_zero"
7599   [(set (pc)
7600         (if_then_else 
7601          (match_operator:SI 0 "cmp_op"
7602                             [(match_operand:SI 2 "register_operand" "d")
7603                              (const_int 0)])
7604         (label_ref (match_operand 1 "" ""))
7605         (pc)))]
7606   "!TARGET_MIPS16"
7607   "*
7609   return mips_output_conditional_branch (insn,
7610                                          operands,
7611                                          /*two_operands_p=*/0,
7612                                          /*float_p=*/0,
7613                                          /*inverted_p=*/0,
7614                                          get_attr_length (insn));
7616   [(set_attr "type"     "branch")
7617    (set_attr "mode"     "none")])
7619 (define_insn "branch_zero_inverted"
7620   [(set (pc)
7621         (if_then_else 
7622          (match_operator:SI 0 "cmp_op"
7623                             [(match_operand:SI 2 "register_operand" "d")
7624                              (const_int 0)])
7625         (pc)
7626         (label_ref (match_operand 1 "" ""))))]
7627   "!TARGET_MIPS16"
7628   "*
7630   return mips_output_conditional_branch (insn,
7631                                          operands,
7632                                          /*two_operands_p=*/0,
7633                                          /*float_p=*/0,
7634                                          /*inverted_p=*/1,
7635                                          get_attr_length (insn));
7637   [(set_attr "type"     "branch")
7638    (set_attr "mode"     "none")])
7640 (define_insn "branch_zero_di"
7641   [(set (pc)
7642         (if_then_else 
7643          (match_operator:DI 0 "cmp_op"
7644                             [(match_operand:DI 2 "se_register_operand" "d")
7645                              (const_int 0)])
7646         (label_ref (match_operand 1 "" ""))
7647         (pc)))]
7648   "!TARGET_MIPS16"
7649   "*
7651   return mips_output_conditional_branch (insn,
7652                                          operands,
7653                                          /*two_operands_p=*/0,
7654                                          /*float_p=*/0,
7655                                          /*inverted_p=*/0,
7656                                          get_attr_length (insn));
7658   [(set_attr "type"     "branch")
7659    (set_attr "mode"     "none")])
7661 (define_insn "branch_zero_di_inverted"
7662   [(set (pc)
7663         (if_then_else 
7664          (match_operator:DI 0 "cmp_op"
7665                             [(match_operand:DI 2 "se_register_operand" "d")
7666                              (const_int 0)])
7667         (pc)
7668         (label_ref (match_operand 1 "" ""))))]
7669   "!TARGET_MIPS16"
7670   "*
7672   return mips_output_conditional_branch (insn,
7673                                          operands,
7674                                          /*two_operands_p=*/0,
7675                                          /*float_p=*/0,
7676                                          /*inverted_p=*/1,
7677                                          get_attr_length (insn));
7679   [(set_attr "type"     "branch")
7680    (set_attr "mode"     "none")])
7682 ;; Conditional branch on equality comparision.
7684 (define_insn "branch_equality"
7685   [(set (pc)
7686         (if_then_else 
7687          (match_operator:SI 0 "equality_op"
7688                             [(match_operand:SI 2 "register_operand" "d")
7689                              (match_operand:SI 3 "register_operand" "d")])
7690          (label_ref (match_operand 1 "" ""))
7691          (pc)))]
7692   "!TARGET_MIPS16"
7693   "*
7695   return mips_output_conditional_branch (insn,
7696                                          operands,
7697                                          /*two_operands_p=*/1,
7698                                          /*float_p=*/0,
7699                                          /*inverted_p=*/0,
7700                                          get_attr_length (insn));
7702   [(set_attr "type"     "branch")
7703    (set_attr "mode"     "none")])
7705 (define_insn "branch_equality_di"
7706   [(set (pc)
7707         (if_then_else 
7708          (match_operator:DI 0 "equality_op"
7709                             [(match_operand:DI 2 "se_register_operand" "d")
7710                              (match_operand:DI 3 "se_register_operand" "d")])
7711         (label_ref (match_operand 1 "" ""))
7712         (pc)))]
7713   "!TARGET_MIPS16"
7714   "*
7716   return mips_output_conditional_branch (insn,
7717                                          operands,
7718                                          /*two_operands_p=*/1,
7719                                          /*float_p=*/0,
7720                                          /*inverted_p=*/0,
7721                                          get_attr_length (insn));
7723   [(set_attr "type"     "branch")
7724    (set_attr "mode"     "none")])
7726 (define_insn "branch_equality_inverted"
7727   [(set (pc)
7728         (if_then_else 
7729          (match_operator:SI 0 "equality_op"
7730                             [(match_operand:SI 2 "register_operand" "d")
7731                              (match_operand:SI 3 "register_operand" "d")])
7732          (pc)
7733          (label_ref (match_operand 1 "" ""))))]
7734   "!TARGET_MIPS16"
7735   "*
7737   return mips_output_conditional_branch (insn,
7738                                          operands,
7739                                          /*two_operands_p=*/1,
7740                                          /*float_p=*/0,
7741                                          /*inverted_p=*/1,
7742                                          get_attr_length (insn));
7744   [(set_attr "type"     "branch")
7745    (set_attr "mode"     "none")])
7747 (define_insn "branch_equality_di_inverted"
7748   [(set (pc)
7749         (if_then_else 
7750          (match_operator:DI 0 "equality_op"
7751                             [(match_operand:DI 2 "se_register_operand" "d")
7752                              (match_operand:DI 3 "se_register_operand" "d")])
7753         (pc)
7754         (label_ref (match_operand 1 "" ""))))]
7755   "!TARGET_MIPS16"
7756   "*
7758   return mips_output_conditional_branch (insn,
7759                                          operands,
7760                                          /*two_operands_p=*/1,
7761                                          /*float_p=*/0,
7762                                          /*inverted_p=*/1,
7763                                          get_attr_length (insn));
7765   [(set_attr "type"     "branch")
7766    (set_attr "mode"     "none")])
7768 ;; MIPS16 branches
7770 (define_insn ""
7771   [(set (pc)
7772         (if_then_else (match_operator:SI 0 "equality_op"
7773                                          [(match_operand:SI 1 "register_operand" "d,t")
7774                                           (const_int 0)])
7775         (match_operand 2 "pc_or_label_operand" "")
7776         (match_operand 3 "pc_or_label_operand" "")))]
7777   "TARGET_MIPS16"
7778   "*
7780   if (operands[2] != pc_rtx)
7781     {
7782       if (which_alternative == 0)
7783         return \"%*b%C0z\\t%1,%2\";
7784       else
7785         return \"%*bt%C0z\\t%2\";
7786     }
7787   else
7788     {
7789       if (which_alternative == 0)
7790         return \"%*b%N0z\\t%1,%3\";
7791       else
7792         return \"%*bt%N0z\\t%3\";
7793     }
7795   [(set_attr "type"     "branch")
7796    (set_attr "mode"     "none")
7797    (set_attr "length"   "8")])
7799 (define_insn ""
7800   [(set (pc)
7801         (if_then_else (match_operator:DI 0 "equality_op"
7802                                          [(match_operand:DI 1 "se_register_operand" "d,t")
7803                                           (const_int 0)])
7804         (match_operand 2 "pc_or_label_operand" "")
7805         (match_operand 3 "pc_or_label_operand" "")))]
7806   "TARGET_MIPS16"
7807   "*
7809   if (operands[2] != pc_rtx)
7810     {
7811       if (which_alternative == 0)
7812         return \"%*b%C0z\\t%1,%2\";
7813       else
7814         return \"%*bt%C0z\\t%2\";
7815     }
7816   else
7817     {
7818       if (which_alternative == 0)
7819         return \"%*b%N0z\\t%1,%3\";
7820       else
7821         return \"%*bt%N0z\\t%3\";
7822     }
7824   [(set_attr "type"     "branch")
7825    (set_attr "mode"     "none")
7826    (set_attr "length"   "8")])
7828 (define_expand "beq"
7829   [(set (pc)
7830         (if_then_else (eq:CC (cc0)
7831                              (const_int 0))
7832                       (label_ref (match_operand 0 "" ""))
7833                       (pc)))]
7834   ""
7835   "
7837   if (operands[0])              /* avoid unused code warning */
7838     {
7839       gen_conditional_branch (operands, EQ);
7840       DONE;
7841     }
7844 (define_expand "bne"
7845   [(set (pc)
7846         (if_then_else (ne:CC (cc0)
7847                              (const_int 0))
7848                       (label_ref (match_operand 0 "" ""))
7849                       (pc)))]
7850   ""
7851   "
7853   if (operands[0])              /* avoid unused code warning */
7854     {
7855       gen_conditional_branch (operands, NE);
7856       DONE;
7857     }
7860 (define_expand "bgt"
7861   [(set (pc)
7862         (if_then_else (gt:CC (cc0)
7863                              (const_int 0))
7864                       (label_ref (match_operand 0 "" ""))
7865                       (pc)))]
7866   ""
7867   "
7869   if (operands[0])              /* avoid unused code warning */
7870     {
7871       gen_conditional_branch (operands, GT);
7872       DONE;
7873     }
7876 (define_expand "bge"
7877   [(set (pc)
7878         (if_then_else (ge:CC (cc0)
7879                              (const_int 0))
7880                       (label_ref (match_operand 0 "" ""))
7881                       (pc)))]
7882   ""
7883   "
7885   if (operands[0])              /* avoid unused code warning */
7886     {
7887       gen_conditional_branch (operands, GE);
7888       DONE;
7889     }
7892 (define_expand "blt"
7893   [(set (pc)
7894         (if_then_else (lt:CC (cc0)
7895                              (const_int 0))
7896                       (label_ref (match_operand 0 "" ""))
7897                       (pc)))]
7898   ""
7899   "
7901   if (operands[0])              /* avoid unused code warning */
7902     {
7903       gen_conditional_branch (operands, LT);
7904       DONE;
7905     }
7908 (define_expand "ble"
7909   [(set (pc)
7910         (if_then_else (le:CC (cc0)
7911                              (const_int 0))
7912                       (label_ref (match_operand 0 "" ""))
7913                       (pc)))]
7914   ""
7915   "
7917   if (operands[0])              /* avoid unused code warning */
7918     {
7919       gen_conditional_branch (operands, LE);
7920       DONE;
7921     }
7924 (define_expand "bgtu"
7925   [(set (pc)
7926         (if_then_else (gtu:CC (cc0)
7927                               (const_int 0))
7928                       (label_ref (match_operand 0 "" ""))
7929                       (pc)))]
7930   ""
7931   "
7933   if (operands[0])              /* avoid unused code warning */
7934     {
7935       gen_conditional_branch (operands, GTU);
7936       DONE;
7937     }
7940 (define_expand "bgeu"
7941   [(set (pc)
7942         (if_then_else (geu:CC (cc0)
7943                               (const_int 0))
7944                       (label_ref (match_operand 0 "" ""))
7945                       (pc)))]
7946   ""
7947   "
7949   if (operands[0])              /* avoid unused code warning */
7950     {
7951       gen_conditional_branch (operands, GEU);
7952       DONE;
7953     }
7957 (define_expand "bltu"
7958   [(set (pc)
7959         (if_then_else (ltu:CC (cc0)
7960                               (const_int 0))
7961                       (label_ref (match_operand 0 "" ""))
7962                       (pc)))]
7963   ""
7964   "
7966   if (operands[0])              /* avoid unused code warning */
7967     {
7968       gen_conditional_branch (operands, LTU);
7969       DONE;
7970     }
7973 (define_expand "bleu"
7974   [(set (pc)
7975         (if_then_else (leu:CC (cc0)
7976                               (const_int 0))
7977                       (label_ref (match_operand 0 "" ""))
7978                       (pc)))]
7979   ""
7980   "
7982   if (operands[0])              /* avoid unused code warning */
7983     {
7984       gen_conditional_branch (operands, LEU);
7985       DONE;
7986     }
7991 ;;  ....................
7993 ;;      SETTING A REGISTER FROM A COMPARISON
7995 ;;  ....................
7997 (define_expand "seq"
7998   [(set (match_operand:SI 0 "register_operand" "=d")
7999         (eq:SI (match_dup 1)
8000                (match_dup 2)))]
8001   ""
8002   "
8004   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8005     FAIL;
8007   /* set up operands from compare.  */
8008   operands[1] = branch_cmp[0];
8009   operands[2] = branch_cmp[1];
8011   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8012     {
8013       gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
8014       DONE;
8015     }
8017   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8018     operands[2] = force_reg (SImode, operands[2]);
8020   /* fall through and generate default code */
8024 (define_insn "seq_si_zero"
8025   [(set (match_operand:SI 0 "register_operand" "=d")
8026         (eq:SI (match_operand:SI 1 "register_operand" "d")
8027                (const_int 0)))]
8028   "!TARGET_MIPS16"
8029   "sltu\\t%0,%1,1"
8030   [(set_attr "type"     "arith")
8031    (set_attr "mode"     "SI")])
8033 (define_insn ""
8034   [(set (match_operand:SI 0 "register_operand" "=t")
8035         (eq:SI (match_operand:SI 1 "register_operand" "d")
8036                (const_int 0)))]
8037   "TARGET_MIPS16"
8038   "sltu\\t%1,1"
8039   [(set_attr "type"     "arith")
8040    (set_attr "mode"     "SI")])
8042 (define_insn "seq_di_zero"
8043   [(set (match_operand:DI 0 "register_operand" "=d")
8044         (eq:DI (match_operand:DI 1 "se_register_operand" "d")
8045                (const_int 0)))]
8046   "TARGET_64BIT && !TARGET_MIPS16"
8047   "sltu\\t%0,%1,1"
8048   [(set_attr "type"     "arith")
8049    (set_attr "mode"     "DI")])
8051 (define_insn ""
8052   [(set (match_operand:DI 0 "register_operand" "=t")
8053         (eq:DI (match_operand:DI 1 "se_register_operand" "d")
8054                (const_int 0)))]
8055   "TARGET_64BIT && TARGET_MIPS16"
8056   "sltu\\t%1,1"
8057   [(set_attr "type"     "arith")
8058    (set_attr "mode"     "DI")])
8060 (define_insn "seq_si"
8061   [(set (match_operand:SI 0 "register_operand" "=d,d")
8062         (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
8063                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
8064   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8065   "@
8066    xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8067    xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8068   [(set_attr "type"     "arith")
8069    (set_attr "mode"     "SI")
8070    (set_attr "length"   "8")])
8072 (define_split
8073   [(set (match_operand:SI 0 "register_operand" "")
8074         (eq:SI (match_operand:SI 1 "register_operand" "")
8075                (match_operand:SI 2 "uns_arith_operand" "")))]
8076   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
8077     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8078   [(set (match_dup 0)
8079         (xor:SI (match_dup 1)
8080                 (match_dup 2)))
8081    (set (match_dup 0)
8082         (ltu:SI (match_dup 0)
8083                 (const_int 1)))]
8084   "")
8086 (define_insn "seq_di"
8087   [(set (match_operand:DI 0 "register_operand" "=d,d")
8088         (eq:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8089                (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
8090   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8091   "@
8092    xor\\t%0,%1,%2\;sltu\\t%0,%0,1
8093    xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
8094   [(set_attr "type"     "arith")
8095    (set_attr "mode"     "DI")
8096    (set_attr "length"   "8")])
8098 (define_split
8099   [(set (match_operand:DI 0 "register_operand" "")
8100         (eq:DI (match_operand:DI 1 "se_register_operand" "")
8101                (match_operand:DI 2 "se_uns_arith_operand" "")))]
8102   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8103     && !TARGET_MIPS16
8104     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8105   [(set (match_dup 0)
8106         (xor:DI (match_dup 1)
8107                 (match_dup 2)))
8108    (set (match_dup 0)
8109         (ltu:DI (match_dup 0)
8110                 (const_int 1)))]
8111   "")
8113 ;; On the mips16 the default code is better than using sltu.
8115 (define_expand "sne"
8116   [(set (match_operand:SI 0 "register_operand" "=d")
8117         (ne:SI (match_dup 1)
8118                (match_dup 2)))]
8119   "!TARGET_MIPS16"
8120   "
8122   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8123     FAIL;
8125   /* set up operands from compare.  */
8126   operands[1] = branch_cmp[0];
8127   operands[2] = branch_cmp[1];
8129   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
8130     {
8131       gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
8132       DONE;
8133     }
8135   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8136     operands[2] = force_reg (SImode, operands[2]);
8138   /* fall through and generate default code */
8141 (define_insn "sne_si_zero"
8142   [(set (match_operand:SI 0 "register_operand" "=d")
8143         (ne:SI (match_operand:SI 1 "register_operand" "d")
8144                (const_int 0)))]
8145   "!TARGET_MIPS16"
8146   "sltu\\t%0,%.,%1"
8147   [(set_attr "type"     "arith")
8148    (set_attr "mode"     "SI")])
8150 (define_insn "sne_di_zero"
8151   [(set (match_operand:DI 0 "register_operand" "=d")
8152         (ne:DI (match_operand:DI 1 "se_register_operand" "d")
8153                (const_int 0)))]
8154   "TARGET_64BIT && !TARGET_MIPS16"
8155   "sltu\\t%0,%.,%1"
8156   [(set_attr "type"     "arith")
8157    (set_attr "mode"     "DI")])
8159 (define_insn "sne_si"
8160   [(set (match_operand:SI 0 "register_operand" "=d,d")
8161         (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
8162                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
8163   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8164   "@
8165     xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8166     xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8167   [(set_attr "type"     "arith")
8168    (set_attr "mode"     "SI")
8169    (set_attr "length"   "8")])
8171 (define_split
8172   [(set (match_operand:SI 0 "register_operand" "")
8173         (ne:SI (match_operand:SI 1 "register_operand" "")
8174                (match_operand:SI 2 "uns_arith_operand" "")))]
8175   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
8176     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8177   [(set (match_dup 0)
8178         (xor:SI (match_dup 1)
8179                 (match_dup 2)))
8180    (set (match_dup 0)
8181         (gtu:SI (match_dup 0)
8182                 (const_int 0)))]
8183   "")
8185 (define_insn "sne_di"
8186   [(set (match_operand:DI 0 "register_operand" "=d,d")
8187         (ne:DI (match_operand:DI 1 "se_register_operand" "%d,d")
8188                (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
8189   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8190   "@
8191     xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
8192     xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
8193   [(set_attr "type"     "arith")
8194    (set_attr "mode"     "DI")
8195    (set_attr "length"   "8")])
8197 (define_split
8198   [(set (match_operand:DI 0 "register_operand" "")
8199         (ne:DI (match_operand:DI 1 "se_register_operand" "")
8200                (match_operand:DI 2 "se_uns_arith_operand" "")))]
8201   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8202     && !TARGET_MIPS16
8203     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
8204   [(set (match_dup 0)
8205         (xor:DI (match_dup 1)
8206                 (match_dup 2)))
8207    (set (match_dup 0)
8208         (gtu:DI (match_dup 0)
8209                 (const_int 0)))]
8210   "")
8212 (define_expand "sgt"
8213   [(set (match_operand:SI 0 "register_operand" "=d")
8214         (gt:SI (match_dup 1)
8215                (match_dup 2)))]
8216   ""
8217   "
8219   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8220     FAIL;
8222   /* set up operands from compare.  */
8223   operands[1] = branch_cmp[0];
8224   operands[2] = branch_cmp[1];
8226   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8227     {
8228       gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
8229       DONE;
8230     }
8232   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8233     operands[2] = force_reg (SImode, operands[2]);
8235   /* fall through and generate default code */
8238 (define_insn "sgt_si"
8239   [(set (match_operand:SI 0 "register_operand" "=d")
8240         (gt:SI (match_operand:SI 1 "register_operand" "d")
8241                (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8242   "!TARGET_MIPS16"
8243   "slt\\t%0,%z2,%1"
8244   [(set_attr "type"     "arith")
8245    (set_attr "mode"     "SI")])
8247 (define_insn ""
8248   [(set (match_operand:SI 0 "register_operand" "=t")
8249         (gt:SI (match_operand:SI 1 "register_operand" "d")
8250                (match_operand:SI 2 "register_operand" "d")))]
8251   "TARGET_MIPS16"
8252   "slt\\t%2,%1"
8253   [(set_attr "type"     "arith")
8254    (set_attr "mode"     "SI")])
8256 (define_insn "sgt_di"
8257   [(set (match_operand:DI 0 "register_operand" "=d")
8258         (gt:DI (match_operand:DI 1 "se_register_operand" "d")
8259                (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
8260   "TARGET_64BIT && !TARGET_MIPS16"
8261   "slt\\t%0,%z2,%1"
8262   [(set_attr "type"     "arith")
8263    (set_attr "mode"     "DI")])
8265 (define_insn ""
8266   [(set (match_operand:DI 0 "register_operand" "=d")
8267         (gt:DI (match_operand:DI 1 "se_register_operand" "d")
8268                (match_operand:DI 2 "se_register_operand" "d")))]
8269   "TARGET_64BIT && TARGET_MIPS16"
8270   "slt\\t%2,%1"
8271   [(set_attr "type"     "arith")
8272    (set_attr "mode"     "DI")])
8274 (define_expand "sge"
8275   [(set (match_operand:SI 0 "register_operand" "=d")
8276         (ge:SI (match_dup 1)
8277                (match_dup 2)))]
8278   ""
8279   "
8281   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8282     FAIL;
8284   /* set up operands from compare.  */
8285   operands[1] = branch_cmp[0];
8286   operands[2] = branch_cmp[1];
8288   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8289     {
8290       gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
8291       DONE;
8292     }
8294   /* fall through and generate default code */
8297 (define_insn "sge_si"
8298   [(set (match_operand:SI 0 "register_operand" "=d")
8299         (ge:SI (match_operand:SI 1 "register_operand" "d")
8300                (match_operand:SI 2 "arith_operand" "dI")))]
8301   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8302   "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8303   [(set_attr "type"     "arith")
8304    (set_attr "mode"     "SI")
8305    (set_attr "length"   "8")])
8307 (define_split
8308   [(set (match_operand:SI 0 "register_operand" "")
8309         (ge:SI (match_operand:SI 1 "register_operand" "")
8310                (match_operand:SI 2 "arith_operand" "")))]
8311   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8312   [(set (match_dup 0)
8313         (lt:SI (match_dup 1)
8314                (match_dup 2)))
8315    (set (match_dup 0)
8316         (xor:SI (match_dup 0)
8317                 (const_int 1)))]
8318   "")
8320 (define_insn "sge_di"
8321   [(set (match_operand:DI 0 "register_operand" "=d")
8322         (ge:DI (match_operand:DI 1 "se_register_operand" "d")
8323                (match_operand:DI 2 "se_arith_operand" "dI")))]
8324   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8325   "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8326   [(set_attr "type"     "arith")
8327    (set_attr "mode"     "DI")
8328    (set_attr "length"   "8")])
8330 (define_split
8331   [(set (match_operand:DI 0 "register_operand" "")
8332         (ge:DI (match_operand:DI 1 "se_register_operand" "")
8333                (match_operand:DI 2 "se_arith_operand" "")))]
8334   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8335    && !TARGET_MIPS16"
8336   [(set (match_dup 0)
8337         (lt:DI (match_dup 1)
8338                (match_dup 2)))
8339    (set (match_dup 0)
8340         (xor:DI (match_dup 0)
8341                 (const_int 1)))]
8342   "")
8344 (define_expand "slt"
8345   [(set (match_operand:SI 0 "register_operand" "=d")
8346         (lt:SI (match_dup 1)
8347                (match_dup 2)))]
8348   ""
8349   "
8351   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8352     FAIL;
8354   /* set up operands from compare.  */
8355   operands[1] = branch_cmp[0];
8356   operands[2] = branch_cmp[1];
8358   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8359     {
8360       gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
8361       DONE;
8362     }
8364   /* fall through and generate default code */
8367 (define_insn "slt_si"
8368   [(set (match_operand:SI 0 "register_operand" "=d")
8369         (lt:SI (match_operand:SI 1 "register_operand" "d")
8370                (match_operand:SI 2 "arith_operand" "dI")))]
8371   "!TARGET_MIPS16"
8372   "slt\\t%0,%1,%2"
8373   [(set_attr "type"     "arith")
8374    (set_attr "mode"     "SI")])
8376 (define_insn ""
8377   [(set (match_operand:SI 0 "register_operand" "=t,t")
8378         (lt:SI (match_operand:SI 1 "register_operand" "d,d")
8379                (match_operand:SI 2 "arith_operand" "d,I")))]
8380   "TARGET_MIPS16"
8381   "slt\\t%1,%2"
8382   [(set_attr "type"     "arith")
8383    (set_attr "mode"     "SI")
8384    (set_attr_alternative "length"
8385                 [(const_int 4)
8386                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8387                                (const_int 4)
8388                                (const_int 8))])])
8390 (define_insn "slt_di"
8391   [(set (match_operand:DI 0 "register_operand" "=d")
8392         (lt:DI (match_operand:DI 1 "se_register_operand" "d")
8393                (match_operand:DI 2 "se_arith_operand" "dI")))]
8394   "TARGET_64BIT && !TARGET_MIPS16"
8395   "slt\\t%0,%1,%2"
8396   [(set_attr "type"     "arith")
8397    (set_attr "mode"     "DI")])
8399 (define_insn ""
8400   [(set (match_operand:DI 0 "register_operand" "=t,t")
8401         (lt:DI (match_operand:DI 1 "se_register_operand" "d,d")
8402                (match_operand:DI 2 "se_arith_operand" "d,I")))]
8403   "TARGET_64BIT && TARGET_MIPS16"
8404   "slt\\t%1,%2"
8405   [(set_attr "type"     "arith")
8406    (set_attr "mode"     "DI")
8407    (set_attr_alternative "length"
8408                 [(const_int 4)
8409                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8410                                (const_int 4)
8411                                (const_int 8))])])
8413 (define_expand "sle"
8414   [(set (match_operand:SI 0 "register_operand" "=d")
8415         (le:SI (match_dup 1)
8416                (match_dup 2)))]
8417   ""
8418   "
8420   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8421     FAIL;
8423   /* set up operands from compare.  */
8424   operands[1] = branch_cmp[0];
8425   operands[2] = branch_cmp[1];
8427   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8428     {
8429       gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
8430       DONE;
8431     }
8433   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8434     operands[2] = force_reg (SImode, operands[2]);
8436   /* fall through and generate default code */
8439 (define_insn "sle_si_const"
8440   [(set (match_operand:SI 0 "register_operand" "=d")
8441         (le:SI (match_operand:SI 1 "register_operand" "d")
8442                (match_operand:SI 2 "small_int" "I")))]
8443   "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8444   "*
8446   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8447   return \"slt\\t%0,%1,%2\";
8449   [(set_attr "type"     "arith")
8450    (set_attr "mode"     "SI")])
8452 (define_insn ""
8453   [(set (match_operand:SI 0 "register_operand" "=t")
8454         (le:SI (match_operand:SI 1 "register_operand" "d")
8455                (match_operand:SI 2 "small_int" "I")))]
8456   "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8457   "*
8459   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8460   return \"slt\\t%1,%2\";
8462   [(set_attr "type"     "arith")
8463    (set_attr "mode"     "SI")
8464    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8465                                       (const_int 4)
8466                                       (const_int 8)))])
8468 (define_insn "sle_di_const"
8469   [(set (match_operand:DI 0 "register_operand" "=d")
8470         (le:DI (match_operand:DI 1 "se_register_operand" "d")
8471                (match_operand:DI 2 "small_int" "I")))]
8472   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8473   "*
8475   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8476   return \"slt\\t%0,%1,%2\";
8478   [(set_attr "type"     "arith")
8479    (set_attr "mode"     "DI")])
8481 (define_insn ""
8482   [(set (match_operand:DI 0 "register_operand" "=t")
8483         (le:DI (match_operand:DI 1 "se_register_operand" "d")
8484                (match_operand:DI 2 "small_int" "I")))]
8485   "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8486   "*
8488   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8489   return \"slt\\t%1,%2\";
8491   [(set_attr "type"     "arith")
8492    (set_attr "mode"     "DI")
8493    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8494                                       (const_int 4)
8495                                       (const_int 8)))])
8497 (define_insn "sle_si_reg"
8498   [(set (match_operand:SI 0 "register_operand" "=d")
8499         (le:SI (match_operand:SI 1 "register_operand" "d")
8500                (match_operand:SI 2 "register_operand" "d")))]
8501   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8502   "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8503   [(set_attr "type"     "arith")
8504    (set_attr "mode"     "SI")
8505    (set_attr "length"   "8")])
8507 (define_split
8508   [(set (match_operand:SI 0 "register_operand" "")
8509         (le:SI (match_operand:SI 1 "register_operand" "")
8510                (match_operand:SI 2 "register_operand" "")))]
8511   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8512   [(set (match_dup 0)
8513         (lt:SI (match_dup 2)
8514                (match_dup 1)))
8515    (set (match_dup 0)
8516         (xor:SI (match_dup 0)
8517                 (const_int 1)))]
8518   "")
8520 (define_insn "sle_di_reg"
8521   [(set (match_operand:DI 0 "register_operand" "=d")
8522         (le:DI (match_operand:DI 1 "se_register_operand" "d")
8523                (match_operand:DI 2 "se_register_operand" "d")))]
8524   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8525   "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8526   [(set_attr "type"     "arith")
8527    (set_attr "mode"     "DI")
8528    (set_attr "length"   "8")])
8530 (define_split
8531   [(set (match_operand:DI 0 "register_operand" "")
8532         (le:DI (match_operand:DI 1 "se_register_operand" "")
8533                (match_operand:DI 2 "se_register_operand" "")))]
8534   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8535    && !TARGET_MIPS16"
8536   [(set (match_dup 0)
8537         (lt:DI (match_dup 2)
8538                (match_dup 1)))
8539    (set (match_dup 0)
8540         (xor:DI (match_dup 0)
8541                 (const_int 1)))]
8542   "")
8544 (define_expand "sgtu"
8545   [(set (match_operand:SI 0 "register_operand" "=d")
8546         (gtu:SI (match_dup 1)
8547                 (match_dup 2)))]
8548   ""
8549   "
8551   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8552     FAIL;
8554   /* set up operands from compare.  */
8555   operands[1] = branch_cmp[0];
8556   operands[2] = branch_cmp[1];
8558   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8559     {
8560       gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
8561       DONE;
8562     }
8564   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8565     operands[2] = force_reg (SImode, operands[2]);
8567   /* fall through and generate default code */
8570 (define_insn "sgtu_si"
8571   [(set (match_operand:SI 0 "register_operand" "=d")
8572         (gtu:SI (match_operand:SI 1 "register_operand" "d")
8573                 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8574   ""
8575   "sltu\\t%0,%z2,%1"
8576   [(set_attr "type"     "arith")
8577    (set_attr "mode"     "SI")])
8579 (define_insn ""
8580   [(set (match_operand:SI 0 "register_operand" "=t")
8581         (gtu:SI (match_operand:SI 1 "register_operand" "d")
8582                 (match_operand:SI 2 "register_operand" "d")))]
8583   ""
8584   "sltu\\t%2,%1"
8585   [(set_attr "type"     "arith")
8586    (set_attr "mode"     "SI")])
8588 (define_insn "sgtu_di"
8589   [(set (match_operand:DI 0 "register_operand" "=d")
8590         (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
8591                 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
8592   "TARGET_64BIT"
8593   "sltu\\t%0,%z2,%1"
8594   [(set_attr "type"     "arith")
8595    (set_attr "mode"     "DI")])
8597 (define_insn ""
8598   [(set (match_operand:DI 0 "register_operand" "=t")
8599         (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
8600                 (match_operand:DI 2 "se_register_operand" "d")))]
8601   "TARGET_64BIT"
8602   "sltu\\t%2,%1"
8603   [(set_attr "type"     "arith")
8604    (set_attr "mode"     "DI")])
8606 (define_expand "sgeu"
8607   [(set (match_operand:SI 0 "register_operand" "=d")
8608         (geu:SI (match_dup 1)
8609                 (match_dup 2)))]
8610   ""
8611   "
8613   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8614     FAIL;
8616   /* set up operands from compare.  */
8617   operands[1] = branch_cmp[0];
8618   operands[2] = branch_cmp[1];
8620   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8621     {
8622       gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
8623       DONE;
8624     }
8626   /* fall through and generate default code */
8629 (define_insn "sgeu_si"
8630   [(set (match_operand:SI 0 "register_operand" "=d")
8631         (geu:SI (match_operand:SI 1 "register_operand" "d")
8632                 (match_operand:SI 2 "arith_operand" "dI")))]
8633   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8634   "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8635   [(set_attr "type"     "arith")
8636    (set_attr "mode"     "SI")
8637    (set_attr "length"   "8")])
8639 (define_split
8640   [(set (match_operand:SI 0 "register_operand" "")
8641         (geu:SI (match_operand:SI 1 "register_operand" "")
8642                 (match_operand:SI 2 "arith_operand" "")))]
8643   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8644   [(set (match_dup 0)
8645         (ltu:SI (match_dup 1)
8646                 (match_dup 2)))
8647    (set (match_dup 0)
8648         (xor:SI (match_dup 0)
8649                 (const_int 1)))]
8650   "")
8652 (define_insn "sgeu_di"
8653   [(set (match_operand:DI 0 "register_operand" "=d")
8654         (geu:DI (match_operand:DI 1 "se_register_operand" "d")
8655                 (match_operand:DI 2 "se_arith_operand" "dI")))]
8656   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8657   "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8658   [(set_attr "type"     "arith")
8659    (set_attr "mode"     "DI")
8660    (set_attr "length"   "8")])
8662 (define_split
8663   [(set (match_operand:DI 0 "register_operand" "")
8664         (geu:DI (match_operand:DI 1 "se_register_operand" "")
8665                 (match_operand:DI 2 "se_arith_operand" "")))]
8666   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8667    && !TARGET_MIPS16"
8668   [(set (match_dup 0)
8669         (ltu:DI (match_dup 1)
8670                 (match_dup 2)))
8671    (set (match_dup 0)
8672         (xor:DI (match_dup 0)
8673                 (const_int 1)))]
8674   "")
8676 (define_expand "sltu"
8677   [(set (match_operand:SI 0 "register_operand" "=d")
8678         (ltu:SI (match_dup 1)
8679                 (match_dup 2)))]
8680   ""
8681   "
8683   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8684     FAIL;
8686   /* set up operands from compare.  */
8687   operands[1] = branch_cmp[0];
8688   operands[2] = branch_cmp[1];
8690   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8691     {
8692       gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
8693       DONE;
8694     }
8696   /* fall through and generate default code */
8699 (define_insn "sltu_si"
8700   [(set (match_operand:SI 0 "register_operand" "=d")
8701         (ltu:SI (match_operand:SI 1 "register_operand" "d")
8702                 (match_operand:SI 2 "arith_operand" "dI")))]
8703   "!TARGET_MIPS16"
8704   "sltu\\t%0,%1,%2"
8705   [(set_attr "type"     "arith")
8706    (set_attr "mode"     "SI")])
8708 (define_insn ""
8709   [(set (match_operand:SI 0 "register_operand" "=t,t")
8710         (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
8711                 (match_operand:SI 2 "arith_operand" "d,I")))]
8712   "TARGET_MIPS16"
8713   "sltu\\t%1,%2"
8714   [(set_attr "type"     "arith")
8715    (set_attr "mode"     "SI")
8716    (set_attr_alternative "length"
8717                 [(const_int 4)
8718                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8719                                (const_int 4)
8720                                (const_int 8))])])
8722 (define_insn "sltu_di"
8723   [(set (match_operand:DI 0 "register_operand" "=d")
8724         (ltu:DI (match_operand:DI 1 "se_register_operand" "d")
8725                 (match_operand:DI 2 "se_arith_operand" "dI")))]
8726   "TARGET_64BIT && !TARGET_MIPS16"
8727   "sltu\\t%0,%1,%2"
8728   [(set_attr "type"     "arith")
8729    (set_attr "mode"     "DI")])
8731 (define_insn ""
8732   [(set (match_operand:DI 0 "register_operand" "=t,t")
8733         (ltu:DI (match_operand:DI 1 "se_register_operand" "d,d")
8734                 (match_operand:DI 2 "se_arith_operand" "d,I")))]
8735   "TARGET_64BIT && TARGET_MIPS16"
8736   "sltu\\t%1,%2"
8737   [(set_attr "type"     "arith")
8738    (set_attr "mode"     "DI")
8739    (set_attr_alternative "length"
8740                 [(const_int 4)
8741                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8742                                (const_int 4)
8743                                (const_int 8))])])
8745 (define_expand "sleu"
8746   [(set (match_operand:SI 0 "register_operand" "=d")
8747         (leu:SI (match_dup 1)
8748                 (match_dup 2)))]
8749   ""
8750   "
8752   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8753     FAIL;
8755   /* set up operands from compare.  */
8756   operands[1] = branch_cmp[0];
8757   operands[2] = branch_cmp[1];
8759   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8760     {
8761       gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
8762       DONE;
8763     }
8765   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8766     operands[2] = force_reg (SImode, operands[2]);
8768   /* fall through and generate default code */
8771 (define_insn "sleu_si_const"
8772   [(set (match_operand:SI 0 "register_operand" "=d")
8773         (leu:SI (match_operand:SI 1 "register_operand" "d")
8774                 (match_operand:SI 2 "small_int" "I")))]
8775   "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8776   "*
8778   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8779   return \"sltu\\t%0,%1,%2\";
8781   [(set_attr "type"     "arith")
8782    (set_attr "mode"     "SI")])
8784 (define_insn ""
8785   [(set (match_operand:SI 0 "register_operand" "=t")
8786         (leu:SI (match_operand:SI 1 "register_operand" "d")
8787                 (match_operand:SI 2 "small_int" "I")))]
8788   "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8789   "*
8791   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8792   return \"sltu\\t%1,%2\";
8794   [(set_attr "type"     "arith")
8795    (set_attr "mode"     "SI")
8796    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8797                                       (const_int 4)
8798                                       (const_int 8)))])
8800 (define_insn "sleu_di_const"
8801   [(set (match_operand:DI 0 "register_operand" "=d")
8802         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
8803                 (match_operand:DI 2 "small_int" "I")))]
8804   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8805   "*
8807   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8808   return \"sltu\\t%0,%1,%2\";
8810   [(set_attr "type"     "arith")
8811    (set_attr "mode"     "DI")])
8813 (define_insn ""
8814   [(set (match_operand:DI 0 "register_operand" "=t")
8815         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
8816                 (match_operand:DI 2 "small_int" "I")))]
8817   "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8818   "*
8820   operands[2] = GEN_INT (INTVAL (operands[2])+1);
8821   return \"sltu\\t%1,%2\";
8823   [(set_attr "type"     "arith")
8824    (set_attr "mode"     "DI")
8825    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8826                                       (const_int 4)
8827                                       (const_int 8)))])
8829 (define_insn "sleu_si_reg"
8830   [(set (match_operand:SI 0 "register_operand" "=d")
8831         (leu:SI (match_operand:SI 1 "register_operand" "d")
8832                 (match_operand:SI 2 "register_operand" "d")))]
8833   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8834   "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8835   [(set_attr "type"     "arith")
8836    (set_attr "mode"     "SI")
8837    (set_attr "length"   "8")])
8839 (define_split
8840   [(set (match_operand:SI 0 "register_operand" "")
8841         (leu:SI (match_operand:SI 1 "register_operand" "")
8842                 (match_operand:SI 2 "register_operand" "")))]
8843   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8844   [(set (match_dup 0)
8845         (ltu:SI (match_dup 2)
8846                 (match_dup 1)))
8847    (set (match_dup 0)
8848         (xor:SI (match_dup 0)
8849                 (const_int 1)))]
8850   "")
8852 (define_insn "sleu_di_reg"
8853   [(set (match_operand:DI 0 "register_operand" "=d")
8854         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
8855                 (match_operand:DI 2 "se_register_operand" "d")))]
8856   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8857   "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8858   [(set_attr "type"     "arith")
8859    (set_attr "mode"     "DI")
8860    (set_attr "length"   "8")])
8862 (define_split
8863   [(set (match_operand:DI 0 "register_operand" "")
8864         (leu:DI (match_operand:DI 1 "se_register_operand" "")
8865                 (match_operand:DI 2 "se_register_operand" "")))]
8866   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8867    && !TARGET_MIPS16"
8868   [(set (match_dup 0)
8869         (ltu:DI (match_dup 2)
8870                 (match_dup 1)))
8871    (set (match_dup 0)
8872         (xor:DI (match_dup 0)
8873                 (const_int 1)))]
8874   "")
8878 ;;  ....................
8880 ;;      FLOATING POINT COMPARISONS
8882 ;;  ....................
8884 (define_insn "seq_df"
8885   [(set (match_operand:CC 0 "register_operand" "=z")
8886         (eq:CC (match_operand:DF 1 "register_operand" "f")
8887                (match_operand:DF 2 "register_operand" "f")))]
8888   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8889   "*
8891   return mips_fill_delay_slot (\"c.eq.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8893  [(set_attr "type"      "fcmp")
8894   (set_attr "mode"      "FPSW")])
8896 (define_insn "slt_df"
8897   [(set (match_operand:CC 0 "register_operand" "=z")
8898         (lt:CC (match_operand:DF 1 "register_operand" "f")
8899                (match_operand:DF 2 "register_operand" "f")))]
8900   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8901   "*
8903   return mips_fill_delay_slot (\"c.lt.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8905  [(set_attr "type"      "fcmp")
8906   (set_attr "mode"      "FPSW")])
8908 (define_insn "sle_df"
8909   [(set (match_operand:CC 0 "register_operand" "=z")
8910         (le:CC (match_operand:DF 1 "register_operand" "f")
8911                (match_operand:DF 2 "register_operand" "f")))]
8912   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8913   "*
8915   return mips_fill_delay_slot (\"c.le.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8917  [(set_attr "type"      "fcmp")
8918   (set_attr "mode"      "FPSW")])
8920 (define_insn "sgt_df"
8921   [(set (match_operand:CC 0 "register_operand" "=z")
8922         (gt:CC (match_operand:DF 1 "register_operand" "f")
8923                (match_operand:DF 2 "register_operand" "f")))]
8924   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8925   "*
8927   return mips_fill_delay_slot (\"c.lt.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
8929  [(set_attr "type"      "fcmp")
8930   (set_attr "mode"      "FPSW")])
8932 (define_insn "sge_df"
8933   [(set (match_operand:CC 0 "register_operand" "=z")
8934         (ge:CC (match_operand:DF 1 "register_operand" "f")
8935                (match_operand:DF 2 "register_operand" "f")))]
8936   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8937   "*
8939   return mips_fill_delay_slot (\"c.le.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
8941  [(set_attr "type"      "fcmp")
8942   (set_attr "mode"      "FPSW")])
8944 (define_insn "seq_sf"
8945   [(set (match_operand:CC 0 "register_operand" "=z")
8946         (eq:CC (match_operand:SF 1 "register_operand" "f")
8947                (match_operand:SF 2 "register_operand" "f")))]
8948   "TARGET_HARD_FLOAT"
8949   "*
8951   return mips_fill_delay_slot (\"c.eq.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8953  [(set_attr "type"      "fcmp")
8954   (set_attr "mode"      "FPSW")])
8956 (define_insn "slt_sf"
8957   [(set (match_operand:CC 0 "register_operand" "=z")
8958         (lt:CC (match_operand:SF 1 "register_operand" "f")
8959                (match_operand:SF 2 "register_operand" "f")))]
8960   "TARGET_HARD_FLOAT"
8961   "*
8963   return mips_fill_delay_slot (\"c.lt.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8965  [(set_attr "type"      "fcmp")
8966   (set_attr "mode"      "FPSW")])
8968 (define_insn "sle_sf"
8969   [(set (match_operand:CC 0 "register_operand" "=z")
8970         (le:CC (match_operand:SF 1 "register_operand" "f")
8971                (match_operand:SF 2 "register_operand" "f")))]
8972   "TARGET_HARD_FLOAT"
8973   "*
8975   return mips_fill_delay_slot (\"c.le.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8977  [(set_attr "type"      "fcmp")
8978   (set_attr "mode"      "FPSW")])
8980 (define_insn "sgt_sf"
8981   [(set (match_operand:CC 0 "register_operand" "=z")
8982         (gt:CC (match_operand:SF 1 "register_operand" "f")
8983                (match_operand:SF 2 "register_operand" "f")))]
8984   "TARGET_HARD_FLOAT"
8985   "*
8987   return mips_fill_delay_slot (\"c.lt.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
8989  [(set_attr "type"      "fcmp")
8990   (set_attr "mode"      "FPSW")])
8992 (define_insn "sge_sf"
8993   [(set (match_operand:CC 0 "register_operand" "=z")
8994         (ge:CC (match_operand:SF 1 "register_operand" "f")
8995                (match_operand:SF 2 "register_operand" "f")))]
8996   "TARGET_HARD_FLOAT"
8997   "*
8999   return mips_fill_delay_slot (\"c.le.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
9001  [(set_attr "type"      "fcmp")
9002   (set_attr "mode"      "FPSW")])
9006 ;;  ....................
9008 ;;      UNCONDITIONAL BRANCHES
9010 ;;  ....................
9012 ;; Unconditional branches.
9014 (define_insn "jump"
9015   [(set (pc)
9016         (label_ref (match_operand 0 "" "")))]
9017   "!TARGET_MIPS16"
9018   "*
9020   if (GET_CODE (operands[0]) == REG)
9021     return \"%*j\\t%0\";
9022   /* ??? I don't know why this is necessary.  This works around an
9023      assembler problem that appears when a label is defined, then referenced
9024      in a switch table, then used in a `j' instruction.  */
9025   else if (mips_abi != ABI_32 && mips_abi != ABI_O64)
9026     return \"%*b\\t%l0\";
9027   else  
9028     return \"%*j\\t%l0\";
9030   [(set_attr "type"     "jump")
9031    (set_attr "mode"     "none")])
9033 ;; We need a different insn for the mips16, because a mips16 branch
9034 ;; does not have a delay slot.
9036 (define_insn ""
9037   [(set (pc)
9038         (label_ref (match_operand 0 "" "")))]
9039   "TARGET_MIPS16 && GET_CODE (operands[0]) != REG"
9040   "b\\t%l0"
9041   [(set_attr "type"     "branch")
9042    (set_attr "mode"     "none")
9043    (set_attr "length"   "8")])
9045 (define_expand "indirect_jump"
9046   [(set (pc) (match_operand 0 "register_operand" "d"))]
9047   ""
9048   "
9050   rtx dest;
9052   if (operands[0])              /* eliminate unused code warnings */
9053     {
9054       dest = operands[0];
9055       if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
9056         operands[0] = copy_to_mode_reg (Pmode, dest);
9058       if (!(Pmode == DImode))
9059         emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
9060       else
9061         emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
9063       DONE;
9064     }
9067 (define_insn "indirect_jump_internal1"
9068   [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
9069   "!(Pmode == DImode)"
9070   "%*j\\t%0"
9071   [(set_attr "type"     "jump")
9072    (set_attr "mode"     "none")])
9074 (define_insn "indirect_jump_internal2"
9075   [(set (pc) (match_operand:DI 0 "se_register_operand" "d"))]
9076   "Pmode == DImode"
9077   "%*j\\t%0"
9078   [(set_attr "type"     "jump")
9079    (set_attr "mode"     "none")])
9081 (define_expand "tablejump"
9082   [(set (pc)
9083         (match_operand 0 "register_operand" "d"))
9084    (use (label_ref (match_operand 1 "" "")))]
9085   ""
9086   "
9088   if (operands[0])              /* eliminate unused code warnings */
9089     {
9090       if (TARGET_MIPS16)
9091         {
9092           if (GET_MODE (operands[0]) != HImode)
9093             abort ();
9094           if (!(Pmode == DImode))
9095             emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
9096           else
9097             emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
9098           DONE;
9099         }
9101       if (GET_MODE (operands[0]) != Pmode)
9102         abort ();
9104       if (! flag_pic)
9105         {
9106           if (!(Pmode == DImode))
9107             emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
9108           else
9109             emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
9110         }
9111       else
9112         {
9113           if (!(Pmode == DImode))
9114             emit_jump_insn (gen_tablejump_internal3 (operands[0], operands[1]));
9115           else
9116             emit_jump_insn (gen_tablejump_internal4 (operands[0], operands[1]));
9117         }
9119       DONE;
9120     }
9123 (define_insn "tablejump_internal1"
9124   [(set (pc)
9125         (match_operand:SI 0 "register_operand" "d"))
9126    (use (label_ref (match_operand 1 "" "")))]
9127   "!(Pmode == DImode)"
9128   "%*j\\t%0"
9129   [(set_attr "type"     "jump")
9130    (set_attr "mode"     "none")])
9132 (define_insn "tablejump_internal2"
9133   [(set (pc)
9134         (match_operand:DI 0 "se_register_operand" "d"))
9135    (use (label_ref (match_operand 1 "" "")))]
9136   "Pmode == DImode"
9137   "%*j\\t%0"
9138   [(set_attr "type"     "jump")
9139    (set_attr "mode"     "none")])
9141 (define_expand "tablejump_internal3"
9142   [(parallel [(set (pc)
9143                    (plus:SI (match_operand:SI 0 "register_operand" "d")
9144                             (label_ref:SI (match_operand:SI 1 "" ""))))
9145               (use (label_ref:SI (match_dup 1)))])]
9146   ""
9147   "")
9149 (define_expand "tablejump_mips161"
9150   [(set (pc) (plus:SI (sign_extend:SI
9151                        (match_operand:HI 0 "register_operand" "d"))
9152                       (label_ref:SI (match_operand:SI 1 "" ""))))]
9153   "TARGET_MIPS16 && !(Pmode == DImode)"
9154   "
9156   if (operands[0])      /* eliminate unused code warnings.  */
9157     {
9158       rtx t1, t2, t3;
9160       t1 = gen_reg_rtx (SImode);
9161       t2 = gen_reg_rtx (SImode);
9162       t3 = gen_reg_rtx (SImode);
9163       emit_insn (gen_extendhisi2 (t1, operands[0]));
9164       emit_move_insn (t2, gen_rtx (LABEL_REF, SImode, operands[1]));
9165       emit_insn (gen_addsi3 (t3, t1, t2));
9166       emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
9167       DONE;
9168     }
9171 (define_expand "tablejump_mips162"
9172   [(set (pc) (plus:DI (sign_extend:DI
9173                        (match_operand:HI 0 "register_operand" "d"))
9174                       (label_ref:DI (match_operand:SI 1 "" ""))))]
9175   "TARGET_MIPS16 && Pmode == DImode"
9176   "
9178   if (operands[0])      /* eliminate unused code warnings.  */
9179     {
9180       rtx t1, t2, t3;
9182       t1 = gen_reg_rtx (DImode);
9183       t2 = gen_reg_rtx (DImode);
9184       t3 = gen_reg_rtx (DImode);
9185       emit_insn (gen_extendhidi2 (t1, operands[0]));
9186       emit_move_insn (t2, gen_rtx (LABEL_REF, DImode, operands[1]));
9187       emit_insn (gen_adddi3 (t3, t1, t2));
9188       emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
9189       DONE;
9190     }
9193 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC.  Otherwise
9194 ;;; it is not valid.  ??? With the USE, the condition tests may not be required
9195 ;;; any longer.
9197 ;;; ??? The length depends on the ABI.  It is two for o32, and one for n32.
9198 ;;; We just use the conservative number here.
9200 (define_insn ""
9201   [(set (pc)
9202         (plus:SI (match_operand:SI 0 "register_operand" "d")
9203                  (label_ref:SI (match_operand:SI 1 "" ""))))
9204    (use (label_ref:SI (match_dup 1)))]
9205   "!(Pmode == DImode) && next_active_insn (insn) != 0
9206    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
9207    && PREV_INSN (next_active_insn (insn)) == operands[1]"
9208   "*
9210   /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic.  */
9211   if (mips_abi == ABI_32 || mips_abi == ABI_O64)
9212     output_asm_insn (\".cpadd\\t%0\", operands);
9213   return \"%*j\\t%0\";
9215   [(set_attr "type"     "jump")
9216    (set_attr "mode"     "none")
9217    (set_attr "length"   "8")])
9219 (define_expand "tablejump_internal4"
9220   [(parallel [(set (pc)
9221                    (plus:DI (match_operand:DI 0 "se_register_operand" "d")
9222                             (label_ref:DI (match_operand:SI 1 "" ""))))
9223               (use (label_ref:DI (match_dup 1)))])]
9224   ""
9225   "")
9227 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC.  Otherwise
9228 ;;; it is not valid.  ??? With the USE, the condition tests may not be required
9229 ;;; any longer.
9231 (define_insn ""
9232   [(set (pc)
9233         (plus:DI (match_operand:DI 0 "se_register_operand" "d")
9234                  (label_ref:DI (match_operand:SI 1 "" ""))))
9235    (use (label_ref:DI (match_dup 1)))]
9236   "Pmode == DImode && next_active_insn (insn) != 0
9237    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
9238    && PREV_INSN (next_active_insn (insn)) == operands[1]"
9239   "%*j\\t%0"
9240   [(set_attr "type"     "jump")
9241    (set_attr "mode"     "none")])
9243 ;; Implement a switch statement when generating embedded PIC code.
9244 ;; Switches are implemented by `tablejump' when not using -membedded-pic.
9246 (define_expand "casesi"
9247   [(set (match_dup 5)
9248         (minus:SI (match_operand:SI 0 "register_operand" "d")
9249                   (match_operand:SI 1 "arith_operand" "dI")))
9250    (set (cc0)
9251         (compare:CC (match_dup 5)
9252                     (match_operand:SI 2 "arith_operand" "")))
9253    (set (pc)
9254         (if_then_else (gtu (cc0)
9255                            (const_int 0))
9256                       (label_ref (match_operand 4 "" ""))
9257                       (pc)))
9258    (parallel
9259     [(set (pc)
9260           (mem:SI (plus:SI (mult:SI (match_dup 5)
9261                                     (const_int 4))
9262                            (label_ref (match_operand 3 "" "")))))
9263      (clobber (match_scratch:SI 6 ""))
9264      (clobber (reg:SI 31))])]
9265   "TARGET_EMBEDDED_PIC"
9266   "
9268   /* We need slightly different code for eight byte table entries.  */
9269   if (Pmode == DImode)
9270     abort ();
9272   if (operands[0])
9273     {
9274       rtx reg = gen_reg_rtx (SImode);
9276       /* If the index is too large, go to the default label.  */
9277       emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
9278       emit_insn (gen_cmpsi (reg, operands[2]));
9279       emit_insn (gen_bgtu (operands[4]));
9281       /* Do the PIC jump.  */
9282       emit_insn (gen_casesi_internal (reg, operands[3], gen_reg_rtx (SImode)));
9284       DONE;
9285     }
9288 ;; An embedded PIC switch statement looks like this:
9289 ;;      bal     $LS1
9290 ;;      sll     $reg,$index,2
9291 ;; $LS1:
9292 ;;      addu    $reg,$reg,$31
9293 ;;      lw      $reg,$L1-$LS1($reg)
9294 ;;      addu    $reg,$reg,$31
9295 ;;      j       $reg
9296 ;; $L1:
9297 ;;      .word   case1-$LS1
9298 ;;      .word   case2-$LS1
9299 ;;      ...
9301 (define_insn "casesi_internal"
9302   [(set (pc)
9303         (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
9304                                   (const_int 4))
9305                          (label_ref (match_operand 1 "" "")))))
9306    (clobber (match_operand:SI 2 "register_operand" "d"))
9307    (clobber (reg:SI 31))]
9308   "TARGET_EMBEDDED_PIC"
9309   "*
9311   output_asm_insn (\"%(bal\\t%S1\;sll\\t%0,2\\n%~%S1:\", operands);
9312   output_asm_insn (\"addu\\t%0,%0,$31%)\", operands);
9313   output_asm_insn (\"lw\\t%0,%1-%S1(%0)\;addu\\t%0,%0,$31\", operands);
9314   return \"j\\t%0\";
9316   [(set_attr "type"     "jump")
9317    (set_attr "mode"     "none")
9318    (set_attr "length"   "24")])
9320 ;; For o32/n32/n64, we save the gp in the jmp_buf as well.  While it is
9321 ;; possible to either pull it off the stack (in the o32 case) or recalculate
9322 ;; it given t9 and our target label, it takes 3 or 4 insns to do so, and
9323 ;; this is easy.
9325 (define_expand "builtin_setjmp_setup"
9326   [(unspec [(match_operand 0 "register_operand" "r")] 20)]
9327   "TARGET_ABICALLS"
9328   "
9330   if (Pmode == DImode)
9331     emit_insn (gen_builtin_setjmp_setup_64 (operands[0]));
9332   else
9333     emit_insn (gen_builtin_setjmp_setup_32 (operands[0]));
9334   DONE;
9337 (define_expand "builtin_setjmp_setup_32"
9338   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
9339                    (const_int 12)))
9340       (reg:SI 28))]
9341   "TARGET_ABICALLS && ! (Pmode == DImode)"
9342   "")
9344 (define_expand "builtin_setjmp_setup_64"
9345   [(set (mem:DI (plus:DI (match_operand:DI 0 "register_operand" "r")
9346                    (const_int 24)))
9347       (reg:DI 28))]
9348   "TARGET_ABICALLS && Pmode == DImode"
9349   "")
9351 ;; For o32/n32/n64, we need to arrange for longjmp to put the 
9352 ;; target address in t9 so that we can use it for loading $gp.
9354 (define_expand "builtin_longjmp"
9355   [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
9356   "TARGET_ABICALLS"
9357   "
9359   /* The elements of the buffer are, in order:  */
9360   int W = (Pmode == DImode ? 8 : 4);
9361   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
9362   rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
9363   rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
9364   rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
9365   rtx pv = gen_rtx_REG (Pmode, 25);
9366   rtx gp = gen_rtx_REG (Pmode, 28);
9368   /* This bit is the same as expand_builtin_longjmp.  */
9369   emit_move_insn (hard_frame_pointer_rtx, fp);
9370   emit_move_insn (pv, lab);
9371   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
9372   emit_move_insn (gp, gpv);
9373   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
9374   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
9375   emit_insn (gen_rtx_USE (VOIDmode, gp));
9376   emit_indirect_jump (pv);
9377   DONE;
9381 ;;  ....................
9383 ;;      Function prologue/epilogue
9385 ;;  ....................
9388 (define_expand "prologue"
9389   [(const_int 1)]
9390   ""
9391   "
9393   if (mips_isa >= 0)            /* avoid unused code warnings */
9394     {
9395       mips_expand_prologue ();
9396       DONE;
9397     }
9400 ;; Block any insns from being moved before this point, since the
9401 ;; profiling call to mcount can use various registers that aren't
9402 ;; saved or used to pass arguments.
9404 (define_insn "blockage"
9405   [(unspec_volatile [(const_int 0)] 0)]
9406   ""
9407   ""
9408   [(set_attr "type"     "unknown")
9409    (set_attr "mode"     "none")
9410    (set_attr "length"   "0")])
9412 (define_expand "epilogue"
9413   [(const_int 2)]
9414   ""
9415   "
9417   if (mips_isa >= 0)            /* avoid unused code warnings */
9418     {
9419       mips_expand_epilogue ();
9420       DONE;
9421     }
9424 ;; Trivial return.  Make it look like a normal return insn as that
9425 ;; allows jump optimizations to work better .
9426 (define_insn "return"
9427   [(return)]
9428   "mips_can_use_return_insn ()"
9429   "%*j\\t$31"
9430   [(set_attr "type"     "jump")
9431    (set_attr "mode"     "none")])
9433 ;; Normal return.
9434 ;; We match any mode for the return address, so that this will work with
9435 ;; both 32 bit and 64 bit targets.
9436 (define_insn "return_internal"
9437   [(use (match_operand 0 "register_operand" ""))
9438    (return)]
9439   ""
9440   "*
9442   return \"%*j\\t%0\";
9444   [(set_attr "type"     "jump")
9445    (set_attr "mode"     "none")])
9446   
9447 ;; When generating embedded PIC code we need to get the address of the
9448 ;; current function.  This specialized instruction does just that.
9450 (define_insn "get_fnaddr"
9451   [(set (match_operand 0 "register_operand" "=d")
9452         (unspec [(match_operand 1 "" "")] 1))
9453    (clobber (reg:SI 31))]
9454   "TARGET_EMBEDDED_PIC
9455    && GET_CODE (operands[1]) == SYMBOL_REF"
9456   "%($LF%= = . + 8\;bal\\t$LF%=\;la\\t%0,%1-$LF%=%)\;addu\\t%0,%0,$31"
9457   [(set_attr "type"     "call")
9458    (set_attr "mode"     "none")
9459    (set_attr "length"   "16")])
9463 ;;  ....................
9465 ;;      FUNCTION CALLS
9467 ;;  ....................
9469 ;; calls.c now passes a third argument, make saber happy
9471 (define_expand "call"
9472   [(parallel [(call (match_operand 0 "memory_operand" "m")
9473                     (match_operand 1 "" "i"))
9474               (clobber (reg:SI 31))
9475               (use (match_operand 2 "" ""))             ;; next_arg_reg
9476               (use (match_operand 3 "" ""))])]          ;; struct_value_size_rtx
9477   ""
9478   "
9480   rtx addr;
9482   if (operands[0])              /* eliminate unused code warnings */
9483     {
9484       addr = XEXP (operands[0], 0);
9485       if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
9486           || ! call_insn_operand (addr, VOIDmode))
9487         XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
9489       /* In order to pass small structures by value in registers
9490          compatibly with the MIPS compiler, we need to shift the value
9491          into the high part of the register.  Function_arg has encoded
9492          a PARALLEL rtx, holding a vector of adjustments to be made
9493          as the next_arg_reg variable, so we split up the insns,
9494          and emit them separately.  */
9496       if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL)
9497         {
9498           rtvec adjust = XVEC (operands[2], 0);
9499           int num = GET_NUM_ELEM (adjust);
9500           int i;
9502           for (i = 0; i < num; i++)
9503             emit_insn (RTVEC_ELT (adjust, i));
9504         }
9506       if (TARGET_MIPS16
9507           && mips16_hard_float
9508           && operands[2] != 0
9509           && (int) GET_MODE (operands[2]) != 0)
9510         {
9511           if (build_mips16_call_stub (NULL_RTX, operands[0], operands[1],
9512                                       (int) GET_MODE (operands[2])))
9513             DONE;
9514         }
9516       emit_call_insn (gen_call_internal0 (operands[0], operands[1],
9517                                           gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
9519       DONE;
9520     }
9523 (define_expand "call_internal0"
9524   [(parallel [(call (match_operand 0 "" "")
9525                     (match_operand 1 "" ""))
9526               (clobber (match_operand:SI 2 "" ""))])]
9527   ""
9528   "")
9530 ;; We need to recognize reg:SI 31 specially for the mips16, because we
9531 ;; don't have a constraint letter for it.
9533 (define_insn ""
9534   [(call (mem (match_operand 0 "call_insn_operand" "ei"))
9535          (match_operand 1 "" "i"))
9536    (clobber (match_operand:SI 2 "register_operand" "=y"))]
9537   "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
9538    && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
9539   "%*jal\\t%0"
9540   [(set_attr "type"     "call")
9541    (set_attr "mode"     "none")
9542    (set_attr "length"   "8")])
9544 (define_insn "call_internal1"
9545   [(call (mem (match_operand 0 "call_insn_operand" "ri"))
9546          (match_operand 1 "" "i"))
9547    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9548   "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
9549   "*
9551   register rtx target = operands[0];
9553   if (GET_CODE (target) == SYMBOL_REF)
9554     return \"%*jal\\t%0\";
9555   else if (GET_CODE (target) == CONST_INT)
9556     return \"%[li\\t%@,%0\\n\\t%*jal\\t%2,%@%]\";
9557   else
9558     return \"%*jal\\t%2,%0\";
9560   [(set_attr "type"     "call")
9561    (set_attr "mode"     "none")])
9563 (define_insn "call_internal2"
9564   [(call (mem (match_operand 0 "call_insn_operand" "ri"))
9565          (match_operand 1 "" "i"))
9566    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9567   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9568   "*
9570   register rtx target = operands[0];
9572   if (GET_CODE (target) == SYMBOL_REF)
9573     {
9574       if (GET_MODE (target) == SImode)
9575         return \"la\\t%^,%0\\n\\tjal\\t%2,%^\";
9576       else
9577         return \"dla\\t%^,%0\\n\\tjal\\t%2,%^\";
9578     }
9579   else if (GET_CODE (target) == CONST_INT)
9580     return \"li\\t%^,%0\\n\\tjal\\t%2,%^\";
9581   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9582     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9583   else
9584     return \"jal\\t%2,%0\";
9586   [(set_attr "type"     "call")
9587    (set_attr "mode"     "none")
9588    (set_attr "length"   "8")])
9590 (define_insn "call_internal3a"
9591   [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9592          (match_operand 1 "" "i"))
9593    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9594   "!(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9595   "%*jal\\t%2,%0"
9596   [(set_attr "type"     "call")
9597    (set_attr "mode"     "none")])
9599 (define_insn "call_internal3b"
9600   [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
9601          (match_operand 1 "" "i"))
9602    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9603   "Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9604   "%*jal\\t%2,%0"
9605   [(set_attr "type"     "call")
9606    (set_attr "mode"     "none")])
9608 (define_insn "call_internal4a"
9609   [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9610          (match_operand 1 "" "i"))
9611    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9612   "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
9613   "*
9615   if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9616     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9617   else
9618     return \"jal\\t%2,%0\";
9620   [(set_attr "type"     "call")
9621    (set_attr "mode"     "none")
9622    (set_attr "length"   "8")])
9624 (define_insn "call_internal4b"
9625   [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
9626          (match_operand 1 "" "i"))
9627    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9628   "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
9629   "*
9631   if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9632     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9633   else
9634     return \"jal\\t%2,%0\";
9636   [(set_attr "type"     "call")
9637    (set_attr "mode"     "none")
9638    (set_attr "length"   "8")])
9640 ;; calls.c now passes a fourth argument, make saber happy
9642 (define_expand "call_value"
9643   [(parallel [(set (match_operand 0 "register_operand" "=df")
9644                    (call (match_operand 1 "memory_operand" "m")
9645                          (match_operand 2 "" "i")))
9646               (clobber (reg:SI 31))
9647               (use (match_operand 3 "" ""))])]          ;; next_arg_reg
9648   ""
9649   "
9651   rtx addr;
9653   if (operands[0])              /* eliminate unused code warning */
9654     {
9655       addr = XEXP (operands[1], 0);
9656       if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
9657           || ! call_insn_operand (addr, VOIDmode))
9658         XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
9660       /* In order to pass small structures by value in registers
9661          compatibly with the MIPS compiler, we need to shift the value
9662          into the high part of the register.  Function_arg has encoded
9663          a PARALLEL rtx, holding a vector of adjustments to be made
9664          as the next_arg_reg variable, so we split up the insns,
9665          and emit them separately.  */
9667       if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL)
9668         {
9669           rtvec adjust = XVEC (operands[3], 0);
9670           int num = GET_NUM_ELEM (adjust);
9671           int i;
9673           for (i = 0; i < num; i++)
9674             emit_insn (RTVEC_ELT (adjust, i));
9675         }
9677       if (TARGET_MIPS16
9678           && mips16_hard_float
9679           && ((operands[3] != 0
9680                && (int) GET_MODE (operands[3]) != 0)
9681               || GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_FLOAT))
9682         {
9683           if (build_mips16_call_stub (operands[0], operands[1], operands[2],
9684                                       (operands[3] == 0 ? 0
9685                                        : (int) GET_MODE (operands[3]))))
9686             DONE;
9687         }
9689       /* Handle Irix6 function calls that have multiple non-contiguous
9690          results.  */
9691       if (GET_CODE (operands[0]) == PARALLEL && XVECLEN (operands[0], 0) > 1)
9692         {
9693           emit_call_insn (gen_call_value_multiple_internal0
9694                           (XEXP (XVECEXP (operands[0], 0, 0), 0),
9695                            operands[1], operands[2],
9696                            XEXP (XVECEXP (operands[0], 0, 1), 0),
9697                            gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
9698           DONE;
9699         }
9701       /* We have a call returning a DImode structure in an FP reg.
9702          Strip off the now unnecessary PARALLEL.  */
9703       if (GET_CODE (operands[0]) == PARALLEL)
9704         operands[0] = XEXP (XVECEXP (operands[0], 0, 0), 0);
9706       emit_call_insn (gen_call_value_internal0 (operands[0], operands[1], operands[2],
9707                                                 gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
9709       DONE;
9710     }
9713 (define_expand "call_value_internal0"
9714   [(parallel [(set (match_operand 0 "" "")
9715                    (call (match_operand 1 "" "")
9716                          (match_operand 2 "" "")))
9717               (clobber (match_operand:SI 3 "" ""))])]
9718   ""
9719   "")
9721 ;; Recognize $31 specially on the mips16, because we don't have a
9722 ;; constraint letter for it.
9724 (define_insn ""
9725   [(set (match_operand 0 "register_operand" "=d")
9726         (call (mem (match_operand 1 "call_insn_operand" "ei"))
9727               (match_operand 2 "" "i")))
9728    (clobber (match_operand:SI 3 "register_operand" "=y"))]
9729   "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
9730    && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
9731   "%*jal\\t%1"
9732   [(set_attr "type"     "call")
9733    (set_attr "mode"     "none")
9734    (set_attr "length"   "8")])
9736 (define_insn "call_value_internal1"
9737   [(set (match_operand 0 "register_operand" "=df")
9738         (call (mem (match_operand 1 "call_insn_operand" "ri"))
9739               (match_operand 2 "" "i")))
9740    (clobber (match_operand:SI 3 "register_operand" "=d"))]
9741   "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
9742   "*
9744   register rtx target = operands[1];
9746   if (GET_CODE (target) == SYMBOL_REF)
9747     return \"%*jal\\t%1\";
9748   else if (GET_CODE (target) == CONST_INT)
9749     return \"%[li\\t%@,%1\\n\\t%*jal\\t%3,%@%]\";
9750   else
9751     return \"%*jal\\t%3,%1\";
9753   [(set_attr "type"     "call")
9754    (set_attr "mode"     "none")])
9756 (define_insn "call_value_internal2"
9757   [(set (match_operand 0 "register_operand" "=df")
9758         (call (mem (match_operand 1 "call_insn_operand" "ri"))
9759               (match_operand 2 "" "i")))
9760    (clobber (match_operand:SI 3 "register_operand" "=d"))]
9761   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9762   "*
9764   register rtx target = operands[1];
9766   if (GET_CODE (target) == SYMBOL_REF)
9767     {
9768       if (GET_MODE (target) == SImode)
9769         return \"la\\t%^,%1\\n\\tjal\\t%3,%^\";
9770       else
9771         return \"dla\\t%^,%1\\n\\tjal\\t%3,%^\";
9772     }
9773   else if (GET_CODE (target) == CONST_INT)
9774     return \"li\\t%^,%1\\n\\tjal\\t%3,%^\";
9775   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9776     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
9777   else
9778     return \"jal\\t%3,%1\";
9780   [(set_attr "type"     "call")
9781    (set_attr "mode"     "none")
9782    (set_attr "length"   "8")])
9784 (define_insn "call_value_internal3a"
9785   [(set (match_operand 0 "register_operand" "=df")
9786         (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
9787               (match_operand 2 "" "i")))
9788    (clobber (match_operand:SI 3 "register_operand" "=d"))]
9789   "!TARGET_MIPS16 
9790    && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9791   "%*jal\\t%3,%1"
9792   [(set_attr "type"     "call")
9793    (set_attr "mode"     "none")])
9795 (define_insn "call_value_internal3b"
9796   [(set (match_operand 0 "register_operand" "=df")
9797         (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
9798               (match_operand 2 "" "i")))
9799    (clobber (match_operand:SI 3 "register_operand" "=d"))]
9800   "!TARGET_MIPS16 
9801    && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9802   "%*jal\\t%3,%1"
9803   [(set_attr "type"     "call")
9804    (set_attr "mode"     "none")])
9806 (define_insn "call_value_internal3c"
9807   [(set (match_operand 0 "register_operand" "=df")
9808         (call (mem:SI (match_operand:SI 1 "register_operand" "e"))
9809               (match_operand 2 "" "i")))
9810    (clobber (match_operand:SI 3 "register_operand" "=y"))]
9811   "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
9812    && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
9813   "%*jal\\t%3,%1"
9814   [(set_attr "type"     "call")
9815    (set_attr "mode"     "none")])
9817 (define_insn "call_value_internal4a"
9818   [(set (match_operand 0 "register_operand" "=df")
9819         (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
9820               (match_operand 2 "" "i")))
9821    (clobber (match_operand:SI 3 "register_operand" "=d"))]
9822   "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
9823   "*
9825   if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
9826     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
9827   else
9828     return \"jal\\t%3,%1\";
9830   [(set_attr "type"     "call")
9831    (set_attr "mode"     "none")
9832    (set_attr "length"   "8")])
9834 (define_insn "call_value_internal4b"
9835   [(set (match_operand 0 "register_operand" "=df")
9836         (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
9837               (match_operand 2 "" "i")))
9838    (clobber (match_operand:SI 3 "register_operand" "=d"))]
9839   "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
9840   "*
9842   if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
9843     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
9844   else
9845     return \"jal\\t%3,%1\";
9847   [(set_attr "type"     "call")
9848    (set_attr "mode"     "none")
9849    (set_attr "length"   "8")])
9851 (define_expand "call_value_multiple_internal0"
9852   [(parallel [(set (match_operand 0 "" "")
9853                    (call (match_operand 1 "" "")
9854                          (match_operand 2 "" "")))
9855               (set (match_operand 3 "" "")
9856                    (call (match_dup 1)
9857                          (match_dup 2)))
9858               (clobber (match_operand:SI 4 "" ""))])]
9859   ""
9860   "")
9862 ;; ??? May eventually need all 6 versions of the call patterns with multiple
9863 ;; return values.
9865 (define_insn "call_value_multiple_internal2"
9866   [(set (match_operand 0 "register_operand" "=df")
9867         (call (mem (match_operand 1 "call_insn_operand" "ri"))
9868               (match_operand 2 "" "i")))
9869    (set (match_operand 3 "register_operand" "=df")
9870         (call (mem (match_dup 1))
9871               (match_dup 2)))
9872    (clobber (match_operand:SI 4 "register_operand" "=d"))]
9873   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9874   "*
9876   register rtx target = operands[1];
9878   if (GET_CODE (target) == SYMBOL_REF)
9879     {
9880       if (GET_MODE (target) == SImode)
9881         return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
9882       else
9883         return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
9884     }
9885   else if (GET_CODE (target) == CONST_INT)
9886     return \"li\\t%^,%1\\n\\tjal\\t%4,%^\";
9887   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9888     return \"move\\t%^,%1\\n\\tjal\\t%4,%^\";
9889   else
9890     return \"jal\\t%4,%1\";
9892   [(set_attr "type"     "call")
9893    (set_attr "mode"     "none")
9894    (set_attr "length"   "8")])
9897 ;; Call subroutine returning any type.
9899 (define_expand "untyped_call"
9900   [(parallel [(call (match_operand 0 "" "")
9901                     (const_int 0))
9902               (match_operand 1 "" "")
9903               (match_operand 2 "" "")])]
9904   ""
9905   "
9907   if (operands[0])              /* silence statement not reached warnings */
9908     {
9909       int i;
9911       emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
9913       for (i = 0; i < XVECLEN (operands[2], 0); i++)
9914         {
9915           rtx set = XVECEXP (operands[2], 0, i);
9916           emit_move_insn (SET_DEST (set), SET_SRC (set));
9917         }
9919       emit_insn (gen_blockage ());
9920       DONE;
9921     }
9925 ;;  ....................
9927 ;;      MISC.
9929 ;;  ....................
9932 (define_insn "nop"
9933   [(const_int 0)]
9934   ""
9935   "%(nop%)"
9936   [(set_attr "type"     "nop")
9937    (set_attr "mode"     "none")])
9939 ;; The MIPS chip does not seem to require stack probes.
9941 ;; (define_expand "probe"
9942 ;;   [(set (match_dup 0)
9943 ;;      (match_dup 1))]
9944 ;;   ""
9945 ;;   "
9946 ;; {
9947 ;;   operands[0] = gen_reg_rtx (SImode);
9948 ;;   operands[1] = gen_rtx (MEM, SImode, stack_pointer_rtx);
9949 ;;   MEM_VOLATILE_P (operands[1]) = TRUE;
9950 ;; 
9951 ;;   /* fall through and generate default code */
9952 ;; }")
9956 ;; MIPS4 Conditional move instructions.
9958 (define_insn ""
9959   [(set (match_operand:SI 0 "register_operand" "=d,d")
9960         (if_then_else:SI
9961          (match_operator 4 "equality_op"
9962                          [(match_operand:SI 1 "register_operand" "d,d")
9963                           (const_int 0)])
9964          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
9965          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
9966   "mips_isa >= 4"
9967   "@
9968     mov%B4\\t%0,%z2,%1
9969     mov%b4\\t%0,%z3,%1"
9970   [(set_attr "type" "move")
9971    (set_attr "mode" "SI")])
9973 (define_insn ""
9974   [(set (match_operand:SI 0 "register_operand" "=d,d")
9975         (if_then_else:SI
9976          (match_operator 4 "equality_op"
9977                          [(match_operand:DI 1 "se_register_operand" "d,d")
9978                           (const_int 0)])
9979          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
9980          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
9981   "mips_isa >= 4"
9982   "@
9983     mov%B4\\t%0,%z2,%1
9984     mov%b4\\t%0,%z3,%1"
9985   [(set_attr "type" "move")
9986    (set_attr "mode" "SI")])
9988 (define_insn ""
9989   [(set (match_operand:SI 0 "register_operand" "=d,d")
9990         (if_then_else:SI
9991          (match_operator 3 "equality_op" [(match_operand:CC 4
9992                                                             "register_operand"
9993                                                             "z,z")
9994                                           (const_int 0)])
9995          (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
9996          (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
9997   "mips_isa >= 4 && TARGET_HARD_FLOAT"
9998   "@
9999     mov%T3\\t%0,%z1,%4
10000     mov%t3\\t%0,%z2,%4"
10001   [(set_attr "type" "move")
10002    (set_attr "mode" "SI")])
10004 (define_insn ""
10005   [(set (match_operand:DI 0 "register_operand" "=d,d")
10006         (if_then_else:DI
10007          (match_operator 4 "equality_op"
10008                          [(match_operand:SI 1 "register_operand" "d,d")
10009                           (const_int 0)])
10010          (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10011          (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
10012   "mips_isa >= 4"
10013   "@
10014     mov%B4\\t%0,%z2,%1
10015     mov%b4\\t%0,%z3,%1"
10016   [(set_attr "type" "move")
10017    (set_attr "mode" "DI")])
10019 (define_insn ""
10020   [(set (match_operand:DI 0 "register_operand" "=d,d")
10021         (if_then_else:DI
10022          (match_operator 4 "equality_op"
10023                          [(match_operand:DI 1 "se_register_operand" "d,d")
10024                           (const_int 0)])
10025          (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
10026          (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
10027   "mips_isa >= 4"
10028   "@
10029     mov%B4\\t%0,%z2,%1
10030     mov%b4\\t%0,%z3,%1"
10031   [(set_attr "type" "move")
10032    (set_attr "mode" "DI")])
10034 (define_insn ""
10035   [(set (match_operand:DI 0 "register_operand" "=d,d")
10036         (if_then_else:DI
10037          (match_operator 3 "equality_op" [(match_operand:CC 4
10038                                                             "register_operand"
10039                                                             "z,z")
10040                                           (const_int 0)])
10041          (match_operand:DI 1 "se_reg_or_0_operand" "dJ,0")
10042          (match_operand:DI 2 "se_reg_or_0_operand" "0,dJ")))]
10043   "mips_isa >= 4 && TARGET_HARD_FLOAT"
10044   "@
10045     mov%T3\\t%0,%z1,%4
10046     mov%t3\\t%0,%z2,%4"
10047   [(set_attr "type" "move")
10048    (set_attr "mode" "DI")])
10050 (define_insn ""
10051   [(set (match_operand:SF 0 "register_operand" "=f,f")
10052         (if_then_else:SF
10053          (match_operator 4 "equality_op"
10054                          [(match_operand:SI 1 "register_operand" "d,d")
10055                           (const_int 0)])
10056          (match_operand:SF 2 "register_operand" "f,0")
10057          (match_operand:SF 3 "register_operand" "0,f")))]
10058   "mips_isa >= 4 && TARGET_HARD_FLOAT"
10059   "@
10060     mov%B4.s\\t%0,%2,%1
10061     mov%b4.s\\t%0,%3,%1"
10062   [(set_attr "type" "move")
10063    (set_attr "mode" "SF")])
10065 (define_insn ""
10066   [(set (match_operand:SF 0 "register_operand" "=f,f")
10067         (if_then_else:SF
10068          (match_operator 3 "equality_op" [(match_operand:CC 4
10069                                                             "register_operand"
10070                                                             "z,z")
10071                                           (const_int 0)])
10072          (match_operand:SF 1 "register_operand" "f,0")
10073          (match_operand:SF 2 "register_operand" "0,f")))]
10074   "mips_isa >= 4 && TARGET_HARD_FLOAT"
10075   "@
10076     mov%T3.s\\t%0,%1,%4
10077     mov%t3.s\\t%0,%2,%4"
10078   [(set_attr "type" "move")
10079    (set_attr "mode" "SF")])
10081 (define_insn ""
10082   [(set (match_operand:DF 0 "register_operand" "=f,f")
10083         (if_then_else:DF
10084          (match_operator 4 "equality_op"
10085                          [(match_operand:SI 1 "register_operand" "d,d")
10086                           (const_int 0)])
10087          (match_operand:DF 2 "register_operand" "f,0")
10088          (match_operand:DF 3 "register_operand" "0,f")))]
10089   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10090   "@
10091     mov%B4.d\\t%0,%2,%1
10092     mov%b4.d\\t%0,%3,%1"
10093   [(set_attr "type" "move")
10094    (set_attr "mode" "DF")])
10096 (define_insn ""
10097   [(set (match_operand:DF 0 "register_operand" "=f,f")
10098         (if_then_else:DF
10099          (match_operator 3 "equality_op" [(match_operand:CC 4
10100                                                             "register_operand"
10101                                                             "z,z")
10102                                           (const_int 0)])
10103          (match_operand:DF 1 "register_operand" "f,0")
10104          (match_operand:DF 2 "register_operand" "0,f")))]
10105   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10106   "@
10107     mov%T3.d\\t%0,%1,%4
10108     mov%t3.d\\t%0,%2,%4"
10109   [(set_attr "type" "move")
10110    (set_attr "mode" "DF")])
10112 ;; These are the main define_expand's used to make conditional moves.
10114 (define_expand "movsicc"
10115   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10116    (set (match_operand:SI 0 "register_operand" "")
10117         (if_then_else:SI (match_dup 5)
10118                          (match_operand:SI 2 "reg_or_0_operand" "")
10119                          (match_operand:SI 3 "reg_or_0_operand" "")))]
10120   "mips_isa >= 4"
10121   "
10123   gen_conditional_move (operands);
10124   DONE;
10127 (define_expand "movdicc"
10128   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10129    (set (match_operand:DI 0 "register_operand" "")
10130         (if_then_else:DI (match_dup 5)
10131                          (match_operand:DI 2 "se_reg_or_0_operand" "")
10132                          (match_operand:DI 3 "se_reg_or_0_operand" "")))]
10133   "mips_isa >= 4"
10134   "
10136   gen_conditional_move (operands);
10137   DONE;
10140 (define_expand "movsfcc"
10141   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10142    (set (match_operand:SF 0 "register_operand" "")
10143         (if_then_else:SF (match_dup 5)
10144                          (match_operand:SF 2 "register_operand" "")
10145                          (match_operand:SF 3 "register_operand" "")))]
10146   "mips_isa >= 4 && TARGET_HARD_FLOAT"
10147   "
10149   gen_conditional_move (operands);
10150   DONE;
10153 (define_expand "movdfcc"
10154   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
10155    (set (match_operand:DF 0 "register_operand" "")
10156         (if_then_else:DF (match_dup 5)
10157                          (match_operand:DF 2 "register_operand" "")
10158                          (match_operand:DF 3 "register_operand" "")))]
10159   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
10160   "
10162   gen_conditional_move (operands);
10163   DONE;
10167 ;;  ....................
10169 ;;      mips16 inline constant tables
10171 ;;  ....................
10174 (define_insn "consttable_qi"
10175   [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "=g")] 10)]
10176   "TARGET_MIPS16"
10177   "*
10179   assemble_integer (operands[0], 1, 1);
10180   return \"\";
10182   [(set_attr "type"     "unknown")
10183    (set_attr "mode"     "QI")
10184    (set_attr "length"   "8")])
10186 (define_insn "consttable_hi"
10187   [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "=g")] 11)]
10188   "TARGET_MIPS16"
10189   "*
10191   assemble_integer (operands[0], 2, 1);
10192   return \"\";
10194   [(set_attr "type"     "unknown")
10195    (set_attr "mode"     "HI")
10196    (set_attr "length"   "8")])
10198 (define_insn "consttable_si"
10199   [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "=g")] 12)]
10200   "TARGET_MIPS16"
10201   "*
10203   assemble_integer (operands[0], 4, 1);
10204   return \"\";
10206   [(set_attr "type"     "unknown")
10207    (set_attr "mode"     "SI")
10208    (set_attr "length"   "8")])
10210 (define_insn "consttable_di"
10211   [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "=g")] 13)]
10212   "TARGET_MIPS16"
10213   "*
10215   assemble_integer (operands[0], 8, 1);
10216   return \"\";
10218   [(set_attr "type"     "unknown")
10219    (set_attr "mode"     "DI")
10220    (set_attr "length"   "16")])
10222 (define_insn "consttable_sf"
10223   [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "=g")] 14)]
10224   "TARGET_MIPS16"
10225   "*
10227   union real_extract u;
10229   if (GET_CODE (operands[0]) != CONST_DOUBLE)
10230     abort ();
10231   bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
10232   assemble_real (u.d, SFmode);
10233   return \"\";
10235   [(set_attr "type"     "unknown")
10236    (set_attr "mode"     "SF")
10237    (set_attr "length"   "8")])
10239 (define_insn "consttable_df"
10240   [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "=g")] 15)]
10241   "TARGET_MIPS16"
10242   "*
10244   union real_extract u;
10246   if (GET_CODE (operands[0]) != CONST_DOUBLE)
10247     abort ();
10248   bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
10249   assemble_real (u.d, DFmode);
10250   return \"\";
10252   [(set_attr "type"     "unknown")
10253    (set_attr "mode"     "DF")
10254    (set_attr "length"   "16")])
10256 (define_insn "align_2"
10257   [(unspec_volatile [(const_int 0)] 16)]
10258   "TARGET_MIPS16"
10259   ".align 1"
10260   [(set_attr "type"     "unknown")
10261    (set_attr "mode"     "HI")
10262    (set_attr "length"   "8")])
10264 (define_insn "align_4"
10265   [(unspec_volatile [(const_int 0)] 17)]
10266   "TARGET_MIPS16"
10267   ".align 2"
10268   [(set_attr "type"     "unknown")
10269    (set_attr "mode"     "SI")
10270    (set_attr "length"   "8")])
10272 (define_insn "align_8"
10273   [(unspec_volatile [(const_int 0)] 18)]
10274   "TARGET_MIPS16"
10275   ".align 3"
10276   [(set_attr "type"     "unknown")
10277    (set_attr "mode"     "DI")
10278    (set_attr "length"   "12")])
10281 ;;  ....................
10283 ;;      mips16 peepholes
10285 ;;  ....................
10288 ;; On the mips16, reload will sometimes decide that a pseudo register
10289 ;; should go into $24, and then later on have to reload that register.
10290 ;; When that happens, we get a load of a general register followed by
10291 ;; a move from the general register to $24 followed by a branch.
10292 ;; These peepholes catch the common case, and fix it to just use the
10293 ;; general register for the branch.
10295 (define_peephole
10296   [(set (match_operand:SI 0 "register_operand" "=t")
10297         (match_operand:SI 1 "register_operand" "d"))
10298    (set (pc)
10299         (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10300                                                           (const_int 0)])
10301                       (match_operand 3 "pc_or_label_operand" "")
10302                       (match_operand 4 "pc_or_label_operand" "")))]
10303   "TARGET_MIPS16
10304    && GET_CODE (operands[0]) == REG
10305    && REGNO (operands[0]) == 24
10306    && dead_or_set_p (insn, operands[0])
10307    && GET_CODE (operands[1]) == REG
10308    && M16_REG_P (REGNO (operands[1]))"
10309   "*
10311   if (operands[3] != pc_rtx)
10312     return \"%*b%C2z\\t%1,%3\";
10313   else
10314     return \"%*b%N2z\\t%1,%4\";
10316   [(set_attr "type"     "branch")
10317    (set_attr "mode"     "none")
10318    (set_attr "length"   "8")])
10320 (define_peephole
10321   [(set (match_operand:DI 0 "register_operand" "=t")
10322         (match_operand:DI 1 "register_operand" "d"))
10323    (set (pc)
10324         (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10325                                                           (const_int 0)])
10326                       (match_operand 3 "pc_or_label_operand" "")
10327                       (match_operand 4 "pc_or_label_operand" "")))]
10328   "TARGET_MIPS16 && TARGET_64BIT
10329    && GET_CODE (operands[0]) == REG
10330    && REGNO (operands[0]) == 24
10331    && dead_or_set_p (insn, operands[0])
10332    && GET_CODE (operands[1]) == REG
10333    && M16_REG_P (REGNO (operands[1]))"
10334   "*
10336   if (operands[3] != pc_rtx)
10337     return \"%*b%C2z\\t%1,%3\";
10338   else
10339     return \"%*b%N2z\\t%1,%4\";
10341   [(set_attr "type"     "branch")
10342    (set_attr "mode"     "none")
10343    (set_attr "length"   "8")])
10345 ;; We can also have the reverse reload: reload will spill $24 into
10346 ;; another register, and then do a branch on that register when it
10347 ;; could have just stuck with $24.
10349 (define_peephole
10350   [(set (match_operand:SI 0 "register_operand" "=d")
10351         (match_operand:SI 1 "register_operand" "t"))
10352    (set (pc)
10353         (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
10354                                                           (const_int 0)])
10355                       (match_operand 3 "pc_or_label_operand" "")
10356                       (match_operand 4 "pc_or_label_operand" "")))]
10357   "TARGET_MIPS16
10358    && GET_CODE (operands[1]) == REG
10359    && REGNO (operands[1]) == 24
10360    && GET_CODE (operands[0]) == REG
10361    && M16_REG_P (REGNO (operands[0]))
10362    && dead_or_set_p (insn, operands[0])"
10363   "*
10365   if (operands[3] != pc_rtx)
10366     return \"%*bt%C2z\\t%3\";
10367   else
10368     return \"%*bt%N2z\\t%4\";
10370   [(set_attr "type"     "branch")
10371    (set_attr "mode"     "none")
10372    (set_attr "length"   "8")])
10374 (define_peephole
10375   [(set (match_operand:DI 0 "register_operand" "=d")
10376         (match_operand:DI 1 "register_operand" "t"))
10377    (set (pc)
10378         (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
10379                                                           (const_int 0)])
10380                       (match_operand 3 "pc_or_label_operand" "")
10381                       (match_operand 4 "pc_or_label_operand" "")))]
10382   "TARGET_MIPS16 && TARGET_64BIT
10383    && GET_CODE (operands[1]) == REG
10384    && REGNO (operands[1]) == 24
10385    && GET_CODE (operands[0]) == REG
10386    && M16_REG_P (REGNO (operands[0]))
10387    && dead_or_set_p (insn, operands[0])"
10388   "*
10390   if (operands[3] != pc_rtx)
10391     return \"%*bt%C2z\\t%3\";
10392   else
10393     return \"%*bt%N2z\\t%4\";
10395   [(set_attr "type"     "branch")
10396    (set_attr "mode"     "none")
10397    (set_attr "length"   "8")])
10399 ;; For the rare case where we need to load an address into a register
10400 ;; that can not be recognized by the normal movsi/addsi instructions.
10401 ;; I have no idea how many insns this can actually generate.  It should
10402 ;; be rare, so over-estimating as 10 instructions should not have any
10403 ;; real performance impact.
10404 (define_insn "leasi"
10405   [(set (match_operand:SI 0 "register_operand" "=d")
10406         (match_operand:SI 1 "address_operand" "p"))]
10407   "Pmode == SImode"
10408   "la %0,%a1"
10409   [(set_attr "type"     "arith")
10410    (set_attr "mode"     "SI")
10411    (set_attr "length"   "40")])
10413 ;; Similarly for targets where we have 64bit pointers.
10414 (define_insn "leadi"
10415   [(set (match_operand:DI 0 "register_operand" "=d")
10416         (match_operand:DI 1 "address_operand" "p"))]
10417   "Pmode == DImode"
10418   "la %0,%a1"
10419   [(set_attr "type"     "arith")
10420    (set_attr "mode"     "DI")
10421    (set_attr "length"   "40")])