OSDN Git Service

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