OSDN Git Service

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