OSDN Git Service

Allow calls to absolute addresses.
[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 ;;  Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
5
6 ;; This file is part of GNU CC.
7
8 ;; GNU CC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
12
13 ;; GNU CC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU CC; see the file COPYING.  If not, write to
20 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21
22 \f
23
24 ;; ....................
25 ;;
26 ;;      Attributes
27 ;;
28 ;; ....................
29
30 ;; Classification of each insn.
31 ;; branch       conditional branch
32 ;; jump         unconditional jump
33 ;; call         unconditional call
34 ;; load         load instruction(s)
35 ;; store        store instruction(s)
36 ;; move         data movement within same register set
37 ;; xfer         transfer to/from coprocessor
38 ;; hilo         transfer of hi/lo registers
39 ;; arith        integer arithmetic instruction
40 ;; darith       double precision integer arithmetic instructions
41 ;; imul         integer multiply
42 ;; idiv         integer divide
43 ;; icmp         integer compare
44 ;; fadd         floating point add/subtract
45 ;; fmul         floating point multiply
46 ;; fdiv         floating point divide
47 ;; fabs         floating point absolute value
48 ;; fneg         floating point negation
49 ;; fcmp         floating point compare
50 ;; fcvt         floating point convert
51 ;; fsqrt        floating point square root
52 ;; multi        multiword sequence (or user asm statements)
53 ;; nop          no operation
54
55 (define_attr "type"
56   "unknown,branch,jump,call,load,store,move,xfer,hilo,arith,darith,imul,idiv,icmp,fadd,fmul,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,multi,nop"
57   (const_string "unknown"))
58
59 ;; Main data type used by the insn
60 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown"))
61
62 ;; # instructions (4 bytes each)
63 (define_attr "length" "" (const_int 1))
64
65 ;; whether or not an instruction has a mandatory delay slot
66 (define_attr "dslot" "no,yes"
67   (if_then_else (eq_attr "type" "branch,jump,call,load,xfer,hilo,fcmp")
68                 (const_string "yes")
69                 (const_string "no")))
70
71 ;; Attribute describing the processor.  This attribute must match exactly
72 ;; with the processor_type enumeration in mips.h.
73
74 ;; Attribute describing the processor
75 ;; (define_attr "cpu" "default,r3000,r6000,r4000"
76 ;;   (const
77 ;;    (cond [(eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R3000"))   (const_string "r3000")
78 ;;           (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R4000"))   (const_string "r4000")
79 ;;           (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R6000"))   (const_string "r6000")]
80 ;;          (const_string "default"))))
81
82 (define_attr "cpu" "default,r3000,r6000,r4000"
83   (const (symbol_ref "mips_cpu_attr")))
84
85 ;; Attribute defining whether or not we can use the branch-likely instructions
86 ;; (MIPS ISA level 2)
87
88 (define_attr "branch_likely" "no,yes"
89   (const
90    (if_then_else (ge (symbol_ref "mips_isa") (const_int 2))
91                  (const_string "yes")
92                  (const_string "no"))))
93
94
95 ;; Describe a user's asm statement.
96 (define_asm_attributes
97   [(set_attr "type" "multi")])
98
99 \f
100
101 ;; .........................
102 ;;
103 ;;      Delay slots, can't describe load/fcmp/xfer delay slots here
104 ;;
105 ;; .........................
106
107 (define_delay (eq_attr "type" "branch")
108   [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
109    (nil)
110    (and (eq_attr "branch_likely" "yes") (and (eq_attr "dslot" "no") (eq_attr "length" "1")))])
111
112 (define_delay (eq_attr "type" "call,jump")
113   [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
114    (nil)
115    (nil)])
116
117 \f
118
119 ;; .........................
120 ;;
121 ;;      Functional units
122 ;;
123 ;; .........................
124
125 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
126 ;                       TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
127
128 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
129
130 (define_function_unit "memory" 1 0
131   (and (eq_attr "type" "load") (eq_attr "cpu" "!r3000"))
132   3 0)
133
134 (define_function_unit "memory" 1 0
135   (and (eq_attr "type" "load") (eq_attr "cpu" "r3000"))
136   2 0)
137
138 (define_function_unit "memory"   1 0 (eq_attr "type" "store") 1 0)
139
140 (define_function_unit "addr"     1 0 (eq_attr "type" "fcmp") 2 0)
141
142 (define_function_unit "memory"   1 0 (eq_attr "type" "xfer") 2 0)
143 (define_function_unit "memory"   1 0 (eq_attr "type" "hilo") 3 0)
144
145 (define_function_unit "imuldiv"  1 1
146   (and (eq_attr "type" "imul") (eq_attr "cpu" "!r3000,r4000"))
147   17 0)
148
149 (define_function_unit "imuldiv"  1 1
150   (and (eq_attr "type" "imul") (eq_attr "cpu" "r3000"))
151   12 0)
152
153 (define_function_unit "imuldiv" 1 1
154   (and (eq_attr "type" "imul") (eq_attr "cpu" "r4000"))
155   10 0)
156
157 (define_function_unit "imuldiv"  1 1
158   (and (eq_attr "type" "idiv") (eq_attr "cpu" "!r3000,r4000"))
159   38 0)
160
161 (define_function_unit "imuldiv"  1 1
162   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000"))
163   35 0)
164
165 (define_function_unit "imuldiv" 1 1
166   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
167   69 0)
168
169 (define_function_unit "adder" 1 1
170   (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r6000"))
171   4 0)
172
173 (define_function_unit "adder" 1 1
174   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000"))
175   2 0)
176
177 (define_function_unit "adder" 1 1
178   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
179   3 0)
180
181 (define_function_unit "adder" 1 1
182   (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "!r3000"))
183   2 0)
184
185 (define_function_unit "adder" 1 1
186   (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000"))
187   1 0)
188
189 (define_function_unit "mult" 1 1
190   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r3000,r6000")))
191   7 0)
192
193 (define_function_unit "mult" 1 1
194   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000")))
195   4 0)
196
197 (define_function_unit "mult" 1 1
198   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
199   5 0)
200
201 (define_function_unit "mult" 1 1
202   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r6000")))
203   8 0)
204
205 (define_function_unit "mult" 1 1
206   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000")))
207   5 0)
208
209 (define_function_unit "mult" 1 1
210   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
211   6 0)
212
213 (define_function_unit "divide" 1 1
214   (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r3000,r6000")))
215   23 0)
216
217 (define_function_unit "divide" 1 1
218   (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000")))
219   12 0)
220
221 (define_function_unit "divide" 1 1
222   (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
223   15 0)
224
225 (define_function_unit "divide" 1 1
226   (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r6000")))
227   36 0)
228
229 (define_function_unit "divide" 1 1
230   (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000")))
231   19 0)
232
233 (define_function_unit "divide" 1 1
234   (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
235   16 0)
236
237 (define_function_unit "divide" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF"))  54 0)
238 (define_function_unit "divide" 1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0)
239
240 \f
241 ;; The following functional units do not use the cpu type, and use
242 ;; much less memory in genattrtab.c.
243
244 ;; (define_function_unit "memory"   1 0 (eq_attr "type" "load")                                3 0)
245 ;; (define_function_unit "memory"   1 0 (eq_attr "type" "store")                               1 0)
246 ;;       
247 ;; (define_function_unit "fp_comp"  1 0 (eq_attr "type" "fcmp")                                2 0)
248 ;;       
249 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer")                                2 0)
250 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo")                                3 0)
251 ;;   
252 ;; (define_function_unit "imuldiv"  1 1 (eq_attr "type" "imul")                               17 0)
253 ;; (define_function_unit "imuldiv"  1 1 (eq_attr "type" "idiv")                               38 0)
254 ;;   
255 ;; (define_function_unit "adder"    1 1 (eq_attr "type" "fadd")                                4 0)
256 ;; (define_function_unit "adder"    1 1 (eq_attr "type" "fabs,fneg")                           2 0)
257 ;;   
258 ;; (define_function_unit "mult"     1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF"))    7 0)
259 ;; (define_function_unit "mult"     1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF"))    8 0)
260 ;;   
261 ;; (define_function_unit "divide"   1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF"))   23 0)
262 ;; (define_function_unit "divide"   1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF"))   36 0)
263 ;; 
264 ;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF"))  54 0)
265 ;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0)
266
267 \f
268 ;;
269 ;;  ....................
270 ;;
271 ;;      ADDITION
272 ;;
273 ;;  ....................
274 ;;
275
276 (define_insn "adddf3"
277   [(set (match_operand:DF 0 "register_operand" "=f")
278         (plus:DF (match_operand:DF 1 "register_operand" "f")
279                  (match_operand:DF 2 "register_operand" "f")))]
280   "TARGET_HARD_FLOAT"
281   "add.d\\t%0,%1,%2"
282   [(set_attr "type"     "fadd")
283    (set_attr "mode"     "DF")
284    (set_attr "length"   "1")])
285
286 (define_insn "addsf3"
287   [(set (match_operand:SF 0 "register_operand" "=f")
288         (plus:SF (match_operand:SF 1 "register_operand" "f")
289                  (match_operand:SF 2 "register_operand" "f")))]
290   "TARGET_HARD_FLOAT"
291   "add.s\\t%0,%1,%2"
292   [(set_attr "type"     "fadd")
293    (set_attr "mode"     "SF")
294    (set_attr "length"   "1")])
295
296 (define_insn "addsi3"
297   [(set (match_operand:SI 0 "register_operand" "=d")
298         (plus:SI (match_operand:SI 1 "arith_operand" "%d")
299                  (match_operand:SI 2 "arith_operand" "dI")))]
300   ""
301   "*
302 {
303   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
304     ? \"subu\\t%0,%1,%n2\"
305     : \"addu\\t%0,%1,%2\";
306 }"
307   [(set_attr "type"     "arith")
308    (set_attr "mode"     "SI")
309    (set_attr "length"   "1")])
310
311 (define_expand "adddi3"
312   [(parallel [(set (match_operand:DI 0 "register_operand" "")
313                    (plus:DI (match_operand:DI 1 "register_operand" "")
314                             (match_operand:DI 2 "arith_operand" "")))
315               (clobber (match_dup 3))])]
316   "!TARGET_DEBUG_G_MODE"
317   "
318 {
319   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768)
320     operands[2] = force_reg (SImode, operands[2]);
321
322   operands[3] = gen_reg_rtx (SImode);
323 }")
324
325 (define_insn "adddi3_internal_1"
326   [(set (match_operand:DI 0 "register_operand" "=d,&d")
327         (plus:DI (match_operand:DI 1 "register_operand" "0,d")
328                  (match_operand:DI 2 "register_operand" "d,d")))
329    (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
330   "!TARGET_DEBUG_G_MODE"
331   "*
332 {
333   return (REGNO (operands[0]) == REGNO (operands[1])
334           && REGNO (operands[0]) == REGNO (operands[2]))
335     ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\"
336     : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\";
337 }"
338   [(set_attr "type"     "darith")
339    (set_attr "mode"     "DI")
340    (set_attr "length"   "4")])
341
342 (define_split
343   [(set (match_operand:DI 0 "register_operand" "")
344         (plus:DI (match_operand:DI 1 "register_operand" "")
345                  (match_operand:DI 2 "register_operand" "")))
346    (clobber (match_operand:SI 3 "register_operand" ""))]
347   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
348    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
349    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
350    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
351    && (REGNO (operands[0]) != REGNO (operands[1])
352        || REGNO (operands[0]) != REGNO (operands[2]))"
353
354   [(set (subreg:SI (match_dup 0) 0)
355         (plus:SI (subreg:SI (match_dup 1) 0)
356                  (subreg:SI (match_dup 2) 0)))
357
358    (set (match_dup 3)
359         (ltu:SI (subreg:SI (match_dup 0) 0)
360                 (subreg:SI (match_dup 2) 0)))
361
362    (set (subreg:SI (match_dup 0) 1)
363         (plus:SI (subreg:SI (match_dup 1) 1)
364                  (subreg:SI (match_dup 2) 1)))
365
366    (set (subreg:SI (match_dup 0) 1)
367         (plus:SI (subreg:SI (match_dup 0) 1)
368                  (match_dup 3)))]
369   "")
370
371 (define_split
372   [(set (match_operand:DI 0 "register_operand" "")
373         (plus:DI (match_operand:DI 1 "register_operand" "")
374                  (match_operand:DI 2 "register_operand" "")))
375    (clobber (match_operand:SI 3 "register_operand" ""))]
376   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
377    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
378    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
379    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
380    && (REGNO (operands[0]) != REGNO (operands[1])
381        || REGNO (operands[0]) != REGNO (operands[2]))"
382
383   [(set (subreg:SI (match_dup 0) 1)
384         (plus:SI (subreg:SI (match_dup 1) 1)
385                  (subreg:SI (match_dup 2) 1)))
386
387    (set (match_dup 3)
388         (ltu:SI (subreg:SI (match_dup 0) 1)
389                 (subreg:SI (match_dup 2) 1)))
390
391    (set (subreg:SI (match_dup 0) 0)
392         (plus:SI (subreg:SI (match_dup 1) 0)
393                  (subreg:SI (match_dup 2) 0)))
394
395    (set (subreg:SI (match_dup 0) 0)
396         (plus:SI (subreg:SI (match_dup 0) 0)
397                  (match_dup 3)))]
398   "")
399
400 (define_insn "adddi3_internal_2"
401   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
402         (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d")
403                  (match_operand:DI 2 "small_int" "P,J,N")))
404    (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
405   "!TARGET_DEBUG_G_MODE && INTVAL (operands[2]) != -32768"
406   "@
407    addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3
408    move\\t%L0,%L1\;move\\t%M0,%M1
409    subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3"
410   [(set_attr "type"     "darith")
411    (set_attr "mode"     "DI")
412    (set_attr "length"   "3,2,4")])
413
414 (define_split
415   [(set (match_operand:DI 0 "register_operand" "")
416         (plus:DI (match_operand:DI 1 "register_operand" "")
417                  (match_operand:DI 2 "small_int" "")))
418    (clobber (match_operand:SI 3 "register_operand" "=d"))]
419   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
420    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
421    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
422    && INTVAL (operands[2]) > 0"
423
424   [(set (subreg:SI (match_dup 0) 0)
425         (plus:SI (subreg:SI (match_dup 1) 0)
426                  (match_dup 2)))
427
428    (set (match_dup 3)
429         (ltu:SI (subreg:SI (match_dup 0) 0)
430                 (match_dup 2)))
431
432    (set (subreg:SI (match_dup 0) 1)
433         (plus:SI (subreg:SI (match_dup 1) 1)
434                  (match_dup 3)))]
435   "")
436
437 (define_split
438   [(set (match_operand:DI 0 "register_operand" "")
439         (plus:DI (match_operand:DI 1 "register_operand" "")
440                  (match_operand:DI 2 "small_int" "")))
441    (clobber (match_operand:SI 3 "register_operand" "=d"))]
442   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
443    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
444    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
445    && INTVAL (operands[2]) > 0"
446
447   [(set (subreg:SI (match_dup 0) 1)
448         (plus:SI (subreg:SI (match_dup 1) 1)
449                  (match_dup 2)))
450
451    (set (match_dup 3)
452         (ltu:SI (subreg:SI (match_dup 0) 1)
453                 (match_dup 2)))
454
455    (set (subreg:SI (match_dup 0) 0)
456         (plus:SI (subreg:SI (match_dup 1) 0)
457                  (match_dup 3)))]
458   "")
459 \f
460 ;;
461 ;;  ....................
462 ;;
463 ;;      SUBTRACTION
464 ;;
465 ;;  ....................
466 ;;
467
468 (define_insn "subdf3"
469   [(set (match_operand:DF 0 "register_operand" "=f")
470         (minus:DF (match_operand:DF 1 "register_operand" "f")
471                   (match_operand:DF 2 "register_operand" "f")))]
472   "TARGET_HARD_FLOAT"
473   "sub.d\\t%0,%1,%2"
474   [(set_attr "type"     "fadd")
475    (set_attr "mode"     "DF")
476    (set_attr "length"   "1")])
477
478 (define_insn "subsf3"
479   [(set (match_operand:SF 0 "register_operand" "=f")
480         (minus:SF (match_operand:SF 1 "register_operand" "f")
481                   (match_operand:SF 2 "register_operand" "f")))]
482   "TARGET_HARD_FLOAT"
483   "sub.s\\t%0,%1,%2"
484   [(set_attr "type"     "fadd")
485    (set_attr "mode"     "SF")
486    (set_attr "length"   "1")])
487
488 (define_insn "subsi3"
489   [(set (match_operand:SI 0 "register_operand" "=d")
490         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
491                   (match_operand:SI 2 "arith_operand" "dI")))]
492   ""
493   "*
494 {
495   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
496     ? \"addu\\t%0,%z1,%n2\"
497     : \"subu\\t%0,%z1,%2\";
498 }"
499   [(set_attr "type"     "arith")
500    (set_attr "mode"     "SI")
501    (set_attr "length"   "1")])
502
503 (define_expand "subdi3"
504   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
505                    (minus:DI (match_operand:DI 1 "register_operand" "d")
506                              (match_operand:DI 2 "register_operand" "d")))
507               (clobber (match_dup 3))])]
508   "!TARGET_DEBUG_G_MODE"
509   "operands[3] = gen_reg_rtx (SImode);")
510
511 (define_insn "subdi3_internal"
512   [(set (match_operand:DI 0 "register_operand" "=d")
513         (minus:DI (match_operand:DI 1 "register_operand" "d")
514                   (match_operand:DI 2 "register_operand" "d")))
515    (clobber (match_operand:SI 3 "register_operand" "=d"))]
516   "!TARGET_DEBUG_G_MODE"
517   "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3"
518   [(set_attr "type"     "darith")
519    (set_attr "mode"     "DI")
520    (set_attr "length"   "4")])
521
522 (define_split
523   [(set (match_operand:DI 0 "register_operand" "")
524         (minus:DI (match_operand:DI 1 "register_operand" "")
525                   (match_operand:DI 2 "register_operand" "")))
526    (clobber (match_operand:SI 3 "register_operand" ""))]
527   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
528    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
529    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
530    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
531
532   [(set (match_dup 3)
533         (ltu:SI (subreg:SI (match_dup 1) 0)
534                 (subreg:SI (match_dup 2) 0)))
535
536    (set (subreg:SI (match_dup 0) 0)
537         (minus:SI (subreg:SI (match_dup 1) 0)
538                   (subreg:SI (match_dup 2) 0)))
539
540    (set (subreg:SI (match_dup 0) 1)
541         (minus:SI (subreg:SI (match_dup 1) 1)
542                   (subreg:SI (match_dup 2) 1)))
543
544    (set (subreg:SI (match_dup 0) 1)
545         (minus:SI (subreg:SI (match_dup 0) 1)
546                   (match_dup 3)))]
547   "")
548
549 (define_split
550   [(set (match_operand:DI 0 "register_operand" "")
551         (minus:DI (match_operand:DI 1 "register_operand" "")
552                   (match_operand:DI 2 "register_operand" "")))
553    (clobber (match_operand:SI 3 "register_operand" ""))]
554   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
555    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
556    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
557    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
558
559   [(set (match_dup 3)
560         (ltu:SI (subreg:SI (match_dup 1) 1)
561                 (subreg:SI (match_dup 2) 1)))
562
563    (set (subreg:SI (match_dup 0) 1)
564         (minus:SI (subreg:SI (match_dup 1) 1)
565                   (subreg:SI (match_dup 2) 1)))
566
567    (set (subreg:SI (match_dup 0) 0)
568         (minus:SI (subreg:SI (match_dup 1) 0)
569                   (subreg:SI (match_dup 2) 0)))
570
571    (set (subreg:SI (match_dup 0) 0)
572         (minus:SI (subreg:SI (match_dup 0) 0)
573                   (match_dup 3)))]
574   "")
575
576 (define_insn "subdi3_internal_2"
577   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
578         (minus:DI (match_operand:DI 1 "register_operand" "d,d,d")
579                   (match_operand:DI 2 "small_int" "P,J,N")))
580    (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
581   "!TARGET_DEBUG_G_MODE && INTVAL (operands[2]) != -32768"
582   "@
583    sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3
584    move\\t%L0,%L1\;move\\t%M0,%M1
585    sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3"
586   [(set_attr "type"     "darith")
587    (set_attr "mode"     "DI")
588    (set_attr "length"   "3,2,4")])
589
590 (define_split
591   [(set (match_operand:DI 0 "register_operand" "")
592         (minus:DI (match_operand:DI 1 "register_operand" "")
593                   (match_operand:DI 2 "small_int" "")))
594    (clobber (match_operand:SI 3 "register_operand" ""))]
595   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
596    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
597    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
598    && INTVAL (operands[2]) > 0"
599
600   [(set (match_dup 3)
601         (ltu:SI (subreg:SI (match_dup 1) 0)
602                 (match_dup 2)))
603
604    (set (subreg:SI (match_dup 0) 0)
605         (minus:SI (subreg:SI (match_dup 1) 0)
606                   (match_dup 2)))
607
608    (set (subreg:SI (match_dup 0) 1)
609         (minus:SI (subreg:SI (match_dup 1) 1)
610                   (match_dup 3)))]
611   "")
612
613 (define_split
614   [(set (match_operand:DI 0 "register_operand" "")
615         (minus:DI (match_operand:DI 1 "register_operand" "")
616                   (match_operand:DI 2 "small_int" "")))
617    (clobber (match_operand:SI 3 "register_operand" ""))]
618   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
619    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
620    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
621    && INTVAL (operands[2]) > 0"
622
623   [(set (match_dup 3)
624         (ltu:SI (subreg:SI (match_dup 1) 1)
625                 (match_dup 2)))
626
627    (set (subreg:SI (match_dup 0) 1)
628         (minus:SI (subreg:SI (match_dup 1) 1)
629                   (match_dup 2)))
630
631    (set (subreg:SI (match_dup 0) 0)
632         (minus:SI (subreg:SI (match_dup 1) 0)
633                   (match_dup 3)))]
634   "")
635
636 \f
637 ;;
638 ;;  ....................
639 ;;
640 ;;      MULTIPLICATION
641 ;;
642 ;;  ....................
643 ;;
644
645 (define_insn "muldf3"
646   [(set (match_operand:DF 0 "register_operand" "=f")
647         (mult:DF (match_operand:DF 1 "register_operand" "f")
648                  (match_operand:DF 2 "register_operand" "f")))]
649   "TARGET_HARD_FLOAT"
650   "mul.d\\t%0,%1,%2"
651   [(set_attr "type"     "fmul")
652    (set_attr "mode"     "DF")
653    (set_attr "length"   "1")])
654
655 (define_insn "mulsf3"
656   [(set (match_operand:SF 0 "register_operand" "=f")
657         (mult:SF (match_operand:SF 1 "register_operand" "f")
658                  (match_operand:SF 2 "register_operand" "f")))]
659   "TARGET_HARD_FLOAT"
660   "mul.s\\t%0,%1,%2"
661   [(set_attr "type"     "fmul")
662    (set_attr "mode"     "SF")
663    (set_attr "length"   "1")])
664
665 (define_insn "mulsi3"
666   [(set (match_operand:SI 0 "register_operand" "=d")
667         (mult:SI (match_operand:SI 1 "register_operand" "d")
668                  (match_operand:SI 2 "register_operand" "d")))
669    (clobber (reg:SI 64))
670    (clobber (reg:SI 65))]
671   ""
672   "*
673 {
674   rtx xoperands[10];
675
676   xoperands[0] = operands[0];
677   xoperands[1] = gen_rtx (REG, SImode, LO_REGNUM);
678
679   output_asm_insn (\"mult\\t%1,%2\", operands);
680   output_asm_insn (mips_move_1word (xoperands, insn), xoperands);
681   return \"\";
682 }"
683   [(set_attr "type"     "imul")
684    (set_attr "mode"     "SI")
685    (set_attr "length"   "3")])          ;; mult + mflo + delay
686
687 (define_split
688   [(set (match_operand:SI 0 "register_operand" "")
689         (mult:SI (match_operand:SI 1 "register_operand" "")
690                  (match_operand:SI 2 "register_operand" "")))
691    (clobber (reg:SI 64))
692    (clobber (reg:SI 65))]
693   "!TARGET_DEBUG_D_MODE"
694   [(parallel [(set (reg:SI 65)          ;; low register
695                    (mult:SI (match_dup 1)
696                             (match_dup 2)))
697               (clobber (reg:SI 64))])
698    (set (match_dup 0)
699         (reg:SI 65))]
700   "")
701
702 (define_insn "mulsi3_internal"
703   [(set (reg:SI 65)             ;; low register
704         (mult:SI (match_operand:SI 0 "register_operand" "d")
705                  (match_operand:SI 1 "register_operand" "d")))
706    (clobber (reg:SI 64))]
707   ""
708   "mult\\t%0,%1"
709   [(set_attr "type"     "imul")
710    (set_attr "mode"     "SI")
711    (set_attr "length"   "1")])
712
713 (define_insn "mulsidi3"
714   [(set (match_operand:DI 0 "register_operand" "=d")
715         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
716                  (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
717    (clobber (reg:DI 64))]
718   ""
719   "*
720 {
721   rtx xoperands[10];
722
723   xoperands[0] = operands[0];
724   xoperands[1] = gen_rtx (REG, DImode, MD_REG_FIRST);
725
726   output_asm_insn (\"mult\\t%1,%2\", operands);
727   output_asm_insn (mips_move_2words (xoperands, insn), xoperands);
728   return \"\";
729 }"
730   [(set_attr "type"     "imul")
731    (set_attr "mode"     "SI")
732    (set_attr "length"   "4")])          ;; mult + mflo + mfhi + delay
733
734 (define_insn "umulsidi3"
735   [(set (match_operand:DI 0 "register_operand" "=d")
736         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
737                  (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
738    (clobber (reg:DI 64))]
739   ""
740   "*
741 {
742   rtx xoperands[10];
743
744   xoperands[0] = operands[0];
745   xoperands[1] = gen_rtx (REG, DImode, MD_REG_FIRST);
746
747   output_asm_insn (\"multu\\t%1,%2\", operands);
748   output_asm_insn (mips_move_2words (xoperands, insn), xoperands);
749   return \"\";
750 }"
751   [(set_attr "type"     "imul")
752    (set_attr "mode"     "SI")
753    (set_attr "length"   "4")])          ;; mult + mflo + mfhi + delay
754
755 \f
756 ;;
757 ;;  ....................
758 ;;
759 ;;      DIVISION and REMAINDER
760 ;;
761 ;;  ....................
762 ;;
763
764 (define_insn "divdf3"
765   [(set (match_operand:DF 0 "register_operand" "=f")
766         (div:DF (match_operand:DF 1 "register_operand" "f")
767                 (match_operand:DF 2 "register_operand" "f")))]
768   "TARGET_HARD_FLOAT"
769   "div.d\\t%0,%1,%2"
770   [(set_attr "type"     "fdiv")
771    (set_attr "mode"     "DF")
772    (set_attr "length"   "1")])
773
774 (define_insn "divsf3"
775   [(set (match_operand:SF 0 "register_operand" "=f")
776         (div:SF (match_operand:SF 1 "register_operand" "f")
777                 (match_operand:SF 2 "register_operand" "f")))]
778   "TARGET_HARD_FLOAT"
779   "div.s\\t%0,%1,%2"
780   [(set_attr "type"     "fdiv")
781    (set_attr "mode"     "SF")
782    (set_attr "length"   "1")])
783
784 ;; If optimizing, prefer the divmod functions over separate div and
785 ;; mod functions, since this will allow using one instruction for both
786 ;; the quotient and remainder.  At present, the divmod is not moved out
787 ;; of loops if it is constant within the loop, so allow -mdebugc to
788 ;; use the old method of doing things.
789
790 ;; 64 is the multiply/divide hi register
791 ;; 65 is the multiply/divide lo register
792
793 (define_insn "divmodsi4"
794   [(set (match_operand:SI 0 "register_operand" "=d")
795         (div:SI (match_operand:SI 1 "register_operand" "d")
796                 (match_operand:SI 2 "register_operand" "d")))
797    (set (match_operand:SI 3 "register_operand" "=d")
798         (mod:SI (match_dup 1)
799                 (match_dup 2)))
800    (clobber (reg:SI 64))
801    (clobber (reg:SI 65))]
802   "optimize"
803   "*
804 {
805   if (find_reg_note (insn, REG_UNUSED, operands[3]))
806     return \"div\\t%0,%1,%2\";
807
808   if (find_reg_note (insn, REG_UNUSED, operands[0]))
809     return \"rem\\t%3,%1,%2\";
810
811   return \"div\\t%0,%1,%2\;mfhi\\t%3\";
812 }"
813   [(set_attr "type"     "idiv")
814    (set_attr "mode"     "SI")
815    (set_attr "length"   "13")])         ;; various tests for dividing by 0 and such
816
817 (define_insn "udivmodsi4"
818   [(set (match_operand:SI 0 "register_operand" "=d")
819         (udiv:SI (match_operand:SI 1 "register_operand" "d")
820                  (match_operand:SI 2 "register_operand" "d")))
821    (set (match_operand:SI 3 "register_operand" "=d")
822         (umod:SI (match_dup 1)
823                  (match_dup 2)))
824    (clobber (reg:SI 64))
825    (clobber (reg:SI 65))]
826   "optimize"
827   "*
828 {
829   if (find_reg_note (insn, REG_UNUSED, operands[3]))
830     return \"divu\\t%0,%1,%2\";
831
832   if (find_reg_note (insn, REG_UNUSED, operands[0]))
833     return \"remu\\t%3,%1,%2\";
834
835   return \"divu\\t%0,%1,%2\;mfhi\\t%3\";
836 }"
837   [(set_attr "type"     "idiv")
838    (set_attr "mode"     "SI")
839    (set_attr "length"   "13")])         ;; various tests for dividing by 0 and such
840
841 (define_insn "divsi3"
842   [(set (match_operand:SI 0 "register_operand" "=d")
843         (div:SI (match_operand:SI 1 "register_operand" "d")
844                 (match_operand:SI 2 "register_operand" "d")))
845    (clobber (reg:SI 64))
846    (clobber (reg:SI 65))]
847   "!optimize"
848   "div\\t%0,%1,%2"
849   [(set_attr "type"     "idiv")
850    (set_attr "mode"     "SI")
851    (set_attr "length"   "13")])         ;; various tests for dividing by 0 and such
852
853 (define_insn "modsi3"
854   [(set (match_operand:SI 0 "register_operand" "=d")
855         (mod:SI (match_operand:SI 1 "register_operand" "d")
856                 (match_operand:SI 2 "register_operand" "d")))
857    (clobber (reg:SI 64))
858    (clobber (reg:SI 65))]
859   "!optimize"
860   "rem\\t%0,%1,%2"
861   [(set_attr "type"     "idiv")
862    (set_attr "mode"     "SI")
863    (set_attr "length"   "14")])         ;; various tests for dividing by 0 and such
864
865 (define_insn "udivsi3"
866   [(set (match_operand:SI 0 "register_operand" "=d")
867         (udiv:SI (match_operand:SI 1 "register_operand" "d")
868                  (match_operand:SI 2 "register_operand" "d")))
869    (clobber (reg:SI 64))
870    (clobber (reg:SI 65))]
871   "!optimize"
872   "divu\\t%0,%1,%2"
873   [(set_attr "type"     "idiv")
874    (set_attr "mode"     "SI")
875    (set_attr "length"   "14")])         ;; various tests for dividing by 0 and such
876
877 (define_insn "umodsi3"
878   [(set (match_operand:SI 0 "register_operand" "=d")
879         (umod:SI (match_operand:SI 1 "register_operand" "d")
880                  (match_operand:SI 2 "register_operand" "d")))
881    (clobber (reg:SI 64))
882    (clobber (reg:SI 65))]
883   "!optimize"
884   "remu\\t%0,%1,%2"
885   [(set_attr "type"     "idiv")
886    (set_attr "mode"     "SI")
887    (set_attr "length"   "14")])         ;; various tests for dividing by 0 and such
888
889 \f
890 ;;
891 ;;  ....................
892 ;;
893 ;;      SQUARE ROOT
894 ;;
895 ;;  ....................
896
897 (define_insn "sqrtdf2"
898   [(set (match_operand:DF 0 "register_operand" "=f")
899         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
900   "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
901   "sqrt.d\\t%0,%1"
902   [(set_attr "type"     "fabs")
903    (set_attr "mode"     "DF")
904    (set_attr "length"   "1")])
905
906 (define_insn "sqrtsf2"
907   [(set (match_operand:SF 0 "register_operand" "=f")
908         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
909   "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
910   "sqrt.s\\t%0,%1"
911   [(set_attr "type"     "fabs")
912    (set_attr "mode"     "SF")
913    (set_attr "length"   "1")])
914
915 \f
916 ;;
917 ;;  ....................
918 ;;
919 ;;      ABSOLUTE VALUE
920 ;;
921 ;;  ....................
922
923 ;; Do not use the integer abs macro instruction, since that signals an
924 ;; exception on -2147483648 (sigh).
925
926 (define_insn "abssi2"
927   [(set (match_operand:SI 0 "register_operand" "=d")
928         (abs:SI (match_operand:SI 1 "register_operand" "d")))]
929   ""
930   "*
931 {
932   dslots_jump_total++;
933   dslots_jump_filled++;
934   operands[2] = const0_rtx;
935
936   return (REGNO (operands[0]) == REGNO (operands[1]))
937                 ? \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n1:\"
938                 : \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n1:%)\";
939 }"
940   [(set_attr "type"     "multi")
941    (set_attr "mode"     "SI")
942    (set_attr "length"   "3")])
943
944 (define_insn "absdf2"
945   [(set (match_operand:DF 0 "register_operand" "=f")
946         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
947   "TARGET_HARD_FLOAT"
948   "abs.d\\t%0,%1"
949   [(set_attr "type"     "fabs")
950    (set_attr "mode"     "DF")
951    (set_attr "length"   "1")])
952
953 (define_insn "abssf2"
954   [(set (match_operand:SF 0 "register_operand" "=f")
955         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
956   "TARGET_HARD_FLOAT"
957   "abs.s\\t%0,%1"
958   [(set_attr "type"     "fabs")
959    (set_attr "mode"     "SF")
960    (set_attr "length"   "1")])
961
962 \f
963 ;;
964 ;;  ....................
965 ;;
966 ;;      FIND FIRST BIT INSTRUCTION
967 ;;
968 ;;  ....................
969 ;;
970
971 (define_insn "ffssi2"
972   [(set (match_operand:SI 0 "register_operand" "=&d")
973         (ffs:SI (match_operand:SI 1 "register_operand" "d")))
974    (clobber (match_scratch:SI 2 "d"))
975    (clobber (match_scratch:SI 3 "d"))]
976   ""
977   "*
978 {
979   dslots_jump_total += 2;
980   dslots_jump_filled += 2;
981   operands[4] = const0_rtx;
982
983   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
984     return \"%(\\
985 move\\t%0,%z4\\n\\
986 \\tbeq\\t%1,%z4,2f\\n\\
987 1:\\tand\\t%2,%1,0x0001\\n\\
988 \\taddu\\t%0,%0,1\\n\\
989 \\tbeq\\t%2,%z4,1b\\n\\
990 \\tsrl\\t%1,%1,1\\n\\
991 2:%)\";
992
993   return \"%(\\
994 move\\t%0,%z4\\n\\
995 \\tmove\\t%3,%1\\n\\
996 \\tbeq\\t%3,%z4,2f\\n\\
997 1:\\tand\\t%2,%3,0x0001\\n\\
998 \\taddu\\t%0,%0,1\\n\\
999 \\tbeq\\t%2,%z4,1b\\n\\
1000 \\tsrl\\t%3,%3,1\\n\\
1001 2:%)\";
1002 }"
1003   [(set_attr "type"     "multi")
1004    (set_attr "mode"     "SI")
1005    (set_attr "length"   "6")])
1006
1007 \f
1008 ;;
1009 ;;  ....................
1010 ;;
1011 ;;      NEGATION and ONE'S COMPLEMENT
1012 ;;
1013 ;;  ....................
1014
1015 (define_insn "negsi2"
1016   [(set (match_operand:SI 0 "register_operand" "=d")
1017         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
1018   ""
1019   "*
1020 {
1021   operands[2] = const0_rtx;
1022   return \"subu\\t%0,%z2,%1\";
1023 }"
1024   [(set_attr "type"     "arith")
1025    (set_attr "mode"     "SI")
1026    (set_attr "length"   "1")])
1027
1028 (define_expand "negdi3"
1029   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
1030                    (neg:DI (match_operand:DI 1 "register_operand" "d")))
1031               (clobber (match_dup 2))])]
1032   "!TARGET_DEBUG_G_MODE"
1033   "operands[2] = gen_reg_rtx (SImode);")
1034
1035 (define_insn "negdi3_internal"
1036   [(set (match_operand:DI 0 "register_operand" "=d")
1037         (neg:DI (match_operand:DI 1 "register_operand" "d")))
1038    (clobber (match_operand:SI 2 "register_operand" "=d"))]
1039   "!TARGET_DEBUG_G_MODE"
1040   "*
1041 {
1042   operands[3] = const0_rtx;
1043   return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\";
1044 }"
1045   [(set_attr "type"     "darith")
1046    (set_attr "mode"     "DI")
1047    (set_attr "length"   "4")])
1048
1049 (define_insn "negdf2"
1050   [(set (match_operand:DF 0 "register_operand" "=f")
1051         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
1052   "TARGET_HARD_FLOAT"
1053   "neg.d\\t%0,%1"
1054   [(set_attr "type"     "fneg")
1055    (set_attr "mode"     "DF")
1056    (set_attr "length"   "1")])
1057
1058 (define_insn "negsf2"
1059   [(set (match_operand:SF 0 "register_operand" "=f")
1060         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
1061   "TARGET_HARD_FLOAT"
1062   "neg.s\\t%0,%1"
1063   [(set_attr "type"     "fneg")
1064    (set_attr "mode"     "SF")
1065    (set_attr "length"   "1")])
1066
1067 (define_insn "one_cmplsi2"
1068   [(set (match_operand:SI 0 "register_operand" "=d")
1069         (not:SI (match_operand:SI 1 "register_operand" "d")))]
1070   ""
1071   "*
1072 {
1073   operands[2] = const0_rtx;
1074   return \"nor\\t%0,%z2,%1\";
1075 }"
1076   [(set_attr "type"     "arith")
1077    (set_attr "mode"     "SI")
1078    (set_attr "length"   "1")])
1079
1080 (define_insn "one_cmpldi2"
1081   [(set (match_operand:DI 0 "register_operand" "=d")
1082         (not:SI (match_operand:DI 1 "register_operand" "d")))]
1083   ""
1084   "*
1085 {
1086   operands[2] = const0_rtx;
1087   return \"nor\\t%M0,%z2,%M1\;nor\\t%L0,%z2,%L1\";
1088 }"
1089   [(set_attr "type"     "darith")
1090    (set_attr "mode"     "DI")
1091    (set_attr "length"   "2")])
1092
1093 (define_split
1094   [(set (match_operand:DI 0 "register_operand" "")
1095         (not:DI (match_operand:DI 1 "register_operand" "")))]
1096   "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1097    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1098    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
1099
1100   [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0)))
1101    (set (subreg:SI (match_dup 0) 1) (not:SI (subreg:SI (match_dup 1) 1)))]
1102   "")
1103
1104 ;; Simple hack to recognize the "nor" instruction on the MIPS
1105 ;; This must appear before the normal or patterns, so that the
1106 ;; combiner will correctly fold things.
1107
1108 (define_insn "norsi3"
1109   [(set (match_operand:SI 0 "register_operand" "=d")
1110         (not:SI (ior:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
1111                         (match_operand:SI 2 "reg_or_0_operand" "dJ"))))]
1112   ""
1113   "nor\\t%0,%z1,%z2"
1114   [(set_attr "type"     "arith")
1115    (set_attr "mode"     "SI")
1116    (set_attr "length"   "1")])
1117
1118 (define_insn "nordi3"
1119   [(set (match_operand:DI 0 "register_operand" "=d")
1120         (not:DI (ior:DI (match_operand:DI 1 "register_operand" "d")
1121                         (match_operand:DI 2 "register_operand" "d"))))]
1122   ""
1123   "nor\\t%M0,%M1,%M2\;nor\\t%L0,%L1,%L2"
1124   [(set_attr "type"     "darith")
1125    (set_attr "mode"     "DI")
1126    (set_attr "length"   "2")])
1127
1128 (define_split
1129   [(set (match_operand:DI 0 "register_operand" "")
1130         (not:DI (ior:DI (match_operand:DI 1 "register_operand" "")
1131                         (match_operand:DI 2 "register_operand" ""))))]
1132   "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1133    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1134    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1135    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1136
1137   [(set (subreg:SI (match_dup 0) 0) (not:SI (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0))))
1138    (set (subreg:SI (match_dup 0) 1) (not:SI (ior:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1))))]
1139   "")
1140
1141 \f
1142 ;;
1143 ;;  ....................
1144 ;;
1145 ;;      LOGICAL
1146 ;;
1147 ;;  ....................
1148 ;;
1149
1150 (define_insn "andsi3"
1151   [(set (match_operand:SI 0 "register_operand" "=d,d")
1152         (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
1153                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
1154   ""
1155   "@
1156    and\\t%0,%1,%2
1157    andi\\t%0,%1,%x2"
1158   [(set_attr "type"     "arith")
1159    (set_attr "mode"     "SI")
1160    (set_attr "length"   "1")])
1161
1162 (define_insn "anddi3"
1163   [(set (match_operand:DI 0 "register_operand" "=d")
1164         (and:DI (match_operand:DI 1 "register_operand" "d")
1165                 (match_operand:DI 2 "register_operand" "d")))]
1166   "!TARGET_DEBUG_G_MODE"
1167   "and\\t%M0,%M1,%M2\;and\\t%L0,%L1,%L2"
1168   [(set_attr "type"     "darith")
1169    (set_attr "mode"     "DI")
1170    (set_attr "length"   "2")])
1171
1172 (define_split
1173   [(set (match_operand:DI 0 "register_operand" "")
1174         (and:DI (match_operand:DI 1 "register_operand" "")
1175                 (match_operand:DI 2 "register_operand" "")))]
1176   "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1177    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1178    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1179    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1180
1181   [(set (subreg:SI (match_dup 0) 0) (and:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
1182    (set (subreg:SI (match_dup 0) 1) (and:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
1183   "")
1184
1185 (define_insn "iorsi3"
1186   [(set (match_operand:SI 0 "register_operand" "=d,d")
1187         (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
1188                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
1189   ""
1190   "@
1191    or\\t%0,%1,%2
1192    ori\\t%0,%1,%x2"
1193   [(set_attr "type"     "arith")
1194    (set_attr "mode"     "SI")
1195    (set_attr "length"   "1")])
1196
1197 (define_insn "iordi3"
1198   [(set (match_operand:DI 0 "register_operand" "=d")
1199         (ior:DI (match_operand:DI 1 "register_operand" "d")
1200                 (match_operand:DI 2 "register_operand" "d")))]
1201   "!TARGET_DEBUG_G_MODE"
1202   "or\\t%M0,%M1,%M2\;or\\t%L0,%L1,%L2"
1203   [(set_attr "type"     "darith")
1204    (set_attr "mode"     "DI")
1205    (set_attr "length"   "2")])
1206
1207 (define_split
1208   [(set (match_operand:DI 0 "register_operand" "")
1209         (ior:DI (match_operand:DI 1 "register_operand" "")
1210                 (match_operand:DI 2 "register_operand" "")))]
1211   "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1212    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1213    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1214    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1215
1216   [(set (subreg:SI (match_dup 0) 0) (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
1217    (set (subreg:SI (match_dup 0) 1) (ior:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
1218   "")
1219
1220 (define_insn "xorsi3"
1221   [(set (match_operand:SI 0 "register_operand" "=d,d")
1222         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
1223                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
1224   ""
1225   "@
1226    xor\\t%0,%1,%2
1227    xori\\t%0,%1,%x2"
1228   [(set_attr "type"     "arith")
1229    (set_attr "mode"     "SI")
1230    (set_attr "length"   "1")])
1231
1232 (define_insn "xordi3"
1233   [(set (match_operand:DI 0 "register_operand" "=d")
1234         (xor:DI (match_operand:DI 1 "register_operand" "d")
1235                 (match_operand:DI 2 "register_operand" "d")))]
1236   "!TARGET_DEBUG_G_MODE"
1237   "xor\\t%M0,%M1,%M2\;xor\\t%L0,%L1,%L2"
1238   [(set_attr "type"     "darith")
1239    (set_attr "mode"     "DI")
1240    (set_attr "length"   "2")])
1241
1242 (define_split
1243   [(set (match_operand:DI 0 "register_operand" "")
1244         (xor:DI (match_operand:DI 1 "register_operand" "")
1245                 (match_operand:DI 2 "register_operand" "")))]
1246   "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1247    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1248    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1249    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1250
1251   [(set (subreg:SI (match_dup 0) 0) (xor:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
1252    (set (subreg:SI (match_dup 0) 1) (xor:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
1253   "")
1254
1255 \f
1256 ;;
1257 ;;  ....................
1258 ;;
1259 ;;      TRUNCATION
1260 ;;
1261 ;;  ....................
1262
1263 (define_insn "truncdfsf2"
1264   [(set (match_operand:SF 0 "register_operand" "=f")
1265         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
1266   "TARGET_HARD_FLOAT"
1267   "cvt.s.d\\t%0,%1"
1268   [(set_attr "type"     "fcvt")
1269    (set_attr "mode"     "SF")
1270    (set_attr "length"   "1")])
1271
1272 \f
1273 ;;
1274 ;;  ....................
1275 ;;
1276 ;;      ZERO EXTENSION
1277 ;;
1278 ;;  ....................
1279
1280 ;; Extension insns.
1281 ;; Those for integer source operand
1282 ;; are ordered widest source type first.
1283
1284 (define_insn "zero_extendhisi2"
1285   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
1286         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
1287   ""
1288   "*
1289 {
1290   if (which_alternative == 0)
1291     return \"andi\\t%0,%1,0xffff\";
1292   else
1293     return mips_move_1word (operands, insn, TRUE);
1294 }"
1295   [(set_attr "type"     "arith,load,load")
1296    (set_attr "mode"     "SI")
1297    (set_attr "length"   "1,1,2")])
1298
1299 (define_insn "zero_extendqihi2"
1300   [(set (match_operand:HI 0 "register_operand" "=d,d,d")
1301         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
1302   ""
1303   "*
1304 {
1305   if (which_alternative == 0)
1306     return \"andi\\t%0,%1,0x00ff\";
1307   else
1308     return mips_move_1word (operands, insn, TRUE);
1309 }"
1310   [(set_attr "type"     "arith,load,load")
1311    (set_attr "mode"     "HI")
1312    (set_attr "length"   "1,1,2")])
1313
1314 (define_insn "zero_extendqisi2"
1315   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
1316         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
1317   ""
1318   "*
1319 {
1320   if (which_alternative == 0)
1321     return \"andi\\t%0,%1,0x00ff\";
1322   else
1323     return mips_move_1word (operands, insn, TRUE);
1324 }"
1325   [(set_attr "type"     "arith,load,load")
1326    (set_attr "mode"     "SI")
1327    (set_attr "length"   "1,1,2")])
1328
1329 \f
1330 ;;
1331 ;;  ....................
1332 ;;
1333 ;;      SIGN EXTENSION
1334 ;;
1335 ;;  ....................
1336
1337 ;; Extension insns.
1338 ;; Those for integer source operand
1339 ;; are ordered widest source type first.
1340
1341 ;; These patterns originally accepted general_operands, however, slightly
1342 ;; better code is generated by only accepting register_operands, and then
1343 ;; letting combine generate the lh and lb insns.
1344
1345 (define_expand "extendhisi2"
1346   [(set (match_operand:SI 0 "register_operand" "")
1347         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1348   ""
1349   "
1350 {
1351   if (optimize && GET_CODE (operands[1]) == MEM)
1352     operands[1] = force_not_mem (operands[1]);
1353
1354   if (GET_CODE (operands[1]) != MEM)
1355     {
1356       rtx op1   = gen_lowpart (SImode, operands[1]);
1357       rtx temp  = gen_reg_rtx (SImode);
1358       rtx shift = gen_rtx (CONST_INT, VOIDmode, 16);
1359
1360       emit_insn (gen_ashlsi3 (temp, op1, shift));
1361       emit_insn (gen_ashrsi3 (operands[0], temp, shift));
1362       DONE;
1363     }
1364 }")
1365
1366 (define_insn "extendhisi2_internal"
1367   [(set (match_operand:SI 0 "register_operand" "=d,d")
1368         (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
1369   ""
1370   "* return mips_move_1word (operands, insn, FALSE);"
1371   [(set_attr "type"     "load")
1372    (set_attr "mode"     "SI")
1373    (set_attr "length"   "1,2")])
1374
1375 (define_expand "extendqihi2"
1376   [(set (match_operand:HI 0 "register_operand" "")
1377         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1378   ""
1379   "
1380 {
1381   if (optimize && GET_CODE (operands[1]) == MEM)
1382     operands[1] = force_not_mem (operands[1]);
1383
1384   if (GET_CODE (operands[1]) != MEM)
1385     {
1386       rtx op0   = gen_lowpart (SImode, operands[0]);
1387       rtx op1   = gen_lowpart (SImode, operands[1]);
1388       rtx temp  = gen_reg_rtx (SImode);
1389       rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
1390
1391       emit_insn (gen_ashlsi3 (temp, op1, shift));
1392       emit_insn (gen_ashrsi3 (op0, temp, shift));
1393       DONE;
1394     }
1395 }")
1396
1397 (define_insn "extendqihi2_internal"
1398   [(set (match_operand:HI 0 "register_operand" "=d,d")
1399         (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
1400   ""
1401   "* return mips_move_1word (operands, insn, FALSE);"
1402   [(set_attr "type"     "load")
1403    (set_attr "mode"     "SI")
1404    (set_attr "length"   "1,2")])
1405
1406
1407 (define_expand "extendqisi2"
1408   [(set (match_operand:SI 0 "register_operand" "")
1409         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1410   ""
1411   "
1412 {
1413   if (optimize && GET_CODE (operands[1]) == MEM)
1414     operands[1] = force_not_mem (operands[1]);
1415
1416   if (GET_CODE (operands[1]) != MEM)
1417     {
1418       rtx op1   = gen_lowpart (SImode, operands[1]);
1419       rtx temp  = gen_reg_rtx (SImode);
1420       rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
1421
1422       emit_insn (gen_ashlsi3 (temp, op1, shift));
1423       emit_insn (gen_ashrsi3 (operands[0], temp, shift));
1424       DONE;
1425     }
1426 }")
1427
1428 (define_insn "extendqisi2_insn"
1429   [(set (match_operand:SI 0 "register_operand" "=d,d")
1430         (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
1431   ""
1432   "* return mips_move_1word (operands, insn, FALSE);"
1433   [(set_attr "type"     "load")
1434    (set_attr "mode"     "SI")
1435    (set_attr "length"   "1,2")])
1436
1437
1438 (define_insn "extendsfdf2"
1439   [(set (match_operand:DF 0 "register_operand" "=f")
1440         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
1441   "TARGET_HARD_FLOAT"
1442   "cvt.d.s\\t%0,%1"
1443   [(set_attr "type"     "fcvt")
1444    (set_attr "mode"     "DF")
1445    (set_attr "length"   "1")])
1446
1447 \f
1448
1449 ;;
1450 ;;  ....................
1451 ;;
1452 ;;      CONVERSIONS
1453 ;;
1454 ;;  ....................
1455
1456 (define_insn "fix_truncdfsi2"
1457   [(set (match_operand:SI 0 "general_operand" "=d,*f,R,o")
1458         (fix:SI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
1459    (clobber (match_scratch:SI 2 "=d,*d,d,d"))
1460    (clobber (match_scratch:DF 3 "=f,*X,f,f"))]
1461   "TARGET_HARD_FLOAT"
1462   "*
1463 {
1464   rtx xoperands[10];
1465
1466   if (which_alternative == 1)
1467     return \"trunc.w.d %0,%1,%2\";
1468
1469   output_asm_insn (\"trunc.w.d %3,%1,%2\", operands);
1470
1471   xoperands[0] = operands[0];
1472   xoperands[1] = operands[3];
1473   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1474   return \"\";
1475 }"
1476   [(set_attr "type"     "fcvt")
1477    (set_attr "mode"     "DF")
1478    (set_attr "length"   "11,9,10,11")])
1479
1480
1481 (define_insn "fix_truncsfsi2"
1482   [(set (match_operand:SI 0 "general_operand" "=d,*f,R,o")
1483         (fix:SI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
1484    (clobber (match_scratch:SI 2 "=d,*d,d,d"))
1485    (clobber (match_scratch:SF 3 "=f,*X,f,f"))]
1486   "TARGET_HARD_FLOAT"
1487   "*
1488 {
1489   rtx xoperands[10];
1490
1491   if (which_alternative == 1)
1492     return \"trunc.w.s %0,%1,%2\";
1493
1494   output_asm_insn (\"trunc.w.s %3,%1,%2\", operands);
1495
1496   xoperands[0] = operands[0];
1497   xoperands[1] = operands[3];
1498   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1499   return \"\";
1500 }"
1501   [(set_attr "type"     "fcvt")
1502    (set_attr "mode"     "SF")
1503    (set_attr "length"   "11,9,10,11")])
1504
1505
1506 (define_insn "floatsidf2"
1507   [(set (match_operand:DF 0 "register_operand" "=f,f,f")
1508         (float:DF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
1509   "TARGET_HARD_FLOAT"
1510   "*
1511 {
1512   dslots_load_total++;
1513   if (GET_CODE (operands[1]) == MEM)
1514     return \"l.s\\t%0,%1%#\;cvt.d.w\\t%0,%0\";
1515
1516   return \"mtc1\\t%1,%0%#\;cvt.d.w\\t%0,%0\";
1517 }"
1518   [(set_attr "type"     "fcvt")
1519    (set_attr "mode"     "DF")
1520    (set_attr "length"   "3,4,3")])
1521
1522
1523 (define_insn "floatsisf2"
1524   [(set (match_operand:SF 0 "register_operand" "=f,f,f")
1525         (float:SF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
1526   "TARGET_HARD_FLOAT"
1527   "*
1528 {
1529   dslots_load_total++;
1530   if (GET_CODE (operands[1]) == MEM)
1531     return \"l.s\\t%0,%1%#\;cvt.s.w\\t%0,%0\";
1532
1533   return \"mtc1\\t%1,%0%#\;cvt.s.w\\t%0,%0\";
1534 }"
1535   [(set_attr "type"     "fcvt")
1536    (set_attr "mode"     "SF")
1537    (set_attr "length"   "3,4,3")])
1538
1539
1540 (define_expand "fixuns_truncdfsi2"
1541   [(set (match_operand:SI 0 "register_operand" "")
1542         (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
1543   "TARGET_HARD_FLOAT"
1544   "
1545 {
1546   rtx reg1 = gen_reg_rtx (DFmode);
1547   rtx reg2 = gen_reg_rtx (DFmode);
1548   rtx reg3 = gen_reg_rtx (SImode);
1549   rtx label1 = gen_label_rtx ();
1550   rtx label2 = gen_label_rtx ();
1551   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
1552
1553   if (reg1)                     /* turn off complaints about unreached code */
1554     {
1555       emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
1556       do_pending_stack_adjust ();
1557
1558       emit_insn (gen_cmpdf (operands[1], reg1));
1559       emit_jump_insn (gen_bge (label1));
1560
1561       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
1562       emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
1563                                gen_rtx (LABEL_REF, VOIDmode, label2)));
1564       emit_barrier ();
1565
1566       emit_label (label1);
1567       emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1));
1568       emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
1569
1570       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
1571       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
1572
1573       emit_label (label2);
1574
1575       /* allow REG_NOTES to be set on last insn (labels don't have enough
1576          fields, and can't be used for REG_NOTES anyway).  */
1577       emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
1578       DONE;
1579     }
1580 }")
1581
1582
1583 (define_expand "fixuns_truncsfsi2"
1584   [(set (match_operand:SI 0 "register_operand" "")
1585         (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
1586   "TARGET_HARD_FLOAT"
1587   "
1588 {
1589   rtx reg1 = gen_reg_rtx (SFmode);
1590   rtx reg2 = gen_reg_rtx (SFmode);
1591   rtx reg3 = gen_reg_rtx (SImode);
1592   rtx label1 = gen_label_rtx ();
1593   rtx label2 = gen_label_rtx ();
1594   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
1595
1596   if (reg1)                     /* turn off complaints about unreached code */
1597     {
1598       emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
1599       do_pending_stack_adjust ();
1600
1601       emit_insn (gen_cmpsf (operands[1], reg1));
1602       emit_jump_insn (gen_bge (label1));
1603
1604       emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
1605       emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
1606                                gen_rtx (LABEL_REF, VOIDmode, label2)));
1607       emit_barrier ();
1608
1609       emit_label (label1);
1610       emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1));
1611       emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
1612
1613       emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
1614       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
1615
1616       emit_label (label2);
1617
1618       /* allow REG_NOTES to be set on last insn (labels don't have enough
1619          fields, and can't be used for REG_NOTES anyway).  */
1620       emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
1621       DONE;
1622     }
1623 }")
1624
1625 \f
1626 ;;
1627 ;;  ....................
1628 ;;
1629 ;;      DATA MOVEMENT
1630 ;;
1631 ;;  ....................
1632
1633 ;; unaligned word moves generated by the block moves.
1634
1635 (define_expand "movsi_unaligned"
1636   [(set (match_operand:SI 0 "general_operand" "")
1637         (unspec [(match_operand:SI 1 "general_operand" "")] 0))]
1638   ""
1639   "
1640 {
1641   /* Handle loads.  */
1642   if (GET_CODE (operands[0]) == MEM)
1643     {
1644       rtx reg = gen_reg_rtx (SImode);
1645       rtx insn = emit_insn (gen_movsi_ulw (reg, operands[1]));
1646       rtx addr = XEXP (operands[0], 0);
1647       if (CONSTANT_P (addr))
1648         REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUIV, addr, REG_NOTES (insn));
1649
1650       if (reg_or_0_operand (operands[1], SImode))
1651         DONE;
1652
1653       operands[1] = reg;
1654     }
1655
1656   /* Generate appropriate load, store.  If not a load or store,
1657      do a normal movsi.  */
1658   if (GET_CODE (operands[0]) != MEM && GET_CODE (operands[1]) != MEM)
1659     {
1660       emit_insn (gen_movsi (operands[0], operands[1]));
1661       DONE;
1662     }
1663
1664   /* Fall through and generate normal code.  */
1665 }")
1666
1667 (define_insn "movsi_ulw"
1668   [(set (match_operand:SI 0 "register_operand" "=&d,&d,d,d")
1669         (unspec [(match_operand:SI 1 "general_operand" "R,o,dIKL,M")] 0))]
1670   ""
1671   "*
1672 {
1673   enum rtx_code code;
1674   char *ret;
1675   rtx offset;
1676   rtx addr;
1677   rtx mem_addr;
1678
1679   if (which_alternative != 0)
1680     return mips_move_1word (operands, insn, FALSE);
1681
1682   if (TARGET_STATS)
1683     mips_count_memory_refs (operands[1], 2);
1684
1685   /* The stack/frame pointers are always aligned, so we can convert
1686      to the faster lw if we are referencing an aligned stack location.  */
1687
1688   offset = const0_rtx;
1689   addr = XEXP (operands[1], 0);
1690   mem_addr = eliminate_constant_term (addr, &offset);
1691
1692   if ((INTVAL (offset) & (UNITS_PER_WORD-1)) == 0
1693       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
1694     ret = \"lw\\t%0,%1\";
1695
1696   else
1697     {
1698       ret = \"ulw\\t%0,%1\";
1699       if (TARGET_GAS)
1700         {
1701           enum rtx_code code = GET_CODE (addr);
1702
1703           if (code == CONST || code == SYMBOL_REF || code == LABEL_REF)
1704             {
1705               operands[2] = gen_rtx (REG, SImode, GP_REG_FIRST + 1);
1706               ret = \"%[la\\t%2,%1\;ulw\\t%0,0(%2)%]\";
1707             }
1708         }
1709     }
1710
1711   return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
1712 }"
1713   [(set_attr "type"     "load,load,move,arith")
1714    (set_attr "mode"     "SI")
1715    (set_attr "length"   "2,4,1,2")])
1716
1717 (define_insn "movsi_usw"
1718   [(set (match_operand:SI 0 "memory_operand" "=R,o")
1719         (unspec [(match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")] 0))]
1720   ""
1721   "*
1722 {
1723   rtx offset = const0_rtx;
1724   rtx addr = XEXP (operands[0], 0);
1725   rtx mem_addr = eliminate_constant_term (addr, &offset);
1726
1727   if (TARGET_STATS)
1728     mips_count_memory_refs (operands[0], 2);
1729
1730   /* The stack/frame pointers are always aligned, so we can convert
1731      to the faster sw if we are referencing an aligned stack location.  */
1732
1733   if ((INTVAL (offset) & (UNITS_PER_WORD-1)) == 0
1734       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
1735     return \"sw\\t%1,%0\";
1736
1737
1738   if (TARGET_GAS)
1739     {
1740       enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
1741
1742       if (code == CONST || code == SYMBOL_REF || code == LABEL_REF)
1743         {
1744           operands[2] = gen_rtx (REG, SImode, GP_REG_FIRST + 1);
1745           return \"%[la\\t%2,%0\;usw\\t%z1,0(%2)%]\";
1746         }
1747     }
1748
1749   return \"usw\\t%z1,%0\";
1750 }"
1751   [(set_attr "type"     "store")
1752    (set_attr "mode"     "SI")
1753    (set_attr "length"   "2,4")])
1754
1755
1756 ;; 64-bit integer moves
1757
1758 ;; Unlike most other insns, the move insns can't be split with
1759 ;; different predicates, because register spilling and other parts of
1760 ;; the compiler, have memoized the insn number already.
1761
1762 (define_expand "movdi"
1763   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1764         (match_operand:DI 1 "general_operand" ""))]
1765   ""
1766   "
1767 {
1768   if ((reload_in_progress | reload_completed) == 0
1769       && !register_operand (operands[0], DImode)
1770       && !register_operand (operands[1], DImode)
1771       && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
1772       && operands[1] != CONST0_RTX (DImode))
1773     {
1774       rtx temp = force_reg (DImode, operands[1]);
1775       emit_move_insn (operands[0], temp);
1776       DONE;
1777     }
1778 }")
1779
1780 (define_insn "movdi_internal"
1781   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*d,*x")
1782         (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,*x,*d"))]
1783   "register_operand (operands[0], DImode)
1784    || register_operand (operands[1], DImode)
1785    || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
1786    || operands[1] == CONST0_RTX (DImode)"
1787   "* return mips_move_2words (operands, insn); "
1788   [(set_attr "type"     "move,arith,load,load,store,store,hilo,hilo")
1789    (set_attr "mode"     "DI")
1790    (set_attr "length"   "2,4,2,4,2,4,2,2")])
1791
1792 (define_split
1793   [(set (match_operand:DI 0 "register_operand" "")
1794         (match_operand:DI 1 "register_operand" ""))]
1795   "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
1796    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1797    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
1798
1799   [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
1800    (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
1801   "")
1802
1803
1804 ;; 32-bit Integer moves
1805
1806 (define_split
1807   [(set (match_operand:SI 0 "register_operand" "")
1808         (match_operand:SI 1 "large_int" ""))]
1809   "!TARGET_DEBUG_D_MODE"
1810   [(set (match_dup 0)
1811         (match_dup 2))
1812    (set (match_dup 0)
1813         (ior:SI (match_dup 0)
1814                 (match_dup 3)))]
1815   "
1816 {
1817   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xffff0000);
1818   operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0x0000ffff);
1819 }")
1820
1821 ;; Unlike most other insns, the move insns can't be split with
1822 ;; different predicates, because register spilling and other parts of
1823 ;; the compiler, have memoized the insn number already.
1824
1825 (define_expand "movsi"
1826   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1827         (match_operand:SI 1 "general_operand" ""))]
1828   ""
1829   "
1830 {
1831   if ((reload_in_progress | reload_completed) == 0
1832       && !register_operand (operands[0], SImode)
1833       && !register_operand (operands[1], SImode)
1834       && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))
1835     {
1836       rtx temp = force_reg (SImode, operands[1]);
1837       emit_move_insn (operands[0], temp);
1838       DONE;
1839     }
1840 }")
1841
1842 ;; The difference between these two is whether or not ints are allowed
1843 ;; in FP registers (off by default, use -mdebugh to enable).
1844
1845 (define_insn "movsi_internal1"
1846   [(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")
1847         (match_operand:SI 1 "general_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*f*z,*d,*f,*R,*m,*f,*f,*d,*x"))]
1848   "TARGET_DEBUG_H_MODE
1849    && (register_operand (operands[0], SImode)
1850        || register_operand (operands[1], SImode)
1851        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
1852   "* return mips_move_1word (operands, insn, TRUE);"
1853   [(set_attr "type"     "move,load,arith,arith,load,load,store,store,xfer,xfer,move,load,load,store,store,hilo,hilo")
1854    (set_attr "mode"     "SI")
1855    (set_attr "length"   "1,2,1,2,1,2,1,2,1,1,1,1,2,1,2,1,1")])
1856
1857 (define_insn "movsi_internal2"
1858   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*z,*d,*x")
1859         (match_operand:SI 1 "general_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,*x,*d"))]
1860   "!TARGET_DEBUG_H_MODE
1861    && (register_operand (operands[0], SImode)
1862        || register_operand (operands[1], SImode)
1863        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
1864   "* return mips_move_1word (operands, insn, TRUE);"
1865   [(set_attr "type"     "move,load,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo")
1866    (set_attr "mode"     "SI")
1867    (set_attr "length"   "1,2,1,2,1,2,1,2,1,1,1,1")])
1868
1869
1870 ;; 16-bit Integer moves
1871
1872 ;; Unlike most other insns, the move insns can't be split with
1873 ;; different predicates, because register spilling and other parts of
1874 ;; the compiler, have memoized the insn number already.
1875 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
1876
1877 (define_expand "movhi"
1878   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1879         (match_operand:HI 1 "general_operand" ""))]
1880   ""
1881   "
1882 {
1883   if ((reload_in_progress | reload_completed) == 0
1884       && !register_operand (operands[0], HImode)
1885       && !register_operand (operands[1], HImode)
1886       && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))
1887     {
1888       rtx temp = force_reg (HImode, operands[1]);
1889       emit_move_insn (operands[0], temp);
1890       DONE;
1891     }
1892 }")
1893
1894 ;; The difference between these two is whether or not ints are allowed
1895 ;; in FP registers (off by default, use -mdebugh to enable).
1896
1897 (define_insn "movhi_internal1"
1898   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f*z,*x,*d")
1899         (match_operand:HI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
1900   "TARGET_DEBUG_H_MODE
1901    && (register_operand (operands[0], HImode)
1902        || register_operand (operands[1], HImode)
1903        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
1904   "* return mips_move_1word (operands, insn, TRUE);"
1905   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
1906    (set_attr "mode"     "HI")
1907    (set_attr "length"   "1,1,1,2,1,2,1,1,1,1,1")])
1908
1909 (define_insn "movhi_internal2"
1910   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
1911         (match_operand:HI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
1912   "!TARGET_DEBUG_H_MODE
1913    && (register_operand (operands[0], HImode)
1914        || register_operand (operands[1], HImode)
1915        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
1916   "* return mips_move_1word (operands, insn, TRUE);"
1917   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
1918    (set_attr "mode"     "HI")
1919    (set_attr "length"   "1,1,1,2,1,2,1,1,1,1")])
1920
1921
1922 ;; 8-bit Integer moves
1923
1924 ;; Unlike most other insns, the move insns can't be split with
1925 ;; different predicates, because register spilling and other parts of
1926 ;; the compiler, have memoized the insn number already.
1927 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
1928
1929 (define_expand "movqi"
1930   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1931         (match_operand:QI 1 "general_operand" ""))]
1932   ""
1933   "
1934 {
1935   if ((reload_in_progress | reload_completed) == 0
1936       && !register_operand (operands[0], QImode)
1937       && !register_operand (operands[1], QImode)
1938       && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))
1939     {
1940       rtx temp = force_reg (QImode, operands[1]);
1941       emit_move_insn (operands[0], temp);
1942       DONE;
1943     }
1944 }")
1945
1946 ;; The difference between these two is whether or not ints are allowed
1947 ;; in FP registers (off by default, use -mdebugh to enable).
1948
1949 (define_insn "movqi_internal1"
1950   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
1951         (match_operand:QI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
1952   "TARGET_DEBUG_H_MODE
1953    && (register_operand (operands[0], QImode)
1954        || register_operand (operands[1], QImode)
1955        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
1956   "* return mips_move_1word (operands, insn, TRUE);"
1957   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
1958    (set_attr "mode"     "QI")
1959    (set_attr "length"   "1,1,1,2,1,2,1,1,1,1,1")])
1960
1961 (define_insn "movqi_internal2"
1962   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
1963         (match_operand:QI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
1964   "!TARGET_DEBUG_H_MODE
1965    && (register_operand (operands[0], QImode)
1966        || register_operand (operands[1], QImode)
1967        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
1968   "* return mips_move_1word (operands, insn, TRUE);"
1969   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
1970    (set_attr "mode"     "QI")
1971    (set_attr "length"   "1,1,1,2,1,2,1,1,1,1")])
1972
1973
1974 ;; 32-bit floating point moves
1975
1976 (define_expand "movsf"
1977   [(set (match_operand:SF 0 "nonimmediate_operand" "")
1978         (match_operand:SF 1 "general_operand" ""))]
1979   ""
1980   "
1981 {
1982   if ((reload_in_progress | reload_completed) == 0
1983       && !register_operand (operands[0], SFmode)
1984       && !register_operand (operands[1], SFmode)
1985       && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
1986       && operands[1] != CONST0_RTX (SFmode))
1987     {
1988       rtx temp = force_reg (SFmode, operands[1]);
1989       emit_move_insn (operands[0], temp);
1990       DONE;
1991     }
1992 }")
1993
1994 (define_insn "movsf_internal"
1995   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m")
1996         (match_operand:SF 1 "general_operand" "f,G,R,Em,fG,fG,*d,*f,*G*d,*R,*E*m,*d,*d"))]
1997   "register_operand (operands[0], SFmode)
1998    || register_operand (operands[1], SFmode)
1999    || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
2000    || operands[1] == CONST0_RTX (SFmode)"
2001   "* return mips_move_1word (operands, insn, FALSE);"
2002   [(set_attr "type"     "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store")
2003    (set_attr "mode"     "SF")
2004    (set_attr "length"   "1,1,1,2,1,2,1,1,1,1,2,1,2")])
2005
2006
2007 ;; 64-bit floating point moves
2008
2009 (define_expand "movdf"
2010   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2011         (match_operand:DF 1 "general_operand" ""))]
2012   ""
2013   "
2014 {
2015   if ((reload_in_progress | reload_completed) == 0
2016       && !register_operand (operands[0], DFmode)
2017       && !register_operand (operands[1], DFmode)
2018       && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
2019       && operands[1] != CONST0_RTX (DFmode))
2020     {
2021       rtx temp = force_reg (DFmode, operands[1]);
2022       emit_move_insn (operands[0], temp);
2023       DONE;
2024     }
2025 }")
2026
2027 (define_insn "movdf_internal"
2028   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,o,f,*f,*d,*d,*d,*d,*R,*o")
2029         (match_operand:DF 1 "general_operand" "f,R,o,fG,fG,E,*d,*f,*d*G,*R,*o*E,*d,*d"))]
2030   "register_operand (operands[0], DFmode)
2031    || register_operand (operands[1], DFmode)
2032    || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
2033    || operands[1] == CONST0_RTX (DFmode)"
2034   "* return mips_move_2words (operands, insn); "
2035   [(set_attr "type"     "move,load,load,store,store,load,xfer,xfer,move,load,load,store,store")
2036    (set_attr "mode"     "DF")
2037    (set_attr "length"   "1,2,4,2,4,4,2,2,2,2,4,2,4")])
2038
2039 (define_split
2040   [(set (match_operand:DF 0 "register_operand" "")
2041         (match_operand:DF 1 "register_operand" ""))]
2042   "reload_completed && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2043    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
2044    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
2045
2046   [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
2047    (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
2048   "")
2049
2050 \f
2051 ;; Block moves, see mips.c for more details.
2052 ;; Argument 0 is the destination
2053 ;; Argument 1 is the source
2054 ;; Argument 2 is the length
2055 ;; Argument 3 is the alignment
2056
2057 (define_expand "movstrsi"
2058   [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
2059                    (mem:BLK (match_operand:BLK 1 "general_operand" "")))
2060               (use (match_operand:SI 2 "arith32_operand" ""))
2061               (use (match_operand:SI 3 "immediate_operand" ""))])]
2062   ""
2063   "
2064 {
2065   if (operands[0])              /* avoid unused code messages */
2066     {
2067       expand_block_move (operands);
2068       DONE;
2069     }
2070 }")
2071
2072 ;; Insn generated by block moves
2073
2074 (define_insn "movstrsi_internal"
2075   [(set (match_operand:BLK 0 "memory_operand" "=Ro")    ;; destination
2076         (match_operand:BLK 1 "memory_operand" "Ro"))    ;; source
2077    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
2078    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
2079    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
2080    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
2081    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
2082    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
2083    (use (const_int 0))]                                 ;; normal block move
2084   ""
2085   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
2086   [(set_attr "type"     "multi")
2087    (set_attr "mode"     "none")
2088    (set_attr "length"   "20")])
2089
2090 ;; Split a block move into 2 parts, the first part is everything
2091 ;; except for the last move, and the second part is just the last
2092 ;; store, which is exactly 1 instruction (ie, not a usw), so it can
2093 ;; fill a delay slot.  This also prevents a bug in delayed branches
2094 ;; from showing up, which reuses one of the registers in our clobbers.
2095
2096 (define_split
2097   [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
2098         (mem:BLK (match_operand:SI 1 "register_operand" "")))
2099    (clobber (match_operand:SI 4 "register_operand" ""))
2100    (clobber (match_operand:SI 5 "register_operand" ""))
2101    (clobber (match_operand:SI 6 "register_operand" ""))
2102    (clobber (match_operand:SI 7 "register_operand" ""))
2103    (use (match_operand:SI 2 "small_int" ""))
2104    (use (match_operand:SI 3 "small_int" ""))
2105    (use (const_int 0))]
2106
2107   "reload_completed && !TARGET_DEBUG_D_MODE && INTVAL (operands[2]) > 0"
2108
2109   ;; All but the last move
2110   [(parallel [(set (mem:BLK (match_dup 0))
2111                    (mem:BLK (match_dup 1)))
2112               (clobber (match_dup 4))
2113               (clobber (match_dup 5))
2114               (clobber (match_dup 6))
2115               (clobber (match_dup 7))
2116               (use (match_dup 2))
2117               (use (match_dup 3))
2118               (use (const_int 1))])
2119
2120    ;; The last store, so it can fill a delay slot
2121    (parallel [(set (mem:BLK (match_dup 0))
2122                    (mem:BLK (match_dup 1)))
2123               (clobber (match_dup 4))
2124               (clobber (match_dup 5))
2125               (clobber (match_dup 6))
2126               (clobber (match_dup 7))
2127               (use (match_dup 2))
2128               (use (match_dup 3))
2129               (use (const_int 2))])]
2130
2131   "")
2132
2133 (define_insn "movstrsi_internal2"
2134   [(set (match_operand:BLK 0 "memory_operand" "=Ro")    ;; destination
2135         (match_operand:BLK 1 "memory_operand" "Ro"))    ;; source
2136    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
2137    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
2138    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
2139    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
2140    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
2141    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
2142    (use (const_int 1))]                                 ;; all but last store
2143   ""
2144   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
2145   [(set_attr "type"     "multi")
2146    (set_attr "mode"     "none")
2147    (set_attr "length"   "20")])
2148
2149 (define_insn "movstrsi_internal3"
2150   [(set (match_operand:BLK 0 "memory_operand" "=Ro")    ;; destination
2151         (match_operand:BLK 1 "memory_operand" "Ro"))    ;; source
2152    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
2153    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
2154    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
2155    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
2156    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
2157    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
2158    (use (const_int 2))]                                 ;; just last store of block mvoe
2159   ""
2160   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
2161   [(set_attr "type"     "store")
2162    (set_attr "mode"     "none")
2163    (set_attr "length"   "1")])
2164
2165 \f
2166 ;;
2167 ;;  ....................
2168 ;;
2169 ;;      SHIFTS
2170 ;;
2171 ;;  ....................
2172
2173 (define_insn "ashlsi3"
2174   [(set (match_operand:SI 0 "register_operand" "=d")
2175         (ashift:SI (match_operand:SI 1 "register_operand" "d")
2176                    (match_operand:SI 2 "arith_operand" "dI")))]
2177   ""
2178   "*
2179 {
2180   if (GET_CODE (operands[2]) == CONST_INT)
2181     operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
2182
2183   return \"sll\\t%0,%1,%2\";
2184 }"
2185   [(set_attr "type"     "arith")
2186    (set_attr "mode"     "SI")
2187    (set_attr "length"   "1")])
2188
2189
2190 (define_expand "ashldi3"
2191   [(parallel [(set (match_operand:DI 0 "register_operand" "")
2192                    (ashift:DI (match_operand:DI 1 "register_operand" "")
2193                               (match_operand:SI 2 "arith_operand" "")))
2194               (clobber (match_dup  3))])]
2195   "!TARGET_DEBUG_G_MODE"
2196   "operands[3] = gen_reg_rtx (SImode);")
2197
2198
2199 (define_insn "ashldi3_internal"
2200   [(set (match_operand:DI 0 "register_operand" "=&d")
2201         (ashift:DI (match_operand:DI 1 "register_operand" "d")
2202                    (match_operand:SI 2 "register_operand" "d")))
2203    (clobber (match_operand:SI 3 "register_operand" "=d"))]
2204   "!TARGET_DEBUG_G_MODE"
2205   "* 
2206 {
2207   operands[4] = const0_rtx;
2208   dslots_jump_total += 3;
2209   dslots_jump_filled += 2;
2210
2211   return \"sll\\t%3,%2,26\\n\\
2212 \\tbgez\\t%3,1f\\n\\
2213 \\tsll\\t%M0,%L1,%2\\n\\
2214 \\t%(b\\t3f\\n\\
2215 \\tmove\\t%L0,%z4%)\\n\\
2216 \\n\\
2217 1:\\n\\
2218 \\t%(beq\\t%3,%z4,2f\\n\\
2219 \\tsll\\t%M0,%M1,%2%)\\n\\
2220 \\n\\
2221 \\tsubu\\t%3,%z4,%2\\n\\
2222 \\tsrl\\t%3,%L1,%3\\n\\
2223 \\tor\\t%M0,%M0,%3\\n\\
2224 2:\\n\\
2225 \\tsll\\t%L0,%L1,%2\\n\\
2226 3:\";
2227 }"
2228   [(set_attr "type"     "darith")
2229    (set_attr "mode"     "SI")
2230    (set_attr "length"   "12")])
2231
2232
2233 (define_insn "ashldi3_internal2"
2234   [(set (match_operand:DI 0 "register_operand" "=d")
2235         (ashift:DI (match_operand:DI 1 "register_operand" "d")
2236                    (match_operand:SI 2 "small_int" "IJK")))
2237    (clobber (match_operand:SI 3 "register_operand" "=d"))]
2238   "!TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
2239   "*
2240 {
2241   operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
2242   operands[4] = const0_rtx;
2243   return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\";
2244 }"
2245   [(set_attr "type"     "darith")
2246    (set_attr "mode"     "DI")
2247    (set_attr "length"   "2")])
2248
2249
2250 (define_split
2251   [(set (match_operand:DI 0 "register_operand" "")
2252         (ashift:DI (match_operand:DI 1 "register_operand" "")
2253                    (match_operand:SI 2 "small_int" "")))
2254    (clobber (match_operand:SI 3 "register_operand" ""))]
2255   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2256    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2257    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2258    && (INTVAL (operands[2]) & 32) != 0"
2259
2260   [(set (subreg:SI (match_dup 0) 1) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
2261    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
2262
2263   "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);")
2264
2265
2266 (define_split
2267   [(set (match_operand:DI 0 "register_operand" "")
2268         (ashift:DI (match_operand:DI 1 "register_operand" "")
2269                    (match_operand:SI 2 "small_int" "")))
2270    (clobber (match_operand:SI 3 "register_operand" ""))]
2271   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2272    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2273    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2274    && (INTVAL (operands[2]) & 32) != 0"
2275
2276   [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
2277    (set (subreg:SI (match_dup 0) 1) (const_int 0))]
2278
2279   "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);")
2280
2281
2282 (define_insn "ashldi3_internal3"
2283   [(set (match_operand:DI 0 "register_operand" "=d")
2284         (ashift:DI (match_operand:DI 1 "register_operand" "d")
2285                    (match_operand:SI 2 "small_int" "IJK")))
2286    (clobber (match_operand:SI 3 "register_operand" "=d"))]
2287   "!TARGET_DEBUG_G_MODE
2288    && (INTVAL (operands[2]) & 63) < 32
2289    && (INTVAL (operands[2]) & 63) != 0"
2290   "*
2291 {
2292   int amount = INTVAL (operands[2]);
2293
2294   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
2295   operands[4] = const0_rtx;
2296   operands[5] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
2297
2298   return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\";
2299 }"
2300   [(set_attr "type"     "darith")
2301    (set_attr "mode"     "DI")
2302    (set_attr "length"   "4")])
2303
2304
2305 (define_split
2306   [(set (match_operand:DI 0 "register_operand" "")
2307         (ashift:DI (match_operand:DI 1 "register_operand" "")
2308                    (match_operand:SI 2 "small_int" "")))
2309    (clobber (match_operand:SI 3 "register_operand" ""))]
2310   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2311    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2312    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2313    && (INTVAL (operands[2]) & 63) < 32
2314    && (INTVAL (operands[2]) & 63) != 0"
2315
2316   [(set (subreg:SI (match_dup 0) 1)
2317         (ashift:SI (subreg:SI (match_dup 1) 1)
2318                    (match_dup 2)))
2319
2320    (set (match_dup 3)
2321         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
2322                      (match_dup 4)))
2323
2324    (set (subreg:SI (match_dup 0) 1)
2325         (ior:SI (subreg:SI (match_dup 0) 1)
2326                 (match_dup 3)))
2327
2328    (set (subreg:SI (match_dup 0) 0)
2329         (ashift:SI (subreg:SI (match_dup 1) 0)
2330                    (match_dup 2)))]
2331   "
2332 {
2333   int amount = INTVAL (operands[2]);
2334   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
2335   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
2336 }")
2337
2338
2339 (define_split
2340   [(set (match_operand:DI 0 "register_operand" "")
2341         (ashift:DI (match_operand:DI 1 "register_operand" "")
2342                    (match_operand:SI 2 "small_int" "")))
2343    (clobber (match_operand:SI 3 "register_operand" ""))]
2344   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2345    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2346    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2347    && (INTVAL (operands[2]) & 63) < 32
2348    && (INTVAL (operands[2]) & 63) != 0"
2349
2350   [(set (subreg:SI (match_dup 0) 0)
2351         (ashift:SI (subreg:SI (match_dup 1) 0)
2352                    (match_dup 2)))
2353
2354    (set (match_dup 3)
2355         (lshiftrt:SI (subreg:SI (match_dup 1) 1)
2356                      (match_dup 4)))
2357
2358    (set (subreg:SI (match_dup 0) 0)
2359         (ior:SI (subreg:SI (match_dup 0) 0)
2360                 (match_dup 3)))
2361
2362    (set (subreg:SI (match_dup 0) 1)
2363         (ashift:SI (subreg:SI (match_dup 1) 1)
2364                    (match_dup 2)))]
2365   "
2366 {
2367   int amount = INTVAL (operands[2]);
2368   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
2369   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
2370 }")
2371
2372
2373 (define_insn "ashrsi3"
2374   [(set (match_operand:SI 0 "register_operand" "=d")
2375         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
2376                      (match_operand:SI 2 "arith_operand" "dI")))]
2377   ""
2378   "*
2379 {
2380   if (GET_CODE (operands[2]) == CONST_INT)
2381     operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
2382
2383   return \"sra\\t%0,%1,%2\";
2384 }"
2385   [(set_attr "type"     "arith")
2386    (set_attr "mode"     "SI")
2387    (set_attr "length"   "1")])
2388
2389
2390 (define_expand "ashrdi3"
2391   [(parallel [(set (match_operand:DI 0 "register_operand" "")
2392                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
2393                                 (match_operand:SI 2 "arith_operand" "")))
2394               (clobber (match_dup  3))])]
2395   "!TARGET_DEBUG_G_MODE"
2396   "operands[3] = gen_reg_rtx (SImode);")
2397
2398
2399 (define_insn "ashrdi3_internal"
2400   [(set (match_operand:DI 0 "register_operand" "=&d")
2401         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2402                      (match_operand:SI 2 "register_operand" "d")))
2403    (clobber (match_operand:SI 3 "register_operand" "=d"))]
2404   "!TARGET_DEBUG_G_MODE"
2405   "* 
2406 {
2407   operands[4] = const0_rtx;
2408   dslots_jump_total += 3;
2409   dslots_jump_filled += 2;
2410
2411   return \"sll\\t%3,%2,26\\n\\
2412 \\tbgez\\t%3,1f\\n\\
2413 \\tsra\\t%L0,%M1,%2\\n\\
2414 \\t%(b\\t3f\\n\\
2415 \\tsra\\t%M0,%M1,31%)\\n\\
2416 \\n\\
2417 1:\\n\\
2418 \\t%(beq\\t%3,%z4,2f\\n\\
2419 \\tsrl\\t%L0,%L1,%2%)\\n\\
2420 \\n\\
2421 \\tsubu\\t%3,%z4,%2\\n\\
2422 \\tsll\\t%3,%M1,%3\\n\\
2423 \\tor\\t%L0,%L0,%3\\n\\
2424 2:\\n\\
2425 \\tsra\\t%M0,%M1,%2\\n\\
2426 3:\";
2427 }"
2428   [(set_attr "type"     "darith")
2429    (set_attr "mode"     "DI")
2430    (set_attr "length"   "12")])
2431
2432
2433 (define_insn "ashrdi3_internal2"
2434   [(set (match_operand:DI 0 "register_operand" "=d")
2435         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2436                      (match_operand:SI 2 "small_int" "IJK")))
2437    (clobber (match_operand:SI 3 "register_operand" "=d"))]
2438   "!TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
2439   "*
2440 {
2441   operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
2442   return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\";
2443 }"
2444   [(set_attr "type"     "darith")
2445    (set_attr "mode"     "DI")
2446    (set_attr "length"   "2")])
2447
2448
2449 (define_split
2450   [(set (match_operand:DI 0 "register_operand" "")
2451         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
2452                      (match_operand:SI 2 "small_int" "")))
2453    (clobber (match_operand:SI 3 "register_operand" ""))]
2454   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2455    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2456    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2457    && (INTVAL (operands[2]) & 32) != 0"
2458
2459   [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
2460    (set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (const_int 31)))]
2461
2462   "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);")
2463
2464
2465 (define_split
2466   [(set (match_operand:DI 0 "register_operand" "")
2467         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
2468                      (match_operand:SI 2 "small_int" "")))
2469    (clobber (match_operand:SI 3 "register_operand" ""))]
2470   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2471    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2472    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2473    && (INTVAL (operands[2]) & 32) != 0"
2474
2475   [(set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
2476    (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
2477
2478   "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);")
2479
2480
2481 (define_insn "ashrdi3_internal3"
2482   [(set (match_operand:DI 0 "register_operand" "=d")
2483         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2484                      (match_operand:SI 2 "small_int" "IJK")))
2485    (clobber (match_operand:SI 3 "register_operand" "=d"))]
2486   "!TARGET_DEBUG_G_MODE
2487    && (INTVAL (operands[2]) & 63) < 32
2488    && (INTVAL (operands[2]) & 63) != 0"
2489   "*
2490 {
2491   int amount = INTVAL (operands[2]);
2492
2493   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
2494   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
2495
2496   return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\";
2497 }"
2498   [(set_attr "type"     "darith")
2499    (set_attr "mode"     "DI")
2500    (set_attr "length"   "4")])
2501
2502
2503 (define_split
2504   [(set (match_operand:DI 0 "register_operand" "")
2505         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
2506                      (match_operand:SI 2 "small_int" "")))
2507    (clobber (match_operand:SI 3 "register_operand" ""))]
2508   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2509    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2510    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2511    && (INTVAL (operands[2]) & 63) < 32
2512    && (INTVAL (operands[2]) & 63) != 0"
2513
2514   [(set (subreg:SI (match_dup 0) 0)
2515         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
2516                      (match_dup 2)))
2517
2518    (set (match_dup 3)
2519         (ashift:SI (subreg:SI (match_dup 1) 1)
2520                    (match_dup 4)))
2521
2522    (set (subreg:SI (match_dup 0) 0)
2523         (ior:SI (subreg:SI (match_dup 0) 0)
2524                 (match_dup 3)))
2525
2526    (set (subreg:SI (match_dup 0) 1)
2527         (ashiftrt:SI (subreg:SI (match_dup 1) 1)
2528                      (match_dup 2)))]
2529   "
2530 {
2531   int amount = INTVAL (operands[2]);
2532   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
2533   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
2534 }")
2535
2536
2537 (define_split
2538   [(set (match_operand:DI 0 "register_operand" "")
2539         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
2540                      (match_operand:SI 2 "small_int" "")))
2541    (clobber (match_operand:SI 3 "register_operand" ""))]
2542   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2543    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2544    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2545    && (INTVAL (operands[2]) & 63) < 32
2546    && (INTVAL (operands[2]) & 63) != 0"
2547
2548   [(set (subreg:SI (match_dup 0) 1)
2549         (lshiftrt:SI (subreg:SI (match_dup 1) 1)
2550                      (match_dup 2)))
2551
2552    (set (match_dup 3)
2553         (ashift:SI (subreg:SI (match_dup 1) 0)
2554                    (match_dup 4)))
2555
2556    (set (subreg:SI (match_dup 0) 1)
2557         (ior:SI (subreg:SI (match_dup 0) 1)
2558                 (match_dup 3)))
2559
2560    (set (subreg:SI (match_dup 0) 0)
2561         (ashiftrt:SI (subreg:SI (match_dup 1) 0)
2562                      (match_dup 2)))]
2563   "
2564 {
2565   int amount = INTVAL (operands[2]);
2566   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
2567   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
2568 }")
2569
2570
2571 (define_insn "lshrsi3"
2572   [(set (match_operand:SI 0 "register_operand" "=d")
2573         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
2574                      (match_operand:SI 2 "arith_operand" "dI")))]
2575   ""
2576   "*
2577 {
2578   if (GET_CODE (operands[2]) == CONST_INT)
2579     operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
2580
2581   return \"srl\\t%0,%1,%2\";
2582 }"
2583   [(set_attr "type"     "arith")
2584    (set_attr "mode"     "SI")
2585    (set_attr "length"   "1")])
2586
2587
2588 (define_expand "lshrdi3"
2589   [(parallel [(set (match_operand:DI 0 "register_operand" "")
2590                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
2591                                 (match_operand:SI 2 "arith_operand" "")))
2592               (clobber (match_dup  3))])]
2593   "!TARGET_DEBUG_G_MODE"
2594   "operands[3] = gen_reg_rtx (SImode);")
2595
2596
2597 (define_insn "lshrdi3_internal"
2598   [(set (match_operand:DI 0 "register_operand" "=&d")
2599         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2600                      (match_operand:SI 2 "register_operand" "d")))
2601    (clobber (match_operand:SI 3 "register_operand" "=d"))]
2602   "!TARGET_DEBUG_G_MODE"
2603   "* 
2604 {
2605   operands[4] = const0_rtx;
2606   dslots_jump_total += 3;
2607   dslots_jump_filled += 2;
2608
2609   return \"sll\\t%3,%2,26\\n\\
2610 \\tbgez\\t%3,1f\\n\\
2611 \\tsrl\\t%L0,%M1,%2\\n\\
2612 \\t%(b\\t3f\\n\\
2613 \\tmove\\t%M0,%z4%)\\n\\
2614 \\n\\
2615 1:\\n\\
2616 \\t%(beq\\t%3,%z4,2f\\n\\
2617 \\tsrl\\t%L0,%L1,%2%)\\n\\
2618 \\n\\
2619 \\tsubu\\t%3,%z4,%2\\n\\
2620 \\tsll\\t%3,%M1,%3\\n\\
2621 \\tor\\t%L0,%L0,%3\\n\\
2622 2:\\n\\
2623 \\tsrl\\t%M0,%M1,%2\\n\\
2624 3:\";
2625 }"
2626   [(set_attr "type"     "darith")
2627    (set_attr "mode"     "DI")
2628    (set_attr "length"   "12")])
2629
2630
2631 (define_insn "lshrdi3_internal2"
2632   [(set (match_operand:DI 0 "register_operand" "=d")
2633         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2634                      (match_operand:SI 2 "small_int" "IJK")))
2635    (clobber (match_operand:SI 3 "register_operand" "=d"))]
2636   "!TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
2637   "*
2638 {
2639   operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
2640   operands[4] = const0_rtx;
2641   return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\";
2642 }"
2643   [(set_attr "type"     "darith")
2644    (set_attr "mode"     "DI")
2645    (set_attr "length"   "2")])
2646
2647
2648 (define_split
2649   [(set (match_operand:DI 0 "register_operand" "")
2650         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
2651                      (match_operand:SI 2 "small_int" "")))
2652    (clobber (match_operand:SI 3 "register_operand" ""))]
2653   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2654    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2655    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2656    && (INTVAL (operands[2]) & 32) != 0"
2657
2658   [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
2659    (set (subreg:SI (match_dup 0) 1) (const_int 0))]
2660
2661   "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);")
2662
2663
2664 (define_split
2665   [(set (match_operand:DI 0 "register_operand" "")
2666         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
2667                      (match_operand:SI 2 "small_int" "")))
2668    (clobber (match_operand:SI 3 "register_operand" ""))]
2669   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2670    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2671    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2672    && (INTVAL (operands[2]) & 32) != 0"
2673
2674   [(set (subreg:SI (match_dup 0) 1) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
2675    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
2676
2677   "operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);")
2678
2679
2680 (define_insn "lshrdi3_internal3"
2681   [(set (match_operand:DI 0 "register_operand" "=d")
2682         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2683                    (match_operand:SI 2 "small_int" "IJK")))
2684    (clobber (match_operand:SI 3 "register_operand" "=d"))]
2685   "!TARGET_DEBUG_G_MODE
2686    && (INTVAL (operands[2]) & 63) < 32
2687    && (INTVAL (operands[2]) & 63) != 0"
2688   "*
2689 {
2690   int amount = INTVAL (operands[2]);
2691
2692   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
2693   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
2694
2695   return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\";
2696 }"
2697   [(set_attr "type"     "darith")
2698    (set_attr "mode"     "DI")
2699    (set_attr "length"   "4")])
2700
2701
2702 (define_split
2703   [(set (match_operand:DI 0 "register_operand" "")
2704         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
2705                      (match_operand:SI 2 "small_int" "")))
2706    (clobber (match_operand:SI 3 "register_operand" ""))]
2707   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2708    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2709    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2710    && (INTVAL (operands[2]) & 63) < 32
2711    && (INTVAL (operands[2]) & 63) != 0"
2712
2713   [(set (subreg:SI (match_dup 0) 0)
2714         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
2715                      (match_dup 2)))
2716
2717    (set (match_dup 3)
2718         (ashift:SI (subreg:SI (match_dup 1) 1)
2719                    (match_dup 4)))
2720
2721    (set (subreg:SI (match_dup 0) 0)
2722         (ior:SI (subreg:SI (match_dup 0) 0)
2723                 (match_dup 3)))
2724
2725    (set (subreg:SI (match_dup 0) 1)
2726         (lshiftrt:SI (subreg:SI (match_dup 1) 1)
2727                      (match_dup 2)))]
2728   "
2729 {
2730   int amount = INTVAL (operands[2]);
2731   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
2732   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
2733 }")
2734
2735
2736 (define_split
2737   [(set (match_operand:DI 0 "register_operand" "")
2738         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
2739                      (match_operand:SI 2 "small_int" "")))
2740    (clobber (match_operand:SI 3 "register_operand" ""))]
2741   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2742    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
2743    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
2744    && (INTVAL (operands[2]) & 63) < 32
2745    && (INTVAL (operands[2]) & 63) != 0"
2746
2747   [(set (subreg:SI (match_dup 0) 1)
2748         (lshiftrt:SI (subreg:SI (match_dup 1) 1)
2749                      (match_dup 2)))
2750
2751    (set (match_dup 3)
2752         (ashift:SI (subreg:SI (match_dup 1) 0)
2753                    (match_dup 4)))
2754
2755    (set (subreg:SI (match_dup 0) 1)
2756         (ior:SI (subreg:SI (match_dup 0) 1)
2757                 (match_dup 3)))
2758
2759    (set (subreg:SI (match_dup 0) 0)
2760         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
2761                      (match_dup 2)))]
2762   "
2763 {
2764   int amount = INTVAL (operands[2]);
2765   operands[2] = gen_rtx (CONST_INT, VOIDmode, (amount & 31));
2766   operands[4] = gen_rtx (CONST_INT, VOIDmode, ((-amount) & 31));
2767 }")
2768
2769 \f
2770 ;;
2771 ;;  ....................
2772 ;;
2773 ;;      COMPARISONS
2774 ;;
2775 ;;  ....................
2776
2777 ;; Flow here is rather complex:
2778 ;;
2779 ;;  1)  The cmp{si,sf,df} routine is called.  It deposits the
2780 ;;      arguments into the branch_cmp array, and the type into
2781 ;;      branch_type.  No RTL is generated.
2782 ;;
2783 ;;  2)  The appropriate branch define_expand is called, which then
2784 ;;      creates the appropriate RTL for the comparison and branch.
2785 ;;      Different CC modes are used, based on what type of branch is
2786 ;;      done, so that we can constrain things appropriately.  There
2787 ;;      are assumptions in the rest of GCC that break if we fold the
2788 ;;      operands into the branchs for integer operations, and use cc0
2789 ;;      for floating point, so we use the fp status register instead.
2790 ;;      If needed, an appropriate temporary is created to hold the
2791 ;;      of the integer compare.
2792
2793 (define_expand "cmpsi"
2794   [(set (cc0)
2795         (compare:CC (match_operand:SI 0 "register_operand" "")
2796                     (match_operand:SI 1 "arith_operand" "")))]
2797   ""
2798   "
2799 {
2800   if (operands[0])              /* avoid unused code message */
2801     {
2802       branch_cmp[0] = operands[0];
2803       branch_cmp[1] = operands[1];
2804       branch_type = CMP_SI;
2805       DONE;
2806     }
2807 }")
2808
2809 (define_expand "tstsi"
2810   [(set (cc0)
2811         (match_operand:SI 0 "register_operand" ""))]
2812   ""
2813   "
2814 {
2815   if (operands[0])              /* avoid unused code message */
2816     {
2817       branch_cmp[0] = operands[0];
2818       branch_cmp[1] = const0_rtx;
2819       branch_type = CMP_SI;
2820       DONE;
2821     }
2822 }")
2823
2824 (define_expand "cmpdf"
2825   [(set (cc0)
2826         (compare:CC_FP (match_operand:DF 0 "register_operand" "")
2827                        (match_operand:DF 1 "register_operand" "")))]
2828   "TARGET_HARD_FLOAT"
2829   "
2830 {
2831   if (operands[0])              /* avoid unused code message */
2832     {
2833       branch_cmp[0] = operands[0];
2834       branch_cmp[1] = operands[1];
2835       branch_type = CMP_DF;
2836       DONE;
2837     }
2838 }")
2839
2840 (define_expand "cmpsf"
2841   [(set (cc0)
2842         (compare:CC_FP (match_operand:SF 0 "register_operand" "")
2843                        (match_operand:SF 1 "register_operand" "")))]
2844   "TARGET_HARD_FLOAT"
2845   "
2846 {
2847   if (operands[0])              /* avoid unused code message */
2848     {
2849       branch_cmp[0] = operands[0];
2850       branch_cmp[1] = operands[1];
2851       branch_type = CMP_SF;
2852       DONE;
2853     }
2854 }")
2855
2856 \f
2857 ;;
2858 ;;  ....................
2859 ;;
2860 ;;      CONDITIONAL BRANCHES
2861 ;;
2862 ;;  ....................
2863
2864 (define_insn "branch_fp_ne"
2865   [(set (pc)
2866         (if_then_else (ne:CC_FP (reg:CC_FP 66)
2867                                 (const_int 0))
2868                       (match_operand 0 "pc_or_label_operand" "")
2869                       (match_operand 1 "pc_or_label_operand" "")))]
2870   ""
2871   "*
2872 {
2873   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2874   return (operands[0] != pc_rtx) ? \"%*bc1t%?\\t%0\" : \"%*bc1f%?\\t%1\";
2875 }"
2876   [(set_attr "type"     "branch")
2877    (set_attr "mode"     "none")
2878    (set_attr "length"   "1")])
2879
2880 (define_insn "branch_fp_ne_rev"
2881   [(set (pc)
2882         (if_then_else (ne:CC_REV_FP (reg:CC_REV_FP 66)
2883                                     (const_int 0))
2884                       (match_operand 0 "pc_or_label_operand" "")
2885                       (match_operand 1 "pc_or_label_operand" "")))]
2886   ""
2887   "*
2888 {
2889   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2890   return (operands[0] != pc_rtx) ? \"%*bc1f%?\\t%0\" : \"%*bc1t%?\\t%1\";
2891 }"
2892   [(set_attr "type"     "branch")
2893    (set_attr "mode"     "none")
2894    (set_attr "length"   "1")])
2895
2896 (define_insn "branch_fp_eq"
2897   [(set (pc)
2898         (if_then_else (eq:CC_FP (reg:CC_FP 66)
2899                                 (const_int 0))
2900                       (match_operand 0 "pc_or_label_operand" "")
2901                       (match_operand 1 "pc_or_label_operand" "")))]
2902   ""
2903   "*
2904 {
2905   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2906   return (operands[0] != pc_rtx) ? \"%*bc1f%?\\t%0\" : \"%*bc1t%?\\t%1\";
2907 }"
2908   [(set_attr "type"     "branch")
2909    (set_attr "mode"     "none")
2910    (set_attr "length"   "1")])
2911
2912 (define_insn "branch_fp_eq_rev"
2913   [(set (pc)
2914         (if_then_else (eq:CC_REV_FP (reg:CC_REV_FP 66)
2915                                     (const_int 0))
2916                       (match_operand 0 "pc_or_label_operand" "")
2917                       (match_operand 1 "pc_or_label_operand" "")))]
2918   ""
2919   "*
2920 {
2921   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2922   return (operands[0] != pc_rtx) ? \"%*bc1t%?\\t%0\" : \"%*bc1f%?\\t%1\";
2923 }"
2924   [(set_attr "type"     "branch")
2925    (set_attr "mode"     "none")
2926    (set_attr "length"   "1")])
2927
2928
2929 (define_insn "branch_zero"
2930   [(set (pc)
2931         (if_then_else (match_operator:SI 0 "cmp_op"
2932                                          [(match_operand:SI 1 "register_operand" "d")
2933                                           (const_int 0)])
2934         (match_operand 2 "pc_or_label_operand" "")
2935         (match_operand 3 "pc_or_label_operand" "")))]
2936   ""
2937   "*
2938 {
2939   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2940   if (operands[2] != pc_rtx)
2941     {                           /* normal jump */
2942       switch (GET_CODE (operands[0]))
2943         {
2944         case EQ:  return \"%*beq%?\\t%z1,%.,%2\";
2945         case NE:  return \"%*bne%?\\t%z1,%.,%2\";
2946         case GTU: return \"%*bne%?\\t%z1,%.,%2\";
2947         case LEU: return \"%*beq%?\\t%z1,%.,%2\";
2948         case GEU: return \"%*j\\t%2\";
2949         case LTU: return \"%*bne%?\\t%.,%.,%2\";
2950         }
2951
2952       return \"%*b%C0z%?\\t%z1,%2\";
2953     }
2954   else
2955     {                           /* inverted jump */
2956       switch (GET_CODE (operands[0]))
2957         {
2958         case EQ:  return \"%*bne%?\\t%z1,%.,%3\";
2959         case NE:  return \"%*beq%?\\t%z1,%.,%3\";
2960         case GTU: return \"%*beq%?\\t%z1,%.,%3\";
2961         case LEU: return \"%*bne%?\\t%z1,%.,%3\";
2962         case GEU: return \"%*beq%?\\t%.,%.,%3\";
2963         case LTU: return \"%*j\\t%3\";
2964         }
2965
2966       return \"%*b%N0z%?\\t%z1,%3\";
2967     }
2968 }"
2969   [(set_attr "type"     "branch")
2970    (set_attr "mode"     "none")
2971    (set_attr "length"   "1")])
2972
2973
2974 (define_insn "branch_equality"
2975   [(set (pc)
2976         (if_then_else (match_operator:SI 0 "equality_op"
2977                                          [(match_operand:SI 1 "register_operand" "d")
2978                                           (match_operand:SI 2 "register_operand" "d")])
2979         (match_operand 3 "pc_or_label_operand" "")
2980         (match_operand 4 "pc_or_label_operand" "")))]
2981   ""
2982   "*
2983 {
2984   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
2985   return (operands[3] != pc_rtx)
2986         ? \"%*b%C0%?\\t%z1,%z2,%3\"
2987         : \"%*b%N0%?\\t%z1,%z2,%4\";
2988 }"
2989   [(set_attr "type"     "branch")
2990    (set_attr "mode"     "none")
2991    (set_attr "length"   "1")])
2992
2993
2994 (define_expand "beq"
2995   [(set (pc)
2996         (if_then_else (eq:CC_EQ (cc0)
2997                                 (const_int 0))
2998                       (label_ref (match_operand 0 "" ""))
2999                       (pc)))]
3000   ""
3001   "
3002 {
3003   if (operands[0])              /* avoid unused code warning */
3004     {
3005       gen_conditional_branch (operands, EQ);
3006       DONE;
3007     }
3008 }")
3009
3010 (define_expand "bne"
3011   [(set (pc)
3012         (if_then_else (ne:CC_EQ (cc0)
3013                                 (const_int 0))
3014                       (label_ref (match_operand 0 "" ""))
3015                       (pc)))]
3016   ""
3017   "
3018 {
3019   if (operands[0])              /* avoid unused code warning */
3020     {
3021       gen_conditional_branch (operands, NE);
3022       DONE;
3023     }
3024 }")
3025
3026 (define_expand "bgt"
3027   [(set (pc)
3028         (if_then_else (gt:CC (cc0)
3029                              (const_int 0))
3030                       (label_ref (match_operand 0 "" ""))
3031                       (pc)))]
3032   ""
3033   "
3034 {
3035   if (operands[0])              /* avoid unused code warning */
3036     {
3037       gen_conditional_branch (operands, GT);
3038       DONE;
3039     }
3040 }")
3041
3042 (define_expand "bge"
3043   [(set (pc)
3044         (if_then_else (ge:CC (cc0)
3045                              (const_int 0))
3046                       (label_ref (match_operand 0 "" ""))
3047                       (pc)))]
3048   ""
3049   "
3050 {
3051   if (operands[0])              /* avoid unused code warning */
3052     {
3053       gen_conditional_branch (operands, GE);
3054       DONE;
3055     }
3056 }")
3057
3058 (define_expand "blt"
3059   [(set (pc)
3060         (if_then_else (lt:CC (cc0)
3061                              (const_int 0))
3062                       (label_ref (match_operand 0 "" ""))
3063                       (pc)))]
3064   ""
3065   "
3066 {
3067   if (operands[0])              /* avoid unused code warning */
3068     {
3069       gen_conditional_branch (operands, LT);
3070       DONE;
3071     }
3072 }")
3073
3074 (define_expand "ble"
3075   [(set (pc)
3076         (if_then_else (le:CC (cc0)
3077                              (const_int 0))
3078                       (label_ref (match_operand 0 "" ""))
3079                       (pc)))]
3080   ""
3081   "
3082 {
3083   if (operands[0])              /* avoid unused code warning */
3084     {
3085       gen_conditional_branch (operands, LE);
3086       DONE;
3087     }
3088 }")
3089
3090 (define_expand "bgtu"
3091   [(set (pc)
3092         (if_then_else (gtu:CC (cc0)
3093                               (const_int 0))
3094                       (label_ref (match_operand 0 "" ""))
3095                       (pc)))]
3096   ""
3097   "
3098 {
3099   if (operands[0])              /* avoid unused code warning */
3100     {
3101       gen_conditional_branch (operands, GTU);
3102       DONE;
3103     }
3104 }")
3105
3106 (define_expand "bgeu"
3107   [(set (pc)
3108         (if_then_else (geu:CC (cc0)
3109                               (const_int 0))
3110                       (label_ref (match_operand 0 "" ""))
3111                       (pc)))]
3112   ""
3113   "
3114 {
3115   if (operands[0])              /* avoid unused code warning */
3116     {
3117       gen_conditional_branch (operands, GEU);
3118       DONE;
3119     }
3120 }")
3121
3122
3123 (define_expand "bltu"
3124   [(set (pc)
3125         (if_then_else (ltu:CC (cc0)
3126                               (const_int 0))
3127                       (label_ref (match_operand 0 "" ""))
3128                       (pc)))]
3129   ""
3130   "
3131 {
3132   if (operands[0])              /* avoid unused code warning */
3133     {
3134       gen_conditional_branch (operands, LTU);
3135       DONE;
3136     }
3137 }")
3138
3139 (define_expand "bleu"
3140   [(set (pc)
3141         (if_then_else (leu:CC (cc0)
3142                               (const_int 0))
3143                       (label_ref (match_operand 0 "" ""))
3144                       (pc)))]
3145   ""
3146   "
3147 {
3148   if (operands[0])              /* avoid unused code warning */
3149     {
3150       gen_conditional_branch (operands, LEU);
3151       DONE;
3152     }
3153 }")
3154
3155 \f
3156 ;;
3157 ;;  ....................
3158 ;;
3159 ;;      SETTING A REGISTER FROM A COMPARISON
3160 ;;
3161 ;;  ....................
3162
3163 (define_expand "seq"
3164   [(set (match_operand:SI 0 "register_operand" "=d")
3165         (eq:SI (match_dup 1)
3166                (match_dup 2)))]
3167   ""
3168   "
3169 {
3170   if (branch_type != CMP_SI)
3171     FAIL;
3172
3173   /* set up operands from compare.  */
3174   operands[1] = branch_cmp[0];
3175   operands[2] = branch_cmp[1];
3176
3177   if (!TARGET_DEBUG_C_MODE)
3178     {
3179       gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
3180       DONE;
3181     }
3182
3183   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
3184     operands[2] = force_reg (SImode, operands[2]);
3185
3186   /* fall through and generate default code */
3187 }")
3188
3189
3190 (define_insn "seq_si_zero"
3191   [(set (match_operand:SI 0 "register_operand" "=d")
3192         (eq:SI (match_operand:SI 1 "register_operand" "d")
3193                (const_int 0)))]
3194   ""
3195   "sltu\\t%0,%1,1"
3196  [(set_attr "type"      "arith")
3197    (set_attr "mode"     "SI")
3198    (set_attr "length"   "1")])
3199
3200 (define_insn "seq_si"
3201   [(set (match_operand:SI 0 "register_operand" "=d,d")
3202         (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
3203                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3204   "TARGET_DEBUG_C_MODE"
3205   "@
3206    xor\\t%0,%1,%2\;sltu\\t%0,%0,1
3207    xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
3208  [(set_attr "type"      "arith")
3209    (set_attr "mode"     "SI")
3210    (set_attr "length"   "2")])
3211
3212 (define_split
3213   [(set (match_operand:SI 0 "register_operand" "")
3214         (eq:SI (match_operand:SI 1 "register_operand" "")
3215                (match_operand:SI 2 "uns_arith_operand" "")))]
3216   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
3217     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
3218   [(set (match_dup 0)
3219         (xor:SI (match_dup 1)
3220                 (match_dup 2)))
3221    (set (match_dup 0)
3222         (ltu:SI (match_dup 0)
3223                 (const_int 1)))]
3224   "")
3225
3226 (define_expand "sne"
3227   [(set (match_operand:SI 0 "register_operand" "=d")
3228         (ne:SI (match_dup 1)
3229                (match_dup 2)))]
3230   ""
3231   "
3232 {
3233   if (branch_type != CMP_SI)
3234     FAIL;
3235
3236   /* set up operands from compare.  */
3237   operands[1] = branch_cmp[0];
3238   operands[2] = branch_cmp[1];
3239
3240   if (!TARGET_DEBUG_C_MODE)
3241     {
3242       gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
3243       DONE;
3244     }
3245
3246   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
3247     operands[2] = force_reg (SImode, operands[2]);
3248
3249   /* fall through and generate default code */
3250 }")
3251
3252 (define_insn "sne_si_zero"
3253   [(set (match_operand:SI 0 "register_operand" "=d")
3254         (ne:SI (match_operand:SI 1 "register_operand" "d")
3255                (const_int 0)))]
3256   ""
3257   "sltu\\t%0,%.,%1"
3258  [(set_attr "type"      "arith")
3259    (set_attr "mode"     "SI")
3260    (set_attr "length"   "1")])
3261
3262 (define_insn "sne_si"
3263   [(set (match_operand:SI 0 "register_operand" "=d,d")
3264         (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
3265                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3266   "TARGET_DEBUG_C_MODE"
3267   "@
3268     xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
3269     xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
3270  [(set_attr "type"      "arith")
3271    (set_attr "mode"     "SI")
3272    (set_attr "length"   "2")])
3273
3274 (define_split
3275   [(set (match_operand:SI 0 "register_operand" "")
3276         (ne:SI (match_operand:SI 1 "register_operand" "")
3277                (match_operand:SI 2 "uns_arith_operand" "")))]
3278   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
3279     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
3280   [(set (match_dup 0)
3281         (xor:SI (match_dup 1)
3282                 (match_dup 2)))
3283    (set (match_dup 0)
3284         (gtu:SI (match_dup 0)
3285                 (const_int 0)))]
3286   "")
3287
3288 (define_expand "sgt"
3289   [(set (match_operand:SI 0 "register_operand" "=d")
3290         (gt:SI (match_dup 1)
3291                (match_dup 2)))]
3292   ""
3293   "
3294 {
3295   if (branch_type != CMP_SI)
3296     FAIL;
3297
3298   /* set up operands from compare.  */
3299   operands[1] = branch_cmp[0];
3300   operands[2] = branch_cmp[1];
3301
3302   if (!TARGET_DEBUG_C_MODE)
3303     {
3304       gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
3305       DONE;
3306     }
3307
3308   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
3309     operands[2] = force_reg (SImode, operands[2]);
3310
3311   /* fall through and generate default code */
3312 }")
3313
3314 (define_insn "sgt_si"
3315   [(set (match_operand:SI 0 "register_operand" "=d")
3316         (gt:SI (match_operand:SI 1 "register_operand" "d")
3317                (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
3318   ""
3319   "slt\\t%0,%z2,%1"
3320  [(set_attr "type"      "arith")
3321    (set_attr "mode"     "SI")
3322    (set_attr "length"   "1")])
3323
3324 (define_expand "sge"
3325   [(set (match_operand:SI 0 "register_operand" "=d")
3326         (ge:SI (match_dup 1)
3327                (match_dup 2)))]
3328   ""
3329   "
3330 {
3331   if (branch_type != CMP_SI)
3332     FAIL;
3333
3334   /* set up operands from compare.  */
3335   operands[1] = branch_cmp[0];
3336   operands[2] = branch_cmp[1];
3337
3338   if (!TARGET_DEBUG_C_MODE)
3339     {
3340       gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
3341       DONE;
3342     }
3343
3344   /* fall through and generate default code */
3345 }")
3346
3347 (define_insn "sge_si"
3348   [(set (match_operand:SI 0 "register_operand" "=d")
3349         (ge:SI (match_operand:SI 1 "register_operand" "d")
3350                (match_operand:SI 2 "arith_operand" "dI")))]
3351   "TARGET_DEBUG_C_MODE"
3352   "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
3353  [(set_attr "type"      "arith")
3354    (set_attr "mode"     "SI")
3355    (set_attr "length"   "2")])
3356
3357 (define_split
3358   [(set (match_operand:SI 0 "register_operand" "")
3359         (ge:SI (match_operand:SI 1 "register_operand" "")
3360                (match_operand:SI 2 "arith_operand" "")))]
3361   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
3362   [(set (match_dup 0)
3363         (lt:SI (match_dup 1)
3364                (match_dup 2)))
3365    (set (match_dup 0)
3366         (xor:SI (match_dup 0)
3367                 (const_int 1)))]
3368   "")
3369
3370 (define_expand "slt"
3371   [(set (match_operand:SI 0 "register_operand" "=d")
3372         (lt:SI (match_dup 1)
3373                (match_dup 2)))]
3374   ""
3375   "
3376 {
3377   if (branch_type != CMP_SI)
3378     FAIL;
3379
3380   /* set up operands from compare.  */
3381   operands[1] = branch_cmp[0];
3382   operands[2] = branch_cmp[1];
3383
3384   if (!TARGET_DEBUG_C_MODE)
3385     {
3386       gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
3387       DONE;
3388     }
3389
3390   /* fall through and generate default code */
3391 }")
3392
3393 (define_insn "slt_si"
3394   [(set (match_operand:SI 0 "register_operand" "=d")
3395         (lt:SI (match_operand:SI 1 "register_operand" "d")
3396                (match_operand:SI 2 "arith_operand" "dI")))]
3397   ""
3398   "slt\\t%0,%1,%2"
3399  [(set_attr "type"      "arith")
3400    (set_attr "mode"     "SI")
3401    (set_attr "length"   "1")])
3402
3403 (define_expand "sle"
3404   [(set (match_operand:SI 0 "register_operand" "=d")
3405         (le:SI (match_dup 1)
3406                (match_dup 2)))]
3407   ""
3408   "
3409 {
3410   if (branch_type != CMP_SI)
3411     FAIL;
3412
3413   /* set up operands from compare.  */
3414   operands[1] = branch_cmp[0];
3415   operands[2] = branch_cmp[1];
3416
3417   if (!TARGET_DEBUG_C_MODE)
3418     {
3419       gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
3420       DONE;
3421     }
3422
3423   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
3424     operands[2] = force_reg (SImode, operands[2]);
3425
3426   /* fall through and generate default code */
3427 }")
3428
3429 (define_insn "sle_si_const"
3430   [(set (match_operand:SI 0 "register_operand" "=d")
3431         (le:SI (match_operand:SI 1 "register_operand" "d")
3432                (match_operand:SI 2 "small_int" "I")))]
3433   "INTVAL (operands[2]) < 32767"
3434   "*
3435 {
3436   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
3437   return \"slt\\t%0,%1,%2\";
3438 }"
3439  [(set_attr "type"      "arith")
3440    (set_attr "mode"     "SI")
3441    (set_attr "length"   "1")])
3442
3443 (define_insn "sle_si_reg"
3444   [(set (match_operand:SI 0 "register_operand" "=d")
3445         (le:SI (match_operand:SI 1 "register_operand" "d")
3446                (match_operand:SI 2 "register_operand" "d")))]
3447   "TARGET_DEBUG_C_MODE"
3448   "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
3449  [(set_attr "type"      "arith")
3450    (set_attr "mode"     "SI")
3451    (set_attr "length"   "2")])
3452
3453 (define_split
3454   [(set (match_operand:SI 0 "register_operand" "")
3455         (le:SI (match_operand:SI 1 "register_operand" "")
3456                (match_operand:SI 2 "register_operand" "")))]
3457   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
3458   [(set (match_dup 0)
3459         (lt:SI (match_dup 2)
3460                (match_dup 1)))
3461    (set (match_dup 0)
3462         (xor:SI (match_dup 0)
3463                 (const_int 1)))]
3464   "")
3465
3466 (define_expand "sgtu"
3467   [(set (match_operand:SI 0 "register_operand" "=d")
3468         (gtu:SI (match_dup 1)
3469                 (match_dup 2)))]
3470   ""
3471   "
3472 {
3473   if (branch_type != CMP_SI)
3474     FAIL;
3475
3476   /* set up operands from compare.  */
3477   operands[1] = branch_cmp[0];
3478   operands[2] = branch_cmp[1];
3479
3480   if (!TARGET_DEBUG_C_MODE)
3481     {
3482       gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
3483       DONE;
3484     }
3485
3486   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
3487     operands[2] = force_reg (SImode, operands[2]);
3488
3489   /* fall through and generate default code */
3490 }")
3491
3492 (define_insn "sgtu_si"
3493   [(set (match_operand:SI 0 "register_operand" "=d")
3494         (gtu:SI (match_operand:SI 1 "register_operand" "d")
3495                 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
3496   ""
3497   "sltu\\t%0,%z2,%1"
3498  [(set_attr "type"      "arith")
3499    (set_attr "mode"     "SI")
3500    (set_attr "length"   "1")])
3501
3502 (define_expand "sgeu"
3503   [(set (match_operand:SI 0 "register_operand" "=d")
3504         (geu:SI (match_dup 1)
3505                 (match_dup 2)))]
3506   ""
3507   "
3508 {
3509   if (branch_type != CMP_SI)
3510     FAIL;
3511
3512   /* set up operands from compare.  */
3513   operands[1] = branch_cmp[0];
3514   operands[2] = branch_cmp[1];
3515
3516   if (!TARGET_DEBUG_C_MODE)
3517     {
3518       gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
3519       DONE;
3520     }
3521
3522   /* fall through and generate default code */
3523 }")
3524
3525 (define_insn "sgeu_si"
3526   [(set (match_operand:SI 0 "register_operand" "=d")
3527         (geu:SI (match_operand:SI 1 "register_operand" "d")
3528                 (match_operand:SI 2 "arith_operand" "dI")))]
3529   "TARGET_DEBUG_C_MODE"
3530   "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
3531  [(set_attr "type"      "arith")
3532    (set_attr "mode"     "SI")
3533    (set_attr "length"   "2")])
3534
3535 (define_split
3536   [(set (match_operand:SI 0 "register_operand" "")
3537         (geu:SI (match_operand:SI 1 "register_operand" "")
3538                 (match_operand:SI 2 "arith_operand" "")))]
3539   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
3540   [(set (match_dup 0)
3541         (ltu:SI (match_dup 1)
3542                 (match_dup 2)))
3543    (set (match_dup 0)
3544         (xor:SI (match_dup 0)
3545                 (const_int 1)))]
3546   "")
3547
3548 (define_expand "sltu"
3549   [(set (match_operand:SI 0 "register_operand" "=d")
3550         (ltu:SI (match_dup 1)
3551                 (match_dup 2)))]
3552   ""
3553   "
3554 {
3555   if (branch_type != CMP_SI)
3556     FAIL;
3557
3558   /* set up operands from compare.  */
3559   operands[1] = branch_cmp[0];
3560   operands[2] = branch_cmp[1];
3561
3562   if (!TARGET_DEBUG_C_MODE)
3563     {
3564       gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
3565       DONE;
3566     }
3567
3568   /* fall through and generate default code */
3569 }")
3570
3571 (define_insn "sltu_si"
3572   [(set (match_operand:SI 0 "register_operand" "=d")
3573         (ltu:SI (match_operand:SI 1 "register_operand" "d")
3574                 (match_operand:SI 2 "arith_operand" "dI")))]
3575   ""
3576   "sltu\\t%0,%1,%2"
3577  [(set_attr "type"      "arith")
3578    (set_attr "mode"     "SI")
3579    (set_attr "length"   "1")])
3580
3581 (define_expand "sleu"
3582   [(set (match_operand:SI 0 "register_operand" "=d")
3583         (leu:SI (match_dup 1)
3584                 (match_dup 2)))]
3585   ""
3586   "
3587 {
3588   if (branch_type != CMP_SI)
3589     FAIL;
3590
3591   /* set up operands from compare.  */
3592   operands[1] = branch_cmp[0];
3593   operands[2] = branch_cmp[1];
3594
3595   if (!TARGET_DEBUG_C_MODE)
3596     {
3597       gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
3598       DONE;
3599     }
3600
3601   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
3602     operands[2] = force_reg (SImode, operands[2]);
3603
3604   /* fall through and generate default code */
3605 }")
3606
3607 (define_insn "sleu_si_const"
3608   [(set (match_operand:SI 0 "register_operand" "=d")
3609         (leu:SI (match_operand:SI 1 "register_operand" "d")
3610                 (match_operand:SI 2 "small_int" "I")))]
3611   "INTVAL (operands[2]) < 32767"
3612   "*
3613 {
3614   operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
3615   return \"sltu\\t%0,%1,%2\";
3616 }"
3617  [(set_attr "type"      "arith")
3618    (set_attr "mode"     "SI")
3619    (set_attr "length"   "1")])
3620
3621 (define_insn "sleu_si_reg"
3622   [(set (match_operand:SI 0 "register_operand" "=d")
3623         (leu:SI (match_operand:SI 1 "register_operand" "d")
3624                 (match_operand:SI 2 "register_operand" "d")))]
3625   "TARGET_DEBUG_C_MODE"
3626   "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
3627  [(set_attr "type"      "arith")
3628    (set_attr "mode"     "SI")
3629    (set_attr "length"   "2")])
3630
3631 (define_split
3632   [(set (match_operand:SI 0 "register_operand" "")
3633         (leu:SI (match_operand:SI 1 "register_operand" "")
3634                 (match_operand:SI 2 "register_operand" "")))]
3635   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
3636   [(set (match_dup 0)
3637         (ltu:SI (match_dup 2)
3638                 (match_dup 1)))
3639    (set (match_dup 0)
3640         (xor:SI (match_dup 0)
3641                 (const_int 1)))]
3642   "")
3643
3644 \f
3645 ;;
3646 ;;  ....................
3647 ;;
3648 ;;      FLOATING POINT COMPARISONS
3649 ;;
3650 ;;  ....................
3651
3652 (define_insn "seq_df"
3653   [(set (reg:CC_FP 66)
3654         (eq:CC_FP (match_operand:DF 0 "register_operand" "f")
3655                   (match_operand:DF 1 "register_operand" "f")))]
3656   ""
3657   "*
3658 {
3659   rtx xoperands[10];
3660   xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
3661   xoperands[1] = operands[0];
3662   xoperands[2] = operands[1];
3663
3664   return mips_fill_delay_slot (\"c.eq.d\\t%0,%1\", DELAY_FCMP, xoperands, insn);
3665 }"
3666  [(set_attr "type"      "fcmp")
3667   (set_attr "mode"      "FPSW")
3668   (set_attr "length"    "1")])
3669
3670 (define_insn "sne_df"
3671   [(set (reg:CC_REV_FP 66)
3672         (ne:CC_REV_FP (match_operand:DF 0 "register_operand" "f")
3673                       (match_operand:DF 1 "register_operand" "f")))]
3674   ""
3675   "*
3676 {
3677   rtx xoperands[10];
3678   xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
3679   xoperands[1] = operands[0];
3680   xoperands[2] = operands[1];
3681
3682   return mips_fill_delay_slot (\"c.eq.d\\t%0,%1\", DELAY_FCMP, xoperands, insn);
3683 }"
3684  [(set_attr "type"      "fcmp")
3685   (set_attr "mode"      "FPSW")
3686   (set_attr "length"    "1")])
3687
3688 (define_insn "slt_df"
3689   [(set (reg:CC_FP 66)
3690         (lt:CC_FP (match_operand:DF 0 "register_operand" "f")
3691                   (match_operand:DF 1 "register_operand" "f")))]
3692   ""
3693   "*
3694 {
3695   rtx xoperands[10];
3696   xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
3697   xoperands[1] = operands[0];
3698   xoperands[2] = operands[1];
3699
3700   return mips_fill_delay_slot (\"c.lt.d\\t%0,%1\", DELAY_FCMP, xoperands, insn);
3701 }"
3702  [(set_attr "type"      "fcmp")
3703   (set_attr "mode"      "FPSW")
3704   (set_attr "length"    "1")])
3705
3706 (define_insn "sle_df"
3707   [(set (reg:CC_FP 66)
3708         (le:CC_FP (match_operand:DF 0 "register_operand" "f")
3709                   (match_operand:DF 1 "register_operand" "f")))]
3710   ""
3711   "*
3712 {
3713   rtx xoperands[10];
3714   xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
3715   xoperands[1] = operands[0];
3716   xoperands[2] = operands[1];
3717
3718   return mips_fill_delay_slot (\"c.le.d\\t%0,%1\", DELAY_FCMP, xoperands, insn);
3719 }"
3720  [(set_attr "type"      "fcmp")
3721   (set_attr "mode"      "FPSW")
3722   (set_attr "length"    "1")])
3723
3724 (define_insn "sgt_df"
3725   [(set (reg:CC_FP 66)
3726         (gt:CC_FP (match_operand:DF 0 "register_operand" "f")
3727                   (match_operand:DF 1 "register_operand" "f")))]
3728   ""
3729   "*
3730 {
3731   rtx xoperands[10];
3732   xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
3733   xoperands[1] = operands[0];
3734   xoperands[2] = operands[1];
3735
3736   return mips_fill_delay_slot (\"c.lt.d\\t%1,%0\", DELAY_FCMP, xoperands, insn);
3737 }"
3738  [(set_attr "type"      "fcmp")
3739   (set_attr "mode"      "FPSW")
3740   (set_attr "length"    "1")])
3741
3742 (define_insn "sge_df"
3743   [(set (reg:CC_FP 66)
3744         (ge:CC_FP (match_operand:DF 0 "register_operand" "f")
3745                   (match_operand:DF 1 "register_operand" "f")))]
3746   ""
3747   "*
3748 {
3749   rtx xoperands[10];
3750   xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
3751   xoperands[1] = operands[0];
3752   xoperands[2] = operands[1];
3753
3754   return mips_fill_delay_slot (\"c.le.d\\t%1,%0\", DELAY_FCMP, xoperands, insn);
3755 }"
3756  [(set_attr "type"      "fcmp")
3757   (set_attr "mode"      "FPSW")
3758   (set_attr "length"    "1")])
3759
3760 (define_insn "seq_sf"
3761   [(set (reg:CC_FP 66)
3762         (eq:CC_FP (match_operand:SF 0 "register_operand" "f")
3763                   (match_operand:SF 1 "register_operand" "f")))]
3764   ""
3765   "*
3766 {
3767   rtx xoperands[10];
3768   xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
3769   xoperands[1] = operands[0];
3770   xoperands[2] = operands[1];
3771
3772   return mips_fill_delay_slot (\"c.eq.s\\t%0,%1\", DELAY_FCMP, xoperands, insn);
3773 }"
3774  [(set_attr "type"      "fcmp")
3775   (set_attr "mode"      "FPSW")
3776   (set_attr "length"    "1")])
3777
3778 (define_insn "sne_sf"
3779   [(set (reg:CC_REV_FP 66)
3780         (ne:CC_REV_FP (match_operand:SF 0 "register_operand" "f")
3781                       (match_operand:SF 1 "register_operand" "f")))]
3782   ""
3783   "*
3784 {
3785   rtx xoperands[10];
3786   xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
3787   xoperands[1] = operands[0];
3788   xoperands[2] = operands[1];
3789
3790   return mips_fill_delay_slot (\"c.eq.s\\t%0,%1\", DELAY_FCMP, xoperands, insn);
3791 }"
3792  [(set_attr "type"      "fcmp")
3793   (set_attr "mode"      "FPSW")
3794   (set_attr "length"    "1")])
3795
3796 (define_insn "slt_sf"
3797   [(set (reg:CC_FP 66)
3798         (lt:CC_FP (match_operand:SF 0 "register_operand" "f")
3799                   (match_operand:SF 1 "register_operand" "f")))]
3800   ""
3801   "*
3802 {
3803   rtx xoperands[10];
3804   xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
3805   xoperands[1] = operands[0];
3806   xoperands[2] = operands[1];
3807
3808   return mips_fill_delay_slot (\"c.lt.s\\t%0,%1\", DELAY_FCMP, xoperands, insn);
3809 }"
3810  [(set_attr "type"      "fcmp")
3811   (set_attr "mode"      "FPSW")
3812   (set_attr "length"    "1")])
3813
3814 (define_insn "sle_sf"
3815   [(set (reg:CC_FP 66)
3816         (le:CC_FP (match_operand:SF 0 "register_operand" "f")
3817                   (match_operand:SF 1 "register_operand" "f")))]
3818   ""
3819   "*
3820 {
3821   rtx xoperands[10];
3822   xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
3823   xoperands[1] = operands[0];
3824   xoperands[2] = operands[1];
3825
3826   return mips_fill_delay_slot (\"c.le.s\\t%0,%1\", DELAY_FCMP, xoperands, insn);
3827 }"
3828  [(set_attr "type"      "fcmp")
3829   (set_attr "mode"      "FPSW")
3830   (set_attr "length"    "1")])
3831
3832 (define_insn "sgt_sf"
3833   [(set (reg:CC_FP 66)
3834         (gt:CC_FP (match_operand:SF 0 "register_operand" "f")
3835                   (match_operand:SF 1 "register_operand" "f")))]
3836   ""
3837   "*
3838 {
3839   rtx xoperands[10];
3840   xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
3841   xoperands[1] = operands[0];
3842   xoperands[2] = operands[1];
3843
3844   return mips_fill_delay_slot (\"c.lt.s\\t%1,%0\", DELAY_FCMP, xoperands, insn);
3845 }"
3846  [(set_attr "type"      "fcmp")
3847   (set_attr "mode"      "FPSW")
3848   (set_attr "length"    "1")])
3849
3850 (define_insn "sge_sf"
3851   [(set (reg:CC_FP 66)
3852         (ge:CC_FP (match_operand:SF 0 "register_operand" "f")
3853                   (match_operand:SF 1 "register_operand" "f")))]
3854   ""
3855   "*
3856 {
3857   rtx xoperands[10];
3858   xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
3859   xoperands[1] = operands[0];
3860   xoperands[2] = operands[1];
3861
3862   return mips_fill_delay_slot (\"c.le.s\\t%1,%0\", DELAY_FCMP, xoperands, insn);
3863 }"
3864  [(set_attr "type"      "fcmp")
3865   (set_attr "mode"      "FPSW")
3866   (set_attr "length"    "1")])
3867
3868 \f
3869 ;;
3870 ;;  ....................
3871 ;;
3872 ;;      UNCONDITIONAL BRANCHES
3873 ;;
3874 ;;  ....................
3875
3876 ;; Unconditional branches.
3877
3878 (define_insn "jump"
3879   [(set (pc)
3880         (label_ref (match_operand 0 "" "")))]
3881   ""
3882   "*
3883 {
3884   if (GET_CODE (operands[0]) == REG)
3885     return \"%*j\\t%0\";
3886   else
3887     return \"%*j\\t%l0\";
3888 }"
3889   [(set_attr "type"     "jump")
3890    (set_attr "mode"     "none")
3891    (set_attr "length"   "1")])
3892
3893 (define_insn "indirect_jump"
3894   [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
3895   ""
3896   "%*j\\t%0"
3897   [(set_attr "type"     "jump")
3898    (set_attr "mode"     "none")
3899    (set_attr "length"   "1")])
3900
3901 (define_insn "tablejump"
3902   [(set (pc)
3903         (match_operand:SI 0 "register_operand" "d"))
3904    (use (label_ref (match_operand 1 "" "")))]
3905   ""
3906   "%*j\\t%0"
3907   [(set_attr "type"     "jump")
3908    (set_attr "mode"     "none")
3909    (set_attr "length"   "1")])
3910
3911 ;; Function return, only allow after optimization, so that we can
3912 ;; eliminate jumps to jumps if no stack space is used.
3913
3914 ;; (define_expand "return"
3915 ;;   [(set (pc) (reg:SI 31))]
3916 ;;   "simple_epilogue_p ()"
3917 ;;   "")
3918
3919 (define_expand "return"
3920   [(parallel [(return)
3921               (use (reg:SI 31))])]
3922   "simple_epilogue_p ()"
3923   "")
3924
3925 (define_insn "return_internal"
3926   [(parallel [(return)
3927               (use (match_operand:SI 0 "register_operand" "d"))])]
3928   ""
3929   "%*j\\t%0"
3930   [(set_attr "type"     "jump")
3931    (set_attr "mode"     "none")
3932    (set_attr "length"   "1")])
3933
3934 \f
3935 ;;
3936 ;;  ....................
3937 ;;
3938 ;;      Function prologue/epilogue
3939 ;;
3940 ;;  ....................
3941 ;;
3942
3943 (define_expand "prologue"
3944   [(const_int 1)]
3945   ""
3946   "
3947 {
3948   if (mips_isa >= 0)            /* avoid unused code warnings */
3949     {
3950       mips_expand_prologue ();
3951       DONE;
3952     }
3953 }")
3954
3955 ;; At present, don't expand the epilogue, reorg.c will clobber the
3956 ;; return register in compiling gen_lowpart (emit-rtl.c).
3957 ;; 
3958 ;; (define_expand "epilogue"
3959 ;;   [(const_int 2)]
3960 ;;   ""
3961 ;;   "
3962 ;; {
3963 ;;   if (mips_isa >= 0)            /* avoid unused code warnings */
3964 ;;     {
3965 ;;       mips_expand_epilogue ();
3966 ;;       DONE;
3967 ;;     }
3968 ;; }")
3969
3970 \f
3971 ;;
3972 ;;  ....................
3973 ;;
3974 ;;      FUNCTION CALLS
3975 ;;
3976 ;;  ....................
3977
3978 ;; calls.c now passes a third argument, make saber happy
3979
3980 (define_expand "call"
3981   [(parallel [(call (match_operand 0 "memory_operand" "m")
3982                     (match_operand 1 "" "i"))
3983               (clobber (match_operand 2 "" ""))])]      ;; overwrite op2 with $31
3984   ""
3985   "
3986 {
3987   rtx addr;
3988
3989   operands[2] = gen_rtx (REG, SImode, GP_REG_FIRST + 31);
3990
3991   addr = XEXP (operands[0], 0);
3992   if (GET_CODE (addr) != REG && !CONSTANT_ADDRESS_P (addr))
3993     XEXP (operands[0], 0) = force_reg (FUNCTION_MODE, addr);
3994 }")
3995
3996 (define_insn "call_internal"
3997   [(call (match_operand 0 "memory_operand" "m")
3998          (match_operand 1 "" "i"))
3999    (clobber (match_operand:SI 2 "register_operand" "=d"))]
4000   ""
4001   "*
4002 {
4003   register rtx target = XEXP (operands[0], 0);
4004
4005   if (GET_CODE (target) == SYMBOL_REF)
4006     return \"%*jal\\t%0\";
4007
4008   else if (GET_CODE (target) == CONST_INT)
4009     {
4010       operands[0] = target;
4011       operands[1] = gen_rtx (REG, SImode, GP_REG_FIRST + 31);
4012       return \"%*%[li\\t%@,%0\\n\\tjal\\t%1,%@%]\";
4013     }
4014
4015   else
4016     {
4017       operands[0] = target;
4018       operands[1] = gen_rtx (REG, SImode, GP_REG_FIRST + 31);
4019       return \"%*jal\\t%1,%0\";
4020     }
4021 }"
4022   [(set_attr "type"     "call")
4023    (set_attr "mode"     "none")
4024    (set_attr "length"   "1")])
4025
4026 ;; calls.c now passes a fourth argument, make saber happy
4027
4028 (define_expand "call_value"
4029   [(parallel [(set (match_operand 0 "register_operand" "=df")
4030                    (call (match_operand 1 "memory_operand" "m")
4031                          (match_operand 2 "" "i")))
4032               (clobber (match_operand 3 "" ""))])]      ;; overwrite op3 with $31
4033   ""
4034   "
4035 {
4036   rtx addr;
4037
4038   operands[3] = gen_rtx (REG, SImode, GP_REG_FIRST + 31);
4039
4040   addr = XEXP (operands[1], 0);
4041   if (GET_CODE (addr) != REG && !CONSTANT_ADDRESS_P (addr))
4042     XEXP (operands[1], 0) = force_reg (FUNCTION_MODE, addr);
4043 }")
4044
4045 (define_insn "call_value_internal"
4046   [(set (match_operand 0 "register_operand" "=df")
4047         (call (match_operand 1 "memory_operand" "m")
4048               (match_operand 2 "" "i")))
4049    (clobber (match_operand:SI 3 "register_operand" "=d"))]
4050   ""
4051   "*
4052 {
4053   register rtx target = XEXP (operands[1], 0);
4054
4055   if (GET_CODE (target) == SYMBOL_REF)
4056     return \"%*jal\\t%1\";
4057
4058   else if (GET_CODE (target) == CONST_INT)
4059     {
4060       operands[1] = target;
4061       operands[2] = gen_rtx (REG, SImode, GP_REG_FIRST + 31);
4062       return \"%*%[li\\t%@,%1\\n\\tjal\\t%2,%@%]\";
4063     }
4064
4065   else
4066     {
4067       operands[1] = target;
4068       operands[2] = gen_rtx (REG, SImode, GP_REG_FIRST + 31);
4069       return \"%*jal\\t%2,%1\";
4070     }
4071 }"
4072   [(set_attr "type"     "call")
4073    (set_attr "mode"     "none")
4074    (set_attr "length"   "1")])
4075
4076 \f
4077 ;;
4078 ;;  ....................
4079 ;;
4080 ;;      MISC.
4081 ;;
4082 ;;  ....................
4083 ;;
4084
4085 (define_insn "nop"
4086   [(const_int 0)]
4087   ""
4088   "%(nop%)"
4089   [(set_attr "type"     "nop")
4090    (set_attr "mode"     "none")
4091    (set_attr "length"   "1")])
4092
4093 (define_expand "probe"
4094   [(set (match_dup 0)
4095         (match_dup 1))]
4096   ""
4097   "
4098 {
4099   operands[0] = gen_reg_rtx (SImode);
4100   operands[1] = gen_rtx (MEM, SImode, stack_pointer_rtx);
4101   MEM_VOLATILE_P (operands[1]) = TRUE;
4102
4103   /* fall through and generate default code */
4104 }")
4105
4106 \f
4107 ;;
4108 ;; Local variables:
4109 ;; mode:emacs-lisp
4110 ;; comment-start: ";; "
4111 ;; eval: (set-syntax-table (copy-sequence (syntax-table)))
4112 ;; eval: (modify-syntax-entry ?[ "(]")
4113 ;; eval: (modify-syntax-entry ?] ")[")
4114 ;; eval: (modify-syntax-entry ?{ "(}")
4115 ;; eval: (modify-syntax-entry ?} "){")
4116 ;; End: