OSDN Git Service

Merge from gcc-2.8
[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-96, 1997 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 (eq_attr "type" "branch,jump,call,load,xfer,hilo,fcmp")
75                 (const_string "yes")
76                 (const_string "no")))
77
78 ;; Attribute describing the processor.  This attribute must match exactly
79 ;; with the processor_type enumeration in mips.h.
80
81 ;; Attribute describing the processor
82 ;; (define_attr "cpu" "default,r3000,r6000,r4000"
83 ;;   (const
84 ;;    (cond [(eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R3000"))   (const_string "r3000")
85 ;;           (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R4000"))   (const_string "r4000")
86 ;;           (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R6000"))   (const_string "r6000")]
87 ;;          (const_string "default"))))
88
89 ;; ??? Fix everything that tests this attribute.
90 (define_attr "cpu"
91   "default,r3000,r3900,r6000,r4000,r4100,r4300,r4600,r4650,r5000,r8000"
92   (const (symbol_ref "mips_cpu_attr")))
93
94 ;; Attribute defining whether or not we can use the branch-likely instructions
95
96 (define_attr "branch_likely" "no,yes"
97   (const
98    (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
99                  (const_string "yes")
100                  (const_string "no"))))
101
102
103 ;; Describe a user's asm statement.
104 (define_asm_attributes
105   [(set_attr "type" "multi")])
106
107 ;; whether or not generating calls to position independent functions
108 (define_attr "abicalls" "no,yes"
109   (const (symbol_ref "mips_abicalls_attr")))
110
111 \f
112
113 ;; .........................
114 ;;
115 ;;      Delay slots, can't describe load/fcmp/xfer delay slots here
116 ;;
117 ;; .........................
118
119 (define_delay (eq_attr "type" "branch")
120   [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
121    (nil)
122    (and (eq_attr "branch_likely" "yes") (and (eq_attr "dslot" "no") (eq_attr "length" "1")))])
123
124 (define_delay (eq_attr "type" "jump")
125   [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
126    (nil)
127    (nil)])
128
129 (define_delay (and (eq_attr "type" "call") (eq_attr "abicalls" "no"))
130   [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
131    (nil)
132    (nil)])
133
134 \f
135
136 ;; .........................
137 ;;
138 ;;      Functional units
139 ;;
140 ;; .........................
141
142 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
143 ;                       TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
144
145 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
146
147 (define_function_unit "memory" 1 0
148   (and (eq_attr "type" "load")
149        (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
150   3 0)
151
152 (define_function_unit "memory" 1 0
153   (and (eq_attr "type" "load")
154        (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
155   2 0)
156
157 (define_function_unit "memory"   1 0 (eq_attr "type" "store") 1 0)
158
159 (define_function_unit "memory"   1 0 (eq_attr "type" "xfer") 2 0)
160
161 (define_function_unit "imuldiv"  1 0
162   (eq_attr "type" "hilo")
163   1 3)
164
165 (define_function_unit "imuldiv"  1 0
166   (and (eq_attr "type" "imul")
167        (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
168   17 17)
169
170 (define_function_unit "imuldiv"  1 0
171   (and (eq_attr "type" "imul") (eq_attr "cpu" "r3000,r3900"))
172   12 12)
173
174 (define_function_unit "imuldiv"  1 0
175   (and (eq_attr "type" "imul") (eq_attr "cpu" "r4000,r4600"))
176   10 10)
177
178 (define_function_unit "imuldiv"  1 0
179   (and (eq_attr "type" "imul") (eq_attr "cpu" "r4650"))
180   4 4)
181
182 (define_function_unit "imuldiv"  1 0
183   (and (eq_attr "type" "imul")
184        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
185   1 1)
186
187 (define_function_unit "imuldiv"  1 0
188   (and (eq_attr "type" "imul")
189        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
190   4 4)
191
192 (define_function_unit "imuldiv"  1 0
193   (and (eq_attr "type" "imul")
194        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000")))
195   5 5)
196
197 (define_function_unit "imuldiv"  1 0
198   (and (eq_attr "type" "imul")
199        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
200   8 8)
201
202 (define_function_unit "imuldiv"  1 0
203   (and (eq_attr "type" "imul")
204        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
205   9 9)
206
207 (define_function_unit "imuldiv"  1 0
208   (and (eq_attr "type" "idiv")
209        (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
210   38 38)
211
212 (define_function_unit "imuldiv"  1 0
213   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000,r3900"))
214   35 35)
215
216 (define_function_unit "imuldiv"  1 0
217   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
218   42 42)
219
220 (define_function_unit "imuldiv"  1 0
221   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
222   36 36)
223
224 (define_function_unit "imuldiv"  1 0
225   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
226   69 69)
227
228 (define_function_unit "imuldiv" 1 0
229   (and (eq_attr "type" "idiv")
230        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
231   35 35)
232
233 (define_function_unit "imuldiv" 1 0
234   (and (eq_attr "type" "idiv")
235        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
236   67 67)
237
238 (define_function_unit "imuldiv" 1 0
239   (and (eq_attr "type" "idiv")
240        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
241   37 37)
242
243 (define_function_unit "imuldiv" 1 0
244   (and (eq_attr "type" "idiv")
245        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
246   69 69)
247
248 (define_function_unit "imuldiv" 1 0
249   (and (eq_attr "type" "idiv")
250        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000")))
251   36 36)
252
253 (define_function_unit "imuldiv" 1 0
254   (and (eq_attr "type" "idiv")
255        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
256   68 68)
257
258 ;; The R4300 does *NOT* have a separate Floating Point Unit, instead
259 ;; the FP hardware is part of the normal ALU circuitry.  This means FP
260 ;; instructions affect the pipe-line, and no functional unit
261 ;; parallelism can occur on R4300 processors.  To force GCC into coding
262 ;; for only a single functional unit, we force the R4300 FP
263 ;; instructions to be processed in the "imuldiv" unit.
264
265 (define_function_unit "adder" 1 1
266   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
267   3 0)
268
269 (define_function_unit "adder" 1 1
270   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r3900,r6000"))
271   2 0)
272
273 (define_function_unit "adder" 1 1
274   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000"))
275   1 0)
276
277 (define_function_unit "adder" 1 1
278   (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
279   4 0)
280
281 (define_function_unit "adder" 1 1
282   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000,r3900"))
283   2 0)
284
285 (define_function_unit "adder" 1 1
286   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
287   3 0)
288
289 (define_function_unit "adder" 1 1
290   (and (eq_attr "type" "fabs,fneg")
291        (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000"))
292   2 0)
293
294 (define_function_unit "adder" 1 1
295   (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r3900,r4600,r4650,r5000"))
296   1 0)
297
298 (define_function_unit "mult" 1 1
299   (and (eq_attr "type" "fmul")
300        (and (eq_attr "mode" "SF")
301             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
302   7 0)
303
304 (define_function_unit "mult" 1 1
305   (and (eq_attr "type" "fmul")
306        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900,r5000")))
307   4 0)
308
309 (define_function_unit "mult" 1 1
310   (and (eq_attr "type" "fmul")
311        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
312   5 0)
313
314 (define_function_unit "mult" 1 1
315   (and (eq_attr "type" "fmul")
316        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
317   8 0)
318
319 (define_function_unit "mult" 1 1
320   (and (eq_attr "type" "fmul")
321        (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")))
322   8 0)
323
324 (define_function_unit "mult" 1 1
325   (and (eq_attr "type" "fmul")
326        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900,r5000")))
327   5 0)
328
329 (define_function_unit "mult" 1 1
330   (and (eq_attr "type" "fmul")
331        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
332   6 0)
333
334 (define_function_unit "divide" 1 1
335   (and (eq_attr "type" "fdiv")
336        (and (eq_attr "mode" "SF")
337             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
338   23 0)
339
340 (define_function_unit "divide" 1 1
341   (and (eq_attr "type" "fdiv")
342        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900")))
343   12 0)
344
345 (define_function_unit "divide" 1 1
346   (and (eq_attr "type" "fdiv")
347        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
348   15 0)
349
350 (define_function_unit "divide" 1 1
351   (and (eq_attr "type" "fdiv")
352        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
353   32 0)
354
355 (define_function_unit "divide" 1 1
356   (and (eq_attr "type" "fdiv")
357        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
358   21 0)
359
360 (define_function_unit "divide" 1 1
361   (and (eq_attr "type" "fdiv")
362        (and (eq_attr "mode" "DF")
363             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300")))
364   36 0)
365
366 (define_function_unit "divide" 1 1
367   (and (eq_attr "type" "fdiv")
368        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900")))
369   19 0)
370
371 (define_function_unit "divide" 1 1
372   (and (eq_attr "type" "fdiv")
373        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
374   16 0)
375
376 (define_function_unit "divide" 1 1
377   (and (eq_attr "type" "fdiv")
378        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
379   61 0)
380
381 ;;; ??? Is this number right?
382 (define_function_unit "divide" 1 1
383   (and (eq_attr "type" "fsqrt")
384        (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
385   54 0)
386
387 (define_function_unit "divide" 1 1
388   (and (eq_attr "type" "fsqrt")
389        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
390   31 0)
391
392 (define_function_unit "divide" 1 1
393   (and (eq_attr "type" "fsqrt")
394        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
395   21 0)
396
397 ;;; ??? Is this number right?
398 (define_function_unit "divide" 1 1
399   (and (eq_attr "type" "fsqrt")
400        (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
401   112 0)
402
403 (define_function_unit "divide" 1 1
404   (and (eq_attr "type" "fsqrt")
405        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
406   60 0)
407
408 (define_function_unit "divide" 1 1
409   (and (eq_attr "type" "fsqrt")
410        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000")))
411   36 0)
412
413 ;; R4300 FP instruction classes treated as part of the "imuldiv"
414 ;; functional unit:
415
416 (define_function_unit "imuldiv" 1 0
417   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
418   3 3)
419
420 (define_function_unit "imuldiv" 1 0
421   (and (eq_attr "type" "fcmp,fabs,fneg") (eq_attr "cpu" "r4300"))
422   1 1)
423
424 (define_function_unit "imuldiv" 1 0
425   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
426   5 5)
427 (define_function_unit "imuldiv" 1 0
428   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
429   8 8)
430
431 (define_function_unit "imuldiv" 1 0
432   (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
433        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
434   29 29)
435 (define_function_unit "imuldiv" 1 0
436   (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
437        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
438   58 58)
439 \f
440 ;; The following functional units do not use the cpu type, and use
441 ;; much less memory in genattrtab.c.
442
443 ;; (define_function_unit "memory"   1 0 (eq_attr "type" "load")                                3 0)
444 ;; (define_function_unit "memory"   1 0 (eq_attr "type" "store")                               1 0)
445 ;;       
446 ;; (define_function_unit "fp_comp"  1 0 (eq_attr "type" "fcmp")                                2 0)
447 ;;       
448 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer")                                2 0)
449 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo")                                3 0)
450 ;;   
451 ;; (define_function_unit "imuldiv"  1 1 (eq_attr "type" "imul")                               17 0)
452 ;; (define_function_unit "imuldiv"  1 1 (eq_attr "type" "idiv")                               38 0)
453 ;;   
454 ;; (define_function_unit "adder"    1 1 (eq_attr "type" "fadd")                                4 0)
455 ;; (define_function_unit "adder"    1 1 (eq_attr "type" "fabs,fneg")                           2 0)
456 ;;   
457 ;; (define_function_unit "mult"     1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF"))    7 0)
458 ;; (define_function_unit "mult"     1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF"))    8 0)
459 ;;   
460 ;; (define_function_unit "divide"   1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF"))   23 0)
461 ;; (define_function_unit "divide"   1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF"))   36 0)
462 ;; 
463 ;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF"))  54 0)
464 ;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0)
465
466 \f
467 ;;
468 ;;  ....................
469 ;;
470 ;;      ADDITION
471 ;;
472 ;;  ....................
473 ;;
474
475 (define_insn "adddf3"
476   [(set (match_operand:DF 0 "register_operand" "=f")
477         (plus:DF (match_operand:DF 1 "register_operand" "f")
478                  (match_operand:DF 2 "register_operand" "f")))]
479   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
480   "add.d\\t%0,%1,%2"
481   [(set_attr "type"     "fadd")
482    (set_attr "mode"     "DF")
483    (set_attr "length"   "1")])
484
485 (define_insn "addsf3"
486   [(set (match_operand:SF 0 "register_operand" "=f")
487         (plus:SF (match_operand:SF 1 "register_operand" "f")
488                  (match_operand:SF 2 "register_operand" "f")))]
489   "TARGET_HARD_FLOAT"
490   "add.s\\t%0,%1,%2"
491   [(set_attr "type"     "fadd")
492    (set_attr "mode"     "SF")
493    (set_attr "length"   "1")])
494
495 (define_expand "addsi3"
496   [(set (match_operand:SI 0 "register_operand" "=d")
497         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
498                  (match_operand:SI 2 "arith_operand" "dI")))]
499   ""
500   "
501 {
502   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768)
503     operands[2] = force_reg (SImode, operands[2]);
504 }")
505
506 (define_insn "addsi3_internal"
507   [(set (match_operand:SI 0 "register_operand" "=d")
508         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
509                  (match_operand:SI 2 "arith_operand" "dI")))]
510   "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768"
511   "addu\\t%0,%z1,%2"
512   [(set_attr "type"     "arith")
513    (set_attr "mode"     "SI")
514    (set_attr "length"   "1")])
515
516 (define_expand "adddi3"
517   [(parallel [(set (match_operand:DI 0 "register_operand" "")
518                    (plus:DI (match_operand:DI 1 "se_register_operand" "")
519                             (match_operand:DI 2 "se_arith_operand" "")))
520               (clobber (match_dup 3))])]
521   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
522   "
523 {
524   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768)
525     operands[2] = force_reg (DImode, operands[2]);
526
527   if (TARGET_64BIT)
528     {
529       emit_insn (gen_adddi3_internal_3 (operands[0], operands[1],
530                                         operands[2]));
531       DONE;
532     }
533
534   operands[3] = gen_reg_rtx (SImode);
535 }")
536
537 (define_insn "adddi3_internal_1"
538   [(set (match_operand:DI 0 "register_operand" "=d,&d")
539         (plus:DI (match_operand:DI 1 "register_operand" "0,d")
540                  (match_operand:DI 2 "register_operand" "d,d")))
541    (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
542   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
543   "*
544 {
545   return (REGNO (operands[0]) == REGNO (operands[1])
546           && REGNO (operands[0]) == REGNO (operands[2]))
547     ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\"
548     : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\";
549 }"
550   [(set_attr "type"     "darith")
551    (set_attr "mode"     "DI")
552    (set_attr "length"   "4")])
553
554 (define_split
555   [(set (match_operand:DI 0 "register_operand" "")
556         (plus:DI (match_operand:DI 1 "register_operand" "")
557                  (match_operand:DI 2 "register_operand" "")))
558    (clobber (match_operand:SI 3 "register_operand" ""))]
559   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
560    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
561    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
562    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
563    && (REGNO (operands[0]) != REGNO (operands[1])
564        || REGNO (operands[0]) != REGNO (operands[2]))"
565
566   [(set (subreg:SI (match_dup 0) 0)
567         (plus:SI (subreg:SI (match_dup 1) 0)
568                  (subreg:SI (match_dup 2) 0)))
569
570    (set (match_dup 3)
571         (ltu:SI (subreg:SI (match_dup 0) 0)
572                 (subreg:SI (match_dup 2) 0)))
573
574    (set (subreg:SI (match_dup 0) 1)
575         (plus:SI (subreg:SI (match_dup 1) 1)
576                  (subreg:SI (match_dup 2) 1)))
577
578    (set (subreg:SI (match_dup 0) 1)
579         (plus:SI (subreg:SI (match_dup 0) 1)
580                  (match_dup 3)))]
581   "")
582
583 (define_split
584   [(set (match_operand:DI 0 "register_operand" "")
585         (plus:DI (match_operand:DI 1 "register_operand" "")
586                  (match_operand:DI 2 "register_operand" "")))
587    (clobber (match_operand:SI 3 "register_operand" ""))]
588   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
589    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
590    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
591    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
592    && (REGNO (operands[0]) != REGNO (operands[1])
593        || REGNO (operands[0]) != REGNO (operands[2]))"
594
595   [(set (subreg:SI (match_dup 0) 1)
596         (plus:SI (subreg:SI (match_dup 1) 1)
597                  (subreg:SI (match_dup 2) 1)))
598
599    (set (match_dup 3)
600         (ltu:SI (subreg:SI (match_dup 0) 1)
601                 (subreg:SI (match_dup 2) 1)))
602
603    (set (subreg:SI (match_dup 0) 0)
604         (plus:SI (subreg:SI (match_dup 1) 0)
605                  (subreg:SI (match_dup 2) 0)))
606
607    (set (subreg:SI (match_dup 0) 0)
608         (plus:SI (subreg:SI (match_dup 0) 0)
609                  (match_dup 3)))]
610   "")
611
612 (define_insn "adddi3_internal_2"
613   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
614         (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d")
615                  (match_operand:DI 2 "small_int" "P,J,N")))
616    (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
617   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && INTVAL (operands[2]) != -32768"
618   "@
619    addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3
620    move\\t%L0,%L1\;move\\t%M0,%M1
621    subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3"
622   [(set_attr "type"     "darith")
623    (set_attr "mode"     "DI")
624    (set_attr "length"   "3,2,4")])
625
626 (define_split
627   [(set (match_operand:DI 0 "register_operand" "")
628         (plus:DI (match_operand:DI 1 "register_operand" "")
629                  (match_operand:DI 2 "small_int" "")))
630    (clobber (match_operand:SI 3 "register_operand" "=d"))]
631   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
632    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
633    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
634    && INTVAL (operands[2]) > 0"
635
636   [(set (subreg:SI (match_dup 0) 0)
637         (plus:SI (subreg:SI (match_dup 1) 0)
638                  (match_dup 2)))
639
640    (set (match_dup 3)
641         (ltu:SI (subreg:SI (match_dup 0) 0)
642                 (match_dup 2)))
643
644    (set (subreg:SI (match_dup 0) 1)
645         (plus:SI (subreg:SI (match_dup 1) 1)
646                  (match_dup 3)))]
647   "")
648
649 (define_split
650   [(set (match_operand:DI 0 "register_operand" "")
651         (plus:DI (match_operand:DI 1 "register_operand" "")
652                  (match_operand:DI 2 "small_int" "")))
653    (clobber (match_operand:SI 3 "register_operand" "=d"))]
654   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
655    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
656    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
657    && INTVAL (operands[2]) > 0"
658
659   [(set (subreg:SI (match_dup 0) 1)
660         (plus:SI (subreg:SI (match_dup 1) 1)
661                  (match_dup 2)))
662
663    (set (match_dup 3)
664         (ltu:SI (subreg:SI (match_dup 0) 1)
665                 (match_dup 2)))
666
667    (set (subreg:SI (match_dup 0) 0)
668         (plus:SI (subreg:SI (match_dup 1) 0)
669                  (match_dup 3)))]
670   "")
671
672 (define_insn "adddi3_internal_3"
673   [(set (match_operand:DI 0 "register_operand" "=d")
674         (plus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
675                  (match_operand:DI 2 "se_arith_operand" "dI")))]
676   "TARGET_64BIT && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
677   "*
678 {
679   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
680     ? \"dsubu\\t%0,%z1,%n2\"
681     : \"daddu\\t%0,%z1,%2\";
682 }"
683   [(set_attr "type"     "darith")
684    (set_attr "mode"     "DI")
685    (set_attr "length"   "1")])
686
687
688 (define_insn "addsi3_internal_2"
689   [(set (match_operand:DI 0 "register_operand" "=d")
690         (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
691                                  (match_operand:SI 2 "arith_operand" "dI"))))]
692   "TARGET_64BIT && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
693   "*
694 {
695   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
696     ? \"subu\\t%0,%z1,%n2\"
697     : \"addu\\t%0,%z1,%2\";
698 }"
699   [(set_attr "type"     "arith")
700    (set_attr "mode"     "SI")
701    (set_attr "length"   "1")])
702
703 \f
704 ;;
705 ;;  ....................
706 ;;
707 ;;      SUBTRACTION
708 ;;
709 ;;  ....................
710 ;;
711
712 (define_insn "subdf3"
713   [(set (match_operand:DF 0 "register_operand" "=f")
714         (minus:DF (match_operand:DF 1 "register_operand" "f")
715                   (match_operand:DF 2 "register_operand" "f")))]
716   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
717   "sub.d\\t%0,%1,%2"
718   [(set_attr "type"     "fadd")
719    (set_attr "mode"     "DF")
720    (set_attr "length"   "1")])
721
722 (define_insn "subsf3"
723   [(set (match_operand:SF 0 "register_operand" "=f")
724         (minus:SF (match_operand:SF 1 "register_operand" "f")
725                   (match_operand:SF 2 "register_operand" "f")))]
726   "TARGET_HARD_FLOAT"
727   "sub.s\\t%0,%1,%2"
728   [(set_attr "type"     "fadd")
729    (set_attr "mode"     "SF")
730    (set_attr "length"   "1")])
731
732 (define_expand "subsi3"
733   [(set (match_operand:SI 0 "register_operand" "=d")
734         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
735                   (match_operand:SI 2 "arith_operand" "dI")))]
736   ""
737   "
738 {
739   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768)
740     operands[2] = force_reg (SImode, operands[2]);
741 }")
742
743 (define_insn "subsi3_internal"
744   [(set (match_operand:SI 0 "register_operand" "=d")
745         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
746                   (match_operand:SI 2 "arith_operand" "dI")))]
747   "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768"
748   "subu\\t%0,%z1,%2"
749   [(set_attr "type"     "arith")
750    (set_attr "mode"     "SI")
751    (set_attr "length"   "1")])
752
753 (define_expand "subdi3"
754   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
755                    (minus:DI (match_operand:DI 1 "se_register_operand" "d")
756                              (match_operand:DI 2 "se_register_operand" "d")))
757               (clobber (match_dup 3))])]
758   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
759   "
760 {
761   if (TARGET_64BIT)
762     {
763       emit_insn (gen_subdi3_internal_3 (operands[0], operands[1],
764                                         operands[2]));
765       DONE;
766     }
767
768   operands[3] = gen_reg_rtx (SImode);
769 }")
770
771 (define_insn "subdi3_internal"
772   [(set (match_operand:DI 0 "register_operand" "=d")
773         (minus:DI (match_operand:DI 1 "register_operand" "d")
774                   (match_operand:DI 2 "register_operand" "d")))
775    (clobber (match_operand:SI 3 "register_operand" "=d"))]
776   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
777   "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3"
778   [(set_attr "type"     "darith")
779    (set_attr "mode"     "DI")
780    (set_attr "length"   "4")])
781
782 (define_split
783   [(set (match_operand:DI 0 "register_operand" "")
784         (minus:DI (match_operand:DI 1 "register_operand" "")
785                   (match_operand:DI 2 "register_operand" "")))
786    (clobber (match_operand:SI 3 "register_operand" ""))]
787   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
788    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
789    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
790    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
791
792   [(set (match_dup 3)
793         (ltu:SI (subreg:SI (match_dup 1) 0)
794                 (subreg:SI (match_dup 2) 0)))
795
796    (set (subreg:SI (match_dup 0) 0)
797         (minus:SI (subreg:SI (match_dup 1) 0)
798                   (subreg:SI (match_dup 2) 0)))
799
800    (set (subreg:SI (match_dup 0) 1)
801         (minus:SI (subreg:SI (match_dup 1) 1)
802                   (subreg:SI (match_dup 2) 1)))
803
804    (set (subreg:SI (match_dup 0) 1)
805         (minus:SI (subreg:SI (match_dup 0) 1)
806                   (match_dup 3)))]
807   "")
808
809 (define_split
810   [(set (match_operand:DI 0 "register_operand" "")
811         (minus:DI (match_operand:DI 1 "register_operand" "")
812                   (match_operand:DI 2 "register_operand" "")))
813    (clobber (match_operand:SI 3 "register_operand" ""))]
814   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
815    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
816    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
817    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
818
819   [(set (match_dup 3)
820         (ltu:SI (subreg:SI (match_dup 1) 1)
821                 (subreg:SI (match_dup 2) 1)))
822
823    (set (subreg:SI (match_dup 0) 1)
824         (minus:SI (subreg:SI (match_dup 1) 1)
825                   (subreg:SI (match_dup 2) 1)))
826
827    (set (subreg:SI (match_dup 0) 0)
828         (minus:SI (subreg:SI (match_dup 1) 0)
829                   (subreg:SI (match_dup 2) 0)))
830
831    (set (subreg:SI (match_dup 0) 0)
832         (minus:SI (subreg:SI (match_dup 0) 0)
833                   (match_dup 3)))]
834   "")
835
836 (define_insn "subdi3_internal_2"
837   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
838         (minus:DI (match_operand:DI 1 "register_operand" "d,d,d")
839                   (match_operand:DI 2 "small_int" "P,J,N")))
840    (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
841   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && INTVAL (operands[2]) != -32768"
842   "@
843    sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3
844    move\\t%L0,%L1\;move\\t%M0,%M1
845    sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3"
846   [(set_attr "type"     "darith")
847    (set_attr "mode"     "DI")
848    (set_attr "length"   "3,2,4")])
849
850 (define_split
851   [(set (match_operand:DI 0 "register_operand" "")
852         (minus:DI (match_operand:DI 1 "register_operand" "")
853                   (match_operand:DI 2 "small_int" "")))
854    (clobber (match_operand:SI 3 "register_operand" ""))]
855   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
856    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
857    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
858    && INTVAL (operands[2]) > 0"
859
860   [(set (match_dup 3)
861         (ltu:SI (subreg:SI (match_dup 1) 0)
862                 (match_dup 2)))
863
864    (set (subreg:SI (match_dup 0) 0)
865         (minus:SI (subreg:SI (match_dup 1) 0)
866                   (match_dup 2)))
867
868    (set (subreg:SI (match_dup 0) 1)
869         (minus:SI (subreg:SI (match_dup 1) 1)
870                   (match_dup 3)))]
871   "")
872
873 (define_split
874   [(set (match_operand:DI 0 "register_operand" "")
875         (minus:DI (match_operand:DI 1 "register_operand" "")
876                   (match_operand:DI 2 "small_int" "")))
877    (clobber (match_operand:SI 3 "register_operand" ""))]
878   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
879    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
880    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
881    && INTVAL (operands[2]) > 0"
882
883   [(set (match_dup 3)
884         (ltu:SI (subreg:SI (match_dup 1) 1)
885                 (match_dup 2)))
886
887    (set (subreg:SI (match_dup 0) 1)
888         (minus:SI (subreg:SI (match_dup 1) 1)
889                   (match_dup 2)))
890
891    (set (subreg:SI (match_dup 0) 0)
892         (minus:SI (subreg:SI (match_dup 1) 0)
893                   (match_dup 3)))]
894   "")
895
896 (define_insn "subdi3_internal_3"
897   [(set (match_operand:DI 0 "register_operand" "=d")
898         (minus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
899                   (match_operand:DI 2 "se_arith_operand" "dI")))]
900   "TARGET_64BIT && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
901   "*
902 {
903   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
904     ? \"daddu\\t%0,%z1,%n2\"
905     : \"dsubu\\t%0,%z1,%2\";
906 }"
907   [(set_attr "type"     "darith")
908    (set_attr "mode"     "DI")
909    (set_attr "length"   "1")])
910
911
912 (define_insn "subsi3_internal_2"
913   [(set (match_operand:DI 0 "register_operand" "=d")
914         (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
915                                   (match_operand:SI 2 "arith_operand" "dI"))))]
916   "TARGET_64BIT && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
917   "*
918 {
919   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
920     ? \"addu\\t%0,%z1,%n2\"
921     : \"subu\\t%0,%z1,%2\";
922 }"
923   [(set_attr "type"     "arith")
924    (set_attr "mode"     "DI")
925    (set_attr "length"   "1")])
926
927 \f
928 ;;
929 ;;  ....................
930 ;;
931 ;;      MULTIPLICATION
932 ;;
933 ;;  ....................
934 ;;
935
936 ;; Early Vr4300 silicon has a CPU bug where multiplies with certain
937 ;; operands may corrupt immediately following multiplies. This is a
938 ;; simple fix to insert NOPs.
939
940 (define_expand "muldf3"
941   [(set (match_operand:DF 0 "register_operand" "=f")
942         (mult:DF (match_operand:DF 1 "register_operand" "f")
943                  (match_operand:DF 2 "register_operand" "f")))]
944   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
945   "
946 {
947   if (mips_cpu != PROCESSOR_R4300)
948     emit_insn (gen_muldf3_internal (operands[0], operands[1], operands[2]));
949   else
950     emit_insn (gen_muldf3_r4300 (operands[0], operands[1], operands[2]));
951   DONE;
952 }")
953
954 (define_insn "muldf3_internal"
955   [(set (match_operand:DF 0 "register_operand" "=f")
956         (mult:DF (match_operand:DF 1 "register_operand" "f")
957                  (match_operand:DF 2 "register_operand" "f")))]
958   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && mips_cpu != PROCESSOR_R4300"
959   "mul.d\\t%0,%1,%2"
960   [(set_attr "type"     "fmul")
961    (set_attr "mode"     "DF")
962    (set_attr "length"   "1")])
963
964 (define_insn "muldf3_r4300"
965   [(set (match_operand:DF 0 "register_operand" "=f")
966         (mult:DF (match_operand:DF 1 "register_operand" "f")
967                  (match_operand:DF 2 "register_operand" "f")))]
968   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && mips_cpu == PROCESSOR_R4300"
969   "*
970 {
971   output_asm_insn (\"mul.d\\t%0,%1,%2\", operands);
972   if (TARGET_4300_MUL_FIX)
973     output_asm_insn (\"nop\", operands);
974   return \"\";
975 }"
976   [(set_attr "type"     "fmul")
977    (set_attr "mode"     "DF")
978    (set_attr "length"   "2")])  ;; mul.d + nop
979
980 (define_expand "mulsf3"
981   [(set (match_operand:SF 0 "register_operand" "=f")
982         (mult:SF (match_operand:SF 1 "register_operand" "f")
983                  (match_operand:SF 2 "register_operand" "f")))]
984   "TARGET_HARD_FLOAT"
985   "
986 {
987   if (mips_cpu != PROCESSOR_R4300)
988     emit_insn( gen_mulsf3_internal (operands[0], operands[1], operands[2]));
989   else
990     emit_insn( gen_mulsf3_r4300 (operands[0], operands[1], operands[2]));
991   DONE;
992 }")
993
994 (define_insn "mulsf3_internal"
995   [(set (match_operand:SF 0 "register_operand" "=f")
996         (mult:SF (match_operand:SF 1 "register_operand" "f")
997                  (match_operand:SF 2 "register_operand" "f")))]
998   "TARGET_HARD_FLOAT && mips_cpu != PROCESSOR_R4300"
999   "mul.s\\t%0,%1,%2"
1000   [(set_attr "type"     "fmul")
1001    (set_attr "mode"     "SF")
1002    (set_attr "length"   "1")])
1003
1004 (define_insn "mulsf3_r4300"
1005   [(set (match_operand:SF 0 "register_operand" "=f")
1006         (mult:SF (match_operand:SF 1 "register_operand" "f")
1007                  (match_operand:SF 2 "register_operand" "f")))]
1008   "TARGET_HARD_FLOAT && mips_cpu == PROCESSOR_R4300"
1009   "*
1010 {
1011   output_asm_insn (\"mul.s\\t%0,%1,%2\", operands);
1012   if (TARGET_4300_MUL_FIX)
1013     output_asm_insn (\"nop\", operands);
1014   return \"\";
1015 }"
1016   [(set_attr "type"     "fmul")
1017    (set_attr "mode"     "SF")
1018    (set_attr "length"   "2")])  ;; mul.s + nop
1019
1020 ;; ??? The R4000 (only) has a cpu bug.  If a double-word shift executes while
1021 ;; a multiply is in progress, it may give an incorrect result.  Avoid
1022 ;; this by keeping the mflo with the mult on the R4000.
1023
1024 (define_expand "mulsi3"
1025   [(set (match_operand:SI 0 "register_operand" "=l")
1026         (mult:SI (match_operand:SI 1 "register_operand" "d")
1027                  (match_operand:SI 2 "register_operand" "d")))
1028    (clobber (match_scratch:SI 3 "=h"))
1029    (clobber (match_scratch:SI 4 "=a"))]
1030   ""
1031   "
1032 {
1033   if (GENERATE_MULT3)
1034     emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1035   else if (TARGET_MAD)
1036     emit_insn (gen_mulsi3_r4650 (operands[0], operands[1], operands[2]));
1037   else if (mips_cpu != PROCESSOR_R4000)
1038     emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1039   else
1040     emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1041   DONE;
1042 }")
1043
1044 (define_insn "mulsi3_mult3"
1045   [(set (match_operand:SI 0 "register_operand" "=d")
1046         (mult:SI (match_operand:SI 1 "register_operand" "d")
1047                  (match_operand:SI 2 "register_operand" "d")))
1048    (clobber (match_scratch:SI 3 "=h"))
1049    (clobber (match_scratch:SI 4 "=l"))
1050    (clobber (match_scratch:SI 5 "=a"))]
1051   "GENERATE_MULT3"
1052   "mult\\t%0,%1,%2"
1053   [(set_attr "type"     "imul")
1054    (set_attr "mode"     "SI")
1055    (set_attr "length"   "1")])
1056
1057 (define_insn "mulsi3_internal"
1058   [(set (match_operand:SI 0 "register_operand" "=l")
1059         (mult:SI (match_operand:SI 1 "register_operand" "d")
1060                  (match_operand:SI 2 "register_operand" "d")))
1061    (clobber (match_scratch:SI 3 "=h"))
1062    (clobber (match_scratch:SI 4 "=a"))]
1063   "mips_cpu != PROCESSOR_R4000"
1064   "mult\\t%1,%2"
1065   [(set_attr "type"     "imul")
1066    (set_attr "mode"     "SI")
1067    (set_attr "length"   "1")])
1068
1069 (define_insn "mulsi3_r4000"
1070   [(set (match_operand:SI 0 "register_operand" "=d")
1071         (mult:SI (match_operand:SI 1 "register_operand" "d")
1072                  (match_operand:SI 2 "register_operand" "d")))
1073    (clobber (match_scratch:SI 3 "=h"))
1074    (clobber (match_scratch:SI 4 "=l"))
1075    (clobber (match_scratch:SI 5 "=a"))]
1076   "mips_cpu == PROCESSOR_R4000"
1077   "*
1078 {
1079   rtx xoperands[10];
1080
1081   xoperands[0] = operands[0];
1082   xoperands[1] = gen_rtx (REG, SImode, LO_REGNUM);
1083
1084   output_asm_insn (\"mult\\t%1,%2\", operands);
1085   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1086   return \"\";
1087 }"
1088   [(set_attr "type"     "imul")
1089    (set_attr "mode"     "SI")
1090    (set_attr "length"   "3")])          ;; mult + mflo + delay
1091
1092 (define_insn "mulsi3_r4650"
1093   [(set (match_operand:SI 0 "register_operand" "=d")
1094         (mult:SI (match_operand:SI 1 "register_operand" "d")
1095                  (match_operand:SI 2 "register_operand" "d")))
1096    (clobber (match_scratch:SI 3 "=h"))
1097    (clobber (match_scratch:SI 4 "=l"))
1098    (clobber (match_scratch:SI 5 "=a"))]
1099   "TARGET_MAD"
1100   "mul\\t%0,%1,%2"
1101   [(set_attr "type"     "imul")
1102    (set_attr "mode"     "SI")
1103    (set_attr "length"   "1")])
1104
1105 (define_expand "muldi3"
1106   [(set (match_operand:DI 0 "register_operand" "=l")
1107         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1108                  (match_operand:DI 2 "register_operand" "d")))
1109    (clobber (match_scratch:DI 3 "=h"))
1110    (clobber (match_scratch:DI 4 "=a"))]
1111   "TARGET_64BIT"
1112   "
1113 {
1114   if (GENERATE_MULT3 || mips_cpu == PROCESSOR_R4000)
1115     emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2]));
1116   else
1117     emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1118   DONE;
1119 }")
1120
1121 ;; Don't accept both operands using se_register_operand, because if
1122 ;; both operands are sign extended we would prefer to use mult in the
1123 ;; mulsidi3 pattern.  Commutativity should permit either operand to be
1124 ;; sign extended.
1125
1126 (define_insn "muldi3_internal"
1127   [(set (match_operand:DI 0 "register_operand" "=l")
1128         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1129                  (match_operand:DI 2 "register_operand" "d")))
1130    (clobber (match_scratch:DI 3 "=h"))
1131    (clobber (match_scratch:DI 4 "=a"))]
1132   "TARGET_64BIT && mips_cpu != PROCESSOR_R4000"
1133   "dmult\\t%1,%2"
1134   [(set_attr "type"     "imul")
1135    (set_attr "mode"     "DI")
1136    (set_attr "length"   "1")])
1137
1138 (define_insn "muldi3_internal2"
1139   [(set (match_operand:DI 0 "register_operand" "=d")
1140         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1141                  (match_operand:DI 2 "register_operand" "d")))
1142    (clobber (match_scratch:DI 3 "=h"))
1143    (clobber (match_scratch:DI 4 "=l"))
1144    (clobber (match_scratch:DI 5 "=a"))]
1145   "TARGET_64BIT && (GENERATE_MULT3 || mips_cpu == PROCESSOR_R4000)"
1146   "*
1147 {
1148   if (GENERATE_MULT3)
1149     output_asm_insn (\"dmult\\t%0,%1,%2\", operands);
1150   else 
1151     {
1152     rtx xoperands[10];
1153
1154     xoperands[0] = operands[0];
1155     xoperands[1] = gen_rtx (REG, DImode, LO_REGNUM);
1156
1157     output_asm_insn (\"dmult\\t%1,%2\", operands);
1158     output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1159     }
1160   return \"\";
1161 }"
1162   [(set_attr "type"     "imul")
1163    (set_attr "mode"     "DI")
1164    (set (attr "length")
1165         (if_then_else (ne (symbol_ref "GENERATE_MULT3") (const_int 0))
1166                        (const_int 1)
1167                        (const_int 3)))])        ;; mult + mflo + delay
1168
1169 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1170
1171 (define_expand "mulsidi3"
1172   [(set (match_operand:DI 0 "register_operand" "=x")
1173         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1174                  (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1175   ""
1176   "
1177 {
1178   if (TARGET_64BIT)
1179     emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2]));
1180   else
1181     emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2]));
1182   DONE;
1183 }")
1184
1185 (define_insn "mulsidi3_internal"
1186   [(set (match_operand:DI 0 "register_operand" "=x")
1187         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1188                  (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1189    (clobber (match_scratch:SI 3 "=a"))]
1190   "!TARGET_64BIT"
1191   "mult\\t%1,%2"
1192   [(set_attr "type"     "imul")
1193    (set_attr "mode"     "SI")
1194    (set_attr "length"   "1")])
1195
1196 (define_insn "mulsidi3_64bit"
1197   [(set (match_operand:DI 0 "register_operand" "=a")
1198         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1199                  (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1200    (clobber (match_scratch:DI 3 "=l"))
1201    (clobber (match_scratch:DI 4 "=h"))]
1202   "TARGET_64BIT"
1203   "mult\\t%1,%2"
1204   [(set_attr "type"     "imul")
1205    (set_attr "mode"     "SI")
1206    (set_attr "length"   "1")])
1207
1208 (define_insn "smulsi3_highpart"
1209   [(set (match_operand:SI 0 "register_operand" "=h")
1210         (truncate:SI
1211          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1212                                (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
1213                       (const_int 32))))
1214    (clobber (match_scratch:SI 3 "=l"))
1215    (clobber (match_scratch:SI 4 "=a"))]
1216   ""
1217   "mult\\t%1,%2"
1218   [(set_attr "type"     "imul")
1219    (set_attr "mode"     "SI")
1220    (set_attr "length"   "1")])
1221
1222 (define_expand "umulsidi3"
1223   [(set (match_operand:DI 0 "register_operand" "=x")
1224         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1225                  (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1226   ""
1227   "
1228 {
1229   if (TARGET_64BIT)
1230     emit_insn (gen_umulsidi3_64bit (operands[0], operands[1], operands[2]));
1231   else
1232     emit_insn (gen_umulsidi3_internal (operands[0], operands[1], operands[2]));
1233   DONE;
1234 }")
1235
1236 (define_insn "umulsidi3_internal"
1237   [(set (match_operand:DI 0 "register_operand" "=x")
1238         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1239                  (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1240    (clobber (match_scratch:SI 3 "=a"))]
1241   "!TARGET_64BIT"
1242   "multu\\t%1,%2"
1243   [(set_attr "type"     "imul")
1244    (set_attr "mode"     "SI")
1245    (set_attr "length"   "1")])
1246
1247 (define_insn "umulsidi3_64bit"
1248   [(set (match_operand:DI 0 "register_operand" "=a")
1249         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1250                  (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1251    (clobber (match_scratch:DI 3 "=l"))
1252    (clobber (match_scratch:DI 4 "=h"))]
1253   "TARGET_64BIT"
1254   "multu\\t%1,%2"
1255   [(set_attr "type"     "imul")
1256    (set_attr "mode"     "SI")
1257    (set_attr "length"   "1")])
1258
1259 (define_insn "umulsi3_highpart"
1260   [(set (match_operand:SI 0 "register_operand" "=h")
1261         (truncate:SI
1262          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1263                                (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
1264                       (const_int 32))))
1265    (clobber (match_scratch:SI 3 "=l"))
1266    (clobber (match_scratch:SI 4 "=a"))]
1267   ""
1268   "multu\\t%1,%2"
1269   [(set_attr "type"     "imul")
1270    (set_attr "mode"     "SI")
1271    (set_attr "length"   "1")])
1272
1273 (define_insn "smuldi3_highpart"
1274   [(set (match_operand:DI 0 "register_operand" "=h")
1275         (truncate:DI
1276          (lshiftrt:TI (mult:TI (sign_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
1277                                (sign_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
1278                       (const_int 64))))
1279    (clobber (match_scratch:DI 3 "=l"))
1280    (clobber (match_scratch:DI 4 "=a"))]
1281   "TARGET_64BIT"
1282   "dmult\\t%1,%2"
1283   [(set_attr "type"     "imul")
1284    (set_attr "mode"     "DI")
1285    (set_attr "length"   "1")])
1286
1287 (define_insn "umuldi3_highpart"
1288   [(set (match_operand:DI 0 "register_operand" "=h")
1289         (truncate:DI
1290          (lshiftrt:TI (mult:TI (zero_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
1291                                (zero_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
1292                       (const_int 64))))
1293    (clobber (match_scratch:DI 3 "=l"))
1294    (clobber (match_scratch:DI 4 "=a"))]
1295   "TARGET_64BIT"
1296   "dmultu\\t%1,%2"
1297   [(set_attr "type"     "imul")
1298    (set_attr "mode"     "DI")
1299    (set_attr "length"   "1")])
1300
1301 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1302 ;; instruction.  The HI/LO registers are used as a 64 bit accumulator.
1303
1304 (define_insn "madsi"
1305   [(set (match_operand:SI 0 "register_operand" "+l")
1306         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1307                           (match_operand:SI 2 "register_operand" "d"))
1308                  (match_dup 0)))
1309    (clobber (match_scratch:SI 3 "=h"))
1310    (clobber (match_scratch:SI 4 "=a"))]
1311   "TARGET_MAD || GENERATE_MADD"
1312   "*
1313 {
1314   if (TARGET_MAD)
1315     return \"mad\\t%1,%2\";
1316   else
1317     return \"madd\\t%1,%2\";
1318 }"
1319   [(set_attr "type"     "imul")
1320    (set_attr "mode"     "SI")
1321    (set_attr "length"   "1")])
1322
1323 (define_insn "maddi"
1324   [(set (match_operand:DI 0 "register_operand" "+x")
1325         (plus:DI (mult:DI (sign_extend:DI
1326                            (match_operand:SI 1 "register_operand" "d"))
1327                           (sign_extend:DI
1328                            (match_operand:SI 2 "register_operand" "d")))
1329                  (match_dup 0)))
1330    (clobber (match_scratch:SI 3 "=a"))]
1331   "TARGET_MAD && ! TARGET_64BIT"
1332   "mad\\t%1,%2"
1333   [(set_attr "type"     "imul")
1334    (set_attr "mode"     "SI")
1335    (set_attr "length"   "1")])
1336
1337 (define_insn "maddi_64bit"
1338   [(set (match_operand:DI 0 "register_operand" "+a")
1339         (plus:DI (mult:DI (sign_extend:DI
1340                            (match_operand:SI 1 "register_operand" "d"))
1341                           (sign_extend:DI
1342                            (match_operand:SI 2 "register_operand" "d")))
1343                  (match_dup 0)))
1344    (clobber (match_scratch:DI 3 "=l"))
1345    (clobber (match_scratch:DI 4 "=h"))]
1346   "TARGET_MAD && TARGET_64BIT"
1347   "mad\\t%1,%2"
1348   [(set_attr "type"     "imul")
1349    (set_attr "mode"     "SI")
1350    (set_attr "length"   "1")])
1351
1352 (define_insn "umaddi"
1353   [(set (match_operand:DI 0 "register_operand" "+x")
1354         (plus:DI (mult:DI (zero_extend:DI
1355                            (match_operand:SI 1 "register_operand" "d"))
1356                           (zero_extend:DI
1357                            (match_operand:SI 2 "register_operand" "d")))
1358                  (match_dup 0)))
1359    (clobber (match_scratch:SI 3 "=a"))]
1360   "TARGET_MAD && ! TARGET_64BIT"
1361   "madu\\t%1,%2"
1362   [(set_attr "type"     "imul")
1363    (set_attr "mode"     "SI")
1364    (set_attr "length"   "1")])
1365
1366 (define_insn "umaddi_64bit"
1367   [(set (match_operand:DI 0 "register_operand" "+a")
1368         (plus:DI (mult:DI (zero_extend:DI
1369                            (match_operand:SI 1 "register_operand" "d"))
1370                           (zero_extend:DI
1371                            (match_operand:SI 2 "register_operand" "d")))
1372                  (match_dup 0)))
1373    (clobber (match_scratch:DI 3 "=l"))
1374    (clobber (match_scratch:DI 4 "=h"))]
1375   "TARGET_MAD && TARGET_64BIT"
1376   "madu\\t%1,%2"
1377   [(set_attr "type"     "imul")
1378    (set_attr "mode"     "SI")
1379    (set_attr "length"   "1")])
1380
1381 (define_insn "madd3"
1382   [(set (match_operand:SI 0 "register_operand" "=d")
1383         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1384                           (match_operand:SI 2 "register_operand" "d"))
1385                  (match_operand:SI 3 "register_operand" "l")))
1386    (clobber (match_scratch:SI 4 "=l"))
1387    (clobber (match_scratch:SI 5 "=h"))
1388    (clobber (match_scratch:SI 6 "=a"))]
1389   "GENERATE_MADD"
1390   "madd\\t%0,%1,%2"
1391   [(set_attr "type"     "imul")
1392    (set_attr "mode"     "SI")
1393    (set_attr "length"   "1")])
1394
1395 ;; Floating point multiply accumulate instructions.
1396
1397 (define_insn ""
1398   [(set (match_operand:DF 0 "register_operand" "=f")
1399         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1400                           (match_operand:DF 2 "register_operand" "f"))
1401                  (match_operand:DF 3 "register_operand" "f")))]
1402   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1403   "madd.d\\t%0,%3,%1,%2"
1404   [(set_attr "type"     "fmadd")
1405    (set_attr "mode"     "DF")
1406    (set_attr "length"   "1")])
1407
1408 (define_insn ""
1409   [(set (match_operand:SF 0 "register_operand" "=f")
1410         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1411                           (match_operand:SF 2 "register_operand" "f"))
1412                  (match_operand:SF 3 "register_operand" "f")))]
1413   "mips_isa >= 4 && TARGET_HARD_FLOAT"
1414   "madd.s\\t%0,%3,%1,%2"
1415   [(set_attr "type"     "fmadd")
1416    (set_attr "mode"     "SF")
1417    (set_attr "length"   "1")])
1418
1419 (define_insn ""
1420   [(set (match_operand:DF 0 "register_operand" "=f")
1421         (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1422                            (match_operand:DF 2 "register_operand" "f"))
1423                   (match_operand:DF 3 "register_operand" "f")))]
1424   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1425   "msub.d\\t%0,%3,%1,%2"
1426   [(set_attr "type"     "fmadd")
1427    (set_attr "mode"     "DF")
1428    (set_attr "length"   "1")])
1429
1430 (define_insn ""
1431   [(set (match_operand:SF 0 "register_operand" "=f")
1432         (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1433                            (match_operand:SF 2 "register_operand" "f"))
1434                   (match_operand:SF 3 "register_operand" "f")))]
1435                   
1436   "mips_isa >= 4 && TARGET_HARD_FLOAT"
1437   "msub.s\\t%0,%3,%1,%2"
1438   [(set_attr "type"     "fmadd")
1439    (set_attr "mode"     "SF")
1440    (set_attr "length"   "1")])
1441
1442 (define_insn ""
1443   [(set (match_operand:DF 0 "register_operand" "=f")
1444         (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1445                                   (match_operand:DF 2 "register_operand" "f"))
1446                          (match_operand:DF 3 "register_operand" "f"))))]
1447   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1448   "nmadd.d\\t%0,%3,%1,%2"
1449   [(set_attr "type"     "fmadd")
1450    (set_attr "mode"     "DF")
1451    (set_attr "length"   "1")])
1452
1453 (define_insn ""
1454   [(set (match_operand:SF 0 "register_operand" "=f")
1455         (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1456                                   (match_operand:SF 2 "register_operand" "f"))
1457                          (match_operand:SF 3 "register_operand" "f"))))]
1458   "mips_isa >= 4 && TARGET_HARD_FLOAT"
1459   "nmadd.s\\t%0,%3,%1,%2"
1460   [(set_attr "type"     "fmadd")
1461    (set_attr "mode"     "SF")
1462    (set_attr "length"   "1")])
1463
1464 (define_insn ""
1465   [(set (match_operand:DF 0 "register_operand" "=f")
1466         (minus:DF (match_operand:DF 1 "register_operand" "f")
1467                   (mult:DF (match_operand:DF 2 "register_operand" "f")
1468                            (match_operand:DF 3 "register_operand" "f"))))]
1469   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1470   "nmsub.d\\t%0,%1,%2,%3"
1471   [(set_attr "type"     "fmadd")
1472    (set_attr "mode"     "DF")
1473    (set_attr "length"   "1")])
1474
1475 (define_insn ""
1476   [(set (match_operand:SF 0 "register_operand" "=f")
1477         (minus:SF (match_operand:SF 1 "register_operand" "f")
1478                   (mult:SF (match_operand:SF 2 "register_operand" "f")
1479                            (match_operand:SF 3 "register_operand" "f"))))]
1480   "mips_isa >= 4 && TARGET_HARD_FLOAT"
1481   "nmsub.s\\t%0,%1,%2,%3"
1482   [(set_attr "type"     "fmadd")
1483    (set_attr "mode"     "SF")
1484    (set_attr "length"   "1")])
1485 \f
1486 ;;
1487 ;;  ....................
1488 ;;
1489 ;;      DIVISION and REMAINDER
1490 ;;
1491 ;;  ....................
1492 ;;
1493
1494 (define_insn "divdf3"
1495   [(set (match_operand:DF 0 "register_operand" "=f")
1496         (div:DF (match_operand:DF 1 "register_operand" "f")
1497                 (match_operand:DF 2 "register_operand" "f")))]
1498   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1499   "div.d\\t%0,%1,%2"
1500   [(set_attr "type"     "fdiv")
1501    (set_attr "mode"     "DF")
1502    (set_attr "length"   "1")])
1503
1504 (define_insn "divsf3"
1505   [(set (match_operand:SF 0 "register_operand" "=f")
1506         (div:SF (match_operand:SF 1 "register_operand" "f")
1507                 (match_operand:SF 2 "register_operand" "f")))]
1508   "TARGET_HARD_FLOAT"
1509   "div.s\\t%0,%1,%2"
1510   [(set_attr "type"     "fdiv")
1511    (set_attr "mode"     "SF")
1512    (set_attr "length"   "1")])
1513
1514 (define_insn ""
1515   [(set (match_operand:DF 0 "register_operand" "=f")
1516         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
1517                 (match_operand:DF 2 "register_operand" "f")))]
1518   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_fast_math"
1519   "recip.d\\t%0,%2"
1520   [(set_attr "type"     "fdiv")
1521    (set_attr "mode"     "DF")
1522    (set_attr "length"   "1")])
1523
1524 (define_insn ""
1525   [(set (match_operand:SF 0 "register_operand" "=f")
1526         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
1527                 (match_operand:SF 2 "register_operand" "f")))]
1528   "mips_isa >= 4 && TARGET_HARD_FLOAT && flag_fast_math"
1529   "recip.s\\t%0,%2"
1530   [(set_attr "type"     "fdiv")
1531    (set_attr "mode"     "SF")
1532    (set_attr "length"   "1")])
1533
1534 ;; If optimizing, prefer the divmod functions over separate div and
1535 ;; mod functions, since this will allow using one instruction for both
1536 ;; the quotient and remainder.  At present, the divmod is not moved out
1537 ;; of loops if it is constant within the loop, so allow -mdebugc to
1538 ;; use the old method of doing things.
1539
1540 ;; 64 is the multiply/divide hi register
1541 ;; 65 is the multiply/divide lo register
1542
1543 ;; ??? We can't accept constants here, because the MIPS assembler will replace
1544 ;; a divide by power of 2 with a shift, and then the remainder is no longer
1545 ;; available.
1546
1547 (define_insn "divmodsi4"
1548   [(set (match_operand:SI 0 "register_operand" "=d")
1549         (div:SI (match_operand:SI 1 "register_operand" "d")
1550                 (match_operand:SI 2 "register_operand" "d")))
1551    (set (match_operand:SI 3 "register_operand" "=d")
1552         (mod:SI (match_dup 1)
1553                 (match_dup 2)))
1554    (clobber (match_scratch:SI 4 "=l"))
1555    (clobber (match_scratch:SI 5 "=h"))
1556    (clobber (match_scratch:SI 6 "=a"))]
1557   "optimize"
1558   "*
1559 {
1560   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1561     return \"div\\t%0,%1,%2\";
1562
1563   if (find_reg_note (insn, REG_UNUSED, operands[0]))
1564     return \"rem\\t%3,%1,%2\";
1565
1566   return \"div\\t%0,%1,%2\;mfhi\\t%3\";
1567 }"
1568   [(set_attr "type"     "idiv")
1569    (set_attr "mode"     "SI")
1570    (set_attr "length"   "14")])         ;; various tests for dividing by 0 and such
1571
1572 (define_insn "divmoddi4"
1573   [(set (match_operand:DI 0 "register_operand" "=d")
1574         (div:DI (match_operand:DI 1 "se_register_operand" "d")
1575                 (match_operand:DI 2 "se_register_operand" "d")))
1576    (set (match_operand:DI 3 "register_operand" "=d")
1577         (mod:DI (match_dup 1)
1578                 (match_dup 2)))
1579    (clobber (match_scratch:DI 4 "=l"))
1580    (clobber (match_scratch:DI 5 "=h"))
1581    (clobber (match_scratch:DI 6 "=a"))]
1582   "TARGET_64BIT && optimize"
1583   "*
1584 {
1585   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1586     return \"ddiv\\t%0,%1,%2\";
1587
1588   if (find_reg_note (insn, REG_UNUSED, operands[0]))
1589     return \"drem\\t%3,%1,%2\";
1590
1591   return \"ddiv\\t%0,%1,%2\;mfhi\\t%3\";
1592 }"
1593   [(set_attr "type"     "idiv")
1594    (set_attr "mode"     "DI")
1595    (set_attr "length"   "15")])         ;; various tests for dividing by 0 and such
1596
1597 (define_insn "udivmodsi4"
1598   [(set (match_operand:SI 0 "register_operand" "=d")
1599         (udiv:SI (match_operand:SI 1 "register_operand" "d")
1600                  (match_operand:SI 2 "register_operand" "d")))
1601    (set (match_operand:SI 3 "register_operand" "=d")
1602         (umod:SI (match_dup 1)
1603                  (match_dup 2)))
1604    (clobber (match_scratch:SI 4 "=l"))
1605    (clobber (match_scratch:SI 5 "=h"))
1606    (clobber (match_scratch:SI 6 "=a"))]
1607   "optimize"
1608   "*
1609 {
1610   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1611     return \"divu\\t%0,%1,%2\";
1612
1613   if (find_reg_note (insn, REG_UNUSED, operands[0]))
1614     return \"remu\\t%3,%1,%2\";
1615
1616   return \"divu\\t%0,%1,%2\;mfhi\\t%3\";
1617 }"
1618   [(set_attr "type"     "idiv")
1619    (set_attr "mode"     "SI")
1620    (set_attr "length"   "8")])          ;; various tests for dividing by 0 and such
1621
1622 (define_insn "udivmoddi4"
1623   [(set (match_operand:DI 0 "register_operand" "=d")
1624         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
1625                  (match_operand:DI 2 "se_register_operand" "d")))
1626    (set (match_operand:DI 3 "register_operand" "=d")
1627         (umod:DI (match_dup 1)
1628                  (match_dup 2)))
1629    (clobber (match_scratch:DI 4 "=l"))
1630    (clobber (match_scratch:DI 5 "=h"))
1631    (clobber (match_scratch:DI 6 "=a"))]
1632   "TARGET_64BIT && optimize"
1633   "*
1634 {
1635   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1636     return \"ddivu\\t%0,%1,%2\";
1637
1638   if (find_reg_note (insn, REG_UNUSED, operands[0]))
1639     return \"dremu\\t%3,%1,%2\";
1640
1641   return \"ddivu\\t%0,%1,%2\;mfhi\\t%3\";
1642 }"
1643   [(set_attr "type"     "idiv")
1644    (set_attr "mode"     "DI")
1645    (set_attr "length"   "8")])          ;; various tests for dividing by 0 and such
1646
1647 (define_insn "divsi3"
1648   [(set (match_operand:SI 0 "register_operand" "=d")
1649         (div:SI (match_operand:SI 1 "register_operand" "d")
1650                 (match_operand:SI 2 "nonmemory_operand" "di")))
1651    (clobber (match_scratch:SI 3 "=l"))
1652    (clobber (match_scratch:SI 4 "=h"))
1653    (clobber (match_scratch:SI 6 "=a"))]
1654   "!optimize"
1655   "div\\t%0,%1,%2"
1656   [(set_attr "type"     "idiv")
1657    (set_attr "mode"     "SI")
1658    (set_attr "length"   "13")])         ;; various tests for dividing by 0 and such
1659
1660 (define_insn "divdi3"
1661   [(set (match_operand:DI 0 "register_operand" "=d")
1662         (div:DI (match_operand:DI 1 "se_register_operand" "d")
1663                 (match_operand:DI 2 "se_nonmemory_operand" "di")))
1664    (clobber (match_scratch:DI 3 "=l"))
1665    (clobber (match_scratch:DI 4 "=h"))
1666    (clobber (match_scratch:DI 6 "=a"))]
1667   "TARGET_64BIT && !optimize"
1668   "ddiv\\t%0,%1,%2"
1669   [(set_attr "type"     "idiv")
1670    (set_attr "mode"     "DI")
1671    (set_attr "length"   "14")])         ;; various tests for dividing by 0 and such
1672
1673 (define_insn "modsi3"
1674   [(set (match_operand:SI 0 "register_operand" "=d")
1675         (mod:SI (match_operand:SI 1 "register_operand" "d")
1676                 (match_operand:SI 2 "nonmemory_operand" "di")))
1677    (clobber (match_scratch:SI 3 "=l"))
1678    (clobber (match_scratch:SI 4 "=h"))
1679    (clobber (match_scratch:SI 6 "=a"))]
1680   "!optimize"
1681   "rem\\t%0,%1,%2"
1682   [(set_attr "type"     "idiv")
1683    (set_attr "mode"     "SI")
1684    (set_attr "length"   "13")])         ;; various tests for dividing by 0 and such
1685
1686 (define_insn "moddi3"
1687   [(set (match_operand:DI 0 "register_operand" "=d")
1688         (mod:DI (match_operand:DI 1 "se_register_operand" "d")
1689                 (match_operand:DI 2 "se_nonmemory_operand" "di")))
1690    (clobber (match_scratch:DI 3 "=l"))
1691    (clobber (match_scratch:DI 4 "=h"))
1692    (clobber (match_scratch:DI 6 "=a"))]
1693   "TARGET_64BIT && !optimize"
1694   "drem\\t%0,%1,%2"
1695   [(set_attr "type"     "idiv")
1696    (set_attr "mode"     "DI")
1697    (set_attr "length"   "14")])         ;; various tests for dividing by 0 and such
1698
1699 (define_insn "udivsi3"
1700   [(set (match_operand:SI 0 "register_operand" "=d")
1701         (udiv:SI (match_operand:SI 1 "register_operand" "d")
1702                  (match_operand:SI 2 "nonmemory_operand" "di")))
1703    (clobber (match_scratch:SI 3 "=l"))
1704    (clobber (match_scratch:SI 4 "=h"))
1705    (clobber (match_scratch:SI 6 "=a"))]
1706   "!optimize"
1707   "divu\\t%0,%1,%2"
1708   [(set_attr "type"     "idiv")
1709    (set_attr "mode"     "SI")
1710    (set_attr "length"   "7")])          ;; various tests for dividing by 0 and such
1711
1712 (define_insn "udivdi3"
1713   [(set (match_operand:DI 0 "register_operand" "=d")
1714         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
1715                  (match_operand:DI 2 "se_nonmemory_operand" "di")))
1716    (clobber (match_scratch:DI 3 "=l"))
1717    (clobber (match_scratch:DI 4 "=h"))
1718    (clobber (match_scratch:DI 6 "=a"))]
1719   "TARGET_64BIT && !optimize"
1720   "ddivu\\t%0,%1,%2"
1721   [(set_attr "type"     "idiv")
1722    (set_attr "mode"     "DI")
1723    (set_attr "length"   "7")])          ;; various tests for dividing by 0 and such
1724
1725 (define_insn "umodsi3"
1726   [(set (match_operand:SI 0 "register_operand" "=d")
1727         (umod:SI (match_operand:SI 1 "register_operand" "d")
1728                  (match_operand:SI 2 "nonmemory_operand" "di")))
1729    (clobber (match_scratch:SI 3 "=l"))
1730    (clobber (match_scratch:SI 4 "=h"))
1731    (clobber (match_scratch:SI 6 "=a"))]
1732   "!optimize"
1733   "remu\\t%0,%1,%2"
1734   [(set_attr "type"     "idiv")
1735    (set_attr "mode"     "SI")
1736    (set_attr "length"   "7")])          ;; various tests for dividing by 0 and such
1737
1738 (define_insn "umoddi3"
1739   [(set (match_operand:DI 0 "register_operand" "=d")
1740         (umod:DI (match_operand:DI 1 "se_register_operand" "d")
1741                  (match_operand:DI 2 "se_nonmemory_operand" "di")))
1742    (clobber (match_scratch:DI 3 "=l"))
1743    (clobber (match_scratch:DI 4 "=h"))
1744    (clobber (match_scratch:DI 6 "=a"))]
1745   "TARGET_64BIT && !optimize"
1746   "dremu\\t%0,%1,%2"
1747   [(set_attr "type"     "idiv")
1748    (set_attr "mode"     "DI")
1749    (set_attr "length"   "7")])          ;; various tests for dividing by 0 and such
1750
1751 \f
1752 ;;
1753 ;;  ....................
1754 ;;
1755 ;;      SQUARE ROOT
1756 ;;
1757 ;;  ....................
1758
1759 (define_insn "sqrtdf2"
1760   [(set (match_operand:DF 0 "register_operand" "=f")
1761         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
1762   "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
1763   "sqrt.d\\t%0,%1"
1764   [(set_attr "type"     "fsqrt")
1765    (set_attr "mode"     "DF")
1766    (set_attr "length"   "1")])
1767
1768 (define_insn "sqrtsf2"
1769   [(set (match_operand:SF 0 "register_operand" "=f")
1770         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
1771   "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
1772   "sqrt.s\\t%0,%1"
1773   [(set_attr "type"     "fsqrt")
1774    (set_attr "mode"     "SF")
1775    (set_attr "length"   "1")])
1776
1777 (define_insn ""
1778   [(set (match_operand:DF 0 "register_operand" "=f")
1779         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
1780                 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
1781   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_fast_math"
1782   "rsqrt.d\\t%0,%2"
1783   [(set_attr "type"     "fsqrt")
1784    (set_attr "mode"     "DF")
1785    (set_attr "length"   "1")])
1786
1787 (define_insn ""
1788   [(set (match_operand:SF 0 "register_operand" "=f")
1789         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
1790                 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
1791   "mips_isa >= 4 && TARGET_HARD_FLOAT && flag_fast_math"
1792   "rsqrt.s\\t%0,%2"
1793   [(set_attr "type"     "fsqrt")
1794    (set_attr "mode"     "SF")
1795    (set_attr "length"   "1")])
1796
1797 \f
1798 ;;
1799 ;;  ....................
1800 ;;
1801 ;;      ABSOLUTE VALUE
1802 ;;
1803 ;;  ....................
1804
1805 ;; Do not use the integer abs macro instruction, since that signals an
1806 ;; exception on -2147483648 (sigh).
1807
1808 (define_insn "abssi2"
1809   [(set (match_operand:SI 0 "register_operand" "=d")
1810         (abs:SI (match_operand:SI 1 "register_operand" "d")))]
1811   ""
1812   "*
1813 {
1814   dslots_jump_total++;
1815   dslots_jump_filled++;
1816   operands[2] = const0_rtx;
1817
1818   if (REGNO (operands[0]) == REGNO (operands[1]))
1819     {
1820       if (GENERATE_BRANCHLIKELY)
1821         return \"%(bltzl\\t%1,1f\\n\\tsubu\\t%0,%z2,%0\\n1:%)\";
1822       else
1823         return \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n1:\";
1824     }     
1825   else
1826     return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n1:%)\";
1827 }"
1828   [(set_attr "type"     "multi")
1829    (set_attr "mode"     "SI")
1830    (set_attr "length"   "3")])
1831
1832 (define_insn "absdi2"
1833   [(set (match_operand:DI 0 "register_operand" "=d")
1834         (abs:DI (match_operand:DI 1 "se_register_operand" "d")))]
1835   "TARGET_64BIT"
1836   "*
1837 {
1838   dslots_jump_total++;
1839   dslots_jump_filled++;
1840   operands[2] = const0_rtx;
1841
1842   if (REGNO (operands[0]) == REGNO (operands[1]))
1843     return \"%(bltzl\\t%1,1f\\n\\tdsubu\\t%0,%z2,%0\\n1:%)\";
1844   else
1845     return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tdsubu\\t%0,%z2,%0\\n1:%)\";
1846 }"
1847   [(set_attr "type"     "multi")
1848    (set_attr "mode"     "DI")
1849    (set_attr "length"   "3")])
1850
1851 (define_insn "absdf2"
1852   [(set (match_operand:DF 0 "register_operand" "=f")
1853         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
1854   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1855   "abs.d\\t%0,%1"
1856   [(set_attr "type"     "fabs")
1857    (set_attr "mode"     "DF")
1858    (set_attr "length"   "1")])
1859
1860 (define_insn "abssf2"
1861   [(set (match_operand:SF 0 "register_operand" "=f")
1862         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
1863   "TARGET_HARD_FLOAT"
1864   "abs.s\\t%0,%1"
1865   [(set_attr "type"     "fabs")
1866    (set_attr "mode"     "SF")
1867    (set_attr "length"   "1")])
1868
1869 \f
1870 ;;
1871 ;;  ....................
1872 ;;
1873 ;;      FIND FIRST BIT INSTRUCTION
1874 ;;
1875 ;;  ....................
1876 ;;
1877
1878 (define_insn "ffssi2"
1879   [(set (match_operand:SI 0 "register_operand" "=&d")
1880         (ffs:SI (match_operand:SI 1 "register_operand" "d")))
1881    (clobber (match_scratch:SI 2 "=&d"))
1882    (clobber (match_scratch:SI 3 "=&d"))]
1883   ""
1884   "*
1885 {
1886   dslots_jump_total += 2;
1887   dslots_jump_filled += 2;
1888   operands[4] = const0_rtx;
1889
1890   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
1891     return \"%(\\
1892 move\\t%0,%z4\\n\\
1893 \\tbeq\\t%1,%z4,2f\\n\\
1894 1:\\tand\\t%2,%1,0x0001\\n\\
1895 \\taddu\\t%0,%0,1\\n\\
1896 \\tbeq\\t%2,%z4,1b\\n\\
1897 \\tsrl\\t%1,%1,1\\n\\
1898 2:%)\";
1899
1900   return \"%(\\
1901 move\\t%0,%z4\\n\\
1902 \\tmove\\t%3,%1\\n\\
1903 \\tbeq\\t%3,%z4,2f\\n\\
1904 1:\\tand\\t%2,%3,0x0001\\n\\
1905 \\taddu\\t%0,%0,1\\n\\
1906 \\tbeq\\t%2,%z4,1b\\n\\
1907 \\tsrl\\t%3,%3,1\\n\\
1908 2:%)\";
1909 }"
1910   [(set_attr "type"     "multi")
1911    (set_attr "mode"     "SI")
1912    (set_attr "length"   "6")])
1913
1914 (define_insn "ffsdi2"
1915   [(set (match_operand:DI 0 "register_operand" "=&d")
1916         (ffs:DI (match_operand:DI 1 "se_register_operand" "d")))
1917    (clobber (match_scratch:DI 2 "=&d"))
1918    (clobber (match_scratch:DI 3 "=&d"))]
1919   "TARGET_64BIT"
1920   "*
1921 {
1922   dslots_jump_total += 2;
1923   dslots_jump_filled += 2;
1924   operands[4] = const0_rtx;
1925
1926   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
1927     return \"%(\\
1928 move\\t%0,%z4\\n\\
1929 \\tbeq\\t%1,%z4,2f\\n\\
1930 1:\\tand\\t%2,%1,0x0001\\n\\
1931 \\tdaddu\\t%0,%0,1\\n\\
1932 \\tbeq\\t%2,%z4,1b\\n\\
1933 \\tdsrl\\t%1,%1,1\\n\\
1934 2:%)\";
1935
1936   return \"%(\\
1937 move\\t%0,%z4\\n\\
1938 \\tmove\\t%3,%1\\n\\
1939 \\tbeq\\t%3,%z4,2f\\n\\
1940 1:\\tand\\t%2,%3,0x0001\\n\\
1941 \\tdaddu\\t%0,%0,1\\n\\
1942 \\tbeq\\t%2,%z4,1b\\n\\
1943 \\tdsrl\\t%3,%3,1\\n\\
1944 2:%)\";
1945 }"
1946   [(set_attr "type"     "multi")
1947    (set_attr "mode"     "DI")
1948    (set_attr "length"   "6")])
1949
1950 \f
1951 ;;
1952 ;;  ....................
1953 ;;
1954 ;;      NEGATION and ONE'S COMPLEMENT
1955 ;;
1956 ;;  ....................
1957
1958 (define_insn "negsi2"
1959   [(set (match_operand:SI 0 "register_operand" "=d")
1960         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
1961   ""
1962   "*
1963 {
1964   operands[2] = const0_rtx;
1965   return \"subu\\t%0,%z2,%1\";
1966 }"
1967   [(set_attr "type"     "arith")
1968    (set_attr "mode"     "SI")
1969    (set_attr "length"   "1")])
1970
1971 (define_expand "negdi2"
1972   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
1973                    (neg:DI (match_operand:DI 1 "se_register_operand" "d")))
1974               (clobber (match_dup 2))])]
1975   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
1976   "
1977 {
1978   if (TARGET_64BIT)
1979     {
1980       emit_insn (gen_negdi2_internal_2 (operands[0], operands[1]));
1981       DONE;
1982     }
1983
1984   operands[2] = gen_reg_rtx (SImode);
1985 }")
1986
1987 (define_insn "negdi2_internal"
1988   [(set (match_operand:DI 0 "register_operand" "=d")
1989         (neg:DI (match_operand:DI 1 "register_operand" "d")))
1990    (clobber (match_operand:SI 2 "register_operand" "=d"))]
1991   "! TARGET_64BIT && !TARGET_DEBUG_G_MODE"
1992   "*
1993 {
1994   operands[3] = const0_rtx;
1995   return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\";
1996 }"
1997   [(set_attr "type"     "darith")
1998    (set_attr "mode"     "DI")
1999    (set_attr "length"   "4")])
2000
2001 (define_insn "negdi2_internal_2"
2002   [(set (match_operand:DI 0 "register_operand" "=d")
2003         (neg:DI (match_operand:DI 1 "se_register_operand" "d")))]
2004   "TARGET_64BIT"
2005   "*
2006 {
2007   operands[2] = const0_rtx;
2008   return \"dsubu\\t%0,%z2,%1\";
2009 }"
2010   [(set_attr "type"     "arith")
2011    (set_attr "mode"     "DI")
2012    (set_attr "length"   "1")])
2013
2014 (define_insn "negdf2"
2015   [(set (match_operand:DF 0 "register_operand" "=f")
2016         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
2017   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2018   "neg.d\\t%0,%1"
2019   [(set_attr "type"     "fneg")
2020    (set_attr "mode"     "DF")
2021    (set_attr "length"   "1")])
2022
2023 (define_insn "negsf2"
2024   [(set (match_operand:SF 0 "register_operand" "=f")
2025         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2026   "TARGET_HARD_FLOAT"
2027   "neg.s\\t%0,%1"
2028   [(set_attr "type"     "fneg")
2029    (set_attr "mode"     "SF")
2030    (set_attr "length"   "1")])
2031
2032 (define_insn "one_cmplsi2"
2033   [(set (match_operand:SI 0 "register_operand" "=d")
2034         (not:SI (match_operand:SI 1 "register_operand" "d")))]
2035   ""
2036   "*
2037 {
2038   operands[2] = const0_rtx;
2039   return \"nor\\t%0,%z2,%1\";
2040 }"
2041   [(set_attr "type"     "arith")
2042    (set_attr "mode"     "SI")
2043    (set_attr "length"   "1")])
2044
2045 (define_insn "one_cmpldi2"
2046   [(set (match_operand:DI 0 "register_operand" "=d")
2047         (not:DI (match_operand:DI 1 "se_register_operand" "d")))]
2048   ""
2049   "*
2050 {
2051   operands[2] = const0_rtx;
2052   if (TARGET_64BIT)
2053     return \"nor\\t%0,%z2,%1\";
2054   return \"nor\\t%M0,%z2,%M1\;nor\\t%L0,%z2,%L1\";
2055 }"
2056   [(set_attr "type"     "darith")
2057    (set_attr "mode"     "DI")
2058    (set (attr "length")
2059         (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
2060                        (const_int 1)
2061                        (const_int 2)))])
2062
2063 (define_split
2064   [(set (match_operand:DI 0 "register_operand" "")
2065         (not:DI (match_operand:DI 1 "register_operand" "")))]
2066   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2067    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
2068    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
2069
2070   [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0)))
2071    (set (subreg:SI (match_dup 0) 1) (not:SI (subreg:SI (match_dup 1) 1)))]
2072   "")
2073
2074 \f
2075 ;;
2076 ;;  ....................
2077 ;;
2078 ;;      LOGICAL
2079 ;;
2080 ;;  ....................
2081 ;;
2082
2083 (define_insn "andsi3"
2084   [(set (match_operand:SI 0 "register_operand" "=d,d")
2085         (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2086                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2087   ""
2088   "@
2089    and\\t%0,%1,%2
2090    andi\\t%0,%1,%x2"
2091   [(set_attr "type"     "arith")
2092    (set_attr "mode"     "SI")
2093    (set_attr "length"   "1")])
2094
2095 (define_insn "anddi3"
2096   [(set (match_operand:DI 0 "register_operand" "=d")
2097         (and:DI (match_operand:DI 1 "se_register_operand" "d")
2098                 (match_operand:DI 2 "se_register_operand" "d")))]
2099   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
2100   "*
2101 {
2102   if (TARGET_64BIT)
2103     return \"and\\t%0,%1,%2\";
2104   return \"and\\t%M0,%M1,%M2\;and\\t%L0,%L1,%L2\";
2105 }"
2106   [(set_attr "type"     "darith")
2107    (set_attr "mode"     "DI")
2108    (set (attr "length")
2109         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
2110                        (const_int 1)
2111                        (const_int 2)))])
2112
2113 (define_split
2114   [(set (match_operand:DI 0 "register_operand" "")
2115         (and:DI (match_operand:DI 1 "register_operand" "")
2116                 (match_operand:DI 2 "register_operand" "")))]
2117   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2118    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
2119    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
2120    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
2121
2122   [(set (subreg:SI (match_dup 0) 0) (and:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
2123    (set (subreg:SI (match_dup 0) 1) (and:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
2124   "")
2125
2126 (define_insn "anddi3_internal1"
2127   [(set (match_operand:DI 0 "register_operand" "=d,d")
2128         (and:DI (match_operand:DI 1 "se_register_operand" "%d,d")
2129                 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
2130   "TARGET_64BIT"
2131   "@
2132    and\\t%0,%1,%2
2133    andi\\t%0,%1,%x2"
2134   [(set_attr "type"     "arith")
2135    (set_attr "mode"     "DI")
2136    (set_attr "length"   "1")])
2137
2138 (define_insn "iorsi3"
2139   [(set (match_operand:SI 0 "register_operand" "=d,d")
2140         (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2141                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2142   ""
2143   "@
2144    or\\t%0,%1,%2
2145    ori\\t%0,%1,%x2"
2146   [(set_attr "type"     "arith")
2147    (set_attr "mode"     "SI")
2148    (set_attr "length"   "1")])
2149
2150 ;;; ??? There is no iordi3 pattern which accepts 'K' constants when
2151 ;;; TARGET_64BIT
2152
2153 (define_insn "iordi3"
2154   [(set (match_operand:DI 0 "register_operand" "=d")
2155         (ior:DI (match_operand:DI 1 "se_register_operand" "d")
2156                 (match_operand:DI 2 "se_register_operand" "d")))]
2157   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
2158   "*
2159 {
2160   if (TARGET_64BIT)
2161     return \"or\\t%0,%1,%2\";
2162   return \"or\\t%M0,%M1,%M2\;or\\t%L0,%L1,%L2\";
2163 }"
2164   [(set_attr "type"     "darith")
2165    (set_attr "mode"     "DI")
2166    (set (attr "length")
2167         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
2168                        (const_int 1)
2169                        (const_int 2)))])
2170
2171 (define_split
2172   [(set (match_operand:DI 0 "register_operand" "")
2173         (ior:DI (match_operand:DI 1 "register_operand" "")
2174                 (match_operand:DI 2 "register_operand" "")))]
2175   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2176    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
2177    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
2178    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
2179
2180   [(set (subreg:SI (match_dup 0) 0) (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
2181    (set (subreg:SI (match_dup 0) 1) (ior:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
2182   "")
2183
2184 (define_insn "xorsi3"
2185   [(set (match_operand:SI 0 "register_operand" "=d,d")
2186         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2187                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2188   ""
2189   "@
2190    xor\\t%0,%1,%2
2191    xori\\t%0,%1,%x2"
2192   [(set_attr "type"     "arith")
2193    (set_attr "mode"     "SI")
2194    (set_attr "length"   "1")])
2195
2196 ;; ??? If delete the 32-bit long long patterns, then could merge this with
2197 ;; the following xordi3_internal pattern.
2198 (define_insn "xordi3"
2199   [(set (match_operand:DI 0 "register_operand" "=d")
2200         (xor:DI (match_operand:DI 1 "se_register_operand" "d")
2201                 (match_operand:DI 2 "se_register_operand" "d")))]
2202   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
2203   "*
2204 {
2205   if (TARGET_64BIT)
2206     return \"xor\\t%0,%1,%2\";
2207   return \"xor\\t%M0,%M1,%M2\;xor\\t%L0,%L1,%L2\";
2208 }"
2209   [(set_attr "type"     "darith")
2210    (set_attr "mode"     "DI")
2211    (set (attr "length")
2212         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
2213                        (const_int 1)
2214                        (const_int 2)))])
2215
2216 (define_split
2217   [(set (match_operand:DI 0 "register_operand" "")
2218         (xor:DI (match_operand:DI 1 "register_operand" "")
2219                 (match_operand:DI 2 "register_operand" "")))]
2220   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2221    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
2222    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
2223    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
2224
2225   [(set (subreg:SI (match_dup 0) 0) (xor:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
2226    (set (subreg:SI (match_dup 0) 1) (xor:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
2227   "")
2228
2229 (define_insn "xordi3_immed"
2230   [(set (match_operand:DI 0 "register_operand" "d")
2231         (xor:DI (match_operand:DI 1 "se_register_operand" "d")
2232                 (match_operand:DI 2 "se_uns_arith_operand" "K")))]
2233   "TARGET_64BIT"
2234   "xori\\t%0,%1,%x2"
2235   [(set_attr "type"     "arith")
2236    (set_attr "mode"     "DI")
2237    (set_attr "length"   "1")])
2238
2239 (define_insn "*norsi3"
2240   [(set (match_operand:SI 0 "register_operand" "=d")
2241         (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
2242                 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
2243   ""
2244   "nor\\t%0,%z1,%z2"
2245   [(set_attr "type"     "arith")
2246    (set_attr "mode"     "SI")
2247    (set_attr "length"   "1")])
2248
2249 (define_insn "*nordi3"
2250   [(set (match_operand:DI 0 "register_operand" "=d")
2251         (and:DI (not:DI (match_operand:DI 1 "se_register_operand" "d"))
2252                 (not:DI (match_operand:DI 2 "se_register_operand" "d"))))]
2253   ""
2254   "*
2255 {
2256   if (TARGET_64BIT)
2257     return \"nor\\t%0,%z1,%z2\";
2258   return \"nor\\t%M0,%M1,%M2\;nor\\t%L0,%L1,%L2\";
2259 }"
2260   [(set_attr "type"     "darith")
2261    (set_attr "mode"     "DI")
2262    (set (attr "length")
2263         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
2264                        (const_int 1)
2265                        (const_int 2)))])
2266
2267 (define_split
2268   [(set (match_operand:DI 0 "register_operand" "")
2269         (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
2270                 (not:DI (match_operand:DI 2 "register_operand" ""))))]
2271   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2272    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
2273    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
2274    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
2275
2276   [(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))))
2277    (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))))]
2278   "")
2279 \f
2280 ;;
2281 ;;  ....................
2282 ;;
2283 ;;      TRUNCATION
2284 ;;
2285 ;;  ....................
2286
2287 (define_insn "truncdfsf2"
2288   [(set (match_operand:SF 0 "register_operand" "=f")
2289         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2290   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2291   "cvt.s.d\\t%0,%1"
2292   [(set_attr "type"     "fcvt")
2293    (set_attr "mode"     "SF")
2294    (set_attr "length"   "1")])
2295
2296 (define_insn "truncdisi2"
2297   [(set (match_operand:SI 0 "register_operand" "=d")
2298         (truncate:SI (match_operand:DI 1 "se_register_operand" "d")))]
2299   "TARGET_64BIT"
2300   "dsll\\t%0,%1,32\;dsra\\t%0,%0,32"
2301   [(set_attr "type"     "darith")
2302    (set_attr "mode"     "SI")
2303    (set_attr "length"   "2")])
2304
2305 (define_insn "truncdihi2"
2306   [(set (match_operand:HI 0 "register_operand" "=d")
2307         (truncate:HI (match_operand:DI 1 "se_register_operand" "d")))]
2308   "TARGET_64BIT"
2309   "andi\\t%0,%1,0xffff"
2310   [(set_attr "type"     "darith")
2311    (set_attr "mode"     "HI")
2312    (set_attr "length"   "1")])
2313
2314 (define_insn "truncdiqi2"
2315   [(set (match_operand:QI 0 "register_operand" "=d")
2316         (truncate:QI (match_operand:DI 1 "se_register_operand" "d")))]
2317   "TARGET_64BIT"
2318   "andi\\t%0,%1,0x00ff"
2319   [(set_attr "type"     "darith")
2320    (set_attr "mode"     "QI")
2321    (set_attr "length"   "1")])
2322
2323 ;; Combiner patterns to optimize shift/truncate combinations.
2324 (define_insn ""
2325   [(set (match_operand:SI 0 "register_operand" "=d")
2326         (truncate:SI (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
2327                                   (match_operand:DI 2 "small_int" "I"))))]
2328   "TARGET_64BIT"
2329   "*
2330 {
2331   int shift_amt = INTVAL (operands[2]) & 0x3f;
2332
2333   if (shift_amt < 32)
2334     {
2335       operands[2] = GEN_INT (32 - shift_amt);
2336       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
2337     }
2338   else
2339     {
2340       operands[2] = GEN_INT (shift_amt);
2341       return \"dsra\\t%0,%1,%2\";
2342     }
2343 }"
2344   [(set_attr "type"     "darith")
2345    (set_attr "mode"     "SI")
2346    (set_attr "length"   "2")])
2347         
2348 (define_insn ""
2349   [(set (match_operand:SI 0 "register_operand" "=d")
2350         (truncate:SI (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
2351                                   (match_operand:DI 2 "small_int" "I"))))]
2352   "TARGET_64BIT"
2353   "*
2354 {
2355   int shift_amt = INTVAL (operands[2]) & 0x3f;
2356
2357   if (shift_amt < 32)
2358     {
2359       operands[2] = GEN_INT (32 - shift_amt);
2360       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
2361     }
2362   else if (shift_amt == 32)
2363     return \"dsra\\t%0,%1,32\";
2364   else
2365     {
2366       operands[2] = GEN_INT (shift_amt);
2367       return \"dsrl\\t%0,%1,%2\";
2368     }
2369 }"
2370   [(set_attr "type"     "darith")
2371    (set_attr "mode"     "SI")
2372    (set_attr "length"   "2")])
2373
2374 (define_insn ""
2375   [(set (match_operand:SI 0 "register_operand" "=d")
2376         (truncate:SI (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
2377                                 (match_operand:DI 2 "small_int" "I"))))]
2378   "TARGET_64BIT"
2379   "*
2380 {
2381   int shift_amt = INTVAL (operands[2]) & 0x3f;
2382
2383   if (shift_amt < 32)
2384     {
2385       operands[2] = GEN_INT (32 + shift_amt);
2386       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
2387     }
2388   else
2389     return \"move\\t%0,%.\";
2390 }"
2391   [(set_attr "type"     "darith")
2392    (set_attr "mode"     "SI")
2393    (set_attr "length"   "2")])
2394
2395 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2396
2397 (define_insn ""
2398   [(set (match_operand:SI 0 "register_operand" "=d")
2399         (zero_extend:SI (truncate:HI
2400                          (match_operand:DI 1 "se_register_operand" "d"))))]
2401   "TARGET_64BIT"
2402   "andi\\t%0,%1,0xffff"
2403   [(set_attr "type"     "darith")
2404    (set_attr "mode"     "SI")
2405    (set_attr "length"   "1")])
2406
2407 (define_insn ""
2408   [(set (match_operand:SI 0 "register_operand" "=d")
2409         (zero_extend:SI (truncate:QI
2410                          (match_operand:DI 1 "se_register_operand" "d"))))]
2411   "TARGET_64BIT"
2412   "andi\\t%0,%1,0xff"
2413   [(set_attr "type"     "darith")
2414    (set_attr "mode"     "SI")
2415    (set_attr "length"   "1")])
2416
2417 (define_insn ""
2418   [(set (match_operand:HI 0 "register_operand" "=d")
2419         (zero_extend:HI (truncate:QI
2420                          (match_operand:DI 1 "se_register_operand" "d"))))]
2421   "TARGET_64BIT"
2422   "andi\\t%0,%1,0xff"
2423   [(set_attr "type"     "darith")
2424    (set_attr "mode"     "HI")
2425    (set_attr "length"   "1")])
2426 \f
2427 ;;
2428 ;;  ....................
2429 ;;
2430 ;;      ZERO EXTENSION
2431 ;;
2432 ;;  ....................
2433
2434 ;; Extension insns.
2435 ;; Those for integer source operand are ordered widest source type first.
2436
2437 (define_expand "zero_extendsidi2"
2438   [(set (match_operand:DI 0 "register_operand" "")
2439         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
2440   "TARGET_64BIT"
2441   "
2442 {
2443   if (optimize && GET_CODE (operands[1]) == MEM)
2444     operands[1] = force_not_mem (operands[1]);
2445
2446   if (GET_CODE (operands[1]) != MEM)
2447     {
2448       rtx op1   = gen_lowpart (DImode, operands[1]);
2449       rtx temp  = gen_reg_rtx (DImode);
2450       rtx shift = gen_rtx (CONST_INT, VOIDmode, 32);
2451
2452       emit_insn (gen_ashldi3 (temp, op1, shift));
2453       emit_insn (gen_lshrdi3 (operands[0], temp, shift));
2454       DONE;
2455     }
2456 }")
2457
2458 (define_insn "zero_extendsidi2_internal"
2459   [(set (match_operand:DI 0 "register_operand" "=d,d")
2460         (zero_extend:DI (match_operand:SI 1 "memory_operand" "R,m")))]
2461   "TARGET_64BIT"
2462   "* return mips_move_1word (operands, insn, TRUE);"
2463   [(set_attr "type"     "load")
2464    (set_attr "mode"     "DI")
2465    (set_attr "length"   "1,2")])
2466
2467 (define_insn "zero_extendhisi2"
2468   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
2469         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
2470   ""
2471   "*
2472 {
2473   if (which_alternative == 0)
2474     return \"andi\\t%0,%1,0xffff\";
2475   else
2476     return mips_move_1word (operands, insn, TRUE);
2477 }"
2478   [(set_attr "type"     "arith,load,load")
2479    (set_attr "mode"     "SI")
2480    (set_attr "length"   "1,1,2")])
2481
2482 (define_insn "zero_extendhidi2"
2483   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
2484         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
2485   "TARGET_64BIT"
2486   "*
2487 {
2488   if (which_alternative == 0)
2489     return \"andi\\t%0,%1,0xffff\";
2490   else
2491     return mips_move_1word (operands, insn, TRUE);
2492 }"
2493   [(set_attr "type"     "arith,load,load")
2494    (set_attr "mode"     "DI")
2495    (set_attr "length"   "1,1,2")])
2496
2497 (define_insn "zero_extendqihi2"
2498   [(set (match_operand:HI 0 "register_operand" "=d,d,d")
2499         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
2500   ""
2501   "*
2502 {
2503   if (which_alternative == 0)
2504     return \"andi\\t%0,%1,0x00ff\";
2505   else
2506     return mips_move_1word (operands, insn, TRUE);
2507 }"
2508   [(set_attr "type"     "arith,load,load")
2509    (set_attr "mode"     "HI")
2510    (set_attr "length"   "1,1,2")])
2511
2512 (define_insn "zero_extendqisi2"
2513   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
2514         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
2515   ""
2516   "*
2517 {
2518   if (which_alternative == 0)
2519     return \"andi\\t%0,%1,0x00ff\";
2520   else
2521     return mips_move_1word (operands, insn, TRUE);
2522 }"
2523   [(set_attr "type"     "arith,load,load")
2524    (set_attr "mode"     "SI")
2525    (set_attr "length"   "1,1,2")])
2526
2527 (define_insn "zero_extendqidi2"
2528   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
2529         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
2530   "TARGET_64BIT"
2531   "*
2532 {
2533   if (which_alternative == 0)
2534     return \"andi\\t%0,%1,0x00ff\";
2535   else
2536     return mips_move_1word (operands, insn, TRUE);
2537 }"
2538   [(set_attr "type"     "arith,load,load")
2539    (set_attr "mode"     "DI")
2540    (set_attr "length"   "1,1,2")])
2541
2542 ;; These can be created when a paradoxical subreg operand with an implicit
2543 ;; sign_extend operator is reloaded.  Because of the subreg, this is really
2544 ;; a zero extend.
2545 ;; ??? It might be possible to eliminate the need for these patterns by adding
2546 ;; more support to reload for implicit sign_extend operators.
2547 (define_insn "*paradoxical_extendhidi2"
2548   [(set (match_operand:DI 0 "register_operand" "=d,d")
2549         (sign_extend:DI
2550          (subreg:SI (match_operand:HI 1 "memory_operand" "R,m") 0)))]
2551   "TARGET_64BIT"
2552   "*
2553 {
2554   return mips_move_1word (operands, insn, TRUE);
2555 }"
2556   [(set_attr "type"     "load,load")
2557    (set_attr "mode"     "DI")
2558    (set_attr "length"   "1,2")])
2559
2560 (define_insn "*paradoxical_extendqidi2"
2561   [(set (match_operand:DI 0 "register_operand" "=d,d")
2562         (sign_extend:DI
2563          (subreg:SI (match_operand:QI 1 "memory_operand" "R,m") 0)))]
2564   "TARGET_64BIT"
2565   "*
2566 {
2567   return mips_move_1word (operands, insn, TRUE);
2568 }"
2569   [(set_attr "type"     "load,load")
2570    (set_attr "mode"     "DI")
2571    (set_attr "length"   "1,2")])
2572 \f
2573 ;;
2574 ;;  ....................
2575 ;;
2576 ;;      SIGN EXTENSION
2577 ;;
2578 ;;  ....................
2579
2580 ;; Extension insns.
2581 ;; Those for integer source operand are ordered widest source type first.
2582
2583 ;; In 64 bit mode, 32 bit values in general registers are always
2584 ;; correctly sign extended.  That means that if the target is a
2585 ;; general register, we can sign extend from SImode to DImode just by
2586 ;; doing a move.
2587
2588 (define_insn "extendsidi2"
2589   [(set (match_operand:DI 0 "register_operand" "=d,*d,d,d")
2590         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,*x,R,m")))]
2591   "TARGET_64BIT"
2592   "* return mips_move_1word (operands, insn, FALSE);"
2593   [(set_attr "type"     "move,hilo,load,load")
2594    (set_attr "mode"     "DI")
2595    (set_attr "length"   "1,1,1,2")])
2596
2597 ;; These patterns originally accepted general_operands, however, slightly
2598 ;; better code is generated by only accepting register_operands, and then
2599 ;; letting combine generate the lh and lb insns.
2600
2601 (define_expand "extendhidi2"
2602   [(set (match_operand:DI 0 "register_operand" "")
2603         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
2604   "TARGET_64BIT"
2605   "
2606 {
2607   if (optimize && GET_CODE (operands[1]) == MEM)
2608     operands[1] = force_not_mem (operands[1]);
2609
2610   if (GET_CODE (operands[1]) != MEM)
2611     {
2612       rtx op1   = gen_lowpart (DImode, operands[1]);
2613       rtx temp  = gen_reg_rtx (DImode);
2614       rtx shift = gen_rtx (CONST_INT, VOIDmode, 48);
2615
2616       emit_insn (gen_ashldi3 (temp, op1, shift));
2617       emit_insn (gen_ashrdi3 (operands[0], temp, shift));
2618       DONE;
2619     }
2620 }")
2621
2622 (define_insn "extendhidi2_internal"
2623   [(set (match_operand:DI 0 "register_operand" "=d,d")
2624         (sign_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
2625   "TARGET_64BIT"
2626   "* return mips_move_1word (operands, insn, FALSE);"
2627   [(set_attr "type"     "load")
2628    (set_attr "mode"     "DI")
2629    (set_attr "length"   "1,2")])
2630
2631 (define_expand "extendhisi2"
2632   [(set (match_operand:SI 0 "register_operand" "")
2633         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2634   ""
2635   "
2636 {
2637   if (optimize && GET_CODE (operands[1]) == MEM)
2638     operands[1] = force_not_mem (operands[1]);
2639
2640   if (GET_CODE (operands[1]) != MEM)
2641     {
2642       rtx op1   = gen_lowpart (SImode, operands[1]);
2643       rtx temp  = gen_reg_rtx (SImode);
2644       rtx shift = gen_rtx (CONST_INT, VOIDmode, 16);
2645
2646       emit_insn (gen_ashlsi3 (temp, op1, shift));
2647       emit_insn (gen_ashrsi3 (operands[0], temp, shift));
2648       DONE;
2649     }
2650 }")
2651
2652 (define_insn "extendhisi2_internal"
2653   [(set (match_operand:SI 0 "register_operand" "=d,d")
2654         (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
2655   ""
2656   "* return mips_move_1word (operands, insn, FALSE);"
2657   [(set_attr "type"     "load")
2658    (set_attr "mode"     "SI")
2659    (set_attr "length"   "1,2")])
2660
2661 (define_expand "extendqihi2"
2662   [(set (match_operand:HI 0 "register_operand" "")
2663         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
2664   ""
2665   "
2666 {
2667   if (optimize && GET_CODE (operands[1]) == MEM)
2668     operands[1] = force_not_mem (operands[1]);
2669
2670   if (GET_CODE (operands[1]) != MEM)
2671     {
2672       rtx op0   = gen_lowpart (SImode, operands[0]);
2673       rtx op1   = gen_lowpart (SImode, operands[1]);
2674       rtx temp  = gen_reg_rtx (SImode);
2675       rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
2676
2677       emit_insn (gen_ashlsi3 (temp, op1, shift));
2678       emit_insn (gen_ashrsi3 (op0, temp, shift));
2679       DONE;
2680     }
2681 }")
2682
2683 (define_insn "extendqihi2_internal"
2684   [(set (match_operand:HI 0 "register_operand" "=d,d")
2685         (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
2686   ""
2687   "* return mips_move_1word (operands, insn, FALSE);"
2688   [(set_attr "type"     "load")
2689    (set_attr "mode"     "SI")
2690    (set_attr "length"   "1,2")])
2691
2692
2693 (define_expand "extendqisi2"
2694   [(set (match_operand:SI 0 "register_operand" "")
2695         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
2696   ""
2697   "
2698 {
2699   if (optimize && GET_CODE (operands[1]) == MEM)
2700     operands[1] = force_not_mem (operands[1]);
2701
2702   if (GET_CODE (operands[1]) != MEM)
2703     {
2704       rtx op1   = gen_lowpart (SImode, operands[1]);
2705       rtx temp  = gen_reg_rtx (SImode);
2706       rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
2707
2708       emit_insn (gen_ashlsi3 (temp, op1, shift));
2709       emit_insn (gen_ashrsi3 (operands[0], temp, shift));
2710       DONE;
2711     }
2712 }")
2713
2714 (define_insn "extendqisi2_insn"
2715   [(set (match_operand:SI 0 "register_operand" "=d,d")
2716         (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
2717   ""
2718   "* return mips_move_1word (operands, insn, FALSE);"
2719   [(set_attr "type"     "load")
2720    (set_attr "mode"     "SI")
2721    (set_attr "length"   "1,2")])
2722
2723 (define_expand "extendqidi2"
2724   [(set (match_operand:DI 0 "register_operand" "")
2725         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
2726   "TARGET_64BIT"
2727   "
2728 {
2729   if (optimize && GET_CODE (operands[1]) == MEM)
2730     operands[1] = force_not_mem (operands[1]);
2731
2732   if (GET_CODE (operands[1]) != MEM)
2733     {
2734       rtx op1   = gen_lowpart (DImode, operands[1]);
2735       rtx temp  = gen_reg_rtx (DImode);
2736       rtx shift = gen_rtx (CONST_INT, VOIDmode, 56);
2737
2738       emit_insn (gen_ashldi3 (temp, op1, shift));
2739       emit_insn (gen_ashrdi3 (operands[0], temp, shift));
2740       DONE;
2741     }
2742 }")
2743
2744 (define_insn "extendqidi2_insn"
2745   [(set (match_operand:DI 0 "register_operand" "=d,d")
2746         (sign_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
2747   "TARGET_64BIT"
2748   "* return mips_move_1word (operands, insn, FALSE);"
2749   [(set_attr "type"     "load")
2750    (set_attr "mode"     "DI")
2751    (set_attr "length"   "1,2")])
2752
2753
2754 (define_insn "extendsfdf2"
2755   [(set (match_operand:DF 0 "register_operand" "=f")
2756         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2757   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2758   "cvt.d.s\\t%0,%1"
2759   [(set_attr "type"     "fcvt")
2760    (set_attr "mode"     "DF")
2761    (set_attr "length"   "1")])
2762
2763 \f
2764
2765 ;;
2766 ;;  ....................
2767 ;;
2768 ;;      CONVERSIONS
2769 ;;
2770 ;;  ....................
2771
2772 ;; The SImode scratch register can not be shared with address regs used for
2773 ;; operand zero, because then the address in the move instruction will be
2774 ;; clobbered.  We mark the scratch register as early clobbered to prevent this.
2775
2776 ;; We need the ?X in alternative 1 so that it will be choosen only if the
2777 ;; destination is a floating point register.  Otherwise, alternative 1 can
2778 ;; have lower cost than alternative 0 (because there is one less loser), and
2779 ;; can be choosen when it won't work (because integral reloads into FP
2780 ;; registers are not supported).
2781
2782 (define_insn "fix_truncdfsi2"
2783   [(set (match_operand:SI 0 "general_operand" "=d,*f,R,o")
2784         (fix:SI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
2785    (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
2786    (clobber (match_scratch:DF 3 "=f,?*X,f,f"))]
2787   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2788   "*
2789 {
2790   rtx xoperands[10];
2791
2792   if (which_alternative == 1)
2793     return \"trunc.w.d %0,%1,%2\";
2794
2795   output_asm_insn (\"trunc.w.d %3,%1,%2\", operands);
2796
2797   xoperands[0] = operands[0];
2798   xoperands[1] = operands[3];
2799   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
2800   return \"\";
2801 }"
2802   [(set_attr "type"     "fcvt")
2803    (set_attr "mode"     "DF")
2804    (set_attr "length"   "11,9,10,11")])
2805
2806
2807 (define_insn "fix_truncsfsi2"
2808   [(set (match_operand:SI 0 "general_operand" "=d,*f,R,o")
2809         (fix:SI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
2810    (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
2811    (clobber (match_scratch:SF 3 "=f,?*X,f,f"))]
2812   "TARGET_HARD_FLOAT"
2813   "*
2814 {
2815   rtx xoperands[10];
2816
2817   if (which_alternative == 1)
2818     return \"trunc.w.s %0,%1,%2\";
2819
2820   output_asm_insn (\"trunc.w.s %3,%1,%2\", operands);
2821
2822   xoperands[0] = operands[0];
2823   xoperands[1] = operands[3];
2824   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
2825   return \"\";
2826 }"
2827   [(set_attr "type"     "fcvt")
2828    (set_attr "mode"     "SF")
2829    (set_attr "length"   "11,9,10,11")])
2830
2831
2832 ;;; ??? trunc.l.d is mentioned in the appendix of the 1993 r4000/r4600 manuals
2833 ;;; but not in the chapter that describes the FPU.  It is not mentioned at all
2834 ;;; in the 1991 manuals.  The r4000 at Cygnus does not have this instruction.
2835
2836 ;;; Deleting this means that we now need two libgcc2.a libraries.  One for
2837 ;;; the 32 bit calling convention and one for the 64 bit calling convention.
2838
2839 ;;; If this is disabled, then fixuns_truncdfdi2 must be disabled also.
2840
2841 (define_insn "fix_truncdfdi2"
2842   [(set (match_operand:DI 0 "general_operand" "=d,*f,R,o")
2843         (fix:DI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
2844    (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
2845   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2846   "*
2847 {
2848   rtx xoperands[10];
2849
2850   if (which_alternative == 1)
2851     return \"trunc.l.d %0,%1\";
2852
2853   output_asm_insn (\"trunc.l.d %2,%1\", operands);
2854
2855   xoperands[0] = operands[0];
2856   xoperands[1] = operands[2];
2857   output_asm_insn (mips_move_2words (xoperands, insn, FALSE), xoperands);
2858   return \"\";
2859 }"
2860   [(set_attr "type"     "fcvt")
2861    (set_attr "mode"     "DF")
2862    (set_attr "length"   "2,1,2,3")])
2863
2864
2865 ;;; ??? trunc.l.s is mentioned in the appendix of the 1993 r4000/r4600 manuals
2866 ;;; but not in the chapter that describes the FPU.  It is not mentioned at all
2867 ;;; in the 1991 manuals.  The r4000 at Cygnus does not have this instruction.
2868 (define_insn "fix_truncsfdi2"
2869   [(set (match_operand:DI 0 "general_operand" "=d,*f,R,o")
2870         (fix:DI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
2871    (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
2872   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2873   "*
2874 {
2875   rtx xoperands[10];
2876
2877   if (which_alternative == 1)
2878     return \"trunc.l.s %0,%1\";
2879
2880   output_asm_insn (\"trunc.l.s %2,%1\", operands);
2881
2882   xoperands[0] = operands[0];
2883   xoperands[1] = operands[2];
2884   output_asm_insn (mips_move_2words (xoperands, insn, FALSE), xoperands);
2885   return \"\";
2886 }"
2887   [(set_attr "type"     "fcvt")
2888    (set_attr "mode"     "SF")
2889    (set_attr "length"   "2,1,2,3")])
2890
2891
2892 (define_insn "floatsidf2"
2893   [(set (match_operand:DF 0 "register_operand" "=f,f,f")
2894         (float:DF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
2895   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2896   "*
2897 {
2898   dslots_load_total++;
2899   if (GET_CODE (operands[1]) == MEM)
2900     return \"l.s\\t%0,%1%#\;cvt.d.w\\t%0,%0\";
2901
2902   return \"mtc1\\t%1,%0%#\;cvt.d.w\\t%0,%0\";
2903 }"
2904   [(set_attr "type"     "fcvt")
2905    (set_attr "mode"     "DF")
2906    (set_attr "length"   "3,4,3")])
2907
2908
2909 (define_insn "floatdidf2"
2910   [(set (match_operand:DF 0 "register_operand" "=f,f,f")
2911         (float:DF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
2912   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2913   "*
2914 {
2915   dslots_load_total++;
2916   if (GET_CODE (operands[1]) == MEM)
2917     return \"l.d\\t%0,%1%#\;cvt.d.l\\t%0,%0\";
2918
2919   return \"dmtc1\\t%1,%0%#\;cvt.d.l\\t%0,%0\";
2920 }"
2921   [(set_attr "type"     "fcvt")
2922    (set_attr "mode"     "DF")
2923    (set_attr "length"   "3,4,3")])
2924
2925
2926 (define_insn "floatsisf2"
2927   [(set (match_operand:SF 0 "register_operand" "=f,f,f")
2928         (float:SF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
2929   "TARGET_HARD_FLOAT"
2930   "*
2931 {
2932   dslots_load_total++;
2933   if (GET_CODE (operands[1]) == MEM)
2934     return \"l.s\\t%0,%1%#\;cvt.s.w\\t%0,%0\";
2935
2936   return \"mtc1\\t%1,%0%#\;cvt.s.w\\t%0,%0\";
2937 }"
2938   [(set_attr "type"     "fcvt")
2939    (set_attr "mode"     "SF")
2940    (set_attr "length"   "3,4,3")])
2941
2942
2943 (define_insn "floatdisf2"
2944   [(set (match_operand:SF 0 "register_operand" "=f,f,f")
2945         (float:SF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
2946   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2947   "*
2948 {
2949   dslots_load_total++;
2950   if (GET_CODE (operands[1]) == MEM)
2951     return \"l.d\\t%0,%1%#\;cvt.s.l\\t%0,%0\";
2952
2953   return \"dmtc1\\t%1,%0%#\;cvt.s.l\\t%0,%0\";
2954 }"
2955   [(set_attr "type"     "fcvt")
2956    (set_attr "mode"     "SF")
2957    (set_attr "length"   "3,4,3")])
2958
2959
2960 (define_expand "fixuns_truncdfsi2"
2961   [(set (match_operand:SI 0 "register_operand" "")
2962         (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
2963   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2964   "
2965 {
2966   rtx reg1 = gen_reg_rtx (DFmode);
2967   rtx reg2 = gen_reg_rtx (DFmode);
2968   rtx reg3 = gen_reg_rtx (SImode);
2969   rtx label1 = gen_label_rtx ();
2970   rtx label2 = gen_label_rtx ();
2971   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
2972
2973   if (reg1)                     /* turn off complaints about unreached code */
2974     {
2975       emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
2976       do_pending_stack_adjust ();
2977
2978       emit_insn (gen_cmpdf (operands[1], reg1));
2979       emit_jump_insn (gen_bge (label1));
2980
2981       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2982       emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
2983                                gen_rtx (LABEL_REF, VOIDmode, label2)));
2984       emit_barrier ();
2985
2986       emit_label (label1);
2987       emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1));
2988       emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
2989
2990       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
2991       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2992
2993       emit_label (label2);
2994
2995       /* allow REG_NOTES to be set on last insn (labels don't have enough
2996          fields, and can't be used for REG_NOTES anyway).  */
2997       emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
2998       DONE;
2999     }
3000 }")
3001
3002
3003 (define_expand "fixuns_truncdfdi2"
3004   [(set (match_operand:DI 0 "register_operand" "")
3005         (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
3006   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3007   "
3008 {
3009   rtx reg1 = gen_reg_rtx (DFmode);
3010   rtx reg2 = gen_reg_rtx (DFmode);
3011   rtx reg3 = gen_reg_rtx (DImode);
3012   rtx label1 = gen_label_rtx ();
3013   rtx label2 = gen_label_rtx ();
3014   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
3015
3016   if (reg1)                     /* turn off complaints about unreached code */
3017     {
3018       emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
3019       do_pending_stack_adjust ();
3020
3021       emit_insn (gen_cmpdf (operands[1], reg1));
3022       emit_jump_insn (gen_bge (label1));
3023
3024       emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3025       emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
3026                                gen_rtx (LABEL_REF, VOIDmode, label2)));
3027       emit_barrier ();
3028
3029       emit_label (label1);
3030       emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1));
3031       emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
3032       emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3033
3034       emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3035       emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3036
3037       emit_label (label2);
3038
3039       /* allow REG_NOTES to be set on last insn (labels don't have enough
3040          fields, and can't be used for REG_NOTES anyway).  */
3041       emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
3042       DONE;
3043     }
3044 }")
3045
3046
3047 (define_expand "fixuns_truncsfsi2"
3048   [(set (match_operand:SI 0 "register_operand" "")
3049         (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
3050   "TARGET_HARD_FLOAT"
3051   "
3052 {
3053   rtx reg1 = gen_reg_rtx (SFmode);
3054   rtx reg2 = gen_reg_rtx (SFmode);
3055   rtx reg3 = gen_reg_rtx (SImode);
3056   rtx label1 = gen_label_rtx ();
3057   rtx label2 = gen_label_rtx ();
3058   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
3059
3060   if (reg1)                     /* turn off complaints about unreached code */
3061     {
3062       emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
3063       do_pending_stack_adjust ();
3064
3065       emit_insn (gen_cmpsf (operands[1], reg1));
3066       emit_jump_insn (gen_bge (label1));
3067
3068       emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3069       emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
3070                                gen_rtx (LABEL_REF, VOIDmode, label2)));
3071       emit_barrier ();
3072
3073       emit_label (label1);
3074       emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1));
3075       emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
3076
3077       emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3078       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3079
3080       emit_label (label2);
3081
3082       /* allow REG_NOTES to be set on last insn (labels don't have enough
3083          fields, and can't be used for REG_NOTES anyway).  */
3084       emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
3085       DONE;
3086     }
3087 }")
3088
3089
3090 (define_expand "fixuns_truncsfdi2"
3091   [(set (match_operand:DI 0 "register_operand" "")
3092         (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
3093   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3094   "
3095 {
3096   rtx reg1 = gen_reg_rtx (SFmode);
3097   rtx reg2 = gen_reg_rtx (SFmode);
3098   rtx reg3 = gen_reg_rtx (DImode);
3099   rtx label1 = gen_label_rtx ();
3100   rtx label2 = gen_label_rtx ();
3101   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
3102
3103   if (reg1)                     /* turn off complaints about unreached code */
3104     {
3105       emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
3106       do_pending_stack_adjust ();
3107
3108       emit_insn (gen_cmpsf (operands[1], reg1));
3109       emit_jump_insn (gen_bge (label1));
3110
3111       emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3112       emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
3113                                gen_rtx (LABEL_REF, VOIDmode, label2)));
3114       emit_barrier ();
3115
3116       emit_label (label1);
3117       emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1));
3118       emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
3119       emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3120
3121       emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3122       emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3123
3124       emit_label (label2);
3125
3126       /* allow REG_NOTES to be set on last insn (labels don't have enough
3127          fields, and can't be used for REG_NOTES anyway).  */
3128       emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
3129       DONE;
3130     }
3131 }")
3132
3133 \f
3134 ;;
3135 ;;  ....................
3136 ;;
3137 ;;      DATA MOVEMENT
3138 ;;
3139 ;;  ....................
3140
3141 ;; Bit field extract patterns which use lwl/lwr.
3142
3143 ;; ??? There should be DImode variants for 64 bit code, but the current
3144 ;; bitfield scheme can't handle that.  We would need to add new optabs
3145 ;; in order to make that work.
3146
3147 ;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
3148 ;; It isn't clear whether this will give better code.
3149
3150 (define_expand "extv"
3151   [(set (match_operand:SI 0 "register_operand" "")
3152         (sign_extract:SI (match_operand:QI 1 "memory_operand" "")
3153                          (match_operand:SI 2 "immediate_operand" "")
3154                          (match_operand:SI 3 "immediate_operand" "")))]
3155   ""
3156   "
3157 {
3158   /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
3159      then fail.  */
3160   if (INTVAL (operands[2]) != 32 || (INTVAL (operands[3]) % 8) != 0)
3161     FAIL;
3162
3163   /* This can happen for a 64 bit target, when extracting a value from
3164      a 64 bit union member.  extract_bit_field doesn't verify that our
3165      source matches the predicate, so we force it to be a MEM here.  */
3166   if (GET_CODE (operands[1]) != MEM)
3167     FAIL;
3168
3169   /* Change the mode to BLKmode for aliasing purposes.  */
3170   operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
3171
3172   /* Otherwise, emit a lwl/lwr pair to load the value.  */
3173   emit_insn (gen_movsi_ulw (operands[0], operands[1]));
3174   DONE;
3175 }")
3176
3177 (define_expand "extzv"
3178   [(set (match_operand:SI 0 "register_operand" "")
3179         (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
3180                          (match_operand:SI 2 "immediate_operand" "")
3181                          (match_operand:SI 3 "immediate_operand" "")))]
3182   ""
3183   "
3184 {
3185   /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
3186      then fail.  */
3187   if (INTVAL (operands[2]) != 32 || (INTVAL (operands[3]) % 8) != 0)
3188     FAIL;
3189
3190   /* This can happen for a 64 bit target, when extracting a value from
3191      a 64 bit union member.  extract_bit_field doesn't verify that our
3192      source matches the predicate, so we force it to be a MEM here.  */
3193   if (GET_CODE (operands[1]) != MEM)
3194     FAIL;
3195
3196   /* Change the mode to BLKmode for aliasing purposes.  */
3197   operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
3198
3199   /* Otherwise, emit a lwl/lwr pair to load the value.  */
3200   emit_insn (gen_movsi_ulw (operands[0], operands[1]));
3201   DONE;
3202 }")
3203
3204 (define_expand "insv"
3205   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
3206                          (match_operand:SI 1 "immediate_operand" "")
3207                          (match_operand:SI 2 "immediate_operand" ""))
3208         (match_operand:SI 3 "register_operand" ""))]
3209   ""
3210   "
3211 {
3212   /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
3213      then fail.  */
3214   if (INTVAL (operands[1]) != 32 || (INTVAL (operands[2]) % 8) != 0)
3215     FAIL;
3216
3217   /* This can happen for a 64 bit target, when storing into a 32 bit union
3218      member.  store_bit_field doesn't verify that our target matches the
3219      predicate, so we force it to be a MEM here.  */
3220   if (GET_CODE (operands[0]) != MEM)
3221     FAIL;
3222
3223   /* Change the mode to BLKmode for aliasing purposes.  */
3224   operands[0] = change_address (operands[0], BLKmode, XEXP (operands[0], 0));
3225
3226   /* Otherwise, emit a swl/swr pair to load the value.  */
3227   emit_insn (gen_movsi_usw (operands[0], operands[3]));
3228   DONE;
3229 }")
3230
3231 ;; unaligned word moves generated by the bit field patterns
3232
3233 (define_insn "movsi_ulw"
3234   [(set (match_operand:SI 0 "register_operand" "=&d,&d")
3235         (unspec:SI [(match_operand:BLK 1 "general_operand" "R,o")] 0))]
3236   ""
3237   "*
3238 {
3239   rtx offset = const0_rtx;
3240   rtx addr = XEXP (operands[1], 0);
3241   rtx mem_addr = eliminate_constant_term (addr, &offset);
3242   char *ret;
3243
3244   if (TARGET_STATS)
3245     mips_count_memory_refs (operands[1], 2);
3246
3247   /* The stack/frame pointers are always aligned, so we can convert
3248      to the faster lw if we are referencing an aligned stack location.  */
3249
3250   if ((INTVAL (offset) & 3) == 0
3251       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
3252     ret = \"lw\\t%0,%1\";
3253   else
3254     ret = \"ulw\\t%0,%1\";
3255
3256   return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
3257 }"
3258   [(set_attr "type"     "load,load")
3259    (set_attr "mode"     "SI")
3260    (set_attr "length"   "2,4")])
3261
3262 (define_insn "movsi_usw"
3263   [(set (match_operand:BLK 0 "memory_operand" "=R,o")
3264         (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")] 1))]
3265   ""
3266   "*
3267 {
3268   rtx offset = const0_rtx;
3269   rtx addr = XEXP (operands[0], 0);
3270   rtx mem_addr = eliminate_constant_term (addr, &offset);
3271
3272   if (TARGET_STATS)
3273     mips_count_memory_refs (operands[0], 2);
3274
3275   /* The stack/frame pointers are always aligned, so we can convert
3276      to the faster sw if we are referencing an aligned stack location.  */
3277
3278   if ((INTVAL (offset) & 3) == 0
3279       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
3280     return \"sw\\t%1,%0\";
3281
3282   return \"usw\\t%z1,%0\";
3283 }"
3284   [(set_attr "type"     "store")
3285    (set_attr "mode"     "SI")
3286    (set_attr "length"   "2,4")])
3287
3288 ;; These two patterns support loading addresses with two instructions instead
3289 ;; of using the macro instruction la.
3290
3291 ;; ??? mips_move_1word has support for HIGH, so this pattern may be
3292 ;; unnecessary.
3293
3294 (define_insn "high"
3295   [(set (match_operand:SI 0 "register_operand" "=r")
3296         (high:SI (match_operand:SI 1 "immediate_operand" "")))]
3297   "mips_split_addresses"
3298   "lui\\t%0,%%hi(%1) # high"
3299   [(set_attr "type"     "move")
3300    (set_attr "length"   "1")])
3301
3302 (define_insn "low"
3303   [(set (match_operand:SI 0 "register_operand" "=r")
3304         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
3305                    (match_operand:SI 2 "immediate_operand" "")))]
3306   "mips_split_addresses"
3307   "addiu\\t%0,%1,%%lo(%2) # low"
3308   [(set_attr "type"     "arith")
3309    (set_attr "mode"     "SI")
3310    (set_attr "length"   "1")])
3311
3312 ;; 64-bit integer moves
3313
3314 ;; Unlike most other insns, the move insns can't be split with
3315 ;; different predicates, because register spilling and other parts of
3316 ;; the compiler, have memoized the insn number already.
3317
3318 (define_expand "movdi"
3319   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3320         (match_operand:DI 1 "general_operand" ""))]
3321   ""
3322   "
3323 {
3324   if (mips_split_addresses && mips_check_split (operands[1], DImode))
3325     {
3326       enum machine_mode mode = GET_MODE (operands[0]);
3327       rtx tem = ((reload_in_progress | reload_completed)
3328                  ? operands[0] : gen_reg_rtx (mode));
3329
3330       emit_insn (gen_rtx (SET, VOIDmode, tem,
3331                           gen_rtx (HIGH, mode, operands[1])));
3332
3333       operands[1] = gen_rtx (LO_SUM, mode, tem, operands[1]);
3334     }
3335
3336   /* If we are generating embedded PIC code, and we are referring to a
3337      symbol in the .text section, we must use an offset from the start
3338      of the function.  */
3339   if (TARGET_EMBEDDED_PIC
3340       && (GET_CODE (operands[1]) == LABEL_REF
3341           || (GET_CODE (operands[1]) == SYMBOL_REF
3342               && ! SYMBOL_REF_FLAG (operands[1]))))
3343     {
3344       rtx temp;
3345
3346       temp = embedded_pic_offset (operands[1]);
3347       temp = gen_rtx (PLUS, Pmode, embedded_pic_fnaddr_rtx,
3348                       force_reg (DImode, temp));
3349       emit_move_insn (operands[0], force_reg (DImode, temp));
3350       DONE;
3351     }
3352
3353   /* If operands[1] is a constant address illegal for pic, then we need to
3354      handle it just like LEGITIMIZE_ADDRESS does.  */
3355   if (flag_pic && pic_address_needs_scratch (operands[1]))
3356     {
3357       rtx temp = force_reg (DImode, XEXP (XEXP (operands[1], 0), 0));
3358       rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
3359
3360       if (! SMALL_INT (temp2))
3361         temp2 = force_reg (DImode, temp2);
3362
3363       emit_move_insn (operands[0], gen_rtx (PLUS, DImode, temp, temp2));
3364       DONE;
3365     }
3366
3367   if ((reload_in_progress | reload_completed) == 0
3368       && !register_operand (operands[0], DImode)
3369       && !register_operand (operands[1], DImode)
3370       && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
3371       && operands[1] != CONST0_RTX (DImode))
3372     {
3373       rtx temp = force_reg (DImode, operands[1]);
3374       emit_move_insn (operands[0], temp);
3375       DONE;
3376     }
3377 }")
3378
3379 (define_insn "movdi_internal"
3380   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*x,*d,*x")
3381         (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,J,*x,*d"))]
3382   "!TARGET_64BIT
3383    && (register_operand (operands[0], DImode)
3384        || register_operand (operands[1], DImode)
3385        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
3386        || operands[1] == CONST0_RTX (DImode))"
3387   "* return mips_move_2words (operands, insn); "
3388   [(set_attr "type"     "move,arith,load,load,store,store,hilo,hilo,hilo")
3389    (set_attr "mode"     "DI")
3390    (set_attr "length"   "2,4,2,4,2,4,2,2,2")])
3391
3392 (define_split
3393   [(set (match_operand:DI 0 "register_operand" "")
3394         (match_operand:DI 1 "register_operand" ""))]
3395   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3396    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3397    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
3398
3399   [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
3400    (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
3401   "")
3402
3403 (define_insn "movdi_internal2"
3404   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*x,*d,*x,*a")
3405         (match_operand:DI 1 "movdi_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,J,*x,*d,*J"))]
3406   "TARGET_64BIT
3407    && (register_operand (operands[0], DImode)
3408        || se_register_operand (operands[1], DImode)
3409        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
3410        || operands[1] == CONST0_RTX (DImode))"
3411   "* return mips_move_2words (operands, insn); "
3412   [(set_attr "type"     "move,load,arith,arith,load,load,store,store,hilo,hilo,hilo,hilo")
3413    (set_attr "mode"     "DI")
3414    (set_attr "length"   "1,2,1,2,1,2,1,2,1,1,1,2")])
3415
3416 ;; Handle input reloads in DImode.
3417 ;; This is mainly to handle reloading HILO_REGNUM.  Note that we may
3418 ;; see it as the source or the destination, depending upon which way
3419 ;; reload handles the instruction.
3420 ;; Making the second operand TImode is a trick.  The compiler may
3421 ;; reuse the same register for operand 0 and operand 2.  Using TImode
3422 ;; gives us two registers, so we can always use the one which is not
3423 ;; used.
3424
3425 (define_expand "reload_indi"
3426   [(set (match_operand:DI 0 "register_operand" "=b")
3427         (match_operand:DI 1 "movdi_operand" "b"))
3428    (clobber (match_operand:TI 2 "register_operand" "=&d"))]
3429   "TARGET_64BIT"
3430   "
3431 {
3432   rtx scratch = gen_rtx (REG, DImode,
3433                          (REGNO (operands[0]) == REGNO (operands[2]) 
3434                           ? REGNO (operands[2]) + 1
3435                           : REGNO (operands[2])));
3436
3437   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
3438     {
3439       if (GET_CODE (operands[1]) == MEM)
3440         {
3441           rtx memword, offword, hiword, loword;
3442
3443           scratch = gen_rtx (REG, SImode, REGNO (scratch));
3444           memword = change_address (operands[1], SImode, NULL_RTX);
3445           offword = change_address (adj_offsettable_operand (operands[1], 4),
3446                                     SImode, NULL_RTX);
3447           if (BYTES_BIG_ENDIAN)
3448             {
3449               hiword = memword;
3450               loword = offword;
3451             }
3452           else
3453             {
3454               hiword = offword;
3455               loword = memword;
3456             }
3457           emit_move_insn (scratch, hiword);
3458           emit_move_insn (gen_rtx (REG, SImode, 64), scratch);
3459           emit_move_insn (scratch, loword);
3460           emit_move_insn (gen_rtx (REG, SImode, 65), scratch);
3461         }
3462       else
3463         {
3464           emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
3465           emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
3466           emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
3467           emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
3468           emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
3469         }
3470       DONE;
3471     }
3472   if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
3473     {
3474       emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
3475       emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
3476       emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
3477       emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
3478       emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
3479       emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
3480       DONE;
3481     }
3482   /* This handles moves between a float register and HI/LO.  */
3483   emit_move_insn (scratch, operands[1]);
3484   emit_move_insn (operands[0], scratch);
3485   DONE;
3486 }")
3487
3488 ;; Handle output reloads in DImode.
3489
3490 (define_expand "reload_outdi"
3491   [(set (match_operand:DI 0 "general_operand" "=b")
3492         (match_operand:DI 1 "se_register_operand" "b"))
3493    (clobber (match_operand:DI 2 "register_operand" "=&d"))]
3494   "TARGET_64BIT"
3495   "
3496 {
3497   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
3498     {
3499       emit_insn (gen_ashrdi3 (operands[2], operands[1], GEN_INT (32)));
3500       emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), operands[2]));
3501       emit_insn (gen_ashldi3 (operands[2], operands[1], GEN_INT (32)));
3502       emit_insn (gen_ashrdi3 (operands[2], operands[2], GEN_INT (32)));
3503       emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), operands[2]));
3504       DONE;
3505     }
3506   if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
3507     {
3508       if (GET_CODE (operands[0]) == MEM)
3509         {
3510           rtx scratch, memword, offword, hiword, loword;
3511
3512           scratch = gen_rtx (REG, SImode, REGNO (operands[2]));
3513           memword = change_address (operands[0], SImode, NULL_RTX);
3514           offword = change_address (adj_offsettable_operand (operands[0], 4),
3515                                     SImode, NULL_RTX);
3516           if (BYTES_BIG_ENDIAN)
3517             {
3518               hiword = memword;
3519               loword = offword;
3520             }
3521           else
3522             {
3523               hiword = offword;
3524               loword = memword;
3525             }
3526           emit_move_insn (scratch, gen_rtx (REG, SImode, 64));
3527           emit_move_insn (hiword, scratch);
3528           emit_move_insn (scratch, gen_rtx (REG, SImode, 65));
3529           emit_move_insn (loword, scratch);
3530         }
3531       else
3532         {
3533           emit_insn (gen_movdi (operands[2], gen_rtx (REG, DImode, 65)));
3534           emit_insn (gen_ashldi3 (operands[2], operands[2], GEN_INT (32)));
3535           emit_insn (gen_lshrdi3 (operands[2], operands[2], GEN_INT (32)));
3536           emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
3537           emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
3538           emit_insn (gen_iordi3 (operands[0], operands[0], operands[2]));
3539         }
3540       DONE;
3541     }
3542   /* This handles moves between a float register and HI/LO.  */
3543   emit_move_insn (operands[2], operands[1]);
3544   emit_move_insn (operands[0], operands[2]);
3545   DONE;
3546 }")
3547
3548 ;; 32-bit Integer moves
3549
3550 (define_split
3551   [(set (match_operand:SI 0 "register_operand" "")
3552         (match_operand:SI 1 "large_int" ""))]
3553   "!TARGET_DEBUG_D_MODE"
3554   [(set (match_dup 0)
3555         (match_dup 2))
3556    (set (match_dup 0)
3557         (ior:SI (match_dup 0)
3558                 (match_dup 3)))]
3559   "
3560 {
3561   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff0000);
3562   operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0x0000ffff);
3563 }")
3564
3565 ;; Unlike most other insns, the move insns can't be split with
3566 ;; different predicates, because register spilling and other parts of
3567 ;; the compiler, have memoized the insn number already.
3568
3569 (define_expand "movsi"
3570   [(set (match_operand:SI 0 "nonimmediate_operand" "")
3571         (match_operand:SI 1 "general_operand" ""))]
3572   ""
3573   "
3574 {
3575   if (mips_split_addresses && mips_check_split (operands[1], SImode))
3576     {
3577       enum machine_mode mode = GET_MODE (operands[0]);
3578       rtx tem = ((reload_in_progress | reload_completed)
3579                  ? operands[0] : gen_reg_rtx (mode));
3580
3581       emit_insn (gen_rtx (SET, VOIDmode, tem,
3582                           gen_rtx (HIGH, mode, operands[1])));
3583
3584       operands[1] = gen_rtx (LO_SUM, mode, tem, operands[1]);
3585     }
3586
3587   /* If we are generating embedded PIC code, and we are referring to a
3588      symbol in the .text section, we must use an offset from the start
3589      of the function.  */
3590   if (TARGET_EMBEDDED_PIC
3591       && (GET_CODE (operands[1]) == LABEL_REF
3592           || (GET_CODE (operands[1]) == SYMBOL_REF
3593               && ! SYMBOL_REF_FLAG (operands[1]))))
3594     {
3595       rtx temp;
3596
3597       temp = embedded_pic_offset (operands[1]);
3598       temp = gen_rtx (PLUS, Pmode, embedded_pic_fnaddr_rtx,
3599                       force_reg (SImode, temp));
3600       emit_move_insn (operands[0], force_reg (SImode, temp));
3601       DONE;
3602     }
3603
3604   /* If operands[1] is a constant address invalid for pic, then we need to
3605      handle it just like LEGITIMIZE_ADDRESS does.  */
3606   if (flag_pic && pic_address_needs_scratch (operands[1]))
3607     {
3608       rtx temp = force_reg (SImode, XEXP (XEXP (operands[1], 0), 0));
3609       rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
3610
3611       if (! SMALL_INT (temp2))
3612         temp2 = force_reg (SImode, temp2);
3613
3614       emit_move_insn (operands[0], gen_rtx (PLUS, SImode, temp, temp2));
3615       DONE;
3616     }
3617
3618   if ((reload_in_progress | reload_completed) == 0
3619       && !register_operand (operands[0], SImode)
3620       && !register_operand (operands[1], SImode)
3621       && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))
3622     {
3623       rtx temp = force_reg (SImode, operands[1]);
3624       emit_move_insn (operands[0], temp);
3625       DONE;
3626     }
3627 }")
3628
3629 ;; The difference between these two is whether or not ints are allowed
3630 ;; in FP registers (off by default, use -mdebugh to enable).
3631
3632 (define_insn "movsi_internal1"
3633   [(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")
3634         (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"))]
3635   "TARGET_DEBUG_H_MODE
3636    && (register_operand (operands[0], SImode)
3637        || register_operand (operands[1], SImode)
3638        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3639   "* return mips_move_1word (operands, insn, FALSE);"
3640   [(set_attr "type"     "move,load,arith,arith,load,load,store,store,xfer,xfer,move,load,load,store,store,hilo,hilo,hilo,hilo")
3641    (set_attr "mode"     "SI")
3642    (set_attr "length"   "1,2,1,2,1,2,1,2,1,1,1,1,2,1,2,1,1,1,1")])
3643
3644 (define_insn "movsi_internal2"
3645   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*z,*x,*d,*x,*d")
3646         (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,J,*x,*d,*a"))]
3647   "!TARGET_DEBUG_H_MODE
3648    && (register_operand (operands[0], SImode)
3649        || register_operand (operands[1], SImode)
3650        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3651   "* return mips_move_1word (operands, insn, FALSE);"
3652   [(set_attr "type"     "move,load,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo,hilo,hilo")
3653    (set_attr "mode"     "SI")
3654    (set_attr "length"   "1,2,1,2,1,2,1,2,1,1,1,1,1,1")])
3655
3656 ;; Reload HILO_REGNUM in SI mode.  This needs a scratch register in
3657 ;; order to set the sign bit correctly in the HI register.
3658
3659 (define_expand "reload_outsi"
3660   [(set (match_operand:SI 0 "general_operand" "=b")
3661         (match_operand:SI 1 "register_operand" "d"))
3662    (clobber (match_operand:SI 2 "register_operand" "=&d"))]
3663   "TARGET_64BIT"
3664   "
3665 {
3666   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
3667     {
3668       emit_insn (gen_movsi (gen_rtx (REG, SImode, 65), operands[1]));
3669       emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31)));
3670       emit_insn (gen_movsi (gen_rtx (REG, SImode, 64), operands[2]));
3671       DONE;
3672     }
3673   /* This handles moves between a float register and HI/LO.  */
3674   emit_move_insn (operands[2], operands[1]);
3675   emit_move_insn (operands[0], operands[2]);
3676   DONE;
3677 }")
3678
3679 ;; This insn handles moving CCmode values.  It's really just a
3680 ;; slightly simplified copy of movsi_internal2, with additional cases
3681 ;; to move a condition register to a general register and to move
3682 ;; between the general registers and the floating point registers.
3683
3684 (define_insn "movcc"
3685   [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*d,*R,*m,*d,*f,*f,*f,*f,*R,*m")
3686         (match_operand:CC 1 "general_operand" "z,*d,*R,*m,*d,*d,*f,*d,*f,*R,*m,*f,*f"))]
3687   "mips_isa >= 4 && TARGET_HARD_FLOAT"
3688   "* return mips_move_1word (operands, insn, FALSE);"
3689   [(set_attr "type"     "move,move,load,load,store,store,xfer,xfer,move,load,load,store,store")
3690    (set_attr "mode"     "SI")
3691    (set_attr "length"   "2,1,1,2,1,2,1,1,1,1,2,1,2")])
3692
3693 ;; Reload condition code registers.  These need scratch registers.
3694
3695 (define_expand "reload_incc"
3696   [(set (match_operand:CC 0 "register_operand" "=z")
3697         (match_operand:CC 1 "general_operand" "z"))
3698    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3699   "mips_isa >= 4 && TARGET_HARD_FLOAT"
3700   "
3701 {
3702   rtx source;
3703   rtx fp1, fp2;
3704
3705   /* This is called when are copying some value into a condition code
3706      register.  Operand 0 is the condition code register.  Operand 1
3707      is the source.  Operand 2 is a scratch register; we use TFmode
3708      because we actually need two floating point registers.  */
3709   if (! ST_REG_P (true_regnum (operands[0]))
3710       || ! FP_REG_P (true_regnum (operands[2])))
3711     abort ();
3712
3713   /* We need to get the source in SFmode so that the insn is
3714      recognized.  */
3715   if (GET_CODE (operands[1]) == MEM)
3716     source = change_address (operands[1], SFmode, NULL_RTX);
3717   else if (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG)
3718     source = gen_rtx (REG, SFmode, true_regnum (operands[1]));
3719   else
3720     source = operands[1];
3721
3722   fp1 = gen_rtx (REG, SFmode, REGNO (operands[2]));
3723   fp2 = gen_rtx (REG, SFmode, REGNO (operands[2]) + 1);
3724
3725   emit_insn (gen_move_insn (fp1, source));
3726   emit_insn (gen_move_insn (fp2, gen_rtx (REG, SFmode, 0)));
3727   emit_insn (gen_rtx (SET, VOIDmode, operands[0],
3728                       gen_rtx (LT, CCmode, fp2, fp1)));
3729
3730   DONE;
3731 }")
3732
3733 (define_expand "reload_outcc"
3734   [(set (match_operand:CC 0 "general_operand" "=z")
3735         (match_operand:CC 1 "register_operand" "z"))
3736    (clobber (match_operand:CC 2 "register_operand" "=&d"))]
3737   "mips_isa >= 4 && TARGET_HARD_FLOAT"
3738   "
3739 {
3740   /* This is called when we are copying a condition code register out
3741      to save it somewhere.  Operand 0 should be the location we are
3742      going to save it to.  Operand 1 should be the condition code
3743      register.  Operand 2 should be a scratch general purpose register
3744      created for us by reload.  The mips_secondary_reload_class
3745      function should have told reload that we don't need a scratch
3746      register if the destination is a general purpose register anyhow.  */
3747   if (ST_REG_P (true_regnum (operands[0]))
3748       || GP_REG_P (true_regnum (operands[0]))
3749       || ! ST_REG_P (true_regnum (operands[1]))
3750       || ! GP_REG_P (true_regnum (operands[2])))
3751     abort ();
3752
3753   /* All we have to do is copy the value from the condition code to
3754      the data register, which movcc can handle, and then store the
3755      value into the real final destination.  */
3756   emit_insn (gen_move_insn (operands[2], operands[1]));
3757   emit_insn (gen_move_insn (operands[0], operands[2]));
3758
3759   DONE;
3760 }")
3761
3762 ;; MIPS4 supports loading and storing a floating point register from
3763 ;; the sum of two general registers.  We use two versions for each of
3764 ;; these four instructions: one where the two general registers are
3765 ;; SImode, and one where they are DImode.  This is because general
3766 ;; registers will be in SImode when they hold 32 bit values, but,
3767 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
3768 ;; instructions will still work correctly.
3769
3770 ;; ??? Perhaps it would be better to support these instructions by
3771 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends.  However, since
3772 ;; these instructions can only be used to load and store floating
3773 ;; point registers, that would probably cause trouble in reload.
3774
3775 (define_insn ""
3776   [(set (match_operand:SF 0 "register_operand" "=f")
3777         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
3778                          (match_operand:SI 2 "register_operand" "d"))))]
3779   "mips_isa >= 4 && TARGET_HARD_FLOAT"
3780   "lwxc1\\t%0,%1(%2)"
3781   [(set_attr "type"     "load")
3782    (set_attr "mode"     "SF")
3783    (set_attr "length"   "1")])
3784
3785 (define_insn ""
3786   [(set (match_operand:SF 0 "register_operand" "=f")
3787         (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
3788                          (match_operand:DI 2 "se_register_operand" "d"))))]
3789   "mips_isa >= 4 && TARGET_HARD_FLOAT"
3790   "lwxc1\\t%0,%1(%2)"
3791   [(set_attr "type"     "load")
3792    (set_attr "mode"     "SF")
3793    (set_attr "length"   "1")])
3794
3795 (define_insn ""
3796   [(set (match_operand:DF 0 "register_operand" "=f")
3797         (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
3798                          (match_operand:SI 2 "register_operand" "d"))))]
3799   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3800   "ldxc1\\t%0,%1(%2)"
3801   [(set_attr "type"     "load")
3802    (set_attr "mode"     "DF")
3803    (set_attr "length"   "1")])
3804
3805 (define_insn ""
3806   [(set (match_operand:DF 0 "register_operand" "=f")
3807         (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
3808                          (match_operand:DI 2 "se_register_operand" "d"))))]
3809   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3810   "ldxc1\\t%0,%1(%2)"
3811   [(set_attr "type"     "load")
3812    (set_attr "mode"     "DF")
3813    (set_attr "length"   "1")])
3814
3815 (define_insn ""
3816   [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
3817                          (match_operand:SI 2 "register_operand" "d")))
3818         (match_operand:SF 0 "register_operand" "=f"))]
3819   "mips_isa >= 4 && TARGET_HARD_FLOAT"
3820   "swxc1\\t%0,%1(%2)"
3821   [(set_attr "type"     "store")
3822    (set_attr "mode"     "SF")
3823    (set_attr "length"   "1")])
3824
3825 (define_insn ""
3826   [(set (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
3827                          (match_operand:DI 2 "se_register_operand" "d")))
3828         (match_operand:SF 0 "register_operand" "=f"))]
3829   "mips_isa >= 4 && TARGET_HARD_FLOAT"
3830   "swxc1\\t%0,%1(%2)"
3831   [(set_attr "type"     "store")
3832    (set_attr "mode"     "SF")
3833    (set_attr "length"   "1")])
3834
3835 (define_insn ""
3836   [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
3837                          (match_operand:SI 2 "register_operand" "d")))
3838         (match_operand:DF 0 "register_operand" "=f"))]
3839   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3840   "sdxc1\\t%0,%1(%2)"
3841   [(set_attr "type"     "store")
3842    (set_attr "mode"     "DF")
3843    (set_attr "length"   "1")])
3844
3845 (define_insn ""
3846   [(set (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
3847                          (match_operand:DI 2 "se_register_operand" "d")))
3848         (match_operand:DF 0 "register_operand" "=f"))]
3849   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3850   "sdxc1\\t%0,%1(%2)"
3851   [(set_attr "type"     "store")
3852    (set_attr "mode"     "DF")
3853    (set_attr "length"   "1")])
3854
3855 ;; 16-bit Integer moves
3856
3857 ;; Unlike most other insns, the move insns can't be split with
3858 ;; different predicates, because register spilling and other parts of
3859 ;; the compiler, have memoized the insn number already.
3860 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
3861
3862 (define_expand "movhi"
3863   [(set (match_operand:HI 0 "nonimmediate_operand" "")
3864         (match_operand:HI 1 "general_operand" ""))]
3865   ""
3866   "
3867 {
3868   if ((reload_in_progress | reload_completed) == 0
3869       && !register_operand (operands[0], HImode)
3870       && !register_operand (operands[1], HImode)
3871       && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))
3872     {
3873       rtx temp = force_reg (HImode, operands[1]);
3874       emit_move_insn (operands[0], temp);
3875       DONE;
3876     }
3877 }")
3878
3879 ;; The difference between these two is whether or not ints are allowed
3880 ;; in FP registers (off by default, use -mdebugh to enable).
3881
3882 (define_insn "movhi_internal1"
3883   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f*z,*x,*d")
3884         (match_operand:HI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
3885   "TARGET_DEBUG_H_MODE
3886    && (register_operand (operands[0], HImode)
3887        || register_operand (operands[1], HImode)
3888        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3889   "* return mips_move_1word (operands, insn, TRUE);"
3890   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
3891    (set_attr "mode"     "HI")
3892    (set_attr "length"   "1,1,1,2,1,2,1,1,1,1,1")])
3893
3894 (define_insn "movhi_internal2"
3895   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
3896         (match_operand:HI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
3897   "!TARGET_DEBUG_H_MODE
3898    && (register_operand (operands[0], HImode)
3899        || register_operand (operands[1], HImode)
3900        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3901   "* return mips_move_1word (operands, insn, TRUE);"
3902   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
3903    (set_attr "mode"     "HI")
3904    (set_attr "length"   "1,1,1,2,1,2,1,1,1,1")])
3905
3906
3907 ;; 8-bit Integer moves
3908
3909 ;; Unlike most other insns, the move insns can't be split with
3910 ;; different predicates, because register spilling and other parts of
3911 ;; the compiler, have memoized the insn number already.
3912 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
3913
3914 (define_expand "movqi"
3915   [(set (match_operand:QI 0 "nonimmediate_operand" "")
3916         (match_operand:QI 1 "general_operand" ""))]
3917   ""
3918   "
3919 {
3920   if ((reload_in_progress | reload_completed) == 0
3921       && !register_operand (operands[0], QImode)
3922       && !register_operand (operands[1], QImode)
3923       && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))
3924     {
3925       rtx temp = force_reg (QImode, operands[1]);
3926       emit_move_insn (operands[0], temp);
3927       DONE;
3928     }
3929 }")
3930
3931 ;; The difference between these two is whether or not ints are allowed
3932 ;; in FP registers (off by default, use -mdebugh to enable).
3933
3934 (define_insn "movqi_internal1"
3935   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
3936         (match_operand:QI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
3937   "TARGET_DEBUG_H_MODE
3938    && (register_operand (operands[0], QImode)
3939        || register_operand (operands[1], QImode)
3940        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3941   "* return mips_move_1word (operands, insn, TRUE);"
3942   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
3943    (set_attr "mode"     "QI")
3944    (set_attr "length"   "1,1,1,2,1,2,1,1,1,1,1")])
3945
3946 (define_insn "movqi_internal2"
3947   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
3948         (match_operand:QI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
3949   "!TARGET_DEBUG_H_MODE
3950    && (register_operand (operands[0], QImode)
3951        || register_operand (operands[1], QImode)
3952        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3953   "* return mips_move_1word (operands, insn, TRUE);"
3954   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
3955    (set_attr "mode"     "QI")
3956    (set_attr "length"   "1,1,1,2,1,2,1,1,1,1")])
3957
3958
3959 ;; 32-bit floating point moves
3960
3961 (define_expand "movsf"
3962   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3963         (match_operand:SF 1 "general_operand" ""))]
3964   ""
3965   "
3966 {
3967   if ((reload_in_progress | reload_completed) == 0
3968       && !register_operand (operands[0], SFmode)
3969       && !register_operand (operands[1], SFmode)
3970       && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
3971       && operands[1] != CONST0_RTX (SFmode))
3972     {
3973       rtx temp = force_reg (SFmode, operands[1]);
3974       emit_move_insn (operands[0], temp);
3975       DONE;
3976     }
3977 }")
3978
3979 (define_insn "movsf_internal1"
3980   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m")
3981         (match_operand:SF 1 "general_operand" "f,G,R,Fm,fG,fG,*d,*f,*G*d,*R,*F*m,*d,*d"))]
3982   "TARGET_HARD_FLOAT
3983    && (register_operand (operands[0], SFmode)
3984        || register_operand (operands[1], SFmode)
3985        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
3986        || operands[1] == CONST0_RTX (SFmode))"
3987   "* return mips_move_1word (operands, insn, FALSE);"
3988   [(set_attr "type"     "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store")
3989    (set_attr "mode"     "SF")
3990    (set_attr "length"   "1,1,1,2,1,2,1,1,1,1,2,1,2")])
3991
3992
3993 (define_insn "movsf_internal2"
3994   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,R,m")
3995         (match_operand:SF 1 "general_operand" "      Gd,R,Fm,d,d"))]
3996   "TARGET_SOFT_FLOAT
3997    && (register_operand (operands[0], SFmode)
3998        || register_operand (operands[1], SFmode)
3999        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
4000        || operands[1] == CONST0_RTX (SFmode))"
4001   "* return mips_move_1word (operands, insn, FALSE);"
4002   [(set_attr "type"     "move,load,load,store,store")
4003    (set_attr "mode"     "SF")
4004    (set_attr "length"   "1,1,2,1,2")])
4005
4006
4007 ;; 64-bit floating point moves
4008
4009 (define_expand "movdf"
4010   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4011         (match_operand:DF 1 "general_operand" ""))]
4012   ""
4013   "
4014 {
4015   if ((reload_in_progress | reload_completed) == 0
4016       && !register_operand (operands[0], DFmode)
4017       && !register_operand (operands[1], DFmode)
4018       && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
4019       && operands[1] != CONST0_RTX (DFmode))
4020     {
4021       rtx temp = force_reg (DFmode, operands[1]);
4022       emit_move_insn (operands[0], temp);
4023       DONE;
4024     }
4025 }")
4026
4027 (define_insn "movdf_internal1"
4028   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,o,f,*f,*d,*d,*d,*d,*R,*o")
4029         (match_operand:DF 1 "general_operand" "f,R,o,fG,fG,F,*d,*f,*d*G,*R,*o*F,*d,*d"))]
4030   "TARGET_HARD_FLOAT && !(TARGET_FLOAT64 && !TARGET_64BIT)
4031    && TARGET_DOUBLE_FLOAT
4032    && (register_operand (operands[0], DFmode)
4033        || register_operand (operands[1], DFmode)
4034        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
4035        || operands[1] == CONST0_RTX (DFmode))"
4036   "* return mips_move_2words (operands, insn); "
4037   [(set_attr "type"     "move,load,load,store,store,load,xfer,xfer,move,load,load,store,store")
4038    (set_attr "mode"     "DF")
4039    (set_attr "length"   "1,2,4,2,4,4,2,2,2,2,4,2,4")])
4040
4041 (define_insn "movdf_internal1a"
4042   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,R,R,o,o,f,*d,*d,*d,*o,*R")
4043         (match_operand:DF 1 "general_operand"      " f,o,f,G,f,G,F,*F,*o,*R,*d,*d"))]
4044   "TARGET_HARD_FLOAT && (TARGET_FLOAT64 && !TARGET_64BIT)
4045    && TARGET_DOUBLE_FLOAT
4046    && (register_operand (operands[0], DFmode)
4047        || register_operand (operands[1], DFmode))
4048        || (GET_CODE (operands [0]) == MEM
4049            && ((GET_CODE (operands[1]) == CONST_INT
4050                 && INTVAL (operands[1]) == 0)
4051                || operands[1] == CONST0_RTX (DFmode)))"
4052   "* return mips_move_2words (operands, insn); "
4053   [(set_attr "type"     "move,load,store,store,store,store,load,load,load,load,store,store")
4054    (set_attr "mode"     "DF")
4055    (set_attr "length"   "1,2,1,1,2,2,2,2,2,1,2,1")])
4056
4057 (define_insn "movdf_internal2"
4058   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,R,o")
4059         (match_operand:DF 1 "general_operand" "dG,R,oF,d,d"))]
4060   "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT)
4061    && (register_operand (operands[0], DFmode)
4062        || register_operand (operands[1], DFmode)
4063        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
4064        || operands[1] == CONST0_RTX (DFmode))"
4065   "* return mips_move_2words (operands, insn); "
4066   [(set_attr "type"     "move,load,load,store,store")
4067    (set_attr "mode"     "DF")
4068    (set_attr "length"   "2,2,4,2,4")])
4069
4070 (define_split
4071   [(set (match_operand:DF 0 "register_operand" "")
4072         (match_operand:DF 1 "register_operand" ""))]
4073   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4074    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
4075    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
4076   [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
4077    (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
4078   "")
4079
4080 ;; Instructions to load the global pointer register.
4081 ;; This is volatile to make sure that the scheduler won't move any symbol_ref
4082 ;; uses in front of it.  All symbol_refs implicitly use the gp reg.
4083
4084 (define_insn "loadgp"
4085   [(set (reg:DI 28)
4086         (unspec_volatile:DI [(match_operand:DI 0 "address_operand" "")] 2))
4087    (clobber (reg:DI 1))]
4088   ""
4089   "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%a0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%a0)))\\n\\tdaddu\\t$gp,$1,$25%]"
4090   [(set_attr "type"     "move")
4091    (set_attr "mode"     "DI")
4092    (set_attr "length"   "3")])
4093 \f
4094 ;; Block moves, see mips.c for more details.
4095 ;; Argument 0 is the destination
4096 ;; Argument 1 is the source
4097 ;; Argument 2 is the length
4098 ;; Argument 3 is the alignment
4099
4100 (define_expand "movstrsi"
4101   [(parallel [(set (match_operand:BLK 0 "general_operand" "")
4102                    (match_operand:BLK 1 "general_operand" ""))
4103               (use (match_operand:SI 2 "arith32_operand" ""))
4104               (use (match_operand:SI 3 "immediate_operand" ""))])]
4105   ""
4106   "
4107 {
4108   if (operands[0])              /* avoid unused code messages */
4109     {
4110       expand_block_move (operands);
4111       DONE;
4112     }
4113 }")
4114
4115 ;; Insn generated by block moves
4116
4117 (define_insn "movstrsi_internal"
4118   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
4119         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
4120    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
4121    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
4122    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
4123    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
4124    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
4125    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
4126    (use (const_int 0))]                                 ;; normal block move
4127   ""
4128   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
4129   [(set_attr "type"     "store")
4130    (set_attr "mode"     "none")
4131    (set_attr "length"   "20")])
4132
4133 ;; Split a block move into 2 parts, the first part is everything
4134 ;; except for the last move, and the second part is just the last
4135 ;; store, which is exactly 1 instruction (ie, not a usw), so it can
4136 ;; fill a delay slot.  This also prevents a bug in delayed branches
4137 ;; from showing up, which reuses one of the registers in our clobbers.
4138
4139 (define_split
4140   [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
4141         (mem:BLK (match_operand:SI 1 "register_operand" "")))
4142    (clobber (match_operand:SI 4 "register_operand" ""))
4143    (clobber (match_operand:SI 5 "register_operand" ""))
4144    (clobber (match_operand:SI 6 "register_operand" ""))
4145    (clobber (match_operand:SI 7 "register_operand" ""))
4146    (use (match_operand:SI 2 "small_int" ""))
4147    (use (match_operand:SI 3 "small_int" ""))
4148    (use (const_int 0))]
4149
4150   "reload_completed && !TARGET_DEBUG_D_MODE && INTVAL (operands[2]) > 0"
4151
4152   ;; All but the last move
4153   [(parallel [(set (mem:BLK (match_dup 0))
4154                    (mem:BLK (match_dup 1)))
4155               (clobber (match_dup 4))
4156               (clobber (match_dup 5))
4157               (clobber (match_dup 6))
4158               (clobber (match_dup 7))
4159               (use (match_dup 2))
4160               (use (match_dup 3))
4161               (use (const_int 1))])
4162
4163    ;; The last store, so it can fill a delay slot
4164    (parallel [(set (mem:BLK (match_dup 0))
4165                    (mem:BLK (match_dup 1)))
4166               (clobber (match_dup 4))
4167               (clobber (match_dup 5))
4168               (clobber (match_dup 6))
4169               (clobber (match_dup 7))
4170               (use (match_dup 2))
4171               (use (match_dup 3))
4172               (use (const_int 2))])]
4173
4174   "")
4175
4176 (define_insn "movstrsi_internal2"
4177   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
4178         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
4179    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
4180    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
4181    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
4182    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
4183    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
4184    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
4185    (use (const_int 1))]                                 ;; all but last store
4186   ""
4187   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
4188   [(set_attr "type"     "store")
4189    (set_attr "mode"     "none")
4190    (set_attr "length"   "20")])
4191
4192 (define_insn "movstrsi_internal3"
4193   [(set (match_operand:BLK 0 "memory_operand" "=Ro")    ;; destination
4194         (match_operand:BLK 1 "memory_operand" "Ro"))    ;; source
4195    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
4196    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
4197    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
4198    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
4199    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
4200    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
4201    (use (const_int 2))]                                 ;; just last store of block move
4202   ""
4203   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
4204   [(set_attr "type"     "store")
4205    (set_attr "mode"     "none")
4206    (set_attr "length"   "1")])
4207
4208 \f
4209 ;;
4210 ;;  ....................
4211 ;;
4212 ;;      SHIFTS
4213 ;;
4214 ;;  ....................
4215
4216 (define_insn "ashlsi3"
4217   [(set (match_operand:SI 0 "register_operand" "=d")
4218         (ashift:SI (match_operand:SI 1 "register_operand" "d")
4219                    (match_operand:SI 2 "arith_operand" "dI")))]
4220   ""
4221   "*
4222 {
4223   if (GET_CODE (operands[2]) == CONST_INT)
4224     operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
4225
4226   return \"sll\\t%0,%1,%2\";
4227 }"
4228   [(set_attr "type"     "arith")
4229    (set_attr "mode"     "SI")
4230    (set_attr "length"   "1")])
4231
4232
4233 (define_expand "ashldi3"
4234   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4235                    (ashift:DI (match_operand:DI 1 "se_register_operand" "")
4236                               (match_operand:SI 2 "arith_operand" "")))
4237               (clobber (match_dup  3))])]
4238   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
4239   "
4240 {
4241   if (TARGET_64BIT)
4242     {
4243       emit_insn (gen_ashldi3_internal4 (operands[0], operands[1],
4244                                         operands[2]));
4245       DONE;
4246     }
4247
4248   operands[3] = gen_reg_rtx (SImode);
4249 }")
4250
4251
4252 (define_insn "ashldi3_internal"
4253   [(set (match_operand:DI 0 "register_operand" "=&d")
4254         (ashift:DI (match_operand:DI 1 "register_operand" "d")
4255                    (match_operand:SI 2 "register_operand" "d")))
4256    (clobber (match_operand:SI 3 "register_operand" "=d"))]
4257   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
4258   "* 
4259 {
4260   operands[4] = const0_rtx;
4261   dslots_jump_total += 3;
4262   dslots_jump_filled += 2;
4263
4264   return \"sll\\t%3,%2,26\\n\\
4265 \\tbgez\\t%3,1f\\n\\
4266 \\tsll\\t%M0,%L1,%2\\n\\
4267 \\t%(b\\t3f\\n\\
4268 \\tmove\\t%L0,%z4%)\\n\\
4269 \\n\\
4270 1:\\n\\
4271 \\t%(beq\\t%3,%z4,2f\\n\\
4272 \\tsll\\t%M0,%M1,%2%)\\n\\
4273 \\n\\
4274 \\tsubu\\t%3,%z4,%2\\n\\
4275 \\tsrl\\t%3,%L1,%3\\n\\
4276 \\tor\\t%M0,%M0,%3\\n\\
4277 2:\\n\\
4278 \\tsll\\t%L0,%L1,%2\\n\\
4279 3:\";
4280 }"
4281   [(set_attr "type"     "darith")
4282    (set_attr "mode"     "SI")
4283    (set_attr "length"   "12")])
4284
4285
4286 (define_insn "ashldi3_internal2"
4287   [(set (match_operand:DI 0 "register_operand" "=d")
4288         (ashift:DI (match_operand:DI 1 "register_operand" "d")
4289                    (match_operand:SI 2 "small_int" "IJK")))
4290    (clobber (match_operand:SI 3 "register_operand" "=d"))]
4291   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
4292   "*
4293 {
4294   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
4295   operands[4] = const0_rtx;
4296   return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\";
4297 }"
4298   [(set_attr "type"     "darith")
4299    (set_attr "mode"     "DI")
4300    (set_attr "length"   "2")])
4301
4302
4303 (define_split
4304   [(set (match_operand:DI 0 "register_operand" "")
4305         (ashift:DI (match_operand:DI 1 "register_operand" "")
4306                    (match_operand:SI 2 "small_int" "")))
4307    (clobber (match_operand:SI 3 "register_operand" ""))]
4308   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4309    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4310    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4311    && (INTVAL (operands[2]) & 32) != 0"
4312
4313   [(set (subreg:SI (match_dup 0) 1) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
4314    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
4315
4316   "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
4317
4318
4319 (define_split
4320   [(set (match_operand:DI 0 "register_operand" "")
4321         (ashift:DI (match_operand:DI 1 "register_operand" "")
4322                    (match_operand:SI 2 "small_int" "")))
4323    (clobber (match_operand:SI 3 "register_operand" ""))]
4324   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4325    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4326    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4327    && (INTVAL (operands[2]) & 32) != 0"
4328
4329   [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
4330    (set (subreg:SI (match_dup 0) 1) (const_int 0))]
4331
4332   "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
4333
4334
4335 (define_insn "ashldi3_internal3"
4336   [(set (match_operand:DI 0 "register_operand" "=d")
4337         (ashift:DI (match_operand:DI 1 "register_operand" "d")
4338                    (match_operand:SI 2 "small_int" "IJK")))
4339    (clobber (match_operand:SI 3 "register_operand" "=d"))]
4340   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE
4341    && (INTVAL (operands[2]) & 63) < 32
4342    && (INTVAL (operands[2]) & 63) != 0"
4343   "*
4344 {
4345   int amount = INTVAL (operands[2]);
4346
4347   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4348   operands[4] = const0_rtx;
4349   operands[5] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4350
4351   return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\";
4352 }"
4353   [(set_attr "type"     "darith")
4354    (set_attr "mode"     "DI")
4355    (set_attr "length"   "4")])
4356
4357
4358 (define_split
4359   [(set (match_operand:DI 0 "register_operand" "")
4360         (ashift:DI (match_operand:DI 1 "register_operand" "")
4361                    (match_operand:SI 2 "small_int" "")))
4362    (clobber (match_operand:SI 3 "register_operand" ""))]
4363   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4364    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4365    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4366    && (INTVAL (operands[2]) & 63) < 32
4367    && (INTVAL (operands[2]) & 63) != 0"
4368
4369   [(set (subreg:SI (match_dup 0) 1)
4370         (ashift:SI (subreg:SI (match_dup 1) 1)
4371                    (match_dup 2)))
4372
4373    (set (match_dup 3)
4374         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
4375                      (match_dup 4)))
4376
4377    (set (subreg:SI (match_dup 0) 1)
4378         (ior:SI (subreg:SI (match_dup 0) 1)
4379                 (match_dup 3)))
4380
4381    (set (subreg:SI (match_dup 0) 0)
4382         (ashift:SI (subreg:SI (match_dup 1) 0)
4383                    (match_dup 2)))]
4384   "
4385 {
4386   int amount = INTVAL (operands[2]);
4387   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4388   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4389 }")
4390
4391
4392 (define_split
4393   [(set (match_operand:DI 0 "register_operand" "")
4394         (ashift:DI (match_operand:DI 1 "register_operand" "")
4395                    (match_operand:SI 2 "small_int" "")))
4396    (clobber (match_operand:SI 3 "register_operand" ""))]
4397   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4398    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4399    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4400    && (INTVAL (operands[2]) & 63) < 32
4401    && (INTVAL (operands[2]) & 63) != 0"
4402
4403   [(set (subreg:SI (match_dup 0) 0)
4404         (ashift:SI (subreg:SI (match_dup 1) 0)
4405                    (match_dup 2)))
4406
4407    (set (match_dup 3)
4408         (lshiftrt:SI (subreg:SI (match_dup 1) 1)
4409                      (match_dup 4)))
4410
4411    (set (subreg:SI (match_dup 0) 0)
4412         (ior:SI (subreg:SI (match_dup 0) 0)
4413                 (match_dup 3)))
4414
4415    (set (subreg:SI (match_dup 0) 1)
4416         (ashift:SI (subreg:SI (match_dup 1) 1)
4417                    (match_dup 2)))]
4418   "
4419 {
4420   int amount = INTVAL (operands[2]);
4421   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4422   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4423 }")
4424
4425
4426 (define_insn "ashldi3_internal4"
4427   [(set (match_operand:DI 0 "register_operand" "=d")
4428         (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
4429                    (match_operand:SI 2 "arith_operand" "dI")))]
4430   "TARGET_64BIT"
4431   "*
4432 {
4433   if (GET_CODE (operands[2]) == CONST_INT)
4434     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4435
4436   return \"dsll\\t%0,%1,%2\";
4437 }"
4438   [(set_attr "type"     "arith")
4439    (set_attr "mode"     "DI")
4440    (set_attr "length"   "1")])
4441
4442
4443 (define_insn "ashrsi3"
4444   [(set (match_operand:SI 0 "register_operand" "=d")
4445         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
4446                      (match_operand:SI 2 "arith_operand" "dI")))]
4447   ""
4448   "*
4449 {
4450   if (GET_CODE (operands[2]) == CONST_INT)
4451     operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
4452
4453   return \"sra\\t%0,%1,%2\";
4454 }"
4455   [(set_attr "type"     "arith")
4456    (set_attr "mode"     "SI")
4457    (set_attr "length"   "1")])
4458
4459
4460 (define_expand "ashrdi3"
4461   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4462                    (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "")
4463                                 (match_operand:SI 2 "arith_operand" "")))
4464               (clobber (match_dup  3))])]
4465   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
4466   "
4467 {
4468   if (TARGET_64BIT)
4469     {
4470       emit_insn (gen_ashrdi3_internal4 (operands[0], operands[1],
4471                                         operands[2]));
4472       DONE;
4473     }
4474
4475   operands[3] = gen_reg_rtx (SImode);
4476 }")
4477
4478
4479 (define_insn "ashrdi3_internal"
4480   [(set (match_operand:DI 0 "register_operand" "=&d")
4481         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
4482                      (match_operand:SI 2 "register_operand" "d")))
4483    (clobber (match_operand:SI 3 "register_operand" "=d"))]
4484   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
4485   "* 
4486 {
4487   operands[4] = const0_rtx;
4488   dslots_jump_total += 3;
4489   dslots_jump_filled += 2;
4490
4491   return \"sll\\t%3,%2,26\\n\\
4492 \\tbgez\\t%3,1f\\n\\
4493 \\tsra\\t%L0,%M1,%2\\n\\
4494 \\t%(b\\t3f\\n\\
4495 \\tsra\\t%M0,%M1,31%)\\n\\
4496 \\n\\
4497 1:\\n\\
4498 \\t%(beq\\t%3,%z4,2f\\n\\
4499 \\tsrl\\t%L0,%L1,%2%)\\n\\
4500 \\n\\
4501 \\tsubu\\t%3,%z4,%2\\n\\
4502 \\tsll\\t%3,%M1,%3\\n\\
4503 \\tor\\t%L0,%L0,%3\\n\\
4504 2:\\n\\
4505 \\tsra\\t%M0,%M1,%2\\n\\
4506 3:\";
4507 }"
4508   [(set_attr "type"     "darith")
4509    (set_attr "mode"     "DI")
4510    (set_attr "length"   "12")])
4511
4512
4513 (define_insn "ashrdi3_internal2"
4514   [(set (match_operand:DI 0 "register_operand" "=d")
4515         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
4516                      (match_operand:SI 2 "small_int" "IJK")))
4517    (clobber (match_operand:SI 3 "register_operand" "=d"))]
4518   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
4519   "*
4520 {
4521   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
4522   return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\";
4523 }"
4524   [(set_attr "type"     "darith")
4525    (set_attr "mode"     "DI")
4526    (set_attr "length"   "2")])
4527
4528
4529 (define_split
4530   [(set (match_operand:DI 0 "register_operand" "")
4531         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4532                      (match_operand:SI 2 "small_int" "")))
4533    (clobber (match_operand:SI 3 "register_operand" ""))]
4534   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4535    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4536    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4537    && (INTVAL (operands[2]) & 32) != 0"
4538
4539   [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
4540    (set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (const_int 31)))]
4541
4542   "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
4543
4544
4545 (define_split
4546   [(set (match_operand:DI 0 "register_operand" "")
4547         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4548                      (match_operand:SI 2 "small_int" "")))
4549    (clobber (match_operand:SI 3 "register_operand" ""))]
4550   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4551    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4552    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4553    && (INTVAL (operands[2]) & 32) != 0"
4554
4555   [(set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
4556    (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
4557
4558   "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
4559
4560
4561 (define_insn "ashrdi3_internal3"
4562   [(set (match_operand:DI 0 "register_operand" "=d")
4563         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
4564                      (match_operand:SI 2 "small_int" "IJK")))
4565    (clobber (match_operand:SI 3 "register_operand" "=d"))]
4566   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE
4567    && (INTVAL (operands[2]) & 63) < 32
4568    && (INTVAL (operands[2]) & 63) != 0"
4569   "*
4570 {
4571   int amount = INTVAL (operands[2]);
4572
4573   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4574   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4575
4576   return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\";
4577 }"
4578   [(set_attr "type"     "darith")
4579    (set_attr "mode"     "DI")
4580    (set_attr "length"   "4")])
4581
4582
4583 (define_split
4584   [(set (match_operand:DI 0 "register_operand" "")
4585         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4586                      (match_operand:SI 2 "small_int" "")))
4587    (clobber (match_operand:SI 3 "register_operand" ""))]
4588   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4589    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4590    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4591    && (INTVAL (operands[2]) & 63) < 32
4592    && (INTVAL (operands[2]) & 63) != 0"
4593
4594   [(set (subreg:SI (match_dup 0) 0)
4595         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
4596                      (match_dup 2)))
4597
4598    (set (match_dup 3)
4599         (ashift:SI (subreg:SI (match_dup 1) 1)
4600                    (match_dup 4)))
4601
4602    (set (subreg:SI (match_dup 0) 0)
4603         (ior:SI (subreg:SI (match_dup 0) 0)
4604                 (match_dup 3)))
4605
4606    (set (subreg:SI (match_dup 0) 1)
4607         (ashiftrt:SI (subreg:SI (match_dup 1) 1)
4608                      (match_dup 2)))]
4609   "
4610 {
4611   int amount = INTVAL (operands[2]);
4612   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4613   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4614 }")
4615
4616
4617 (define_split
4618   [(set (match_operand:DI 0 "register_operand" "")
4619         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4620                      (match_operand:SI 2 "small_int" "")))
4621    (clobber (match_operand:SI 3 "register_operand" ""))]
4622   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4623    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4624    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4625    && (INTVAL (operands[2]) & 63) < 32
4626    && (INTVAL (operands[2]) & 63) != 0"
4627
4628   [(set (subreg:SI (match_dup 0) 1)
4629         (lshiftrt:SI (subreg:SI (match_dup 1) 1)
4630                      (match_dup 2)))
4631
4632    (set (match_dup 3)
4633         (ashift:SI (subreg:SI (match_dup 1) 0)
4634                    (match_dup 4)))
4635
4636    (set (subreg:SI (match_dup 0) 1)
4637         (ior:SI (subreg:SI (match_dup 0) 1)
4638                 (match_dup 3)))
4639
4640    (set (subreg:SI (match_dup 0) 0)
4641         (ashiftrt:SI (subreg:SI (match_dup 1) 0)
4642                      (match_dup 2)))]
4643   "
4644 {
4645   int amount = INTVAL (operands[2]);
4646   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4647   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4648 }")
4649
4650
4651 (define_insn "ashrdi3_internal4"
4652   [(set (match_operand:DI 0 "register_operand" "=d")
4653         (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
4654                      (match_operand:SI 2 "arith_operand" "dI")))]
4655   "TARGET_64BIT"
4656   "*
4657 {
4658   if (GET_CODE (operands[2]) == CONST_INT)
4659     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4660
4661   return \"dsra\\t%0,%1,%2\";
4662 }"
4663   [(set_attr "type"     "arith")
4664    (set_attr "mode"     "DI")
4665    (set_attr "length"   "1")])
4666
4667
4668 (define_insn "lshrsi3"
4669   [(set (match_operand:SI 0 "register_operand" "=d")
4670         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
4671                      (match_operand:SI 2 "arith_operand" "dI")))]
4672   ""
4673   "*
4674 {
4675   if (GET_CODE (operands[2]) == CONST_INT)
4676     operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
4677
4678   return \"srl\\t%0,%1,%2\";
4679 }"
4680   [(set_attr "type"     "arith")
4681    (set_attr "mode"     "SI")
4682    (set_attr "length"   "1")])
4683
4684
4685 (define_expand "lshrdi3"
4686   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4687                    (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "")
4688                                 (match_operand:SI 2 "arith_operand" "")))
4689               (clobber (match_dup  3))])]
4690   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
4691   "
4692 {
4693   if (TARGET_64BIT)
4694     {
4695       emit_insn (gen_lshrdi3_internal4 (operands[0], operands[1],
4696                                         operands[2]));
4697       DONE;
4698     }
4699
4700   operands[3] = gen_reg_rtx (SImode);
4701 }")
4702
4703
4704 (define_insn "lshrdi3_internal"
4705   [(set (match_operand:DI 0 "register_operand" "=&d")
4706         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
4707                      (match_operand:SI 2 "register_operand" "d")))
4708    (clobber (match_operand:SI 3 "register_operand" "=d"))]
4709   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
4710   "* 
4711 {
4712   operands[4] = const0_rtx;
4713   dslots_jump_total += 3;
4714   dslots_jump_filled += 2;
4715
4716   return \"sll\\t%3,%2,26\\n\\
4717 \\tbgez\\t%3,1f\\n\\
4718 \\tsrl\\t%L0,%M1,%2\\n\\
4719 \\t%(b\\t3f\\n\\
4720 \\tmove\\t%M0,%z4%)\\n\\
4721 \\n\\
4722 1:\\n\\
4723 \\t%(beq\\t%3,%z4,2f\\n\\
4724 \\tsrl\\t%L0,%L1,%2%)\\n\\
4725 \\n\\
4726 \\tsubu\\t%3,%z4,%2\\n\\
4727 \\tsll\\t%3,%M1,%3\\n\\
4728 \\tor\\t%L0,%L0,%3\\n\\
4729 2:\\n\\
4730 \\tsrl\\t%M0,%M1,%2\\n\\
4731 3:\";
4732 }"
4733   [(set_attr "type"     "darith")
4734    (set_attr "mode"     "DI")
4735    (set_attr "length"   "12")])
4736
4737
4738 (define_insn "lshrdi3_internal2"
4739   [(set (match_operand:DI 0 "register_operand" "=d")
4740         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
4741                      (match_operand:SI 2 "small_int" "IJK")))
4742    (clobber (match_operand:SI 3 "register_operand" "=d"))]
4743   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
4744   "*
4745 {
4746   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);
4747   operands[4] = const0_rtx;
4748   return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\";
4749 }"
4750   [(set_attr "type"     "darith")
4751    (set_attr "mode"     "DI")
4752    (set_attr "length"   "2")])
4753
4754
4755 (define_split
4756   [(set (match_operand:DI 0 "register_operand" "")
4757         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
4758                      (match_operand:SI 2 "small_int" "")))
4759    (clobber (match_operand:SI 3 "register_operand" ""))]
4760   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4761    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4762    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4763    && (INTVAL (operands[2]) & 32) != 0"
4764
4765   [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
4766    (set (subreg:SI (match_dup 0) 1) (const_int 0))]
4767
4768   "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
4769
4770
4771 (define_split
4772   [(set (match_operand:DI 0 "register_operand" "")
4773         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
4774                      (match_operand:SI 2 "small_int" "")))
4775    (clobber (match_operand:SI 3 "register_operand" ""))]
4776   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4777    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4778    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4779    && (INTVAL (operands[2]) & 32) != 0"
4780
4781   [(set (subreg:SI (match_dup 0) 1) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
4782    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
4783
4784   "operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0x1f);")
4785
4786
4787 (define_insn "lshrdi3_internal3"
4788   [(set (match_operand:DI 0 "register_operand" "=d")
4789         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
4790                    (match_operand:SI 2 "small_int" "IJK")))
4791    (clobber (match_operand:SI 3 "register_operand" "=d"))]
4792   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE
4793    && (INTVAL (operands[2]) & 63) < 32
4794    && (INTVAL (operands[2]) & 63) != 0"
4795   "*
4796 {
4797   int amount = INTVAL (operands[2]);
4798
4799   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4800   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4801
4802   return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\";
4803 }"
4804   [(set_attr "type"     "darith")
4805    (set_attr "mode"     "DI")
4806    (set_attr "length"   "4")])
4807
4808
4809 (define_split
4810   [(set (match_operand:DI 0 "register_operand" "")
4811         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
4812                      (match_operand:SI 2 "small_int" "")))
4813    (clobber (match_operand:SI 3 "register_operand" ""))]
4814   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4815    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4816    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4817    && (INTVAL (operands[2]) & 63) < 32
4818    && (INTVAL (operands[2]) & 63) != 0"
4819
4820   [(set (subreg:SI (match_dup 0) 0)
4821         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
4822                      (match_dup 2)))
4823
4824    (set (match_dup 3)
4825         (ashift:SI (subreg:SI (match_dup 1) 1)
4826                    (match_dup 4)))
4827
4828    (set (subreg:SI (match_dup 0) 0)
4829         (ior:SI (subreg:SI (match_dup 0) 0)
4830                 (match_dup 3)))
4831
4832    (set (subreg:SI (match_dup 0) 1)
4833         (lshiftrt:SI (subreg:SI (match_dup 1) 1)
4834                      (match_dup 2)))]
4835   "
4836 {
4837   int amount = INTVAL (operands[2]);
4838   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4839   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4840 }")
4841
4842
4843 (define_split
4844   [(set (match_operand:DI 0 "register_operand" "")
4845         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
4846                      (match_operand:SI 2 "small_int" "")))
4847    (clobber (match_operand:SI 3 "register_operand" ""))]
4848   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4849    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4850    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4851    && (INTVAL (operands[2]) & 63) < 32
4852    && (INTVAL (operands[2]) & 63) != 0"
4853
4854   [(set (subreg:SI (match_dup 0) 1)
4855         (lshiftrt:SI (subreg:SI (match_dup 1) 1)
4856                      (match_dup 2)))
4857
4858    (set (match_dup 3)
4859         (ashift:SI (subreg:SI (match_dup 1) 0)
4860                    (match_dup 4)))
4861
4862    (set (subreg:SI (match_dup 0) 1)
4863         (ior:SI (subreg:SI (match_dup 0) 1)
4864                 (match_dup 3)))
4865
4866    (set (subreg:SI (match_dup 0) 0)
4867         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
4868                      (match_dup 2)))]
4869   "
4870 {
4871   int amount = INTVAL (operands[2]);
4872   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
4873   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
4874 }")
4875
4876
4877 (define_insn "lshrdi3_internal4"
4878   [(set (match_operand:DI 0 "register_operand" "=d")
4879         (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
4880                      (match_operand:SI 2 "arith_operand" "dI")))]
4881   "TARGET_64BIT"
4882   "*
4883 {
4884   if (GET_CODE (operands[2]) == CONST_INT)
4885     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4886
4887   return \"dsrl\\t%0,%1,%2\";
4888 }"
4889   [(set_attr "type"     "arith")
4890    (set_attr "mode"     "DI")
4891    (set_attr "length"   "1")])
4892
4893 \f
4894 ;;
4895 ;;  ....................
4896 ;;
4897 ;;      COMPARISONS
4898 ;;
4899 ;;  ....................
4900
4901 ;; Flow here is rather complex:
4902 ;;
4903 ;;  1)  The cmp{si,di,sf,df} routine is called.  It deposits the
4904 ;;      arguments into the branch_cmp array, and the type into
4905 ;;      branch_type.  No RTL is generated.
4906 ;;
4907 ;;  2)  The appropriate branch define_expand is called, which then
4908 ;;      creates the appropriate RTL for the comparison and branch.
4909 ;;      Different CC modes are used, based on what type of branch is
4910 ;;      done, so that we can constrain things appropriately.  There
4911 ;;      are assumptions in the rest of GCC that break if we fold the
4912 ;;      operands into the branchs for integer operations, and use cc0
4913 ;;      for floating point, so we use the fp status register instead.
4914 ;;      If needed, an appropriate temporary is created to hold the
4915 ;;      of the integer compare.
4916
4917 (define_expand "cmpsi"
4918   [(set (cc0)
4919         (compare:CC (match_operand:SI 0 "register_operand" "")
4920                     (match_operand:SI 1 "arith_operand" "")))]
4921   ""
4922   "
4923 {
4924   if (operands[0])              /* avoid unused code message */
4925     {
4926       branch_cmp[0] = operands[0];
4927       branch_cmp[1] = operands[1];
4928       branch_type = CMP_SI;
4929       DONE;
4930     }
4931 }")
4932
4933 (define_expand "tstsi"
4934   [(set (cc0)
4935         (match_operand:SI 0 "register_operand" ""))]
4936   ""
4937   "
4938 {
4939   if (operands[0])              /* avoid unused code message */
4940     {
4941       branch_cmp[0] = operands[0];
4942       branch_cmp[1] = const0_rtx;
4943       branch_type = CMP_SI;
4944       DONE;
4945     }
4946 }")
4947
4948 (define_expand "cmpdi"
4949   [(set (cc0)
4950         (compare:CC (match_operand:DI 0 "se_register_operand" "")
4951                     (match_operand:DI 1 "se_arith_operand" "")))]
4952   "TARGET_64BIT"
4953   "
4954 {
4955   if (operands[0])              /* avoid unused code message */
4956     {
4957       branch_cmp[0] = operands[0];
4958       branch_cmp[1] = operands[1];
4959       branch_type = CMP_DI;
4960       DONE;
4961     }
4962 }")
4963
4964 (define_expand "tstdi"
4965   [(set (cc0)
4966         (match_operand:DI 0 "se_register_operand" ""))]
4967   "TARGET_64BIT"
4968   "
4969 {
4970   if (operands[0])              /* avoid unused code message */
4971     {
4972       branch_cmp[0] = operands[0];
4973       branch_cmp[1] = const0_rtx;
4974       branch_type = CMP_DI;
4975       DONE;
4976     }
4977 }")
4978
4979 (define_expand "cmpdf"
4980   [(set (cc0)
4981         (compare:CC (match_operand:DF 0 "register_operand" "")
4982                     (match_operand:DF 1 "register_operand" "")))]
4983   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4984   "
4985 {
4986   if (operands[0])              /* avoid unused code message */
4987     {
4988       branch_cmp[0] = operands[0];
4989       branch_cmp[1] = operands[1];
4990       branch_type = CMP_DF;
4991       DONE;
4992     }
4993 }")
4994
4995 (define_expand "cmpsf"
4996   [(set (cc0)
4997         (compare:CC (match_operand:SF 0 "register_operand" "")
4998                     (match_operand:SF 1 "register_operand" "")))]
4999   "TARGET_HARD_FLOAT"
5000   "
5001 {
5002   if (operands[0])              /* avoid unused code message */
5003     {
5004       branch_cmp[0] = operands[0];
5005       branch_cmp[1] = operands[1];
5006       branch_type = CMP_SF;
5007       DONE;
5008     }
5009 }")
5010
5011 \f
5012 ;;
5013 ;;  ....................
5014 ;;
5015 ;;      CONDITIONAL BRANCHES
5016 ;;
5017 ;;  ....................
5018
5019 (define_insn "branch_fp_ne"
5020   [(set (pc)
5021         (if_then_else (ne:CC (match_operand:CC 0 "register_operand" "z")
5022                              (const_int 0))
5023                       (match_operand 1 "pc_or_label_operand" "")
5024                       (match_operand 2 "pc_or_label_operand" "")))]
5025   "TARGET_HARD_FLOAT"
5026   "*
5027 {
5028   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
5029   return (operands[1] != pc_rtx) ? \"%*bc1t%?\\t%Z0%1\" : \"%*bc1f%?\\t%Z0%2\";
5030 }"
5031   [(set_attr "type"     "branch")
5032    (set_attr "mode"     "none")
5033    (set_attr "length"   "1")])
5034
5035 (define_insn "branch_fp_eq"
5036   [(set (pc)
5037         (if_then_else (eq:CC (match_operand:CC 0 "register_operand" "z")
5038                              (const_int 0))
5039                       (match_operand 1 "pc_or_label_operand" "")
5040                       (match_operand 2 "pc_or_label_operand" "")))]
5041   "TARGET_HARD_FLOAT"
5042   "*
5043 {
5044   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
5045   return (operands[1] != pc_rtx) ? \"%*bc1f%?\\t%Z0%1\" : \"%*bc1t%?\\t%Z0%2\";
5046 }"
5047   [(set_attr "type"     "branch")
5048    (set_attr "mode"     "none")
5049    (set_attr "length"   "1")])
5050
5051 (define_insn "branch_zero"
5052   [(set (pc)
5053         (if_then_else (match_operator:SI 0 "cmp_op"
5054                                          [(match_operand:SI 1 "register_operand" "d")
5055                                           (const_int 0)])
5056         (match_operand 2 "pc_or_label_operand" "")
5057         (match_operand 3 "pc_or_label_operand" "")))]
5058   ""
5059   "*
5060 {
5061   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
5062   if (operands[2] != pc_rtx)
5063     {                           /* normal jump */
5064       switch (GET_CODE (operands[0]))
5065         {
5066         case EQ:  return \"%*beq%?\\t%z1,%.,%2\";
5067         case NE:  return \"%*bne%?\\t%z1,%.,%2\";
5068         case GTU: return \"%*bne%?\\t%z1,%.,%2\";
5069         case LEU: return \"%*beq%?\\t%z1,%.,%2\";
5070         case GEU: return \"%*j\\t%2\";
5071         case LTU: return \"%*bne%?\\t%.,%.,%2\";
5072         }
5073
5074       return \"%*b%C0z%?\\t%z1,%2\";
5075     }
5076   else
5077     {                           /* inverted jump */
5078       switch (GET_CODE (operands[0]))
5079         {
5080         case EQ:  return \"%*bne%?\\t%z1,%.,%3\";
5081         case NE:  return \"%*beq%?\\t%z1,%.,%3\";
5082         case GTU: return \"%*beq%?\\t%z1,%.,%3\";
5083         case LEU: return \"%*bne%?\\t%z1,%.,%3\";
5084         case GEU: return \"%*beq%?\\t%.,%.,%3\";
5085         case LTU: return \"%*j\\t%3\";
5086         }
5087
5088       return \"%*b%N0z%?\\t%z1,%3\";
5089     }
5090 }"
5091   [(set_attr "type"     "branch")
5092    (set_attr "mode"     "none")
5093    (set_attr "length"   "1")])
5094
5095
5096 (define_insn "branch_zero_di"
5097   [(set (pc)
5098         (if_then_else (match_operator:DI 0 "cmp_op"
5099                                          [(match_operand:DI 1 "se_register_operand" "d")
5100                                           (const_int 0)])
5101         (match_operand 2 "pc_or_label_operand" "")
5102         (match_operand 3 "pc_or_label_operand" "")))]
5103   ""
5104   "*
5105 {
5106   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
5107   if (operands[2] != pc_rtx)
5108     {                           /* normal jump */
5109       switch (GET_CODE (operands[0]))
5110         {
5111         case EQ:  return \"%*beq%?\\t%z1,%.,%2\";
5112         case NE:  return \"%*bne%?\\t%z1,%.,%2\";
5113         case GTU: return \"%*bne%?\\t%z1,%.,%2\";
5114         case LEU: return \"%*beq%?\\t%z1,%.,%2\";
5115         case GEU: return \"%*j\\t%2\";
5116         case LTU: return \"%*bne%?\\t%.,%.,%2\";
5117         }
5118
5119       return \"%*b%C0z%?\\t%z1,%2\";
5120     }
5121   else
5122     {                           /* inverted jump */
5123       switch (GET_CODE (operands[0]))
5124         {
5125         case EQ:  return \"%*bne%?\\t%z1,%.,%3\";
5126         case NE:  return \"%*beq%?\\t%z1,%.,%3\";
5127         case GTU: return \"%*beq%?\\t%z1,%.,%3\";
5128         case LEU: return \"%*bne%?\\t%z1,%.,%3\";
5129         case GEU: return \"%*beq%?\\t%.,%.,%3\";
5130         case LTU: return \"%*j\\t%3\";
5131         }
5132
5133       return \"%*b%N0z%?\\t%z1,%3\";
5134     }
5135 }"
5136   [(set_attr "type"     "branch")
5137    (set_attr "mode"     "none")
5138    (set_attr "length"   "1")])
5139
5140
5141 (define_insn "branch_equality"
5142   [(set (pc)
5143         (if_then_else (match_operator:SI 0 "equality_op"
5144                                          [(match_operand:SI 1 "register_operand" "d")
5145                                           (match_operand:SI 2 "register_operand" "d")])
5146         (match_operand 3 "pc_or_label_operand" "")
5147         (match_operand 4 "pc_or_label_operand" "")))]
5148   ""
5149   "*
5150 {
5151   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
5152   return (operands[3] != pc_rtx)
5153         ? \"%*b%C0%?\\t%z1,%z2,%3\"
5154         : \"%*b%N0%?\\t%z1,%z2,%4\";
5155 }"
5156   [(set_attr "type"     "branch")
5157    (set_attr "mode"     "none")
5158    (set_attr "length"   "1")])
5159
5160
5161 (define_insn "branch_equality_di"
5162   [(set (pc)
5163         (if_then_else (match_operator:DI 0 "equality_op"
5164                                          [(match_operand:DI 1 "se_register_operand" "d")
5165                                           (match_operand:DI 2 "se_register_operand" "d")])
5166         (match_operand 3 "pc_or_label_operand" "")
5167         (match_operand 4 "pc_or_label_operand" "")))]
5168   ""
5169   "*
5170 {
5171   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
5172   return (operands[3] != pc_rtx)
5173         ? \"%*b%C0%?\\t%z1,%z2,%3\"
5174         : \"%*b%N0%?\\t%z1,%z2,%4\";
5175 }"
5176   [(set_attr "type"     "branch")
5177    (set_attr "mode"     "none")
5178    (set_attr "length"   "1")])
5179
5180
5181 (define_expand "beq"
5182   [(set (pc)
5183         (if_then_else (eq:CC (cc0)
5184                              (const_int 0))
5185                       (label_ref (match_operand 0 "" ""))
5186                       (pc)))]
5187   ""
5188   "
5189 {
5190   if (operands[0])              /* avoid unused code warning */
5191     {
5192       gen_conditional_branch (operands, EQ);
5193       DONE;
5194     }
5195 }")
5196
5197 (define_expand "bne"
5198   [(set (pc)
5199         (if_then_else (ne:CC (cc0)
5200                              (const_int 0))
5201                       (label_ref (match_operand 0 "" ""))
5202                       (pc)))]
5203   ""
5204   "
5205 {
5206   if (operands[0])              /* avoid unused code warning */
5207     {
5208       gen_conditional_branch (operands, NE);
5209       DONE;
5210     }
5211 }")
5212
5213 (define_expand "bgt"
5214   [(set (pc)
5215         (if_then_else (gt:CC (cc0)
5216                              (const_int 0))
5217                       (label_ref (match_operand 0 "" ""))
5218                       (pc)))]
5219   ""
5220   "
5221 {
5222   if (operands[0])              /* avoid unused code warning */
5223     {
5224       gen_conditional_branch (operands, GT);
5225       DONE;
5226     }
5227 }")
5228
5229 (define_expand "bge"
5230   [(set (pc)
5231         (if_then_else (ge:CC (cc0)
5232                              (const_int 0))
5233                       (label_ref (match_operand 0 "" ""))
5234                       (pc)))]
5235   ""
5236   "
5237 {
5238   if (operands[0])              /* avoid unused code warning */
5239     {
5240       gen_conditional_branch (operands, GE);
5241       DONE;
5242     }
5243 }")
5244
5245 (define_expand "blt"
5246   [(set (pc)
5247         (if_then_else (lt:CC (cc0)
5248                              (const_int 0))
5249                       (label_ref (match_operand 0 "" ""))
5250                       (pc)))]
5251   ""
5252   "
5253 {
5254   if (operands[0])              /* avoid unused code warning */
5255     {
5256       gen_conditional_branch (operands, LT);
5257       DONE;
5258     }
5259 }")
5260
5261 (define_expand "ble"
5262   [(set (pc)
5263         (if_then_else (le:CC (cc0)
5264                              (const_int 0))
5265                       (label_ref (match_operand 0 "" ""))
5266                       (pc)))]
5267   ""
5268   "
5269 {
5270   if (operands[0])              /* avoid unused code warning */
5271     {
5272       gen_conditional_branch (operands, LE);
5273       DONE;
5274     }
5275 }")
5276
5277 (define_expand "bgtu"
5278   [(set (pc)
5279         (if_then_else (gtu:CC (cc0)
5280                               (const_int 0))
5281                       (label_ref (match_operand 0 "" ""))
5282                       (pc)))]
5283   ""
5284   "
5285 {
5286   if (operands[0])              /* avoid unused code warning */
5287     {
5288       gen_conditional_branch (operands, GTU);
5289       DONE;
5290     }
5291 }")
5292
5293 (define_expand "bgeu"
5294   [(set (pc)
5295         (if_then_else (geu:CC (cc0)
5296                               (const_int 0))
5297                       (label_ref (match_operand 0 "" ""))
5298                       (pc)))]
5299   ""
5300   "
5301 {
5302   if (operands[0])              /* avoid unused code warning */
5303     {
5304       gen_conditional_branch (operands, GEU);
5305       DONE;
5306     }
5307 }")
5308
5309
5310 (define_expand "bltu"
5311   [(set (pc)
5312         (if_then_else (ltu:CC (cc0)
5313                               (const_int 0))
5314                       (label_ref (match_operand 0 "" ""))
5315                       (pc)))]
5316   ""
5317   "
5318 {
5319   if (operands[0])              /* avoid unused code warning */
5320     {
5321       gen_conditional_branch (operands, LTU);
5322       DONE;
5323     }
5324 }")
5325
5326 (define_expand "bleu"
5327   [(set (pc)
5328         (if_then_else (leu:CC (cc0)
5329                               (const_int 0))
5330                       (label_ref (match_operand 0 "" ""))
5331                       (pc)))]
5332   ""
5333   "
5334 {
5335   if (operands[0])              /* avoid unused code warning */
5336     {
5337       gen_conditional_branch (operands, LEU);
5338       DONE;
5339     }
5340 }")
5341
5342 \f
5343 ;;
5344 ;;  ....................
5345 ;;
5346 ;;      SETTING A REGISTER FROM A COMPARISON
5347 ;;
5348 ;;  ....................
5349
5350 (define_expand "seq"
5351   [(set (match_operand:SI 0 "register_operand" "=d")
5352         (eq:SI (match_dup 1)
5353                (match_dup 2)))]
5354   ""
5355   "
5356 {
5357   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5358     FAIL;
5359
5360   /* set up operands from compare.  */
5361   operands[1] = branch_cmp[0];
5362   operands[2] = branch_cmp[1];
5363
5364   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5365     {
5366       gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
5367       DONE;
5368     }
5369
5370   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
5371     operands[2] = force_reg (SImode, operands[2]);
5372
5373   /* fall through and generate default code */
5374 }")
5375
5376
5377 (define_insn "seq_si_zero"
5378   [(set (match_operand:SI 0 "register_operand" "=d")
5379         (eq:SI (match_operand:SI 1 "register_operand" "d")
5380                (const_int 0)))]
5381   ""
5382   "sltu\\t%0,%1,1"
5383   [(set_attr "type"     "arith")
5384    (set_attr "mode"     "SI")
5385    (set_attr "length"   "1")])
5386
5387 (define_insn "seq_di_zero"
5388   [(set (match_operand:DI 0 "register_operand" "=d")
5389         (eq:DI (match_operand:DI 1 "se_register_operand" "d")
5390                (const_int 0)))]
5391   "TARGET_64BIT"
5392   "sltu\\t%0,%1,1"
5393   [(set_attr "type"     "arith")
5394    (set_attr "mode"     "DI")
5395    (set_attr "length"   "1")])
5396
5397 (define_insn "seq_si"
5398   [(set (match_operand:SI 0 "register_operand" "=d,d")
5399         (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
5400                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
5401   "TARGET_DEBUG_C_MODE"
5402   "@
5403    xor\\t%0,%1,%2\;sltu\\t%0,%0,1
5404    xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
5405   [(set_attr "type"     "arith")
5406    (set_attr "mode"     "SI")
5407    (set_attr "length"   "2")])
5408
5409 (define_split
5410   [(set (match_operand:SI 0 "register_operand" "")
5411         (eq:SI (match_operand:SI 1 "register_operand" "")
5412                (match_operand:SI 2 "uns_arith_operand" "")))]
5413   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
5414     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
5415   [(set (match_dup 0)
5416         (xor:SI (match_dup 1)
5417                 (match_dup 2)))
5418    (set (match_dup 0)
5419         (ltu:SI (match_dup 0)
5420                 (const_int 1)))]
5421   "")
5422
5423 (define_insn "seq_di"
5424   [(set (match_operand:DI 0 "register_operand" "=d,d")
5425         (eq:DI (match_operand:DI 1 "se_register_operand" "%d,d")
5426                (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
5427   "TARGET_64BIT && TARGET_DEBUG_C_MODE"
5428   "@
5429    xor\\t%0,%1,%2\;sltu\\t%0,%0,1
5430    xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
5431   [(set_attr "type"     "arith")
5432    (set_attr "mode"     "DI")
5433    (set_attr "length"   "2")])
5434
5435 (define_split
5436   [(set (match_operand:DI 0 "register_operand" "")
5437         (eq:DI (match_operand:DI 1 "se_register_operand" "")
5438                (match_operand:DI 2 "se_uns_arith_operand" "")))]
5439   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
5440     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
5441   [(set (match_dup 0)
5442         (xor:DI (match_dup 1)
5443                 (match_dup 2)))
5444    (set (match_dup 0)
5445         (ltu:DI (match_dup 0)
5446                 (const_int 1)))]
5447   "")
5448
5449 (define_expand "sne"
5450   [(set (match_operand:SI 0 "register_operand" "=d")
5451         (ne:SI (match_dup 1)
5452                (match_dup 2)))]
5453   ""
5454   "
5455 {
5456   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5457     FAIL;
5458
5459   /* set up operands from compare.  */
5460   operands[1] = branch_cmp[0];
5461   operands[2] = branch_cmp[1];
5462
5463   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5464     {
5465       gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
5466       DONE;
5467     }
5468
5469   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
5470     operands[2] = force_reg (SImode, operands[2]);
5471
5472   /* fall through and generate default code */
5473 }")
5474
5475 (define_insn "sne_si_zero"
5476   [(set (match_operand:SI 0 "register_operand" "=d")
5477         (ne:SI (match_operand:SI 1 "register_operand" "d")
5478                (const_int 0)))]
5479   ""
5480   "sltu\\t%0,%.,%1"
5481   [(set_attr "type"     "arith")
5482    (set_attr "mode"     "SI")
5483    (set_attr "length"   "1")])
5484
5485 (define_insn "sne_di_zero"
5486   [(set (match_operand:DI 0 "register_operand" "=d")
5487         (ne:DI (match_operand:DI 1 "se_register_operand" "d")
5488                (const_int 0)))]
5489   "TARGET_64BIT"
5490   "sltu\\t%0,%.,%1"
5491   [(set_attr "type"     "arith")
5492    (set_attr "mode"     "DI")
5493    (set_attr "length"   "1")])
5494
5495 (define_insn "sne_si"
5496   [(set (match_operand:SI 0 "register_operand" "=d,d")
5497         (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
5498                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
5499   "TARGET_DEBUG_C_MODE"
5500   "@
5501     xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
5502     xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
5503   [(set_attr "type"     "arith")
5504    (set_attr "mode"     "SI")
5505    (set_attr "length"   "2")])
5506
5507 (define_split
5508   [(set (match_operand:SI 0 "register_operand" "")
5509         (ne:SI (match_operand:SI 1 "register_operand" "")
5510                (match_operand:SI 2 "uns_arith_operand" "")))]
5511   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
5512     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
5513   [(set (match_dup 0)
5514         (xor:SI (match_dup 1)
5515                 (match_dup 2)))
5516    (set (match_dup 0)
5517         (gtu:SI (match_dup 0)
5518                 (const_int 0)))]
5519   "")
5520
5521 (define_insn "sne_di"
5522   [(set (match_operand:DI 0 "register_operand" "=d,d")
5523         (ne:DI (match_operand:DI 1 "se_register_operand" "%d,d")
5524                (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
5525   "TARGET_64BIT && TARGET_DEBUG_C_MODE"
5526   "@
5527     xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
5528     xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
5529   [(set_attr "type"     "arith")
5530    (set_attr "mode"     "DI")
5531    (set_attr "length"   "2")])
5532
5533 (define_split
5534   [(set (match_operand:DI 0 "register_operand" "")
5535         (ne:DI (match_operand:DI 1 "se_register_operand" "")
5536                (match_operand:DI 2 "se_uns_arith_operand" "")))]
5537   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
5538     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
5539   [(set (match_dup 0)
5540         (xor:DI (match_dup 1)
5541                 (match_dup 2)))
5542    (set (match_dup 0)
5543         (gtu:DI (match_dup 0)
5544                 (const_int 0)))]
5545   "")
5546
5547 (define_expand "sgt"
5548   [(set (match_operand:SI 0 "register_operand" "=d")
5549         (gt:SI (match_dup 1)
5550                (match_dup 2)))]
5551   ""
5552   "
5553 {
5554   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5555     FAIL;
5556
5557   /* set up operands from compare.  */
5558   operands[1] = branch_cmp[0];
5559   operands[2] = branch_cmp[1];
5560
5561   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5562     {
5563       gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
5564       DONE;
5565     }
5566
5567   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
5568     operands[2] = force_reg (SImode, operands[2]);
5569
5570   /* fall through and generate default code */
5571 }")
5572
5573 (define_insn "sgt_si"
5574   [(set (match_operand:SI 0 "register_operand" "=d")
5575         (gt:SI (match_operand:SI 1 "register_operand" "d")
5576                (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
5577   ""
5578   "slt\\t%0,%z2,%1"
5579   [(set_attr "type"     "arith")
5580    (set_attr "mode"     "SI")
5581    (set_attr "length"   "1")])
5582
5583 (define_insn "sgt_di"
5584   [(set (match_operand:DI 0 "register_operand" "=d")
5585         (gt:DI (match_operand:DI 1 "se_register_operand" "d")
5586                (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
5587   "TARGET_64BIT"
5588   "slt\\t%0,%z2,%1"
5589   [(set_attr "type"     "arith")
5590    (set_attr "mode"     "DI")
5591    (set_attr "length"   "1")])
5592
5593 (define_expand "sge"
5594   [(set (match_operand:SI 0 "register_operand" "=d")
5595         (ge:SI (match_dup 1)
5596                (match_dup 2)))]
5597   ""
5598   "
5599 {
5600   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5601     FAIL;
5602
5603   /* set up operands from compare.  */
5604   operands[1] = branch_cmp[0];
5605   operands[2] = branch_cmp[1];
5606
5607   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5608     {
5609       gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
5610       DONE;
5611     }
5612
5613   /* fall through and generate default code */
5614 }")
5615
5616 (define_insn "sge_si"
5617   [(set (match_operand:SI 0 "register_operand" "=d")
5618         (ge:SI (match_operand:SI 1 "register_operand" "d")
5619                (match_operand:SI 2 "arith_operand" "dI")))]
5620   "TARGET_DEBUG_C_MODE"
5621   "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
5622   [(set_attr "type"     "arith")
5623    (set_attr "mode"     "SI")
5624    (set_attr "length"   "2")])
5625
5626 (define_split
5627   [(set (match_operand:SI 0 "register_operand" "")
5628         (ge:SI (match_operand:SI 1 "register_operand" "")
5629                (match_operand:SI 2 "arith_operand" "")))]
5630   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5631   [(set (match_dup 0)
5632         (lt:SI (match_dup 1)
5633                (match_dup 2)))
5634    (set (match_dup 0)
5635         (xor:SI (match_dup 0)
5636                 (const_int 1)))]
5637   "")
5638
5639 (define_insn "sge_di"
5640   [(set (match_operand:DI 0 "register_operand" "=d")
5641         (ge:DI (match_operand:DI 1 "se_register_operand" "d")
5642                (match_operand:DI 2 "se_arith_operand" "dI")))]
5643   "TARGET_64BIT && TARGET_DEBUG_C_MODE"
5644   "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
5645   [(set_attr "type"     "arith")
5646    (set_attr "mode"     "DI")
5647    (set_attr "length"   "2")])
5648
5649 (define_split
5650   [(set (match_operand:DI 0 "register_operand" "")
5651         (ge:DI (match_operand:DI 1 "se_register_operand" "")
5652                (match_operand:DI 2 "se_arith_operand" "")))]
5653   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5654   [(set (match_dup 0)
5655         (lt:DI (match_dup 1)
5656                (match_dup 2)))
5657    (set (match_dup 0)
5658         (xor:DI (match_dup 0)
5659                 (const_int 1)))]
5660   "")
5661
5662 (define_expand "slt"
5663   [(set (match_operand:SI 0 "register_operand" "=d")
5664         (lt:SI (match_dup 1)
5665                (match_dup 2)))]
5666   ""
5667   "
5668 {
5669   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5670     FAIL;
5671
5672   /* set up operands from compare.  */
5673   operands[1] = branch_cmp[0];
5674   operands[2] = branch_cmp[1];
5675
5676   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5677     {
5678       gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
5679       DONE;
5680     }
5681
5682   /* fall through and generate default code */
5683 }")
5684
5685 (define_insn "slt_si"
5686   [(set (match_operand:SI 0 "register_operand" "=d")
5687         (lt:SI (match_operand:SI 1 "register_operand" "d")
5688                (match_operand:SI 2 "arith_operand" "dI")))]
5689   ""
5690   "slt\\t%0,%1,%2"
5691   [(set_attr "type"     "arith")
5692    (set_attr "mode"     "SI")
5693    (set_attr "length"   "1")])
5694
5695 (define_insn "slt_di"
5696   [(set (match_operand:DI 0 "register_operand" "=d")
5697         (lt:DI (match_operand:DI 1 "se_register_operand" "d")
5698                (match_operand:DI 2 "se_arith_operand" "dI")))]
5699   "TARGET_64BIT"
5700   "slt\\t%0,%1,%2"
5701   [(set_attr "type"     "arith")
5702    (set_attr "mode"     "DI")
5703    (set_attr "length"   "1")])
5704
5705 (define_expand "sle"
5706   [(set (match_operand:SI 0 "register_operand" "=d")
5707         (le:SI (match_dup 1)
5708                (match_dup 2)))]
5709   ""
5710   "
5711 {
5712   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5713     FAIL;
5714
5715   /* set up operands from compare.  */
5716   operands[1] = branch_cmp[0];
5717   operands[2] = branch_cmp[1];
5718
5719   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5720     {
5721       gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
5722       DONE;
5723     }
5724
5725   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
5726     operands[2] = force_reg (SImode, operands[2]);
5727
5728   /* fall through and generate default code */
5729 }")
5730
5731 (define_insn "sle_si_const"
5732   [(set (match_operand:SI 0 "register_operand" "=d")
5733         (le:SI (match_operand:SI 1 "register_operand" "d")
5734                (match_operand:SI 2 "small_int" "I")))]
5735   "INTVAL (operands[2]) < 32767"
5736   "*
5737 {
5738   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
5739   return \"slt\\t%0,%1,%2\";
5740 }"
5741   [(set_attr "type"     "arith")
5742    (set_attr "mode"     "SI")
5743    (set_attr "length"   "1")])
5744
5745 (define_insn "sle_di_const"
5746   [(set (match_operand:DI 0 "register_operand" "=d")
5747         (le:DI (match_operand:DI 1 "se_register_operand" "d")
5748                (match_operand:DI 2 "small_int" "I")))]
5749   "TARGET_64BIT && INTVAL (operands[2]) < 32767"
5750   "*
5751 {
5752   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
5753   return \"slt\\t%0,%1,%2\";
5754 }"
5755   [(set_attr "type"     "arith")
5756    (set_attr "mode"     "DI")
5757    (set_attr "length"   "1")])
5758
5759 (define_insn "sle_si_reg"
5760   [(set (match_operand:SI 0 "register_operand" "=d")
5761         (le:SI (match_operand:SI 1 "register_operand" "d")
5762                (match_operand:SI 2 "register_operand" "d")))]
5763   "TARGET_DEBUG_C_MODE"
5764   "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
5765   [(set_attr "type"     "arith")
5766    (set_attr "mode"     "SI")
5767    (set_attr "length"   "2")])
5768
5769 (define_split
5770   [(set (match_operand:SI 0 "register_operand" "")
5771         (le:SI (match_operand:SI 1 "register_operand" "")
5772                (match_operand:SI 2 "register_operand" "")))]
5773   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5774   [(set (match_dup 0)
5775         (lt:SI (match_dup 2)
5776                (match_dup 1)))
5777    (set (match_dup 0)
5778         (xor:SI (match_dup 0)
5779                 (const_int 1)))]
5780   "")
5781
5782 (define_insn "sle_di_reg"
5783   [(set (match_operand:DI 0 "register_operand" "=d")
5784         (le:DI (match_operand:DI 1 "se_register_operand" "d")
5785                (match_operand:DI 2 "se_register_operand" "d")))]
5786   "TARGET_64BIT && TARGET_DEBUG_C_MODE"
5787   "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
5788   [(set_attr "type"     "arith")
5789    (set_attr "mode"     "DI")
5790    (set_attr "length"   "2")])
5791
5792 (define_split
5793   [(set (match_operand:DI 0 "register_operand" "")
5794         (le:DI (match_operand:DI 1 "se_register_operand" "")
5795                (match_operand:DI 2 "se_register_operand" "")))]
5796   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5797   [(set (match_dup 0)
5798         (lt:DI (match_dup 2)
5799                (match_dup 1)))
5800    (set (match_dup 0)
5801         (xor:DI (match_dup 0)
5802                 (const_int 1)))]
5803   "")
5804
5805 (define_expand "sgtu"
5806   [(set (match_operand:SI 0 "register_operand" "=d")
5807         (gtu:SI (match_dup 1)
5808                 (match_dup 2)))]
5809   ""
5810   "
5811 {
5812   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5813     FAIL;
5814
5815   /* set up operands from compare.  */
5816   operands[1] = branch_cmp[0];
5817   operands[2] = branch_cmp[1];
5818
5819   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5820     {
5821       gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
5822       DONE;
5823     }
5824
5825   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
5826     operands[2] = force_reg (SImode, operands[2]);
5827
5828   /* fall through and generate default code */
5829 }")
5830
5831 (define_insn "sgtu_si"
5832   [(set (match_operand:SI 0 "register_operand" "=d")
5833         (gtu:SI (match_operand:SI 1 "register_operand" "d")
5834                 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
5835   ""
5836   "sltu\\t%0,%z2,%1"
5837   [(set_attr "type"     "arith")
5838    (set_attr "mode"     "SI")
5839    (set_attr "length"   "1")])
5840
5841 (define_insn "sgtu_di"
5842   [(set (match_operand:DI 0 "register_operand" "=d")
5843         (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
5844                 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
5845   "TARGET_64BIT"
5846   "sltu\\t%0,%z2,%1"
5847   [(set_attr "type"     "arith")
5848    (set_attr "mode"     "DI")
5849    (set_attr "length"   "1")])
5850
5851 (define_expand "sgeu"
5852   [(set (match_operand:SI 0 "register_operand" "=d")
5853         (geu:SI (match_dup 1)
5854                 (match_dup 2)))]
5855   ""
5856   "
5857 {
5858   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5859     FAIL;
5860
5861   /* set up operands from compare.  */
5862   operands[1] = branch_cmp[0];
5863   operands[2] = branch_cmp[1];
5864
5865   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5866     {
5867       gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
5868       DONE;
5869     }
5870
5871   /* fall through and generate default code */
5872 }")
5873
5874 (define_insn "sgeu_si"
5875   [(set (match_operand:SI 0 "register_operand" "=d")
5876         (geu:SI (match_operand:SI 1 "register_operand" "d")
5877                 (match_operand:SI 2 "arith_operand" "dI")))]
5878   "TARGET_DEBUG_C_MODE"
5879   "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
5880   [(set_attr "type"     "arith")
5881    (set_attr "mode"     "SI")
5882    (set_attr "length"   "2")])
5883
5884 (define_split
5885   [(set (match_operand:SI 0 "register_operand" "")
5886         (geu:SI (match_operand:SI 1 "register_operand" "")
5887                 (match_operand:SI 2 "arith_operand" "")))]
5888   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5889   [(set (match_dup 0)
5890         (ltu:SI (match_dup 1)
5891                 (match_dup 2)))
5892    (set (match_dup 0)
5893         (xor:SI (match_dup 0)
5894                 (const_int 1)))]
5895   "")
5896
5897 (define_insn "sgeu_di"
5898   [(set (match_operand:DI 0 "register_operand" "=d")
5899         (geu:DI (match_operand:DI 1 "se_register_operand" "d")
5900                 (match_operand:DI 2 "se_arith_operand" "dI")))]
5901   "TARGET_64BIT && TARGET_DEBUG_C_MODE"
5902   "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
5903   [(set_attr "type"     "arith")
5904    (set_attr "mode"     "DI")
5905    (set_attr "length"   "2")])
5906
5907 (define_split
5908   [(set (match_operand:DI 0 "register_operand" "")
5909         (geu:DI (match_operand:DI 1 "se_register_operand" "")
5910                 (match_operand:DI 2 "se_arith_operand" "")))]
5911   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5912   [(set (match_dup 0)
5913         (ltu:DI (match_dup 1)
5914                 (match_dup 2)))
5915    (set (match_dup 0)
5916         (xor:DI (match_dup 0)
5917                 (const_int 1)))]
5918   "")
5919
5920 (define_expand "sltu"
5921   [(set (match_operand:SI 0 "register_operand" "=d")
5922         (ltu:SI (match_dup 1)
5923                 (match_dup 2)))]
5924   ""
5925   "
5926 {
5927   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5928     FAIL;
5929
5930   /* set up operands from compare.  */
5931   operands[1] = branch_cmp[0];
5932   operands[2] = branch_cmp[1];
5933
5934   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5935     {
5936       gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
5937       DONE;
5938     }
5939
5940   /* fall through and generate default code */
5941 }")
5942
5943 (define_insn "sltu_si"
5944   [(set (match_operand:SI 0 "register_operand" "=d")
5945         (ltu:SI (match_operand:SI 1 "register_operand" "d")
5946                 (match_operand:SI 2 "arith_operand" "dI")))]
5947   ""
5948   "sltu\\t%0,%1,%2"
5949   [(set_attr "type"     "arith")
5950    (set_attr "mode"     "SI")
5951    (set_attr "length"   "1")])
5952
5953 (define_insn "sltu_di"
5954   [(set (match_operand:DI 0 "register_operand" "=d")
5955         (ltu:DI (match_operand:DI 1 "se_register_operand" "d")
5956                 (match_operand:DI 2 "se_arith_operand" "dI")))]
5957   "TARGET_64BIT"
5958   "sltu\\t%0,%1,%2"
5959   [(set_attr "type"     "arith")
5960    (set_attr "mode"     "DI")
5961    (set_attr "length"   "1")])
5962
5963 (define_expand "sleu"
5964   [(set (match_operand:SI 0 "register_operand" "=d")
5965         (leu:SI (match_dup 1)
5966                 (match_dup 2)))]
5967   ""
5968   "
5969 {
5970   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5971     FAIL;
5972
5973   /* set up operands from compare.  */
5974   operands[1] = branch_cmp[0];
5975   operands[2] = branch_cmp[1];
5976
5977   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5978     {
5979       gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
5980       DONE;
5981     }
5982
5983   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
5984     operands[2] = force_reg (SImode, operands[2]);
5985
5986   /* fall through and generate default code */
5987 }")
5988
5989 (define_insn "sleu_si_const"
5990   [(set (match_operand:SI 0 "register_operand" "=d")
5991         (leu:SI (match_operand:SI 1 "register_operand" "d")
5992                 (match_operand:SI 2 "small_int" "I")))]
5993   "INTVAL (operands[2]) < 32767"
5994   "*
5995 {
5996   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
5997   return \"sltu\\t%0,%1,%2\";
5998 }"
5999   [(set_attr "type"     "arith")
6000    (set_attr "mode"     "SI")
6001    (set_attr "length"   "1")])
6002
6003 (define_insn "sleu_di_const"
6004   [(set (match_operand:DI 0 "register_operand" "=d")
6005         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
6006                 (match_operand:DI 2 "small_int" "I")))]
6007   "TARGET_64BIT && INTVAL (operands[2]) < 32767"
6008   "*
6009 {
6010   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
6011   return \"sltu\\t%0,%1,%2\";
6012 }"
6013   [(set_attr "type"     "arith")
6014    (set_attr "mode"     "DI")
6015    (set_attr "length"   "1")])
6016
6017 (define_insn "sleu_si_reg"
6018   [(set (match_operand:SI 0 "register_operand" "=d")
6019         (leu:SI (match_operand:SI 1 "register_operand" "d")
6020                 (match_operand:SI 2 "register_operand" "d")))]
6021   "TARGET_DEBUG_C_MODE"
6022   "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
6023   [(set_attr "type"     "arith")
6024    (set_attr "mode"     "SI")
6025    (set_attr "length"   "2")])
6026
6027 (define_split
6028   [(set (match_operand:SI 0 "register_operand" "")
6029         (leu:SI (match_operand:SI 1 "register_operand" "")
6030                 (match_operand:SI 2 "register_operand" "")))]
6031   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
6032   [(set (match_dup 0)
6033         (ltu:SI (match_dup 2)
6034                 (match_dup 1)))
6035    (set (match_dup 0)
6036         (xor:SI (match_dup 0)
6037                 (const_int 1)))]
6038   "")
6039
6040 (define_insn "sleu_di_reg"
6041   [(set (match_operand:DI 0 "register_operand" "=d")
6042         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
6043                 (match_operand:DI 2 "se_register_operand" "d")))]
6044   "TARGET_64BIT && TARGET_DEBUG_C_MODE"
6045   "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
6046   [(set_attr "type"     "arith")
6047    (set_attr "mode"     "DI")
6048    (set_attr "length"   "2")])
6049
6050 (define_split
6051   [(set (match_operand:DI 0 "register_operand" "")
6052         (leu:DI (match_operand:DI 1 "se_register_operand" "")
6053                 (match_operand:DI 2 "se_register_operand" "")))]
6054   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
6055   [(set (match_dup 0)
6056         (ltu:DI (match_dup 2)
6057                 (match_dup 1)))
6058    (set (match_dup 0)
6059         (xor:DI (match_dup 0)
6060                 (const_int 1)))]
6061   "")
6062
6063 \f
6064 ;;
6065 ;;  ....................
6066 ;;
6067 ;;      FLOATING POINT COMPARISONS
6068 ;;
6069 ;;  ....................
6070
6071 (define_insn "seq_df"
6072   [(set (match_operand:CC 0 "register_operand" "=z")
6073         (eq:CC (match_operand:DF 1 "register_operand" "f")
6074                (match_operand:DF 2 "register_operand" "f")))]
6075   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6076   "*
6077 {
6078   return mips_fill_delay_slot (\"c.eq.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
6079 }"
6080  [(set_attr "type"      "fcmp")
6081   (set_attr "mode"      "FPSW")
6082   (set_attr "length"    "1")])
6083
6084 (define_insn "slt_df"
6085   [(set (match_operand:CC 0 "register_operand" "=z")
6086         (lt:CC (match_operand:DF 1 "register_operand" "f")
6087                (match_operand:DF 2 "register_operand" "f")))]
6088   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6089   "*
6090 {
6091   return mips_fill_delay_slot (\"c.lt.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
6092 }"
6093  [(set_attr "type"      "fcmp")
6094   (set_attr "mode"      "FPSW")
6095   (set_attr "length"    "1")])
6096
6097 (define_insn "sle_df"
6098   [(set (match_operand:CC 0 "register_operand" "=z")
6099         (le:CC (match_operand:DF 1 "register_operand" "f")
6100                (match_operand:DF 2 "register_operand" "f")))]
6101   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6102   "*
6103 {
6104   return mips_fill_delay_slot (\"c.le.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
6105 }"
6106  [(set_attr "type"      "fcmp")
6107   (set_attr "mode"      "FPSW")
6108   (set_attr "length"    "1")])
6109
6110 (define_insn "sgt_df"
6111   [(set (match_operand:CC 0 "register_operand" "=z")
6112         (gt:CC (match_operand:DF 1 "register_operand" "f")
6113                (match_operand:DF 2 "register_operand" "f")))]
6114   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6115   "*
6116 {
6117   return mips_fill_delay_slot (\"c.lt.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
6118 }"
6119  [(set_attr "type"      "fcmp")
6120   (set_attr "mode"      "FPSW")
6121   (set_attr "length"    "1")])
6122
6123 (define_insn "sge_df"
6124   [(set (match_operand:CC 0 "register_operand" "=z")
6125         (ge:CC (match_operand:DF 1 "register_operand" "f")
6126                (match_operand:DF 2 "register_operand" "f")))]
6127   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6128   "*
6129 {
6130   return mips_fill_delay_slot (\"c.le.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
6131 }"
6132  [(set_attr "type"      "fcmp")
6133   (set_attr "mode"      "FPSW")
6134   (set_attr "length"    "1")])
6135
6136 (define_insn "seq_sf"
6137   [(set (match_operand:CC 0 "register_operand" "=z")
6138         (eq:CC (match_operand:SF 1 "register_operand" "f")
6139                (match_operand:SF 2 "register_operand" "f")))]
6140   "TARGET_HARD_FLOAT"
6141   "*
6142 {
6143   return mips_fill_delay_slot (\"c.eq.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
6144 }"
6145  [(set_attr "type"      "fcmp")
6146   (set_attr "mode"      "FPSW")
6147   (set_attr "length"    "1")])
6148
6149 (define_insn "slt_sf"
6150   [(set (match_operand:CC 0 "register_operand" "=z")
6151         (lt:CC (match_operand:SF 1 "register_operand" "f")
6152                (match_operand:SF 2 "register_operand" "f")))]
6153   "TARGET_HARD_FLOAT"
6154   "*
6155 {
6156   return mips_fill_delay_slot (\"c.lt.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
6157 }"
6158  [(set_attr "type"      "fcmp")
6159   (set_attr "mode"      "FPSW")
6160   (set_attr "length"    "1")])
6161
6162 (define_insn "sle_sf"
6163   [(set (match_operand:CC 0 "register_operand" "=z")
6164         (le:CC (match_operand:SF 1 "register_operand" "f")
6165                (match_operand:SF 2 "register_operand" "f")))]
6166   "TARGET_HARD_FLOAT"
6167   "*
6168 {
6169   return mips_fill_delay_slot (\"c.le.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
6170 }"
6171  [(set_attr "type"      "fcmp")
6172   (set_attr "mode"      "FPSW")
6173   (set_attr "length"    "1")])
6174
6175 (define_insn "sgt_sf"
6176   [(set (match_operand:CC 0 "register_operand" "=z")
6177         (gt:CC (match_operand:SF 1 "register_operand" "f")
6178                (match_operand:SF 2 "register_operand" "f")))]
6179   "TARGET_HARD_FLOAT"
6180   "*
6181 {
6182   return mips_fill_delay_slot (\"c.lt.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
6183 }"
6184  [(set_attr "type"      "fcmp")
6185   (set_attr "mode"      "FPSW")
6186   (set_attr "length"    "1")])
6187
6188 (define_insn "sge_sf"
6189   [(set (match_operand:CC 0 "register_operand" "=z")
6190         (ge:CC (match_operand:SF 1 "register_operand" "f")
6191                (match_operand:SF 2 "register_operand" "f")))]
6192   "TARGET_HARD_FLOAT"
6193   "*
6194 {
6195   return mips_fill_delay_slot (\"c.le.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
6196 }"
6197  [(set_attr "type"      "fcmp")
6198   (set_attr "mode"      "FPSW")
6199   (set_attr "length"    "1")])
6200
6201 \f
6202 ;;
6203 ;;  ....................
6204 ;;
6205 ;;      UNCONDITIONAL BRANCHES
6206 ;;
6207 ;;  ....................
6208
6209 ;; Unconditional branches.
6210
6211 (define_insn "jump"
6212   [(set (pc)
6213         (label_ref (match_operand 0 "" "")))]
6214   ""
6215   "*
6216 {
6217   if (GET_CODE (operands[0]) == REG)
6218     return \"%*j\\t%0\";
6219   /* ??? I don't know why this is necessary.  This works around an
6220      assembler problem that appears when a label is defined, then referenced
6221      in a switch table, then used in a `j' instruction.  */
6222   else if (mips_abi != ABI_32)
6223     return \"%*b\\t%l0\";
6224   else  
6225     return \"%*j\\t%l0\";
6226 }"
6227   [(set_attr "type"     "jump")
6228    (set_attr "mode"     "none")
6229    (set_attr "length"   "1")])
6230
6231 (define_expand "indirect_jump"
6232   [(set (pc) (match_operand 0 "register_operand" "d"))]
6233   ""
6234   "
6235 {
6236   rtx dest;
6237
6238   if (operands[0])              /* eliminate unused code warnings */
6239     {
6240       dest = operands[0];
6241       if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
6242         operands[0] = copy_to_mode_reg (Pmode, dest);
6243
6244       if (!TARGET_LONG64)
6245         emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
6246       else
6247         emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
6248
6249       DONE;
6250     }
6251 }")
6252
6253 (define_insn "indirect_jump_internal1"
6254   [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
6255   "!TARGET_LONG64"
6256   "%*j\\t%0"
6257   [(set_attr "type"     "jump")
6258    (set_attr "mode"     "none")
6259    (set_attr "length"   "1")])
6260
6261 (define_insn "indirect_jump_internal2"
6262   [(set (pc) (match_operand:DI 0 "se_register_operand" "d"))]
6263   "TARGET_LONG64"
6264   "%*j\\t%0"
6265   [(set_attr "type"     "jump")
6266    (set_attr "mode"     "none")
6267    (set_attr "length"   "1")])
6268
6269 (define_expand "tablejump"
6270   [(set (pc)
6271         (match_operand 0 "register_operand" "d"))
6272    (use (label_ref (match_operand 1 "" "")))]
6273   ""
6274   "
6275 {
6276   rtx dest;
6277
6278   if (operands[0])              /* eliminate unused code warnings */
6279     {
6280       if (GET_MODE (operands[0]) != Pmode)
6281         abort ();
6282
6283       if (! flag_pic)
6284         {
6285           if (!TARGET_LONG64)
6286             emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
6287           else
6288             emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
6289         }
6290       else
6291         {
6292           if (!TARGET_LONG64)
6293             emit_jump_insn (gen_tablejump_internal3 (operands[0], operands[1]));
6294           else
6295             emit_jump_insn (gen_tablejump_internal4 (operands[0], operands[1]));
6296         }
6297
6298       DONE;
6299     }
6300 }")
6301
6302 (define_insn "tablejump_internal1"
6303   [(set (pc)
6304         (match_operand:SI 0 "register_operand" "d"))
6305    (use (label_ref (match_operand 1 "" "")))]
6306   "!TARGET_LONG64"
6307   "%*j\\t%0"
6308   [(set_attr "type"     "jump")
6309    (set_attr "mode"     "none")
6310    (set_attr "length"   "1")])
6311
6312 (define_insn "tablejump_internal2"
6313   [(set (pc)
6314         (match_operand:DI 0 "se_register_operand" "d"))
6315    (use (label_ref (match_operand 1 "" "")))]
6316   "TARGET_LONG64"
6317   "%*j\\t%0"
6318   [(set_attr "type"     "jump")
6319    (set_attr "mode"     "none")
6320    (set_attr "length"   "1")])
6321
6322 (define_expand "tablejump_internal3"
6323   [(set (pc)
6324         (plus:SI (match_operand:SI 0 "register_operand" "d")
6325                  (label_ref:SI (match_operand:SI 1 "" ""))))]
6326   ""
6327   "")
6328
6329 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC.  Otherwise
6330 ;;; it is not valid.
6331
6332 ;;; ??? The length depends on the ABI.  It is two for o32, and one for n32.
6333 ;;; We just use the conservative number here.
6334
6335 (define_insn ""
6336   [(set (pc)
6337         (plus:SI (match_operand:SI 0 "register_operand" "d")
6338                  (label_ref:SI (match_operand:SI 1 "" ""))))]
6339   "!TARGET_LONG64 && next_active_insn (insn) != 0
6340    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
6341    && PREV_INSN (next_active_insn (insn)) == operands[1]"
6342   "*
6343 {
6344   /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic.  */
6345   if (mips_abi == ABI_32)
6346     output_asm_insn (\".cpadd\\t%0\", operands);
6347   return \"%*j\\t%0\";
6348 }"
6349   [(set_attr "type"     "jump")
6350    (set_attr "mode"     "none")
6351    (set_attr "length"   "2")])
6352
6353 (define_expand "tablejump_internal4"
6354   [(set (pc)
6355         (plus:DI (match_operand:DI 0 "se_register_operand" "d")
6356                  (label_ref:DI (match_operand:SI 1 "" ""))))]
6357   ""
6358   "")
6359
6360 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC.  Otherwise
6361 ;;; it is not valid.
6362
6363 (define_insn ""
6364   [(set (pc)
6365         (plus:DI (match_operand:DI 0 "se_register_operand" "d")
6366                  (label_ref:DI (match_operand:SI 1 "" ""))))]
6367   "TARGET_LONG64 && next_active_insn (insn) != 0
6368    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
6369    && PREV_INSN (next_active_insn (insn)) == operands[1]"
6370   "%*j\\t%0"
6371   [(set_attr "type"     "jump")
6372    (set_attr "mode"     "none")
6373    (set_attr "length"   "1")])
6374
6375 ;; Implement a switch statement when generating embedded PIC code.
6376 ;; Switches are implemented by `tablejump' when not using -membedded-pic.
6377
6378 (define_expand "casesi"
6379   [(set (match_dup 5)
6380         (minus:SI (match_operand:SI 0 "register_operand" "d")
6381                   (match_operand:SI 1 "arith_operand" "dI")))
6382    (set (cc0)
6383         (compare:CC (match_dup 5)
6384                     (match_operand:SI 2 "arith_operand" "")))
6385    (set (pc)
6386         (if_then_else (gtu (cc0)
6387                            (const_int 0))
6388                       (label_ref (match_operand 4 "" ""))
6389                       (pc)))
6390    (parallel
6391     [(set (pc)
6392           (mem:SI (plus:SI (mult:SI (match_dup 5)
6393                                     (const_int 4))
6394                            (label_ref (match_operand 3 "" "")))))
6395      (clobber (match_scratch:SI 6 ""))
6396      (clobber (reg:SI 31))])]
6397   "TARGET_EMBEDDED_PIC"
6398   "
6399 {
6400   /* We need slightly different code for eight byte table entries.  */
6401   if (TARGET_LONG64)
6402     abort ();
6403
6404   if (operands[0])
6405     {
6406       rtx reg = gen_reg_rtx (SImode);
6407
6408       /* If the index is too large, go to the default label.  */
6409       emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
6410       emit_insn (gen_cmpsi (reg, operands[2]));
6411       emit_insn (gen_bgtu (operands[4]));
6412
6413       /* Do the PIC jump.  */
6414       emit_insn (gen_casesi_internal (reg, operands[3], gen_reg_rtx (SImode)));
6415
6416       DONE;
6417     }
6418 }")
6419
6420 ;; An embedded PIC switch statement looks like this:
6421 ;;      bal     $LS1
6422 ;;      sll     $reg,$index,2
6423 ;; $LS1:
6424 ;;      addu    $reg,$reg,$31
6425 ;;      lw      $reg,$L1-$LS1($reg)
6426 ;;      addu    $reg,$reg,$31
6427 ;;      j       $reg
6428 ;; $L1:
6429 ;;      .word   case1-$LS1
6430 ;;      .word   case2-$LS1
6431 ;;      ...
6432
6433 (define_insn "casesi_internal"
6434   [(set (pc)
6435         (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
6436                                   (const_int 4))
6437                          (label_ref (match_operand 1 "" "")))))
6438    (clobber (match_operand:SI 2 "register_operand" "d"))
6439    (clobber (reg:SI 31))]
6440   "TARGET_EMBEDDED_PIC"
6441   "*
6442 {
6443   output_asm_insn (\"%(bal\\t%S1\;sll\\t%0,2\\n%S1:\", operands);
6444   output_asm_insn (\"addu\\t%0,%0,$31%)\", operands);
6445   output_asm_insn (\"lw\\t%0,%1-%S1(%0)\;addu\\t%0,%0,$31\", operands);
6446   return \"j\\t%0\";
6447 }"
6448   [(set_attr "type"     "jump")
6449    (set_attr "mode"     "none")
6450    (set_attr "length"   "6")])
6451
6452 ;; ??? This is a hack to work around a problem with expand_builtin_setjmp.
6453 ;; It restores the frame pointer, and then does a call to restore the global
6454 ;; pointer (gp) register.  The call insn implicitly (via the assembler) reloads
6455 ;; gp from the stack.  However, call insns do not depend on $fp, so it is
6456 ;; possible for the instruction scheduler to move the fp restore after the
6457 ;; call, which then causes gp to be corrupted.  We fix this by emitting a
6458 ;; scheduler barrier.  A better fix is to put code here that restores the
6459 ;; $gp, and then the call is unnecessary.  This is only a problem when PIC
6460 ;; (TARGET_ABICALLS), and only when the gp register is caller-saved
6461 ;; (irix5/o32, but not irix6/n32/n64).
6462
6463 (define_expand "nonlocal_goto_receiver"
6464   [(const_int 0)]
6465   ""
6466   "
6467 {
6468   emit_insn (gen_blockage ());
6469 }")
6470 \f
6471 ;;
6472 ;;  ....................
6473 ;;
6474 ;;      Function prologue/epilogue
6475 ;;
6476 ;;  ....................
6477 ;;
6478
6479 (define_expand "prologue"
6480   [(const_int 1)]
6481   ""
6482   "
6483 {
6484   if (mips_isa >= 0)            /* avoid unused code warnings */
6485     {
6486       mips_expand_prologue ();
6487       DONE;
6488     }
6489 }")
6490
6491 ;; Block any insns from being moved before this point, since the
6492 ;; profiling call to mcount can use various registers that aren't
6493 ;; saved or used to pass arguments.
6494
6495 (define_insn "blockage"
6496   [(unspec_volatile [(const_int 0)] 0)]
6497   ""
6498   ""
6499   [(set_attr "type"     "unknown")
6500    (set_attr "mode"     "none")
6501    (set_attr "length"   "0")])
6502
6503 (define_expand "epilogue"
6504   [(const_int 2)]
6505   ""
6506   "
6507 {
6508   if (mips_isa >= 0)            /* avoid unused code warnings */
6509     {
6510       mips_expand_epilogue ();
6511       DONE;
6512     }
6513 }")
6514
6515 ;; Trivial return.  Make it look like a normal return insn as that
6516 ;; allows jump optimizations to work better .
6517 (define_insn "return"
6518   [(return)]
6519   "mips_can_use_return_insn ()"
6520   "%*j\\t$31"
6521   [(set_attr "type"     "jump")
6522    (set_attr "mode"     "none")
6523    (set_attr "length"   "1")])
6524
6525 ;; Normal return.
6526 (define_insn "return_internal"
6527   [(use (reg:SI 31))
6528    (return)]
6529   ""
6530   "%*j\\t$31"
6531   [(set_attr "type"     "jump")
6532    (set_attr "mode"     "none")
6533    (set_attr "length"   "1")])
6534   
6535 ;; When generating embedded PIC code we need to get the address of the
6536 ;; current function.  This specialized instruction does just that.
6537
6538 (define_insn "get_fnaddr"
6539   [(set (match_operand 0 "register_operand" "=d")
6540         (unspec [(match_operand 1 "" "")] 1))
6541    (clobber (reg:SI 31))]
6542   "TARGET_EMBEDDED_PIC
6543    && GET_CODE (operands[1]) == SYMBOL_REF"
6544   "%($LF%= = . + 8\;bal\\t$LF%=\;la\\t%0,%1-$LF%=%)\;addu\\t%0,%0,$31"
6545   [(set_attr "type"     "call")
6546    (set_attr "mode"     "none")
6547    (set_attr "length"   "4")])
6548
6549 \f
6550 ;;
6551 ;;  ....................
6552 ;;
6553 ;;      FUNCTION CALLS
6554 ;;
6555 ;;  ....................
6556
6557 ;; calls.c now passes a third argument, make saber happy
6558
6559 (define_expand "call"
6560   [(parallel [(call (match_operand 0 "memory_operand" "m")
6561                     (match_operand 1 "" "i"))
6562               (clobber (reg:SI 31))
6563               (use (match_operand 2 "" ""))             ;; next_arg_reg
6564               (use (match_operand 3 "" ""))])]          ;; struct_value_size_rtx
6565   ""
6566   "
6567 {
6568   rtx addr;
6569
6570   if (operands[0])              /* eliminate unused code warnings */
6571     {
6572       addr = XEXP (operands[0], 0);
6573       if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
6574           || ! call_insn_operand (addr, VOIDmode))
6575         XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
6576
6577       /* In order to pass small structures by value in registers
6578          compatibly with the MIPS compiler, we need to shift the value
6579          into the high part of the register.  Function_arg has encoded
6580          a PARALLEL rtx, holding a vector of adjustments to be made
6581          as the next_arg_reg variable, so we split up the insns,
6582          and emit them separately.  */
6583
6584       if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL)
6585         {
6586           rtvec adjust = XVEC (operands[2], 0);
6587           int num = GET_NUM_ELEM (adjust);
6588           int i;
6589
6590           for (i = 0; i < num; i++)
6591             emit_insn (RTVEC_ELT (adjust, i));
6592         }
6593
6594       emit_call_insn (gen_call_internal0 (operands[0], operands[1],
6595                                           gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
6596       DONE;
6597     }
6598 }")
6599
6600 (define_expand "call_internal0"
6601   [(parallel [(call (match_operand 0 "" "")
6602                     (match_operand 1 "" ""))
6603               (clobber (match_operand:SI 2 "" ""))])]
6604   ""
6605   "")
6606
6607 (define_insn "call_internal1"
6608   [(call (mem (match_operand 0 "call_insn_operand" "ri"))
6609          (match_operand 1 "" "i"))
6610    (clobber (match_operand:SI 2 "register_operand" "=d"))]
6611   "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
6612   "*
6613 {
6614   register rtx target = operands[0];
6615
6616   if (GET_CODE (target) == SYMBOL_REF)
6617     return \"%*jal\\t%0\";
6618   else if (GET_CODE (target) == CONST_INT)
6619     return \"%[li\\t%@,%0\\n\\t%*jal\\t%2,%@%]\";
6620   else
6621     return \"%*jal\\t%2,%0\";
6622 }"
6623   [(set_attr "type"     "call")
6624    (set_attr "mode"     "none")
6625    (set_attr "length"   "1")])
6626
6627 (define_insn "call_internal2"
6628   [(call (mem (match_operand 0 "call_insn_operand" "ri"))
6629          (match_operand 1 "" "i"))
6630    (clobber (match_operand:SI 2 "register_operand" "=d"))]
6631   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
6632   "*
6633 {
6634   register rtx target = operands[0];
6635
6636   if (GET_CODE (target) == SYMBOL_REF)
6637     {
6638       if (GET_MODE (target) == SImode)
6639         return \"la\\t%^,%0\\n\\tjal\\t%2,%^\";
6640       else
6641         return \"dla\\t%^,%0\\n\\tjal\\t%2,%^\";
6642     }
6643   else if (GET_CODE (target) == CONST_INT)
6644     return \"li\\t%^,%0\\n\\tjal\\t%2,%^\";
6645   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
6646     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
6647   else
6648     return \"jal\\t%2,%0\";
6649 }"
6650   [(set_attr "type"     "call")
6651    (set_attr "mode"     "none")
6652    (set_attr "length"   "2")])
6653
6654 (define_insn "call_internal3a"
6655   [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
6656          (match_operand 1 "" "i"))
6657    (clobber (match_operand:SI 2 "register_operand" "=d"))]
6658   "!TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
6659   "%*jal\\t%2,%0"
6660   [(set_attr "type"     "call")
6661    (set_attr "mode"     "none")
6662    (set_attr "length"   "1")])
6663
6664 (define_insn "call_internal3b"
6665   [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
6666          (match_operand 1 "" "i"))
6667    (clobber (match_operand:SI 2 "register_operand" "=d"))]
6668   "TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
6669   "%*jal\\t%2,%0"
6670   [(set_attr "type"     "call")
6671    (set_attr "mode"     "none")
6672    (set_attr "length"   "1")])
6673
6674 (define_insn "call_internal4a"
6675   [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
6676          (match_operand 1 "" "i"))
6677    (clobber (match_operand:SI 2 "register_operand" "=d"))]
6678   "!TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
6679   "*
6680 {
6681   if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
6682     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
6683   else
6684     return \"jal\\t%2,%0\";
6685 }"
6686   [(set_attr "type"     "call")
6687    (set_attr "mode"     "none")
6688    (set_attr "length"   "2")])
6689
6690 (define_insn "call_internal4b"
6691   [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
6692          (match_operand 1 "" "i"))
6693    (clobber (match_operand:SI 2 "register_operand" "=d"))]
6694   "TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
6695   "*
6696 {
6697   if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
6698     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
6699   else
6700     return \"jal\\t%2,%0\";
6701 }"
6702   [(set_attr "type"     "call")
6703    (set_attr "mode"     "none")
6704    (set_attr "length"   "2")])
6705
6706 ;; calls.c now passes a fourth argument, make saber happy
6707
6708 (define_expand "call_value"
6709   [(parallel [(set (match_operand 0 "register_operand" "=df")
6710                    (call (match_operand 1 "memory_operand" "m")
6711                          (match_operand 2 "" "i")))
6712               (clobber (reg:SI 31))
6713               (use (match_operand 3 "" ""))])]          ;; next_arg_reg
6714   ""
6715   "
6716 {
6717   rtx addr;
6718
6719   if (operands[0])              /* eliminate unused code warning */
6720     {
6721       addr = XEXP (operands[1], 0);
6722       if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
6723           || ! call_insn_operand (addr, VOIDmode))
6724         XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
6725
6726       /* In order to pass small structures by value in registers
6727          compatibly with the MIPS compiler, we need to shift the value
6728          into the high part of the register.  Function_arg has encoded
6729          a PARALLEL rtx, holding a vector of adjustments to be made
6730          as the next_arg_reg variable, so we split up the insns,
6731          and emit them separately.  */
6732
6733       if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL)
6734         {
6735           rtvec adjust = XVEC (operands[3], 0);
6736           int num = GET_NUM_ELEM (adjust);
6737           int i;
6738
6739           for (i = 0; i < num; i++)
6740             emit_insn (RTVEC_ELT (adjust, i));
6741         }
6742
6743       /* Handle Irix6 function calls that have multiple non-contiguous
6744          results.  */
6745       if (GET_CODE (operands[0]) == PARALLEL && XVECLEN (operands[0], 0) > 1)
6746         {
6747           emit_call_insn (gen_call_value_multiple_internal0
6748                           (XEXP (XVECEXP (operands[0], 0, 0), 0),
6749                            operands[1], operands[2],
6750                            XEXP (XVECEXP (operands[0], 0, 1), 0),
6751                            gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
6752           DONE;
6753         }
6754
6755       /* We have a call returning a DImode structure in an FP reg.
6756          Strip off the now unnecessary PARALLEL.  */
6757       if (GET_CODE (operands[0]) == PARALLEL)
6758         operands[0] = XEXP (XVECEXP (operands[0], 0, 0), 0);
6759
6760       emit_call_insn (gen_call_value_internal0 (operands[0], operands[1], operands[2],
6761                                                 gen_rtx (REG, SImode, GP_REG_FIRST + 31)));
6762
6763       DONE;
6764     }
6765 }")
6766
6767 (define_expand "call_value_internal0"
6768   [(parallel [(set (match_operand 0 "" "")
6769                    (call (match_operand 1 "" "")
6770                          (match_operand 2 "" "")))
6771               (clobber (match_operand:SI 3 "" ""))])]
6772   ""
6773   "")
6774
6775 (define_insn "call_value_internal1"
6776   [(set (match_operand 0 "register_operand" "=df")
6777         (call (mem (match_operand 1 "call_insn_operand" "ri"))
6778               (match_operand 2 "" "i")))
6779    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6780   "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
6781   "*
6782 {
6783   register rtx target = operands[1];
6784
6785   if (GET_CODE (target) == SYMBOL_REF)
6786     return \"%*jal\\t%1\";
6787   else if (GET_CODE (target) == CONST_INT)
6788     return \"%[li\\t%@,%1\\n\\t%*jal\\t%3,%@%]\";
6789   else
6790     return \"%*jal\\t%3,%1\";
6791 }"
6792   [(set_attr "type"     "call")
6793    (set_attr "mode"     "none")
6794    (set_attr "length"   "1")])
6795
6796 (define_insn "call_value_internal2"
6797   [(set (match_operand 0 "register_operand" "=df")
6798         (call (mem (match_operand 1 "call_insn_operand" "ri"))
6799               (match_operand 2 "" "i")))
6800    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6801   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
6802   "*
6803 {
6804   register rtx target = operands[1];
6805
6806   if (GET_CODE (target) == SYMBOL_REF)
6807     {
6808       if (GET_MODE (target) == SImode)
6809         return \"la\\t%^,%1\\n\\tjal\\t%3,%^\";
6810       else
6811         return \"dla\\t%^,%1\\n\\tjal\\t%3,%^\";
6812     }
6813   else if (GET_CODE (target) == CONST_INT)
6814     return \"li\\t%^,%1\\n\\tjal\\t%3,%^\";
6815   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
6816     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
6817   else
6818     return \"jal\\t%3,%1\";
6819 }"
6820   [(set_attr "type"     "call")
6821    (set_attr "mode"     "none")
6822    (set_attr "length"   "2")])
6823
6824 (define_insn "call_value_internal3a"
6825   [(set (match_operand 0 "register_operand" "=df")
6826         (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
6827               (match_operand 2 "" "i")))
6828    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6829   "!TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
6830   "%*jal\\t%3,%1"
6831   [(set_attr "type"     "call")
6832    (set_attr "mode"     "none")
6833    (set_attr "length"   "1")])
6834
6835 (define_insn "call_value_internal3b"
6836   [(set (match_operand 0 "register_operand" "=df")
6837         (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
6838               (match_operand 2 "" "i")))
6839    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6840   "TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
6841   "%*jal\\t%3,%1"
6842   [(set_attr "type"     "call")
6843    (set_attr "mode"     "none")
6844    (set_attr "length"   "1")])
6845
6846 (define_insn "call_value_internal4a"
6847   [(set (match_operand 0 "register_operand" "=df")
6848         (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
6849               (match_operand 2 "" "i")))
6850    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6851   "!TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
6852   "*
6853 {
6854   if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
6855     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
6856   else
6857     return \"jal\\t%3,%1\";
6858 }"
6859   [(set_attr "type"     "call")
6860    (set_attr "mode"     "none")
6861    (set_attr "length"   "2")])
6862
6863 (define_insn "call_value_internal4b"
6864   [(set (match_operand 0 "register_operand" "=df")
6865         (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
6866               (match_operand 2 "" "i")))
6867    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6868   "TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
6869   "*
6870 {
6871   if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
6872     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
6873   else
6874     return \"jal\\t%3,%1\";
6875 }"
6876   [(set_attr "type"     "call")
6877    (set_attr "mode"     "none")
6878    (set_attr "length"   "2")])
6879
6880 (define_expand "call_value_multiple_internal0"
6881   [(parallel [(set (match_operand 0 "" "")
6882                    (call (match_operand 1 "" "")
6883                          (match_operand 2 "" "")))
6884               (set (match_operand 3 "" "")
6885                    (call (match_dup 1)
6886                          (match_dup 2)))
6887               (clobber (match_operand:SI 4 "" ""))])]
6888   ""
6889   "")
6890
6891 ;; ??? May eventually need all 6 versions of the call patterns with multiple
6892 ;; return values.
6893
6894 (define_insn "call_value_multiple_internal2"
6895   [(set (match_operand 0 "register_operand" "=df")
6896         (call (mem (match_operand 1 "call_insn_operand" "ri"))
6897               (match_operand 2 "" "i")))
6898    (set (match_operand 3 "register_operand" "=df")
6899         (call (mem (match_dup 1))
6900               (match_dup 2)))
6901    (clobber (match_operand:SI 4 "register_operand" "=d"))]
6902   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
6903   "*
6904 {
6905   register rtx target = operands[1];
6906
6907   if (GET_CODE (target) == SYMBOL_REF)
6908     {
6909       if (GET_MODE (target) == SImode)
6910         return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
6911       else
6912         return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
6913     }
6914   else if (GET_CODE (target) == CONST_INT)
6915     return \"li\\t%^,%1\\n\\tjal\\t%4,%^\";
6916   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
6917     return \"move\\t%^,%1\\n\\tjal\\t%4,%^\";
6918   else
6919     return \"jal\\t%4,%1\";
6920 }"
6921   [(set_attr "type"     "call")
6922    (set_attr "mode"     "none")
6923    (set_attr "length"   "2")])
6924
6925
6926 ;; Call subroutine returning any type.
6927
6928 (define_expand "untyped_call"
6929   [(parallel [(call (match_operand 0 "" "")
6930                     (const_int 0))
6931               (match_operand 1 "" "")
6932               (match_operand 2 "" "")])]
6933   ""
6934   "
6935 {
6936   if (operands[0])              /* silence statement not reached warnings */
6937     {
6938       int i;
6939
6940       emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
6941
6942       for (i = 0; i < XVECLEN (operands[2], 0); i++)
6943         {
6944           rtx set = XVECEXP (operands[2], 0, i);
6945           emit_move_insn (SET_DEST (set), SET_SRC (set));
6946         }
6947
6948       emit_insn (gen_blockage ());
6949       DONE;
6950     }
6951 }")
6952 \f
6953 ;;
6954 ;;  ....................
6955 ;;
6956 ;;      MISC.
6957 ;;
6958 ;;  ....................
6959 ;;
6960
6961 (define_insn "nop"
6962   [(const_int 0)]
6963   ""
6964   "%(nop%)"
6965   [(set_attr "type"     "nop")
6966    (set_attr "mode"     "none")
6967    (set_attr "length"   "1")])
6968
6969 ;; The MIPS chip does not seem to require stack probes.
6970 ;;
6971 ;; (define_expand "probe"
6972 ;;   [(set (match_dup 0)
6973 ;;      (match_dup 1))]
6974 ;;   ""
6975 ;;   "
6976 ;; {
6977 ;;   operands[0] = gen_reg_rtx (SImode);
6978 ;;   operands[1] = gen_rtx (MEM, SImode, stack_pointer_rtx);
6979 ;;   MEM_VOLATILE_P (operands[1]) = TRUE;
6980 ;; 
6981 ;;   /* fall through and generate default code */
6982 ;; }")
6983 ;;
6984 \f
6985 ;;
6986 ;; MIPS4 Conditional move instructions.
6987
6988 (define_insn ""
6989   [(set (match_operand:SI 0 "register_operand" "=d,d")
6990         (if_then_else:SI
6991          (match_operator 4 "equality_op"
6992                          [(match_operand:SI 1 "register_operand" "d,d")
6993                           (const_int 0)])
6994          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
6995          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
6996   "mips_isa >= 4"
6997   "@
6998     mov%B4\\t%0,%z2,%1
6999     mov%b4\\t%0,%z3,%1"
7000   [(set_attr "type" "move")
7001    (set_attr "mode" "SI")])
7002
7003 (define_insn ""
7004   [(set (match_operand:SI 0 "register_operand" "=d,d")
7005         (if_then_else:SI
7006          (match_operator 4 "equality_op"
7007                          [(match_operand:DI 1 "se_register_operand" "d,d")
7008                           (const_int 0)])
7009          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
7010          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
7011   "mips_isa >= 4"
7012   "@
7013     mov%B4\\t%0,%z2,%1
7014     mov%b4\\t%0,%z3,%1"
7015   [(set_attr "type" "move")
7016    (set_attr "mode" "SI")])
7017
7018 (define_insn ""
7019   [(set (match_operand:SI 0 "register_operand" "=d,d")
7020         (if_then_else:SI
7021          (match_operator 3 "equality_op" [(match_operand:CC 4
7022                                                             "register_operand"
7023                                                             "z,z")
7024                                           (const_int 0)])
7025          (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
7026          (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
7027   "mips_isa >= 4 && TARGET_HARD_FLOAT"
7028   "@
7029     mov%T3\\t%0,%z1,%4
7030     mov%t3\\t%0,%z2,%4"
7031   [(set_attr "type" "move")
7032    (set_attr "mode" "SI")])
7033
7034 (define_insn ""
7035   [(set (match_operand:DI 0 "register_operand" "=d,d")
7036         (if_then_else:DI
7037          (match_operator 4 "equality_op"
7038                          [(match_operand:SI 1 "register_operand" "d,d")
7039                           (const_int 0)])
7040          (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
7041          (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
7042   "mips_isa >= 4"
7043   "@
7044     mov%B4\\t%0,%z2,%1
7045     mov%b4\\t%0,%z3,%1"
7046   [(set_attr "type" "move")
7047    (set_attr "mode" "DI")])
7048
7049 (define_insn ""
7050   [(set (match_operand:DI 0 "register_operand" "=d,d")
7051         (if_then_else:DI
7052          (match_operator 4 "equality_op"
7053                          [(match_operand:DI 1 "se_register_operand" "d,d")
7054                           (const_int 0)])
7055          (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
7056          (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
7057   "mips_isa >= 4"
7058   "@
7059     mov%B4\\t%0,%z2,%1
7060     mov%b4\\t%0,%z3,%1"
7061   [(set_attr "type" "move")
7062    (set_attr "mode" "DI")])
7063
7064 (define_insn ""
7065   [(set (match_operand:DI 0 "register_operand" "=d,d")
7066         (if_then_else:DI
7067          (match_operator 3 "equality_op" [(match_operand:CC 4
7068                                                             "register_operand"
7069                                                             "z,z")
7070                                           (const_int 0)])
7071          (match_operand:DI 1 "se_reg_or_0_operand" "dJ,0")
7072          (match_operand:DI 2 "se_reg_or_0_operand" "0,dJ")))]
7073   "mips_isa >= 4 && TARGET_HARD_FLOAT"
7074   "@
7075     mov%T3\\t%0,%z1,%4
7076     mov%t3\\t%0,%z2,%4"
7077   [(set_attr "type" "move")
7078    (set_attr "mode" "DI")])
7079
7080 (define_insn ""
7081   [(set (match_operand:SF 0 "register_operand" "=f,f")
7082         (if_then_else:SF
7083          (match_operator 4 "equality_op"
7084                          [(match_operand:SI 1 "register_operand" "d,d")
7085                           (const_int 0)])
7086          (match_operand:SF 2 "register_operand" "f,0")
7087          (match_operand:SF 3 "register_operand" "0,f")))]
7088   "mips_isa >= 4 && TARGET_HARD_FLOAT"
7089   "@
7090     mov%B4.s\\t%0,%2,%1
7091     mov%b4.s\\t%0,%3,%1"
7092   [(set_attr "type" "move")
7093    (set_attr "mode" "SF")])
7094
7095 (define_insn ""
7096   [(set (match_operand:SF 0 "register_operand" "=f,f")
7097         (if_then_else:SF
7098          (match_operator 3 "equality_op" [(match_operand:CC 4
7099                                                             "register_operand"
7100                                                             "z,z")
7101                                           (const_int 0)])
7102          (match_operand:SF 1 "register_operand" "f,0")
7103          (match_operand:SF 2 "register_operand" "0,f")))]
7104   "mips_isa >= 4 && TARGET_HARD_FLOAT"
7105   "@
7106     mov%T3.s\\t%0,%1,%4
7107     mov%t3.s\\t%0,%2,%4"
7108   [(set_attr "type" "move")
7109    (set_attr "mode" "SF")])
7110
7111 (define_insn ""
7112   [(set (match_operand:DF 0 "register_operand" "=f,f")
7113         (if_then_else:DF
7114          (match_operator 4 "equality_op"
7115                          [(match_operand:SI 1 "register_operand" "d,d")
7116                           (const_int 0)])
7117          (match_operand:DF 2 "register_operand" "f,0")
7118          (match_operand:DF 3 "register_operand" "0,f")))]
7119   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7120   "@
7121     mov%B4.d\\t%0,%2,%1
7122     mov%b4.d\\t%0,%3,%1"
7123   [(set_attr "type" "move")
7124    (set_attr "mode" "DF")])
7125
7126 (define_insn ""
7127   [(set (match_operand:DF 0 "register_operand" "=f,f")
7128         (if_then_else:DF
7129          (match_operator 3 "equality_op" [(match_operand:CC 4
7130                                                             "register_operand"
7131                                                             "z,z")
7132                                           (const_int 0)])
7133          (match_operand:DF 1 "register_operand" "f,0")
7134          (match_operand:DF 2 "register_operand" "0,f")))]
7135   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7136   "@
7137     mov%T3.d\\t%0,%1,%4
7138     mov%t3.d\\t%0,%2,%4"
7139   [(set_attr "type" "move")
7140    (set_attr "mode" "DF")])
7141
7142 ;; These are the main define_expand's used to make conditional moves.
7143
7144 (define_expand "movsicc"
7145   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
7146    (set (match_operand:SI 0 "register_operand" "")
7147         (if_then_else:SI (match_dup 5)
7148                          (match_operand:SI 2 "reg_or_0_operand" "")
7149                          (match_operand:SI 3 "reg_or_0_operand" "")))]
7150   "mips_isa >= 4"
7151   "
7152 {
7153   gen_conditional_move (operands);
7154   DONE;
7155 }")
7156
7157 (define_expand "movdicc"
7158   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
7159    (set (match_operand:DI 0 "register_operand" "")
7160         (if_then_else:DI (match_dup 5)
7161                          (match_operand:DI 2 "se_reg_or_0_operand" "")
7162                          (match_operand:DI 3 "se_reg_or_0_operand" "")))]
7163   "mips_isa >= 4"
7164   "
7165 {
7166   gen_conditional_move (operands);
7167   DONE;
7168 }")
7169
7170 (define_expand "movsfcc"
7171   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
7172    (set (match_operand:SF 0 "register_operand" "")
7173         (if_then_else:SF (match_dup 5)
7174                          (match_operand:SF 2 "register_operand" "")
7175                          (match_operand:SF 3 "register_operand" "")))]
7176   "mips_isa >= 4 && TARGET_HARD_FLOAT"
7177   "
7178 {
7179   gen_conditional_move (operands);
7180   DONE;
7181 }")
7182
7183 (define_expand "movdfcc"
7184   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
7185    (set (match_operand:DF 0 "register_operand" "")
7186         (if_then_else:DF (match_dup 5)
7187                          (match_operand:DF 2 "register_operand" "")
7188                          (match_operand:DF 3 "register_operand" "")))]
7189   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7190   "
7191 {
7192   gen_conditional_move (operands);
7193   DONE;
7194 }")