OSDN Git Service

* m32r.md, mips.md, mn10200.md, mn10300.md, pyr.md: Add
[pf3gnuchains/gcc-fork.git] / gcc / config / mips / mips.md
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-97, 1998 Free Software Foundation, Inc.
7
8 ;; This file is part of GNU CC.
9
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.
14
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.
19
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.
24
25 ;; ??? Currently does not have define_function_unit support for the R8000.
26 ;; Must include new entries for fmadd in addition to existing entries.
27
28 \f
29
30 ;; ....................
31 ;;
32 ;;      Attributes
33 ;;
34 ;; ....................
35
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
61
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"))
65
66 ;; Main data type used by the insn
67 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown"))
68
69 ;; # instructions (4 bytes each)
70 (define_attr "length" "" (const_int 1))
71
72 ;; whether or not an instruction has a mandatory delay slot
73 (define_attr "dslot" "no,yes"
74   (if_then_else (ior (eq_attr "type" "branch,jump,call,xfer,hilo,fcmp")
75                      (and (eq_attr "type" "load")
76                           (and (eq (symbol_ref "mips_isa") (const_int 1))
77                                    (eq (symbol_ref "mips16") (const_int 0)))))
78                 (const_string "yes")
79                 (const_string "no")))
80
81 ;; Attribute describing the processor.  This attribute must match exactly
82 ;; with the processor_type enumeration in mips.h.
83
84 ;; Attribute describing the processor
85 ;; (define_attr "cpu" "default,r3000,r6000,r4000"
86 ;;   (const
87 ;;    (cond [(eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R3000"))   (const_string "r3000")
88 ;;           (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R4000"))   (const_string "r4000")
89 ;;           (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R6000"))   (const_string "r6000")]
90 ;;          (const_string "default"))))
91
92 ;; ??? Fix everything that tests this attribute.
93 (define_attr "cpu"
94   "default,r3000,r3900,r6000,r4000,r4100,r4300,r4600,r4650,r5000,r8000"
95   (const (symbol_ref "mips_cpu_attr")))
96
97 ;; Attribute defining whether or not we can use the branch-likely instructions
98
99 (define_attr "branch_likely" "no,yes"
100   (const
101    (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
102                  (const_string "yes")
103                  (const_string "no"))))
104
105
106 ;; Describe a user's asm statement.
107 (define_asm_attributes
108   [(set_attr "type" "multi")])
109
110 ;; whether or not generating calls to position independent functions
111 (define_attr "abicalls" "no,yes"
112   (const (symbol_ref "mips_abicalls_attr")))
113
114 \f
115
116 ;; .........................
117 ;;
118 ;;      Delay slots, can't describe load/fcmp/xfer delay slots here
119 ;;
120 ;; .........................
121
122 (define_delay (and (eq_attr "type" "branch")
123                    (eq (symbol_ref "mips16") (const_int 0)))
124   [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
125    (nil)
126    (and (eq_attr "branch_likely" "yes") (and (eq_attr "dslot" "no") (eq_attr "length" "1")))])
127
128 (define_delay (eq_attr "type" "jump")
129   [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
130    (nil)
131    (nil)])
132
133 (define_delay (and (eq_attr "type" "call") (eq_attr "abicalls" "no"))
134   [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
135    (nil)
136    (nil)])
137
138 \f
139
140 ;; .........................
141 ;;
142 ;;      Functional units
143 ;;
144 ;; .........................
145
146 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
147 ;                       TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
148
149 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
150
151 (define_function_unit "memory" 1 0
152   (and (eq_attr "type" "load")
153        (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
154   3 0)
155
156 (define_function_unit "memory" 1 0
157   (and (eq_attr "type" "load")
158        (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
159   2 0)
160
161 (define_function_unit "memory"   1 0 (eq_attr "type" "store") 1 0)
162
163 (define_function_unit "memory"   1 0 (eq_attr "type" "xfer") 2 0)
164
165 (define_function_unit "imuldiv"  1 0
166   (eq_attr "type" "hilo")
167   1 3)
168
169 (define_function_unit "imuldiv"  1 0
170   (and (eq_attr "type" "imul")
171        (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
172   17 17)
173
174 ;; On them mips16, we want to stronly discourage a mult from appearing
175 ;; after an mflo, since that requires explicit nop instructions.  We
176 ;; do this by pretending that mflo ties up the function unit for long
177 ;; enough that the scheduler will ignore load stalls and the like when
178 ;; selecting instructions to between the two instructions.
179
180 (define_function_unit "imuldiv" 1 0
181   (and (eq_attr "type" "hilo") (ne (symbol_ref "mips16") (const_int 0)))
182   1 5)
183
184 (define_function_unit "imuldiv"  1 0
185   (and (eq_attr "type" "imul") (eq_attr "cpu" "r3000,r3900"))
186   12 12)
187
188 (define_function_unit "imuldiv"  1 0
189   (and (eq_attr "type" "imul") (eq_attr "cpu" "r4000,r4600"))
190   10 10)
191
192 (define_function_unit "imuldiv"  1 0
193   (and (eq_attr "type" "imul") (eq_attr "cpu" "r4650"))
194   4 4)
195
196 (define_function_unit "imuldiv"  1 0
197   (and (eq_attr "type" "imul")
198        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
199   1 1)
200
201 (define_function_unit "imuldiv"  1 0
202   (and (eq_attr "type" "imul")
203        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
204   4 4)
205
206 (define_function_unit "imuldiv"  1 0
207   (and (eq_attr "type" "imul")
208        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000")))
209   5 5)
210
211 (define_function_unit "imuldiv"  1 0
212   (and (eq_attr "type" "imul")
213        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
214   8 8)
215
216 (define_function_unit "imuldiv"  1 0
217   (and (eq_attr "type" "imul")
218        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
219   9 9)
220
221 (define_function_unit "imuldiv"  1 0
222   (and (eq_attr "type" "idiv")
223        (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
224   38 38)
225
226 (define_function_unit "imuldiv"  1 0
227   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000,r3900"))
228   35 35)
229
230 (define_function_unit "imuldiv"  1 0
231   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
232   42 42)
233
234 (define_function_unit "imuldiv"  1 0
235   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
236   36 36)
237
238 (define_function_unit "imuldiv"  1 0
239   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
240   69 69)
241
242 (define_function_unit "imuldiv" 1 0
243   (and (eq_attr "type" "idiv")
244        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
245   35 35)
246
247 (define_function_unit "imuldiv" 1 0
248   (and (eq_attr "type" "idiv")
249        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
250   67 67)
251
252 (define_function_unit "imuldiv" 1 0
253   (and (eq_attr "type" "idiv")
254        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
255   37 37)
256
257 (define_function_unit "imuldiv" 1 0
258   (and (eq_attr "type" "idiv")
259        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
260   69 69)
261
262 (define_function_unit "imuldiv" 1 0
263   (and (eq_attr "type" "idiv")
264        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000")))
265   36 36)
266
267 (define_function_unit "imuldiv" 1 0
268   (and (eq_attr "type" "idiv")
269        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
270   68 68)
271
272 ;; The R4300 does *NOT* have a separate Floating Point Unit, instead
273 ;; the FP hardware is part of the normal ALU circuitry.  This means FP
274 ;; instructions affect the pipe-line, and no functional unit
275 ;; parallelism can occur on R4300 processors.  To force GCC into coding
276 ;; for only a single functional unit, we force the R4300 FP
277 ;; instructions to be processed in the "imuldiv" unit.
278
279 (define_function_unit "adder" 1 1
280   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
281   3 0)
282
283 (define_function_unit "adder" 1 1
284   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r3900,r6000"))
285   2 0)
286
287 (define_function_unit "adder" 1 1
288   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000"))
289   1 0)
290
291 (define_function_unit "adder" 1 1
292   (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
293   4 0)
294
295 (define_function_unit "adder" 1 1
296   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000,r3900"))
297   2 0)
298
299 (define_function_unit "adder" 1 1
300   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
301   3 0)
302
303 (define_function_unit "adder" 1 1
304   (and (eq_attr "type" "fabs,fneg")
305        (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000"))
306   2 0)
307
308 (define_function_unit "adder" 1 1
309   (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r3900,r4600,r4650,r5000"))
310   1 0)
311
312 (define_function_unit "mult" 1 1
313   (and (eq_attr "type" "fmul")
314        (and (eq_attr "mode" "SF")
315             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
316   7 0)
317
318 (define_function_unit "mult" 1 1
319   (and (eq_attr "type" "fmul")
320        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900,r5000")))
321   4 0)
322
323 (define_function_unit "mult" 1 1
324   (and (eq_attr "type" "fmul")
325        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
326   5 0)
327
328 (define_function_unit "mult" 1 1
329   (and (eq_attr "type" "fmul")
330        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
331   8 0)
332
333 (define_function_unit "mult" 1 1
334   (and (eq_attr "type" "fmul")
335        (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")))
336   8 0)
337
338 (define_function_unit "mult" 1 1
339   (and (eq_attr "type" "fmul")
340        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900,r5000")))
341   5 0)
342
343 (define_function_unit "mult" 1 1
344   (and (eq_attr "type" "fmul")
345        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
346   6 0)
347
348 (define_function_unit "divide" 1 1
349   (and (eq_attr "type" "fdiv")
350        (and (eq_attr "mode" "SF")
351             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
352   23 0)
353
354 (define_function_unit "divide" 1 1
355   (and (eq_attr "type" "fdiv")
356        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900")))
357   12 0)
358
359 (define_function_unit "divide" 1 1
360   (and (eq_attr "type" "fdiv")
361        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
362   15 0)
363
364 (define_function_unit "divide" 1 1
365   (and (eq_attr "type" "fdiv")
366        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
367   32 0)
368
369 (define_function_unit "divide" 1 1
370   (and (eq_attr "type" "fdiv")
371        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
372   21 0)
373
374 (define_function_unit "divide" 1 1
375   (and (eq_attr "type" "fdiv")
376        (and (eq_attr "mode" "DF")
377             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300")))
378   36 0)
379
380 (define_function_unit "divide" 1 1
381   (and (eq_attr "type" "fdiv")
382        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900")))
383   19 0)
384
385 (define_function_unit "divide" 1 1
386   (and (eq_attr "type" "fdiv")
387        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
388   16 0)
389
390 (define_function_unit "divide" 1 1
391   (and (eq_attr "type" "fdiv")
392        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
393   61 0)
394
395 ;;; ??? Is this number right?
396 (define_function_unit "divide" 1 1
397   (and (eq_attr "type" "fsqrt")
398        (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
399   54 0)
400
401 (define_function_unit "divide" 1 1
402   (and (eq_attr "type" "fsqrt")
403        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
404   31 0)
405
406 (define_function_unit "divide" 1 1
407   (and (eq_attr "type" "fsqrt")
408        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
409   21 0)
410
411 ;;; ??? Is this number right?
412 (define_function_unit "divide" 1 1
413   (and (eq_attr "type" "fsqrt")
414        (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
415   112 0)
416
417 (define_function_unit "divide" 1 1
418   (and (eq_attr "type" "fsqrt")
419        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
420   60 0)
421
422 (define_function_unit "divide" 1 1
423   (and (eq_attr "type" "fsqrt")
424        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000")))
425   36 0)
426
427 ;; R4300 FP instruction classes treated as part of the "imuldiv"
428 ;; functional unit:
429
430 (define_function_unit "imuldiv" 1 0
431   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
432   3 3)
433
434 (define_function_unit "imuldiv" 1 0
435   (and (eq_attr "type" "fcmp,fabs,fneg") (eq_attr "cpu" "r4300"))
436   1 1)
437
438 (define_function_unit "imuldiv" 1 0
439   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
440   5 5)
441 (define_function_unit "imuldiv" 1 0
442   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
443   8 8)
444
445 (define_function_unit "imuldiv" 1 0
446   (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
447        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
448   29 29)
449 (define_function_unit "imuldiv" 1 0
450   (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
451        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
452   58 58)
453 \f
454 ;; The following functional units do not use the cpu type, and use
455 ;; much less memory in genattrtab.c.
456
457 ;; (define_function_unit "memory"   1 0 (eq_attr "type" "load")                                3 0)
458 ;; (define_function_unit "memory"   1 0 (eq_attr "type" "store")                               1 0)
459 ;;       
460 ;; (define_function_unit "fp_comp"  1 0 (eq_attr "type" "fcmp")                                2 0)
461 ;;       
462 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer")                                2 0)
463 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo")                                3 0)
464 ;;   
465 ;; (define_function_unit "imuldiv"  1 1 (eq_attr "type" "imul")                               17 0)
466 ;; (define_function_unit "imuldiv"  1 1 (eq_attr "type" "idiv")                               38 0)
467 ;;   
468 ;; (define_function_unit "adder"    1 1 (eq_attr "type" "fadd")                                4 0)
469 ;; (define_function_unit "adder"    1 1 (eq_attr "type" "fabs,fneg")                           2 0)
470 ;;   
471 ;; (define_function_unit "mult"     1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF"))    7 0)
472 ;; (define_function_unit "mult"     1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF"))    8 0)
473 ;;   
474 ;; (define_function_unit "divide"   1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF"))   23 0)
475 ;; (define_function_unit "divide"   1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF"))   36 0)
476 ;; 
477 ;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF"))  54 0)
478 ;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0)
479
480 \f
481 ;;
482 ;;  ....................
483 ;;
484 ;;      ADDITION
485 ;;
486 ;;  ....................
487 ;;
488
489 (define_insn "adddf3"
490   [(set (match_operand:DF 0 "register_operand" "=f")
491         (plus:DF (match_operand:DF 1 "register_operand" "f")
492                  (match_operand:DF 2 "register_operand" "f")))]
493   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
494   "add.d\\t%0,%1,%2"
495   [(set_attr "type"     "fadd")
496    (set_attr "mode"     "DF")
497    (set_attr "length"   "1")])
498
499 (define_insn "addsf3"
500   [(set (match_operand:SF 0 "register_operand" "=f")
501         (plus:SF (match_operand:SF 1 "register_operand" "f")
502                  (match_operand:SF 2 "register_operand" "f")))]
503   "TARGET_HARD_FLOAT"
504   "add.s\\t%0,%1,%2"
505   [(set_attr "type"     "fadd")
506    (set_attr "mode"     "SF")
507    (set_attr "length"   "1")])
508
509 (define_expand "addsi3"
510   [(set (match_operand:SI 0 "register_operand" "=d")
511         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
512                  (match_operand:SI 2 "arith_operand" "dI")))]
513   ""
514   "
515 {
516   /* The mips16 assembler handles -32768 correctly, and so does gas,
517      but some other MIPS assemblers think that -32768 needs to be
518      loaded into a register before it can be added in.  */
519   if (! TARGET_MIPS16
520       && ! TARGET_GAS
521       && GET_CODE (operands[2]) == CONST_INT
522       && INTVAL (operands[2]) == -32768)
523     operands[2] = force_reg (SImode, operands[2]);
524 }")
525
526 (define_insn "addsi3_internal"
527   [(set (match_operand:SI 0 "register_operand" "=d")
528         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
529                  (match_operand:SI 2 "arith_operand" "dI")))]
530   "! TARGET_MIPS16
531    && (TARGET_GAS
532        || GET_CODE (operands[2]) != CONST_INT
533        || INTVAL (operands[2]) != -32768)"
534   "addu\\t%0,%z1,%2"
535   [(set_attr "type"     "arith")
536    (set_attr "mode"     "SI")
537    (set_attr "length"   "1")])
538
539 ;; For the mips16, we need to recognize stack pointer additions
540 ;; explicitly, since we don't have a constraint for $sp.  These insns
541 ;; will be generated by the save_restore_insns functions.
542
543 (define_insn ""
544   [(set (reg:SI 29)
545         (plus:SI (reg:SI 29)
546                  (match_operand:SI 0 "small_int" "I")))]
547   "TARGET_MIPS16"
548   "addu\\t%$,%$,%0"
549   [(set_attr "type"     "arith")
550    (set_attr "mode"     "SI")
551    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
552                                       (const_int 1)
553                                       (const_int 2)))])
554
555 (define_insn ""
556   [(set (match_operand:SI 0 "register_operand" "=d")
557         (plus:SI (reg:SI 29)
558                  (match_operand:SI 1 "small_int" "I")))]
559   "TARGET_MIPS16"
560   "addu\\t%0,%$,%1"
561   [(set_attr "type"     "arith")
562    (set_attr "mode"     "SI")
563    (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4" "")
564                                       (const_int 1)
565                                       (const_int 2)))])
566
567 (define_insn ""
568   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
569         (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
570                  (match_operand:SI 2 "arith_operand" "IQ,O,d")))]
571   "TARGET_MIPS16
572    && (GET_CODE (operands[1]) != REG
573        || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
574        || M16_REG_P (REGNO (operands[1]))
575        || REGNO (operands[1]) == ARG_POINTER_REGNUM
576        || REGNO (operands[1]) == FRAME_POINTER_REGNUM
577        || REGNO (operands[1]) == STACK_POINTER_REGNUM)
578    && (GET_CODE (operands[2]) != REG
579        || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
580        || M16_REG_P (REGNO (operands[2]))
581        || REGNO (operands[2]) == ARG_POINTER_REGNUM
582        || REGNO (operands[2]) == FRAME_POINTER_REGNUM
583        || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
584   "*
585 {
586   if (REGNO (operands[0]) == REGNO (operands[1]))
587     return \"addu\\t%0,%2\";
588   return \"addu\\t%0,%1,%2\";
589 }"
590   [(set_attr "type"     "arith")
591    (set_attr "mode"     "SI")
592    (set_attr_alternative "length"
593                 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
594                                (const_int 1)
595                                (const_int 2))
596                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
597                                (const_int 1)
598                                (const_int 2))
599                  (const_int 1)])])
600
601
602 ;; On the mips16, we can sometimes split an add of a constant which is
603 ;; a 4 byte instruction into two adds which are both 2 byte
604 ;; instructions.  There are two cases: one where we are adding a
605 ;; constant plus a register to another register, and one where we are
606 ;; simply adding a constant to a register.
607
608 (define_split
609   [(set (match_operand:SI 0 "register_operand" "")
610         (plus:SI (match_dup 0)
611                  (match_operand:SI 1 "const_int_operand" "")))]
612   "TARGET_MIPS16 && reload_completed
613    && GET_CODE (operands[0]) == REG
614    && M16_REG_P (REGNO (operands[0]))
615    && GET_CODE (operands[1]) == CONST_INT
616    && ((INTVAL (operands[1]) > 0x7f
617         && INTVAL (operands[1]) <= 0x7f + 0x7f)
618        || (INTVAL (operands[1]) < - 0x80
619            && INTVAL (operands[1]) >= - 0x80 - 0x80))"
620   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
621    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
622   "
623 {
624   HOST_WIDE_INT val = INTVAL (operands[1]);
625
626   if (val >= 0)
627     {
628       operands[1] = GEN_INT (0x7f);
629       operands[2] = GEN_INT (val - 0x7f);
630     }
631   else
632     {
633       operands[1] = GEN_INT (- 0x80);
634       operands[2] = GEN_INT (val + 0x80);
635     }
636 }")
637
638 (define_split
639   [(set (match_operand:SI 0 "register_operand" "")
640         (plus:SI (match_operand:SI 1 "register_operand" "")
641                  (match_operand:SI 2 "const_int_operand" "")))]
642   "TARGET_MIPS16 && reload_completed
643    && GET_CODE (operands[0]) == REG
644    && M16_REG_P (REGNO (operands[0]))
645    && GET_CODE (operands[1]) == REG
646    && M16_REG_P (REGNO (operands[1]))
647    && REGNO (operands[0]) != REGNO (operands[1])
648    && GET_CODE (operands[2]) == CONST_INT
649    && ((INTVAL (operands[2]) > 0x7
650         && INTVAL (operands[2]) <= 0x7 + 0x7f)
651        || (INTVAL (operands[2]) < - 0x8
652            && INTVAL (operands[2]) >= - 0x8 - 0x80))"
653   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
654    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
655   "
656 {
657   HOST_WIDE_INT val = INTVAL (operands[2]);
658
659   if (val >= 0)
660     {
661       operands[2] = GEN_INT (0x7);
662       operands[3] = GEN_INT (val - 0x7);
663     }
664   else
665     {
666       operands[2] = GEN_INT (- 0x8);
667       operands[3] = GEN_INT (val + 0x8);
668     }
669 }")
670
671 (define_expand "adddi3"
672   [(parallel [(set (match_operand:DI 0 "register_operand" "")
673                    (plus:DI (match_operand:DI 1 "se_register_operand" "")
674                             (match_operand:DI 2 "se_arith_operand" "")))
675               (clobber (match_dup 3))])]
676   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
677   "
678 {
679   /* The mips16 assembler handles -32768 correctly, and so does gas,
680      but some other MIPS assemblers think that -32768 needs to be
681      loaded into a register before it can be added in.  */
682   if (! TARGET_MIPS16
683       && ! TARGET_GAS
684       && GET_CODE (operands[2]) == CONST_INT
685       && INTVAL (operands[2]) == -32768)
686     operands[2] = force_reg (DImode, operands[2]);
687
688   if (TARGET_64BIT)
689     {
690       emit_insn (gen_adddi3_internal_3 (operands[0], operands[1],
691                                         operands[2]));
692       DONE;
693     }
694
695   operands[3] = gen_reg_rtx (SImode);
696 }")
697
698 (define_insn "adddi3_internal_1"
699   [(set (match_operand:DI 0 "register_operand" "=d,&d")
700         (plus:DI (match_operand:DI 1 "register_operand" "0,d")
701                  (match_operand:DI 2 "register_operand" "d,d")))
702    (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
703   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
704   "*
705 {
706   return (REGNO (operands[0]) == REGNO (operands[1])
707           && REGNO (operands[0]) == REGNO (operands[2]))
708     ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\"
709     : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\";
710 }"
711   [(set_attr "type"     "darith")
712    (set_attr "mode"     "DI")
713    (set_attr "length"   "4")])
714
715 (define_split
716   [(set (match_operand:DI 0 "register_operand" "")
717         (plus:DI (match_operand:DI 1 "register_operand" "")
718                  (match_operand:DI 2 "register_operand" "")))
719    (clobber (match_operand:SI 3 "register_operand" ""))]
720   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
721    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
722    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
723    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
724    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
725    && (REGNO (operands[0]) != REGNO (operands[1])
726        || REGNO (operands[0]) != REGNO (operands[2]))"
727
728   [(set (subreg:SI (match_dup 0) 0)
729         (plus:SI (subreg:SI (match_dup 1) 0)
730                  (subreg:SI (match_dup 2) 0)))
731
732    (set (match_dup 3)
733         (ltu:SI (subreg:SI (match_dup 0) 0)
734                 (subreg:SI (match_dup 2) 0)))
735
736    (set (subreg:SI (match_dup 0) 1)
737         (plus:SI (subreg:SI (match_dup 1) 1)
738                  (subreg:SI (match_dup 2) 1)))
739
740    (set (subreg:SI (match_dup 0) 1)
741         (plus:SI (subreg:SI (match_dup 0) 1)
742                  (match_dup 3)))]
743   "")
744
745 (define_split
746   [(set (match_operand:DI 0 "register_operand" "")
747         (plus:DI (match_operand:DI 1 "register_operand" "")
748                  (match_operand:DI 2 "register_operand" "")))
749    (clobber (match_operand:SI 3 "register_operand" ""))]
750   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
751    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
752    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
753    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
754    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
755    && (REGNO (operands[0]) != REGNO (operands[1])
756        || REGNO (operands[0]) != REGNO (operands[2]))"
757
758   [(set (subreg:SI (match_dup 0) 1)
759         (plus:SI (subreg:SI (match_dup 1) 1)
760                  (subreg:SI (match_dup 2) 1)))
761
762    (set (match_dup 3)
763         (ltu:SI (subreg:SI (match_dup 0) 1)
764                 (subreg:SI (match_dup 2) 1)))
765
766    (set (subreg:SI (match_dup 0) 0)
767         (plus:SI (subreg:SI (match_dup 1) 0)
768                  (subreg:SI (match_dup 2) 0)))
769
770    (set (subreg:SI (match_dup 0) 0)
771         (plus:SI (subreg:SI (match_dup 0) 0)
772                  (match_dup 3)))]
773   "")
774
775 (define_insn "adddi3_internal_2"
776   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
777         (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d")
778                  (match_operand:DI 2 "small_int" "P,J,N")))
779    (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
780   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
781    && INTVAL (operands[2]) != -32768"
782   "@
783    addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3
784    move\\t%L0,%L1\;move\\t%M0,%M1
785    subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3"
786   [(set_attr "type"     "darith")
787    (set_attr "mode"     "DI")
788    (set_attr "length"   "3,2,4")])
789
790 (define_split
791   [(set (match_operand:DI 0 "register_operand" "")
792         (plus:DI (match_operand:DI 1 "register_operand" "")
793                  (match_operand:DI 2 "small_int" "")))
794    (clobber (match_operand:SI 3 "register_operand" "=d"))]
795   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
796    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
797    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
798    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
799    && INTVAL (operands[2]) > 0"
800
801   [(set (subreg:SI (match_dup 0) 0)
802         (plus:SI (subreg:SI (match_dup 1) 0)
803                  (match_dup 2)))
804
805    (set (match_dup 3)
806         (ltu:SI (subreg:SI (match_dup 0) 0)
807                 (match_dup 2)))
808
809    (set (subreg:SI (match_dup 0) 1)
810         (plus:SI (subreg:SI (match_dup 1) 1)
811                  (match_dup 3)))]
812   "")
813
814 (define_split
815   [(set (match_operand:DI 0 "register_operand" "")
816         (plus:DI (match_operand:DI 1 "register_operand" "")
817                  (match_operand:DI 2 "small_int" "")))
818    (clobber (match_operand:SI 3 "register_operand" "=d"))]
819   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
820    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
821    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
822    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
823    && INTVAL (operands[2]) > 0"
824
825   [(set (subreg:SI (match_dup 0) 1)
826         (plus:SI (subreg:SI (match_dup 1) 1)
827                  (match_dup 2)))
828
829    (set (match_dup 3)
830         (ltu:SI (subreg:SI (match_dup 0) 1)
831                 (match_dup 2)))
832
833    (set (subreg:SI (match_dup 0) 0)
834         (plus:SI (subreg:SI (match_dup 1) 0)
835                  (match_dup 3)))]
836   "")
837
838 (define_insn "adddi3_internal_3"
839   [(set (match_operand:DI 0 "register_operand" "=d")
840         (plus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
841                  (match_operand:DI 2 "se_arith_operand" "dI")))]
842   "TARGET_64BIT
843    && !TARGET_MIPS16
844    && (TARGET_GAS
845        || GET_CODE (operands[2]) != CONST_INT
846        || INTVAL (operands[2]) != -32768)"
847   "*
848 {
849   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
850     ? \"dsubu\\t%0,%z1,%n2\"
851     : \"daddu\\t%0,%z1,%2\";
852 }"
853   [(set_attr "type"     "darith")
854    (set_attr "mode"     "DI")
855    (set_attr "length"   "1")])
856
857 ;; For the mips16, we need to recognize stack pointer additions
858 ;; explicitly, since we don't have a constraint for $sp.  These insns
859 ;; will be generated by the save_restore_insns functions.
860
861 (define_insn ""
862   [(set (reg:DI 29)
863         (plus:DI (reg:DI 29)
864                  (match_operand:DI 0 "small_int" "I")))]
865   "TARGET_MIPS16 && TARGET_64BIT"
866   "daddu\\t%$,%$,%0"
867   [(set_attr "type"     "arith")
868    (set_attr "mode"     "DI")
869    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
870                                       (const_int 1)
871                                       (const_int 2)))])
872
873 (define_insn ""
874   [(set (match_operand:DI 0 "register_operand" "=d")
875         (plus:DI (reg:DI 29)
876                  (match_operand:DI 1 "small_int" "I")))]
877   "TARGET_MIPS16 && TARGET_64BIT"
878   "daddu\\t%0,%$,%1"
879   [(set_attr "type"     "arith")
880    (set_attr "mode"     "DI")
881    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4" "")
882                                       (const_int 1)
883                                       (const_int 2)))])
884
885 (define_insn ""
886   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
887         (plus:DI (match_operand:DI 1 "register_operand" "0,d,d")
888                  (match_operand:DI 2 "arith_operand" "IQ,O,d")))]
889   "TARGET_MIPS16 && TARGET_64BIT
890    && (GET_CODE (operands[1]) != REG
891        || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
892        || M16_REG_P (REGNO (operands[1]))
893        || REGNO (operands[1]) == ARG_POINTER_REGNUM
894        || REGNO (operands[1]) == FRAME_POINTER_REGNUM
895        || REGNO (operands[1]) == STACK_POINTER_REGNUM)
896    && (GET_CODE (operands[2]) != REG
897        || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
898        || M16_REG_P (REGNO (operands[2]))
899        || REGNO (operands[2]) == ARG_POINTER_REGNUM
900        || REGNO (operands[2]) == FRAME_POINTER_REGNUM
901        || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
902   "*
903 {
904   if (REGNO (operands[0]) == REGNO (operands[1]))
905     return \"daddu\\t%0,%2\";
906   return \"daddu\\t%0,%1,%2\";
907 }"
908   [(set_attr "type"     "arith")
909    (set_attr "mode"     "DI")
910    (set_attr_alternative "length"
911                 [(if_then_else (match_operand:VOID 2 "m16_simm5_1" "")
912                                (const_int 1)
913                                (const_int 2))
914                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
915                                (const_int 1)
916                                (const_int 2))
917                  (const_int 1)])])
918
919
920 ;; On the mips16, we can sometimes split an add of a constant which is
921 ;; a 4 byte instruction into two adds which are both 2 byte
922 ;; instructions.  There are two cases: one where we are adding a
923 ;; constant plus a register to another register, and one where we are
924 ;; simply adding a constant to a register.
925
926 (define_split
927   [(set (match_operand:DI 0 "register_operand" "")
928         (plus:DI (match_dup 0)
929                  (match_operand:DI 1 "const_int_operand" "")))]
930   "TARGET_MIPS16 && TARGET_64BIT && reload_completed
931    && GET_CODE (operands[0]) == REG
932    && M16_REG_P (REGNO (operands[0]))
933    && GET_CODE (operands[1]) == CONST_INT
934    && ((INTVAL (operands[1]) > 0xf
935         && INTVAL (operands[1]) <= 0xf + 0xf)
936        || (INTVAL (operands[1]) < - 0x10
937            && INTVAL (operands[1]) >= - 0x10 - 0x10))"
938   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
939    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
940   "
941 {
942   HOST_WIDE_INT val = INTVAL (operands[1]);
943
944   if (val >= 0)
945     {
946       operands[1] = GEN_INT (0xf);
947       operands[2] = GEN_INT (val - 0xf);
948     }
949   else
950     {
951       operands[1] = GEN_INT (- 0x10);
952       operands[2] = GEN_INT (val + 0x10);
953     }
954 }")
955
956 (define_split
957   [(set (match_operand:DI 0 "register_operand" "")
958         (plus:DI (match_operand:DI 1 "register_operand" "")
959                  (match_operand:DI 2 "const_int_operand" "")))]
960   "TARGET_MIPS16 && TARGET_64BIT && reload_completed
961    && GET_CODE (operands[0]) == REG
962    && M16_REG_P (REGNO (operands[0]))
963    && GET_CODE (operands[1]) == REG
964    && M16_REG_P (REGNO (operands[1]))
965    && REGNO (operands[0]) != REGNO (operands[1])
966    && GET_CODE (operands[2]) == CONST_INT
967    && ((INTVAL (operands[2]) > 0x7
968         && INTVAL (operands[2]) <= 0x7 + 0xf)
969        || (INTVAL (operands[2]) < - 0x8
970            && INTVAL (operands[2]) >= - 0x8 - 0x10))"
971   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
972    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
973   "
974 {
975   HOST_WIDE_INT val = INTVAL (operands[2]);
976
977   if (val >= 0)
978     {
979       operands[2] = GEN_INT (0x7);
980       operands[3] = GEN_INT (val - 0x7);
981     }
982   else
983     {
984       operands[2] = GEN_INT (- 0x8);
985       operands[3] = GEN_INT (val + 0x8);
986     }
987 }")
988
989 (define_insn "addsi3_internal_2"
990   [(set (match_operand:DI 0 "register_operand" "=d")
991         (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
992                                  (match_operand:SI 2 "arith_operand" "dI"))))]
993   "TARGET_64BIT
994    && !TARGET_MIPS16
995    && (TARGET_GAS
996        || GET_CODE (operands[2]) != CONST_INT
997        || INTVAL (operands[2]) != -32768)"
998   "*
999 {
1000   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1001     ? \"subu\\t%0,%z1,%n2\"
1002     : \"addu\\t%0,%z1,%2\";
1003 }"
1004   [(set_attr "type"     "arith")
1005    (set_attr "mode"     "SI")
1006    (set_attr "length"   "1")])
1007
1008 (define_insn ""
1009   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1010         (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1011                                  (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1012   "TARGET_MIPS16 && TARGET_64BIT"
1013   "*
1014 {
1015   if (REGNO (operands[0]) == REGNO (operands[1]))
1016     return \"addu\\t%0,%2\";
1017   return \"addu\\t%0,%1,%2\";
1018 }"
1019   [(set_attr "type"     "arith")
1020    (set_attr "mode"     "SI")
1021    (set_attr_alternative "length"
1022                 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
1023                                (const_int 1)
1024                                (const_int 2))
1025                  (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
1026                                (const_int 1)
1027                                (const_int 2))
1028                  (const_int 1)])])
1029
1030 \f
1031 ;;
1032 ;;  ....................
1033 ;;
1034 ;;      SUBTRACTION
1035 ;;
1036 ;;  ....................
1037 ;;
1038
1039 (define_insn "subdf3"
1040   [(set (match_operand:DF 0 "register_operand" "=f")
1041         (minus:DF (match_operand:DF 1 "register_operand" "f")
1042                   (match_operand:DF 2 "register_operand" "f")))]
1043   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1044   "sub.d\\t%0,%1,%2"
1045   [(set_attr "type"     "fadd")
1046    (set_attr "mode"     "DF")
1047    (set_attr "length"   "1")])
1048
1049 (define_insn "subsf3"
1050   [(set (match_operand:SF 0 "register_operand" "=f")
1051         (minus:SF (match_operand:SF 1 "register_operand" "f")
1052                   (match_operand:SF 2 "register_operand" "f")))]
1053   "TARGET_HARD_FLOAT"
1054   "sub.s\\t%0,%1,%2"
1055   [(set_attr "type"     "fadd")
1056    (set_attr "mode"     "SF")
1057    (set_attr "length"   "1")])
1058
1059 (define_expand "subsi3"
1060   [(set (match_operand:SI 0 "register_operand" "=d")
1061         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1062                   (match_operand:SI 2 "arith_operand" "dI")))]
1063   ""
1064   "
1065 {
1066   if (GET_CODE (operands[2]) == CONST_INT
1067       && (INTVAL (operands[2]) == -32768
1068           || (TARGET_MIPS16
1069               && INTVAL (operands[2]) == -0x4000)))
1070     operands[2] = force_reg (SImode, operands[2]);
1071 }")
1072
1073 (define_insn "subsi3_internal"
1074   [(set (match_operand:SI 0 "register_operand" "=d")
1075         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1076                   (match_operand:SI 2 "arith_operand" "dI")))]
1077   "!TARGET_MIPS16
1078    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1079   "subu\\t%0,%z1,%2"
1080   [(set_attr "type"     "arith")
1081    (set_attr "mode"     "SI")
1082    (set_attr "length"   "1")])
1083
1084 ;; For the mips16, we need to recognize stack pointer subtractions
1085 ;; explicitly, since we don't have a constraint for $sp.  These insns
1086 ;; will be generated by the save_restore_insns functions.
1087
1088 (define_insn ""
1089   [(set (reg:SI 29)
1090         (minus:SI (reg:SI 29)
1091                   (match_operand:SI 0 "small_int" "I")))]
1092   "TARGET_MIPS16
1093    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1094   "addu\\t%$,%$,%n0"
1095   [(set_attr "type"     "arith")
1096    (set_attr "mode"     "SI")
1097    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1098                                       (const_int 1)
1099                                       (const_int 2)))])
1100
1101 (define_insn ""
1102   [(set (match_operand:SI 0 "register_operand" "=d")
1103         (minus:SI (reg:SI 29)
1104                   (match_operand:SI 1 "small_int" "I")))]
1105   "TARGET_MIPS16
1106    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1107   "addu\\t%0,%$,%n1"
1108   [(set_attr "type"     "arith")
1109    (set_attr "mode"     "SI")
1110    (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_nuimm8_4" "")
1111                                       (const_int 1)
1112                                       (const_int 2)))])
1113
1114
1115 (define_insn ""
1116   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
1117         (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1118                   (match_operand:SI 2 "arith_operand" "I,O,d")))]
1119   "TARGET_MIPS16
1120    && (GET_CODE (operands[2]) != CONST_INT
1121        || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1122   "*
1123 {
1124   if (REGNO (operands[0]) == REGNO (operands[1]))
1125     return \"subu\\t%0,%2\";
1126   return \"subu\\t%0,%1,%2\";
1127 }"
1128   [(set_attr "type"     "arith")
1129    (set_attr "mode"     "SI")
1130    (set_attr_alternative "length"
1131                 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1132                                (const_int 1)
1133                                (const_int 2))
1134                  (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1135                                (const_int 1)
1136                                (const_int 2))
1137                  (const_int 1)])])
1138
1139 ;; On the mips16, we can sometimes split an subtract of a constant
1140 ;; which is a 4 byte instruction into two adds which are both 2 byte
1141 ;; instructions.  There are two cases: one where we are setting a
1142 ;; register to a register minus a constant, and one where we are
1143 ;; simply subtracting a constant from a register.
1144
1145 (define_split
1146   [(set (match_operand:SI 0 "register_operand" "")
1147         (minus:SI (match_dup 0)
1148                   (match_operand:SI 1 "const_int_operand" "")))]
1149   "TARGET_MIPS16 && reload_completed
1150    && GET_CODE (operands[0]) == REG
1151    && M16_REG_P (REGNO (operands[0]))
1152    && GET_CODE (operands[1]) == CONST_INT
1153    && ((INTVAL (operands[1]) > 0x80
1154         && INTVAL (operands[1]) <= 0x80 + 0x80)
1155        || (INTVAL (operands[1]) < - 0x7f
1156            && INTVAL (operands[1]) >= - 0x7f - 0x7f))"
1157   [(set (match_dup 0) (minus:SI (match_dup 0) (match_dup 1)))
1158    (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))]
1159   "
1160 {
1161   HOST_WIDE_INT val = INTVAL (operands[1]);
1162
1163   if (val >= 0)
1164     {
1165       operands[1] = GEN_INT (0x80);
1166       operands[2] = GEN_INT (val - 0x80);
1167     }
1168   else
1169     {
1170       operands[1] = GEN_INT (- 0x7f);
1171       operands[2] = GEN_INT (val + 0x7f);
1172     }
1173 }")
1174
1175 (define_split
1176   [(set (match_operand:SI 0 "register_operand" "")
1177         (minus:SI (match_operand:SI 1 "register_operand" "")
1178                   (match_operand:SI 2 "const_int_operand" "")))]
1179   "TARGET_MIPS16 && reload_completed
1180    && GET_CODE (operands[0]) == REG
1181    && M16_REG_P (REGNO (operands[0]))
1182    && GET_CODE (operands[1]) == REG
1183    && M16_REG_P (REGNO (operands[1]))
1184    && REGNO (operands[0]) != REGNO (operands[1])
1185    && GET_CODE (operands[2]) == CONST_INT
1186    && ((INTVAL (operands[2]) > 0x8
1187         && INTVAL (operands[2]) <= 0x8 + 0x80)
1188        || (INTVAL (operands[2]) < - 0x7
1189            && INTVAL (operands[2]) >= - 0x7 - 0x7f))"
1190   [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
1191    (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 3)))]
1192   "
1193 {
1194   HOST_WIDE_INT val = INTVAL (operands[2]);
1195
1196   if (val >= 0)
1197     {
1198       operands[2] = GEN_INT (0x8);
1199       operands[3] = GEN_INT (val - 0x8);
1200     }
1201   else
1202     {
1203       operands[2] = GEN_INT (- 0x7);
1204       operands[3] = GEN_INT (val + 0x7);
1205     }
1206 }")
1207
1208 (define_expand "subdi3"
1209   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
1210                    (minus:DI (match_operand:DI 1 "se_register_operand" "d")
1211                              (match_operand:DI 2 "se_register_operand" "d")))
1212               (clobber (match_dup 3))])]
1213   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
1214   "
1215 {
1216   if (TARGET_64BIT)
1217     {
1218       emit_insn (gen_subdi3_internal_3 (operands[0], operands[1],
1219                                         operands[2]));
1220       DONE;
1221     }
1222
1223   operands[3] = gen_reg_rtx (SImode);
1224 }")
1225
1226 (define_insn "subdi3_internal"
1227   [(set (match_operand:DI 0 "register_operand" "=d")
1228         (minus:DI (match_operand:DI 1 "register_operand" "d")
1229                   (match_operand:DI 2 "register_operand" "d")))
1230    (clobber (match_operand:SI 3 "register_operand" "=d"))]
1231   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
1232   "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3"
1233   [(set_attr "type"     "darith")
1234    (set_attr "mode"     "DI")
1235    (set_attr "length"   "4")])
1236
1237 (define_split
1238   [(set (match_operand:DI 0 "register_operand" "")
1239         (minus:DI (match_operand:DI 1 "register_operand" "")
1240                   (match_operand:DI 2 "register_operand" "")))
1241    (clobber (match_operand:SI 3 "register_operand" ""))]
1242   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1243    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1244    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1245    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1246    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1247
1248   [(set (match_dup 3)
1249         (ltu:SI (subreg:SI (match_dup 1) 0)
1250                 (subreg:SI (match_dup 2) 0)))
1251
1252    (set (subreg:SI (match_dup 0) 0)
1253         (minus:SI (subreg:SI (match_dup 1) 0)
1254                   (subreg:SI (match_dup 2) 0)))
1255
1256    (set (subreg:SI (match_dup 0) 1)
1257         (minus:SI (subreg:SI (match_dup 1) 1)
1258                   (subreg:SI (match_dup 2) 1)))
1259
1260    (set (subreg:SI (match_dup 0) 1)
1261         (minus:SI (subreg:SI (match_dup 0) 1)
1262                   (match_dup 3)))]
1263   "")
1264
1265 (define_split
1266   [(set (match_operand:DI 0 "register_operand" "")
1267         (minus:DI (match_operand:DI 1 "register_operand" "")
1268                   (match_operand:DI 2 "register_operand" "")))
1269    (clobber (match_operand:SI 3 "register_operand" ""))]
1270   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1271    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1272    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1273    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1274    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1275
1276   [(set (match_dup 3)
1277         (ltu:SI (subreg:SI (match_dup 1) 1)
1278                 (subreg:SI (match_dup 2) 1)))
1279
1280    (set (subreg:SI (match_dup 0) 1)
1281         (minus:SI (subreg:SI (match_dup 1) 1)
1282                   (subreg:SI (match_dup 2) 1)))
1283
1284    (set (subreg:SI (match_dup 0) 0)
1285         (minus:SI (subreg:SI (match_dup 1) 0)
1286                   (subreg:SI (match_dup 2) 0)))
1287
1288    (set (subreg:SI (match_dup 0) 0)
1289         (minus:SI (subreg:SI (match_dup 0) 0)
1290                   (match_dup 3)))]
1291   "")
1292
1293 (define_insn "subdi3_internal_2"
1294   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1295         (minus:DI (match_operand:DI 1 "register_operand" "d,d,d")
1296                   (match_operand:DI 2 "small_int" "P,J,N")))
1297    (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
1298   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1299    && INTVAL (operands[2]) != -32768"
1300   "@
1301    sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3
1302    move\\t%L0,%L1\;move\\t%M0,%M1
1303    sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3"
1304   [(set_attr "type"     "darith")
1305    (set_attr "mode"     "DI")
1306    (set_attr "length"   "3,2,4")])
1307
1308 (define_split
1309   [(set (match_operand:DI 0 "register_operand" "")
1310         (minus:DI (match_operand:DI 1 "register_operand" "")
1311                   (match_operand:DI 2 "small_int" "")))
1312    (clobber (match_operand:SI 3 "register_operand" ""))]
1313   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1314    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1315    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1316    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1317    && INTVAL (operands[2]) > 0"
1318
1319   [(set (match_dup 3)
1320         (ltu:SI (subreg:SI (match_dup 1) 0)
1321                 (match_dup 2)))
1322
1323    (set (subreg:SI (match_dup 0) 0)
1324         (minus:SI (subreg:SI (match_dup 1) 0)
1325                   (match_dup 2)))
1326
1327    (set (subreg:SI (match_dup 0) 1)
1328         (minus:SI (subreg:SI (match_dup 1) 1)
1329                   (match_dup 3)))]
1330   "")
1331
1332 (define_split
1333   [(set (match_operand:DI 0 "register_operand" "")
1334         (minus:DI (match_operand:DI 1 "register_operand" "")
1335                   (match_operand:DI 2 "small_int" "")))
1336    (clobber (match_operand:SI 3 "register_operand" ""))]
1337   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1338    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1339    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1340    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1341    && INTVAL (operands[2]) > 0"
1342
1343   [(set (match_dup 3)
1344         (ltu:SI (subreg:SI (match_dup 1) 1)
1345                 (match_dup 2)))
1346
1347    (set (subreg:SI (match_dup 0) 1)
1348         (minus:SI (subreg:SI (match_dup 1) 1)
1349                   (match_dup 2)))
1350
1351    (set (subreg:SI (match_dup 0) 0)
1352         (minus:SI (subreg:SI (match_dup 1) 0)
1353                   (match_dup 3)))]
1354   "")
1355
1356 (define_insn "subdi3_internal_3"
1357   [(set (match_operand:DI 0 "register_operand" "=d")
1358         (minus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
1359                   (match_operand:DI 2 "se_arith_operand" "dI")))]
1360   "TARGET_64BIT && !TARGET_MIPS16
1361    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1362   "*
1363 {
1364   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1365     ? \"daddu\\t%0,%z1,%n2\"
1366     : \"dsubu\\t%0,%z1,%2\";
1367 }"
1368   [(set_attr "type"     "darith")
1369    (set_attr "mode"     "DI")
1370    (set_attr "length"   "1")])
1371
1372 ;; For the mips16, we need to recognize stack pointer subtractions
1373 ;; explicitly, since we don't have a constraint for $sp.  These insns
1374 ;; will be generated by the save_restore_insns functions.
1375
1376 (define_insn ""
1377   [(set (reg:DI 29)
1378         (minus:DI (reg:DI 29)
1379                   (match_operand:DI 0 "small_int" "I")))]
1380   "TARGET_MIPS16
1381    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1382   "daddu\\t%$,%$,%n0"
1383   [(set_attr "type"     "arith")
1384    (set_attr "mode"     "DI")
1385    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "")
1386                                       (const_int 1)
1387                                       (const_int 2)))])
1388
1389 (define_insn ""
1390   [(set (match_operand:DI 0 "register_operand" "=d")
1391         (minus:DI (reg:DI 29)
1392                   (match_operand:DI 1 "small_int" "I")))]
1393   "TARGET_MIPS16
1394    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1395   "daddu\\t%0,%$,%n1"
1396   [(set_attr "type"     "arith")
1397    (set_attr "mode"     "DI")
1398    (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nuimm5_4" "")
1399                                       (const_int 1)
1400                                       (const_int 2)))])
1401
1402 (define_insn ""
1403   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1404         (minus:DI (match_operand:DI 1 "register_operand" "0,d,d")
1405                   (match_operand:DI 2 "arith_operand" "I,O,d")))]
1406   "TARGET_MIPS16
1407    && (GET_CODE (operands[2]) != CONST_INT
1408        || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1409   "*
1410 {
1411   if (REGNO (operands[0]) == REGNO (operands[1]))
1412     return \"dsubu\\t%0,%2\";
1413   return \"dsubu\\t%0,%1,%2\";
1414 }"
1415   [(set_attr "type"     "arith")
1416    (set_attr "mode"     "DI")
1417    (set_attr_alternative "length"
1418                 [(if_then_else (match_operand:VOID 2 "m16_nsimm5_1" "")
1419                                (const_int 1)
1420                                (const_int 2))
1421                  (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1422                                (const_int 1)
1423                                (const_int 2))
1424                  (const_int 1)])])
1425
1426 ;; On the mips16, we can sometimes split an add of a constant which is
1427 ;; a 4 byte instruction into two adds which are both 2 byte
1428 ;; instructions.  There are two cases: one where we are adding a
1429 ;; constant plus a register to another register, and one where we are
1430 ;; simply adding a constant to a register.
1431
1432 (define_split
1433   [(set (match_operand:DI 0 "register_operand" "")
1434         (minus:DI (match_dup 0)
1435                   (match_operand:DI 1 "const_int_operand" "")))]
1436   "TARGET_MIPS16 && TARGET_64BIT && reload_completed
1437    && GET_CODE (operands[0]) == REG
1438    && M16_REG_P (REGNO (operands[0]))
1439    && GET_CODE (operands[1]) == CONST_INT
1440    && ((INTVAL (operands[1]) > 0x10
1441         && INTVAL (operands[1]) <= 0x10 + 0x10)
1442        || (INTVAL (operands[1]) < - 0xf
1443            && INTVAL (operands[1]) >= - 0xf - 0xf))"
1444   [(set (match_dup 0) (minus:DI (match_dup 0) (match_dup 1)))
1445    (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))]
1446   "
1447 {
1448   HOST_WIDE_INT val = INTVAL (operands[1]);
1449
1450   if (val >= 0)
1451     {
1452       operands[1] = GEN_INT (0xf);
1453       operands[2] = GEN_INT (val - 0xf);
1454     }
1455   else
1456     {
1457       operands[1] = GEN_INT (- 0x10);
1458       operands[2] = GEN_INT (val + 0x10);
1459     }
1460 }")
1461
1462 (define_split
1463   [(set (match_operand:DI 0 "register_operand" "")
1464         (minus:DI (match_operand:DI 1 "register_operand" "")
1465                   (match_operand:DI 2 "const_int_operand" "")))]
1466   "TARGET_MIPS16 && TARGET_64BIT && reload_completed
1467    && GET_CODE (operands[0]) == REG
1468    && M16_REG_P (REGNO (operands[0]))
1469    && GET_CODE (operands[1]) == REG
1470    && M16_REG_P (REGNO (operands[1]))
1471    && REGNO (operands[0]) != REGNO (operands[1])
1472    && GET_CODE (operands[2]) == CONST_INT
1473    && ((INTVAL (operands[2]) > 0x8
1474         && INTVAL (operands[2]) <= 0x8 + 0x10)
1475        || (INTVAL (operands[2]) < - 0x7
1476            && INTVAL (operands[2]) >= - 0x7 - 0xf))"
1477   [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))
1478    (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 3)))]
1479   "
1480 {
1481   HOST_WIDE_INT val = INTVAL (operands[2]);
1482
1483   if (val >= 0)
1484     {
1485       operands[2] = GEN_INT (0x8);
1486       operands[3] = GEN_INT (val - 0x8);
1487     }
1488   else
1489     {
1490       operands[2] = GEN_INT (- 0x7);
1491       operands[3] = GEN_INT (val + 0x7);
1492     }
1493 }")
1494
1495 (define_insn "subsi3_internal_2"
1496   [(set (match_operand:DI 0 "register_operand" "=d")
1497         (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1498                                   (match_operand:SI 2 "arith_operand" "dI"))))]
1499   "TARGET_64BIT && !TARGET_MIPS16
1500    && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
1501   "*
1502 {
1503   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
1504     ? \"addu\\t%0,%z1,%n2\"
1505     : \"subu\\t%0,%z1,%2\";
1506 }"
1507   [(set_attr "type"     "arith")
1508    (set_attr "mode"     "DI")
1509    (set_attr "length"   "1")])
1510
1511 (define_insn ""
1512   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1513         (sign_extend:DI (minus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1514                                   (match_operand:SI 2 "arith_operand" "I,O,d"))))]
1515   "TARGET_64BIT && TARGET_MIPS16
1516    && (GET_CODE (operands[2]) != CONST_INT
1517        || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))"
1518   "*
1519 {
1520   if (REGNO (operands[0]) == REGNO (operands[1]))
1521     return \"subu\\t%0,%2\";
1522   return \"subu\\t%0,%1,%2\";
1523 }"
1524   [(set_attr "type"     "arith")
1525    (set_attr "mode"     "SI")
1526    (set_attr_alternative "length"
1527                 [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "")
1528                                (const_int 1)
1529                                (const_int 2))
1530                  (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "")
1531                                (const_int 1)
1532                                (const_int 2))
1533                  (const_int 1)])])
1534   
1535
1536 \f
1537 ;;
1538 ;;  ....................
1539 ;;
1540 ;;      MULTIPLICATION
1541 ;;
1542 ;;  ....................
1543 ;;
1544
1545 ;; Early Vr4300 silicon has a CPU bug where multiplies with certain
1546 ;; operands may corrupt immediately following multiplies. This is a
1547 ;; simple fix to insert NOPs.
1548
1549 (define_expand "muldf3"
1550   [(set (match_operand:DF 0 "register_operand" "=f")
1551         (mult:DF (match_operand:DF 1 "register_operand" "f")
1552                  (match_operand:DF 2 "register_operand" "f")))]
1553   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1554   "
1555 {
1556   if (mips_cpu != PROCESSOR_R4300)
1557     emit_insn (gen_muldf3_internal (operands[0], operands[1], operands[2]));
1558   else
1559     emit_insn (gen_muldf3_r4300 (operands[0], operands[1], operands[2]));
1560   DONE;
1561 }")
1562
1563 (define_insn "muldf3_internal"
1564   [(set (match_operand:DF 0 "register_operand" "=f")
1565         (mult:DF (match_operand:DF 1 "register_operand" "f")
1566                  (match_operand:DF 2 "register_operand" "f")))]
1567   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && mips_cpu != PROCESSOR_R4300"
1568   "mul.d\\t%0,%1,%2"
1569   [(set_attr "type"     "fmul")
1570    (set_attr "mode"     "DF")
1571    (set_attr "length"   "1")])
1572
1573 (define_insn "muldf3_r4300"
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   "*
1579 {
1580   output_asm_insn (\"mul.d\\t%0,%1,%2\", operands);
1581   if (TARGET_4300_MUL_FIX)
1582     output_asm_insn (\"nop\", operands);
1583   return \"\";
1584 }"
1585   [(set_attr "type"     "fmul")
1586    (set_attr "mode"     "DF")
1587    (set_attr "length"   "2")])  ;; mul.d + nop
1588
1589 (define_expand "mulsf3"
1590   [(set (match_operand:SF 0 "register_operand" "=f")
1591         (mult:SF (match_operand:SF 1 "register_operand" "f")
1592                  (match_operand:SF 2 "register_operand" "f")))]
1593   "TARGET_HARD_FLOAT"
1594   "
1595 {
1596   if (mips_cpu != PROCESSOR_R4300)
1597     emit_insn( gen_mulsf3_internal (operands[0], operands[1], operands[2]));
1598   else
1599     emit_insn( gen_mulsf3_r4300 (operands[0], operands[1], operands[2]));
1600   DONE;
1601 }")
1602
1603 (define_insn "mulsf3_internal"
1604   [(set (match_operand:SF 0 "register_operand" "=f")
1605         (mult:SF (match_operand:SF 1 "register_operand" "f")
1606                  (match_operand:SF 2 "register_operand" "f")))]
1607   "TARGET_HARD_FLOAT && mips_cpu != PROCESSOR_R4300"
1608   "mul.s\\t%0,%1,%2"
1609   [(set_attr "type"     "fmul")
1610    (set_attr "mode"     "SF")
1611    (set_attr "length"   "1")])
1612
1613 (define_insn "mulsf3_r4300"
1614   [(set (match_operand:SF 0 "register_operand" "=f")
1615         (mult:SF (match_operand:SF 1 "register_operand" "f")
1616                  (match_operand:SF 2 "register_operand" "f")))]
1617   "TARGET_HARD_FLOAT && mips_cpu == PROCESSOR_R4300"
1618   "*
1619 {
1620   output_asm_insn (\"mul.s\\t%0,%1,%2\", operands);
1621   if (TARGET_4300_MUL_FIX)
1622     output_asm_insn (\"nop\", operands);
1623   return \"\";
1624 }"
1625   [(set_attr "type"     "fmul")
1626    (set_attr "mode"     "SF")
1627    (set_attr "length"   "2")])  ;; mul.s + nop
1628
1629 ;; ??? The R4000 (only) has a cpu bug.  If a double-word shift executes while
1630 ;; a multiply is in progress, it may give an incorrect result.  Avoid
1631 ;; this by keeping the mflo with the mult on the R4000.
1632
1633 (define_expand "mulsi3"
1634   [(set (match_operand:SI 0 "register_operand" "=l")
1635         (mult:SI (match_operand:SI 1 "register_operand" "d")
1636                  (match_operand:SI 2 "register_operand" "d")))
1637    (clobber (match_scratch:SI 3 "=h"))
1638    (clobber (match_scratch:SI 4 "=a"))]
1639   ""
1640   "
1641 {
1642   if (GENERATE_MULT3)
1643     emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1644   else if (TARGET_MAD)
1645     emit_insn (gen_mulsi3_r4650 (operands[0], operands[1], operands[2]));
1646   else if (mips_cpu != PROCESSOR_R4000 || TARGET_MIPS16)
1647     emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1648   else
1649     emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1650   DONE;
1651 }")
1652
1653 (define_insn "mulsi3_mult3"
1654   [(set (match_operand:SI 0 "register_operand" "=d")
1655         (mult:SI (match_operand:SI 1 "register_operand" "d")
1656                  (match_operand:SI 2 "register_operand" "d")))
1657    (clobber (match_scratch:SI 3 "=h"))
1658    (clobber (match_scratch:SI 4 "=l"))
1659    (clobber (match_scratch:SI 5 "=a"))]
1660   "GENERATE_MULT3"
1661   "mult\\t%0,%1,%2"
1662   [(set_attr "type"     "imul")
1663    (set_attr "mode"     "SI")
1664    (set_attr "length"   "1")])
1665
1666 (define_insn "mulsi3_internal"
1667   [(set (match_operand:SI 0 "register_operand" "=l")
1668         (mult:SI (match_operand:SI 1 "register_operand" "d")
1669                  (match_operand:SI 2 "register_operand" "d")))
1670    (clobber (match_scratch:SI 3 "=h"))
1671    (clobber (match_scratch:SI 4 "=a"))]
1672   "mips_cpu != PROCESSOR_R4000 || TARGET_MIPS16"
1673   "mult\\t%1,%2"
1674   [(set_attr "type"     "imul")
1675    (set_attr "mode"     "SI")
1676    (set_attr "length"   "1")])
1677
1678 (define_insn "mulsi3_r4000"
1679   [(set (match_operand:SI 0 "register_operand" "=d")
1680         (mult:SI (match_operand:SI 1 "register_operand" "d")
1681                  (match_operand:SI 2 "register_operand" "d")))
1682    (clobber (match_scratch:SI 3 "=h"))
1683    (clobber (match_scratch:SI 4 "=l"))
1684    (clobber (match_scratch:SI 5 "=a"))]
1685   "mips_cpu == PROCESSOR_R4000 && !TARGET_MIPS16"
1686   "*
1687 {
1688   rtx xoperands[10];
1689
1690   xoperands[0] = operands[0];
1691   xoperands[1] = gen_rtx (REG, SImode, LO_REGNUM);
1692
1693   output_asm_insn (\"mult\\t%1,%2\", operands);
1694   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1695   return \"\";
1696 }"
1697   [(set_attr "type"     "imul")
1698    (set_attr "mode"     "SI")
1699    (set_attr "length"   "3")])          ;; mult + mflo + delay
1700
1701 (define_insn "mulsi3_r4650"
1702   [(set (match_operand:SI 0 "register_operand" "=d")
1703         (mult:SI (match_operand:SI 1 "register_operand" "d")
1704                  (match_operand:SI 2 "register_operand" "d")))
1705    (clobber (match_scratch:SI 3 "=h"))
1706    (clobber (match_scratch:SI 4 "=l"))
1707    (clobber (match_scratch:SI 5 "=a"))]
1708   "TARGET_MAD"
1709   "mul\\t%0,%1,%2"
1710   [(set_attr "type"     "imul")
1711    (set_attr "mode"     "SI")
1712    (set_attr "length"   "1")])
1713
1714 (define_expand "muldi3"
1715   [(set (match_operand:DI 0 "register_operand" "=l")
1716         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1717                  (match_operand:DI 2 "register_operand" "d")))
1718    (clobber (match_scratch:DI 3 "=h"))
1719    (clobber (match_scratch:DI 4 "=a"))]
1720   "TARGET_64BIT"
1721   "
1722 {
1723   if (GENERATE_MULT3 || mips_cpu == PROCESSOR_R4000 || TARGET_MIPS16)
1724     emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2]));
1725   else
1726     emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1727   DONE;
1728 }")
1729
1730 ;; Don't accept both operands using se_register_operand, because if
1731 ;; both operands are sign extended we would prefer to use mult in the
1732 ;; mulsidi3 pattern.  Commutativity should permit either operand to be
1733 ;; sign extended.
1734
1735 (define_insn "muldi3_internal"
1736   [(set (match_operand:DI 0 "register_operand" "=l")
1737         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1738                  (match_operand:DI 2 "register_operand" "d")))
1739    (clobber (match_scratch:DI 3 "=h"))
1740    (clobber (match_scratch:DI 4 "=a"))]
1741   "TARGET_64BIT && mips_cpu != PROCESSOR_R4000 && !TARGET_MIPS16"
1742   "dmult\\t%1,%2"
1743   [(set_attr "type"     "imul")
1744    (set_attr "mode"     "DI")
1745    (set_attr "length"   "1")])
1746
1747 (define_insn "muldi3_internal2"
1748   [(set (match_operand:DI 0 "register_operand" "=d")
1749         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1750                  (match_operand:DI 2 "register_operand" "d")))
1751    (clobber (match_scratch:DI 3 "=h"))
1752    (clobber (match_scratch:DI 4 "=l"))
1753    (clobber (match_scratch:DI 5 "=a"))]
1754   "TARGET_64BIT && (GENERATE_MULT3 || mips_cpu == PROCESSOR_R4000 || TARGET_MIPS16)"
1755   "*
1756 {
1757   if (GENERATE_MULT3)
1758     output_asm_insn (\"dmult\\t%0,%1,%2\", operands);
1759   else 
1760     {
1761     rtx xoperands[10];
1762
1763     xoperands[0] = operands[0];
1764     xoperands[1] = gen_rtx (REG, DImode, LO_REGNUM);
1765
1766     output_asm_insn (\"dmult\\t%1,%2\", operands);
1767     output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1768     }
1769   return \"\";
1770 }"
1771   [(set_attr "type"     "imul")
1772    (set_attr "mode"     "DI")
1773    (set (attr "length")
1774         (if_then_else (ne (symbol_ref "GENERATE_MULT3") (const_int 0))
1775                        (const_int 1)
1776                        (const_int 3)))])        ;; mult + mflo + delay
1777
1778 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1779
1780 (define_expand "mulsidi3"
1781   [(set (match_operand:DI 0 "register_operand" "=x")
1782         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1783                  (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1784   ""
1785   "
1786 {
1787   if (TARGET_64BIT)
1788     emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2]));
1789   else
1790     emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2]));
1791   DONE;
1792 }")
1793
1794 (define_insn "mulsidi3_internal"
1795   [(set (match_operand:DI 0 "register_operand" "=x")
1796         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1797                  (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1798    (clobber (match_scratch:SI 3 "=a"))]
1799   "!TARGET_64BIT"
1800   "mult\\t%1,%2"
1801   [(set_attr "type"     "imul")
1802    (set_attr "mode"     "SI")
1803    (set_attr "length"   "1")])
1804
1805 (define_insn "mulsidi3_64bit"
1806   [(set (match_operand:DI 0 "register_operand" "=a")
1807         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1808                  (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1809    (clobber (match_scratch:DI 3 "=l"))
1810    (clobber (match_scratch:DI 4 "=h"))]
1811   "TARGET_64BIT"
1812   "mult\\t%1,%2"
1813   [(set_attr "type"     "imul")
1814    (set_attr "mode"     "SI")
1815    (set_attr "length"   "1")])
1816
1817 (define_insn "smulsi3_highpart"
1818   [(set (match_operand:SI 0 "register_operand" "=h")
1819         (truncate:SI
1820          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1821                                (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
1822                       (const_int 32))))
1823    (clobber (match_scratch:SI 3 "=l"))
1824    (clobber (match_scratch:SI 4 "=a"))]
1825   ""
1826   "mult\\t%1,%2"
1827   [(set_attr "type"     "imul")
1828    (set_attr "mode"     "SI")
1829    (set_attr "length"   "1")])
1830
1831 (define_expand "umulsidi3"
1832   [(set (match_operand:DI 0 "register_operand" "=x")
1833         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1834                  (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1835   ""
1836   "
1837 {
1838   if (TARGET_64BIT)
1839     emit_insn (gen_umulsidi3_64bit (operands[0], operands[1], operands[2]));
1840   else
1841     emit_insn (gen_umulsidi3_internal (operands[0], operands[1], operands[2]));
1842   DONE;
1843 }")
1844
1845 (define_insn "umulsidi3_internal"
1846   [(set (match_operand:DI 0 "register_operand" "=x")
1847         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1848                  (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1849    (clobber (match_scratch:SI 3 "=a"))]
1850   "!TARGET_64BIT"
1851   "multu\\t%1,%2"
1852   [(set_attr "type"     "imul")
1853    (set_attr "mode"     "SI")
1854    (set_attr "length"   "1")])
1855
1856 (define_insn "umulsidi3_64bit"
1857   [(set (match_operand:DI 0 "register_operand" "=a")
1858         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1859                  (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1860    (clobber (match_scratch:DI 3 "=l"))
1861    (clobber (match_scratch:DI 4 "=h"))]
1862   "TARGET_64BIT"
1863   "multu\\t%1,%2"
1864   [(set_attr "type"     "imul")
1865    (set_attr "mode"     "SI")
1866    (set_attr "length"   "1")])
1867
1868 (define_insn "umulsi3_highpart"
1869   [(set (match_operand:SI 0 "register_operand" "=h")
1870         (truncate:SI
1871          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1872                                (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
1873                       (const_int 32))))
1874    (clobber (match_scratch:SI 3 "=l"))
1875    (clobber (match_scratch:SI 4 "=a"))]
1876   ""
1877   "multu\\t%1,%2"
1878   [(set_attr "type"     "imul")
1879    (set_attr "mode"     "SI")
1880    (set_attr "length"   "1")])
1881
1882 (define_insn "smuldi3_highpart"
1883   [(set (match_operand:DI 0 "register_operand" "=h")
1884         (truncate:DI
1885          (lshiftrt:TI (mult:TI (sign_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
1886                                (sign_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
1887                       (const_int 64))))
1888    (clobber (match_scratch:DI 3 "=l"))
1889    (clobber (match_scratch:DI 4 "=a"))]
1890   "TARGET_64BIT"
1891   "dmult\\t%1,%2"
1892   [(set_attr "type"     "imul")
1893    (set_attr "mode"     "DI")
1894    (set_attr "length"   "1")])
1895
1896 (define_insn "umuldi3_highpart"
1897   [(set (match_operand:DI 0 "register_operand" "=h")
1898         (truncate:DI
1899          (lshiftrt:TI (mult:TI (zero_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
1900                                (zero_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
1901                       (const_int 64))))
1902    (clobber (match_scratch:DI 3 "=l"))
1903    (clobber (match_scratch:DI 4 "=a"))]
1904   "TARGET_64BIT"
1905   "dmultu\\t%1,%2"
1906   [(set_attr "type"     "imul")
1907    (set_attr "mode"     "DI")
1908    (set_attr "length"   "1")])
1909
1910 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1911 ;; instruction.  The HI/LO registers are used as a 64 bit accumulator.
1912
1913 (define_insn "madsi"
1914   [(set (match_operand:SI 0 "register_operand" "+l")
1915         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1916                           (match_operand:SI 2 "register_operand" "d"))
1917                  (match_dup 0)))
1918    (clobber (match_scratch:SI 3 "=h"))
1919    (clobber (match_scratch:SI 4 "=a"))]
1920   "TARGET_MAD || GENERATE_MADD"
1921   "*
1922 {
1923   if (TARGET_MAD)
1924     return \"mad\\t%1,%2\";
1925   else
1926     return \"madd\\t%1,%2\";
1927 }"
1928   [(set_attr "type"     "imul")
1929    (set_attr "mode"     "SI")
1930    (set_attr "length"   "1")])
1931
1932 (define_insn "maddi"
1933   [(set (match_operand:DI 0 "register_operand" "+x")
1934         (plus:DI (mult:DI (sign_extend:DI
1935                            (match_operand:SI 1 "register_operand" "d"))
1936                           (sign_extend:DI
1937                            (match_operand:SI 2 "register_operand" "d")))
1938                  (match_dup 0)))
1939    (clobber (match_scratch:SI 3 "=a"))]
1940   "TARGET_MAD && ! TARGET_64BIT"
1941   "mad\\t%1,%2"
1942   [(set_attr "type"     "imul")
1943    (set_attr "mode"     "SI")
1944    (set_attr "length"   "1")])
1945
1946 (define_insn "maddi_64bit"
1947   [(set (match_operand:DI 0 "register_operand" "+a")
1948         (plus:DI (mult:DI (sign_extend:DI
1949                            (match_operand:SI 1 "register_operand" "d"))
1950                           (sign_extend:DI
1951                            (match_operand:SI 2 "register_operand" "d")))
1952                  (match_dup 0)))
1953    (clobber (match_scratch:DI 3 "=l"))
1954    (clobber (match_scratch:DI 4 "=h"))]
1955   "TARGET_MAD && TARGET_64BIT"
1956   "mad\\t%1,%2"
1957   [(set_attr "type"     "imul")
1958    (set_attr "mode"     "SI")
1959    (set_attr "length"   "1")])
1960
1961 (define_insn "umaddi"
1962   [(set (match_operand:DI 0 "register_operand" "+x")
1963         (plus:DI (mult:DI (zero_extend:DI
1964                            (match_operand:SI 1 "register_operand" "d"))
1965                           (zero_extend:DI
1966                            (match_operand:SI 2 "register_operand" "d")))
1967                  (match_dup 0)))
1968    (clobber (match_scratch:SI 3 "=a"))]
1969   "TARGET_MAD && ! TARGET_64BIT"
1970   "madu\\t%1,%2"
1971   [(set_attr "type"     "imul")
1972    (set_attr "mode"     "SI")
1973    (set_attr "length"   "1")])
1974
1975 (define_insn "umaddi_64bit"
1976   [(set (match_operand:DI 0 "register_operand" "+a")
1977         (plus:DI (mult:DI (zero_extend:DI
1978                            (match_operand:SI 1 "register_operand" "d"))
1979                           (zero_extend:DI
1980                            (match_operand:SI 2 "register_operand" "d")))
1981                  (match_dup 0)))
1982    (clobber (match_scratch:DI 3 "=l"))
1983    (clobber (match_scratch:DI 4 "=h"))]
1984   "TARGET_MAD && TARGET_64BIT"
1985   "madu\\t%1,%2"
1986   [(set_attr "type"     "imul")
1987    (set_attr "mode"     "SI")
1988    (set_attr "length"   "1")])
1989
1990 (define_insn "madd3"
1991   [(set (match_operand:SI 0 "register_operand" "=d")
1992         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1993                           (match_operand:SI 2 "register_operand" "d"))
1994                  (match_operand:SI 3 "register_operand" "l")))
1995    (clobber (match_scratch:SI 4 "=l"))
1996    (clobber (match_scratch:SI 5 "=h"))
1997    (clobber (match_scratch:SI 6 "=a"))]
1998   "GENERATE_MADD"
1999   "madd\\t%0,%1,%2"
2000   [(set_attr "type"     "imul")
2001    (set_attr "mode"     "SI")
2002    (set_attr "length"   "1")])
2003
2004 ;; Floating point multiply accumulate instructions.
2005
2006 (define_insn ""
2007   [(set (match_operand:DF 0 "register_operand" "=f")
2008         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2009                           (match_operand:DF 2 "register_operand" "f"))
2010                  (match_operand:DF 3 "register_operand" "f")))]
2011   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2012   "madd.d\\t%0,%3,%1,%2"
2013   [(set_attr "type"     "fmadd")
2014    (set_attr "mode"     "DF")
2015    (set_attr "length"   "1")])
2016
2017 (define_insn ""
2018   [(set (match_operand:SF 0 "register_operand" "=f")
2019         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2020                           (match_operand:SF 2 "register_operand" "f"))
2021                  (match_operand:SF 3 "register_operand" "f")))]
2022   "mips_isa >= 4 && TARGET_HARD_FLOAT"
2023   "madd.s\\t%0,%3,%1,%2"
2024   [(set_attr "type"     "fmadd")
2025    (set_attr "mode"     "SF")
2026    (set_attr "length"   "1")])
2027
2028 (define_insn ""
2029   [(set (match_operand:DF 0 "register_operand" "=f")
2030         (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2031                            (match_operand:DF 2 "register_operand" "f"))
2032                   (match_operand:DF 3 "register_operand" "f")))]
2033   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2034   "msub.d\\t%0,%3,%1,%2"
2035   [(set_attr "type"     "fmadd")
2036    (set_attr "mode"     "DF")
2037    (set_attr "length"   "1")])
2038
2039 (define_insn ""
2040   [(set (match_operand:SF 0 "register_operand" "=f")
2041         (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2042                            (match_operand:SF 2 "register_operand" "f"))
2043                   (match_operand:SF 3 "register_operand" "f")))]
2044                   
2045   "mips_isa >= 4 && TARGET_HARD_FLOAT"
2046   "msub.s\\t%0,%3,%1,%2"
2047   [(set_attr "type"     "fmadd")
2048    (set_attr "mode"     "SF")
2049    (set_attr "length"   "1")])
2050
2051 (define_insn ""
2052   [(set (match_operand:DF 0 "register_operand" "=f")
2053         (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2054                                   (match_operand:DF 2 "register_operand" "f"))
2055                          (match_operand:DF 3 "register_operand" "f"))))]
2056   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2057   "nmadd.d\\t%0,%3,%1,%2"
2058   [(set_attr "type"     "fmadd")
2059    (set_attr "mode"     "DF")
2060    (set_attr "length"   "1")])
2061
2062 (define_insn ""
2063   [(set (match_operand:SF 0 "register_operand" "=f")
2064         (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2065                                   (match_operand:SF 2 "register_operand" "f"))
2066                          (match_operand:SF 3 "register_operand" "f"))))]
2067   "mips_isa >= 4 && TARGET_HARD_FLOAT"
2068   "nmadd.s\\t%0,%3,%1,%2"
2069   [(set_attr "type"     "fmadd")
2070    (set_attr "mode"     "SF")
2071    (set_attr "length"   "1")])
2072
2073 (define_insn ""
2074   [(set (match_operand:DF 0 "register_operand" "=f")
2075         (minus:DF (match_operand:DF 1 "register_operand" "f")
2076                   (mult:DF (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   "nmsub.d\\t%0,%1,%2,%3"
2080   [(set_attr "type"     "fmadd")
2081    (set_attr "mode"     "DF")
2082    (set_attr "length"   "1")])
2083
2084 (define_insn ""
2085   [(set (match_operand:SF 0 "register_operand" "=f")
2086         (minus:SF (match_operand:SF 1 "register_operand" "f")
2087                   (mult:SF (match_operand:SF 2 "register_operand" "f")
2088                            (match_operand:SF 3 "register_operand" "f"))))]
2089   "mips_isa >= 4 && TARGET_HARD_FLOAT"
2090   "nmsub.s\\t%0,%1,%2,%3"
2091   [(set_attr "type"     "fmadd")
2092    (set_attr "mode"     "SF")
2093    (set_attr "length"   "1")])
2094 \f
2095 ;;
2096 ;;  ....................
2097 ;;
2098 ;;      DIVISION and REMAINDER
2099 ;;
2100 ;;  ....................
2101 ;;
2102
2103 (define_insn "divdf3"
2104   [(set (match_operand:DF 0 "register_operand" "=f")
2105         (div:DF (match_operand:DF 1 "register_operand" "f")
2106                 (match_operand:DF 2 "register_operand" "f")))]
2107   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2108   "div.d\\t%0,%1,%2"
2109   [(set_attr "type"     "fdiv")
2110    (set_attr "mode"     "DF")
2111    (set_attr "length"   "1")])
2112
2113 (define_insn "divsf3"
2114   [(set (match_operand:SF 0 "register_operand" "=f")
2115         (div:SF (match_operand:SF 1 "register_operand" "f")
2116                 (match_operand:SF 2 "register_operand" "f")))]
2117   "TARGET_HARD_FLOAT"
2118   "div.s\\t%0,%1,%2"
2119   [(set_attr "type"     "fdiv")
2120    (set_attr "mode"     "SF")
2121    (set_attr "length"   "1")])
2122
2123 (define_insn ""
2124   [(set (match_operand:DF 0 "register_operand" "=f")
2125         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2126                 (match_operand:DF 2 "register_operand" "f")))]
2127   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_fast_math"
2128   "recip.d\\t%0,%2"
2129   [(set_attr "type"     "fdiv")
2130    (set_attr "mode"     "DF")
2131    (set_attr "length"   "1")])
2132
2133 (define_insn ""
2134   [(set (match_operand:SF 0 "register_operand" "=f")
2135         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2136                 (match_operand:SF 2 "register_operand" "f")))]
2137   "mips_isa >= 4 && TARGET_HARD_FLOAT && flag_fast_math"
2138   "recip.s\\t%0,%2"
2139   [(set_attr "type"     "fdiv")
2140    (set_attr "mode"     "SF")
2141    (set_attr "length"   "1")])
2142
2143 ;; If optimizing, prefer the divmod functions over separate div and
2144 ;; mod functions, since this will allow using one instruction for both
2145 ;; the quotient and remainder.  At present, the divmod is not moved out
2146 ;; of loops if it is constant within the loop, so allow -mdebugc to
2147 ;; use the old method of doing things.
2148
2149 ;; 64 is the multiply/divide hi register
2150 ;; 65 is the multiply/divide lo register
2151
2152 ;; ??? We can't accept constants here, because the MIPS assembler will replace
2153 ;; a divide by power of 2 with a shift, and then the remainder is no longer
2154 ;; available.
2155
2156 (define_insn "divmodsi4"
2157   [(set (match_operand:SI 0 "register_operand" "=d")
2158         (div:SI (match_operand:SI 1 "register_operand" "d")
2159                 (match_operand:SI 2 "register_operand" "d")))
2160    (set (match_operand:SI 3 "register_operand" "=d")
2161         (mod:SI (match_dup 1)
2162                 (match_dup 2)))
2163    (clobber (match_scratch:SI 4 "=l"))
2164    (clobber (match_scratch:SI 5 "=h"))
2165    (clobber (match_scratch:SI 6 "=a"))]
2166   "optimize"
2167   "*
2168 {
2169   if (find_reg_note (insn, REG_UNUSED, operands[3]))
2170     return \"div\\t%0,%1,%2\";
2171
2172   if (find_reg_note (insn, REG_UNUSED, operands[0]))
2173     return \"rem\\t%3,%1,%2\";
2174
2175   return \"div\\t%0,%1,%2\;mfhi\\t%3\";
2176 }"
2177   [(set_attr "type"     "idiv")
2178    (set_attr "mode"     "SI")
2179    (set_attr "length"   "14")])         ;; various tests for dividing by 0 and such
2180
2181 (define_insn "divmoddi4"
2182   [(set (match_operand:DI 0 "register_operand" "=d")
2183         (div:DI (match_operand:DI 1 "se_register_operand" "d")
2184                 (match_operand:DI 2 "se_register_operand" "d")))
2185    (set (match_operand:DI 3 "register_operand" "=d")
2186         (mod:DI (match_dup 1)
2187                 (match_dup 2)))
2188    (clobber (match_scratch:DI 4 "=l"))
2189    (clobber (match_scratch:DI 5 "=h"))
2190    (clobber (match_scratch:DI 6 "=a"))]
2191   "TARGET_64BIT && optimize"
2192   "*
2193 {
2194   if (find_reg_note (insn, REG_UNUSED, operands[3]))
2195     return \"ddiv\\t%0,%1,%2\";
2196
2197   if (find_reg_note (insn, REG_UNUSED, operands[0]))
2198     return \"drem\\t%3,%1,%2\";
2199
2200   return \"ddiv\\t%0,%1,%2\;mfhi\\t%3\";
2201 }"
2202   [(set_attr "type"     "idiv")
2203    (set_attr "mode"     "DI")
2204    (set_attr "length"   "15")])         ;; various tests for dividing by 0 and such
2205
2206 (define_insn "udivmodsi4"
2207   [(set (match_operand:SI 0 "register_operand" "=d")
2208         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2209                  (match_operand:SI 2 "register_operand" "d")))
2210    (set (match_operand:SI 3 "register_operand" "=d")
2211         (umod:SI (match_dup 1)
2212                  (match_dup 2)))
2213    (clobber (match_scratch:SI 4 "=l"))
2214    (clobber (match_scratch:SI 5 "=h"))
2215    (clobber (match_scratch:SI 6 "=a"))]
2216   "optimize"
2217   "*
2218 {
2219   if (find_reg_note (insn, REG_UNUSED, operands[3]))
2220     return \"divu\\t%0,%1,%2\";
2221
2222   if (find_reg_note (insn, REG_UNUSED, operands[0]))
2223     return \"remu\\t%3,%1,%2\";
2224
2225   return \"divu\\t%0,%1,%2\;mfhi\\t%3\";
2226 }"
2227   [(set_attr "type"     "idiv")
2228    (set_attr "mode"     "SI")
2229    (set_attr "length"   "8")])          ;; various tests for dividing by 0 and such
2230
2231 (define_insn "udivmoddi4"
2232   [(set (match_operand:DI 0 "register_operand" "=d")
2233         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2234                  (match_operand:DI 2 "se_register_operand" "d")))
2235    (set (match_operand:DI 3 "register_operand" "=d")
2236         (umod:DI (match_dup 1)
2237                  (match_dup 2)))
2238    (clobber (match_scratch:DI 4 "=l"))
2239    (clobber (match_scratch:DI 5 "=h"))
2240    (clobber (match_scratch:DI 6 "=a"))]
2241   "TARGET_64BIT && optimize"
2242   "*
2243 {
2244   if (find_reg_note (insn, REG_UNUSED, operands[3]))
2245     return \"ddivu\\t%0,%1,%2\";
2246
2247   if (find_reg_note (insn, REG_UNUSED, operands[0]))
2248     return \"dremu\\t%3,%1,%2\";
2249
2250   return \"ddivu\\t%0,%1,%2\;mfhi\\t%3\";
2251 }"
2252   [(set_attr "type"     "idiv")
2253    (set_attr "mode"     "DI")
2254    (set_attr "length"   "8")])          ;; various tests for dividing by 0 and such
2255
2256 (define_expand "divsi3"
2257   [(set (match_operand:SI 0 "register_operand" "=d")
2258         (div:SI (match_operand:SI 1 "register_operand" "d")
2259                 (match_operand:SI 2 "nonmemory_operand" "di")))
2260    (clobber (match_scratch:SI 3 "=l"))
2261    (clobber (match_scratch:SI 4 "=h"))
2262    (clobber (match_scratch:SI 6 "=a"))]
2263   "!optimize"
2264   "
2265 {
2266   /* MIPS16 needs div/rem ops in registers. */
2267   if (TARGET_MIPS16)
2268     operands[2] = force_reg (SImode, operands[2]);
2269 }")
2270
2271 (define_insn "divsi3_internal"
2272   [(set (match_operand:SI 0 "register_operand" "=d")
2273         (div:SI (match_operand:SI 1 "register_operand" "d")
2274                 (match_operand:SI 2 "nonmemory_operand" "di")))]
2275   "!optimize"
2276   "div\\t%0,%1,%2"
2277   [(set_attr "type"     "idiv")
2278    (set_attr "mode"     "SI")
2279    (set_attr "length"   "13")]) ;; various tests for dividing by 0 and such
2280
2281 (define_expand "divdi3"
2282   [(set (match_operand:DI 0 "register_operand" "=d")
2283         (div:DI (match_operand:DI 1 "se_register_operand" "d")
2284                 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2285    (clobber (match_scratch:DI 3 "=l"))
2286    (clobber (match_scratch:DI 4 "=h"))
2287    (clobber (match_scratch:DI 6 "=a"))]
2288   "TARGET_64BIT && !optimize"
2289   "
2290 {
2291   /* MIPS16 needs div/rem ops in registers. */
2292   if (TARGET_MIPS16)
2293     operands[2] = force_reg (DImode, operands[2]);
2294 }")
2295
2296 (define_insn "divdi3_internal"
2297   [(set (match_operand:DI 0 "register_operand" "=d")
2298         (div:DI (match_operand:DI 1 "se_register_operand" "d")
2299                 (match_operand:DI 2 "se_nonmemory_operand" "di")))]
2300   "TARGET_64BIT && !optimize"
2301   "ddiv\\t%0,%1,%2"
2302   [(set_attr "type"     "idiv")
2303    (set_attr "mode"     "DI")
2304    (set_attr "length"   "14")]) ;; various tests for dividing by 0 and such
2305
2306 (define_expand "modsi3"
2307   [(set (match_operand:SI 0 "register_operand" "=d")
2308         (mod:SI (match_operand:SI 1 "register_operand" "d")
2309                 (match_operand:SI 2 "nonmemory_operand" "di")))
2310    (clobber (match_scratch:SI 3 "=l"))
2311    (clobber (match_scratch:SI 4 "=h"))
2312    (clobber (match_scratch:SI 6 "=a"))]
2313   "!optimize"
2314   "
2315 {
2316   /* MIPS16 needs div/rem ops in registers. */
2317   if (TARGET_MIPS16)
2318     operands[2] = force_reg (SImode, operands[2]);
2319 }")
2320
2321 (define_insn "modsi3_internal"
2322   [(set (match_operand:SI 0 "register_operand" "=d")
2323         (mod:SI (match_operand:SI 1 "register_operand" "d")
2324                 (match_operand:SI 2 "nonmemory_operand" "di")))]
2325   "!optimize"
2326   "rem\\t%0,%1,%2"
2327   [(set_attr "type"     "idiv")
2328    (set_attr "mode"     "SI")
2329    (set_attr "length"   "13")]) ;; various tests for dividing by 0 and such
2330
2331 (define_expand "moddi3"
2332   [(set (match_operand:DI 0 "register_operand" "=d")
2333         (mod:DI (match_operand:DI 1 "se_register_operand" "d")
2334                 (match_operand:DI 2 "se_nonmemory_operand" "di")))
2335    (clobber (match_scratch:DI 3 "=l"))
2336    (clobber (match_scratch:DI 4 "=h"))
2337    (clobber (match_scratch:DI 6 "=a"))]
2338   "TARGET_64BIT && !optimize"
2339   "
2340 {
2341   /* MIPS16 needs div/rem ops in registers. */
2342   if (TARGET_MIPS16)
2343     operands[2] = force_reg (DImode, operands[2]);
2344 }")
2345
2346 (define_insn "moddi3_internal"
2347   [(set (match_operand:DI 0 "register_operand" "=d")
2348         (mod:DI (match_operand:DI 1 "se_register_operand" "d")
2349                 (match_operand:DI 2 "se_nonmemory_operand" "di")))]
2350   "TARGET_64BIT && !optimize"
2351   "drem\\t%0,%1,%2"
2352   [(set_attr "type"     "idiv")
2353    (set_attr "mode"     "DI")
2354    (set_attr "length"   "14")]) ;; various tests for dividing by 0 and such
2355
2356 (define_expand "udivsi3"
2357   [(set (match_operand:SI 0 "register_operand" "=d")
2358         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2359                  (match_operand:SI 2 "nonmemory_operand" "di")))
2360    (clobber (match_scratch:SI 3 "=l"))
2361    (clobber (match_scratch:SI 4 "=h"))
2362    (clobber (match_scratch:SI 6 "=a"))]
2363   "!optimize"
2364   "
2365 {
2366   /* MIPS16 needs div/rem ops in registers. */
2367   if (TARGET_MIPS16)
2368     operands[2] = force_reg (SImode, operands[2]);
2369 }")
2370
2371 (define_insn "udivsi3_internal"
2372   [(set (match_operand:SI 0 "register_operand" "=d")
2373         (udiv:SI (match_operand:SI 1 "register_operand" "d")
2374                  (match_operand:SI 2 "nonmemory_operand" "di")))]
2375   "!optimize"
2376   "divu\\t%0,%1,%2"
2377   [(set_attr "type"     "idiv")
2378    (set_attr "mode"     "SI")
2379    (set_attr "length"   "7")])  ;; various tests for dividing by 0 and such
2380
2381 (define_expand "udivdi3"
2382   [(set (match_operand:DI 0 "register_operand" "=d")
2383         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2384                  (match_operand:DI 2 "se_nonmemory_operand" "di")))
2385    (clobber (match_scratch:DI 3 "=l"))
2386    (clobber (match_scratch:DI 4 "=h"))
2387    (clobber (match_scratch:DI 6 "=a"))]
2388   "TARGET_64BIT && !optimize"
2389   "
2390 {
2391   /* MIPS16 needs div/rem ops in registers. */
2392   if (TARGET_MIPS16)
2393     operands[2] = force_reg (DImode, operands[2]);
2394 }")
2395
2396 (define_insn "udivdi3_internal"
2397   [(set (match_operand:DI 0 "register_operand" "=d")
2398         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
2399                  (match_operand:DI 2 "se_nonmemory_operand" "di")))]
2400   "TARGET_64BIT && !optimize"
2401   "ddivu\\t%0,%1,%2"
2402   [(set_attr "type"     "idiv")
2403    (set_attr "mode"     "DI")
2404    (set_attr "length"   "7")])  ;; various tests for dividing by 0 and such
2405
2406 (define_expand "umodsi3"
2407   [(set (match_operand:SI 0 "register_operand" "=d")
2408         (umod:SI (match_operand:SI 1 "register_operand" "d")
2409                  (match_operand:SI 2 "nonmemory_operand" "di")))
2410    (clobber (match_scratch:SI 3 "=l"))
2411    (clobber (match_scratch:SI 4 "=h"))
2412    (clobber (match_scratch:SI 6 "=a"))]
2413   "!optimize"
2414   "
2415 {
2416   /* MIPS16 needs div/rem ops in registers. */
2417   if (TARGET_MIPS16)
2418     operands[2] = force_reg (SImode, operands[2]);
2419 }")
2420
2421 (define_insn "umodsi3_internal"
2422   [(set (match_operand:SI 0 "register_operand" "=d")
2423         (umod:SI (match_operand:SI 1 "register_operand" "d")
2424                  (match_operand:SI 2 "nonmemory_operand" "di")))]
2425   "!optimize"
2426   "remu\\t%0,%1,%2"
2427   [(set_attr "type"     "idiv")
2428    (set_attr "mode"     "SI")
2429    (set_attr "length"   "7")])  ;; various tests for dividing by 0 and such
2430
2431 (define_expand "umoddi3"
2432   [(set (match_operand:DI 0 "register_operand" "=d")
2433         (umod:DI (match_operand:DI 1 "se_register_operand" "d")
2434                  (match_operand:DI 2 "se_nonmemory_operand" "di")))
2435    (clobber (match_scratch:DI 3 "=l"))
2436    (clobber (match_scratch:DI 4 "=h"))
2437    (clobber (match_scratch:DI 6 "=a"))]
2438   "TARGET_64BIT && !optimize"
2439   "
2440 {
2441   /* MIPS16 needs div/rem ops in registers. */
2442   if (TARGET_MIPS16)
2443     operands[2] = force_reg (DImode, operands[2]);
2444 }")
2445
2446 (define_insn "umoddi3_internal"
2447   [(set (match_operand:DI 0 "register_operand" "=d")
2448         (umod:DI (match_operand:DI 1 "se_register_operand" "d")
2449                  (match_operand:DI 2 "se_nonmemory_operand" "di")))]
2450   "TARGET_64BIT && !optimize"
2451   "dremu\\t%0,%1,%2"
2452   [(set_attr "type"     "idiv")
2453    (set_attr "mode"     "DI")
2454    (set_attr "length"   "7")])  ;; various tests for dividing by 0 and such
2455
2456 \f
2457 ;;
2458 ;;  ....................
2459 ;;
2460 ;;      SQUARE ROOT
2461 ;;
2462 ;;  ....................
2463
2464 (define_insn "sqrtdf2"
2465   [(set (match_operand:DF 0 "register_operand" "=f")
2466         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2467   "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
2468   "sqrt.d\\t%0,%1"
2469   [(set_attr "type"     "fsqrt")
2470    (set_attr "mode"     "DF")
2471    (set_attr "length"   "1")])
2472
2473 (define_insn "sqrtsf2"
2474   [(set (match_operand:SF 0 "register_operand" "=f")
2475         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2476   "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
2477   "sqrt.s\\t%0,%1"
2478   [(set_attr "type"     "fsqrt")
2479    (set_attr "mode"     "SF")
2480    (set_attr "length"   "1")])
2481
2482 (define_insn ""
2483   [(set (match_operand:DF 0 "register_operand" "=f")
2484         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2485                 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
2486   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_fast_math"
2487   "rsqrt.d\\t%0,%2"
2488   [(set_attr "type"     "fsqrt")
2489    (set_attr "mode"     "DF")
2490    (set_attr "length"   "1")])
2491
2492 (define_insn ""
2493   [(set (match_operand:SF 0 "register_operand" "=f")
2494         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2495                 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
2496   "mips_isa >= 4 && TARGET_HARD_FLOAT && flag_fast_math"
2497   "rsqrt.s\\t%0,%2"
2498   [(set_attr "type"     "fsqrt")
2499    (set_attr "mode"     "SF")
2500    (set_attr "length"   "1")])
2501
2502 \f
2503 ;;
2504 ;;  ....................
2505 ;;
2506 ;;      ABSOLUTE VALUE
2507 ;;
2508 ;;  ....................
2509
2510 ;; Do not use the integer abs macro instruction, since that signals an
2511 ;; exception on -2147483648 (sigh).
2512
2513 (define_insn "abssi2"
2514   [(set (match_operand:SI 0 "register_operand" "=d")
2515         (abs:SI (match_operand:SI 1 "register_operand" "d")))]
2516   "!TARGET_MIPS16"
2517   "*
2518 {
2519   dslots_jump_total++;
2520   dslots_jump_filled++;
2521   operands[2] = const0_rtx;
2522
2523   if (REGNO (operands[0]) == REGNO (operands[1]))
2524     {
2525       if (GENERATE_BRANCHLIKELY)
2526         return \"%(bltzl\\t%1,1f\\n\\tsubu\\t%0,%z2,%0\\n1:%)\";
2527       else
2528         return \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n1:\";
2529     }     
2530   else
2531     return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n1:%)\";
2532 }"
2533   [(set_attr "type"     "multi")
2534    (set_attr "mode"     "SI")
2535    (set_attr "length"   "3")])
2536
2537 (define_insn "absdi2"
2538   [(set (match_operand:DI 0 "register_operand" "=d")
2539         (abs:DI (match_operand:DI 1 "se_register_operand" "d")))]
2540   "TARGET_64BIT && !TARGET_MIPS16"
2541   "*
2542 {
2543   dslots_jump_total++;
2544   dslots_jump_filled++;
2545   operands[2] = const0_rtx;
2546
2547   if (REGNO (operands[0]) == REGNO (operands[1]))
2548     return \"%(bltzl\\t%1,1f\\n\\tdsubu\\t%0,%z2,%0\\n1:%)\";
2549   else
2550     return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tdsubu\\t%0,%z2,%0\\n1:%)\";
2551 }"
2552   [(set_attr "type"     "multi")
2553    (set_attr "mode"     "DI")
2554    (set_attr "length"   "3")])
2555
2556 (define_insn "absdf2"
2557   [(set (match_operand:DF 0 "register_operand" "=f")
2558         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
2559   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2560   "abs.d\\t%0,%1"
2561   [(set_attr "type"     "fabs")
2562    (set_attr "mode"     "DF")
2563    (set_attr "length"   "1")])
2564
2565 (define_insn "abssf2"
2566   [(set (match_operand:SF 0 "register_operand" "=f")
2567         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2568   "TARGET_HARD_FLOAT"
2569   "abs.s\\t%0,%1"
2570   [(set_attr "type"     "fabs")
2571    (set_attr "mode"     "SF")
2572    (set_attr "length"   "1")])
2573
2574 \f
2575 ;;
2576 ;;  ....................
2577 ;;
2578 ;;      FIND FIRST BIT INSTRUCTION
2579 ;;
2580 ;;  ....................
2581 ;;
2582
2583 (define_insn "ffssi2"
2584   [(set (match_operand:SI 0 "register_operand" "=&d")
2585         (ffs:SI (match_operand:SI 1 "register_operand" "d")))
2586    (clobber (match_scratch:SI 2 "=&d"))
2587    (clobber (match_scratch:SI 3 "=&d"))]
2588   "!TARGET_MIPS16"
2589   "*
2590 {
2591   dslots_jump_total += 2;
2592   dslots_jump_filled += 2;
2593   operands[4] = const0_rtx;
2594
2595   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2596     return \"%(\\
2597 move\\t%0,%z4\\n\\
2598 \\tbeq\\t%1,%z4,2f\\n\\
2599 1:\\tand\\t%2,%1,0x0001\\n\\
2600 \\taddu\\t%0,%0,1\\n\\
2601 \\tbeq\\t%2,%z4,1b\\n\\
2602 \\tsrl\\t%1,%1,1\\n\\
2603 2:%)\";
2604
2605   return \"%(\\
2606 move\\t%0,%z4\\n\\
2607 \\tmove\\t%3,%1\\n\\
2608 \\tbeq\\t%3,%z4,2f\\n\\
2609 1:\\tand\\t%2,%3,0x0001\\n\\
2610 \\taddu\\t%0,%0,1\\n\\
2611 \\tbeq\\t%2,%z4,1b\\n\\
2612 \\tsrl\\t%3,%3,1\\n\\
2613 2:%)\";
2614 }"
2615   [(set_attr "type"     "multi")
2616    (set_attr "mode"     "SI")
2617    (set_attr "length"   "6")])
2618
2619 (define_insn "ffsdi2"
2620   [(set (match_operand:DI 0 "register_operand" "=&d")
2621         (ffs:DI (match_operand:DI 1 "se_register_operand" "d")))
2622    (clobber (match_scratch:DI 2 "=&d"))
2623    (clobber (match_scratch:DI 3 "=&d"))]
2624   "TARGET_64BIT && !TARGET_MIPS16"
2625   "*
2626 {
2627   dslots_jump_total += 2;
2628   dslots_jump_filled += 2;
2629   operands[4] = const0_rtx;
2630
2631   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2632     return \"%(\\
2633 move\\t%0,%z4\\n\\
2634 \\tbeq\\t%1,%z4,2f\\n\\
2635 1:\\tand\\t%2,%1,0x0001\\n\\
2636 \\tdaddu\\t%0,%0,1\\n\\
2637 \\tbeq\\t%2,%z4,1b\\n\\
2638 \\tdsrl\\t%1,%1,1\\n\\
2639 2:%)\";
2640
2641   return \"%(\\
2642 move\\t%0,%z4\\n\\
2643 \\tmove\\t%3,%1\\n\\
2644 \\tbeq\\t%3,%z4,2f\\n\\
2645 1:\\tand\\t%2,%3,0x0001\\n\\
2646 \\tdaddu\\t%0,%0,1\\n\\
2647 \\tbeq\\t%2,%z4,1b\\n\\
2648 \\tdsrl\\t%3,%3,1\\n\\
2649 2:%)\";
2650 }"
2651   [(set_attr "type"     "multi")
2652    (set_attr "mode"     "DI")
2653    (set_attr "length"   "6")])
2654
2655 \f
2656 ;;
2657 ;;  ....................
2658 ;;
2659 ;;      NEGATION and ONE'S COMPLEMENT
2660 ;;
2661 ;;  ....................
2662
2663 (define_insn "negsi2"
2664   [(set (match_operand:SI 0 "register_operand" "=d")
2665         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2666   ""
2667   "*
2668 {
2669   if (TARGET_MIPS16)
2670     return \"neg\\t%0,%1\";
2671   operands[2] = const0_rtx;
2672   return \"subu\\t%0,%z2,%1\";
2673 }"
2674   [(set_attr "type"     "arith")
2675    (set_attr "mode"     "SI")
2676    (set_attr "length"   "1")])
2677
2678 (define_expand "negdi2"
2679   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
2680                    (neg:DI (match_operand:DI 1 "se_register_operand" "d")))
2681               (clobber (match_dup 2))])]
2682   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
2683   "
2684 {
2685   if (TARGET_64BIT)
2686     {
2687       emit_insn (gen_negdi2_internal_2 (operands[0], operands[1]));
2688       DONE;
2689     }
2690
2691   operands[2] = gen_reg_rtx (SImode);
2692 }")
2693
2694 (define_insn "negdi2_internal"
2695   [(set (match_operand:DI 0 "register_operand" "=d")
2696         (neg:DI (match_operand:DI 1 "register_operand" "d")))
2697    (clobber (match_operand:SI 2 "register_operand" "=d"))]
2698   "! TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
2699   "*
2700 {
2701   operands[3] = const0_rtx;
2702   return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\";
2703 }"
2704   [(set_attr "type"     "darith")
2705    (set_attr "mode"     "DI")
2706    (set_attr "length"   "4")])
2707
2708 (define_insn "negdi2_internal_2"
2709   [(set (match_operand:DI 0 "register_operand" "=d")
2710         (neg:DI (match_operand:DI 1 "se_register_operand" "d")))]
2711   "TARGET_64BIT && !TARGET_MIPS16"
2712   "*
2713 {
2714   operands[2] = const0_rtx;
2715   return \"dsubu\\t%0,%z2,%1\";
2716 }"
2717   [(set_attr "type"     "arith")
2718    (set_attr "mode"     "DI")
2719    (set_attr "length"   "1")])
2720
2721 (define_insn "negdf2"
2722   [(set (match_operand:DF 0 "register_operand" "=f")
2723         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
2724   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2725   "neg.d\\t%0,%1"
2726   [(set_attr "type"     "fneg")
2727    (set_attr "mode"     "DF")
2728    (set_attr "length"   "1")])
2729
2730 (define_insn "negsf2"
2731   [(set (match_operand:SF 0 "register_operand" "=f")
2732         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2733   "TARGET_HARD_FLOAT"
2734   "neg.s\\t%0,%1"
2735   [(set_attr "type"     "fneg")
2736    (set_attr "mode"     "SF")
2737    (set_attr "length"   "1")])
2738
2739 (define_insn "one_cmplsi2"
2740   [(set (match_operand:SI 0 "register_operand" "=d")
2741         (not:SI (match_operand:SI 1 "register_operand" "d")))]
2742   ""
2743   "*
2744 {
2745   if (TARGET_MIPS16)
2746     return \"not\\t%0,%1\";
2747   operands[2] = const0_rtx;
2748   return \"nor\\t%0,%z2,%1\";
2749 }"
2750   [(set_attr "type"     "arith")
2751    (set_attr "mode"     "SI")
2752    (set_attr "length"   "1")])
2753
2754 (define_insn "one_cmpldi2"
2755   [(set (match_operand:DI 0 "register_operand" "=d")
2756         (not:DI (match_operand:DI 1 "se_register_operand" "d")))]
2757   ""
2758   "*
2759 {
2760   if (TARGET_MIPS16)
2761     {
2762       if (TARGET_64BIT)
2763         return \"not\\t%0,%1\";
2764       return \"not\\t%M0,%M1\;not\\t%L0,%L1\";
2765     }
2766   operands[2] = const0_rtx;
2767   if (TARGET_64BIT)
2768     return \"nor\\t%0,%z2,%1\";
2769   return \"nor\\t%M0,%z2,%M1\;nor\\t%L0,%z2,%L1\";
2770 }"
2771   [(set_attr "type"     "darith")
2772    (set_attr "mode"     "DI")
2773    (set (attr "length")
2774         (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
2775                        (const_int 1)
2776                        (const_int 2)))])
2777
2778 (define_split
2779   [(set (match_operand:DI 0 "register_operand" "")
2780         (not:DI (match_operand:DI 1 "register_operand" "")))]
2781   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2782    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
2783    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
2784
2785   [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0)))
2786    (set (subreg:SI (match_dup 0) 1) (not:SI (subreg:SI (match_dup 1) 1)))]
2787   "")
2788
2789 \f
2790 ;;
2791 ;;  ....................
2792 ;;
2793 ;;      LOGICAL
2794 ;;
2795 ;;  ....................
2796 ;;
2797
2798 ;; Many of these instructions uses trivial define_expands, because we
2799 ;; want to use a different set of constraints when TARGET_MIPS16.
2800
2801 (define_expand "andsi3"
2802   [(set (match_operand:SI 0 "register_operand" "=d,d")
2803         (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2804                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2805   ""
2806   "
2807 {
2808   if (TARGET_MIPS16)
2809     operands[2] = force_reg (SImode, operands[2]);
2810 }")
2811
2812 (define_insn ""
2813   [(set (match_operand:SI 0 "register_operand" "=d,d")
2814         (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2815                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2816   "!TARGET_MIPS16"
2817   "@
2818    and\\t%0,%1,%2
2819    andi\\t%0,%1,%x2"
2820   [(set_attr "type"     "arith")
2821    (set_attr "mode"     "SI")
2822    (set_attr "length"   "1")])
2823
2824 (define_insn ""
2825   [(set (match_operand:SI 0 "register_operand" "=d")
2826         (and:SI (match_operand:SI 1 "register_operand" "%0")
2827                 (match_operand:SI 2 "register_operand" "d")))]
2828   "TARGET_MIPS16"
2829   "and\\t%0,%2"
2830   [(set_attr "type"     "arith")
2831    (set_attr "mode"     "SI")
2832    (set_attr "length"   "1")])
2833
2834 (define_expand "anddi3"
2835   [(set (match_operand:DI 0 "register_operand" "=d")
2836         (and:DI (match_operand:DI 1 "se_register_operand" "d")
2837                 (match_operand:DI 2 "se_register_operand" "d")))]
2838   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
2839   "
2840 {
2841   if (TARGET_MIPS16)
2842     operands[2] = force_reg (DImode, operands[2]);
2843 }")
2844
2845 (define_insn ""
2846   [(set (match_operand:DI 0 "register_operand" "=d")
2847         (and:DI (match_operand:DI 1 "se_register_operand" "d")
2848                 (match_operand:DI 2 "se_register_operand" "d")))]
2849   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
2850   "*
2851 {
2852   if (TARGET_64BIT)
2853     return \"and\\t%0,%1,%2\";
2854   return \"and\\t%M0,%M1,%M2\;and\\t%L0,%L1,%L2\";
2855 }"
2856   [(set_attr "type"     "darith")
2857    (set_attr "mode"     "DI")
2858    (set (attr "length")
2859         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
2860                        (const_int 1)
2861                        (const_int 2)))])
2862
2863 (define_insn ""
2864   [(set (match_operand:DI 0 "register_operand" "=d")
2865         (and:DI (match_operand:DI 1 "se_register_operand" "0")
2866                 (match_operand:DI 2 "se_register_operand" "d")))]
2867   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
2868   "*
2869 {
2870   if (TARGET_64BIT)
2871     return \"and\\t%0,%2\";
2872   return \"and\\t%M0,%M2\;and\\t%L0,%L2\";
2873 }"
2874   [(set_attr "type"     "darith")
2875    (set_attr "mode"     "DI")
2876    (set (attr "length")
2877         (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
2878                        (const_int 1)
2879                        (const_int 2)))])
2880
2881 (define_split
2882   [(set (match_operand:DI 0 "register_operand" "")
2883         (and:DI (match_operand:DI 1 "register_operand" "")
2884                 (match_operand:DI 2 "register_operand" "")))]
2885   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2886    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
2887    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
2888    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
2889
2890   [(set (subreg:SI (match_dup 0) 0) (and:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
2891    (set (subreg:SI (match_dup 0) 1) (and:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
2892   "")
2893
2894 (define_insn "anddi3_internal1"
2895   [(set (match_operand:DI 0 "register_operand" "=d,d")
2896         (and:DI (match_operand:DI 1 "se_register_operand" "%d,d")
2897                 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
2898   "TARGET_64BIT && !TARGET_MIPS16"
2899   "@
2900    and\\t%0,%1,%2
2901    andi\\t%0,%1,%x2"
2902   [(set_attr "type"     "arith")
2903    (set_attr "mode"     "DI")
2904    (set_attr "length"   "1")])
2905
2906 (define_expand "iorsi3"
2907   [(set (match_operand:SI 0 "register_operand" "=d,d")
2908         (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2909                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2910   ""
2911   "
2912 {
2913   if (TARGET_MIPS16)
2914     operands[2] = force_reg (SImode, operands[2]);
2915 }")
2916
2917 (define_insn ""
2918   [(set (match_operand:SI 0 "register_operand" "=d,d")
2919         (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2920                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2921   "!TARGET_MIPS16"
2922   "@
2923    or\\t%0,%1,%2
2924    ori\\t%0,%1,%x2"
2925   [(set_attr "type"     "arith")
2926    (set_attr "mode"     "SI")
2927    (set_attr "length"   "1")])
2928
2929 (define_insn ""
2930   [(set (match_operand:SI 0 "register_operand" "=d")
2931         (ior:SI (match_operand:SI 1 "register_operand" "%0")
2932                 (match_operand:SI 2 "register_operand" "d")))]
2933   "TARGET_MIPS16"
2934   "or\\t%0,%2"
2935   [(set_attr "type"     "arith")
2936    (set_attr "mode"     "SI")
2937    (set_attr "length"   "1")])
2938
2939 ;;; ??? There is no iordi3 pattern which accepts 'K' constants when
2940 ;;; TARGET_64BIT
2941
2942 (define_expand "iordi3"
2943   [(set (match_operand:DI 0 "register_operand" "=d")
2944         (ior:DI (match_operand:DI 1 "se_register_operand" "d")
2945                 (match_operand:DI 2 "se_register_operand" "d")))]
2946   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
2947   "")
2948
2949 (define_insn ""
2950   [(set (match_operand:DI 0 "register_operand" "=d")
2951         (ior:DI (match_operand:DI 1 "se_register_operand" "d")
2952                 (match_operand:DI 2 "se_register_operand" "d")))]
2953   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
2954   "*
2955 {
2956   if (TARGET_64BIT)
2957     return \"or\\t%0,%1,%2\";
2958   return \"or\\t%M0,%M1,%M2\;or\\t%L0,%L1,%L2\";
2959 }"
2960   [(set_attr "type"     "darith")
2961    (set_attr "mode"     "DI")
2962    (set (attr "length")
2963         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
2964                        (const_int 1)
2965                        (const_int 2)))])
2966
2967 (define_insn ""
2968   [(set (match_operand:DI 0 "register_operand" "=d")
2969         (ior:DI (match_operand:DI 1 "se_register_operand" "0")
2970                 (match_operand:DI 2 "se_register_operand" "d")))]
2971   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16"
2972   "*
2973 {
2974   if (TARGET_64BIT)
2975     return \"or\\t%0,%2\";
2976   return \"or\\t%M0,%M2\;or\\t%L0,%L2\";
2977 }"
2978   [(set_attr "type"     "darith")
2979    (set_attr "mode"     "DI")
2980    (set (attr "length")
2981         (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
2982                        (const_int 1)
2983                        (const_int 2)))])
2984
2985 (define_split
2986   [(set (match_operand:DI 0 "register_operand" "")
2987         (ior:DI (match_operand:DI 1 "register_operand" "")
2988                 (match_operand:DI 2 "register_operand" "")))]
2989   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2990    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
2991    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
2992    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
2993
2994   [(set (subreg:SI (match_dup 0) 0) (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
2995    (set (subreg:SI (match_dup 0) 1) (ior:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
2996   "")
2997
2998 (define_expand "xorsi3"
2999   [(set (match_operand:SI 0 "register_operand" "=d,d")
3000         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3001                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3002   ""
3003   "")
3004
3005 (define_insn ""
3006   [(set (match_operand:SI 0 "register_operand" "=d,d")
3007         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3008                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3009   "!TARGET_MIPS16"
3010   "@
3011    xor\\t%0,%1,%2
3012    xori\\t%0,%1,%x2"
3013   [(set_attr "type"     "arith")
3014    (set_attr "mode"     "SI")
3015    (set_attr "length"   "1")])
3016
3017 (define_insn ""
3018   [(set (match_operand:SI 0 "register_operand" "=d,t,t")
3019         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
3020                 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
3021   "TARGET_MIPS16"
3022   "@
3023    xor\\t%0,%2
3024    cmpi\\t%1,%2
3025    cmp\\t%1,%2"
3026   [(set_attr "type"     "arith")
3027    (set_attr "mode"     "SI")
3028    (set_attr_alternative "length"
3029                 [(const_int 1)
3030                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3031                                (const_int 1)
3032                                (const_int 2))
3033                  (const_int 1)])])
3034
3035 ;; ??? If delete the 32-bit long long patterns, then could merge this with
3036 ;; the following xordi3_internal pattern.
3037 (define_expand "xordi3"
3038   [(set (match_operand:DI 0 "register_operand" "=d")
3039         (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3040                 (match_operand:DI 2 "se_register_operand" "d")))]
3041   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
3042   "")
3043
3044 (define_insn ""
3045   [(set (match_operand:DI 0 "register_operand" "=d")
3046         (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3047                 (match_operand:DI 2 "se_register_operand" "d")))]
3048   "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
3049   "*
3050 {
3051   if (TARGET_64BIT)
3052     return \"xor\\t%0,%1,%2\";
3053   return \"xor\\t%M0,%M1,%M2\;xor\\t%L0,%L1,%L2\";
3054 }"
3055   [(set_attr "type"     "darith")
3056    (set_attr "mode"     "DI")
3057    (set (attr "length")
3058         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3059                        (const_int 1)
3060                        (const_int 2)))])
3061
3062 (define_insn ""
3063   [(set (match_operand:DI 0 "register_operand" "=d")
3064         (xor:DI (match_operand:DI 1 "se_register_operand" "0")
3065                 (match_operand:DI 2 "se_register_operand" "d")))]
3066   "!TARGET_64BIT && TARGET_MIPS16"
3067   "xor\\t%M0,%M2\;xor\\t%L0,%L2"
3068   [(set_attr "type"     "darith")
3069    (set_attr "mode"     "DI")
3070    (set_attr "length"   "2")])
3071
3072 (define_insn ""
3073   [(set (match_operand:DI 0 "register_operand" "=d,t,t")
3074         (xor:DI (match_operand:DI 1 "se_register_operand" "%0,d,d")
3075                 (match_operand:DI 2 "se_uns_arith_operand" "d,K,d")))]
3076   "TARGET_64BIT && TARGET_MIPS16"
3077   "@
3078    xor\\t%0,%2
3079    cmpi\\t%1,%2
3080    cmp\\t%1,%2"
3081   [(set_attr "type"     "arith")
3082    (set_attr "mode"     "DI")
3083    (set_attr_alternative "length"
3084                 [(const_int 1)
3085                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3086                                (const_int 1)
3087                                (const_int 2))
3088                  (const_int 1)])])
3089
3090 (define_split
3091   [(set (match_operand:DI 0 "register_operand" "")
3092         (xor:DI (match_operand:DI 1 "register_operand" "")
3093                 (match_operand:DI 2 "register_operand" "")))]
3094   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3095    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3096    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3097    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3098
3099   [(set (subreg:SI (match_dup 0) 0) (xor:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
3100    (set (subreg:SI (match_dup 0) 1) (xor:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
3101   "")
3102
3103 (define_insn "xordi3_immed"
3104   [(set (match_operand:DI 0 "register_operand" "=d")
3105         (xor:DI (match_operand:DI 1 "se_register_operand" "d")
3106                 (match_operand:DI 2 "se_uns_arith_operand" "K")))]
3107   "TARGET_64BIT && !TARGET_MIPS16"
3108   "xori\\t%0,%1,%x2"
3109   [(set_attr "type"     "arith")
3110    (set_attr "mode"     "DI")
3111    (set_attr "length"   "1")])
3112
3113 (define_insn "*norsi3"
3114   [(set (match_operand:SI 0 "register_operand" "=d")
3115         (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
3116                 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
3117   "!TARGET_MIPS16"
3118   "nor\\t%0,%z1,%z2"
3119   [(set_attr "type"     "arith")
3120    (set_attr "mode"     "SI")
3121    (set_attr "length"   "1")])
3122
3123 (define_insn "*nordi3"
3124   [(set (match_operand:DI 0 "register_operand" "=d")
3125         (and:DI (not:DI (match_operand:DI 1 "se_register_operand" "d"))
3126                 (not:DI (match_operand:DI 2 "se_register_operand" "d"))))]
3127   "!TARGET_MIPS16"
3128   "*
3129 {
3130   if (TARGET_64BIT)
3131     return \"nor\\t%0,%z1,%z2\";
3132   return \"nor\\t%M0,%M1,%M2\;nor\\t%L0,%L1,%L2\";
3133 }"
3134   [(set_attr "type"     "darith")
3135    (set_attr "mode"     "DI")
3136    (set (attr "length")
3137         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
3138                        (const_int 1)
3139                        (const_int 2)))])
3140
3141 (define_split
3142   [(set (match_operand:DI 0 "register_operand" "")
3143         (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
3144                 (not:DI (match_operand:DI 2 "register_operand" ""))))]
3145   "reload_completed && !TARGET_MIPS16 && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3146    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3147    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
3148    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
3149
3150   [(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))))
3151    (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))))]
3152   "")
3153 \f
3154 ;;
3155 ;;  ....................
3156 ;;
3157 ;;      TRUNCATION
3158 ;;
3159 ;;  ....................
3160
3161 (define_insn "truncdfsf2"
3162   [(set (match_operand:SF 0 "register_operand" "=f")
3163         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3164   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3165   "cvt.s.d\\t%0,%1"
3166   [(set_attr "type"     "fcvt")
3167    (set_attr "mode"     "SF")
3168    (set_attr "length"   "1")])
3169
3170 (define_insn "truncdisi2"
3171   [(set (match_operand:SI 0 "register_operand" "=d")
3172         (truncate:SI (match_operand:DI 1 "se_register_operand" "d")))]
3173   "TARGET_64BIT"
3174   "*
3175 {
3176   if (TARGET_MIPS16)
3177     return \"dsll\\t%0,%1,32\;dsra\\t%0,32\";
3178   return \"dsll\\t%0,%1,32\;dsra\\t%0,%0,32\";
3179 }"
3180   [(set_attr "type"     "darith")
3181    (set_attr "mode"     "SI")
3182    (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0))
3183                                       (const_int 2)
3184                                       (const_int 4)))])
3185
3186 (define_insn "truncdihi2"
3187   [(set (match_operand:HI 0 "register_operand" "=d")
3188         (truncate:HI (match_operand:DI 1 "se_register_operand" "d")))]
3189   "TARGET_64BIT && !TARGET_MIPS16"
3190   "andi\\t%0,%1,0xffff"
3191   [(set_attr "type"     "darith")
3192    (set_attr "mode"     "HI")
3193    (set_attr "length"   "1")])
3194
3195 (define_insn "truncdiqi2"
3196   [(set (match_operand:QI 0 "register_operand" "=d")
3197         (truncate:QI (match_operand:DI 1 "se_register_operand" "d")))]
3198   "TARGET_64BIT && !TARGET_MIPS16"
3199   "andi\\t%0,%1,0x00ff"
3200   [(set_attr "type"     "darith")
3201    (set_attr "mode"     "QI")
3202    (set_attr "length"   "1")])
3203
3204 ;; Combiner patterns to optimize shift/truncate combinations.
3205 (define_insn ""
3206   [(set (match_operand:SI 0 "register_operand" "=d")
3207         (truncate:SI (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
3208                                   (match_operand:DI 2 "small_int" "I"))))]
3209   "TARGET_64BIT && !TARGET_MIPS16"
3210   "*
3211 {
3212   int shift_amt = INTVAL (operands[2]) & 0x3f;
3213
3214   if (shift_amt < 32)
3215     {
3216       operands[2] = GEN_INT (32 - shift_amt);
3217       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3218     }
3219   else
3220     {
3221       operands[2] = GEN_INT (shift_amt);
3222       return \"dsra\\t%0,%1,%2\";
3223     }
3224 }"
3225   [(set_attr "type"     "darith")
3226    (set_attr "mode"     "SI")
3227    (set_attr "length"   "2")])
3228         
3229 (define_insn ""
3230   [(set (match_operand:SI 0 "register_operand" "=d")
3231         (truncate:SI (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
3232                                   (match_operand:DI 2 "small_int" "I"))))]
3233   "TARGET_64BIT && !TARGET_MIPS16"
3234   "*
3235 {
3236   int shift_amt = INTVAL (operands[2]) & 0x3f;
3237
3238   if (shift_amt < 32)
3239     {
3240       operands[2] = GEN_INT (32 - shift_amt);
3241       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3242     }
3243   else if (shift_amt == 32)
3244     return \"dsra\\t%0,%1,32\";
3245   else
3246     {
3247       operands[2] = GEN_INT (shift_amt);
3248       return \"dsrl\\t%0,%1,%2\";
3249     }
3250 }"
3251   [(set_attr "type"     "darith")
3252    (set_attr "mode"     "SI")
3253    (set_attr "length"   "2")])
3254
3255 (define_insn ""
3256   [(set (match_operand:SI 0 "register_operand" "=d")
3257         (truncate:SI (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
3258                                 (match_operand:DI 2 "small_int" "I"))))]
3259   "TARGET_64BIT"
3260   "*
3261 {
3262   int shift_amt = INTVAL (operands[2]) & 0x3f;
3263
3264   if (shift_amt < 32)
3265     {
3266       operands[2] = GEN_INT (32 + shift_amt);
3267       if (TARGET_MIPS16)
3268         return \"dsll\\t%0,%1,%2\;dsra\\t%0,32\";
3269       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
3270     }
3271   else
3272     return \"move\\t%0,%.\";
3273 }"
3274   [(set_attr "type"     "darith")
3275    (set_attr "mode"     "SI")
3276    (set_attr "length"   "2")])
3277
3278 ;; Combiner patterns to optimize truncate/zero_extend combinations.
3279
3280 (define_insn ""
3281   [(set (match_operand:SI 0 "register_operand" "=d")
3282         (zero_extend:SI (truncate:HI
3283                          (match_operand:DI 1 "se_register_operand" "d"))))]
3284   "TARGET_64BIT && !TARGET_MIPS16"
3285   "andi\\t%0,%1,0xffff"
3286   [(set_attr "type"     "darith")
3287    (set_attr "mode"     "SI")
3288    (set_attr "length"   "1")])
3289
3290 (define_insn ""
3291   [(set (match_operand:SI 0 "register_operand" "=d")
3292         (zero_extend:SI (truncate:QI
3293                          (match_operand:DI 1 "se_register_operand" "d"))))]
3294   "TARGET_64BIT && !TARGET_MIPS16"
3295   "andi\\t%0,%1,0xff"
3296   [(set_attr "type"     "darith")
3297    (set_attr "mode"     "SI")
3298    (set_attr "length"   "1")])
3299
3300 (define_insn ""
3301   [(set (match_operand:HI 0 "register_operand" "=d")
3302         (zero_extend:HI (truncate:QI
3303                          (match_operand:DI 1 "se_register_operand" "d"))))]
3304   "TARGET_64BIT && !TARGET_MIPS16"
3305   "andi\\t%0,%1,0xff"
3306   [(set_attr "type"     "darith")
3307    (set_attr "mode"     "HI")
3308    (set_attr "length"   "1")])
3309 \f
3310 ;;
3311 ;;  ....................
3312 ;;
3313 ;;      ZERO EXTENSION
3314 ;;
3315 ;;  ....................
3316
3317 ;; Extension insns.
3318 ;; Those for integer source operand are ordered widest source type first.
3319
3320 (define_expand "zero_extendsidi2"
3321   [(set (match_operand:DI 0 "register_operand" "")
3322         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3323   "TARGET_64BIT"
3324   "
3325 {
3326   if (optimize && GET_CODE (operands[1]) == MEM)
3327     operands[1] = force_not_mem (operands[1]);
3328
3329   if (GET_CODE (operands[1]) != MEM)
3330     {
3331       rtx op1   = gen_lowpart (DImode, operands[1]);
3332       rtx temp  = gen_reg_rtx (DImode);
3333       rtx shift = gen_rtx (CONST_INT, VOIDmode, 32);
3334
3335       emit_insn (gen_ashldi3 (temp, op1, shift));
3336       emit_insn (gen_lshrdi3 (operands[0], temp, shift));
3337       DONE;
3338     }
3339 }")
3340
3341 (define_insn "zero_extendsidi2_internal"
3342   [(set (match_operand:DI 0 "register_operand" "=d,d")
3343         (zero_extend:DI (match_operand:SI 1 "memory_operand" "R,m")))]
3344   "TARGET_64BIT"
3345   "* return mips_move_1word (operands, insn, TRUE);"
3346   [(set_attr "type"     "load")
3347    (set_attr "mode"     "DI")
3348    (set_attr "length"   "1,2")])
3349
3350 (define_expand "zero_extendhisi2"
3351   [(set (match_operand:SI 0 "register_operand" "")
3352         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3353   ""
3354   "
3355 {
3356   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3357     {
3358       rtx op = gen_lowpart (SImode, operands[1]);
3359       rtx temp = force_reg (SImode, GEN_INT (0xffff));
3360
3361       emit_insn (gen_andsi3 (operands[0], op, temp));
3362       DONE;
3363     }
3364 }")
3365
3366 (define_insn ""
3367   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
3368         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
3369   "!TARGET_MIPS16"
3370   "*
3371 {
3372   if (which_alternative == 0)
3373     return \"andi\\t%0,%1,0xffff\";
3374   else
3375     return mips_move_1word (operands, insn, TRUE);
3376 }"
3377   [(set_attr "type"     "arith,load,load")
3378    (set_attr "mode"     "SI")
3379    (set_attr "length"   "1,1,2")])
3380
3381 (define_insn ""
3382   [(set (match_operand:SI 0 "register_operand" "=d,d")
3383         (zero_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
3384   "TARGET_MIPS16"
3385   "* return mips_move_1word (operands, insn, TRUE);"
3386   [(set_attr "type"     "load,load")
3387    (set_attr "mode"     "SI")
3388    (set_attr "length"   "1,2")])
3389
3390 (define_expand "zero_extendhidi2"
3391   [(set (match_operand:DI 0 "register_operand" "")
3392         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
3393   "TARGET_64BIT"
3394   "
3395 {
3396   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3397     {
3398       rtx op = gen_lowpart (DImode, operands[1]);
3399       rtx temp = force_reg (DImode, GEN_INT (0xffff));
3400
3401       emit_insn (gen_anddi3 (operands[0], op, temp));
3402       DONE;
3403     }
3404 }")
3405
3406 (define_insn ""
3407   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
3408         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
3409   "TARGET_64BIT && !TARGET_MIPS16"
3410   "*
3411 {
3412   if (which_alternative == 0)
3413     return \"andi\\t%0,%1,0xffff\";
3414   else
3415     return mips_move_1word (operands, insn, TRUE);
3416 }"
3417   [(set_attr "type"     "arith,load,load")
3418    (set_attr "mode"     "DI")
3419    (set_attr "length"   "1,1,2")])
3420
3421 (define_insn ""
3422   [(set (match_operand:DI 0 "register_operand" "=d,d")
3423         (zero_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
3424   "TARGET_64BIT && TARGET_MIPS16"
3425   "* return mips_move_1word (operands, insn, TRUE);"
3426   [(set_attr "type"     "load,load")
3427    (set_attr "mode"     "DI")
3428    (set_attr "length"   "1,2")])
3429
3430 (define_expand "zero_extendqihi2"
3431   [(set (match_operand:HI 0 "register_operand" "")
3432         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3433   ""
3434   "
3435 {
3436   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3437     {
3438       rtx op0 = gen_lowpart (SImode, operands[0]);
3439       rtx op1 = gen_lowpart (SImode, operands[1]);
3440       rtx temp = force_reg (SImode, GEN_INT (0xff));
3441
3442       emit_insn (gen_andsi3 (op0, op1, temp));
3443       DONE;
3444     }
3445 }")
3446
3447 (define_insn ""
3448   [(set (match_operand:HI 0 "register_operand" "=d,d,d")
3449         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
3450   "!TARGET_MIPS16"
3451   "*
3452 {
3453   if (which_alternative == 0)
3454     return \"andi\\t%0,%1,0x00ff\";
3455   else
3456     return mips_move_1word (operands, insn, TRUE);
3457 }"
3458   [(set_attr "type"     "arith,load,load")
3459    (set_attr "mode"     "HI")
3460    (set_attr "length"   "1,1,2")])
3461
3462 (define_insn ""
3463   [(set (match_operand:HI 0 "register_operand" "=d,d")
3464         (zero_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
3465   "TARGET_MIPS16"
3466   "* return mips_move_1word (operands, insn, TRUE);"
3467   [(set_attr "type"     "load,load")
3468    (set_attr "mode"     "HI")
3469    (set_attr "length"   "1,2")])
3470
3471 (define_expand "zero_extendqisi2"
3472   [(set (match_operand:SI 0 "register_operand" "")
3473         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3474   ""
3475   "
3476 {
3477   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3478     {
3479       rtx op = gen_lowpart (SImode, operands[1]);
3480       rtx temp = force_reg (SImode, GEN_INT (0xff));
3481
3482       emit_insn (gen_andsi3 (operands[0], op, temp));
3483       DONE;
3484     }
3485 }")
3486
3487 (define_insn ""
3488   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
3489         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
3490   "!TARGET_MIPS16"
3491   "*
3492 {
3493   if (which_alternative == 0)
3494     return \"andi\\t%0,%1,0x00ff\";
3495   else
3496     return mips_move_1word (operands, insn, TRUE);
3497 }"
3498   [(set_attr "type"     "arith,load,load")
3499    (set_attr "mode"     "SI")
3500    (set_attr "length"   "1,1,2")])
3501
3502 (define_insn ""
3503   [(set (match_operand:SI 0 "register_operand" "=d,d")
3504         (zero_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
3505   "TARGET_MIPS16"
3506   "* return mips_move_1word (operands, insn, TRUE);"
3507   [(set_attr "type"     "load,load")
3508    (set_attr "mode"     "SI")
3509    (set_attr "length"   "1,2")])
3510
3511 (define_expand "zero_extendqidi2"
3512   [(set (match_operand:DI 0 "register_operand" "")
3513         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
3514   "TARGET_64BIT"
3515   "
3516 {
3517   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3518     {
3519       rtx op = gen_lowpart (DImode, operands[1]);
3520       rtx temp = force_reg (DImode, GEN_INT (0xff));
3521
3522       emit_insn (gen_anddi3 (operands[0], op, temp));
3523       DONE;
3524     }
3525 }")
3526
3527 (define_insn ""
3528   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
3529         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
3530   "TARGET_64BIT && !TARGET_MIPS16"
3531   "*
3532 {
3533   if (which_alternative == 0)
3534     return \"andi\\t%0,%1,0x00ff\";
3535   else
3536     return mips_move_1word (operands, insn, TRUE);
3537 }"
3538   [(set_attr "type"     "arith,load,load")
3539    (set_attr "mode"     "DI")
3540    (set_attr "length"   "1,1,2")])
3541
3542 ;; These can be created when a paradoxical subreg operand with an implicit
3543 ;; sign_extend operator is reloaded.  Because of the subreg, this is really
3544 ;; a zero extend.
3545 ;; ??? It might be possible to eliminate the need for these patterns by adding
3546 ;; more support to reload for implicit sign_extend operators.
3547 (define_insn "*paradoxical_extendhidi2"
3548   [(set (match_operand:DI 0 "register_operand" "=d,d")
3549         (sign_extend:DI
3550          (subreg:SI (match_operand:HI 1 "memory_operand" "R,m") 0)))]
3551   "TARGET_64BIT"
3552   "*
3553 {
3554   return mips_move_1word (operands, insn, TRUE);
3555 }"
3556   [(set_attr "type"     "load,load")
3557    (set_attr "mode"     "DI")
3558    (set_attr "length"   "1,2")])
3559
3560 (define_insn ""
3561   [(set (match_operand:DI 0 "register_operand" "=d,d")
3562         (zero_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
3563   "TARGET_64BIT && TARGET_MIPS16"
3564   "* return mips_move_1word (operands, insn, TRUE);"
3565   [(set_attr "type"     "load,load")
3566    (set_attr "mode"     "DI")
3567    (set_attr "length"   "1,2")])
3568 \f
3569 ;;
3570 ;;  ....................
3571 ;;
3572 ;;      SIGN EXTENSION
3573 ;;
3574 ;;  ....................
3575
3576 ;; Extension insns.
3577 ;; Those for integer source operand are ordered widest source type first.
3578
3579 ;; In 64 bit mode, 32 bit values in general registers are always
3580 ;; correctly sign extended.  That means that if the target is a
3581 ;; general register, we can sign extend from SImode to DImode just by
3582 ;; doing a move.
3583
3584 (define_insn "extendsidi2"
3585   [(set (match_operand:DI 0 "register_operand" "=d,*d,d,d")
3586         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,*x,R,m")))]
3587   "TARGET_64BIT"
3588   "* return mips_move_1word (operands, insn, FALSE);"
3589   [(set_attr "type"     "move,hilo,load,load")
3590    (set_attr "mode"     "DI")
3591    (set_attr "length"   "1,1,1,2")])
3592
3593 ;; These patterns originally accepted general_operands, however, slightly
3594 ;; better code is generated by only accepting register_operands, and then
3595 ;; letting combine generate the lh and lb insns.
3596
3597 (define_expand "extendhidi2"
3598   [(set (match_operand:DI 0 "register_operand" "")
3599         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
3600   "TARGET_64BIT"
3601   "
3602 {
3603   if (optimize && GET_CODE (operands[1]) == MEM)
3604     operands[1] = force_not_mem (operands[1]);
3605
3606   if (GET_CODE (operands[1]) != MEM)
3607     {
3608       rtx op1   = gen_lowpart (DImode, operands[1]);
3609       rtx temp  = gen_reg_rtx (DImode);
3610       rtx shift = gen_rtx (CONST_INT, VOIDmode, 48);
3611
3612       emit_insn (gen_ashldi3 (temp, op1, shift));
3613       emit_insn (gen_ashrdi3 (operands[0], temp, shift));
3614       DONE;
3615     }
3616 }")
3617
3618 (define_insn "extendhidi2_internal"
3619   [(set (match_operand:DI 0 "register_operand" "=d,d")
3620         (sign_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
3621   "TARGET_64BIT"
3622   "* return mips_move_1word (operands, insn, FALSE);"
3623   [(set_attr "type"     "load")
3624    (set_attr "mode"     "DI")
3625    (set_attr "length"   "1,2")])
3626
3627 (define_expand "extendhisi2"
3628   [(set (match_operand:SI 0 "register_operand" "")
3629         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3630   ""
3631   "
3632 {
3633   if (optimize && GET_CODE (operands[1]) == MEM)
3634     operands[1] = force_not_mem (operands[1]);
3635
3636   if (GET_CODE (operands[1]) != MEM)
3637     {
3638       rtx op1   = gen_lowpart (SImode, operands[1]);
3639       rtx temp  = gen_reg_rtx (SImode);
3640       rtx shift = gen_rtx (CONST_INT, VOIDmode, 16);
3641
3642       emit_insn (gen_ashlsi3 (temp, op1, shift));
3643       emit_insn (gen_ashrsi3 (operands[0], temp, shift));
3644       DONE;
3645     }
3646 }")
3647
3648 (define_insn "extendhisi2_internal"
3649   [(set (match_operand:SI 0 "register_operand" "=d,d")
3650         (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
3651   ""
3652   "* return mips_move_1word (operands, insn, FALSE);"
3653   [(set_attr "type"     "load")
3654    (set_attr "mode"     "SI")
3655    (set_attr "length"   "1,2")])
3656
3657 (define_expand "extendqihi2"
3658   [(set (match_operand:HI 0 "register_operand" "")
3659         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3660   ""
3661   "
3662 {
3663   if (optimize && GET_CODE (operands[1]) == MEM)
3664     operands[1] = force_not_mem (operands[1]);
3665
3666   if (GET_CODE (operands[1]) != MEM)
3667     {
3668       rtx op0   = gen_lowpart (SImode, operands[0]);
3669       rtx op1   = gen_lowpart (SImode, operands[1]);
3670       rtx temp  = gen_reg_rtx (SImode);
3671       rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
3672
3673       emit_insn (gen_ashlsi3 (temp, op1, shift));
3674       emit_insn (gen_ashrsi3 (op0, temp, shift));
3675       DONE;
3676     }
3677 }")
3678
3679 (define_insn "extendqihi2_internal"
3680   [(set (match_operand:HI 0 "register_operand" "=d,d")
3681         (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
3682   ""
3683   "* return mips_move_1word (operands, insn, FALSE);"
3684   [(set_attr "type"     "load")
3685    (set_attr "mode"     "SI")
3686    (set_attr "length"   "1,2")])
3687
3688
3689 (define_expand "extendqisi2"
3690   [(set (match_operand:SI 0 "register_operand" "")
3691         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3692   ""
3693   "
3694 {
3695   if (optimize && GET_CODE (operands[1]) == MEM)
3696     operands[1] = force_not_mem (operands[1]);
3697
3698   if (GET_CODE (operands[1]) != MEM)
3699     {
3700       rtx op1   = gen_lowpart (SImode, operands[1]);
3701       rtx temp  = gen_reg_rtx (SImode);
3702       rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
3703
3704       emit_insn (gen_ashlsi3 (temp, op1, shift));
3705       emit_insn (gen_ashrsi3 (operands[0], temp, shift));
3706       DONE;
3707     }
3708 }")
3709
3710 (define_insn "extendqisi2_insn"
3711   [(set (match_operand:SI 0 "register_operand" "=d,d")
3712         (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
3713   ""
3714   "* return mips_move_1word (operands, insn, FALSE);"
3715   [(set_attr "type"     "load")
3716    (set_attr "mode"     "SI")
3717    (set_attr "length"   "1,2")])
3718
3719 (define_expand "extendqidi2"
3720   [(set (match_operand:DI 0 "register_operand" "")
3721         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
3722   "TARGET_64BIT"
3723   "
3724 {
3725   if (optimize && GET_CODE (operands[1]) == MEM)
3726     operands[1] = force_not_mem (operands[1]);
3727
3728   if (GET_CODE (operands[1]) != MEM)
3729     {
3730       rtx op1   = gen_lowpart (DImode, operands[1]);
3731       rtx temp  = gen_reg_rtx (DImode);
3732       rtx shift = gen_rtx (CONST_INT, VOIDmode, 56);
3733
3734       emit_insn (gen_ashldi3 (temp, op1, shift));
3735       emit_insn (gen_ashrdi3 (operands[0], temp, shift));
3736       DONE;
3737     }
3738 }")
3739
3740 (define_insn "extendqidi2_insn"
3741   [(set (match_operand:DI 0 "register_operand" "=d,d")
3742         (sign_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
3743   "TARGET_64BIT"
3744   "* return mips_move_1word (operands, insn, FALSE);"
3745   [(set_attr "type"     "load")
3746    (set_attr "mode"     "DI")
3747    (set_attr "length"   "1,2")])
3748
3749
3750 (define_insn "extendsfdf2"
3751   [(set (match_operand:DF 0 "register_operand" "=f")
3752         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
3753   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3754   "cvt.d.s\\t%0,%1"
3755   [(set_attr "type"     "fcvt")
3756    (set_attr "mode"     "DF")
3757    (set_attr "length"   "1")])
3758
3759 \f
3760
3761 ;;
3762 ;;  ....................
3763 ;;
3764 ;;      CONVERSIONS
3765 ;;
3766 ;;  ....................
3767
3768 ;; The SImode scratch register can not be shared with address regs used for
3769 ;; operand zero, because then the address in the move instruction will be
3770 ;; clobbered.  We mark the scratch register as early clobbered to prevent this.
3771
3772 ;; We need the ?X in alternative 1 so that it will be choosen only if the
3773 ;; destination is a floating point register.  Otherwise, alternative 1 can
3774 ;; have lower cost than alternative 0 (because there is one less loser), and
3775 ;; can be choosen when it won't work (because integral reloads into FP
3776 ;; registers are not supported).
3777
3778 (define_insn "fix_truncdfsi2"
3779   [(set (match_operand:SI 0 "general_operand" "=d,*f,R,To")
3780         (fix:SI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
3781    (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
3782    (clobber (match_scratch:DF 3 "=f,?*X,f,f"))]
3783   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3784   "*
3785 {
3786   rtx xoperands[10];
3787
3788   if (which_alternative == 1)
3789     return \"trunc.w.d %0,%1,%2\";
3790
3791   output_asm_insn (\"trunc.w.d %3,%1,%2\", operands);
3792
3793   xoperands[0] = operands[0];
3794   xoperands[1] = operands[3];
3795   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
3796   return \"\";
3797 }"
3798   [(set_attr "type"     "fcvt")
3799    (set_attr "mode"     "DF")
3800    (set_attr "length"   "11,9,10,11")])
3801
3802
3803 (define_insn "fix_truncsfsi2"
3804   [(set (match_operand:SI 0 "general_operand" "=d,*f,R,To")
3805         (fix:SI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
3806    (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
3807    (clobber (match_scratch:SF 3 "=f,?*X,f,f"))]
3808   "TARGET_HARD_FLOAT"
3809   "*
3810 {
3811   rtx xoperands[10];
3812
3813   if (which_alternative == 1)
3814     return \"trunc.w.s %0,%1,%2\";
3815
3816   output_asm_insn (\"trunc.w.s %3,%1,%2\", operands);
3817
3818   xoperands[0] = operands[0];
3819   xoperands[1] = operands[3];
3820   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
3821   return \"\";
3822 }"
3823   [(set_attr "type"     "fcvt")
3824    (set_attr "mode"     "SF")
3825    (set_attr "length"   "11,9,10,11")])
3826
3827
3828 ;;; ??? trunc.l.d is mentioned in the appendix of the 1993 r4000/r4600 manuals
3829 ;;; but not in the chapter that describes the FPU.  It is not mentioned at all
3830 ;;; in the 1991 manuals.  The r4000 at Cygnus does not have this instruction.
3831
3832 ;;; Deleting this means that we now need two libgcc2.a libraries.  One for
3833 ;;; the 32 bit calling convention and one for the 64 bit calling convention.
3834
3835 ;;; If this is disabled, then fixuns_truncdfdi2 must be disabled also.
3836
3837 (define_insn "fix_truncdfdi2"
3838   [(set (match_operand:DI 0 "general_operand" "=d,*f,R,To")
3839         (fix:DI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
3840    (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
3841   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3842   "*
3843 {
3844   rtx xoperands[10];
3845
3846   if (which_alternative == 1)
3847     return \"trunc.l.d %0,%1\";
3848
3849   output_asm_insn (\"trunc.l.d %2,%1\", operands);
3850
3851   xoperands[0] = operands[0];
3852   xoperands[1] = operands[2];
3853   output_asm_insn (mips_move_2words (xoperands, insn, FALSE), xoperands);
3854   return \"\";
3855 }"
3856   [(set_attr "type"     "fcvt")
3857    (set_attr "mode"     "DF")
3858    (set_attr "length"   "2,1,2,3")])
3859
3860
3861 ;;; ??? trunc.l.s is mentioned in the appendix of the 1993 r4000/r4600 manuals
3862 ;;; but not in the chapter that describes the FPU.  It is not mentioned at all
3863 ;;; in the 1991 manuals.  The r4000 at Cygnus does not have this instruction.
3864 (define_insn "fix_truncsfdi2"
3865   [(set (match_operand:DI 0 "general_operand" "=d,*f,R,To")
3866         (fix:DI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
3867    (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
3868   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3869   "*
3870 {
3871   rtx xoperands[10];
3872
3873   if (which_alternative == 1)
3874     return \"trunc.l.s %0,%1\";
3875
3876   output_asm_insn (\"trunc.l.s %2,%1\", operands);
3877
3878   xoperands[0] = operands[0];
3879   xoperands[1] = operands[2];
3880   output_asm_insn (mips_move_2words (xoperands, insn, FALSE), xoperands);
3881   return \"\";
3882 }"
3883   [(set_attr "type"     "fcvt")
3884    (set_attr "mode"     "SF")
3885    (set_attr "length"   "2,1,2,3")])
3886
3887
3888 (define_insn "floatsidf2"
3889   [(set (match_operand:DF 0 "register_operand" "=f,f,f")
3890         (float:DF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
3891   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3892   "*
3893 {
3894   dslots_load_total++;
3895   if (GET_CODE (operands[1]) == MEM)
3896     return \"l.s\\t%0,%1%#\;cvt.d.w\\t%0,%0\";
3897
3898   return \"mtc1\\t%1,%0%#\;cvt.d.w\\t%0,%0\";
3899 }"
3900   [(set_attr "type"     "fcvt")
3901    (set_attr "mode"     "DF")
3902    (set_attr "length"   "3,4,3")])
3903
3904
3905 (define_insn "floatdidf2"
3906   [(set (match_operand:DF 0 "register_operand" "=f,f,f")
3907         (float:DF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
3908   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3909   "*
3910 {
3911   dslots_load_total++;
3912   if (GET_CODE (operands[1]) == MEM)
3913     return \"l.d\\t%0,%1%#\;cvt.d.l\\t%0,%0\";
3914
3915   return \"dmtc1\\t%1,%0%#\;cvt.d.l\\t%0,%0\";
3916 }"
3917   [(set_attr "type"     "fcvt")
3918    (set_attr "mode"     "DF")
3919    (set_attr "length"   "3,4,3")])
3920
3921
3922 (define_insn "floatsisf2"
3923   [(set (match_operand:SF 0 "register_operand" "=f,f,f")
3924         (float:SF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
3925   "TARGET_HARD_FLOAT"
3926   "*
3927 {
3928   dslots_load_total++;
3929   if (GET_CODE (operands[1]) == MEM)
3930     return \"l.s\\t%0,%1%#\;cvt.s.w\\t%0,%0\";
3931
3932   return \"mtc1\\t%1,%0%#\;cvt.s.w\\t%0,%0\";
3933 }"
3934   [(set_attr "type"     "fcvt")
3935    (set_attr "mode"     "SF")
3936    (set_attr "length"   "3,4,3")])
3937
3938
3939 (define_insn "floatdisf2"
3940   [(set (match_operand:SF 0 "register_operand" "=f,f,f")
3941         (float:SF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
3942   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3943   "*
3944 {
3945   dslots_load_total++;
3946   if (GET_CODE (operands[1]) == MEM)
3947     return \"l.d\\t%0,%1%#\;cvt.s.l\\t%0,%0\";
3948
3949   return \"dmtc1\\t%1,%0%#\;cvt.s.l\\t%0,%0\";
3950 }"
3951   [(set_attr "type"     "fcvt")
3952    (set_attr "mode"     "SF")
3953    (set_attr "length"   "3,4,3")])
3954
3955
3956 (define_expand "fixuns_truncdfsi2"
3957   [(set (match_operand:SI 0 "register_operand" "")
3958         (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
3959   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3960   "
3961 {
3962   rtx reg1 = gen_reg_rtx (DFmode);
3963   rtx reg2 = gen_reg_rtx (DFmode);
3964   rtx reg3 = gen_reg_rtx (SImode);
3965   rtx label1 = gen_label_rtx ();
3966   rtx label2 = gen_label_rtx ();
3967   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
3968
3969   if (reg1)                     /* turn off complaints about unreached code */
3970     {
3971       emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
3972       do_pending_stack_adjust ();
3973
3974       emit_insn (gen_cmpdf (operands[1], reg1));
3975       emit_jump_insn (gen_bge (label1));
3976
3977       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
3978       emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
3979                                gen_rtx (LABEL_REF, VOIDmode, label2)));
3980       emit_barrier ();
3981
3982       emit_label (label1);
3983       emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1));
3984       emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
3985
3986       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
3987       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3988
3989       emit_label (label2);
3990
3991       /* allow REG_NOTES to be set on last insn (labels don't have enough
3992          fields, and can't be used for REG_NOTES anyway).  */
3993       emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
3994       DONE;
3995     }
3996 }")
3997
3998
3999 (define_expand "fixuns_truncdfdi2"
4000   [(set (match_operand:DI 0 "register_operand" "")
4001         (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
4002   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4003   "
4004 {
4005   rtx reg1 = gen_reg_rtx (DFmode);
4006   rtx reg2 = gen_reg_rtx (DFmode);
4007   rtx reg3 = gen_reg_rtx (DImode);
4008   rtx label1 = gen_label_rtx ();
4009   rtx label2 = gen_label_rtx ();
4010   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
4011
4012   if (reg1)                     /* turn off complaints about unreached code */
4013     {
4014       emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
4015       do_pending_stack_adjust ();
4016
4017       emit_insn (gen_cmpdf (operands[1], reg1));
4018       emit_jump_insn (gen_bge (label1));
4019
4020       emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
4021       emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
4022                                gen_rtx (LABEL_REF, VOIDmode, label2)));
4023       emit_barrier ();
4024
4025       emit_label (label1);
4026       emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1));
4027       emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
4028       emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4029
4030       emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
4031       emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4032
4033       emit_label (label2);
4034
4035       /* allow REG_NOTES to be set on last insn (labels don't have enough
4036          fields, and can't be used for REG_NOTES anyway).  */
4037       emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
4038       DONE;
4039     }
4040 }")
4041
4042
4043 (define_expand "fixuns_truncsfsi2"
4044   [(set (match_operand:SI 0 "register_operand" "")
4045         (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
4046   "TARGET_HARD_FLOAT"
4047   "
4048 {
4049   rtx reg1 = gen_reg_rtx (SFmode);
4050   rtx reg2 = gen_reg_rtx (SFmode);
4051   rtx reg3 = gen_reg_rtx (SImode);
4052   rtx label1 = gen_label_rtx ();
4053   rtx label2 = gen_label_rtx ();
4054   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
4055
4056   if (reg1)                     /* turn off complaints about unreached code */
4057     {
4058       emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
4059       do_pending_stack_adjust ();
4060
4061       emit_insn (gen_cmpsf (operands[1], reg1));
4062       emit_jump_insn (gen_bge (label1));
4063
4064       emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
4065       emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
4066                                gen_rtx (LABEL_REF, VOIDmode, label2)));
4067       emit_barrier ();
4068
4069       emit_label (label1);
4070       emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1));
4071       emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
4072
4073       emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
4074       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
4075
4076       emit_label (label2);
4077
4078       /* allow REG_NOTES to be set on last insn (labels don't have enough
4079          fields, and can't be used for REG_NOTES anyway).  */
4080       emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
4081       DONE;
4082     }
4083 }")
4084
4085
4086 (define_expand "fixuns_truncsfdi2"
4087   [(set (match_operand:DI 0 "register_operand" "")
4088         (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
4089   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
4090   "
4091 {
4092   rtx reg1 = gen_reg_rtx (SFmode);
4093   rtx reg2 = gen_reg_rtx (SFmode);
4094   rtx reg3 = gen_reg_rtx (DImode);
4095   rtx label1 = gen_label_rtx ();
4096   rtx label2 = gen_label_rtx ();
4097   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
4098
4099   if (reg1)                     /* turn off complaints about unreached code */
4100     {
4101       emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
4102       do_pending_stack_adjust ();
4103
4104       emit_insn (gen_cmpsf (operands[1], reg1));
4105       emit_jump_insn (gen_bge (label1));
4106
4107       emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
4108       emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
4109                                gen_rtx (LABEL_REF, VOIDmode, label2)));
4110       emit_barrier ();
4111
4112       emit_label (label1);
4113       emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1));
4114       emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
4115       emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
4116
4117       emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
4118       emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
4119
4120       emit_label (label2);
4121
4122       /* allow REG_NOTES to be set on last insn (labels don't have enough
4123          fields, and can't be used for REG_NOTES anyway).  */
4124       emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
4125       DONE;
4126     }
4127 }")
4128
4129 \f
4130 ;;
4131 ;;  ....................
4132 ;;
4133 ;;      DATA MOVEMENT
4134 ;;
4135 ;;  ....................
4136
4137 ;; Bit field extract patterns which use lwl/lwr.
4138
4139 ;; ??? There should be DImode variants for 64 bit code, but the current
4140 ;; bitfield scheme can't handle that.  We would need to add new optabs
4141 ;; in order to make that work.
4142
4143 ;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
4144 ;; It isn't clear whether this will give better code.
4145
4146 (define_expand "extv"
4147   [(set (match_operand:SI 0 "register_operand" "")
4148         (sign_extract:SI (match_operand:QI 1 "memory_operand" "")
4149                          (match_operand:SI 2 "immediate_operand" "")
4150                          (match_operand:SI 3 "immediate_operand" "")))]
4151   "!TARGET_MIPS16"
4152   "
4153 {
4154   /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
4155      then fail.  */
4156   if (INTVAL (operands[2]) != 32 || (INTVAL (operands[3]) % 8) != 0)
4157     FAIL;
4158
4159   /* This can happen for a 64 bit target, when extracting a value from
4160      a 64 bit union member.  extract_bit_field doesn't verify that our
4161      source matches the predicate, so we force it to be a MEM here.  */
4162   if (GET_CODE (operands[1]) != MEM)
4163     FAIL;
4164
4165   /* Change the mode to BLKmode for aliasing purposes.  */
4166   operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
4167
4168   /* Otherwise, emit a lwl/lwr pair to load the value.  */
4169   emit_insn (gen_movsi_ulw (operands[0], operands[1]));
4170   DONE;
4171 }")
4172
4173 (define_expand "extzv"
4174   [(set (match_operand:SI 0 "register_operand" "")
4175         (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
4176                          (match_operand:SI 2 "immediate_operand" "")
4177                          (match_operand:SI 3 "immediate_operand" "")))]
4178   "!TARGET_MIPS16"
4179   "
4180 {
4181   /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
4182      then fail.  */
4183   if (INTVAL (operands[2]) != 32 || (INTVAL (operands[3]) % 8) != 0)
4184     FAIL;
4185
4186   /* This can happen for a 64 bit target, when extracting a value from
4187      a 64 bit union member.  extract_bit_field doesn't verify that our
4188      source matches the predicate, so we force it to be a MEM here.  */
4189   if (GET_CODE (operands[1]) != MEM)
4190     FAIL;
4191
4192   /* Change the mode to BLKmode for aliasing purposes.  */
4193   operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
4194
4195   /* Otherwise, emit a lwl/lwr pair to load the value.  */
4196   emit_insn (gen_movsi_ulw (operands[0], operands[1]));
4197   DONE;
4198 }")
4199
4200 (define_expand "insv"
4201   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
4202                          (match_operand:SI 1 "immediate_operand" "")
4203                          (match_operand:SI 2 "immediate_operand" ""))
4204         (match_operand:SI 3 "register_operand" ""))]
4205   "!TARGET_MIPS16"
4206   "
4207 {
4208   /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
4209      then fail.  */
4210   if (INTVAL (operands[1]) != 32 || (INTVAL (operands[2]) % 8) != 0)
4211     FAIL;
4212
4213   /* This can happen for a 64 bit target, when storing into a 32 bit union
4214      member.  store_bit_field doesn't verify that our target matches the
4215      predicate, so we force it to be a MEM here.  */
4216   if (GET_CODE (operands[0]) != MEM)
4217     FAIL;
4218
4219   /* Change the mode to BLKmode for aliasing purposes.  */
4220   operands[0] = change_address (operands[0], BLKmode, XEXP (operands[0], 0));
4221
4222   /* Otherwise, emit a swl/swr pair to load the value.  */
4223   emit_insn (gen_movsi_usw (operands[0], operands[3]));
4224   DONE;
4225 }")
4226
4227 ;; unaligned word moves generated by the bit field patterns
4228
4229 (define_insn "movsi_ulw"
4230   [(set (match_operand:SI 0 "register_operand" "=&d,&d")
4231         (unspec:SI [(match_operand:BLK 1 "general_operand" "R,o")] 0))]
4232   "!TARGET_MIPS16"
4233   "*
4234 {
4235   rtx offset = const0_rtx;
4236   rtx addr = XEXP (operands[1], 0);
4237   rtx mem_addr = eliminate_constant_term (addr, &offset);
4238   char *ret;
4239
4240   if (TARGET_STATS)
4241     mips_count_memory_refs (operands[1], 2);
4242
4243   /* The stack/frame pointers are always aligned, so we can convert
4244      to the faster lw if we are referencing an aligned stack location.  */
4245
4246   if ((INTVAL (offset) & 3) == 0
4247       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4248     ret = \"lw\\t%0,%1\";
4249   else
4250     ret = \"ulw\\t%0,%1\";
4251
4252   return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
4253 }"
4254   [(set_attr "type"     "load,load")
4255    (set_attr "mode"     "SI")
4256    (set_attr "length"   "2,4")])
4257
4258 (define_insn "movsi_usw"
4259   [(set (match_operand:BLK 0 "memory_operand" "=R,o")
4260         (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")] 1))]
4261   "!TARGET_MIPS16"
4262   "*
4263 {
4264   rtx offset = const0_rtx;
4265   rtx addr = XEXP (operands[0], 0);
4266   rtx mem_addr = eliminate_constant_term (addr, &offset);
4267
4268   if (TARGET_STATS)
4269     mips_count_memory_refs (operands[0], 2);
4270
4271   /* The stack/frame pointers are always aligned, so we can convert
4272      to the faster sw if we are referencing an aligned stack location.  */
4273
4274   if ((INTVAL (offset) & 3) == 0
4275       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
4276     return \"sw\\t%1,%0\";
4277
4278   return \"usw\\t%z1,%0\";
4279 }"
4280   [(set_attr "type"     "store")
4281    (set_attr "mode"     "SI")
4282    (set_attr "length"   "2,4")])
4283
4284 ;; These two patterns support loading addresses with two instructions instead
4285 ;; of using the macro instruction la.
4286
4287 ;; ??? mips_move_1word has support for HIGH, so this pattern may be
4288 ;; unnecessary.
4289
4290 (define_insn "high"
4291   [(set (match_operand:SI 0 "register_operand" "=r")
4292         (high:SI (match_operand:SI 1 "immediate_operand" "")))]
4293   "mips_split_addresses && !TARGET_MIPS16"
4294   "lui\\t%0,%%hi(%1) # high"
4295   [(set_attr "type"     "move")
4296    (set_attr "length"   "1")])
4297
4298 (define_insn "low"
4299   [(set (match_operand:SI 0 "register_operand" "=r")
4300         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
4301                    (match_operand:SI 2 "immediate_operand" "")))]
4302   "mips_split_addresses && !TARGET_MIPS16"
4303   "addiu\\t%0,%1,%%lo(%2) # low"
4304   [(set_attr "type"     "arith")
4305    (set_attr "mode"     "SI")
4306    (set_attr "length"   "1")])
4307
4308 ;; 64-bit integer moves
4309
4310 ;; Unlike most other insns, the move insns can't be split with
4311 ;; different predicates, because register spilling and other parts of
4312 ;; the compiler, have memoized the insn number already.
4313
4314 (define_expand "movdi"
4315   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4316         (match_operand:DI 1 "general_operand" ""))]
4317   ""
4318   "
4319 {
4320   if (mips_split_addresses && mips_check_split (operands[1], DImode))
4321     {
4322       enum machine_mode mode = GET_MODE (operands[0]);
4323       rtx tem = ((reload_in_progress | reload_completed)
4324                  ? operands[0] : gen_reg_rtx (mode));
4325
4326       emit_insn (gen_rtx (SET, VOIDmode, tem,
4327                           gen_rtx (HIGH, mode, operands[1])));
4328
4329       operands[1] = gen_rtx (LO_SUM, mode, tem, operands[1]);
4330     }
4331
4332   /* If we are generating embedded PIC code, and we are referring to a
4333      symbol in the .text section, we must use an offset from the start
4334      of the function.  */
4335   if (TARGET_EMBEDDED_PIC
4336       && (GET_CODE (operands[1]) == LABEL_REF
4337           || (GET_CODE (operands[1]) == SYMBOL_REF
4338               && ! SYMBOL_REF_FLAG (operands[1]))))
4339     {
4340       rtx temp;
4341
4342       temp = embedded_pic_offset (operands[1]);
4343       temp = gen_rtx (PLUS, Pmode, embedded_pic_fnaddr_rtx,
4344                       force_reg (DImode, temp));
4345       emit_move_insn (operands[0], force_reg (DImode, temp));
4346       DONE;
4347     }
4348
4349   /* If operands[1] is a constant address illegal for pic, then we need to
4350      handle it just like LEGITIMIZE_ADDRESS does.  */
4351   if (flag_pic && pic_address_needs_scratch (operands[1]))
4352     {
4353       rtx temp = force_reg (DImode, XEXP (XEXP (operands[1], 0), 0));
4354       rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
4355
4356       if (! SMALL_INT (temp2))
4357         temp2 = force_reg (DImode, temp2);
4358
4359       emit_move_insn (operands[0], gen_rtx (PLUS, DImode, temp, temp2));
4360       DONE;
4361     }
4362
4363   /* On the mips16, we can handle a GP relative reference by adding in
4364      $gp.  We need to check the name to see whether this is a string
4365      constant.  */
4366   if (TARGET_MIPS16
4367       && register_operand (operands[0], DImode)
4368       && GET_CODE (operands[1]) == SYMBOL_REF
4369       && SYMBOL_REF_FLAG (operands[1]))
4370     {
4371       char *name = XSTR (operands[1], 0);
4372
4373       if (name[0] != '*'
4374           || strncmp (name + 1, LOCAL_LABEL_PREFIX,
4375                       sizeof LOCAL_LABEL_PREFIX - 1) != 0)
4376         {
4377           rtx base_reg;
4378
4379           if (reload_in_progress || reload_completed)
4380             {
4381               /* In movsi we use the constant table here.  However, in
4382                  this case, we're better off copying $28 into a
4383                  register and adding, because the constant table entry
4384                  would be 8 bytes.  */
4385               base_reg = operands[0];
4386               emit_move_insn (base_reg,
4387                               gen_rtx (CONST, DImode,
4388                                        gen_rtx (REG, DImode,
4389                                                 GP_REG_FIRST + 28)));
4390             }
4391           else
4392             {
4393               base_reg = gen_reg_rtx (Pmode);
4394               emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
4395             }
4396
4397           emit_move_insn (operands[0],
4398                           gen_rtx (PLUS, SImode, base_reg,
4399                                    mips16_gp_offset (operands[1])));
4400           DONE;
4401         }
4402     }
4403
4404   if ((reload_in_progress | reload_completed) == 0
4405       && !register_operand (operands[0], DImode)
4406       && !register_operand (operands[1], DImode)
4407       && (TARGET_MIPS16
4408           || (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
4409               && operands[1] != CONST0_RTX (DImode)))
4410     {
4411       rtx temp = force_reg (DImode, operands[1]);
4412       emit_move_insn (operands[0], temp);
4413       DONE;
4414     }
4415 }")
4416
4417 ;; For mips16, we need a special case to handle storing $31 into
4418 ;; memory, since we don't have a constraint to match $31.  This
4419 ;; instruction can be generated by save_restore_insns.
4420
4421 (define_insn ""
4422   [(set (match_operand:DI 0 "memory_operand" "R,m")
4423         (reg:DI 31))]
4424   "TARGET_MIPS16 && TARGET_64BIT"
4425   "*
4426 {
4427   operands[1] = gen_rtx (REG, DImode, 31);
4428   return mips_move_2words (operands, insn);
4429 }"
4430   [(set_attr "type"     "store")
4431    (set_attr "mode"     "DI")
4432    (set_attr "length"   "1,2")])
4433
4434 (define_insn "movdi_internal"
4435   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*x,*d,*x")
4436         (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,J,*x,*d"))]
4437   "!TARGET_64BIT && !TARGET_MIPS16
4438    && (register_operand (operands[0], DImode)
4439        || register_operand (operands[1], DImode)
4440        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
4441        || operands[1] == CONST0_RTX (DImode))"
4442   "* return mips_move_2words (operands, insn); "
4443   [(set_attr "type"     "move,arith,load,load,store,store,hilo,hilo,hilo")
4444    (set_attr "mode"     "DI")
4445    (set_attr "length"   "2,4,2,4,2,4,2,2,2")])
4446
4447 (define_insn ""
4448   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,To,*d")
4449         (match_operand:DI 1 "general_operand" "d,d,y,K,N,R,To,d,d,*x"))]
4450   "!TARGET_64BIT && TARGET_MIPS16
4451    && (register_operand (operands[0], DImode)
4452        || register_operand (operands[1], DImode))"
4453   "* return mips_move_2words (operands, insn);"
4454   [(set_attr "type"     "move,move,move,arith,arith,load,load,store,store,hilo")
4455    (set_attr "mode"     "DI")
4456    (set_attr "length"   "2,2,2,2,3,2,4,2,4,2")])
4457
4458 (define_split
4459   [(set (match_operand:DI 0 "register_operand" "")
4460         (match_operand:DI 1 "register_operand" ""))]
4461   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4462    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
4463    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
4464
4465   [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
4466    (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
4467   "")
4468
4469 (define_insn "movdi_internal2"
4470   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*x,*d,*x,*a")
4471         (match_operand:DI 1 "movdi_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,J,*x,*d,*J"))]
4472   "TARGET_64BIT && !TARGET_MIPS16
4473    && (register_operand (operands[0], DImode)
4474        || se_register_operand (operands[1], DImode)
4475        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
4476        || operands[1] == CONST0_RTX (DImode))"
4477   "* return mips_move_2words (operands, insn); "
4478   [(set_attr "type"     "move,load,arith,arith,load,load,store,store,hilo,hilo,hilo,hilo")
4479    (set_attr "mode"     "DI")
4480    (set_attr "length"   "1,2,1,2,1,2,1,2,1,1,1,2")])
4481
4482 (define_insn ""
4483   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,R,m,*d")
4484         (match_operand:DI 1 "movdi_operand" "d,d,y,K,N,s,R,m,d,d,*x"))]
4485   "TARGET_64BIT && TARGET_MIPS16
4486    && (register_operand (operands[0], DImode)
4487        || se_register_operand (operands[1], DImode))"
4488   "* return mips_move_2words (operands, insn);"
4489   [(set_attr "type"     "move,move,move,arith,arith,arith,load,load,store,store,hilo")
4490    (set_attr "mode"     "DI")
4491    (set_attr_alternative "length"
4492                 [(const_int 1)
4493                  (const_int 1)
4494                  (const_int 1)
4495                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
4496                                (const_int 1)
4497                                (const_int 2))
4498                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
4499                                (const_int 2)
4500                                (const_int 3))
4501                  (if_then_else (match_operand:VOID 1 "m16_usym5_4" "")
4502                                (const_int 1)
4503                                (const_int 2))
4504                  (const_int 1)
4505                  (const_int 2)
4506                  (const_int 1)
4507                  (const_int 2)
4508                  (const_int 1)])])
4509
4510 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
4511 ;; when the original load is a 4 byte instruction but the add and the
4512 ;; load are 2 2 byte instructions.
4513
4514 (define_split
4515   [(set (match_operand:DI 0 "register_operand" "")
4516         (mem:DI (plus:DI (match_dup 0)
4517                          (match_operand:DI 1 "const_int_operand" ""))))]
4518   "TARGET_64BIT && TARGET_MIPS16 && reload_completed
4519    && GET_CODE (operands[0]) == REG
4520    && M16_REG_P (REGNO (operands[0]))
4521    && GET_CODE (operands[1]) == CONST_INT
4522    && ((INTVAL (operands[1]) < 0
4523         && INTVAL (operands[1]) >= -0x10)
4524        || (INTVAL (operands[1]) >= 32 * 8
4525            && INTVAL (operands[1]) <= 31 * 8 + 0x8)
4526        || (INTVAL (operands[1]) >= 0
4527            && INTVAL (operands[1]) < 32 * 8
4528            && (INTVAL (operands[1]) & 7) != 0))"
4529   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
4530    (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
4531   "
4532 {
4533   HOST_WIDE_INT val = INTVAL (operands[1]);
4534
4535   if (val < 0)
4536     operands[2] = GEN_INT (0);
4537   else if (val >= 32 * 8)
4538     {
4539       int off = val & 7;
4540
4541       operands[1] = GEN_INT (0x8 + off);
4542       operands[2] = GEN_INT (val - off - 0x8);
4543     }
4544   else
4545     {
4546       int off = val & 7;
4547
4548       operands[1] = GEN_INT (off);
4549       operands[2] = GEN_INT (val - off);
4550     }
4551 }")
4552
4553 ;; Handle input reloads in DImode.
4554 ;; This is mainly to handle reloading HILO_REGNUM.  Note that we may
4555 ;; see it as the source or the destination, depending upon which way
4556 ;; reload handles the instruction.
4557 ;; Making the second operand TImode is a trick.  The compiler may
4558 ;; reuse the same register for operand 0 and operand 2.  Using TImode
4559 ;; gives us two registers, so we can always use the one which is not
4560 ;; used.
4561
4562 (define_expand "reload_indi"
4563   [(set (match_operand:DI 0 "register_operand" "=b")
4564         (match_operand:DI 1 "movdi_operand" "b"))
4565    (clobber (match_operand:TI 2 "register_operand" "=&d"))]
4566   "TARGET_64BIT"
4567   "
4568 {
4569   rtx scratch = gen_rtx (REG, DImode,
4570                          (REGNO (operands[0]) == REGNO (operands[2]) 
4571                           ? REGNO (operands[2]) + 1
4572                           : REGNO (operands[2])));
4573
4574   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
4575     {
4576       if (GET_CODE (operands[1]) == MEM)
4577         {
4578           rtx memword, offword, hiword, loword;
4579
4580           scratch = gen_rtx (REG, SImode, REGNO (scratch));
4581           memword = change_address (operands[1], SImode, NULL_RTX);
4582           offword = change_address (adj_offsettable_operand (operands[1], 4),
4583                                     SImode, NULL_RTX);
4584           if (BYTES_BIG_ENDIAN)
4585             {
4586               hiword = memword;
4587               loword = offword;
4588             }
4589           else
4590             {
4591               hiword = offword;
4592               loword = memword;
4593             }
4594           emit_move_insn (scratch, hiword);
4595           emit_move_insn (gen_rtx (REG, SImode, 64), scratch);
4596           emit_move_insn (scratch, loword);
4597           emit_move_insn (gen_rtx (REG, SImode, 65), scratch);
4598         }
4599       else
4600         {
4601           emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
4602           emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
4603           emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
4604           emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
4605           emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
4606         }
4607       DONE;
4608     }
4609   if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
4610     {
4611       emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
4612       emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
4613       emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
4614       emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
4615       emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
4616       emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
4617       DONE;
4618     }
4619   /* This handles moves between a float register and HI/LO.  */
4620   emit_move_insn (scratch, operands[1]);
4621   emit_move_insn (operands[0], scratch);
4622   DONE;
4623 }")
4624
4625 ;; Handle output reloads in DImode.
4626
4627 (define_expand "reload_outdi"
4628   [(set (match_operand:DI 0 "general_operand" "=b")
4629         (match_operand:DI 1 "se_register_operand" "b"))
4630    (clobber (match_operand:DI 2 "register_operand" "=&d"))]
4631   "TARGET_64BIT"
4632   "
4633 {
4634   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
4635     {
4636       emit_insn (gen_ashrdi3 (operands[2], operands[1], GEN_INT (32)));
4637       emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), operands[2]));
4638       emit_insn (gen_ashldi3 (operands[2], operands[1], GEN_INT (32)));
4639       emit_insn (gen_ashrdi3 (operands[2], operands[2], GEN_INT (32)));
4640       emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), operands[2]));
4641       DONE;
4642     }
4643   if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
4644     {
4645       if (GET_CODE (operands[0]) == MEM)
4646         {
4647           rtx scratch, memword, offword, hiword, loword;
4648
4649           scratch = gen_rtx (REG, SImode, REGNO (operands[2]));
4650           memword = change_address (operands[0], SImode, NULL_RTX);
4651           offword = change_address (adj_offsettable_operand (operands[0], 4),
4652                                     SImode, NULL_RTX);
4653           if (BYTES_BIG_ENDIAN)
4654             {
4655               hiword = memword;
4656               loword = offword;
4657             }
4658           else
4659             {
4660               hiword = offword;
4661               loword = memword;
4662             }
4663           emit_move_insn (scratch, gen_rtx (REG, SImode, 64));
4664           emit_move_insn (hiword, scratch);
4665           emit_move_insn (scratch, gen_rtx (REG, SImode, 65));
4666           emit_move_insn (loword, scratch);
4667         }
4668       else
4669         {
4670           emit_insn (gen_movdi (operands[2], gen_rtx (REG, DImode, 65)));
4671           emit_insn (gen_ashldi3 (operands[2], operands[2], GEN_INT (32)));
4672           emit_insn (gen_lshrdi3 (operands[2], operands[2], GEN_INT (32)));
4673           emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
4674           emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
4675           emit_insn (gen_iordi3 (operands[0], operands[0], operands[2]));
4676         }
4677       DONE;
4678     }
4679   /* This handles moves between a float register and HI/LO.  */
4680   emit_move_insn (operands[2], operands[1]);
4681   emit_move_insn (operands[0], operands[2]);
4682   DONE;
4683 }")
4684
4685 ;; 32-bit Integer moves
4686
4687 (define_split
4688   [(set (match_operand:SI 0 "register_operand" "")
4689         (match_operand:SI 1 "large_int" ""))]
4690   "!TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
4691   [(set (match_dup 0)
4692         (match_dup 2))
4693    (set (match_dup 0)
4694         (ior:SI (match_dup 0)
4695                 (match_dup 3)))]
4696   "
4697 {
4698   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff0000);
4699   operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0x0000ffff);
4700 }")
4701
4702 ;; Unlike most other insns, the move insns can't be split with
4703 ;; different predicates, because register spilling and other parts of
4704 ;; the compiler, have memoized the insn number already.
4705
4706 (define_expand "movsi"
4707   [(set (match_operand:SI 0 "nonimmediate_operand" "")
4708         (match_operand:SI 1 "general_operand" ""))]
4709   ""
4710   "
4711 {
4712   if (mips_split_addresses && mips_check_split (operands[1], SImode))
4713     {
4714       enum machine_mode mode = GET_MODE (operands[0]);
4715       rtx tem = ((reload_in_progress | reload_completed)
4716                  ? operands[0] : gen_reg_rtx (mode));
4717
4718       emit_insn (gen_rtx (SET, VOIDmode, tem,
4719                           gen_rtx (HIGH, mode, operands[1])));
4720
4721       operands[1] = gen_rtx (LO_SUM, mode, tem, operands[1]);
4722     }
4723
4724   /* If we are generating embedded PIC code, and we are referring to a
4725      symbol in the .text section, we must use an offset from the start
4726      of the function.  */
4727   if (TARGET_EMBEDDED_PIC
4728       && (GET_CODE (operands[1]) == LABEL_REF
4729           || (GET_CODE (operands[1]) == SYMBOL_REF
4730               && ! SYMBOL_REF_FLAG (operands[1]))))
4731     {
4732       rtx temp;
4733
4734       temp = embedded_pic_offset (operands[1]);
4735       temp = gen_rtx (PLUS, Pmode, embedded_pic_fnaddr_rtx,
4736                       force_reg (SImode, temp));
4737       emit_move_insn (operands[0], force_reg (SImode, temp));
4738       DONE;
4739     }
4740
4741   /* If operands[1] is a constant address invalid for pic, then we need to
4742      handle it just like LEGITIMIZE_ADDRESS does.  */
4743   if (flag_pic && pic_address_needs_scratch (operands[1]))
4744     {
4745       rtx temp = force_reg (SImode, XEXP (XEXP (operands[1], 0), 0));
4746       rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
4747
4748       if (! SMALL_INT (temp2))
4749         temp2 = force_reg (SImode, temp2);
4750
4751       emit_move_insn (operands[0], gen_rtx (PLUS, SImode, temp, temp2));
4752       DONE;
4753     }
4754
4755   /* On the mips16, we can handle a GP relative reference by adding in
4756      $gp.  We need to check the name to see whether this is a string
4757      constant.  */
4758   if (TARGET_MIPS16
4759       && register_operand (operands[0], SImode)
4760       && GET_CODE (operands[1]) == SYMBOL_REF
4761       && SYMBOL_REF_FLAG (operands[1]))
4762     {
4763       char *name = XSTR (operands[1], 0);
4764
4765       if (name[0] != '*'
4766           || strncmp (name + 1, LOCAL_LABEL_PREFIX,
4767                       sizeof LOCAL_LABEL_PREFIX - 1) != 0)
4768         {
4769           rtx base_reg;
4770
4771           if (reload_in_progress || reload_completed)
4772             {
4773               /* We need to reload this address.  In this case we
4774                  aren't going to have a chance to combine loading the
4775                  address with the load or store.  That means that we
4776                  can either generate a 2 byte move followed by a 4
4777                  byte addition, or a 2 byte load with a 4 byte entry
4778                  in the constant table.  Since the entry in the
4779                  constant table might be shared, we're better off, on
4780                  average, loading the address from the constant table.  */
4781               emit_move_insn (operands[0],
4782                               force_const_mem (SImode, operands[1]));
4783               DONE;
4784             }
4785
4786           base_reg = gen_reg_rtx (Pmode);
4787           emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
4788
4789           emit_move_insn (operands[0],
4790                           gen_rtx (PLUS, SImode, base_reg,
4791                                    mips16_gp_offset (operands[1])));
4792           DONE;
4793         }
4794     }
4795
4796   if ((reload_in_progress | reload_completed) == 0
4797       && !register_operand (operands[0], SImode)
4798       && !register_operand (operands[1], SImode)
4799       && (TARGET_MIPS16
4800           || GET_CODE (operands[1]) != CONST_INT
4801           || INTVAL (operands[1]) != 0))
4802     {
4803       rtx temp = force_reg (SImode, operands[1]);
4804       emit_move_insn (operands[0], temp);
4805       DONE;
4806     }
4807 }")
4808
4809 ;; For mips16, we need a special case to handle storing $31 into
4810 ;; memory, since we don't have a constraint to match $31.  This
4811 ;; instruction can be generated by save_restore_insns.
4812
4813 (define_insn ""
4814   [(set (match_operand:SI 0 "memory_operand" "R,m")
4815         (reg:SI 31))]
4816   "TARGET_MIPS16"
4817   "*
4818 {
4819   operands[1] = gen_rtx (REG, SImode, 31);
4820   return mips_move_1word (operands, insn, FALSE);
4821 }"
4822   [(set_attr "type"     "store")
4823    (set_attr "mode"     "SI")
4824    (set_attr "length"   "1,2")])
4825
4826 ;; The difference between these two is whether or not ints are allowed
4827 ;; in FP registers (off by default, use -mdebugh to enable).
4828
4829 (define_insn "movsi_internal1"
4830   [(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")
4831         (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"))]
4832   "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
4833    && (register_operand (operands[0], SImode)
4834        || register_operand (operands[1], SImode)
4835        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
4836   "* return mips_move_1word (operands, insn, FALSE);"
4837   [(set_attr "type"     "move,load,arith,arith,load,load,store,store,xfer,xfer,move,load,load,store,store,hilo,hilo,hilo,hilo")
4838    (set_attr "mode"     "SI")
4839    (set_attr "length"   "1,2,1,2,1,2,1,2,1,1,1,1,2,1,2,1,1,1,1")])
4840
4841 (define_insn "movsi_internal2"
4842   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*z,*x,*d,*x,*d")
4843         (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,J,*x,*d,*a"))]
4844   "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
4845    && (register_operand (operands[0], SImode)
4846        || register_operand (operands[1], SImode)
4847        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
4848   "* return mips_move_1word (operands, insn, FALSE);"
4849   [(set_attr "type"     "move,load,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo,hilo,hilo")
4850    (set_attr "mode"     "SI")
4851    (set_attr "length"   "1,2,1,2,1,2,1,2,1,1,1,1,1,1")])
4852
4853 ;; This is the mips16 movsi instruction.  We accept a small integer as
4854 ;; the source if the destination is a GP memory reference.  This is
4855 ;; because we want the combine pass to turn adding a GP reference to a
4856 ;; register into a direct GP reference, but the combine pass will pass
4857 ;; in the source as a constant if it finds an equivalent one.  If the
4858 ;; instruction is recognized, reload will force the constant back out
4859 ;; into a register.
4860
4861 (define_insn ""
4862   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,d,R,m,*d,*d")
4863         (match_operand:SI 1 "move_operand" "d,d,y,S,K,N,s,R,m,d,d,*x,*a"))]
4864   "TARGET_MIPS16
4865    && (register_operand (operands[0], SImode)
4866        || register_operand (operands[1], SImode)
4867        || (GET_CODE (operands[0]) == MEM
4868            && GET_CODE (XEXP (operands[0], 0)) == PLUS
4869            && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST
4870            && mips16_gp_offset_p (XEXP (XEXP (operands[0], 0), 1))
4871            && GET_CODE (operands[1]) == CONST_INT
4872            && (SMALL_INT (operands[1])
4873                || SMALL_INT_UNSIGNED (operands[1]))))"
4874   "* return mips_move_1word (operands, insn, FALSE);"
4875   [(set_attr "type"     "move,move,move,load,arith,arith,arith,load,load,store,store,hilo,hilo")
4876    (set_attr "mode"     "SI")
4877    (set_attr_alternative "length"
4878                 [(const_int 1)
4879                  (const_int 1)
4880                  (const_int 1)
4881                  (const_int 2)
4882                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
4883                                (const_int 1)
4884                                (const_int 2))
4885                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
4886                                (const_int 2)
4887                                (const_int 3))
4888                  (if_then_else (match_operand:VOID 1 "m16_usym8_4" "")
4889                                (const_int 1)
4890                                (const_int 2))
4891                  (const_int 1)
4892                  (const_int 2)
4893                  (const_int 1)
4894                  (const_int 2)
4895                  (const_int 1)
4896                  (const_int 1)])])
4897
4898 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
4899 ;; when the original load is a 4 byte instruction but the add and the
4900 ;; load are 2 2 byte instructions.
4901
4902 (define_split
4903   [(set (match_operand:SI 0 "register_operand" "")
4904         (mem:SI (plus:SI (match_dup 0)
4905                          (match_operand:SI 1 "const_int_operand" ""))))]
4906   "TARGET_MIPS16 && reload_completed
4907    && GET_CODE (operands[0]) == REG
4908    && M16_REG_P (REGNO (operands[0]))
4909    && GET_CODE (operands[1]) == CONST_INT
4910    && ((INTVAL (operands[1]) < 0
4911         && INTVAL (operands[1]) >= -0x80)
4912        || (INTVAL (operands[1]) >= 32 * 4
4913            && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
4914        || (INTVAL (operands[1]) >= 0
4915            && INTVAL (operands[1]) < 32 * 4
4916            && (INTVAL (operands[1]) & 3) != 0))"
4917   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4918    (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
4919   "
4920 {
4921   HOST_WIDE_INT val = INTVAL (operands[1]);
4922
4923   if (val < 0)
4924     operands[2] = GEN_INT (0);
4925   else if (val >= 32 * 4)
4926     {
4927       int off = val & 3;
4928
4929       operands[1] = GEN_INT (0x7c + off);
4930       operands[2] = GEN_INT (val - off - 0x7c);
4931     }
4932   else
4933     {
4934       int off = val & 3;
4935
4936       operands[1] = GEN_INT (off);
4937       operands[2] = GEN_INT (val - off);
4938     }
4939 }")
4940
4941 ;; On the mips16, we can split a load of certain constants into a load
4942 ;; and an add.  This turns a 4 byte instruction into 2 2 byte
4943 ;; instructions.
4944
4945 (define_split
4946   [(set (match_operand:SI 0 "register_operand" "")
4947         (match_operand:SI 1 "const_int_operand" ""))]
4948   "TARGET_MIPS16 && reload_completed
4949    && GET_CODE (operands[0]) == REG
4950    && M16_REG_P (REGNO (operands[0]))
4951    && GET_CODE (operands[1]) == CONST_INT
4952    && INTVAL (operands[1]) >= 0x100
4953    && INTVAL (operands[1]) <= 0xff + 0x7f"
4954   [(set (match_dup 0) (match_dup 1))
4955    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
4956   "
4957 {
4958   int val = INTVAL (operands[1]);
4959
4960   operands[1] = GEN_INT (0xff);
4961   operands[2] = GEN_INT (val - 0xff);
4962 }")
4963
4964 ;; On the mips16, we can split a load of a negative constant into a
4965 ;; load and a neg.  That's what mips_move_1word will generate anyhow.
4966
4967 (define_split
4968   [(set (match_operand:SI 0 "register_operand" "")
4969         (match_operand:SI 1 "const_int_operand" ""))]
4970   "TARGET_MIPS16 && reload_completed
4971    && GET_CODE (operands[0]) == REG
4972    && M16_REG_P (REGNO (operands[0]))
4973    && GET_CODE (operands[1]) == CONST_INT
4974    && INTVAL (operands[1]) < 0
4975    && INTVAL (operands[1]) > - 0x8000"
4976   [(set (match_dup 0) (match_dup 1))
4977    (set (match_dup 0) (neg:SI (match_dup 0)))]
4978   "
4979 {
4980   operands[1] = GEN_INT (- INTVAL (operands[1]));
4981 }")
4982
4983 ;; Reload HILO_REGNUM in SI mode.  This needs a scratch register in
4984 ;; order to set the sign bit correctly in the HI register.
4985
4986 (define_expand "reload_outsi"
4987   [(set (match_operand:SI 0 "general_operand" "=b")
4988         (match_operand:SI 1 "register_operand" "b"))
4989    (clobber (match_operand:SI 2 "register_operand" "=&d"))]
4990   "TARGET_64BIT || TARGET_MIPS16"
4991   "
4992 {
4993   if (TARGET_64BIT
4994       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
4995     {
4996       emit_insn (gen_movsi (gen_rtx (REG, SImode, 65), operands[1]));
4997       emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31)));
4998       emit_insn (gen_movsi (gen_rtx (REG, SImode, 64), operands[2]));
4999       DONE;
5000     }
5001   /* Use a mult to reload LO on mips16.  ??? This is hideous.  */
5002   if (TARGET_MIPS16
5003       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5004     {
5005       emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5006       /* This is gen_mulsi3_internal, but we need to fill in the
5007          scratch registers.  */
5008       emit_insn (gen_rtx (PARALLEL, VOIDmode,
5009                           gen_rtvec (3,
5010                                      gen_rtx (SET, VOIDmode,
5011                                               operands[0],
5012                                               gen_rtx (MULT, SImode,
5013                                                        operands[1],
5014                                                        operands[2])),
5015                                      gen_rtx (CLOBBER, VOIDmode,
5016                                               gen_rtx (REG, SImode, 64)),
5017                                      gen_rtx (CLOBBER, VOIDmode,
5018                                               gen_rtx (REG, SImode, 66)))));
5019       DONE;
5020     }
5021   /* FIXME: I don't know how to get a value into the HI register.  */
5022   if (GET_CODE (operands[0]) == REG && GP_REG_P (operands[0]))
5023     {
5024       emit_move_insn (operands[0], operands[1]);
5025       DONE;
5026     }
5027   /* This handles moves between a float register and HI/LO.  */
5028   emit_move_insn (operands[2], operands[1]);
5029   emit_move_insn (operands[0], operands[2]);
5030   DONE;
5031 }")
5032
5033 ;; Reload a value into HI or LO.  There is no mthi or mtlo on mips16,
5034 ;; so we use a mult.  ??? This is hideous, and we ought to figure out
5035 ;; something better.
5036
5037 (define_expand "reload_insi"
5038   [(set (match_operand:SI 0 "register_operand" "=b")
5039         (match_operand:SI 1 "register_operand" "b"))
5040    (clobber (match_operand:SI 2 "register_operand" "=&d"))]
5041   "TARGET_MIPS16"
5042   "
5043 {
5044   if (TARGET_MIPS16
5045       && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LO_REGNUM)
5046     {
5047       emit_insn (gen_movsi (operands[2], GEN_INT (1)));
5048       /* This is gen_mulsi3_internal, but we need to fill in the
5049          scratch registers.  */
5050       emit_insn (gen_rtx (PARALLEL, VOIDmode,
5051                           gen_rtvec (3,
5052                                      gen_rtx (SET, VOIDmode,
5053                                               operands[0],
5054                                               gen_rtx (MULT, SImode,
5055                                                        operands[1],
5056                                                        operands[2])),
5057                                      gen_rtx (CLOBBER, VOIDmode,
5058                                               gen_rtx (REG, SImode, 64)),
5059                                      gen_rtx (CLOBBER, VOIDmode,
5060                                               gen_rtx (REG, SImode, 66)))));
5061       DONE;
5062     }
5063   /* FIXME: I don't know how to get a value into the HI register.  */
5064   emit_move_insn (operands[0], operands[1]);
5065   DONE;
5066 }")
5067
5068 ;; This insn handles moving CCmode values.  It's really just a
5069 ;; slightly simplified copy of movsi_internal2, with additional cases
5070 ;; to move a condition register to a general register and to move
5071 ;; between the general registers and the floating point registers.
5072
5073 (define_insn "movcc"
5074   [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*d,*R,*m,*d,*f,*f,*f,*f,*R,*m")
5075         (match_operand:CC 1 "general_operand" "z,*d,*R,*m,*d,*d,*f,*d,*f,*R,*m,*f,*f"))]
5076   "mips_isa >= 4 && TARGET_HARD_FLOAT"
5077   "* return mips_move_1word (operands, insn, FALSE);"
5078   [(set_attr "type"     "move,move,load,load,store,store,xfer,xfer,move,load,load,store,store")
5079    (set_attr "mode"     "SI")
5080    (set_attr "length"   "2,1,1,2,1,2,1,1,1,1,2,1,2")])
5081
5082 ;; Reload condition code registers.  These need scratch registers.
5083
5084 (define_expand "reload_incc"
5085   [(set (match_operand:CC 0 "register_operand" "=z")
5086         (match_operand:CC 1 "general_operand" "z"))
5087    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
5088   "mips_isa >= 4 && TARGET_HARD_FLOAT"
5089   "
5090 {
5091   rtx source;
5092   rtx fp1, fp2;
5093
5094   /* This is called when are copying some value into a condition code
5095      register.  Operand 0 is the condition code register.  Operand 1
5096      is the source.  Operand 2 is a scratch register; we use TFmode
5097      because we actually need two floating point registers.  */
5098   if (! ST_REG_P (true_regnum (operands[0]))
5099       || ! FP_REG_P (true_regnum (operands[2])))
5100     abort ();
5101
5102   /* We need to get the source in SFmode so that the insn is
5103      recognized.  */
5104   if (GET_CODE (operands[1]) == MEM)
5105     source = change_address (operands[1], SFmode, NULL_RTX);
5106   else if (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG)
5107     source = gen_rtx (REG, SFmode, true_regnum (operands[1]));
5108   else
5109     source = operands[1];
5110
5111   fp1 = gen_rtx (REG, SFmode, REGNO (operands[2]));
5112   fp2 = gen_rtx (REG, SFmode, REGNO (operands[2]) + 1);
5113
5114   emit_insn (gen_move_insn (fp1, source));
5115   emit_insn (gen_move_insn (fp2, gen_rtx (REG, SFmode, 0)));
5116   emit_insn (gen_rtx (SET, VOIDmode, operands[0],
5117                       gen_rtx (LT, CCmode, fp2, fp1)));
5118
5119   DONE;
5120 }")
5121
5122 (define_expand "reload_outcc"
5123   [(set (match_operand:CC 0 "general_operand" "=z")
5124         (match_operand:CC 1 "register_operand" "z"))
5125    (clobber (match_operand:CC 2 "register_operand" "=&d"))]
5126   "mips_isa >= 4 && TARGET_HARD_FLOAT"
5127   "
5128 {
5129   /* This is called when we are copying a condition code register out
5130      to save it somewhere.  Operand 0 should be the location we are
5131      going to save it to.  Operand 1 should be the condition code
5132      register.  Operand 2 should be a scratch general purpose register
5133      created for us by reload.  The mips_secondary_reload_class
5134      function should have told reload that we don't need a scratch
5135      register if the destination is a general purpose register anyhow.  */
5136   if (ST_REG_P (true_regnum (operands[0]))
5137       || GP_REG_P (true_regnum (operands[0]))
5138       || ! ST_REG_P (true_regnum (operands[1]))
5139       || ! GP_REG_P (true_regnum (operands[2])))
5140     abort ();
5141
5142   /* All we have to do is copy the value from the condition code to
5143      the data register, which movcc can handle, and then store the
5144      value into the real final destination.  */
5145   emit_insn (gen_move_insn (operands[2], operands[1]));
5146   emit_insn (gen_move_insn (operands[0], operands[2]));
5147
5148   DONE;
5149 }")
5150
5151 ;; MIPS4 supports loading and storing a floating point register from
5152 ;; the sum of two general registers.  We use two versions for each of
5153 ;; these four instructions: one where the two general registers are
5154 ;; SImode, and one where they are DImode.  This is because general
5155 ;; registers will be in SImode when they hold 32 bit values, but,
5156 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
5157 ;; instructions will still work correctly.
5158
5159 ;; ??? Perhaps it would be better to support these instructions by
5160 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends.  However, since
5161 ;; these instructions can only be used to load and store floating
5162 ;; point registers, that would probably cause trouble in reload.
5163
5164 (define_insn ""
5165   [(set (match_operand:SF 0 "register_operand" "=f")
5166         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5167                          (match_operand:SI 2 "register_operand" "d"))))]
5168   "mips_isa >= 4 && TARGET_HARD_FLOAT"
5169   "lwxc1\\t%0,%1(%2)"
5170   [(set_attr "type"     "load")
5171    (set_attr "mode"     "SF")
5172    (set_attr "length"   "1")])
5173
5174 (define_insn ""
5175   [(set (match_operand:SF 0 "register_operand" "=f")
5176         (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5177                          (match_operand:DI 2 "se_register_operand" "d"))))]
5178   "mips_isa >= 4 && TARGET_HARD_FLOAT"
5179   "lwxc1\\t%0,%1(%2)"
5180   [(set_attr "type"     "load")
5181    (set_attr "mode"     "SF")
5182    (set_attr "length"   "1")])
5183
5184 (define_insn ""
5185   [(set (match_operand:DF 0 "register_operand" "=f")
5186         (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5187                          (match_operand:SI 2 "register_operand" "d"))))]
5188   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5189   "ldxc1\\t%0,%1(%2)"
5190   [(set_attr "type"     "load")
5191    (set_attr "mode"     "DF")
5192    (set_attr "length"   "1")])
5193
5194 (define_insn ""
5195   [(set (match_operand:DF 0 "register_operand" "=f")
5196         (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5197                          (match_operand:DI 2 "se_register_operand" "d"))))]
5198   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5199   "ldxc1\\t%0,%1(%2)"
5200   [(set_attr "type"     "load")
5201    (set_attr "mode"     "DF")
5202    (set_attr "length"   "1")])
5203
5204 (define_insn ""
5205   [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
5206                          (match_operand:SI 2 "register_operand" "d")))
5207         (match_operand:SF 0 "register_operand" "=f"))]
5208   "mips_isa >= 4 && TARGET_HARD_FLOAT"
5209   "swxc1\\t%0,%1(%2)"
5210   [(set_attr "type"     "store")
5211    (set_attr "mode"     "SF")
5212    (set_attr "length"   "1")])
5213
5214 (define_insn ""
5215   [(set (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5216                          (match_operand:DI 2 "se_register_operand" "d")))
5217         (match_operand:SF 0 "register_operand" "=f"))]
5218   "mips_isa >= 4 && TARGET_HARD_FLOAT"
5219   "swxc1\\t%0,%1(%2)"
5220   [(set_attr "type"     "store")
5221    (set_attr "mode"     "SF")
5222    (set_attr "length"   "1")])
5223
5224 (define_insn ""
5225   [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
5226                          (match_operand:SI 2 "register_operand" "d")))
5227         (match_operand:DF 0 "register_operand" "=f"))]
5228   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5229   "sdxc1\\t%0,%1(%2)"
5230   [(set_attr "type"     "store")
5231    (set_attr "mode"     "DF")
5232    (set_attr "length"   "1")])
5233
5234 (define_insn ""
5235   [(set (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
5236                          (match_operand:DI 2 "se_register_operand" "d")))
5237         (match_operand:DF 0 "register_operand" "=f"))]
5238   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5239   "sdxc1\\t%0,%1(%2)"
5240   [(set_attr "type"     "store")
5241    (set_attr "mode"     "DF")
5242    (set_attr "length"   "1")])
5243
5244 ;; 16-bit Integer moves
5245
5246 ;; Unlike most other insns, the move insns can't be split with
5247 ;; different predicates, because register spilling and other parts of
5248 ;; the compiler, have memoized the insn number already.
5249 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
5250
5251 (define_expand "movhi"
5252   [(set (match_operand:HI 0 "nonimmediate_operand" "")
5253         (match_operand:HI 1 "general_operand" ""))]
5254   ""
5255   "
5256 {
5257   if ((reload_in_progress | reload_completed) == 0
5258       && !register_operand (operands[0], HImode)
5259       && !register_operand (operands[1], HImode)
5260       && (TARGET_MIPS16
5261           || (GET_CODE (operands[1]) != CONST_INT
5262           || INTVAL (operands[1]) != 0)))
5263     {
5264       rtx temp = force_reg (HImode, operands[1]);
5265       emit_move_insn (operands[0], temp);
5266       DONE;
5267     }
5268 }")
5269
5270 ;; The difference between these two is whether or not ints are allowed
5271 ;; in FP registers (off by default, use -mdebugh to enable).
5272
5273 (define_insn "movhi_internal1"
5274   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f*z,*x,*d")
5275         (match_operand:HI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
5276   "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5277    && (register_operand (operands[0], HImode)
5278        || register_operand (operands[1], HImode)
5279        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5280   "* return mips_move_1word (operands, insn, TRUE);"
5281   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
5282    (set_attr "mode"     "HI")
5283    (set_attr "length"   "1,1,1,2,1,2,1,1,1,1,1")])
5284
5285 (define_insn "movhi_internal2"
5286   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
5287         (match_operand:HI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
5288   "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5289    && (register_operand (operands[0], HImode)
5290        || register_operand (operands[1], HImode)
5291        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5292   "* return mips_move_1word (operands, insn, TRUE);"
5293   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
5294    (set_attr "mode"     "HI")
5295    (set_attr "length"   "1,1,1,2,1,2,1,1,1,1")])
5296
5297 (define_insn ""
5298   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
5299         (match_operand:HI 1 "general_operand"      "d,d,y,K,N,R,m,d,d,*x"))]
5300   "TARGET_MIPS16
5301    && (register_operand (operands[0], HImode)
5302        || register_operand (operands[1], HImode))"
5303   "* return mips_move_1word (operands, insn, TRUE);"
5304   [(set_attr "type"     "move,move,move,arith,arith,load,load,store,store,hilo")
5305    (set_attr "mode"     "HI")
5306    (set_attr_alternative "length"
5307                 [(const_int 1)
5308                  (const_int 1)
5309                  (const_int 1)
5310                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5311                                (const_int 1)
5312                                (const_int 2))
5313                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5314                                (const_int 2)
5315                                (const_int 3))
5316                  (const_int 1)
5317                  (const_int 2)
5318                  (const_int 1)
5319                  (const_int 2)
5320                  (const_int 1)])])
5321
5322
5323 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
5324 ;; when the original load is a 4 byte instruction but the add and the
5325 ;; load are 2 2 byte instructions.
5326
5327 (define_split
5328   [(set (match_operand:HI 0 "register_operand" "")
5329         (mem:SI (plus:SI (match_dup 0)
5330                          (match_operand:SI 1 "const_int_operand" ""))))]
5331   "TARGET_MIPS16 && reload_completed
5332    && GET_CODE (operands[0]) == REG
5333    && M16_REG_P (REGNO (operands[0]))
5334    && GET_CODE (operands[1]) == CONST_INT
5335    && ((INTVAL (operands[1]) < 0
5336         && INTVAL (operands[1]) >= -0x80)
5337        || (INTVAL (operands[1]) >= 32 * 2
5338            && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
5339        || (INTVAL (operands[1]) >= 0
5340            && INTVAL (operands[1]) < 32 * 2
5341            && (INTVAL (operands[1]) & 1) != 0))"
5342   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5343    (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
5344   "
5345 {
5346   HOST_WIDE_INT val = INTVAL (operands[1]);
5347
5348   if (val < 0)
5349     operands[2] = GEN_INT (0);
5350   else if (val >= 32 * 2)
5351     {
5352       int off = val & 1;
5353
5354       operands[1] = GEN_INT (0x7e + off);
5355       operands[2] = GEN_INT (val - off - 0x7e);
5356     }
5357   else
5358     {
5359       int off = val & 1;
5360
5361       operands[1] = GEN_INT (off);
5362       operands[2] = GEN_INT (val - off);
5363     }
5364 }")
5365
5366 ;; 8-bit Integer moves
5367
5368 ;; Unlike most other insns, the move insns can't be split with
5369 ;; different predicates, because register spilling and other parts of
5370 ;; the compiler, have memoized the insn number already.
5371 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
5372
5373 (define_expand "movqi"
5374   [(set (match_operand:QI 0 "nonimmediate_operand" "")
5375         (match_operand:QI 1 "general_operand" ""))]
5376   ""
5377   "
5378 {
5379   if ((reload_in_progress | reload_completed) == 0
5380       && !register_operand (operands[0], QImode)
5381       && !register_operand (operands[1], QImode)
5382       && (TARGET_MIPS16
5383           || (GET_CODE (operands[1]) != CONST_INT
5384           || INTVAL (operands[1]) != 0)))
5385     {
5386       rtx temp = force_reg (QImode, operands[1]);
5387       emit_move_insn (operands[0], temp);
5388       DONE;
5389     }
5390 }")
5391
5392 ;; The difference between these two is whether or not ints are allowed
5393 ;; in FP registers (off by default, use -mdebugh to enable).
5394
5395 (define_insn "movqi_internal1"
5396   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
5397         (match_operand:QI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
5398   "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5399    && (register_operand (operands[0], QImode)
5400        || register_operand (operands[1], QImode)
5401        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5402   "* return mips_move_1word (operands, insn, TRUE);"
5403   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
5404    (set_attr "mode"     "QI")
5405    (set_attr "length"   "1,1,1,2,1,2,1,1,1,1,1")])
5406
5407 (define_insn "movqi_internal2"
5408   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
5409         (match_operand:QI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
5410   "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
5411    && (register_operand (operands[0], QImode)
5412        || register_operand (operands[1], QImode)
5413        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
5414   "* return mips_move_1word (operands, insn, TRUE);"
5415   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
5416    (set_attr "mode"     "QI")
5417    (set_attr "length"   "1,1,1,2,1,2,1,1,1,1")])
5418
5419 (define_insn ""
5420   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
5421         (match_operand:QI 1 "general_operand"      "d,d,y,K,N,R,m,d,d,*x"))]
5422   "TARGET_MIPS16
5423    && (register_operand (operands[0], QImode)
5424        || register_operand (operands[1], QImode))"
5425   "* return mips_move_1word (operands, insn, TRUE);"
5426   [(set_attr "type"     "move,move,move,arith,arith,load,load,store,store,hilo")
5427    (set_attr "mode"     "QI")
5428    (set_attr_alternative "length"
5429                 [(const_int 1)
5430                  (const_int 1)
5431                  (const_int 1)
5432                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
5433                                (const_int 1)
5434                                (const_int 2))
5435                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
5436                                (const_int 2)
5437                                (const_int 3))
5438                  (const_int 1)
5439                  (const_int 2)
5440                  (const_int 1)
5441                  (const_int 2)
5442                  (const_int 1)])])
5443
5444
5445 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
5446 ;; when the original load is a 4 byte instruction but the add and the
5447 ;; load are 2 2 byte instructions.
5448
5449 (define_split
5450   [(set (match_operand:QI 0 "register_operand" "")
5451         (mem:QI (plus:SI (match_dup 0)
5452                          (match_operand:SI 1 "const_int_operand" ""))))]
5453   "TARGET_MIPS16 && reload_completed
5454    && GET_CODE (operands[0]) == REG
5455    && M16_REG_P (REGNO (operands[0]))
5456    && GET_CODE (operands[1]) == CONST_INT
5457    && ((INTVAL (operands[1]) < 0
5458         && INTVAL (operands[1]) >= -0x80)
5459        || (INTVAL (operands[1]) >= 32
5460            && INTVAL (operands[1]) <= 31 + 0x7f))"
5461   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
5462    (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
5463   "
5464 {
5465   HOST_WIDE_INT val = INTVAL (operands[1]);
5466
5467   if (val < 0)
5468     operands[2] = GEN_INT (0);
5469   else
5470     {
5471       operands[1] = GEN_INT (0x7f);
5472       operands[2] = GEN_INT (val - 0x7f);
5473     }
5474 }")
5475
5476 ;; 32-bit floating point moves
5477
5478 (define_expand "movsf"
5479   [(set (match_operand:SF 0 "nonimmediate_operand" "")
5480         (match_operand:SF 1 "general_operand" ""))]
5481   ""
5482   "
5483 {
5484   if ((reload_in_progress | reload_completed) == 0
5485       && !register_operand (operands[0], SFmode)
5486       && !register_operand (operands[1], SFmode)
5487       && (TARGET_MIPS16
5488           || (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
5489               && operands[1] != CONST0_RTX (SFmode)))
5490     {
5491       rtx temp = force_reg (SFmode, operands[1]);
5492       emit_move_insn (operands[0], temp);
5493       DONE;
5494     }
5495 }")
5496
5497 (define_insn "movsf_internal1"
5498   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m")
5499         (match_operand:SF 1 "general_operand" "f,G,R,Fm,fG,fG,*d,*f,*G*d,*R,*F*m,*d,*d"))]
5500   "TARGET_HARD_FLOAT
5501    && (register_operand (operands[0], SFmode)
5502        || register_operand (operands[1], SFmode)
5503        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5504        || operands[1] == CONST0_RTX (SFmode))"
5505   "* return mips_move_1word (operands, insn, FALSE);"
5506   [(set_attr "type"     "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store")
5507    (set_attr "mode"     "SF")
5508    (set_attr "length"   "1,1,1,2,1,2,1,1,1,1,2,1,2")])
5509
5510
5511 (define_insn "movsf_internal2"
5512   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,R,m")
5513         (match_operand:SF 1 "general_operand" "      Gd,R,Fm,d,d"))]
5514   "TARGET_SOFT_FLOAT && !TARGET_MIPS16
5515    && (register_operand (operands[0], SFmode)
5516        || register_operand (operands[1], SFmode)
5517        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5518        || operands[1] == CONST0_RTX (SFmode))"
5519   "* return mips_move_1word (operands, insn, FALSE);"
5520   [(set_attr "type"     "move,load,load,store,store")
5521    (set_attr "mode"     "SF")
5522    (set_attr "length"   "1,1,2,1,2")])
5523
5524 (define_insn ""
5525   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,d,R,m")
5526         (match_operand:SF 1 "general_operand"      "d,d,y,R,Fm,d,d"))]
5527   "TARGET_MIPS16
5528    && (register_operand (operands[0], SFmode)
5529        || register_operand (operands[1], SFmode))"
5530   "* return mips_move_1word (operands, insn, FALSE);"
5531   [(set_attr "type"     "move,move,move,load,load,store,store")
5532    (set_attr "mode"     "SF")
5533    (set_attr "length"   "1,1,1,1,2,1,2")])
5534
5535
5536 ;; 64-bit floating point moves
5537
5538 (define_expand "movdf"
5539   [(set (match_operand:DF 0 "nonimmediate_operand" "")
5540         (match_operand:DF 1 "general_operand" ""))]
5541   ""
5542   "
5543 {
5544   if ((reload_in_progress | reload_completed) == 0
5545       && !register_operand (operands[0], DFmode)
5546       && !register_operand (operands[1], DFmode)
5547       && (TARGET_MIPS16
5548           || (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
5549               && operands[1] != CONST0_RTX (DFmode)))
5550     {
5551       rtx temp = force_reg (DFmode, operands[1]);
5552       emit_move_insn (operands[0], temp);
5553       DONE;
5554     }
5555 }")
5556
5557 (define_insn "movdf_internal1"
5558   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,To,f,*f,*d,*d,*d,*d,*R,*T")
5559         (match_operand:DF 1 "general_operand" "f,R,To,fG,fG,F,*d,*f,*d*G,*R,*T*F,*d,*d"))]
5560   "TARGET_HARD_FLOAT && !(TARGET_FLOAT64 && !TARGET_64BIT)
5561    && TARGET_DOUBLE_FLOAT
5562    && (register_operand (operands[0], DFmode)
5563        || register_operand (operands[1], DFmode)
5564        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5565        || operands[1] == CONST0_RTX (DFmode))"
5566   "* return mips_move_2words (operands, insn); "
5567   [(set_attr "type"     "move,load,load,store,store,load,xfer,xfer,move,load,load,store,store")
5568    (set_attr "mode"     "DF")
5569    (set_attr "length"   "1,2,4,2,4,4,2,2,2,2,4,2,4")])
5570
5571 (define_insn "movdf_internal1a"
5572   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,R,R,To,To,f,*d,*d,*d,*To,*R")
5573         (match_operand:DF 1 "general_operand"      " f,To,f,G,f,G,F,*F,*To,*R,*d,*d"))]
5574   "TARGET_HARD_FLOAT && (TARGET_FLOAT64 && !TARGET_64BIT)
5575    && TARGET_DOUBLE_FLOAT
5576    && (register_operand (operands[0], DFmode)
5577        || register_operand (operands[1], DFmode))
5578        || (GET_CODE (operands [0]) == MEM
5579            && ((GET_CODE (operands[1]) == CONST_INT
5580                 && INTVAL (operands[1]) == 0)
5581                || operands[1] == CONST0_RTX (DFmode)))"
5582   "* return mips_move_2words (operands, insn); "
5583   [(set_attr "type"     "move,load,store,store,store,store,load,load,load,load,store,store")
5584    (set_attr "mode"     "DF")
5585    (set_attr "length"   "1,2,1,1,2,2,2,2,2,1,2,1")])
5586
5587 (define_insn "movdf_internal2"
5588   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,R,To")
5589         (match_operand:DF 1 "general_operand" "dG,R,ToF,d,d"))]
5590   "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
5591    && (register_operand (operands[0], DFmode)
5592        || register_operand (operands[1], DFmode)
5593        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
5594        || operands[1] == CONST0_RTX (DFmode))"
5595   "* return mips_move_2words (operands, insn); "
5596   [(set_attr "type"     "move,load,load,store,store")
5597    (set_attr "mode"     "DF")
5598    (set_attr "length"   "2,2,4,2,4")])
5599
5600 (define_insn ""
5601   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,d,R,To")
5602         (match_operand:DF 1 "general_operand" "d,d,y,R,ToF,d,d"))]
5603   "TARGET_MIPS16
5604    && (register_operand (operands[0], DFmode)
5605        || register_operand (operands[1], DFmode))"
5606   "* return mips_move_2words (operands, insn);"
5607   [(set_attr "type"     "move,move,move,load,load,store,store")
5608    (set_attr "mode"     "DF")
5609    (set_attr "length"   "2,2,2,2,4,2,4")])
5610
5611 (define_split
5612   [(set (match_operand:DF 0 "register_operand" "")
5613         (match_operand:DF 1 "register_operand" ""))]
5614   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
5615    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
5616    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
5617   [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
5618    (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
5619   "")
5620
5621 ;; Instructions to load the global pointer register.
5622 ;; This is volatile to make sure that the scheduler won't move any symbol_ref
5623 ;; uses in front of it.  All symbol_refs implicitly use the gp reg.
5624
5625 (define_insn "loadgp"
5626   [(set (reg:DI 28)
5627         (unspec_volatile:DI [(match_operand:DI 0 "address_operand" "")] 2))
5628    (clobber (reg:DI 1))]
5629   ""
5630   "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%a0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%a0)))\\n\\tdaddu\\t$gp,$1,$25%]"
5631   [(set_attr "type"     "move")
5632    (set_attr "mode"     "DI")
5633    (set_attr "length"   "3")])
5634 \f
5635 ;; Block moves, see mips.c for more details.
5636 ;; Argument 0 is the destination
5637 ;; Argument 1 is the source
5638 ;; Argument 2 is the length
5639 ;; Argument 3 is the alignment
5640
5641 (define_expand "movstrsi"
5642   [(parallel [(set (match_operand:BLK 0 "general_operand" "")
5643                    (match_operand:BLK 1 "general_operand" ""))
5644               (use (match_operand:SI 2 "arith32_operand" ""))
5645               (use (match_operand:SI 3 "immediate_operand" ""))])]
5646   "!TARGET_MIPS16"
5647   "
5648 {
5649   if (operands[0])              /* avoid unused code messages */
5650     {
5651       expand_block_move (operands);
5652       DONE;
5653     }
5654 }")
5655
5656 ;; Insn generated by block moves
5657
5658 (define_insn "movstrsi_internal"
5659   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
5660         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
5661    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
5662    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
5663    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
5664    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
5665    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
5666    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
5667    (use (const_int 0))]                                 ;; normal block move
5668   ""
5669   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
5670   [(set_attr "type"     "store")
5671    (set_attr "mode"     "none")
5672    (set_attr "length"   "20")])
5673
5674 ;; We need mips16 versions, because an offset from the stack pointer
5675 ;; is not offsettable, since the stack pointer can only handle 4 and 8
5676 ;; byte loads.
5677
5678 (define_insn ""
5679   [(set (match_operand:BLK 0 "memory_operand" "=d")     ;; destination
5680         (match_operand:BLK 1 "memory_operand" "d"))     ;; source
5681    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
5682    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
5683    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
5684    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
5685    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
5686    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
5687    (use (const_int 0))]                                 ;; normal block move
5688   "TARGET_MIPS16"
5689   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
5690   [(set_attr "type"     "multi")
5691    (set_attr "mode"     "none")
5692    (set_attr "length"   "20")])
5693
5694 (define_insn ""
5695   [(set (match_operand:BLK 0 "memory_operand" "=d")     ;; destination
5696         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
5697    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
5698    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
5699    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
5700    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
5701    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
5702    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
5703    (use (const_int 0))]                                 ;; normal block move
5704   "TARGET_MIPS16"
5705   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
5706   [(set_attr "type"     "multi")
5707    (set_attr "mode"     "none")
5708    (set_attr "length"   "20")])
5709
5710 (define_insn ""
5711   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
5712         (match_operand:BLK 1 "memory_operand" "d"))     ;; source
5713    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
5714    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
5715    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
5716    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
5717    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
5718    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
5719    (use (const_int 0))]                                 ;; normal block move
5720   "TARGET_MIPS16"
5721   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
5722   [(set_attr "type"     "multi")
5723    (set_attr "mode"     "none")
5724    (set_attr "length"   "20")])
5725
5726 ;; Split a block move into 2 parts, the first part is everything
5727 ;; except for the last move, and the second part is just the last
5728 ;; store, which is exactly 1 instruction (ie, not a usw), so it can
5729 ;; fill a delay slot.  This also prevents a bug in delayed branches
5730 ;; from showing up, which reuses one of the registers in our clobbers.
5731
5732 (define_split
5733   [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
5734         (mem:BLK (match_operand:SI 1 "register_operand" "")))
5735    (clobber (match_operand:SI 4 "register_operand" ""))
5736    (clobber (match_operand:SI 5 "register_operand" ""))
5737    (clobber (match_operand:SI 6 "register_operand" ""))
5738    (clobber (match_operand:SI 7 "register_operand" ""))
5739    (use (match_operand:SI 2 "small_int" ""))
5740    (use (match_operand:SI 3 "small_int" ""))
5741    (use (const_int 0))]
5742
5743   "reload_completed && !TARGET_DEBUG_D_MODE && INTVAL (operands[2]) > 0"
5744
5745   ;; All but the last move
5746   [(parallel [(set (mem:BLK (match_dup 0))
5747                    (mem:BLK (match_dup 1)))
5748               (clobber (match_dup 4))
5749               (clobber (match_dup 5))
5750               (clobber (match_dup 6))
5751               (clobber (match_dup 7))
5752               (use (match_dup 2))
5753               (use (match_dup 3))
5754               (use (const_int 1))])
5755
5756    ;; The last store, so it can fill a delay slot
5757    (parallel [(set (mem:BLK (match_dup 0))
5758                    (mem:BLK (match_dup 1)))
5759               (clobber (match_dup 4))
5760               (clobber (match_dup 5))
5761               (clobber (match_dup 6))
5762               (clobber (match_dup 7))
5763               (use (match_dup 2))
5764               (use (match_dup 3))
5765               (use (const_int 2))])]
5766
5767   "")
5768
5769 (define_insn "movstrsi_internal2"
5770   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
5771         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
5772    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
5773    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
5774    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
5775    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
5776    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
5777    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
5778    (use (const_int 1))]                                 ;; all but last store
5779   ""
5780   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
5781   [(set_attr "type"     "store")
5782    (set_attr "mode"     "none")
5783    (set_attr "length"   "20")])
5784
5785 (define_insn ""
5786   [(set (match_operand:BLK 0 "memory_operand" "=d")     ;; destination
5787         (match_operand:BLK 1 "memory_operand" "d"))     ;; source
5788    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
5789    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
5790    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
5791    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
5792    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
5793    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
5794    (use (const_int 1))]                                 ;; all but last store
5795   "TARGET_MIPS16"
5796   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
5797   [(set_attr "type"     "multi")
5798    (set_attr "mode"     "none")
5799    (set_attr "length"   "20")])
5800
5801 (define_insn "movstrsi_internal3"
5802   [(set (match_operand:BLK 0 "memory_operand" "=Ro")    ;; destination
5803         (match_operand:BLK 1 "memory_operand" "Ro"))    ;; source
5804    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
5805    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
5806    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
5807    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
5808    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
5809    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
5810    (use (const_int 2))]                                 ;; just last store of block move
5811   ""
5812   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
5813   [(set_attr "type"     "store")
5814    (set_attr "mode"     "none")
5815    (set_attr "length"   "1")])
5816
5817 (define_insn ""
5818   [(set (match_operand:BLK 0 "memory_operand" "=d")     ;; destination
5819         (match_operand:BLK 1 "memory_operand" "d"))     ;; source
5820    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
5821    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
5822    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
5823    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
5824    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
5825    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
5826    (use (const_int 2))]                                 ;; just last store of block move
5827   "TARGET_MIPS16"
5828   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
5829   [(set_attr "type"     "store")
5830    (set_attr "mode"     "none")
5831    (set_attr "length"   "1")])
5832
5833 \f
5834 ;;
5835 ;;  ....................
5836 ;;
5837 ;;      SHIFTS
5838 ;;
5839 ;;  ....................
5840
5841 ;; Many of these instructions uses trivial define_expands, because we
5842 ;; want to use a different set of constraints when TARGET_MIPS16.
5843
5844 (define_expand "ashlsi3"
5845   [(set (match_operand:SI 0 "register_operand" "=d")
5846         (ashift:SI (match_operand:SI 1 "register_operand" "d")
5847                    (match_operand:SI 2 "arith_operand" "dI")))]
5848   ""
5849   "
5850 {
5851   /* On the mips16, a shift of more than 8 is a four byte instruction,
5852      so, for a shift between 8 and 16, it is just as fast to do two
5853      shifts of 8 or less.  If there is a lot of shifting going on, we
5854      may win in CSE.  Otherwise combine will put the shifts back
5855      together again.  This can be called by function_arg, so we must
5856      be careful not to allocate a new register if we've reached the
5857      reload pass.  */
5858   if (TARGET_MIPS16
5859       && optimize
5860       && GET_CODE (operands[2]) == CONST_INT
5861       && INTVAL (operands[2]) > 8
5862       && INTVAL (operands[2]) <= 16
5863       && ! reload_in_progress
5864       && ! reload_completed)
5865     {
5866       rtx temp = gen_reg_rtx (SImode);
5867
5868       emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
5869       emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
5870                                         GEN_INT (INTVAL (operands[2]) - 8)));
5871       DONE;
5872     }
5873 }")
5874
5875 (define_insn "ashlsi3_internal1"
5876   [(set (match_operand:SI 0 "register_operand" "=d")
5877         (ashift:SI (match_operand:SI 1 "register_operand" "d")
5878                    (match_operand:SI 2 "arith_operand" "dI")))]
5879   "!TARGET_MIPS16"
5880   "*
5881 {
5882   if (GET_CODE (operands[2]) == CONST_INT)
5883     operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
5884
5885   return \"sll\\t%0,%1,%2\";
5886 }"
5887   [(set_attr "type"     "arith")
5888    (set_attr "mode"     "SI")
5889    (set_attr "length"   "1")])
5890
5891 (define_insn "ashlsi3_internal2"
5892   [(set (match_operand:SI 0 "register_operand" "=d,d")
5893         (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
5894                    (match_operand:SI 2 "arith_operand" "d,I")))]
5895   "TARGET_MIPS16"
5896   "*
5897 {
5898   if (which_alternative == 0)
5899     return \"sll\\t%0,%2\";
5900
5901   if (GET_CODE (operands[2]) == CONST_INT)
5902     operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
5903
5904   return \"sll\\t%0,%1,%2\";
5905 }"
5906   [(set_attr "type"     "arith")
5907    (set_attr "mode"     "SI")
5908    (set_attr_alternative "length"
5909                 [(const_int 1)
5910                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
5911                                (const_int 1)
5912                                (const_int 2))])])
5913
5914 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5915
5916 (define_split
5917   [(set (match_operand:SI 0 "register_operand" "")
5918         (ashift:SI (match_operand:SI 1 "register_operand" "")
5919                    (match_operand:SI 2 "const_int_operand" "")))]
5920   "TARGET_MIPS16
5921    && reload_completed
5922    && GET_CODE (operands[2]) == CONST_INT
5923    && INTVAL (operands[2]) > 8
5924    && INTVAL (operands[2]) <= 16"
5925   [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
5926    (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
5927 "
5928 {
5929   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
5930 }")
5931
5932 (define_expand "ashldi3"
5933   [(parallel [(set (match_operand:DI 0 "register_operand" "")
5934                    (ashift:DI (match_operand:DI 1 "se_register_operand" "")
5935                               (match_operand:SI 2 "arith_operand" "")))
5936               (clobber (match_dup  3))])]
5937   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
5938   "
5939 {
5940   if (TARGET_64BIT)
5941     {
5942       /* On the mips16, a shift of more than 8 is a four byte
5943          instruction, so, for a shift between 8 and 16, it is just as
5944          fast to do two shifts of 8 or less.  If there is a lot of
5945          shifting going on, we may win in CSE.  Otherwise combine will
5946          put the shifts back together again.  This can be called by
5947          function_arg, so we must be careful not to allocate a new
5948          register if we've reached the reload pass.  */
5949       if (TARGET_MIPS16
5950           && optimize
5951           && GET_CODE (operands[2]) == CONST_INT
5952           && INTVAL (operands[2]) > 8
5953           && INTVAL (operands[2]) <= 16
5954           && ! reload_in_progress
5955           && ! reload_completed)
5956         {
5957           rtx temp = gen_reg_rtx (DImode);
5958
5959           emit_insn (gen_ashldi3_internal4 (temp, operands[1], GEN_INT (8)));
5960           emit_insn (gen_ashldi3_internal4 (operands[0], temp,
5961                                             GEN_INT (INTVAL (operands[2]) - 8)));
5962           DONE;
5963         }
5964
5965       emit_insn (gen_ashldi3_internal4 (operands[0], operands[1],
5966                                         operands[2]));
5967       DONE;
5968     }
5969
5970   operands[3] = gen_reg_rtx (SImode);
5971 }")
5972
5973
5974 (define_insn "ashldi3_internal"
5975   [(set (match_operand:DI 0 "register_operand" "=&d")
5976         (ashift:DI (match_operand:DI 1 "register_operand" "d")
5977                    (match_operand:SI 2 "register_operand" "d")))
5978    (clobber (match_operand:SI 3 "register_operand" "=d"))]
5979   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
5980   "* 
5981 {
5982   operands[4] = const0_rtx;
5983   dslots_jump_total += 3;
5984   dslots_jump_filled += 2;
5985
5986   return \"sll\\t%3,%2,26\\n\\
5987 \\tbgez\\t%3,1f\\n\\
5988 \\tsll\\t%M0,%L1,%2\\n\\
5989 \\t%(b\\t3f\\n\\
5990 \\tmove\\t%L0,%z4%)\\n\\
5991 \\n\\
5992 1:\\n\\
5993 \\t%(beq\\t%3,%z4,2f\\n\\
5994 \\tsll\\t%M0,%M1,%2%)\\n\\
5995 \\n\\
5996 \\tsubu\\t%3,%z4,%2\\n\\
5997 \\tsrl\\t%3,%L1,%3\\n\\
5998 \\tor\\t%M0,%M0,%3\\n\\
5999 2:\\n\\
6000 \\tsll\\t%L0,%L1,%2\\n\\
6001 3:\";
6002 }"
6003   [(set_attr "type"     "darith")
6004    (set_attr "mode"     "SI")
6005    (set_attr "length"   "12")])
6006
6007
6008 (define_insn "ashldi3_internal2"
6009   [(set (match_operand:DI 0 "register_operand" "=d")
6010         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6011                    (match_operand:SI 2 "small_int" "IJK")))
6012    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6013   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6014    && (INTVAL (operands[2]) & 32) != 0"
6015   "*
6016 {
6017   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
6018   operands[4] = const0_rtx;
6019   return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\";
6020 }"
6021   [(set_attr "type"     "darith")
6022    (set_attr "mode"     "DI")
6023    (set_attr "length"   "2")])
6024
6025
6026 (define_split
6027   [(set (match_operand:DI 0 "register_operand" "")
6028         (ashift:DI (match_operand:DI 1 "register_operand" "")
6029                    (match_operand:SI 2 "small_int" "")))
6030    (clobber (match_operand:SI 3 "register_operand" ""))]
6031   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6032    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6033    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6034    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6035    && (INTVAL (operands[2]) & 32) != 0"
6036
6037   [(set (subreg:SI (match_dup 0) 1) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
6038    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
6039
6040   "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
6041
6042
6043 (define_split
6044   [(set (match_operand:DI 0 "register_operand" "")
6045         (ashift:DI (match_operand:DI 1 "register_operand" "")
6046                    (match_operand:SI 2 "small_int" "")))
6047    (clobber (match_operand:SI 3 "register_operand" ""))]
6048   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6049    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6050    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6051    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6052    && (INTVAL (operands[2]) & 32) != 0"
6053
6054   [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
6055    (set (subreg:SI (match_dup 0) 1) (const_int 0))]
6056
6057   "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
6058
6059
6060 (define_insn "ashldi3_internal3"
6061   [(set (match_operand:DI 0 "register_operand" "=d")
6062         (ashift:DI (match_operand:DI 1 "register_operand" "d")
6063                    (match_operand:SI 2 "small_int" "IJK")))
6064    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6065   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6066    && (INTVAL (operands[2]) & 63) < 32
6067    && (INTVAL (operands[2]) & 63) != 0"
6068   "*
6069 {
6070   int amount = INTVAL (operands[2]);
6071
6072   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
6073   operands[4] = const0_rtx;
6074   operands[5] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
6075
6076   return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\";
6077 }"
6078   [(set_attr "type"     "darith")
6079    (set_attr "mode"     "DI")
6080    (set_attr "length"   "4")])
6081
6082
6083 (define_split
6084   [(set (match_operand:DI 0 "register_operand" "")
6085         (ashift:DI (match_operand:DI 1 "register_operand" "")
6086                    (match_operand:SI 2 "small_int" "")))
6087    (clobber (match_operand:SI 3 "register_operand" ""))]
6088   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6089    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6090    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6091    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6092    && (INTVAL (operands[2]) & 63) < 32
6093    && (INTVAL (operands[2]) & 63) != 0"
6094
6095   [(set (subreg:SI (match_dup 0) 1)
6096         (ashift:SI (subreg:SI (match_dup 1) 1)
6097                    (match_dup 2)))
6098
6099    (set (match_dup 3)
6100         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6101                      (match_dup 4)))
6102
6103    (set (subreg:SI (match_dup 0) 1)
6104         (ior:SI (subreg:SI (match_dup 0) 1)
6105                 (match_dup 3)))
6106
6107    (set (subreg:SI (match_dup 0) 0)
6108         (ashift:SI (subreg:SI (match_dup 1) 0)
6109                    (match_dup 2)))]
6110   "
6111 {
6112   int amount = INTVAL (operands[2]);
6113   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
6114   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
6115 }")
6116
6117
6118 (define_split
6119   [(set (match_operand:DI 0 "register_operand" "")
6120         (ashift:DI (match_operand:DI 1 "register_operand" "")
6121                    (match_operand:SI 2 "small_int" "")))
6122    (clobber (match_operand:SI 3 "register_operand" ""))]
6123   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6124    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6125    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6126    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6127    && (INTVAL (operands[2]) & 63) < 32
6128    && (INTVAL (operands[2]) & 63) != 0"
6129
6130   [(set (subreg:SI (match_dup 0) 0)
6131         (ashift:SI (subreg:SI (match_dup 1) 0)
6132                    (match_dup 2)))
6133
6134    (set (match_dup 3)
6135         (lshiftrt:SI (subreg:SI (match_dup 1) 1)
6136                      (match_dup 4)))
6137
6138    (set (subreg:SI (match_dup 0) 0)
6139         (ior:SI (subreg:SI (match_dup 0) 0)
6140                 (match_dup 3)))
6141
6142    (set (subreg:SI (match_dup 0) 1)
6143         (ashift:SI (subreg:SI (match_dup 1) 1)
6144                    (match_dup 2)))]
6145   "
6146 {
6147   int amount = INTVAL (operands[2]);
6148   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
6149   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
6150 }")
6151
6152
6153 (define_insn "ashldi3_internal4"
6154   [(set (match_operand:DI 0 "register_operand" "=d")
6155         (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
6156                    (match_operand:SI 2 "arith_operand" "dI")))]
6157   "TARGET_64BIT && !TARGET_MIPS16"
6158   "*
6159 {
6160   if (GET_CODE (operands[2]) == CONST_INT)
6161     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6162
6163   return \"dsll\\t%0,%1,%2\";
6164 }"
6165   [(set_attr "type"     "arith")
6166    (set_attr "mode"     "DI")
6167    (set_attr "length"   "1")])
6168
6169 (define_insn ""
6170   [(set (match_operand:DI 0 "register_operand" "=d,d")
6171         (ashift:DI (match_operand:DI 1 "se_register_operand" "0,d")
6172                    (match_operand:SI 2 "arith_operand" "d,I")))]
6173   "TARGET_64BIT && TARGET_MIPS16"
6174   "*
6175 {
6176   if (which_alternative == 0)
6177     return \"dsll\\t%0,%2\";
6178
6179   if (GET_CODE (operands[2]) == CONST_INT)
6180     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6181
6182   return \"dsll\\t%0,%1,%2\";
6183 }"
6184   [(set_attr "type"     "arith")
6185    (set_attr "mode"     "DI")
6186    (set_attr_alternative "length"
6187                 [(const_int 1)
6188                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6189                                (const_int 1)
6190                                (const_int 2))])])
6191
6192
6193 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6194
6195 (define_split
6196   [(set (match_operand:DI 0 "register_operand" "")
6197         (ashift:DI (match_operand:DI 1 "register_operand" "")
6198                    (match_operand:SI 2 "const_int_operand" "")))]
6199   "TARGET_MIPS16 && TARGET_64BIT
6200    && reload_completed
6201    && GET_CODE (operands[2]) == CONST_INT
6202    && INTVAL (operands[2]) > 8
6203    && INTVAL (operands[2]) <= 16"
6204   [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
6205    (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
6206 "
6207 {
6208   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6209 }")
6210
6211 (define_expand "ashrsi3"
6212   [(set (match_operand:SI 0 "register_operand" "=d")
6213         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6214                      (match_operand:SI 2 "arith_operand" "dI")))]
6215   ""
6216   "
6217 {
6218   /* On the mips16, a shift of more than 8 is a four byte instruction,
6219      so, for a shift between 8 and 16, it is just as fast to do two
6220      shifts of 8 or less.  If there is a lot of shifting going on, we
6221      may win in CSE.  Otherwise combine will put the shifts back
6222      together again.  */
6223   if (TARGET_MIPS16
6224       && optimize
6225       && GET_CODE (operands[2]) == CONST_INT
6226       && INTVAL (operands[2]) > 8
6227       && INTVAL (operands[2]) <= 16)
6228     {
6229       rtx temp = gen_reg_rtx (SImode);
6230
6231       emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
6232       emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
6233                                         GEN_INT (INTVAL (operands[2]) - 8)));
6234       DONE;
6235     }
6236 }")
6237
6238 (define_insn "ashrsi3_internal1"
6239   [(set (match_operand:SI 0 "register_operand" "=d")
6240         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
6241                      (match_operand:SI 2 "arith_operand" "dI")))]
6242   "!TARGET_MIPS16"
6243   "*
6244 {
6245   if (GET_CODE (operands[2]) == CONST_INT)
6246     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6247
6248   return \"sra\\t%0,%1,%2\";
6249 }"
6250   [(set_attr "type"     "arith")
6251    (set_attr "mode"     "SI")
6252    (set_attr "length"   "1")])
6253
6254 (define_insn "ashrsi3_internal2"
6255   [(set (match_operand:SI 0 "register_operand" "=d,d")
6256         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
6257                      (match_operand:SI 2 "arith_operand" "d,I")))]
6258   "TARGET_MIPS16"
6259   "*
6260 {
6261   if (which_alternative == 0)
6262     return \"sra\\t%0,%2\";
6263
6264   if (GET_CODE (operands[2]) == CONST_INT)
6265     operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
6266
6267   return \"sra\\t%0,%1,%2\";
6268 }"
6269   [(set_attr "type"     "arith")
6270    (set_attr "mode"     "SI")
6271    (set_attr_alternative "length"
6272                 [(const_int 1)
6273                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6274                                (const_int 1)
6275                                (const_int 2))])])
6276
6277
6278 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6279
6280 (define_split
6281   [(set (match_operand:SI 0 "register_operand" "")
6282         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
6283                      (match_operand:SI 2 "const_int_operand" "")))]
6284   "TARGET_MIPS16
6285    && reload_completed
6286    && GET_CODE (operands[2]) == CONST_INT
6287    && INTVAL (operands[2]) > 8
6288    && INTVAL (operands[2]) <= 16"
6289   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
6290    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
6291 "
6292 {
6293   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6294 }")
6295
6296 (define_expand "ashrdi3"
6297   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6298                    (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "")
6299                                 (match_operand:SI 2 "arith_operand" "")))
6300               (clobber (match_dup  3))])]
6301   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6302   "
6303 {
6304   if (TARGET_64BIT)
6305     {
6306       /* On the mips16, a shift of more than 8 is a four byte
6307          instruction, so, for a shift between 8 and 16, it is just as
6308          fast to do two shifts of 8 or less.  If there is a lot of
6309          shifting going on, we may win in CSE.  Otherwise combine will
6310          put the shifts back together again.  */
6311       if (TARGET_MIPS16
6312           && optimize
6313           && GET_CODE (operands[2]) == CONST_INT
6314           && INTVAL (operands[2]) > 8
6315           && INTVAL (operands[2]) <= 16)
6316         {
6317           rtx temp = gen_reg_rtx (DImode);
6318
6319           emit_insn (gen_ashrdi3_internal4 (temp, operands[1], GEN_INT (8)));
6320           emit_insn (gen_ashrdi3_internal4 (operands[0], temp,
6321                                             GEN_INT (INTVAL (operands[2]) - 8)));
6322           DONE;
6323         }
6324
6325       emit_insn (gen_ashrdi3_internal4 (operands[0], operands[1],
6326                                         operands[2]));
6327       DONE;
6328     }
6329
6330   operands[3] = gen_reg_rtx (SImode);
6331 }")
6332
6333
6334 (define_insn "ashrdi3_internal"
6335   [(set (match_operand:DI 0 "register_operand" "=&d")
6336         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
6337                      (match_operand:SI 2 "register_operand" "d")))
6338    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6339   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
6340   "* 
6341 {
6342   operands[4] = const0_rtx;
6343   dslots_jump_total += 3;
6344   dslots_jump_filled += 2;
6345
6346   return \"sll\\t%3,%2,26\\n\\
6347 \\tbgez\\t%3,1f\\n\\
6348 \\tsra\\t%L0,%M1,%2\\n\\
6349 \\t%(b\\t3f\\n\\
6350 \\tsra\\t%M0,%M1,31%)\\n\\
6351 \\n\\
6352 1:\\n\\
6353 \\t%(beq\\t%3,%z4,2f\\n\\
6354 \\tsrl\\t%L0,%L1,%2%)\\n\\
6355 \\n\\
6356 \\tsubu\\t%3,%z4,%2\\n\\
6357 \\tsll\\t%3,%M1,%3\\n\\
6358 \\tor\\t%L0,%L0,%3\\n\\
6359 2:\\n\\
6360 \\tsra\\t%M0,%M1,%2\\n\\
6361 3:\";
6362 }"
6363   [(set_attr "type"     "darith")
6364    (set_attr "mode"     "DI")
6365    (set_attr "length"   "12")])
6366
6367
6368 (define_insn "ashrdi3_internal2"
6369   [(set (match_operand:DI 0 "register_operand" "=d")
6370         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
6371                      (match_operand:SI 2 "small_int" "IJK")))
6372    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6373   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
6374   "*
6375 {
6376   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
6377   return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\";
6378 }"
6379   [(set_attr "type"     "darith")
6380    (set_attr "mode"     "DI")
6381    (set_attr "length"   "2")])
6382
6383
6384 (define_split
6385   [(set (match_operand:DI 0 "register_operand" "")
6386         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6387                      (match_operand:SI 2 "small_int" "")))
6388    (clobber (match_operand:SI 3 "register_operand" ""))]
6389   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
6390    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6391    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6392    && (INTVAL (operands[2]) & 32) != 0"
6393
6394   [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
6395    (set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (const_int 31)))]
6396
6397   "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
6398
6399
6400 (define_split
6401   [(set (match_operand:DI 0 "register_operand" "")
6402         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6403                      (match_operand:SI 2 "small_int" "")))
6404    (clobber (match_operand:SI 3 "register_operand" ""))]
6405   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
6406    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6407    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6408    && (INTVAL (operands[2]) & 32) != 0"
6409
6410   [(set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
6411    (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
6412
6413   "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
6414
6415
6416 (define_insn "ashrdi3_internal3"
6417   [(set (match_operand:DI 0 "register_operand" "=d")
6418         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
6419                      (match_operand:SI 2 "small_int" "IJK")))
6420    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6421   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6422    && (INTVAL (operands[2]) & 63) < 32
6423    && (INTVAL (operands[2]) & 63) != 0"
6424   "*
6425 {
6426   int amount = INTVAL (operands[2]);
6427
6428   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
6429   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
6430
6431   return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\";
6432 }"
6433   [(set_attr "type"     "darith")
6434    (set_attr "mode"     "DI")
6435    (set_attr "length"   "4")])
6436
6437
6438 (define_split
6439   [(set (match_operand:DI 0 "register_operand" "")
6440         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6441                      (match_operand:SI 2 "small_int" "")))
6442    (clobber (match_operand:SI 3 "register_operand" ""))]
6443   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6444    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6445    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6446    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6447    && (INTVAL (operands[2]) & 63) < 32
6448    && (INTVAL (operands[2]) & 63) != 0"
6449
6450   [(set (subreg:SI (match_dup 0) 0)
6451         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6452                      (match_dup 2)))
6453
6454    (set (match_dup 3)
6455         (ashift:SI (subreg:SI (match_dup 1) 1)
6456                    (match_dup 4)))
6457
6458    (set (subreg:SI (match_dup 0) 0)
6459         (ior:SI (subreg:SI (match_dup 0) 0)
6460                 (match_dup 3)))
6461
6462    (set (subreg:SI (match_dup 0) 1)
6463         (ashiftrt:SI (subreg:SI (match_dup 1) 1)
6464                      (match_dup 2)))]
6465   "
6466 {
6467   int amount = INTVAL (operands[2]);
6468   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
6469   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
6470 }")
6471
6472
6473 (define_split
6474   [(set (match_operand:DI 0 "register_operand" "")
6475         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6476                      (match_operand:SI 2 "small_int" "")))
6477    (clobber (match_operand:SI 3 "register_operand" ""))]
6478   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6479    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6480    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6481    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6482    && (INTVAL (operands[2]) & 63) < 32
6483    && (INTVAL (operands[2]) & 63) != 0"
6484
6485   [(set (subreg:SI (match_dup 0) 1)
6486         (lshiftrt:SI (subreg:SI (match_dup 1) 1)
6487                      (match_dup 2)))
6488
6489    (set (match_dup 3)
6490         (ashift:SI (subreg:SI (match_dup 1) 0)
6491                    (match_dup 4)))
6492
6493    (set (subreg:SI (match_dup 0) 1)
6494         (ior:SI (subreg:SI (match_dup 0) 1)
6495                 (match_dup 3)))
6496
6497    (set (subreg:SI (match_dup 0) 0)
6498         (ashiftrt:SI (subreg:SI (match_dup 1) 0)
6499                      (match_dup 2)))]
6500   "
6501 {
6502   int amount = INTVAL (operands[2]);
6503   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
6504   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
6505 }")
6506
6507
6508 (define_insn "ashrdi3_internal4"
6509   [(set (match_operand:DI 0 "register_operand" "=d")
6510         (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
6511                      (match_operand:SI 2 "arith_operand" "dI")))]
6512   "TARGET_64BIT && !TARGET_MIPS16"
6513   "*
6514 {
6515   if (GET_CODE (operands[2]) == CONST_INT)
6516     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6517
6518   return \"dsra\\t%0,%1,%2\";
6519 }"
6520   [(set_attr "type"     "arith")
6521    (set_attr "mode"     "DI")
6522    (set_attr "length"   "1")])
6523
6524 (define_insn ""
6525   [(set (match_operand:DI 0 "register_operand" "=d,d")
6526         (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
6527                      (match_operand:SI 2 "arith_operand" "d,I")))]
6528   "TARGET_64BIT && TARGET_MIPS16"
6529   "*
6530 {
6531   if (GET_CODE (operands[2]) == CONST_INT)
6532     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6533
6534   return \"dsra\\t%0,%2\";
6535 }"
6536   [(set_attr "type"     "arith")
6537    (set_attr "mode"     "DI")
6538    (set_attr_alternative "length"
6539                 [(const_int 1)
6540                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6541                                (const_int 1)
6542                                (const_int 2))])])
6543
6544 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6545
6546 (define_split
6547   [(set (match_operand:DI 0 "register_operand" "")
6548         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6549                      (match_operand:SI 2 "const_int_operand" "")))]
6550   "TARGET_MIPS16 && TARGET_64BIT
6551    && reload_completed
6552    && GET_CODE (operands[2]) == CONST_INT
6553    && INTVAL (operands[2]) > 8
6554    && INTVAL (operands[2]) <= 16"
6555   [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
6556    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
6557 "
6558 {
6559   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6560 }")
6561
6562 (define_expand "lshrsi3"
6563   [(set (match_operand:SI 0 "register_operand" "=d")
6564         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
6565                      (match_operand:SI 2 "arith_operand" "dI")))]
6566   ""
6567   "
6568 {
6569   /* On the mips16, a shift of more than 8 is a four byte instruction,
6570      so, for a shift between 8 and 16, it is just as fast to do two
6571      shifts of 8 or less.  If there is a lot of shifting going on, we
6572      may win in CSE.  Otherwise combine will put the shifts back
6573      together again.  */
6574   if (TARGET_MIPS16
6575       && optimize
6576       && GET_CODE (operands[2]) == CONST_INT
6577       && INTVAL (operands[2]) > 8
6578       && INTVAL (operands[2]) <= 16)
6579     {
6580       rtx temp = gen_reg_rtx (SImode);
6581
6582       emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
6583       emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
6584                                         GEN_INT (INTVAL (operands[2]) - 8)));
6585       DONE;
6586     }
6587 }")
6588
6589 (define_insn "lshrsi3_internal1"
6590   [(set (match_operand:SI 0 "register_operand" "=d")
6591         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
6592                      (match_operand:SI 2 "arith_operand" "dI")))]
6593   "!TARGET_MIPS16"
6594   "*
6595 {
6596   if (GET_CODE (operands[2]) == CONST_INT)
6597     operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
6598
6599   return \"srl\\t%0,%1,%2\";
6600 }"
6601   [(set_attr "type"     "arith")
6602    (set_attr "mode"     "SI")
6603    (set_attr "length"   "1")])
6604
6605 (define_insn "lshrsi3_internal2"
6606   [(set (match_operand:SI 0 "register_operand" "=d,d")
6607         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
6608                      (match_operand:SI 2 "arith_operand" "d,I")))]
6609   "TARGET_MIPS16"
6610   "*
6611 {
6612   if (which_alternative == 0)
6613     return \"srl\\t%0,%2\";
6614
6615   if (GET_CODE (operands[2]) == CONST_INT)
6616     operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
6617
6618   return \"srl\\t%0,%1,%2\";
6619 }"
6620   [(set_attr "type"     "arith")
6621    (set_attr "mode"     "SI")
6622    (set_attr_alternative "length"
6623                 [(const_int 1)
6624                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6625                                (const_int 1)
6626                                (const_int 2))])])
6627
6628
6629 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6630
6631 (define_split
6632   [(set (match_operand:SI 0 "register_operand" "")
6633         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
6634                      (match_operand:SI 2 "const_int_operand" "")))]
6635   "TARGET_MIPS16
6636    && reload_completed
6637    && GET_CODE (operands[2]) == CONST_INT
6638    && INTVAL (operands[2]) > 8
6639    && INTVAL (operands[2]) <= 16"
6640   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
6641    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
6642 "
6643 {
6644   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6645 }")
6646
6647 ;; If we load a byte on the mips16 as a bitfield, the resulting
6648 ;; sequence of instructions is too complicated for combine, because it
6649 ;; involves four instructions: a load, a shift, a constant load into a
6650 ;; register, and an and (the key problem here is that the mips16 does
6651 ;; not have and immediate).  We recognize a shift of a load in order
6652 ;; to make it simple enough for combine to understand.
6653
6654 (define_insn ""
6655   [(set (match_operand:SI 0 "register_operand" "d,d")
6656         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "R,m")
6657                      (match_operand:SI 2 "immediate_operand" "I,I")))]
6658   "TARGET_MIPS16"
6659   "lw\\t%0,%1\;srl\\t%0,%2"
6660   [(set_attr "type"     "load")
6661    (set_attr "mode"     "SI")
6662    (set_attr_alternative "length"
6663                 [(if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6664                                (const_int 2)
6665                                (const_int 3))
6666                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6667                                (const_int 3)
6668                                (const_int 4))])])
6669
6670 (define_split
6671   [(set (match_operand:SI 0 "register_operand" "")
6672         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "")
6673                      (match_operand:SI 2 "immediate_operand" "")))]
6674   "TARGET_MIPS16"
6675   [(set (match_dup 0) (match_dup 1))
6676    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
6677   "")
6678
6679 (define_expand "lshrdi3"
6680   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6681                    (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "")
6682                                 (match_operand:SI 2 "arith_operand" "")))
6683               (clobber (match_dup  3))])]
6684   "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
6685   "
6686 {
6687   if (TARGET_64BIT)
6688     {
6689       /* On the mips16, a shift of more than 8 is a four byte
6690          instruction, so, for a shift between 8 and 16, it is just as
6691          fast to do two shifts of 8 or less.  If there is a lot of
6692          shifting going on, we may win in CSE.  Otherwise combine will
6693          put the shifts back together again.  */
6694       if (TARGET_MIPS16
6695           && optimize
6696           && GET_CODE (operands[2]) == CONST_INT
6697           && INTVAL (operands[2]) > 8
6698           && INTVAL (operands[2]) <= 16)
6699         {
6700           rtx temp = gen_reg_rtx (DImode);
6701
6702           emit_insn (gen_lshrdi3_internal4 (temp, operands[1], GEN_INT (8)));
6703           emit_insn (gen_lshrdi3_internal4 (operands[0], temp,
6704                                             GEN_INT (INTVAL (operands[2]) - 8)));
6705           DONE;
6706         }
6707
6708       emit_insn (gen_lshrdi3_internal4 (operands[0], operands[1],
6709                                         operands[2]));
6710       DONE;
6711     }
6712
6713   operands[3] = gen_reg_rtx (SImode);
6714 }")
6715
6716
6717 (define_insn "lshrdi3_internal"
6718   [(set (match_operand:DI 0 "register_operand" "=&d")
6719         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
6720                      (match_operand:SI 2 "register_operand" "d")))
6721    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6722   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
6723   "* 
6724 {
6725   operands[4] = const0_rtx;
6726   dslots_jump_total += 3;
6727   dslots_jump_filled += 2;
6728
6729   return \"sll\\t%3,%2,26\\n\\
6730 \\tbgez\\t%3,1f\\n\\
6731 \\tsrl\\t%L0,%M1,%2\\n\\
6732 \\t%(b\\t3f\\n\\
6733 \\tmove\\t%M0,%z4%)\\n\\
6734 \\n\\
6735 1:\\n\\
6736 \\t%(beq\\t%3,%z4,2f\\n\\
6737 \\tsrl\\t%L0,%L1,%2%)\\n\\
6738 \\n\\
6739 \\tsubu\\t%3,%z4,%2\\n\\
6740 \\tsll\\t%3,%M1,%3\\n\\
6741 \\tor\\t%L0,%L0,%3\\n\\
6742 2:\\n\\
6743 \\tsrl\\t%M0,%M1,%2\\n\\
6744 3:\";
6745 }"
6746   [(set_attr "type"     "darith")
6747    (set_attr "mode"     "DI")
6748    (set_attr "length"   "12")])
6749
6750
6751 (define_insn "lshrdi3_internal2"
6752   [(set (match_operand:DI 0 "register_operand" "=d")
6753         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
6754                      (match_operand:SI 2 "small_int" "IJK")))
6755    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6756   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6757    && (INTVAL (operands[2]) & 32) != 0"
6758   "*
6759 {
6760   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
6761   operands[4] = const0_rtx;
6762   return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\";
6763 }"
6764   [(set_attr "type"     "darith")
6765    (set_attr "mode"     "DI")
6766    (set_attr "length"   "2")])
6767
6768
6769 (define_split
6770   [(set (match_operand:DI 0 "register_operand" "")
6771         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6772                      (match_operand:SI 2 "small_int" "")))
6773    (clobber (match_operand:SI 3 "register_operand" ""))]
6774   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6775    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6776    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6777    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6778    && (INTVAL (operands[2]) & 32) != 0"
6779
6780   [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
6781    (set (subreg:SI (match_dup 0) 1) (const_int 0))]
6782
6783   "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
6784
6785
6786 (define_split
6787   [(set (match_operand:DI 0 "register_operand" "")
6788         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6789                      (match_operand:SI 2 "small_int" "")))
6790    (clobber (match_operand:SI 3 "register_operand" ""))]
6791   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6792    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6793    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6794    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6795    && (INTVAL (operands[2]) & 32) != 0"
6796
6797   [(set (subreg:SI (match_dup 0) 1) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
6798    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
6799
6800   "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
6801
6802
6803 (define_insn "lshrdi3_internal3"
6804   [(set (match_operand:DI 0 "register_operand" "=d")
6805         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
6806                    (match_operand:SI 2 "small_int" "IJK")))
6807    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6808   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6809    && (INTVAL (operands[2]) & 63) < 32
6810    && (INTVAL (operands[2]) & 63) != 0"
6811   "*
6812 {
6813   int amount = INTVAL (operands[2]);
6814
6815   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
6816   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
6817
6818   return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\";
6819 }"
6820   [(set_attr "type"     "darith")
6821    (set_attr "mode"     "DI")
6822    (set_attr "length"   "4")])
6823
6824
6825 (define_split
6826   [(set (match_operand:DI 0 "register_operand" "")
6827         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6828                      (match_operand:SI 2 "small_int" "")))
6829    (clobber (match_operand:SI 3 "register_operand" ""))]
6830   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6831    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6832    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6833    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6834    && (INTVAL (operands[2]) & 63) < 32
6835    && (INTVAL (operands[2]) & 63) != 0"
6836
6837   [(set (subreg:SI (match_dup 0) 0)
6838         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6839                      (match_dup 2)))
6840
6841    (set (match_dup 3)
6842         (ashift:SI (subreg:SI (match_dup 1) 1)
6843                    (match_dup 4)))
6844
6845    (set (subreg:SI (match_dup 0) 0)
6846         (ior:SI (subreg:SI (match_dup 0) 0)
6847                 (match_dup 3)))
6848
6849    (set (subreg:SI (match_dup 0) 1)
6850         (lshiftrt:SI (subreg:SI (match_dup 1) 1)
6851                      (match_dup 2)))]
6852   "
6853 {
6854   int amount = INTVAL (operands[2]);
6855   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
6856   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
6857 }")
6858
6859
6860 (define_split
6861   [(set (match_operand:DI 0 "register_operand" "")
6862         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6863                      (match_operand:SI 2 "small_int" "")))
6864    (clobber (match_operand:SI 3 "register_operand" ""))]
6865   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6866    && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6867    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6868    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6869    && (INTVAL (operands[2]) & 63) < 32
6870    && (INTVAL (operands[2]) & 63) != 0"
6871
6872   [(set (subreg:SI (match_dup 0) 1)
6873         (lshiftrt:SI (subreg:SI (match_dup 1) 1)
6874                      (match_dup 2)))
6875
6876    (set (match_dup 3)
6877         (ashift:SI (subreg:SI (match_dup 1) 0)
6878                    (match_dup 4)))
6879
6880    (set (subreg:SI (match_dup 0) 1)
6881         (ior:SI (subreg:SI (match_dup 0) 1)
6882                 (match_dup 3)))
6883
6884    (set (subreg:SI (match_dup 0) 0)
6885         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6886                      (match_dup 2)))]
6887   "
6888 {
6889   int amount = INTVAL (operands[2]);
6890   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
6891   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
6892 }")
6893
6894
6895 (define_insn "lshrdi3_internal4"
6896   [(set (match_operand:DI 0 "register_operand" "=d")
6897         (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
6898                      (match_operand:SI 2 "arith_operand" "dI")))]
6899   "TARGET_64BIT && !TARGET_MIPS16"
6900   "*
6901 {
6902   if (GET_CODE (operands[2]) == CONST_INT)
6903     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6904
6905   return \"dsrl\\t%0,%1,%2\";
6906 }"
6907   [(set_attr "type"     "arith")
6908    (set_attr "mode"     "DI")
6909    (set_attr "length"   "1")])
6910
6911 (define_insn ""
6912   [(set (match_operand:DI 0 "register_operand" "=d,d")
6913         (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0")
6914                      (match_operand:SI 2 "arith_operand" "d,I")))]
6915   "TARGET_64BIT && TARGET_MIPS16"
6916   "*
6917 {
6918   if (GET_CODE (operands[2]) == CONST_INT)
6919     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6920
6921   return \"dsrl\\t%0,%2\";
6922 }"
6923   [(set_attr "type"     "arith")
6924    (set_attr "mode"     "DI")
6925    (set_attr_alternative "length"
6926                 [(const_int 1)
6927                  (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6928                                (const_int 1)
6929                                (const_int 2))])])
6930
6931 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6932
6933 (define_split
6934   [(set (match_operand:DI 0 "register_operand" "")
6935         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6936                      (match_operand:SI 2 "const_int_operand" "")))]
6937   "TARGET_MIPS16
6938    && reload_completed
6939    && GET_CODE (operands[2]) == CONST_INT
6940    && INTVAL (operands[2]) > 8
6941    && INTVAL (operands[2]) <= 16"
6942   [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
6943    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
6944 "
6945 {
6946   operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
6947 }")
6948
6949 \f
6950 ;;
6951 ;;  ....................
6952 ;;
6953 ;;      COMPARISONS
6954 ;;
6955 ;;  ....................
6956
6957 ;; Flow here is rather complex:
6958 ;;
6959 ;;  1)  The cmp{si,di,sf,df} routine is called.  It deposits the
6960 ;;      arguments into the branch_cmp array, and the type into
6961 ;;      branch_type.  No RTL is generated.
6962 ;;
6963 ;;  2)  The appropriate branch define_expand is called, which then
6964 ;;      creates the appropriate RTL for the comparison and branch.
6965 ;;      Different CC modes are used, based on what type of branch is
6966 ;;      done, so that we can constrain things appropriately.  There
6967 ;;      are assumptions in the rest of GCC that break if we fold the
6968 ;;      operands into the branchs for integer operations, and use cc0
6969 ;;      for floating point, so we use the fp status register instead.
6970 ;;      If needed, an appropriate temporary is created to hold the
6971 ;;      of the integer compare.
6972
6973 (define_expand "cmpsi"
6974   [(set (cc0)
6975         (compare:CC (match_operand:SI 0 "register_operand" "")
6976                     (match_operand:SI 1 "arith_operand" "")))]
6977   ""
6978   "
6979 {
6980   if (operands[0])              /* avoid unused code message */
6981     {
6982       branch_cmp[0] = operands[0];
6983       branch_cmp[1] = operands[1];
6984       branch_type = CMP_SI;
6985       DONE;
6986     }
6987 }")
6988
6989 (define_expand "tstsi"
6990   [(set (cc0)
6991         (match_operand:SI 0 "register_operand" ""))]
6992   ""
6993   "
6994 {
6995   if (operands[0])              /* avoid unused code message */
6996     {
6997       branch_cmp[0] = operands[0];
6998       branch_cmp[1] = const0_rtx;
6999       branch_type = CMP_SI;
7000       DONE;
7001     }
7002 }")
7003
7004 (define_expand "cmpdi"
7005   [(set (cc0)
7006         (compare:CC (match_operand:DI 0 "se_register_operand" "")
7007                     (match_operand:DI 1 "se_arith_operand" "")))]
7008   "TARGET_64BIT"
7009   "
7010 {
7011   if (operands[0])              /* avoid unused code message */
7012     {
7013       branch_cmp[0] = operands[0];
7014       branch_cmp[1] = operands[1];
7015       branch_type = CMP_DI;
7016       DONE;
7017     }
7018 }")
7019
7020 (define_expand "tstdi"
7021   [(set (cc0)
7022         (match_operand:DI 0 "se_register_operand" ""))]
7023   "TARGET_64BIT"
7024   "
7025 {
7026   if (operands[0])              /* avoid unused code message */
7027     {
7028       branch_cmp[0] = operands[0];
7029       branch_cmp[1] = const0_rtx;
7030       branch_type = CMP_DI;
7031       DONE;
7032     }
7033 }")
7034
7035 (define_expand "cmpdf"
7036   [(set (cc0)
7037         (compare:CC (match_operand:DF 0 "register_operand" "")
7038                     (match_operand:DF 1 "register_operand" "")))]
7039   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7040   "
7041 {
7042   if (operands[0])              /* avoid unused code message */
7043     {
7044       branch_cmp[0] = operands[0];
7045       branch_cmp[1] = operands[1];
7046       branch_type = CMP_DF;
7047       DONE;
7048     }
7049 }")
7050
7051 (define_expand "cmpsf"
7052   [(set (cc0)
7053         (compare:CC (match_operand:SF 0 "register_operand" "")
7054                     (match_operand:SF 1 "register_operand" "")))]
7055   "TARGET_HARD_FLOAT"
7056   "
7057 {
7058   if (operands[0])              /* avoid unused code message */
7059     {
7060       branch_cmp[0] = operands[0];
7061       branch_cmp[1] = operands[1];
7062       branch_type = CMP_SF;
7063       DONE;
7064     }
7065 }")
7066
7067 \f
7068 ;;
7069 ;;  ....................
7070 ;;
7071 ;;      CONDITIONAL BRANCHES
7072 ;;
7073 ;;  ....................
7074
7075 (define_insn "branch_fp_ne"
7076   [(set (pc)
7077         (if_then_else (ne:CC (match_operand:CC 0 "register_operand" "z")
7078                              (const_int 0))
7079                       (match_operand 1 "pc_or_label_operand" "")
7080                       (match_operand 2 "pc_or_label_operand" "")))]
7081   "TARGET_HARD_FLOAT"
7082   "*
7083 {
7084   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
7085   return (operands[1] != pc_rtx) ? \"%*bc1t%?\\t%Z0%1\" : \"%*bc1f%?\\t%Z0%2\";
7086 }"
7087   [(set_attr "type"     "branch")
7088    (set_attr "mode"     "none")
7089    (set_attr "length"   "1")])
7090
7091 (define_insn "branch_fp_eq"
7092   [(set (pc)
7093         (if_then_else (eq:CC (match_operand:CC 0 "register_operand" "z")
7094                              (const_int 0))
7095                       (match_operand 1 "pc_or_label_operand" "")
7096                       (match_operand 2 "pc_or_label_operand" "")))]
7097   "TARGET_HARD_FLOAT"
7098   "*
7099 {
7100   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
7101   return (operands[1] != pc_rtx) ? \"%*bc1f%?\\t%Z0%1\" : \"%*bc1t%?\\t%Z0%2\";
7102 }"
7103   [(set_attr "type"     "branch")
7104    (set_attr "mode"     "none")
7105    (set_attr "length"   "1")])
7106
7107 (define_insn "branch_zero"
7108   [(set (pc)
7109         (if_then_else (match_operator:SI 0 "cmp_op"
7110                                          [(match_operand:SI 1 "register_operand" "d")
7111                                           (const_int 0)])
7112         (match_operand 2 "pc_or_label_operand" "")
7113         (match_operand 3 "pc_or_label_operand" "")))]
7114   "!TARGET_MIPS16"
7115   "*
7116 {
7117   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
7118   if (operands[2] != pc_rtx)
7119     {                           /* normal jump */
7120       switch (GET_CODE (operands[0]))
7121         {
7122         case EQ:  return \"%*beq%?\\t%z1,%.,%2\";
7123         case NE:  return \"%*bne%?\\t%z1,%.,%2\";
7124         case GTU: return \"%*bne%?\\t%z1,%.,%2\";
7125         case LEU: return \"%*beq%?\\t%z1,%.,%2\";
7126         case GEU: return \"%*j\\t%2\";
7127         case LTU: return \"%*bne%?\\t%.,%.,%2\";
7128         }
7129
7130       return \"%*b%C0z%?\\t%z1,%2\";
7131     }
7132   else
7133     {                           /* inverted jump */
7134       switch (GET_CODE (operands[0]))
7135         {
7136         case EQ:  return \"%*bne%?\\t%z1,%.,%3\";
7137         case NE:  return \"%*beq%?\\t%z1,%.,%3\";
7138         case GTU: return \"%*beq%?\\t%z1,%.,%3\";
7139         case LEU: return \"%*bne%?\\t%z1,%.,%3\";
7140         case GEU: return \"%*beq%?\\t%.,%.,%3\";
7141         case LTU: return \"%*j\\t%3\";
7142         }
7143
7144       return \"%*b%N0z%?\\t%z1,%3\";
7145     }
7146 }"
7147   [(set_attr "type"     "branch")
7148    (set_attr "mode"     "none")
7149    (set_attr "length"   "1")])
7150
7151
7152 (define_insn ""
7153   [(set (pc)
7154         (if_then_else (match_operator:SI 0 "equality_op"
7155                                          [(match_operand:SI 1 "register_operand" "d,t")
7156                                           (const_int 0)])
7157         (match_operand 2 "pc_or_label_operand" "")
7158         (match_operand 3 "pc_or_label_operand" "")))]
7159   "TARGET_MIPS16"
7160   "*
7161 {
7162   if (operands[2] != pc_rtx)
7163     {
7164       if (which_alternative == 0)
7165         return \"%*b%C0z\\t%1,%2\";
7166       else
7167         return \"%*bt%C0z\\t%2\";
7168     }
7169   else
7170     {
7171       if (which_alternative == 0)
7172         return \"%*b%N0z\\t%1,%3\";
7173       else
7174         return \"%*bt%N0z\\t%3\";
7175     }
7176 }"
7177   [(set_attr "type"     "branch")
7178    (set_attr "mode"     "none")
7179    (set_attr "length"   "2")])
7180
7181 (define_insn "branch_zero_di"
7182   [(set (pc)
7183         (if_then_else (match_operator:DI 0 "cmp_op"
7184                                          [(match_operand:DI 1 "se_register_operand" "d")
7185                                           (const_int 0)])
7186         (match_operand 2 "pc_or_label_operand" "")
7187         (match_operand 3 "pc_or_label_operand" "")))]
7188   "!TARGET_MIPS16"
7189   "*
7190 {
7191   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
7192   if (operands[2] != pc_rtx)
7193     {                           /* normal jump */
7194       switch (GET_CODE (operands[0]))
7195         {
7196         case EQ:  return \"%*beq%?\\t%z1,%.,%2\";
7197         case NE:  return \"%*bne%?\\t%z1,%.,%2\";
7198         case GTU: return \"%*bne%?\\t%z1,%.,%2\";
7199         case LEU: return \"%*beq%?\\t%z1,%.,%2\";
7200         case GEU: return \"%*j\\t%2\";
7201         case LTU: return \"%*bne%?\\t%.,%.,%2\";
7202         }
7203
7204       return \"%*b%C0z%?\\t%z1,%2\";
7205     }
7206   else
7207     {                           /* inverted jump */
7208       switch (GET_CODE (operands[0]))
7209         {
7210         case EQ:  return \"%*bne%?\\t%z1,%.,%3\";
7211         case NE:  return \"%*beq%?\\t%z1,%.,%3\";
7212         case GTU: return \"%*beq%?\\t%z1,%.,%3\";
7213         case LEU: return \"%*bne%?\\t%z1,%.,%3\";
7214         case GEU: return \"%*beq%?\\t%.,%.,%3\";
7215         case LTU: return \"%*j\\t%3\";
7216         }
7217
7218       return \"%*b%N0z%?\\t%z1,%3\";
7219     }
7220 }"
7221   [(set_attr "type"     "branch")
7222    (set_attr "mode"     "none")
7223    (set_attr "length"   "1")])
7224
7225 (define_insn ""
7226   [(set (pc)
7227         (if_then_else (match_operator:DI 0 "equality_op"
7228                                          [(match_operand:DI 1 "se_register_operand" "d,t")
7229                                           (const_int 0)])
7230         (match_operand 2 "pc_or_label_operand" "")
7231         (match_operand 3 "pc_or_label_operand" "")))]
7232   "TARGET_MIPS16"
7233   "*
7234 {
7235   if (operands[2] != pc_rtx)
7236     {
7237       if (which_alternative == 0)
7238         return \"%*b%C0z\\t%1,%2\";
7239       else
7240         return \"%*bt%C0z\\t%2\";
7241     }
7242   else
7243     {
7244       if (which_alternative == 0)
7245         return \"%*b%N0z\\t%1,%3\";
7246       else
7247         return \"%*bt%N0z\\t%3\";
7248     }
7249 }"
7250   [(set_attr "type"     "branch")
7251    (set_attr "mode"     "none")
7252    (set_attr "length"   "2")])
7253
7254
7255 (define_insn "branch_equality"
7256   [(set (pc)
7257         (if_then_else (match_operator:SI 0 "equality_op"
7258                                          [(match_operand:SI 1 "register_operand" "d")
7259                                           (match_operand:SI 2 "register_operand" "d")])
7260         (match_operand 3 "pc_or_label_operand" "")
7261         (match_operand 4 "pc_or_label_operand" "")))]
7262   "!TARGET_MIPS16"
7263   "*
7264 {
7265   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
7266   return (operands[3] != pc_rtx)
7267         ? \"%*b%C0%?\\t%z1,%z2,%3\"
7268         : \"%*b%N0%?\\t%z1,%z2,%4\";
7269 }"
7270   [(set_attr "type"     "branch")
7271    (set_attr "mode"     "none")
7272    (set_attr "length"   "1")])
7273
7274
7275 (define_insn "branch_equality_di"
7276   [(set (pc)
7277         (if_then_else (match_operator:DI 0 "equality_op"
7278                                          [(match_operand:DI 1 "se_register_operand" "d")
7279                                           (match_operand:DI 2 "se_register_operand" "d")])
7280         (match_operand 3 "pc_or_label_operand" "")
7281         (match_operand 4 "pc_or_label_operand" "")))]
7282   "!TARGET_MIPS16"
7283   "*
7284 {
7285   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
7286   return (operands[3] != pc_rtx)
7287         ? \"%*b%C0%?\\t%z1,%z2,%3\"
7288         : \"%*b%N0%?\\t%z1,%z2,%4\";
7289 }"
7290   [(set_attr "type"     "branch")
7291    (set_attr "mode"     "none")
7292    (set_attr "length"   "1")])
7293
7294
7295 (define_expand "beq"
7296   [(set (pc)
7297         (if_then_else (eq:CC (cc0)
7298                              (const_int 0))
7299                       (label_ref (match_operand 0 "" ""))
7300                       (pc)))]
7301   ""
7302   "
7303 {
7304   if (operands[0])              /* avoid unused code warning */
7305     {
7306       gen_conditional_branch (operands, EQ);
7307       DONE;
7308     }
7309 }")
7310
7311 (define_expand "bne"
7312   [(set (pc)
7313         (if_then_else (ne:CC (cc0)
7314                              (const_int 0))
7315                       (label_ref (match_operand 0 "" ""))
7316                       (pc)))]
7317   ""
7318   "
7319 {
7320   if (operands[0])              /* avoid unused code warning */
7321     {
7322       gen_conditional_branch (operands, NE);
7323       DONE;
7324     }
7325 }")
7326
7327 (define_expand "bgt"
7328   [(set (pc)
7329         (if_then_else (gt:CC (cc0)
7330                              (const_int 0))
7331                       (label_ref (match_operand 0 "" ""))
7332                       (pc)))]
7333   ""
7334   "
7335 {
7336   if (operands[0])              /* avoid unused code warning */
7337     {
7338       gen_conditional_branch (operands, GT);
7339       DONE;
7340     }
7341 }")
7342
7343 (define_expand "bge"
7344   [(set (pc)
7345         (if_then_else (ge:CC (cc0)
7346                              (const_int 0))
7347                       (label_ref (match_operand 0 "" ""))
7348                       (pc)))]
7349   ""
7350   "
7351 {
7352   if (operands[0])              /* avoid unused code warning */
7353     {
7354       gen_conditional_branch (operands, GE);
7355       DONE;
7356     }
7357 }")
7358
7359 (define_expand "blt"
7360   [(set (pc)
7361         (if_then_else (lt:CC (cc0)
7362                              (const_int 0))
7363                       (label_ref (match_operand 0 "" ""))
7364                       (pc)))]
7365   ""
7366   "
7367 {
7368   if (operands[0])              /* avoid unused code warning */
7369     {
7370       gen_conditional_branch (operands, LT);
7371       DONE;
7372     }
7373 }")
7374
7375 (define_expand "ble"
7376   [(set (pc)
7377         (if_then_else (le:CC (cc0)
7378                              (const_int 0))
7379                       (label_ref (match_operand 0 "" ""))
7380                       (pc)))]
7381   ""
7382   "
7383 {
7384   if (operands[0])              /* avoid unused code warning */
7385     {
7386       gen_conditional_branch (operands, LE);
7387       DONE;
7388     }
7389 }")
7390
7391 (define_expand "bgtu"
7392   [(set (pc)
7393         (if_then_else (gtu:CC (cc0)
7394                               (const_int 0))
7395                       (label_ref (match_operand 0 "" ""))
7396                       (pc)))]
7397   ""
7398   "
7399 {
7400   if (operands[0])              /* avoid unused code warning */
7401     {
7402       gen_conditional_branch (operands, GTU);
7403       DONE;
7404     }
7405 }")
7406
7407 (define_expand "bgeu"
7408   [(set (pc)
7409         (if_then_else (geu:CC (cc0)
7410                               (const_int 0))
7411                       (label_ref (match_operand 0 "" ""))
7412                       (pc)))]
7413   ""
7414   "
7415 {
7416   if (operands[0])              /* avoid unused code warning */
7417     {
7418       gen_conditional_branch (operands, GEU);
7419       DONE;
7420     }
7421 }")
7422
7423
7424 (define_expand "bltu"
7425   [(set (pc)
7426         (if_then_else (ltu:CC (cc0)
7427                               (const_int 0))
7428                       (label_ref (match_operand 0 "" ""))
7429                       (pc)))]
7430   ""
7431   "
7432 {
7433   if (operands[0])              /* avoid unused code warning */
7434     {
7435       gen_conditional_branch (operands, LTU);
7436       DONE;
7437     }
7438 }")
7439
7440 (define_expand "bleu"
7441   [(set (pc)
7442         (if_then_else (leu:CC (cc0)
7443                               (const_int 0))
7444                       (label_ref (match_operand 0 "" ""))
7445                       (pc)))]
7446   ""
7447   "
7448 {
7449   if (operands[0])              /* avoid unused code warning */
7450     {
7451       gen_conditional_branch (operands, LEU);
7452       DONE;
7453     }
7454 }")
7455
7456 \f
7457 ;;
7458 ;;  ....................
7459 ;;
7460 ;;      SETTING A REGISTER FROM A COMPARISON
7461 ;;
7462 ;;  ....................
7463
7464 (define_expand "seq"
7465   [(set (match_operand:SI 0 "register_operand" "=d")
7466         (eq:SI (match_dup 1)
7467                (match_dup 2)))]
7468   ""
7469   "
7470 {
7471   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7472     FAIL;
7473
7474   /* set up operands from compare.  */
7475   operands[1] = branch_cmp[0];
7476   operands[2] = branch_cmp[1];
7477
7478   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7479     {
7480       gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
7481       DONE;
7482     }
7483
7484   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
7485     operands[2] = force_reg (SImode, operands[2]);
7486
7487   /* fall through and generate default code */
7488 }")
7489
7490
7491 (define_insn "seq_si_zero"
7492   [(set (match_operand:SI 0 "register_operand" "=d")
7493         (eq:SI (match_operand:SI 1 "register_operand" "d")
7494                (const_int 0)))]
7495   "!TARGET_MIPS16"
7496   "sltu\\t%0,%1,1"
7497   [(set_attr "type"     "arith")
7498    (set_attr "mode"     "SI")
7499    (set_attr "length"   "1")])
7500
7501 (define_insn ""
7502   [(set (match_operand:SI 0 "register_operand" "=t")
7503         (eq:SI (match_operand:SI 1 "register_operand" "d")
7504                (const_int 0)))]
7505   "TARGET_MIPS16"
7506   "sltu\\t%1,1"
7507   [(set_attr "type"     "arith")
7508    (set_attr "mode"     "SI")
7509    (set_attr "length"   "1")])
7510
7511 (define_insn "seq_di_zero"
7512   [(set (match_operand:DI 0 "register_operand" "=d")
7513         (eq:DI (match_operand:DI 1 "se_register_operand" "d")
7514                (const_int 0)))]
7515   "TARGET_64BIT && !TARGET_MIPS16"
7516   "sltu\\t%0,%1,1"
7517   [(set_attr "type"     "arith")
7518    (set_attr "mode"     "DI")
7519    (set_attr "length"   "1")])
7520
7521 (define_insn ""
7522   [(set (match_operand:DI 0 "register_operand" "=t")
7523         (eq:DI (match_operand:DI 1 "se_register_operand" "d")
7524                (const_int 0)))]
7525   "TARGET_64BIT && TARGET_MIPS16"
7526   "sltu\\t%1,1"
7527   [(set_attr "type"     "arith")
7528    (set_attr "mode"     "DI")
7529    (set_attr "length"   "1")])
7530
7531 (define_insn "seq_si"
7532   [(set (match_operand:SI 0 "register_operand" "=d,d")
7533         (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
7534                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
7535   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7536   "@
7537    xor\\t%0,%1,%2\;sltu\\t%0,%0,1
7538    xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
7539   [(set_attr "type"     "arith")
7540    (set_attr "mode"     "SI")
7541    (set_attr "length"   "2")])
7542
7543 (define_split
7544   [(set (match_operand:SI 0 "register_operand" "")
7545         (eq:SI (match_operand:SI 1 "register_operand" "")
7546                (match_operand:SI 2 "uns_arith_operand" "")))]
7547   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
7548     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
7549   [(set (match_dup 0)
7550         (xor:SI (match_dup 1)
7551                 (match_dup 2)))
7552    (set (match_dup 0)
7553         (ltu:SI (match_dup 0)
7554                 (const_int 1)))]
7555   "")
7556
7557 (define_insn "seq_di"
7558   [(set (match_operand:DI 0 "register_operand" "=d,d")
7559         (eq:DI (match_operand:DI 1 "se_register_operand" "%d,d")
7560                (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
7561   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7562   "@
7563    xor\\t%0,%1,%2\;sltu\\t%0,%0,1
7564    xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
7565   [(set_attr "type"     "arith")
7566    (set_attr "mode"     "DI")
7567    (set_attr "length"   "2")])
7568
7569 (define_split
7570   [(set (match_operand:DI 0 "register_operand" "")
7571         (eq:DI (match_operand:DI 1 "se_register_operand" "")
7572                (match_operand:DI 2 "se_uns_arith_operand" "")))]
7573   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7574     && !TARGET_MIPS16
7575     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
7576   [(set (match_dup 0)
7577         (xor:DI (match_dup 1)
7578                 (match_dup 2)))
7579    (set (match_dup 0)
7580         (ltu:DI (match_dup 0)
7581                 (const_int 1)))]
7582   "")
7583
7584 ;; On the mips16 the default code is better than using sltu.
7585
7586 (define_expand "sne"
7587   [(set (match_operand:SI 0 "register_operand" "=d")
7588         (ne:SI (match_dup 1)
7589                (match_dup 2)))]
7590   "!TARGET_MIPS16"
7591   "
7592 {
7593   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7594     FAIL;
7595
7596   /* set up operands from compare.  */
7597   operands[1] = branch_cmp[0];
7598   operands[2] = branch_cmp[1];
7599
7600   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
7601     {
7602       gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
7603       DONE;
7604     }
7605
7606   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
7607     operands[2] = force_reg (SImode, operands[2]);
7608
7609   /* fall through and generate default code */
7610 }")
7611
7612 (define_insn "sne_si_zero"
7613   [(set (match_operand:SI 0 "register_operand" "=d")
7614         (ne:SI (match_operand:SI 1 "register_operand" "d")
7615                (const_int 0)))]
7616   "!TARGET_MIPS16"
7617   "sltu\\t%0,%.,%1"
7618   [(set_attr "type"     "arith")
7619    (set_attr "mode"     "SI")
7620    (set_attr "length"   "1")])
7621
7622 (define_insn "sne_di_zero"
7623   [(set (match_operand:DI 0 "register_operand" "=d")
7624         (ne:DI (match_operand:DI 1 "se_register_operand" "d")
7625                (const_int 0)))]
7626   "TARGET_64BIT && !TARGET_MIPS16"
7627   "sltu\\t%0,%.,%1"
7628   [(set_attr "type"     "arith")
7629    (set_attr "mode"     "DI")
7630    (set_attr "length"   "1")])
7631
7632 (define_insn "sne_si"
7633   [(set (match_operand:SI 0 "register_operand" "=d,d")
7634         (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
7635                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
7636   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7637   "@
7638     xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
7639     xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
7640   [(set_attr "type"     "arith")
7641    (set_attr "mode"     "SI")
7642    (set_attr "length"   "2")])
7643
7644 (define_split
7645   [(set (match_operand:SI 0 "register_operand" "")
7646         (ne:SI (match_operand:SI 1 "register_operand" "")
7647                (match_operand:SI 2 "uns_arith_operand" "")))]
7648   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
7649     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
7650   [(set (match_dup 0)
7651         (xor:SI (match_dup 1)
7652                 (match_dup 2)))
7653    (set (match_dup 0)
7654         (gtu:SI (match_dup 0)
7655                 (const_int 0)))]
7656   "")
7657
7658 (define_insn "sne_di"
7659   [(set (match_operand:DI 0 "register_operand" "=d,d")
7660         (ne:DI (match_operand:DI 1 "se_register_operand" "%d,d")
7661                (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
7662   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7663   "@
7664     xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
7665     xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
7666   [(set_attr "type"     "arith")
7667    (set_attr "mode"     "DI")
7668    (set_attr "length"   "2")])
7669
7670 (define_split
7671   [(set (match_operand:DI 0 "register_operand" "")
7672         (ne:DI (match_operand:DI 1 "se_register_operand" "")
7673                (match_operand:DI 2 "se_uns_arith_operand" "")))]
7674   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7675     && !TARGET_MIPS16
7676     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
7677   [(set (match_dup 0)
7678         (xor:DI (match_dup 1)
7679                 (match_dup 2)))
7680    (set (match_dup 0)
7681         (gtu:DI (match_dup 0)
7682                 (const_int 0)))]
7683   "")
7684
7685 (define_expand "sgt"
7686   [(set (match_operand:SI 0 "register_operand" "=d")
7687         (gt:SI (match_dup 1)
7688                (match_dup 2)))]
7689   ""
7690   "
7691 {
7692   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7693     FAIL;
7694
7695   /* set up operands from compare.  */
7696   operands[1] = branch_cmp[0];
7697   operands[2] = branch_cmp[1];
7698
7699   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7700     {
7701       gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
7702       DONE;
7703     }
7704
7705   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
7706     operands[2] = force_reg (SImode, operands[2]);
7707
7708   /* fall through and generate default code */
7709 }")
7710
7711 (define_insn "sgt_si"
7712   [(set (match_operand:SI 0 "register_operand" "=d")
7713         (gt:SI (match_operand:SI 1 "register_operand" "d")
7714                (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
7715   "!TARGET_MIPS16"
7716   "slt\\t%0,%z2,%1"
7717   [(set_attr "type"     "arith")
7718    (set_attr "mode"     "SI")
7719    (set_attr "length"   "1")])
7720
7721 (define_insn ""
7722   [(set (match_operand:SI 0 "register_operand" "=t")
7723         (gt:SI (match_operand:SI 1 "register_operand" "d")
7724                (match_operand:SI 2 "register_operand" "d")))]
7725   "TARGET_MIPS16"
7726   "slt\\t%2,%1"
7727   [(set_attr "type"     "arith")
7728    (set_attr "mode"     "SI")
7729    (set_attr "length"   "1")])
7730
7731 (define_insn "sgt_di"
7732   [(set (match_operand:DI 0 "register_operand" "=d")
7733         (gt:DI (match_operand:DI 1 "se_register_operand" "d")
7734                (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
7735   "TARGET_64BIT && !TARGET_MIPS16"
7736   "slt\\t%0,%z2,%1"
7737   [(set_attr "type"     "arith")
7738    (set_attr "mode"     "DI")
7739    (set_attr "length"   "1")])
7740
7741 (define_insn ""
7742   [(set (match_operand:DI 0 "register_operand" "=d")
7743         (gt:DI (match_operand:DI 1 "se_register_operand" "d")
7744                (match_operand:DI 2 "se_register_operand" "d")))]
7745   "TARGET_64BIT && TARGET_MIPS16"
7746   "slt\\t%2,%1"
7747   [(set_attr "type"     "arith")
7748    (set_attr "mode"     "DI")
7749    (set_attr "length"   "1")])
7750
7751 (define_expand "sge"
7752   [(set (match_operand:SI 0 "register_operand" "=d")
7753         (ge:SI (match_dup 1)
7754                (match_dup 2)))]
7755   ""
7756   "
7757 {
7758   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7759     FAIL;
7760
7761   /* set up operands from compare.  */
7762   operands[1] = branch_cmp[0];
7763   operands[2] = branch_cmp[1];
7764
7765   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7766     {
7767       gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
7768       DONE;
7769     }
7770
7771   /* fall through and generate default code */
7772 }")
7773
7774 (define_insn "sge_si"
7775   [(set (match_operand:SI 0 "register_operand" "=d")
7776         (ge:SI (match_operand:SI 1 "register_operand" "d")
7777                (match_operand:SI 2 "arith_operand" "dI")))]
7778   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7779   "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
7780   [(set_attr "type"     "arith")
7781    (set_attr "mode"     "SI")
7782    (set_attr "length"   "2")])
7783
7784 (define_split
7785   [(set (match_operand:SI 0 "register_operand" "")
7786         (ge:SI (match_operand:SI 1 "register_operand" "")
7787                (match_operand:SI 2 "arith_operand" "")))]
7788   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
7789   [(set (match_dup 0)
7790         (lt:SI (match_dup 1)
7791                (match_dup 2)))
7792    (set (match_dup 0)
7793         (xor:SI (match_dup 0)
7794                 (const_int 1)))]
7795   "")
7796
7797 (define_insn "sge_di"
7798   [(set (match_operand:DI 0 "register_operand" "=d")
7799         (ge:DI (match_operand:DI 1 "se_register_operand" "d")
7800                (match_operand:DI 2 "se_arith_operand" "dI")))]
7801   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7802   "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
7803   [(set_attr "type"     "arith")
7804    (set_attr "mode"     "DI")
7805    (set_attr "length"   "2")])
7806
7807 (define_split
7808   [(set (match_operand:DI 0 "register_operand" "")
7809         (ge:DI (match_operand:DI 1 "se_register_operand" "")
7810                (match_operand:DI 2 "se_arith_operand" "")))]
7811   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7812    && !TARGET_MIPS16"
7813   [(set (match_dup 0)
7814         (lt:DI (match_dup 1)
7815                (match_dup 2)))
7816    (set (match_dup 0)
7817         (xor:DI (match_dup 0)
7818                 (const_int 1)))]
7819   "")
7820
7821 (define_expand "slt"
7822   [(set (match_operand:SI 0 "register_operand" "=d")
7823         (lt:SI (match_dup 1)
7824                (match_dup 2)))]
7825   ""
7826   "
7827 {
7828   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7829     FAIL;
7830
7831   /* set up operands from compare.  */
7832   operands[1] = branch_cmp[0];
7833   operands[2] = branch_cmp[1];
7834
7835   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7836     {
7837       gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
7838       DONE;
7839     }
7840
7841   /* fall through and generate default code */
7842 }")
7843
7844 (define_insn "slt_si"
7845   [(set (match_operand:SI 0 "register_operand" "=d")
7846         (lt:SI (match_operand:SI 1 "register_operand" "d")
7847                (match_operand:SI 2 "arith_operand" "dI")))]
7848   "!TARGET_MIPS16"
7849   "slt\\t%0,%1,%2"
7850   [(set_attr "type"     "arith")
7851    (set_attr "mode"     "SI")
7852    (set_attr "length"   "1")])
7853
7854 (define_insn ""
7855   [(set (match_operand:SI 0 "register_operand" "=t,t")
7856         (lt:SI (match_operand:SI 1 "register_operand" "d,d")
7857                (match_operand:SI 2 "arith_operand" "d,I")))]
7858   "TARGET_MIPS16"
7859   "slt\\t%1,%2"
7860   [(set_attr "type"     "arith")
7861    (set_attr "mode"     "SI")
7862    (set_attr_alternative "length"
7863                 [(const_int 1)
7864                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
7865                                (const_int 1)
7866                                (const_int 2))])])
7867
7868 (define_insn "slt_di"
7869   [(set (match_operand:DI 0 "register_operand" "=d")
7870         (lt:DI (match_operand:DI 1 "se_register_operand" "d")
7871                (match_operand:DI 2 "se_arith_operand" "dI")))]
7872   "TARGET_64BIT && !TARGET_MIPS16"
7873   "slt\\t%0,%1,%2"
7874   [(set_attr "type"     "arith")
7875    (set_attr "mode"     "DI")
7876    (set_attr "length"   "1")])
7877
7878 (define_insn ""
7879   [(set (match_operand:DI 0 "register_operand" "=t,t")
7880         (lt:DI (match_operand:DI 1 "se_register_operand" "d,d")
7881                (match_operand:DI 2 "se_arith_operand" "d,I")))]
7882   "TARGET_64BIT && TARGET_MIPS16"
7883   "slt\\t%1,%2"
7884   [(set_attr "type"     "arith")
7885    (set_attr "mode"     "DI")
7886    (set_attr_alternative "length"
7887                 [(const_int 1)
7888                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
7889                                (const_int 1)
7890                                (const_int 2))])])
7891
7892 (define_expand "sle"
7893   [(set (match_operand:SI 0 "register_operand" "=d")
7894         (le:SI (match_dup 1)
7895                (match_dup 2)))]
7896   ""
7897   "
7898 {
7899   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7900     FAIL;
7901
7902   /* set up operands from compare.  */
7903   operands[1] = branch_cmp[0];
7904   operands[2] = branch_cmp[1];
7905
7906   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7907     {
7908       gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
7909       DONE;
7910     }
7911
7912   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
7913     operands[2] = force_reg (SImode, operands[2]);
7914
7915   /* fall through and generate default code */
7916 }")
7917
7918 (define_insn "sle_si_const"
7919   [(set (match_operand:SI 0 "register_operand" "=d")
7920         (le:SI (match_operand:SI 1 "register_operand" "d")
7921                (match_operand:SI 2 "small_int" "I")))]
7922   "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7923   "*
7924 {
7925   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
7926   return \"slt\\t%0,%1,%2\";
7927 }"
7928   [(set_attr "type"     "arith")
7929    (set_attr "mode"     "SI")
7930    (set_attr "length"   "1")])
7931
7932 (define_insn ""
7933   [(set (match_operand:SI 0 "register_operand" "=t")
7934         (le:SI (match_operand:SI 1 "register_operand" "d")
7935                (match_operand:SI 2 "small_int" "I")))]
7936   "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7937   "*
7938 {
7939   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
7940   return \"slt\\t%1,%2\";
7941 }"
7942   [(set_attr "type"     "arith")
7943    (set_attr "mode"     "SI")
7944    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
7945                                       (const_int 1)
7946                                       (const_int 2)))])
7947
7948 (define_insn "sle_di_const"
7949   [(set (match_operand:DI 0 "register_operand" "=d")
7950         (le:DI (match_operand:DI 1 "se_register_operand" "d")
7951                (match_operand:DI 2 "small_int" "I")))]
7952   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7953   "*
7954 {
7955   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
7956   return \"slt\\t%0,%1,%2\";
7957 }"
7958   [(set_attr "type"     "arith")
7959    (set_attr "mode"     "DI")
7960    (set_attr "length"   "1")])
7961
7962 (define_insn ""
7963   [(set (match_operand:DI 0 "register_operand" "=t")
7964         (le:DI (match_operand:DI 1 "se_register_operand" "d")
7965                (match_operand:DI 2 "small_int" "I")))]
7966   "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7967   "*
7968 {
7969   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
7970   return \"slt\\t%1,%2\";
7971 }"
7972   [(set_attr "type"     "arith")
7973    (set_attr "mode"     "DI")
7974    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
7975                                       (const_int 1)
7976                                       (const_int 2)))])
7977
7978 (define_insn "sle_si_reg"
7979   [(set (match_operand:SI 0 "register_operand" "=d")
7980         (le:SI (match_operand:SI 1 "register_operand" "d")
7981                (match_operand:SI 2 "register_operand" "d")))]
7982   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7983   "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
7984   [(set_attr "type"     "arith")
7985    (set_attr "mode"     "SI")
7986    (set_attr "length"   "2")])
7987
7988 (define_split
7989   [(set (match_operand:SI 0 "register_operand" "")
7990         (le:SI (match_operand:SI 1 "register_operand" "")
7991                (match_operand:SI 2 "register_operand" "")))]
7992   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
7993   [(set (match_dup 0)
7994         (lt:SI (match_dup 2)
7995                (match_dup 1)))
7996    (set (match_dup 0)
7997         (xor:SI (match_dup 0)
7998                 (const_int 1)))]
7999   "")
8000
8001 (define_insn "sle_di_reg"
8002   [(set (match_operand:DI 0 "register_operand" "=d")
8003         (le:DI (match_operand:DI 1 "se_register_operand" "d")
8004                (match_operand:DI 2 "se_register_operand" "d")))]
8005   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8006   "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8007   [(set_attr "type"     "arith")
8008    (set_attr "mode"     "DI")
8009    (set_attr "length"   "2")])
8010
8011 (define_split
8012   [(set (match_operand:DI 0 "register_operand" "")
8013         (le:DI (match_operand:DI 1 "se_register_operand" "")
8014                (match_operand:DI 2 "se_register_operand" "")))]
8015   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8016    && !TARGET_MIPS16"
8017   [(set (match_dup 0)
8018         (lt:DI (match_dup 2)
8019                (match_dup 1)))
8020    (set (match_dup 0)
8021         (xor:DI (match_dup 0)
8022                 (const_int 1)))]
8023   "")
8024
8025 (define_expand "sgtu"
8026   [(set (match_operand:SI 0 "register_operand" "=d")
8027         (gtu:SI (match_dup 1)
8028                 (match_dup 2)))]
8029   ""
8030   "
8031 {
8032   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8033     FAIL;
8034
8035   /* set up operands from compare.  */
8036   operands[1] = branch_cmp[0];
8037   operands[2] = branch_cmp[1];
8038
8039   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8040     {
8041       gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
8042       DONE;
8043     }
8044
8045   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
8046     operands[2] = force_reg (SImode, operands[2]);
8047
8048   /* fall through and generate default code */
8049 }")
8050
8051 (define_insn "sgtu_si"
8052   [(set (match_operand:SI 0 "register_operand" "=d")
8053         (gtu:SI (match_operand:SI 1 "register_operand" "d")
8054                 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
8055   ""
8056   "sltu\\t%0,%z2,%1"
8057   [(set_attr "type"     "arith")
8058    (set_attr "mode"     "SI")
8059    (set_attr "length"   "1")])
8060
8061 (define_insn ""
8062   [(set (match_operand:SI 0 "register_operand" "=t")
8063         (gtu:SI (match_operand:SI 1 "register_operand" "d")
8064                 (match_operand:SI 2 "register_operand" "d")))]
8065   ""
8066   "sltu\\t%2,%1"
8067   [(set_attr "type"     "arith")
8068    (set_attr "mode"     "SI")
8069    (set_attr "length"   "1")])
8070
8071 (define_insn "sgtu_di"
8072   [(set (match_operand:DI 0 "register_operand" "=d")
8073         (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
8074                 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
8075   "TARGET_64BIT"
8076   "sltu\\t%0,%z2,%1"
8077   [(set_attr "type"     "arith")
8078    (set_attr "mode"     "DI")
8079    (set_attr "length"   "1")])
8080
8081 (define_insn ""
8082   [(set (match_operand:DI 0 "register_operand" "=t")
8083         (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
8084                 (match_operand:DI 2 "se_register_operand" "d")))]
8085   "TARGET_64BIT"
8086   "sltu\\t%2,%1"
8087   [(set_attr "type"     "arith")
8088    (set_attr "mode"     "DI")
8089    (set_attr "length"   "1")])
8090
8091 (define_expand "sgeu"
8092   [(set (match_operand:SI 0 "register_operand" "=d")
8093         (geu:SI (match_dup 1)
8094                 (match_dup 2)))]
8095   ""
8096   "
8097 {
8098   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8099     FAIL;
8100
8101   /* set up operands from compare.  */
8102   operands[1] = branch_cmp[0];
8103   operands[2] = branch_cmp[1];
8104
8105   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8106     {
8107       gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
8108       DONE;
8109     }
8110
8111   /* fall through and generate default code */
8112 }")
8113
8114 (define_insn "sgeu_si"
8115   [(set (match_operand:SI 0 "register_operand" "=d")
8116         (geu:SI (match_operand:SI 1 "register_operand" "d")
8117                 (match_operand:SI 2 "arith_operand" "dI")))]
8118   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8119   "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8120   [(set_attr "type"     "arith")
8121    (set_attr "mode"     "SI")
8122    (set_attr "length"   "2")])
8123
8124 (define_split
8125   [(set (match_operand:SI 0 "register_operand" "")
8126         (geu:SI (match_operand:SI 1 "register_operand" "")
8127                 (match_operand:SI 2 "arith_operand" "")))]
8128   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8129   [(set (match_dup 0)
8130         (ltu:SI (match_dup 1)
8131                 (match_dup 2)))
8132    (set (match_dup 0)
8133         (xor:SI (match_dup 0)
8134                 (const_int 1)))]
8135   "")
8136
8137 (define_insn "sgeu_di"
8138   [(set (match_operand:DI 0 "register_operand" "=d")
8139         (geu:DI (match_operand:DI 1 "se_register_operand" "d")
8140                 (match_operand:DI 2 "se_arith_operand" "dI")))]
8141   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8142   "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
8143   [(set_attr "type"     "arith")
8144    (set_attr "mode"     "DI")
8145    (set_attr "length"   "2")])
8146
8147 (define_split
8148   [(set (match_operand:DI 0 "register_operand" "")
8149         (geu:DI (match_operand:DI 1 "se_register_operand" "")
8150                 (match_operand:DI 2 "se_arith_operand" "")))]
8151   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8152    && !TARGET_MIPS16"
8153   [(set (match_dup 0)
8154         (ltu:DI (match_dup 1)
8155                 (match_dup 2)))
8156    (set (match_dup 0)
8157         (xor:DI (match_dup 0)
8158                 (const_int 1)))]
8159   "")
8160
8161 (define_expand "sltu"
8162   [(set (match_operand:SI 0 "register_operand" "=d")
8163         (ltu:SI (match_dup 1)
8164                 (match_dup 2)))]
8165   ""
8166   "
8167 {
8168   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8169     FAIL;
8170
8171   /* set up operands from compare.  */
8172   operands[1] = branch_cmp[0];
8173   operands[2] = branch_cmp[1];
8174
8175   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8176     {
8177       gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
8178       DONE;
8179     }
8180
8181   /* fall through and generate default code */
8182 }")
8183
8184 (define_insn "sltu_si"
8185   [(set (match_operand:SI 0 "register_operand" "=d")
8186         (ltu:SI (match_operand:SI 1 "register_operand" "d")
8187                 (match_operand:SI 2 "arith_operand" "dI")))]
8188   "!TARGET_MIPS16"
8189   "sltu\\t%0,%1,%2"
8190   [(set_attr "type"     "arith")
8191    (set_attr "mode"     "SI")
8192    (set_attr "length"   "1")])
8193
8194 (define_insn ""
8195   [(set (match_operand:SI 0 "register_operand" "=t,t")
8196         (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
8197                 (match_operand:SI 2 "arith_operand" "d,I")))]
8198   "TARGET_MIPS16"
8199   "sltu\\t%1,%2"
8200   [(set_attr "type"     "arith")
8201    (set_attr "mode"     "SI")
8202    (set_attr_alternative "length"
8203                 [(const_int 1)
8204                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8205                                (const_int 1)
8206                                (const_int 2))])])
8207
8208 (define_insn "sltu_di"
8209   [(set (match_operand:DI 0 "register_operand" "=d")
8210         (ltu:DI (match_operand:DI 1 "se_register_operand" "d")
8211                 (match_operand:DI 2 "se_arith_operand" "dI")))]
8212   "TARGET_64BIT && !TARGET_MIPS16"
8213   "sltu\\t%0,%1,%2"
8214   [(set_attr "type"     "arith")
8215    (set_attr "mode"     "DI")
8216    (set_attr "length"   "1")])
8217
8218 (define_insn ""
8219   [(set (match_operand:DI 0 "register_operand" "=t,t")
8220         (ltu:DI (match_operand:DI 1 "se_register_operand" "d,d")
8221                 (match_operand:DI 2 "se_arith_operand" "d,I")))]
8222   "TARGET_64BIT && TARGET_MIPS16"
8223   "sltu\\t%1,%2"
8224   [(set_attr "type"     "arith")
8225    (set_attr "mode"     "DI")
8226    (set_attr_alternative "length"
8227                 [(const_int 1)
8228                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
8229                                (const_int 1)
8230                                (const_int 2))])])
8231
8232 (define_expand "sleu"
8233   [(set (match_operand:SI 0 "register_operand" "=d")
8234         (leu:SI (match_dup 1)
8235                 (match_dup 2)))]
8236   ""
8237   "
8238 {
8239   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
8240     FAIL;
8241
8242   /* set up operands from compare.  */
8243   operands[1] = branch_cmp[0];
8244   operands[2] = branch_cmp[1];
8245
8246   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
8247     {
8248       gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
8249       DONE;
8250     }
8251
8252   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
8253     operands[2] = force_reg (SImode, operands[2]);
8254
8255   /* fall through and generate default code */
8256 }")
8257
8258 (define_insn "sleu_si_const"
8259   [(set (match_operand:SI 0 "register_operand" "=d")
8260         (leu:SI (match_operand:SI 1 "register_operand" "d")
8261                 (match_operand:SI 2 "small_int" "I")))]
8262   "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8263   "*
8264 {
8265   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
8266   return \"sltu\\t%0,%1,%2\";
8267 }"
8268   [(set_attr "type"     "arith")
8269    (set_attr "mode"     "SI")
8270    (set_attr "length"   "1")])
8271
8272 (define_insn ""
8273   [(set (match_operand:SI 0 "register_operand" "=t")
8274         (leu:SI (match_operand:SI 1 "register_operand" "d")
8275                 (match_operand:SI 2 "small_int" "I")))]
8276   "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8277   "*
8278 {
8279   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
8280   return \"sltu\\t%1,%2\";
8281 }"
8282   [(set_attr "type"     "arith")
8283    (set_attr "mode"     "SI")
8284    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8285                                       (const_int 1)
8286                                       (const_int 2)))])
8287
8288 (define_insn "sleu_di_const"
8289   [(set (match_operand:DI 0 "register_operand" "=d")
8290         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
8291                 (match_operand:DI 2 "small_int" "I")))]
8292   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8293   "*
8294 {
8295   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
8296   return \"sltu\\t%0,%1,%2\";
8297 }"
8298   [(set_attr "type"     "arith")
8299    (set_attr "mode"     "DI")
8300    (set_attr "length"   "1")])
8301
8302 (define_insn ""
8303   [(set (match_operand:DI 0 "register_operand" "=t")
8304         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
8305                 (match_operand:DI 2 "small_int" "I")))]
8306   "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
8307   "*
8308 {
8309   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
8310   return \"sltu\\t%1,%2\";
8311 }"
8312   [(set_attr "type"     "arith")
8313    (set_attr "mode"     "DI")
8314    (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
8315                                       (const_int 1)
8316                                       (const_int 2)))])
8317
8318 (define_insn "sleu_si_reg"
8319   [(set (match_operand:SI 0 "register_operand" "=d")
8320         (leu:SI (match_operand:SI 1 "register_operand" "d")
8321                 (match_operand:SI 2 "register_operand" "d")))]
8322   "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8323   "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8324   [(set_attr "type"     "arith")
8325    (set_attr "mode"     "SI")
8326    (set_attr "length"   "2")])
8327
8328 (define_split
8329   [(set (match_operand:SI 0 "register_operand" "")
8330         (leu:SI (match_operand:SI 1 "register_operand" "")
8331                 (match_operand:SI 2 "register_operand" "")))]
8332   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
8333   [(set (match_dup 0)
8334         (ltu:SI (match_dup 2)
8335                 (match_dup 1)))
8336    (set (match_dup 0)
8337         (xor:SI (match_dup 0)
8338                 (const_int 1)))]
8339   "")
8340
8341 (define_insn "sleu_di_reg"
8342   [(set (match_operand:DI 0 "register_operand" "=d")
8343         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
8344                 (match_operand:DI 2 "se_register_operand" "d")))]
8345   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
8346   "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
8347   [(set_attr "type"     "arith")
8348    (set_attr "mode"     "DI")
8349    (set_attr "length"   "2")])
8350
8351 (define_split
8352   [(set (match_operand:DI 0 "register_operand" "")
8353         (leu:DI (match_operand:DI 1 "se_register_operand" "")
8354                 (match_operand:DI 2 "se_register_operand" "")))]
8355   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
8356    && !TARGET_MIPS16"
8357   [(set (match_dup 0)
8358         (ltu:DI (match_dup 2)
8359                 (match_dup 1)))
8360    (set (match_dup 0)
8361         (xor:DI (match_dup 0)
8362                 (const_int 1)))]
8363   "")
8364
8365 \f
8366 ;;
8367 ;;  ....................
8368 ;;
8369 ;;      FLOATING POINT COMPARISONS
8370 ;;
8371 ;;  ....................
8372
8373 (define_insn "seq_df"
8374   [(set (match_operand:CC 0 "register_operand" "=z")
8375         (eq:CC (match_operand:DF 1 "register_operand" "f")
8376                (match_operand:DF 2 "register_operand" "f")))]
8377   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8378   "*
8379 {
8380   return mips_fill_delay_slot (\"c.eq.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8381 }"
8382  [(set_attr "type"      "fcmp")
8383   (set_attr "mode"      "FPSW")
8384   (set_attr "length"    "1")])
8385
8386 (define_insn "slt_df"
8387   [(set (match_operand:CC 0 "register_operand" "=z")
8388         (lt:CC (match_operand:DF 1 "register_operand" "f")
8389                (match_operand:DF 2 "register_operand" "f")))]
8390   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8391   "*
8392 {
8393   return mips_fill_delay_slot (\"c.lt.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8394 }"
8395  [(set_attr "type"      "fcmp")
8396   (set_attr "mode"      "FPSW")
8397   (set_attr "length"    "1")])
8398
8399 (define_insn "sle_df"
8400   [(set (match_operand:CC 0 "register_operand" "=z")
8401         (le:CC (match_operand:DF 1 "register_operand" "f")
8402                (match_operand:DF 2 "register_operand" "f")))]
8403   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8404   "*
8405 {
8406   return mips_fill_delay_slot (\"c.le.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8407 }"
8408  [(set_attr "type"      "fcmp")
8409   (set_attr "mode"      "FPSW")
8410   (set_attr "length"    "1")])
8411
8412 (define_insn "sgt_df"
8413   [(set (match_operand:CC 0 "register_operand" "=z")
8414         (gt:CC (match_operand:DF 1 "register_operand" "f")
8415                (match_operand:DF 2 "register_operand" "f")))]
8416   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8417   "*
8418 {
8419   return mips_fill_delay_slot (\"c.lt.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
8420 }"
8421  [(set_attr "type"      "fcmp")
8422   (set_attr "mode"      "FPSW")
8423   (set_attr "length"    "1")])
8424
8425 (define_insn "sge_df"
8426   [(set (match_operand:CC 0 "register_operand" "=z")
8427         (ge:CC (match_operand:DF 1 "register_operand" "f")
8428                (match_operand:DF 2 "register_operand" "f")))]
8429   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8430   "*
8431 {
8432   return mips_fill_delay_slot (\"c.le.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
8433 }"
8434  [(set_attr "type"      "fcmp")
8435   (set_attr "mode"      "FPSW")
8436   (set_attr "length"    "1")])
8437
8438 (define_insn "seq_sf"
8439   [(set (match_operand:CC 0 "register_operand" "=z")
8440         (eq:CC (match_operand:SF 1 "register_operand" "f")
8441                (match_operand:SF 2 "register_operand" "f")))]
8442   "TARGET_HARD_FLOAT"
8443   "*
8444 {
8445   return mips_fill_delay_slot (\"c.eq.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8446 }"
8447  [(set_attr "type"      "fcmp")
8448   (set_attr "mode"      "FPSW")
8449   (set_attr "length"    "1")])
8450
8451 (define_insn "slt_sf"
8452   [(set (match_operand:CC 0 "register_operand" "=z")
8453         (lt:CC (match_operand:SF 1 "register_operand" "f")
8454                (match_operand:SF 2 "register_operand" "f")))]
8455   "TARGET_HARD_FLOAT"
8456   "*
8457 {
8458   return mips_fill_delay_slot (\"c.lt.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8459 }"
8460  [(set_attr "type"      "fcmp")
8461   (set_attr "mode"      "FPSW")
8462   (set_attr "length"    "1")])
8463
8464 (define_insn "sle_sf"
8465   [(set (match_operand:CC 0 "register_operand" "=z")
8466         (le:CC (match_operand:SF 1 "register_operand" "f")
8467                (match_operand:SF 2 "register_operand" "f")))]
8468   "TARGET_HARD_FLOAT"
8469   "*
8470 {
8471   return mips_fill_delay_slot (\"c.le.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
8472 }"
8473  [(set_attr "type"      "fcmp")
8474   (set_attr "mode"      "FPSW")
8475   (set_attr "length"    "1")])
8476
8477 (define_insn "sgt_sf"
8478   [(set (match_operand:CC 0 "register_operand" "=z")
8479         (gt:CC (match_operand:SF 1 "register_operand" "f")
8480                (match_operand:SF 2 "register_operand" "f")))]
8481   "TARGET_HARD_FLOAT"
8482   "*
8483 {
8484   return mips_fill_delay_slot (\"c.lt.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
8485 }"
8486  [(set_attr "type"      "fcmp")
8487   (set_attr "mode"      "FPSW")
8488   (set_attr "length"    "1")])
8489
8490 (define_insn "sge_sf"
8491   [(set (match_operand:CC 0 "register_operand" "=z")
8492         (ge:CC (match_operand:SF 1 "register_operand" "f")
8493                (match_operand:SF 2 "register_operand" "f")))]
8494   "TARGET_HARD_FLOAT"
8495   "*
8496 {
8497   return mips_fill_delay_slot (\"c.le.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
8498 }"
8499  [(set_attr "type"      "fcmp")
8500   (set_attr "mode"      "FPSW")
8501   (set_attr "length"    "1")])
8502
8503 \f
8504 ;;
8505 ;;  ....................
8506 ;;
8507 ;;      UNCONDITIONAL BRANCHES
8508 ;;
8509 ;;  ....................
8510
8511 ;; Unconditional branches.
8512
8513 (define_insn "jump"
8514   [(set (pc)
8515         (label_ref (match_operand 0 "" "")))]
8516   "!TARGET_MIPS16"
8517   "*
8518 {
8519   if (GET_CODE (operands[0]) == REG)
8520     return \"%*j\\t%0\";
8521   /* ??? I don't know why this is necessary.  This works around an
8522      assembler problem that appears when a label is defined, then referenced
8523      in a switch table, then used in a `j' instruction.  */
8524   else if (mips_abi != ABI_32)
8525     return \"%*b\\t%l0\";
8526   else  
8527     return \"%*j\\t%l0\";
8528 }"
8529   [(set_attr "type"     "jump")
8530    (set_attr "mode"     "none")
8531    (set_attr "length"   "1")])
8532
8533 ;; We need a different insn for the mips16, because a mips16 branch
8534 ;; does not have a delay slot.
8535
8536 (define_insn ""
8537   [(set (pc)
8538         (label_ref (match_operand 0 "" "")))]
8539   "TARGET_MIPS16 && GET_CODE (operands[0]) != REG"
8540   "b\\t%l0"
8541   [(set_attr "type"     "branch")
8542    (set_attr "mode"     "none")
8543    (set_attr "length"   "2")])
8544
8545 (define_expand "indirect_jump"
8546   [(set (pc) (match_operand 0 "register_operand" "d"))]
8547   ""
8548   "
8549 {
8550   rtx dest;
8551
8552   if (operands[0])              /* eliminate unused code warnings */
8553     {
8554       dest = operands[0];
8555       if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
8556         operands[0] = copy_to_mode_reg (Pmode, dest);
8557
8558       if (!TARGET_LONG64)
8559         emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
8560       else
8561         emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
8562
8563       DONE;
8564     }
8565 }")
8566
8567 (define_insn "indirect_jump_internal1"
8568   [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
8569   "!TARGET_LONG64"
8570   "%*j\\t%0"
8571   [(set_attr "type"     "jump")
8572    (set_attr "mode"     "none")
8573    (set_attr "length"   "1")])
8574
8575 (define_insn "indirect_jump_internal2"
8576   [(set (pc) (match_operand:DI 0 "se_register_operand" "d"))]
8577   "TARGET_LONG64"
8578   "%*j\\t%0"
8579   [(set_attr "type"     "jump")
8580    (set_attr "mode"     "none")
8581    (set_attr "length"   "1")])
8582
8583 (define_expand "tablejump"
8584   [(set (pc)
8585         (match_operand 0 "register_operand" "d"))
8586    (use (label_ref (match_operand 1 "" "")))]
8587   ""
8588   "
8589 {
8590   rtx dest;
8591
8592   if (operands[0])              /* eliminate unused code warnings */
8593     {
8594       if (TARGET_MIPS16)
8595         {
8596           if (GET_MODE (operands[0]) != HImode)
8597             abort ();
8598           if (!TARGET_LONG64)
8599             emit_jump_insn (gen_tablejump_mips161 (operands[0], operands[1]));
8600           else
8601             emit_jump_insn (gen_tablejump_mips162 (operands[0], operands[1]));
8602           DONE;
8603         }
8604
8605       if (GET_MODE (operands[0]) != Pmode)
8606         abort ();
8607
8608       if (! flag_pic)
8609         {
8610           if (!TARGET_LONG64)
8611             emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
8612           else
8613             emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
8614         }
8615       else
8616         {
8617           if (!TARGET_LONG64)
8618             emit_jump_insn (gen_tablejump_internal3 (operands[0], operands[1]));
8619           else
8620             emit_jump_insn (gen_tablejump_internal4 (operands[0], operands[1]));
8621         }
8622
8623       DONE;
8624     }
8625 }")
8626
8627 (define_insn "tablejump_internal1"
8628   [(set (pc)
8629         (match_operand:SI 0 "register_operand" "d"))
8630    (use (label_ref (match_operand 1 "" "")))]
8631   "!TARGET_LONG64"
8632   "%*j\\t%0"
8633   [(set_attr "type"     "jump")
8634    (set_attr "mode"     "none")
8635    (set_attr "length"   "1")])
8636
8637 (define_insn "tablejump_internal2"
8638   [(set (pc)
8639         (match_operand:DI 0 "se_register_operand" "d"))
8640    (use (label_ref (match_operand 1 "" "")))]
8641   "TARGET_LONG64"
8642   "%*j\\t%0"
8643   [(set_attr "type"     "jump")
8644    (set_attr "mode"     "none")
8645    (set_attr "length"   "1")])
8646
8647 (define_expand "tablejump_internal3"
8648   [(set (pc)
8649         (plus:SI (match_operand:SI 0 "register_operand" "d")
8650                  (label_ref:SI (match_operand:SI 1 "" ""))))]
8651   ""
8652   "")
8653
8654 (define_expand "tablejump_mips161"
8655   [(set (pc) (plus:SI (sign_extend:SI
8656                        (match_operand:HI 0 "register_operand" "d"))
8657                       (label_ref:SI (match_operand:SI 1 "" ""))))]
8658   "TARGET_MIPS16 && !TARGET_LONG64"
8659   "
8660 {
8661   if (operands[0])      /* eliminate unused code warnings.  */
8662     {
8663       rtx t1, t2, t3;
8664
8665       t1 = gen_reg_rtx (SImode);
8666       t2 = gen_reg_rtx (SImode);
8667       t3 = gen_reg_rtx (SImode);
8668       emit_insn (gen_extendhisi2 (t1, operands[0]));
8669       emit_move_insn (t2, gen_rtx (LABEL_REF, SImode, operands[1]));
8670       emit_insn (gen_addsi3 (t3, t1, t2));
8671       emit_insn (gen_tablejump_internal1 (t3, operands[1]));
8672       DONE;
8673     }
8674 }")
8675
8676 (define_expand "tablejump_mips162"
8677   [(set (pc) (plus:DI (sign_extend:DI
8678                        (match_operand:HI 0 "register_operand" "d"))
8679                       (label_ref:DI (match_operand:SI 1 "" ""))))]
8680   "TARGET_MIPS16 && TARGET_LONG64"
8681   "
8682 {
8683   if (operands[0])      /* eliminate unused code warnings.  */
8684     {
8685       rtx t1, t2, t3;
8686
8687       t1 = gen_reg_rtx (DImode);
8688       t2 = gen_reg_rtx (DImode);
8689       t3 = gen_reg_rtx (DImode);
8690       emit_insn (gen_extendhidi2 (t1, operands[0]));
8691       emit_move_insn (t2, gen_rtx (LABEL_REF, DImode, operands[1]));
8692       emit_insn (gen_adddi3 (t3, t1, t2));
8693       emit_insn (gen_tablejump_internal2 (t3, operands[1]));
8694       DONE;
8695     }
8696 }")
8697
8698 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC.  Otherwise
8699 ;;; it is not valid.
8700
8701 ;;; ??? The length depends on the ABI.  It is two for o32, and one for n32.
8702 ;;; We just use the conservative number here.
8703
8704 (define_insn ""
8705   [(set (pc)
8706         (plus:SI (match_operand:SI 0 "register_operand" "d")
8707                  (label_ref:SI (match_operand:SI 1 "" ""))))]
8708   "!TARGET_LONG64 && next_active_insn (insn) != 0
8709    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
8710    && PREV_INSN (next_active_insn (insn)) == operands[1]"
8711   "*
8712 {
8713   /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic.  */
8714   if (mips_abi == ABI_32)
8715     output_asm_insn (\".cpadd\\t%0\", operands);
8716   return \"%*j\\t%0\";
8717 }"
8718   [(set_attr "type"     "jump")
8719    (set_attr "mode"     "none")
8720    (set_attr "length"   "2")])
8721
8722 (define_expand "tablejump_internal4"
8723   [(set (pc)
8724         (plus:DI (match_operand:DI 0 "se_register_operand" "d")
8725                  (label_ref:DI (match_operand:SI 1 "" ""))))]
8726   ""
8727   "")
8728
8729 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC.  Otherwise
8730 ;;; it is not valid.
8731
8732 (define_insn ""
8733   [(set (pc)
8734         (plus:DI (match_operand:DI 0 "se_register_operand" "d")
8735                  (label_ref:DI (match_operand:SI 1 "" ""))))]
8736   "TARGET_LONG64 && next_active_insn (insn) != 0
8737    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
8738    && PREV_INSN (next_active_insn (insn)) == operands[1]"
8739   "%*j\\t%0"
8740   [(set_attr "type"     "jump")
8741    (set_attr "mode"     "none")
8742    (set_attr "length"   "1")])
8743
8744 ;; Implement a switch statement when generating embedded PIC code.
8745 ;; Switches are implemented by `tablejump' when not using -membedded-pic.
8746
8747 (define_expand "casesi"
8748   [(set (match_dup 5)
8749         (minus:SI (match_operand:SI 0 "register_operand" "d")
8750                   (match_operand:SI 1 "arith_operand" "dI")))
8751    (set (cc0)
8752         (compare:CC (match_dup 5)
8753                     (match_operand:SI 2 "arith_operand" "")))
8754    (set (pc)
8755         (if_then_else (gtu (cc0)
8756                            (const_int 0))
8757                       (label_ref (match_operand 4 "" ""))
8758                       (pc)))
8759    (parallel
8760     [(set (pc)
8761           (mem:SI (plus:SI (mult:SI (match_dup 5)
8762                                     (const_int 4))
8763                            (label_ref (match_operand 3 "" "")))))
8764      (clobber (match_scratch:SI 6 ""))
8765      (clobber (reg:SI 31))])]
8766   "TARGET_EMBEDDED_PIC"
8767   "
8768 {
8769   /* We need slightly different code for eight byte table entries.  */
8770   if (TARGET_LONG64)
8771     abort ();
8772
8773   if (operands[0])
8774     {
8775       rtx reg = gen_reg_rtx (SImode);
8776
8777       /* If the index is too large, go to the default label.  */
8778       emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
8779       emit_insn (gen_cmpsi (reg, operands[2]));
8780       emit_insn (gen_bgtu (operands[4]));
8781
8782       /* Do the PIC jump.  */
8783       emit_insn (gen_casesi_internal (reg, operands[3], gen_reg_rtx (SImode)));
8784
8785       DONE;
8786     }
8787 }")
8788
8789 ;; An embedded PIC switch statement looks like this:
8790 ;;      bal     $LS1
8791 ;;      sll     $reg,$index,2
8792 ;; $LS1:
8793 ;;      addu    $reg,$reg,$31
8794 ;;      lw      $reg,$L1-$LS1($reg)
8795 ;;      addu    $reg,$reg,$31
8796 ;;      j       $reg
8797 ;; $L1:
8798 ;;      .word   case1-$LS1
8799 ;;      .word   case2-$LS1
8800 ;;      ...
8801
8802 (define_insn "casesi_internal"
8803   [(set (pc)
8804         (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
8805                                   (const_int 4))
8806                          (label_ref (match_operand 1 "" "")))))
8807    (clobber (match_operand:SI 2 "register_operand" "d"))
8808    (clobber (reg:SI 31))]
8809   "TARGET_EMBEDDED_PIC"
8810   "*
8811 {
8812   output_asm_insn (\"%(bal\\t%S1\;sll\\t%0,2\\n%S1:\", operands);
8813   output_asm_insn (\"addu\\t%0,%0,$31%)\", operands);
8814   output_asm_insn (\"lw\\t%0,%1-%S1(%0)\;addu\\t%0,%0,$31\", operands);
8815   return \"j\\t%0\";
8816 }"
8817   [(set_attr "type"     "jump")
8818    (set_attr "mode"     "none")
8819    (set_attr "length"   "6")])
8820
8821 ;; ??? This is a hack to work around a problem with expand_builtin_setjmp.
8822 ;; It restores the frame pointer, and then does a call to restore the global
8823 ;; pointer (gp) register.  The call insn implicitly (via the assembler) reloads
8824 ;; gp from the stack.  However, call insns do not depend on $fp, so it is
8825 ;; possible for the instruction scheduler to move the fp restore after the
8826 ;; call, which then causes gp to be corrupted.  We fix this by emitting a
8827 ;; scheduler barrier.  A better fix is to put code here that restores the
8828 ;; $gp, and then the call is unnecessary.  This is only a problem when PIC
8829 ;; (TARGET_ABICALLS), and only when the gp register is caller-saved
8830 ;; (irix5/o32, but not irix6/n32/n64).
8831
8832 (define_expand "nonlocal_goto_receiver"
8833   [(const_int 0)]
8834   ""
8835   "
8836 {
8837   emit_insn (gen_blockage ());
8838 }")
8839
8840 ;; For n32/n64, we need to restore gp after a builtin setjmp.   We do this
8841 ;; by making use of the fact that we've just called __dummy.
8842
8843 (define_expand "builtin_setjmp_receiver"
8844   [(const_int 0)]
8845   "TARGET_ABICALLS && mips_abi != ABI_32"
8846   "
8847 {
8848   emit_insn (gen_loadgp (gen_rtx (SYMBOL_REF, Pmode, \"__dummy\")));
8849   emit_insn (gen_blockage ());
8850 }")
8851 \f
8852 ;;
8853 ;;  ....................
8854 ;;
8855 ;;      Function prologue/epilogue
8856 ;;
8857 ;;  ....................
8858 ;;
8859
8860 (define_expand "prologue"
8861   [(const_int 1)]
8862   ""
8863   "
8864 {
8865   if (mips_isa >= 0)            /* avoid unused code warnings */
8866     {
8867       mips_expand_prologue ();
8868       DONE;
8869     }
8870 }")
8871
8872 ;; Block any insns from being moved before this point, since the
8873 ;; profiling call to mcount can use various registers that aren't
8874 ;; saved or used to pass arguments.
8875
8876 (define_insn "blockage"
8877   [(unspec_volatile [(const_int 0)] 0)]
8878   ""
8879   ""
8880   [(set_attr "type"     "unknown")
8881    (set_attr "mode"     "none")
8882    (set_attr "length"   "0")])
8883
8884 (define_expand "epilogue"
8885   [(const_int 2)]
8886   ""
8887   "
8888 {
8889   if (mips_isa >= 0)            /* avoid unused code warnings */
8890     {
8891       mips_expand_epilogue ();
8892       DONE;
8893     }
8894 }")
8895
8896 ;; Trivial return.  Make it look like a normal return insn as that
8897 ;; allows jump optimizations to work better .
8898 (define_insn "return"
8899   [(return)]
8900   "mips_can_use_return_insn ()"
8901   "%*j\\t$31"
8902   [(set_attr "type"     "jump")
8903    (set_attr "mode"     "none")
8904    (set_attr "length"   "1")])
8905
8906 ;; Normal return.
8907 ;; We match any mode for the return address, so that this will work with
8908 ;; both 32 bit and 64 bit targets.
8909 (define_insn "return_internal"
8910   [(use (match_operand 0 "register_operand" ""))
8911    (return)]
8912   ""
8913   "*
8914 {
8915   return \"%*j\\t%0\";
8916 }"
8917   [(set_attr "type"     "jump")
8918    (set_attr "mode"     "none")
8919    (set_attr "length"   "1")])
8920   
8921 ;; When generating embedded PIC code we need to get the address of the
8922 ;; current function.  This specialized instruction does just that.
8923
8924 (define_insn "get_fnaddr"
8925   [(set (match_operand 0 "register_operand" "=d")
8926         (unspec [(match_operand 1 "" "")] 1))
8927    (clobber (reg:SI 31))]
8928   "TARGET_EMBEDDED_PIC
8929    && GET_CODE (operands[1]) == SYMBOL_REF"
8930   "%($LF%= = . + 8\;bal\\t$LF%=\;la\\t%0,%1-$LF%=%)\;addu\\t%0,%0,$31"
8931   [(set_attr "type"     "call")
8932    (set_attr "mode"     "none")
8933    (set_attr "length"   "4")])
8934
8935 \f
8936 ;;
8937 ;;  ....................
8938 ;;
8939 ;;      FUNCTION CALLS
8940 ;;
8941 ;;  ....................
8942
8943 ;; calls.c now passes a third argument, make saber happy
8944
8945 (define_expand "call"
8946   [(parallel [(call (match_operand 0 "memory_operand" "m")
8947                     (match_operand 1 "" "i"))
8948               (clobber (reg:SI 31))
8949               (use (match_operand 2 "" ""))             ;; next_arg_reg
8950               (use (match_operand 3 "" ""))])]          ;; struct_value_size_rtx
8951   ""
8952   "
8953 {
8954   rtx addr;
8955
8956   if (operands[0])              /* eliminate unused code warnings */
8957     {
8958       addr = XEXP (operands[0], 0);
8959       if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
8960           || ! call_insn_operand (addr, VOIDmode))
8961         XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
8962
8963       /* In order to pass small structures by value in registers
8964          compatibly with the MIPS compiler, we need to shift the value
8965          into the high part of the register.  Function_arg has encoded
8966          a PARALLEL rtx, holding a vector of adjustments to be made
8967          as the next_arg_reg variable, so we split up the insns,
8968          and emit them separately.  */
8969
8970       if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL)
8971         {
8972           rtvec adjust = XVEC (operands[2], 0);
8973           int num = GET_NUM_ELEM (adjust);
8974           int i;
8975
8976           for (i = 0; i < num; i++)
8977             emit_insn (RTVEC_ELT (adjust, i));
8978         }
8979
8980       if (TARGET_MIPS16
8981           && mips16_hard_float
8982           && operands[2] != 0
8983           && (int) GET_MODE (operands[2]) != 0)
8984         {
8985           if (build_mips16_call_stub (NULL_RTX, operands[0], operands[1],
8986                                       (int) GET_MODE (operands[2])))
8987             DONE;
8988         }
8989
8990       emit_call_insn (gen_call_internal0 (operands[0], operands[1],
8991                                           gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
8992
8993       DONE;
8994     }
8995 }")
8996
8997 (define_expand "call_internal0"
8998   [(parallel [(call (match_operand 0 "" "")
8999                     (match_operand 1 "" ""))
9000               (clobber (match_operand:SI 2 "" ""))])]
9001   ""
9002   "")
9003
9004 ;; We need to recognize reg:SI 31 specially for the mips16, because we
9005 ;; don't have a constraint letter for it.
9006
9007 (define_insn ""
9008   [(call (mem (match_operand 0 "call_insn_operand" "ei"))
9009          (match_operand 1 "" "i"))
9010    (clobber (match_operand:SI 2 "register_operand" "=y"))]
9011   "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
9012    && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
9013   "%*jal\\t%0"
9014   [(set_attr "type"     "call")
9015    (set_attr "mode"     "none")
9016    (set_attr "length"   "2")])
9017
9018 (define_insn "call_internal1"
9019   [(call (mem (match_operand 0 "call_insn_operand" "ri"))
9020          (match_operand 1 "" "i"))
9021    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9022   "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
9023   "*
9024 {
9025   register rtx target = operands[0];
9026
9027   if (GET_CODE (target) == SYMBOL_REF)
9028     return \"%*jal\\t%0\";
9029   else if (GET_CODE (target) == CONST_INT)
9030     return \"%[li\\t%@,%0\\n\\t%*jal\\t%2,%@%]\";
9031   else
9032     return \"%*jal\\t%2,%0\";
9033 }"
9034   [(set_attr "type"     "call")
9035    (set_attr "mode"     "none")
9036    (set_attr "length"   "1")])
9037
9038 (define_insn "call_internal2"
9039   [(call (mem (match_operand 0 "call_insn_operand" "ri"))
9040          (match_operand 1 "" "i"))
9041    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9042   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9043   "*
9044 {
9045   register rtx target = operands[0];
9046
9047   if (GET_CODE (target) == SYMBOL_REF)
9048     {
9049       if (GET_MODE (target) == SImode)
9050         return \"la\\t%^,%0\\n\\tjal\\t%2,%^\";
9051       else
9052         return \"dla\\t%^,%0\\n\\tjal\\t%2,%^\";
9053     }
9054   else if (GET_CODE (target) == CONST_INT)
9055     return \"li\\t%^,%0\\n\\tjal\\t%2,%^\";
9056   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9057     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9058   else
9059     return \"jal\\t%2,%0\";
9060 }"
9061   [(set_attr "type"     "call")
9062    (set_attr "mode"     "none")
9063    (set_attr "length"   "2")])
9064
9065 (define_insn "call_internal3a"
9066   [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9067          (match_operand 1 "" "i"))
9068    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9069   "!TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9070   "%*jal\\t%2,%0"
9071   [(set_attr "type"     "call")
9072    (set_attr "mode"     "none")
9073    (set_attr "length"   "1")])
9074
9075 (define_insn "call_internal3b"
9076   [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
9077          (match_operand 1 "" "i"))
9078    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9079   "TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9080   "%*jal\\t%2,%0"
9081   [(set_attr "type"     "call")
9082    (set_attr "mode"     "none")
9083    (set_attr "length"   "1")])
9084
9085 (define_insn "call_internal4a"
9086   [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
9087          (match_operand 1 "" "i"))
9088    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9089   "!TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
9090   "*
9091 {
9092   if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9093     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9094   else
9095     return \"jal\\t%2,%0\";
9096 }"
9097   [(set_attr "type"     "call")
9098    (set_attr "mode"     "none")
9099    (set_attr "length"   "2")])
9100
9101 (define_insn "call_internal4b"
9102   [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
9103          (match_operand 1 "" "i"))
9104    (clobber (match_operand:SI 2 "register_operand" "=d"))]
9105   "TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
9106   "*
9107 {
9108   if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
9109     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
9110   else
9111     return \"jal\\t%2,%0\";
9112 }"
9113   [(set_attr "type"     "call")
9114    (set_attr "mode"     "none")
9115    (set_attr "length"   "2")])
9116
9117 ;; calls.c now passes a fourth argument, make saber happy
9118
9119 (define_expand "call_value"
9120   [(parallel [(set (match_operand 0 "register_operand" "=df")
9121                    (call (match_operand 1 "memory_operand" "m")
9122                          (match_operand 2 "" "i")))
9123               (clobber (reg:SI 31))
9124               (use (match_operand 3 "" ""))])]          ;; next_arg_reg
9125   ""
9126   "
9127 {
9128   rtx addr;
9129
9130   if (operands[0])              /* eliminate unused code warning */
9131     {
9132       addr = XEXP (operands[1], 0);
9133       if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
9134           || ! call_insn_operand (addr, VOIDmode))
9135         XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
9136
9137       /* In order to pass small structures by value in registers
9138          compatibly with the MIPS compiler, we need to shift the value
9139          into the high part of the register.  Function_arg has encoded
9140          a PARALLEL rtx, holding a vector of adjustments to be made
9141          as the next_arg_reg variable, so we split up the insns,
9142          and emit them separately.  */
9143
9144       if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL)
9145         {
9146           rtvec adjust = XVEC (operands[3], 0);
9147           int num = GET_NUM_ELEM (adjust);
9148           int i;
9149
9150           for (i = 0; i < num; i++)
9151             emit_insn (RTVEC_ELT (adjust, i));
9152         }
9153
9154       if (TARGET_MIPS16
9155           && mips16_hard_float
9156           && ((operands[3] != 0
9157                && (int) GET_MODE (operands[3]) != 0)
9158               || GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_FLOAT))
9159         {
9160           if (build_mips16_call_stub (operands[0], operands[1], operands[2],
9161                                       (operands[3] == 0 ? 0
9162                                        : (int) GET_MODE (operands[3]))))
9163             DONE;
9164         }
9165
9166       /* Handle Irix6 function calls that have multiple non-contiguous
9167          results.  */
9168       if (GET_CODE (operands[0]) == PARALLEL && XVECLEN (operands[0], 0) > 1)
9169         {
9170           emit_call_insn (gen_call_value_multiple_internal0
9171                           (XEXP (XVECEXP (operands[0], 0, 0), 0),
9172                            operands[1], operands[2],
9173                            XEXP (XVECEXP (operands[0], 0, 1), 0),
9174                            gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
9175           DONE;
9176         }
9177
9178       /* We have a call returning a DImode structure in an FP reg.
9179          Strip off the now unnecessary PARALLEL.  */
9180       if (GET_CODE (operands[0]) == PARALLEL)
9181         operands[0] = XEXP (XVECEXP (operands[0], 0, 0), 0);
9182
9183       emit_call_insn (gen_call_value_internal0 (operands[0], operands[1], operands[2],
9184                                                 gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
9185
9186       DONE;
9187     }
9188 }")
9189
9190 (define_expand "call_value_internal0"
9191   [(parallel [(set (match_operand 0 "" "")
9192                    (call (match_operand 1 "" "")
9193                          (match_operand 2 "" "")))
9194               (clobber (match_operand:SI 3 "" ""))])]
9195   ""
9196   "")
9197
9198 ;; Recognize $31 specially on the mips16, because we don't have a
9199 ;; constraint letter for it.
9200
9201 (define_insn ""
9202   [(set (match_operand 0 "register_operand" "=d")
9203         (call (mem (match_operand 1 "call_insn_operand" "ei"))
9204               (match_operand 2 "" "i")))
9205    (clobber (match_operand:SI 3 "register_operand" "=y"))]
9206   "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
9207    && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
9208   "%*jal\\t%1"
9209   [(set_attr "type"     "call")
9210    (set_attr "mode"     "none")
9211    (set_attr "length"   "2")])
9212
9213 (define_insn "call_value_internal1"
9214   [(set (match_operand 0 "register_operand" "=df")
9215         (call (mem (match_operand 1 "call_insn_operand" "ri"))
9216               (match_operand 2 "" "i")))
9217    (clobber (match_operand:SI 3 "register_operand" "=d"))]
9218   "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
9219   "*
9220 {
9221   register rtx target = operands[1];
9222
9223   if (GET_CODE (target) == SYMBOL_REF)
9224     return \"%*jal\\t%1\";
9225   else if (GET_CODE (target) == CONST_INT)
9226     return \"%[li\\t%@,%1\\n\\t%*jal\\t%3,%@%]\";
9227   else
9228     return \"%*jal\\t%3,%1\";
9229 }"
9230   [(set_attr "type"     "call")
9231    (set_attr "mode"     "none")
9232    (set_attr "length"   "1")])
9233
9234 (define_insn "call_value_internal2"
9235   [(set (match_operand 0 "register_operand" "=df")
9236         (call (mem (match_operand 1 "call_insn_operand" "ri"))
9237               (match_operand 2 "" "i")))
9238    (clobber (match_operand:SI 3 "register_operand" "=d"))]
9239   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9240   "*
9241 {
9242   register rtx target = operands[1];
9243
9244   if (GET_CODE (target) == SYMBOL_REF)
9245     {
9246       if (GET_MODE (target) == SImode)
9247         return \"la\\t%^,%1\\n\\tjal\\t%3,%^\";
9248       else
9249         return \"dla\\t%^,%1\\n\\tjal\\t%3,%^\";
9250     }
9251   else if (GET_CODE (target) == CONST_INT)
9252     return \"li\\t%^,%1\\n\\tjal\\t%3,%^\";
9253   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9254     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
9255   else
9256     return \"jal\\t%3,%1\";
9257 }"
9258   [(set_attr "type"     "call")
9259    (set_attr "mode"     "none")
9260    (set_attr "length"   "2")])
9261
9262 (define_insn "call_value_internal3a"
9263   [(set (match_operand 0 "register_operand" "=df")
9264         (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
9265               (match_operand 2 "" "i")))
9266    (clobber (match_operand:SI 3 "register_operand" "=d"))]
9267   "!TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9268   "%*jal\\t%3,%1"
9269   [(set_attr "type"     "call")
9270    (set_attr "mode"     "none")
9271    (set_attr "length"   "1")])
9272
9273 (define_insn "call_value_internal3b"
9274   [(set (match_operand 0 "register_operand" "=df")
9275         (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
9276               (match_operand 2 "" "i")))
9277    (clobber (match_operand:SI 3 "register_operand" "=d"))]
9278   "TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
9279   "%*jal\\t%3,%1"
9280   [(set_attr "type"     "call")
9281    (set_attr "mode"     "none")
9282    (set_attr "length"   "1")])
9283
9284 (define_insn "call_value_internal4a"
9285   [(set (match_operand 0 "register_operand" "=df")
9286         (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
9287               (match_operand 2 "" "i")))
9288    (clobber (match_operand:SI 3 "register_operand" "=d"))]
9289   "!TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
9290   "*
9291 {
9292   if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
9293     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
9294   else
9295     return \"jal\\t%3,%1\";
9296 }"
9297   [(set_attr "type"     "call")
9298    (set_attr "mode"     "none")
9299    (set_attr "length"   "2")])
9300
9301 (define_insn "call_value_internal4b"
9302   [(set (match_operand 0 "register_operand" "=df")
9303         (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
9304               (match_operand 2 "" "i")))
9305    (clobber (match_operand:SI 3 "register_operand" "=d"))]
9306   "TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
9307   "*
9308 {
9309   if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
9310     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
9311   else
9312     return \"jal\\t%3,%1\";
9313 }"
9314   [(set_attr "type"     "call")
9315    (set_attr "mode"     "none")
9316    (set_attr "length"   "2")])
9317
9318 (define_expand "call_value_multiple_internal0"
9319   [(parallel [(set (match_operand 0 "" "")
9320                    (call (match_operand 1 "" "")
9321                          (match_operand 2 "" "")))
9322               (set (match_operand 3 "" "")
9323                    (call (match_dup 1)
9324                          (match_dup 2)))
9325               (clobber (match_operand:SI 4 "" ""))])]
9326   ""
9327   "")
9328
9329 ;; ??? May eventually need all 6 versions of the call patterns with multiple
9330 ;; return values.
9331
9332 (define_insn "call_value_multiple_internal2"
9333   [(set (match_operand 0 "register_operand" "=df")
9334         (call (mem (match_operand 1 "call_insn_operand" "ri"))
9335               (match_operand 2 "" "i")))
9336    (set (match_operand 3 "register_operand" "=df")
9337         (call (mem (match_dup 1))
9338               (match_dup 2)))
9339    (clobber (match_operand:SI 4 "register_operand" "=d"))]
9340   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
9341   "*
9342 {
9343   register rtx target = operands[1];
9344
9345   if (GET_CODE (target) == SYMBOL_REF)
9346     {
9347       if (GET_MODE (target) == SImode)
9348         return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
9349       else
9350         return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
9351     }
9352   else if (GET_CODE (target) == CONST_INT)
9353     return \"li\\t%^,%1\\n\\tjal\\t%4,%^\";
9354   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
9355     return \"move\\t%^,%1\\n\\tjal\\t%4,%^\";
9356   else
9357     return \"jal\\t%4,%1\";
9358 }"
9359   [(set_attr "type"     "call")
9360    (set_attr "mode"     "none")
9361    (set_attr "length"   "2")])
9362
9363
9364 ;; Call subroutine returning any type.
9365
9366 (define_expand "untyped_call"
9367   [(parallel [(call (match_operand 0 "" "")
9368                     (const_int 0))
9369               (match_operand 1 "" "")
9370               (match_operand 2 "" "")])]
9371   ""
9372   "
9373 {
9374   if (operands[0])              /* silence statement not reached warnings */
9375     {
9376       int i;
9377
9378       emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
9379
9380       for (i = 0; i < XVECLEN (operands[2], 0); i++)
9381         {
9382           rtx set = XVECEXP (operands[2], 0, i);
9383           emit_move_insn (SET_DEST (set), SET_SRC (set));
9384         }
9385
9386       emit_insn (gen_blockage ());
9387       DONE;
9388     }
9389 }")
9390 \f
9391 ;;
9392 ;;  ....................
9393 ;;
9394 ;;      MISC.
9395 ;;
9396 ;;  ....................
9397 ;;
9398
9399 (define_insn "nop"
9400   [(const_int 0)]
9401   ""
9402   "%(nop%)"
9403   [(set_attr "type"     "nop")
9404    (set_attr "mode"     "none")
9405    (set_attr "length"   "1")])
9406
9407 ;; The MIPS chip does not seem to require stack probes.
9408 ;;
9409 ;; (define_expand "probe"
9410 ;;   [(set (match_dup 0)
9411 ;;      (match_dup 1))]
9412 ;;   ""
9413 ;;   "
9414 ;; {
9415 ;;   operands[0] = gen_reg_rtx (SImode);
9416 ;;   operands[1] = gen_rtx (MEM, SImode, stack_pointer_rtx);
9417 ;;   MEM_VOLATILE_P (operands[1]) = TRUE;
9418 ;; 
9419 ;;   /* fall through and generate default code */
9420 ;; }")
9421 ;;
9422 \f
9423 ;;
9424 ;; MIPS4 Conditional move instructions.
9425
9426 (define_insn ""
9427   [(set (match_operand:SI 0 "register_operand" "=d,d")
9428         (if_then_else:SI
9429          (match_operator 4 "equality_op"
9430                          [(match_operand:SI 1 "register_operand" "d,d")
9431                           (const_int 0)])
9432          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
9433          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
9434   "mips_isa >= 4"
9435   "@
9436     mov%B4\\t%0,%z2,%1
9437     mov%b4\\t%0,%z3,%1"
9438   [(set_attr "type" "move")
9439    (set_attr "mode" "SI")])
9440
9441 (define_insn ""
9442   [(set (match_operand:SI 0 "register_operand" "=d,d")
9443         (if_then_else:SI
9444          (match_operator 4 "equality_op"
9445                          [(match_operand:DI 1 "se_register_operand" "d,d")
9446                           (const_int 0)])
9447          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
9448          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
9449   "mips_isa >= 4"
9450   "@
9451     mov%B4\\t%0,%z2,%1
9452     mov%b4\\t%0,%z3,%1"
9453   [(set_attr "type" "move")
9454    (set_attr "mode" "SI")])
9455
9456 (define_insn ""
9457   [(set (match_operand:SI 0 "register_operand" "=d,d")
9458         (if_then_else:SI
9459          (match_operator 3 "equality_op" [(match_operand:CC 4
9460                                                             "register_operand"
9461                                                             "z,z")
9462                                           (const_int 0)])
9463          (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
9464          (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
9465   "mips_isa >= 4 && TARGET_HARD_FLOAT"
9466   "@
9467     mov%T3\\t%0,%z1,%4
9468     mov%t3\\t%0,%z2,%4"
9469   [(set_attr "type" "move")
9470    (set_attr "mode" "SI")])
9471
9472 (define_insn ""
9473   [(set (match_operand:DI 0 "register_operand" "=d,d")
9474         (if_then_else:DI
9475          (match_operator 4 "equality_op"
9476                          [(match_operand:SI 1 "register_operand" "d,d")
9477                           (const_int 0)])
9478          (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
9479          (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
9480   "mips_isa >= 4"
9481   "@
9482     mov%B4\\t%0,%z2,%1
9483     mov%b4\\t%0,%z3,%1"
9484   [(set_attr "type" "move")
9485    (set_attr "mode" "DI")])
9486
9487 (define_insn ""
9488   [(set (match_operand:DI 0 "register_operand" "=d,d")
9489         (if_then_else:DI
9490          (match_operator 4 "equality_op"
9491                          [(match_operand:DI 1 "se_register_operand" "d,d")
9492                           (const_int 0)])
9493          (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
9494          (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
9495   "mips_isa >= 4"
9496   "@
9497     mov%B4\\t%0,%z2,%1
9498     mov%b4\\t%0,%z3,%1"
9499   [(set_attr "type" "move")
9500    (set_attr "mode" "DI")])
9501
9502 (define_insn ""
9503   [(set (match_operand:DI 0 "register_operand" "=d,d")
9504         (if_then_else:DI
9505          (match_operator 3 "equality_op" [(match_operand:CC 4
9506                                                             "register_operand"
9507                                                             "z,z")
9508                                           (const_int 0)])
9509          (match_operand:DI 1 "se_reg_or_0_operand" "dJ,0")
9510          (match_operand:DI 2 "se_reg_or_0_operand" "0,dJ")))]
9511   "mips_isa >= 4 && TARGET_HARD_FLOAT"
9512   "@
9513     mov%T3\\t%0,%z1,%4
9514     mov%t3\\t%0,%z2,%4"
9515   [(set_attr "type" "move")
9516    (set_attr "mode" "DI")])
9517
9518 (define_insn ""
9519   [(set (match_operand:SF 0 "register_operand" "=f,f")
9520         (if_then_else:SF
9521          (match_operator 4 "equality_op"
9522                          [(match_operand:SI 1 "register_operand" "d,d")
9523                           (const_int 0)])
9524          (match_operand:SF 2 "register_operand" "f,0")
9525          (match_operand:SF 3 "register_operand" "0,f")))]
9526   "mips_isa >= 4 && TARGET_HARD_FLOAT"
9527   "@
9528     mov%B4.s\\t%0,%2,%1
9529     mov%b4.s\\t%0,%3,%1"
9530   [(set_attr "type" "move")
9531    (set_attr "mode" "SF")])
9532
9533 (define_insn ""
9534   [(set (match_operand:SF 0 "register_operand" "=f,f")
9535         (if_then_else:SF
9536          (match_operator 3 "equality_op" [(match_operand:CC 4
9537                                                             "register_operand"
9538                                                             "z,z")
9539                                           (const_int 0)])
9540          (match_operand:SF 1 "register_operand" "f,0")
9541          (match_operand:SF 2 "register_operand" "0,f")))]
9542   "mips_isa >= 4 && TARGET_HARD_FLOAT"
9543   "@
9544     mov%T3.s\\t%0,%1,%4
9545     mov%t3.s\\t%0,%2,%4"
9546   [(set_attr "type" "move")
9547    (set_attr "mode" "SF")])
9548
9549 (define_insn ""
9550   [(set (match_operand:DF 0 "register_operand" "=f,f")
9551         (if_then_else:DF
9552          (match_operator 4 "equality_op"
9553                          [(match_operand:SI 1 "register_operand" "d,d")
9554                           (const_int 0)])
9555          (match_operand:DF 2 "register_operand" "f,0")
9556          (match_operand:DF 3 "register_operand" "0,f")))]
9557   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9558   "@
9559     mov%B4.d\\t%0,%2,%1
9560     mov%b4.d\\t%0,%3,%1"
9561   [(set_attr "type" "move")
9562    (set_attr "mode" "DF")])
9563
9564 (define_insn ""
9565   [(set (match_operand:DF 0 "register_operand" "=f,f")
9566         (if_then_else:DF
9567          (match_operator 3 "equality_op" [(match_operand:CC 4
9568                                                             "register_operand"
9569                                                             "z,z")
9570                                           (const_int 0)])
9571          (match_operand:DF 1 "register_operand" "f,0")
9572          (match_operand:DF 2 "register_operand" "0,f")))]
9573   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9574   "@
9575     mov%T3.d\\t%0,%1,%4
9576     mov%t3.d\\t%0,%2,%4"
9577   [(set_attr "type" "move")
9578    (set_attr "mode" "DF")])
9579
9580 ;; These are the main define_expand's used to make conditional moves.
9581
9582 (define_expand "movsicc"
9583   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
9584    (set (match_operand:SI 0 "register_operand" "")
9585         (if_then_else:SI (match_dup 5)
9586                          (match_operand:SI 2 "reg_or_0_operand" "")
9587                          (match_operand:SI 3 "reg_or_0_operand" "")))]
9588   "mips_isa >= 4"
9589   "
9590 {
9591   gen_conditional_move (operands);
9592   DONE;
9593 }")
9594
9595 (define_expand "movdicc"
9596   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
9597    (set (match_operand:DI 0 "register_operand" "")
9598         (if_then_else:DI (match_dup 5)
9599                          (match_operand:DI 2 "se_reg_or_0_operand" "")
9600                          (match_operand:DI 3 "se_reg_or_0_operand" "")))]
9601   "mips_isa >= 4"
9602   "
9603 {
9604   gen_conditional_move (operands);
9605   DONE;
9606 }")
9607
9608 (define_expand "movsfcc"
9609   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
9610    (set (match_operand:SF 0 "register_operand" "")
9611         (if_then_else:SF (match_dup 5)
9612                          (match_operand:SF 2 "register_operand" "")
9613                          (match_operand:SF 3 "register_operand" "")))]
9614   "mips_isa >= 4 && TARGET_HARD_FLOAT"
9615   "
9616 {
9617   gen_conditional_move (operands);
9618   DONE;
9619 }")
9620
9621 (define_expand "movdfcc"
9622   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
9623    (set (match_operand:DF 0 "register_operand" "")
9624         (if_then_else:DF (match_dup 5)
9625                          (match_operand:DF 2 "register_operand" "")
9626                          (match_operand:DF 3 "register_operand" "")))]
9627   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
9628   "
9629 {
9630   gen_conditional_move (operands);
9631   DONE;
9632 }")
9633 \f
9634 ;;
9635 ;;  ....................
9636 ;;
9637 ;;      mips16 inline constant tables
9638 ;;
9639 ;;  ....................
9640 ;;
9641
9642 (define_insn "consttable_qi"
9643   [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "=g")] 10)]
9644   "TARGET_MIPS16"
9645   "*
9646 {
9647   assemble_integer (operands[0], 1, 1);
9648   return \"\";
9649 }"
9650   [(set_attr "type"     "unknown")
9651    (set_attr "mode"     "QI")
9652    (set_attr "length"   "2")])
9653
9654 (define_insn "consttable_hi"
9655   [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "=g")] 11)]
9656   "TARGET_MIPS16"
9657   "*
9658 {
9659   assemble_integer (operands[0], 2, 1);
9660   return \"\";
9661 }"
9662   [(set_attr "type"     "unknown")
9663    (set_attr "mode"     "HI")
9664    (set_attr "length"   "2")])
9665
9666 (define_insn "consttable_si"
9667   [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "=g")] 12)]
9668   "TARGET_MIPS16"
9669   "*
9670 {
9671   assemble_integer (operands[0], 4, 1);
9672   return \"\";
9673 }"
9674   [(set_attr "type"     "unknown")
9675    (set_attr "mode"     "SI")
9676    (set_attr "length"   "2")])
9677
9678 (define_insn "consttable_di"
9679   [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "=g")] 13)]
9680   "TARGET_MIPS16"
9681   "*
9682 {
9683   assemble_integer (operands[0], 8, 1);
9684   return \"\";
9685 }"
9686   [(set_attr "type"     "unknown")
9687    (set_attr "mode"     "DI")
9688    (set_attr "length"   "4")])
9689
9690 (define_insn "consttable_sf"
9691   [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "=g")] 14)]
9692   "TARGET_MIPS16"
9693   "*
9694 {
9695   union real_extract u;
9696
9697   if (GET_CODE (operands[0]) != CONST_DOUBLE)
9698     abort ();
9699   bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
9700   assemble_real (u.d, SFmode);
9701   return \"\";
9702 }"
9703   [(set_attr "type"     "unknown")
9704    (set_attr "mode"     "SF")
9705    (set_attr "length"   "2")])
9706
9707 (define_insn "consttable_df"
9708   [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "=g")] 15)]
9709   "TARGET_MIPS16"
9710   "*
9711 {
9712   union real_extract u;
9713
9714   if (GET_CODE (operands[0]) != CONST_DOUBLE)
9715     abort ();
9716   bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
9717   assemble_real (u.d, DFmode);
9718   return \"\";
9719 }"
9720   [(set_attr "type"     "unknown")
9721    (set_attr "mode"     "DF")
9722    (set_attr "length"   "4")])
9723
9724 (define_insn "align_2"
9725   [(unspec_volatile [(const_int 0)] 16)]
9726   "TARGET_MIPS16"
9727   ".align 1"
9728   [(set_attr "type"     "unknown")
9729    (set_attr "mode"     "HI")
9730    (set_attr "length"   "2")])
9731
9732 (define_insn "align_4"
9733   [(unspec_volatile [(const_int 0)] 17)]
9734   "TARGET_MIPS16"
9735   ".align 2"
9736   [(set_attr "type"     "unknown")
9737    (set_attr "mode"     "SI")
9738    (set_attr "length"   "2")])
9739
9740 (define_insn "align_8"
9741   [(unspec_volatile [(const_int 0)] 18)]
9742   "TARGET_MIPS16"
9743   ".align 3"
9744   [(set_attr "type"     "unknown")
9745    (set_attr "mode"     "DI")
9746    (set_attr "length"   "3")])
9747 \f
9748 ;;
9749 ;;  ....................
9750 ;;
9751 ;;      mips16 peepholes
9752 ;;
9753 ;;  ....................
9754 ;;
9755
9756 ;; On the mips16, reload will sometimes decide that a pseudo register
9757 ;; should go into $24, and then later on have to reload that register.
9758 ;; When that happens, we get a load of a general register followed by
9759 ;; a move from the general register to $24 followed by a branch.
9760 ;; These peepholes catch the common case, and fix it to just use the
9761 ;; general register for the branch.
9762
9763 (define_peephole
9764   [(set (match_operand:SI 0 "register_operand" "=t")
9765         (match_operand:SI 1 "register_operand" "d"))
9766    (set (pc)
9767         (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
9768                                                           (const_int 0)])
9769                       (match_operand 3 "pc_or_label_operand" "")
9770                       (match_operand 4 "pc_or_label_operand" "")))]
9771   "TARGET_MIPS16
9772    && GET_CODE (operands[0]) == REG
9773    && REGNO (operands[0]) == 24
9774 ;; ??? This is WRONG, dead_or_set_p cannot be used after reload
9775 ;; because the REG_DEAD notes are not maintained after reload.
9776    && dead_or_set_p (insn, operands[0])
9777    && GET_CODE (operands[1]) == REG
9778    && M16_REG_P (REGNO (operands[1]))"
9779   "*
9780 {
9781   if (operands[3] != pc_rtx)
9782     return \"%*b%C2z\\t%1,%3\";
9783   else
9784     return \"%*b%N2z\\t%1,%4\";
9785 }"
9786   [(set_attr "type"     "branch")
9787    (set_attr "mode"     "none")
9788    (set_attr "length"   "2")])
9789
9790 (define_peephole
9791   [(set (match_operand:DI 0 "register_operand" "=t")
9792         (match_operand:DI 1 "register_operand" "d"))
9793    (set (pc)
9794         (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
9795                                                           (const_int 0)])
9796                       (match_operand 3 "pc_or_label_operand" "")
9797                       (match_operand 4 "pc_or_label_operand" "")))]
9798   "TARGET_MIPS16 && TARGET_64BIT
9799    && GET_CODE (operands[0]) == REG
9800    && REGNO (operands[0]) == 24
9801 ;; ??? This is WRONG, dead_or_set_p cannot be used after reload
9802 ;; because the REG_DEAD notes are not maintained after reload.
9803    && dead_or_set_p (insn, operands[0])
9804    && GET_CODE (operands[1]) == REG
9805    && M16_REG_P (REGNO (operands[1]))"
9806   "*
9807 {
9808   if (operands[3] != pc_rtx)
9809     return \"%*b%C2z\\t%1,%3\";
9810   else
9811     return \"%*b%N2z\\t%1,%4\";
9812 }"
9813   [(set_attr "type"     "branch")
9814    (set_attr "mode"     "none")
9815    (set_attr "length"   "2")])
9816
9817 ;; We can also have the reverse reload: reload will spill $24 into
9818 ;; another register, and then do a branch on that register when it
9819 ;; could have just stuck with $24.
9820
9821 (define_peephole
9822   [(set (match_operand:SI 0 "register_operand" "=d")
9823         (match_operand:SI 1 "register_operand" "t"))
9824    (set (pc)
9825         (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
9826                                                           (const_int 0)])
9827                       (match_operand 3 "pc_or_label_operand" "")
9828                       (match_operand 4 "pc_or_label_operand" "")))]
9829   "TARGET_MIPS16
9830    && GET_CODE (operands[1]) == REG
9831    && REGNO (operands[1]) == 24
9832    && GET_CODE (operands[0]) == REG
9833    && M16_REG_P (REGNO (operands[0]))
9834 ;; ??? This is WRONG, dead_or_set_p cannot be used after reload
9835 ;; because the REG_DEAD notes are not maintained after reload.
9836    && dead_or_set_p (insn, operands[0])"
9837   "*
9838 {
9839   if (operands[3] != pc_rtx)
9840     return \"%*bt%C2z\\t%3\";
9841   else
9842     return \"%*bt%N2z\\t%4\";
9843 }"
9844   [(set_attr "type"     "branch")
9845    (set_attr "mode"     "none")
9846    (set_attr "length"   "2")])
9847
9848 (define_peephole
9849   [(set (match_operand:DI 0 "register_operand" "=d")
9850         (match_operand:DI 1 "register_operand" "t"))
9851    (set (pc)
9852         (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
9853                                                           (const_int 0)])
9854                       (match_operand 3 "pc_or_label_operand" "")
9855                       (match_operand 4 "pc_or_label_operand" "")))]
9856   "TARGET_MIPS16 && TARGET_64BIT
9857    && GET_CODE (operands[1]) == REG
9858    && REGNO (operands[1]) == 24
9859    && GET_CODE (operands[0]) == REG
9860    && M16_REG_P (REGNO (operands[0]))
9861 ;; ??? This is WRONG, dead_or_set_p cannot be used after reload
9862 ;; because the REG_DEAD notes are not maintained after reload.
9863    && dead_or_set_p (insn, operands[0])"
9864   "*
9865 {
9866   if (operands[3] != pc_rtx)
9867     return \"%*bt%C2z\\t%3\";
9868   else
9869     return \"%*bt%N2z\\t%4\";
9870 }"
9871   [(set_attr "type"     "branch")
9872    (set_attr "mode"     "none")
9873    (set_attr "length"   "2")])