OSDN Git Service

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