OSDN Git Service

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