Import final gcc2 snapshot (990109)
[official-gcc.git] / gcc / config / mips / mips.md
blob560eed764518592376739ea5b2a9a18c3c740991
1 ;;  Mips.md          Machine Description for MIPS based processors
2 ;;  Copyright (C) 1989, 90-97, 1998 Free Software Foundation, Inc.
3 ;;  Contributed by   A. Lichnewsky, lich@inria.inria.fr
4 ;;  Changes by       Michael Meissner, meissner@osf.org
5 ;;  64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
6 ;;  Brendan Eich, brendan@microunity.com.
8 ;; This file is part of GNU CC.
10 ;; GNU CC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
15 ;; GNU CC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU CC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
25 ;; ??? Currently does not have define_function_unit support for the R8000.
26 ;; Must include new entries for fmadd in addition to existing entries.
30 ;; ....................
32 ;;      Attributes
34 ;; ....................
36 ;; Classification of each insn.
37 ;; branch       conditional branch
38 ;; jump         unconditional jump
39 ;; call         unconditional call
40 ;; load         load instruction(s)
41 ;; store        store instruction(s)
42 ;; move         data movement within same register set
43 ;; xfer         transfer to/from coprocessor
44 ;; hilo         transfer of hi/lo registers
45 ;; arith        integer arithmetic instruction
46 ;; darith       double precision integer arithmetic instructions
47 ;; imul         integer multiply
48 ;; idiv         integer divide
49 ;; icmp         integer compare
50 ;; fadd         floating point add/subtract
51 ;; fmul         floating point multiply
52 ;; fmadd        floating point multiply-add
53 ;; fdiv         floating point divide
54 ;; fabs         floating point absolute value
55 ;; fneg         floating point negation
56 ;; fcmp         floating point compare
57 ;; fcvt         floating point convert
58 ;; fsqrt        floating point square root
59 ;; multi        multiword sequence (or user asm statements)
60 ;; nop          no operation
62 (define_attr "type"
63   "unknown,branch,jump,call,load,store,move,xfer,hilo,arith,darith,imul,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,multi,nop"
64   (const_string "unknown"))
66 ;; Main data type used by the insn
67 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown"))
69 ;; # instructions (4 bytes each)
70 (define_attr "length" "" (const_int 1))
72 ;; whether or not an instruction has a mandatory delay slot
73 (define_attr "dslot" "no,yes"
74   (if_then_else (eq_attr "type" "branch,jump,call,load,xfer,hilo,fcmp")
75                 (const_string "yes")
76                 (const_string "no")))
78 ;; Attribute describing the processor.  This attribute must match exactly
79 ;; with the processor_type enumeration in mips.h.
81 ;; Attribute describing the processor
82 ;; (define_attr "cpu" "default,r3000,r6000,r4000"
83 ;;   (const
84 ;;    (cond [(eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R3000"))   (const_string "r3000")
85 ;;           (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R4000"))   (const_string "r4000")
86 ;;           (eq (symbol_ref "mips_cpu") (symbol_ref "PROCESSOR_R6000"))   (const_string "r6000")]
87 ;;          (const_string "default"))))
89 ;; ??? Fix everything that tests this attribute.
90 (define_attr "cpu"
91   "default,r3000,r3900,r6000,r4000,r4100,r4300,r4600,r4650,r5000,r8000"
92   (const (symbol_ref "mips_cpu_attr")))
94 ;; Attribute defining whether or not we can use the branch-likely instructions
96 (define_attr "branch_likely" "no,yes"
97   (const
98    (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
99                  (const_string "yes")
100                  (const_string "no"))))
103 ;; Describe a user's asm statement.
104 (define_asm_attributes
105   [(set_attr "type" "multi")])
107 ;; whether or not generating calls to position independent functions
108 (define_attr "abicalls" "no,yes"
109   (const (symbol_ref "mips_abicalls_attr")))
113 ;; .........................
115 ;;      Delay slots, can't describe load/fcmp/xfer delay slots here
117 ;; .........................
119 (define_delay (eq_attr "type" "branch")
120   [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
121    (nil)
122    (and (eq_attr "branch_likely" "yes") (and (eq_attr "dslot" "no") (eq_attr "length" "1")))])
124 (define_delay (eq_attr "type" "jump")
125   [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
126    (nil)
127    (nil)])
129 (define_delay (and (eq_attr "type" "call") (eq_attr "abicalls" "no"))
130   [(and (eq_attr "dslot" "no") (eq_attr "length" "1"))
131    (nil)
132    (nil)])
136 ;; .........................
138 ;;      Functional units
140 ;; .........................
142 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
143 ;                       TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
145 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
147 (define_function_unit "memory" 1 0
148   (and (eq_attr "type" "load")
149        (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
150   3 0)
152 (define_function_unit "memory" 1 0
153   (and (eq_attr "type" "load")
154        (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
155   2 0)
157 (define_function_unit "memory"   1 0 (eq_attr "type" "store") 1 0)
159 (define_function_unit "memory"   1 0 (eq_attr "type" "xfer") 2 0)
161 (define_function_unit "imuldiv"  1 0
162   (eq_attr "type" "hilo")
163   1 3)
165 (define_function_unit "imuldiv"  1 0
166   (and (eq_attr "type" "imul")
167        (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
168   17 17)
170 (define_function_unit "imuldiv"  1 0
171   (and (eq_attr "type" "imul") (eq_attr "cpu" "r3000,r3900"))
172   12 12)
174 (define_function_unit "imuldiv"  1 0
175   (and (eq_attr "type" "imul") (eq_attr "cpu" "r4000,r4600"))
176   10 10)
178 (define_function_unit "imuldiv"  1 0
179   (and (eq_attr "type" "imul") (eq_attr "cpu" "r4650"))
180   4 4)
182 (define_function_unit "imuldiv"  1 0
183   (and (eq_attr "type" "imul")
184        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
185   1 1)
187 (define_function_unit "imuldiv"  1 0
188   (and (eq_attr "type" "imul")
189        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
190   4 4)
192 (define_function_unit "imuldiv"  1 0
193   (and (eq_attr "type" "imul")
194        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000")))
195   5 5)
197 (define_function_unit "imuldiv"  1 0
198   (and (eq_attr "type" "imul")
199        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
200   8 8)
202 (define_function_unit "imuldiv"  1 0
203   (and (eq_attr "type" "imul")
204        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
205   9 9)
207 (define_function_unit "imuldiv"  1 0
208   (and (eq_attr "type" "idiv")
209        (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
210   38 38)
212 (define_function_unit "imuldiv"  1 0
213   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000,r3900"))
214   35 35)
216 (define_function_unit "imuldiv"  1 0
217   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
218   42 42)
220 (define_function_unit "imuldiv"  1 0
221   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
222   36 36)
224 (define_function_unit "imuldiv"  1 0
225   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
226   69 69)
228 (define_function_unit "imuldiv" 1 0
229   (and (eq_attr "type" "idiv")
230        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
231   35 35)
233 (define_function_unit "imuldiv" 1 0
234   (and (eq_attr "type" "idiv")
235        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
236   67 67)
238 (define_function_unit "imuldiv" 1 0
239   (and (eq_attr "type" "idiv")
240        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
241   37 37)
243 (define_function_unit "imuldiv" 1 0
244   (and (eq_attr "type" "idiv")
245        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
246   69 69)
248 (define_function_unit "imuldiv" 1 0
249   (and (eq_attr "type" "idiv")
250        (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000")))
251   36 36)
253 (define_function_unit "imuldiv" 1 0
254   (and (eq_attr "type" "idiv")
255        (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
256   68 68)
258 ;; The R4300 does *NOT* have a separate Floating Point Unit, instead
259 ;; the FP hardware is part of the normal ALU circuitry.  This means FP
260 ;; instructions affect the pipe-line, and no functional unit
261 ;; parallelism can occur on R4300 processors.  To force GCC into coding
262 ;; for only a single functional unit, we force the R4300 FP
263 ;; instructions to be processed in the "imuldiv" unit.
265 (define_function_unit "adder" 1 1
266   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
267   3 0)
269 (define_function_unit "adder" 1 1
270   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r3900,r6000"))
271   2 0)
273 (define_function_unit "adder" 1 1
274   (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000"))
275   1 0)
277 (define_function_unit "adder" 1 1
278   (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
279   4 0)
281 (define_function_unit "adder" 1 1
282   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000,r3900"))
283   2 0)
285 (define_function_unit "adder" 1 1
286   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
287   3 0)
289 (define_function_unit "adder" 1 1
290   (and (eq_attr "type" "fabs,fneg")
291        (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000"))
292   2 0)
294 (define_function_unit "adder" 1 1
295   (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r3900,r4600,r4650,r5000"))
296   1 0)
298 (define_function_unit "mult" 1 1
299   (and (eq_attr "type" "fmul")
300        (and (eq_attr "mode" "SF")
301             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
302   7 0)
304 (define_function_unit "mult" 1 1
305   (and (eq_attr "type" "fmul")
306        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900,r5000")))
307   4 0)
309 (define_function_unit "mult" 1 1
310   (and (eq_attr "type" "fmul")
311        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
312   5 0)
314 (define_function_unit "mult" 1 1
315   (and (eq_attr "type" "fmul")
316        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
317   8 0)
319 (define_function_unit "mult" 1 1
320   (and (eq_attr "type" "fmul")
321        (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")))
322   8 0)
324 (define_function_unit "mult" 1 1
325   (and (eq_attr "type" "fmul")
326        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900,r5000")))
327   5 0)
329 (define_function_unit "mult" 1 1
330   (and (eq_attr "type" "fmul")
331        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
332   6 0)
334 (define_function_unit "divide" 1 1
335   (and (eq_attr "type" "fdiv")
336        (and (eq_attr "mode" "SF")
337             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
338   23 0)
340 (define_function_unit "divide" 1 1
341   (and (eq_attr "type" "fdiv")
342        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900")))
343   12 0)
345 (define_function_unit "divide" 1 1
346   (and (eq_attr "type" "fdiv")
347        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
348   15 0)
350 (define_function_unit "divide" 1 1
351   (and (eq_attr "type" "fdiv")
352        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
353   32 0)
355 (define_function_unit "divide" 1 1
356   (and (eq_attr "type" "fdiv")
357        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
358   21 0)
360 (define_function_unit "divide" 1 1
361   (and (eq_attr "type" "fdiv")
362        (and (eq_attr "mode" "DF")
363             (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300")))
364   36 0)
366 (define_function_unit "divide" 1 1
367   (and (eq_attr "type" "fdiv")
368        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900")))
369   19 0)
371 (define_function_unit "divide" 1 1
372   (and (eq_attr "type" "fdiv")
373        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
374   16 0)
376 (define_function_unit "divide" 1 1
377   (and (eq_attr "type" "fdiv")
378        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
379   61 0)
381 ;;; ??? Is this number right?
382 (define_function_unit "divide" 1 1
383   (and (eq_attr "type" "fsqrt")
384        (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
385   54 0)
387 (define_function_unit "divide" 1 1
388   (and (eq_attr "type" "fsqrt")
389        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
390   31 0)
392 (define_function_unit "divide" 1 1
393   (and (eq_attr "type" "fsqrt")
394        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
395   21 0)
397 ;;; ??? Is this number right?
398 (define_function_unit "divide" 1 1
399   (and (eq_attr "type" "fsqrt")
400        (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
401   112 0)
403 (define_function_unit "divide" 1 1
404   (and (eq_attr "type" "fsqrt")
405        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
406   60 0)
408 (define_function_unit "divide" 1 1
409   (and (eq_attr "type" "fsqrt")
410        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000")))
411   36 0)
413 ;; R4300 FP instruction classes treated as part of the "imuldiv"
414 ;; functional unit:
416 (define_function_unit "imuldiv" 1 0
417   (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
418   3 3)
420 (define_function_unit "imuldiv" 1 0
421   (and (eq_attr "type" "fcmp,fabs,fneg") (eq_attr "cpu" "r4300"))
422   1 1)
424 (define_function_unit "imuldiv" 1 0
425   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
426   5 5)
427 (define_function_unit "imuldiv" 1 0
428   (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
429   8 8)
431 (define_function_unit "imuldiv" 1 0
432   (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
433        (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
434   29 29)
435 (define_function_unit "imuldiv" 1 0
436   (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
437        (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
438   58 58)
440 ;; The following functional units do not use the cpu type, and use
441 ;; much less memory in genattrtab.c.
443 ;; (define_function_unit "memory"   1 0 (eq_attr "type" "load")                                3 0)
444 ;; (define_function_unit "memory"   1 0 (eq_attr "type" "store")                               1 0)
445 ;;       
446 ;; (define_function_unit "fp_comp"  1 0 (eq_attr "type" "fcmp")                                2 0)
447 ;;       
448 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "xfer")                                2 0)
449 ;; (define_function_unit "transfer" 1 0 (eq_attr "type" "hilo")                                3 0)
450 ;;   
451 ;; (define_function_unit "imuldiv"  1 1 (eq_attr "type" "imul")                               17 0)
452 ;; (define_function_unit "imuldiv"  1 1 (eq_attr "type" "idiv")                               38 0)
453 ;;   
454 ;; (define_function_unit "adder"    1 1 (eq_attr "type" "fadd")                                4 0)
455 ;; (define_function_unit "adder"    1 1 (eq_attr "type" "fabs,fneg")                           2 0)
456 ;;   
457 ;; (define_function_unit "mult"     1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "SF"))    7 0)
458 ;; (define_function_unit "mult"     1 1 (and (eq_attr "type" "fmul") (eq_attr "mode" "DF"))    8 0)
459 ;;   
460 ;; (define_function_unit "divide"   1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "SF"))   23 0)
461 ;; (define_function_unit "divide"   1 1 (and (eq_attr "type" "fdiv") (eq_attr "mode" "DF"))   36 0)
462 ;; 
463 ;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "SF"))  54 0)
464 ;; (define_function_unit "sqrt"     1 1 (and (eq_attr "type" "fsqrt") (eq_attr "mode" "DF")) 112 0)
468 ;;  ....................
470 ;;      ADDITION
472 ;;  ....................
475 (define_insn "adddf3"
476   [(set (match_operand:DF 0 "register_operand" "=f")
477         (plus:DF (match_operand:DF 1 "register_operand" "f")
478                  (match_operand:DF 2 "register_operand" "f")))]
479   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
480   "add.d\\t%0,%1,%2"
481   [(set_attr "type"     "fadd")
482    (set_attr "mode"     "DF")
483    (set_attr "length"   "1")])
485 (define_insn "addsf3"
486   [(set (match_operand:SF 0 "register_operand" "=f")
487         (plus:SF (match_operand:SF 1 "register_operand" "f")
488                  (match_operand:SF 2 "register_operand" "f")))]
489   "TARGET_HARD_FLOAT"
490   "add.s\\t%0,%1,%2"
491   [(set_attr "type"     "fadd")
492    (set_attr "mode"     "SF")
493    (set_attr "length"   "1")])
495 (define_expand "addsi3"
496   [(set (match_operand:SI 0 "register_operand" "=d")
497         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
498                  (match_operand:SI 2 "arith_operand" "dI")))]
499   ""
500   "
502   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768)
503     operands[2] = force_reg (SImode, operands[2]);
506 (define_insn "addsi3_internal"
507   [(set (match_operand:SI 0 "register_operand" "=d")
508         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
509                  (match_operand:SI 2 "arith_operand" "dI")))]
510   "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768"
511   "addu\\t%0,%z1,%2"
512   [(set_attr "type"     "arith")
513    (set_attr "mode"     "SI")
514    (set_attr "length"   "1")])
516 (define_expand "adddi3"
517   [(parallel [(set (match_operand:DI 0 "register_operand" "")
518                    (plus:DI (match_operand:DI 1 "se_register_operand" "")
519                             (match_operand:DI 2 "se_arith_operand" "")))
520               (clobber (match_dup 3))])]
521   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
522   "
524   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768)
525     operands[2] = force_reg (DImode, operands[2]);
527   if (TARGET_64BIT)
528     {
529       emit_insn (gen_adddi3_internal_3 (operands[0], operands[1],
530                                         operands[2]));
531       DONE;
532     }
534   operands[3] = gen_reg_rtx (SImode);
537 (define_insn "adddi3_internal_1"
538   [(set (match_operand:DI 0 "register_operand" "=d,&d")
539         (plus:DI (match_operand:DI 1 "register_operand" "0,d")
540                  (match_operand:DI 2 "register_operand" "d,d")))
541    (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
542   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
543   "*
545   return (REGNO (operands[0]) == REGNO (operands[1])
546           && REGNO (operands[0]) == REGNO (operands[2]))
547     ? \"srl\\t%3,%L0,31\;sll\\t%M0,%M0,1\;sll\\t%L0,%L1,1\;addu\\t%M0,%M0,%3\"
548     : \"addu\\t%L0,%L1,%L2\;sltu\\t%3,%L0,%L2\;addu\\t%M0,%M1,%M2\;addu\\t%M0,%M0,%3\";
550   [(set_attr "type"     "darith")
551    (set_attr "mode"     "DI")
552    (set_attr "length"   "4")])
554 (define_split
555   [(set (match_operand:DI 0 "register_operand" "")
556         (plus:DI (match_operand:DI 1 "register_operand" "")
557                  (match_operand:DI 2 "register_operand" "")))
558    (clobber (match_operand:SI 3 "register_operand" ""))]
559   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
560    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
561    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
562    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
563    && (REGNO (operands[0]) != REGNO (operands[1])
564        || REGNO (operands[0]) != REGNO (operands[2]))"
566   [(set (subreg:SI (match_dup 0) 0)
567         (plus:SI (subreg:SI (match_dup 1) 0)
568                  (subreg:SI (match_dup 2) 0)))
570    (set (match_dup 3)
571         (ltu:SI (subreg:SI (match_dup 0) 0)
572                 (subreg:SI (match_dup 2) 0)))
574    (set (subreg:SI (match_dup 0) 1)
575         (plus:SI (subreg:SI (match_dup 1) 1)
576                  (subreg:SI (match_dup 2) 1)))
578    (set (subreg:SI (match_dup 0) 1)
579         (plus:SI (subreg:SI (match_dup 0) 1)
580                  (match_dup 3)))]
581   "")
583 (define_split
584   [(set (match_operand:DI 0 "register_operand" "")
585         (plus:DI (match_operand:DI 1 "register_operand" "")
586                  (match_operand:DI 2 "register_operand" "")))
587    (clobber (match_operand:SI 3 "register_operand" ""))]
588   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
589    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
590    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
591    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
592    && (REGNO (operands[0]) != REGNO (operands[1])
593        || REGNO (operands[0]) != REGNO (operands[2]))"
595   [(set (subreg:SI (match_dup 0) 1)
596         (plus:SI (subreg:SI (match_dup 1) 1)
597                  (subreg:SI (match_dup 2) 1)))
599    (set (match_dup 3)
600         (ltu:SI (subreg:SI (match_dup 0) 1)
601                 (subreg:SI (match_dup 2) 1)))
603    (set (subreg:SI (match_dup 0) 0)
604         (plus:SI (subreg:SI (match_dup 1) 0)
605                  (subreg:SI (match_dup 2) 0)))
607    (set (subreg:SI (match_dup 0) 0)
608         (plus:SI (subreg:SI (match_dup 0) 0)
609                  (match_dup 3)))]
610   "")
612 (define_insn "adddi3_internal_2"
613   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
614         (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d")
615                  (match_operand:DI 2 "small_int" "P,J,N")))
616    (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
617   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && INTVAL (operands[2]) != -32768"
618   "@
619    addu\\t%L0,%L1,%2\;sltu\\t%3,%L0,%2\;addu\\t%M0,%M1,%3
620    move\\t%L0,%L1\;move\\t%M0,%M1
621    subu\\t%L0,%L1,%n2\;sltu\\t%3,%L0,%2\;subu\\t%M0,%M1,1\;addu\\t%M0,%M0,%3"
622   [(set_attr "type"     "darith")
623    (set_attr "mode"     "DI")
624    (set_attr "length"   "3,2,4")])
626 (define_split
627   [(set (match_operand:DI 0 "register_operand" "")
628         (plus:DI (match_operand:DI 1 "register_operand" "")
629                  (match_operand:DI 2 "small_int" "")))
630    (clobber (match_operand:SI 3 "register_operand" "=d"))]
631   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
632    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
633    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
634    && INTVAL (operands[2]) > 0"
636   [(set (subreg:SI (match_dup 0) 0)
637         (plus:SI (subreg:SI (match_dup 1) 0)
638                  (match_dup 2)))
640    (set (match_dup 3)
641         (ltu:SI (subreg:SI (match_dup 0) 0)
642                 (match_dup 2)))
644    (set (subreg:SI (match_dup 0) 1)
645         (plus:SI (subreg:SI (match_dup 1) 1)
646                  (match_dup 3)))]
647   "")
649 (define_split
650   [(set (match_operand:DI 0 "register_operand" "")
651         (plus:DI (match_operand:DI 1 "register_operand" "")
652                  (match_operand:DI 2 "small_int" "")))
653    (clobber (match_operand:SI 3 "register_operand" "=d"))]
654   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
655    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
656    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
657    && INTVAL (operands[2]) > 0"
659   [(set (subreg:SI (match_dup 0) 1)
660         (plus:SI (subreg:SI (match_dup 1) 1)
661                  (match_dup 2)))
663    (set (match_dup 3)
664         (ltu:SI (subreg:SI (match_dup 0) 1)
665                 (match_dup 2)))
667    (set (subreg:SI (match_dup 0) 0)
668         (plus:SI (subreg:SI (match_dup 1) 0)
669                  (match_dup 3)))]
670   "")
672 (define_insn "adddi3_internal_3"
673   [(set (match_operand:DI 0 "register_operand" "=d")
674         (plus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
675                  (match_operand:DI 2 "se_arith_operand" "dI")))]
676   "TARGET_64BIT && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
677   "*
679   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
680     ? \"dsubu\\t%0,%z1,%n2\"
681     : \"daddu\\t%0,%z1,%2\";
683   [(set_attr "type"     "darith")
684    (set_attr "mode"     "DI")
685    (set_attr "length"   "1")])
688 (define_insn "addsi3_internal_2"
689   [(set (match_operand:DI 0 "register_operand" "=d")
690         (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
691                                  (match_operand:SI 2 "arith_operand" "dI"))))]
692   "TARGET_64BIT && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
693   "*
695   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
696     ? \"subu\\t%0,%z1,%n2\"
697     : \"addu\\t%0,%z1,%2\";
699   [(set_attr "type"     "arith")
700    (set_attr "mode"     "SI")
701    (set_attr "length"   "1")])
705 ;;  ....................
707 ;;      SUBTRACTION
709 ;;  ....................
712 (define_insn "subdf3"
713   [(set (match_operand:DF 0 "register_operand" "=f")
714         (minus:DF (match_operand:DF 1 "register_operand" "f")
715                   (match_operand:DF 2 "register_operand" "f")))]
716   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
717   "sub.d\\t%0,%1,%2"
718   [(set_attr "type"     "fadd")
719    (set_attr "mode"     "DF")
720    (set_attr "length"   "1")])
722 (define_insn "subsf3"
723   [(set (match_operand:SF 0 "register_operand" "=f")
724         (minus:SF (match_operand:SF 1 "register_operand" "f")
725                   (match_operand:SF 2 "register_operand" "f")))]
726   "TARGET_HARD_FLOAT"
727   "sub.s\\t%0,%1,%2"
728   [(set_attr "type"     "fadd")
729    (set_attr "mode"     "SF")
730    (set_attr "length"   "1")])
732 (define_expand "subsi3"
733   [(set (match_operand:SI 0 "register_operand" "=d")
734         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
735                   (match_operand:SI 2 "arith_operand" "dI")))]
736   ""
737   "
739   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == -32768)
740     operands[2] = force_reg (SImode, operands[2]);
743 (define_insn "subsi3_internal"
744   [(set (match_operand:SI 0 "register_operand" "=d")
745         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
746                   (match_operand:SI 2 "arith_operand" "dI")))]
747   "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768"
748   "subu\\t%0,%z1,%2"
749   [(set_attr "type"     "arith")
750    (set_attr "mode"     "SI")
751    (set_attr "length"   "1")])
753 (define_expand "subdi3"
754   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
755                    (minus:DI (match_operand:DI 1 "se_register_operand" "d")
756                              (match_operand:DI 2 "se_register_operand" "d")))
757               (clobber (match_dup 3))])]
758   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
759   "
761   if (TARGET_64BIT)
762     {
763       emit_insn (gen_subdi3_internal_3 (operands[0], operands[1],
764                                         operands[2]));
765       DONE;
766     }
768   operands[3] = gen_reg_rtx (SImode);
771 (define_insn "subdi3_internal"
772   [(set (match_operand:DI 0 "register_operand" "=d")
773         (minus:DI (match_operand:DI 1 "register_operand" "d")
774                   (match_operand:DI 2 "register_operand" "d")))
775    (clobber (match_operand:SI 3 "register_operand" "=d"))]
776   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
777   "sltu\\t%3,%L1,%L2\;subu\\t%L0,%L1,%L2\;subu\\t%M0,%M1,%M2\;subu\\t%M0,%M0,%3"
778   [(set_attr "type"     "darith")
779    (set_attr "mode"     "DI")
780    (set_attr "length"   "4")])
782 (define_split
783   [(set (match_operand:DI 0 "register_operand" "")
784         (minus:DI (match_operand:DI 1 "register_operand" "")
785                   (match_operand:DI 2 "register_operand" "")))
786    (clobber (match_operand:SI 3 "register_operand" ""))]
787   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
788    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
789    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
790    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
792   [(set (match_dup 3)
793         (ltu:SI (subreg:SI (match_dup 1) 0)
794                 (subreg:SI (match_dup 2) 0)))
796    (set (subreg:SI (match_dup 0) 0)
797         (minus:SI (subreg:SI (match_dup 1) 0)
798                   (subreg:SI (match_dup 2) 0)))
800    (set (subreg:SI (match_dup 0) 1)
801         (minus:SI (subreg:SI (match_dup 1) 1)
802                   (subreg:SI (match_dup 2) 1)))
804    (set (subreg:SI (match_dup 0) 1)
805         (minus:SI (subreg:SI (match_dup 0) 1)
806                   (match_dup 3)))]
807   "")
809 (define_split
810   [(set (match_operand:DI 0 "register_operand" "")
811         (minus:DI (match_operand:DI 1 "register_operand" "")
812                   (match_operand:DI 2 "register_operand" "")))
813    (clobber (match_operand:SI 3 "register_operand" ""))]
814   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
815    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
816    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
817    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
819   [(set (match_dup 3)
820         (ltu:SI (subreg:SI (match_dup 1) 1)
821                 (subreg:SI (match_dup 2) 1)))
823    (set (subreg:SI (match_dup 0) 1)
824         (minus:SI (subreg:SI (match_dup 1) 1)
825                   (subreg:SI (match_dup 2) 1)))
827    (set (subreg:SI (match_dup 0) 0)
828         (minus:SI (subreg:SI (match_dup 1) 0)
829                   (subreg:SI (match_dup 2) 0)))
831    (set (subreg:SI (match_dup 0) 0)
832         (minus:SI (subreg:SI (match_dup 0) 0)
833                   (match_dup 3)))]
834   "")
836 (define_insn "subdi3_internal_2"
837   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
838         (minus:DI (match_operand:DI 1 "register_operand" "d,d,d")
839                   (match_operand:DI 2 "small_int" "P,J,N")))
840    (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
841   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && INTVAL (operands[2]) != -32768"
842   "@
843    sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3
844    move\\t%L0,%L1\;move\\t%M0,%M1
845    sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3"
846   [(set_attr "type"     "darith")
847    (set_attr "mode"     "DI")
848    (set_attr "length"   "3,2,4")])
850 (define_split
851   [(set (match_operand:DI 0 "register_operand" "")
852         (minus:DI (match_operand:DI 1 "register_operand" "")
853                   (match_operand:DI 2 "small_int" "")))
854    (clobber (match_operand:SI 3 "register_operand" ""))]
855   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
856    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
857    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
858    && INTVAL (operands[2]) > 0"
860   [(set (match_dup 3)
861         (ltu:SI (subreg:SI (match_dup 1) 0)
862                 (match_dup 2)))
864    (set (subreg:SI (match_dup 0) 0)
865         (minus:SI (subreg:SI (match_dup 1) 0)
866                   (match_dup 2)))
868    (set (subreg:SI (match_dup 0) 1)
869         (minus:SI (subreg:SI (match_dup 1) 1)
870                   (match_dup 3)))]
871   "")
873 (define_split
874   [(set (match_operand:DI 0 "register_operand" "")
875         (minus:DI (match_operand:DI 1 "register_operand" "")
876                   (match_operand:DI 2 "small_int" "")))
877    (clobber (match_operand:SI 3 "register_operand" ""))]
878   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
879    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
880    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
881    && INTVAL (operands[2]) > 0"
883   [(set (match_dup 3)
884         (ltu:SI (subreg:SI (match_dup 1) 1)
885                 (match_dup 2)))
887    (set (subreg:SI (match_dup 0) 1)
888         (minus:SI (subreg:SI (match_dup 1) 1)
889                   (match_dup 2)))
891    (set (subreg:SI (match_dup 0) 0)
892         (minus:SI (subreg:SI (match_dup 1) 0)
893                   (match_dup 3)))]
894   "")
896 (define_insn "subdi3_internal_3"
897   [(set (match_operand:DI 0 "register_operand" "=d")
898         (minus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ")
899                   (match_operand:DI 2 "se_arith_operand" "dI")))]
900   "TARGET_64BIT && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
901   "*
903   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
904     ? \"daddu\\t%0,%z1,%n2\"
905     : \"dsubu\\t%0,%z1,%2\";
907   [(set_attr "type"     "darith")
908    (set_attr "mode"     "DI")
909    (set_attr "length"   "1")])
912 (define_insn "subsi3_internal_2"
913   [(set (match_operand:DI 0 "register_operand" "=d")
914         (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
915                                   (match_operand:SI 2 "arith_operand" "dI"))))]
916   "TARGET_64BIT && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
917   "*
919   return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
920     ? \"addu\\t%0,%z1,%n2\"
921     : \"subu\\t%0,%z1,%2\";
923   [(set_attr "type"     "arith")
924    (set_attr "mode"     "DI")
925    (set_attr "length"   "1")])
929 ;;  ....................
931 ;;      MULTIPLICATION
933 ;;  ....................
936 ;; Early Vr4300 silicon has a CPU bug where multiplies with certain
937 ;; operands may corrupt immediately following multiplies. This is a
938 ;; simple fix to insert NOPs.
940 (define_expand "muldf3"
941   [(set (match_operand:DF 0 "register_operand" "=f")
942         (mult:DF (match_operand:DF 1 "register_operand" "f")
943                  (match_operand:DF 2 "register_operand" "f")))]
944   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
945   "
947   if (mips_cpu != PROCESSOR_R4300)
948     emit_insn (gen_muldf3_internal (operands[0], operands[1], operands[2]));
949   else
950     emit_insn (gen_muldf3_r4300 (operands[0], operands[1], operands[2]));
951   DONE;
954 (define_insn "muldf3_internal"
955   [(set (match_operand:DF 0 "register_operand" "=f")
956         (mult:DF (match_operand:DF 1 "register_operand" "f")
957                  (match_operand:DF 2 "register_operand" "f")))]
958   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && mips_cpu != PROCESSOR_R4300"
959   "mul.d\\t%0,%1,%2"
960   [(set_attr "type"     "fmul")
961    (set_attr "mode"     "DF")
962    (set_attr "length"   "1")])
964 (define_insn "muldf3_r4300"
965   [(set (match_operand:DF 0 "register_operand" "=f")
966         (mult:DF (match_operand:DF 1 "register_operand" "f")
967                  (match_operand:DF 2 "register_operand" "f")))]
968   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && mips_cpu == PROCESSOR_R4300"
969   "*
971   output_asm_insn (\"mul.d\\t%0,%1,%2\", operands);
972   if (TARGET_4300_MUL_FIX)
973     output_asm_insn (\"nop\", operands);
974   return \"\";
976   [(set_attr "type"     "fmul")
977    (set_attr "mode"     "DF")
978    (set_attr "length"   "2")])  ;; mul.d + nop
980 (define_expand "mulsf3"
981   [(set (match_operand:SF 0 "register_operand" "=f")
982         (mult:SF (match_operand:SF 1 "register_operand" "f")
983                  (match_operand:SF 2 "register_operand" "f")))]
984   "TARGET_HARD_FLOAT"
985   "
987   if (mips_cpu != PROCESSOR_R4300)
988     emit_insn( gen_mulsf3_internal (operands[0], operands[1], operands[2]));
989   else
990     emit_insn( gen_mulsf3_r4300 (operands[0], operands[1], operands[2]));
991   DONE;
994 (define_insn "mulsf3_internal"
995   [(set (match_operand:SF 0 "register_operand" "=f")
996         (mult:SF (match_operand:SF 1 "register_operand" "f")
997                  (match_operand:SF 2 "register_operand" "f")))]
998   "TARGET_HARD_FLOAT && mips_cpu != PROCESSOR_R4300"
999   "mul.s\\t%0,%1,%2"
1000   [(set_attr "type"     "fmul")
1001    (set_attr "mode"     "SF")
1002    (set_attr "length"   "1")])
1004 (define_insn "mulsf3_r4300"
1005   [(set (match_operand:SF 0 "register_operand" "=f")
1006         (mult:SF (match_operand:SF 1 "register_operand" "f")
1007                  (match_operand:SF 2 "register_operand" "f")))]
1008   "TARGET_HARD_FLOAT && mips_cpu == PROCESSOR_R4300"
1009   "*
1011   output_asm_insn (\"mul.s\\t%0,%1,%2\", operands);
1012   if (TARGET_4300_MUL_FIX)
1013     output_asm_insn (\"nop\", operands);
1014   return \"\";
1016   [(set_attr "type"     "fmul")
1017    (set_attr "mode"     "SF")
1018    (set_attr "length"   "2")])  ;; mul.s + nop
1020 ;; ??? The R4000 (only) has a cpu bug.  If a double-word shift executes while
1021 ;; a multiply is in progress, it may give an incorrect result.  Avoid
1022 ;; this by keeping the mflo with the mult on the R4000.
1024 (define_expand "mulsi3"
1025   [(set (match_operand:SI 0 "register_operand" "=l")
1026         (mult:SI (match_operand:SI 1 "register_operand" "d")
1027                  (match_operand:SI 2 "register_operand" "d")))
1028    (clobber (match_scratch:SI 3 "=h"))
1029    (clobber (match_scratch:SI 4 "=a"))]
1030   ""
1031   "
1033   if (GENERATE_MULT3)
1034     emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1035   else if (TARGET_MAD)
1036     emit_insn (gen_mulsi3_r4650 (operands[0], operands[1], operands[2]));
1037   else if (mips_cpu != PROCESSOR_R4000)
1038     emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1039   else
1040     emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1041   DONE;
1044 (define_insn "mulsi3_mult3"
1045   [(set (match_operand:SI 0 "register_operand" "=d")
1046         (mult:SI (match_operand:SI 1 "register_operand" "d")
1047                  (match_operand:SI 2 "register_operand" "d")))
1048    (clobber (match_scratch:SI 3 "=h"))
1049    (clobber (match_scratch:SI 4 "=l"))
1050    (clobber (match_scratch:SI 5 "=a"))]
1051   "GENERATE_MULT3"
1052   "mult\\t%0,%1,%2"
1053   [(set_attr "type"     "imul")
1054    (set_attr "mode"     "SI")
1055    (set_attr "length"   "1")])
1057 (define_insn "mulsi3_internal"
1058   [(set (match_operand:SI 0 "register_operand" "=l")
1059         (mult:SI (match_operand:SI 1 "register_operand" "d")
1060                  (match_operand:SI 2 "register_operand" "d")))
1061    (clobber (match_scratch:SI 3 "=h"))
1062    (clobber (match_scratch:SI 4 "=a"))]
1063   "mips_cpu != PROCESSOR_R4000"
1064   "mult\\t%1,%2"
1065   [(set_attr "type"     "imul")
1066    (set_attr "mode"     "SI")
1067    (set_attr "length"   "1")])
1069 (define_insn "mulsi3_r4000"
1070   [(set (match_operand:SI 0 "register_operand" "=d")
1071         (mult:SI (match_operand:SI 1 "register_operand" "d")
1072                  (match_operand:SI 2 "register_operand" "d")))
1073    (clobber (match_scratch:SI 3 "=h"))
1074    (clobber (match_scratch:SI 4 "=l"))
1075    (clobber (match_scratch:SI 5 "=a"))]
1076   "mips_cpu == PROCESSOR_R4000"
1077   "*
1079   rtx xoperands[10];
1081   xoperands[0] = operands[0];
1082   xoperands[1] = gen_rtx_REG (SImode, LO_REGNUM);
1084   output_asm_insn (\"mult\\t%1,%2\", operands);
1085   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1086   return \"\";
1088   [(set_attr "type"     "imul")
1089    (set_attr "mode"     "SI")
1090    (set_attr "length"   "3")])          ;; mult + mflo + delay
1092 (define_insn "mulsi3_r4650"
1093   [(set (match_operand:SI 0 "register_operand" "=d")
1094         (mult:SI (match_operand:SI 1 "register_operand" "d")
1095                  (match_operand:SI 2 "register_operand" "d")))
1096    (clobber (match_scratch:SI 3 "=h"))
1097    (clobber (match_scratch:SI 4 "=l"))
1098    (clobber (match_scratch:SI 5 "=a"))]
1099   "TARGET_MAD"
1100   "mul\\t%0,%1,%2"
1101   [(set_attr "type"     "imul")
1102    (set_attr "mode"     "SI")
1103    (set_attr "length"   "1")])
1105 (define_expand "muldi3"
1106   [(set (match_operand:DI 0 "register_operand" "=l")
1107         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1108                  (match_operand:DI 2 "register_operand" "d")))
1109    (clobber (match_scratch:DI 3 "=h"))
1110    (clobber (match_scratch:DI 4 "=a"))]
1111   "TARGET_64BIT"
1112   "
1114   if (mips_cpu != PROCESSOR_R4000)
1115     emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1116   else
1117     emit_insn (gen_muldi3_r4000 (operands[0], operands[1], operands[2]));
1118   DONE;
1121 ;; Don't accept both operands using se_register_operand, because if
1122 ;; both operands are sign extended we would prefer to use mult in the
1123 ;; mulsidi3 pattern.  Commutativity should permit either operand to be
1124 ;; sign extended.
1126 (define_insn "muldi3_internal"
1127   [(set (match_operand:DI 0 "register_operand" "=l")
1128         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1129                  (match_operand:DI 2 "register_operand" "d")))
1130    (clobber (match_scratch:DI 3 "=h"))
1131    (clobber (match_scratch:DI 4 "=a"))]
1132   "TARGET_64BIT && mips_cpu != PROCESSOR_R4000"
1133   "dmult\\t%1,%2"
1134   [(set_attr "type"     "imul")
1135    (set_attr "mode"     "DI")
1136    (set_attr "length"   "1")])
1138 (define_insn "muldi3_r4000"
1139   [(set (match_operand:DI 0 "register_operand" "=d")
1140         (mult:DI (match_operand:DI 1 "se_register_operand" "d")
1141                  (match_operand:DI 2 "register_operand" "d")))
1142    (clobber (match_scratch:DI 3 "=h"))
1143    (clobber (match_scratch:DI 4 "=l"))
1144    (clobber (match_scratch:DI 5 "=a"))]
1145   "TARGET_64BIT && mips_cpu == PROCESSOR_R4000"
1146   "*
1148   rtx xoperands[10];
1150   xoperands[0] = operands[0];
1151   xoperands[1] = gen_rtx_REG (DImode, LO_REGNUM);
1153   output_asm_insn (\"dmult\\t%1,%2\", operands);
1154   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
1155   return \"\";
1157   [(set_attr "type"     "imul")
1158    (set_attr "mode"     "DI")
1159    (set_attr "length"   "3")])          ;; mult + mflo + delay
1161 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1163 (define_expand "mulsidi3"
1164   [(set (match_operand:DI 0 "register_operand" "=x")
1165         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1166                  (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1167   ""
1168   "
1170   if (TARGET_64BIT)
1171     emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2]));
1172   else
1173     emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2]));
1174   DONE;
1177 (define_insn "mulsidi3_internal"
1178   [(set (match_operand:DI 0 "register_operand" "=x")
1179         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1180                  (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1181    (clobber (match_scratch:SI 3 "=a"))]
1182   "!TARGET_64BIT"
1183   "mult\\t%1,%2"
1184   [(set_attr "type"     "imul")
1185    (set_attr "mode"     "SI")
1186    (set_attr "length"   "1")])
1188 (define_insn "mulsidi3_64bit"
1189   [(set (match_operand:DI 0 "register_operand" "=a")
1190         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1191                  (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1192    (clobber (match_scratch:DI 3 "=l"))
1193    (clobber (match_scratch:DI 4 "=h"))]
1194   "TARGET_64BIT"
1195   "mult\\t%1,%2"
1196   [(set_attr "type"     "imul")
1197    (set_attr "mode"     "SI")
1198    (set_attr "length"   "1")])
1200 (define_insn "smulsi3_highpart"
1201   [(set (match_operand:SI 0 "register_operand" "=h")
1202         (truncate:SI
1203          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1204                                (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
1205                       (const_int 32))))
1206    (clobber (match_scratch:SI 3 "=l"))
1207    (clobber (match_scratch:SI 4 "=a"))]
1208   ""
1209   "mult\\t%1,%2"
1210   [(set_attr "type"     "imul")
1211    (set_attr "mode"     "SI")
1212    (set_attr "length"   "1")])
1214 (define_expand "umulsidi3"
1215   [(set (match_operand:DI 0 "register_operand" "=x")
1216         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1217                  (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1218   ""
1219   "
1221   if (TARGET_64BIT)
1222     emit_insn (gen_umulsidi3_64bit (operands[0], operands[1], operands[2]));
1223   else
1224     emit_insn (gen_umulsidi3_internal (operands[0], operands[1], operands[2]));
1225   DONE;
1228 (define_insn "umulsidi3_internal"
1229   [(set (match_operand:DI 0 "register_operand" "=x")
1230         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1231                  (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1232    (clobber (match_scratch:SI 3 "=a"))]
1233   "!TARGET_64BIT"
1234   "multu\\t%1,%2"
1235   [(set_attr "type"     "imul")
1236    (set_attr "mode"     "SI")
1237    (set_attr "length"   "1")])
1239 (define_insn "umulsidi3_64bit"
1240   [(set (match_operand:DI 0 "register_operand" "=a")
1241         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1242                  (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1243    (clobber (match_scratch:DI 3 "=l"))
1244    (clobber (match_scratch:DI 4 "=h"))]
1245   "TARGET_64BIT"
1246   "multu\\t%1,%2"
1247   [(set_attr "type"     "imul")
1248    (set_attr "mode"     "SI")
1249    (set_attr "length"   "1")])
1251 (define_insn "umulsi3_highpart"
1252   [(set (match_operand:SI 0 "register_operand" "=h")
1253         (truncate:SI
1254          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1255                                (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
1256                       (const_int 32))))
1257    (clobber (match_scratch:SI 3 "=l"))
1258    (clobber (match_scratch:SI 4 "=a"))]
1259   ""
1260   "multu\\t%1,%2"
1261   [(set_attr "type"     "imul")
1262    (set_attr "mode"     "SI")
1263    (set_attr "length"   "1")])
1265 (define_insn "smuldi3_highpart"
1266   [(set (match_operand:DI 0 "register_operand" "=h")
1267         (truncate:DI
1268          (lshiftrt:TI (mult:TI (sign_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
1269                                (sign_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
1270                       (const_int 64))))
1271    (clobber (match_scratch:DI 3 "=l"))
1272    (clobber (match_scratch:DI 4 "=a"))]
1273   "TARGET_64BIT"
1274   "dmult\\t%1,%2"
1275   [(set_attr "type"     "imul")
1276    (set_attr "mode"     "DI")
1277    (set_attr "length"   "1")])
1279 (define_insn "umuldi3_highpart"
1280   [(set (match_operand:DI 0 "register_operand" "=h")
1281         (truncate:DI
1282          (lshiftrt:TI (mult:TI (zero_extend:TI (match_operand:DI 1 "se_register_operand" "d"))
1283                                (zero_extend:TI (match_operand:DI 2 "se_register_operand" "d")))
1284                       (const_int 64))))
1285    (clobber (match_scratch:DI 3 "=l"))
1286    (clobber (match_scratch:DI 4 "=a"))]
1287   "TARGET_64BIT"
1288   "dmultu\\t%1,%2"
1289   [(set_attr "type"     "imul")
1290    (set_attr "mode"     "DI")
1291    (set_attr "length"   "1")])
1293 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1294 ;; instruction.  The HI/LO registers are used as a 64 bit accumulator.
1296 (define_insn "madsi"
1297   [(set (match_operand:SI 0 "register_operand" "+l")
1298         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1299                           (match_operand:SI 2 "register_operand" "d"))
1300                  (match_dup 0)))
1301    (clobber (match_scratch:SI 3 "=h"))
1302    (clobber (match_scratch:SI 4 "=a"))]
1303   "TARGET_MAD || GENERATE_MADD"
1304   "*
1306   if (TARGET_MAD)
1307     return \"mad\\t%1,%2\";
1308   else
1309     return \"madd\\t%1,%2\";
1311   [(set_attr "type"     "imul")
1312    (set_attr "mode"     "SI")
1313    (set_attr "length"   "1")])
1315 (define_insn "maddi"
1316   [(set (match_operand:DI 0 "register_operand" "+x")
1317         (plus:DI (mult:DI (sign_extend:DI
1318                            (match_operand:SI 1 "register_operand" "d"))
1319                           (sign_extend:DI
1320                            (match_operand:SI 2 "register_operand" "d")))
1321                  (match_dup 0)))
1322    (clobber (match_scratch:SI 3 "=a"))]
1323   "TARGET_MAD && ! TARGET_64BIT"
1324   "mad\\t%1,%2"
1325   [(set_attr "type"     "imul")
1326    (set_attr "mode"     "SI")
1327    (set_attr "length"   "1")])
1329 (define_insn "maddi_64bit"
1330   [(set (match_operand:DI 0 "register_operand" "+a")
1331         (plus:DI (mult:DI (sign_extend:DI
1332                            (match_operand:SI 1 "register_operand" "d"))
1333                           (sign_extend:DI
1334                            (match_operand:SI 2 "register_operand" "d")))
1335                  (match_dup 0)))
1336    (clobber (match_scratch:DI 3 "=l"))
1337    (clobber (match_scratch:DI 4 "=h"))]
1338   "TARGET_MAD && TARGET_64BIT"
1339   "mad\\t%1,%2"
1340   [(set_attr "type"     "imul")
1341    (set_attr "mode"     "SI")
1342    (set_attr "length"   "1")])
1344 (define_insn "umaddi"
1345   [(set (match_operand:DI 0 "register_operand" "+x")
1346         (plus:DI (mult:DI (zero_extend:DI
1347                            (match_operand:SI 1 "register_operand" "d"))
1348                           (zero_extend:DI
1349                            (match_operand:SI 2 "register_operand" "d")))
1350                  (match_dup 0)))
1351    (clobber (match_scratch:SI 3 "=a"))]
1352   "TARGET_MAD && ! TARGET_64BIT"
1353   "madu\\t%1,%2"
1354   [(set_attr "type"     "imul")
1355    (set_attr "mode"     "SI")
1356    (set_attr "length"   "1")])
1358 (define_insn "umaddi_64bit"
1359   [(set (match_operand:DI 0 "register_operand" "+a")
1360         (plus:DI (mult:DI (zero_extend:DI
1361                            (match_operand:SI 1 "register_operand" "d"))
1362                           (zero_extend:DI
1363                            (match_operand:SI 2 "register_operand" "d")))
1364                  (match_dup 0)))
1365    (clobber (match_scratch:DI 3 "=l"))
1366    (clobber (match_scratch:DI 4 "=h"))]
1367   "TARGET_MAD && TARGET_64BIT"
1368   "madu\\t%1,%2"
1369   [(set_attr "type"     "imul")
1370    (set_attr "mode"     "SI")
1371    (set_attr "length"   "1")])
1373 (define_insn "madd3"
1374   [(set (match_operand:SI 0 "register_operand" "=d")
1375         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1376                           (match_operand:SI 2 "register_operand" "d"))
1377                  (match_operand:SI 3 "register_operand" "l")))
1378    (clobber (match_scratch:SI 4 "=l"))
1379    (clobber (match_scratch:SI 5 "=h"))
1380    (clobber (match_scratch:SI 6 "=a"))]
1381   "GENERATE_MADD"
1382   "madd\\t%0,%1,%2"
1383   [(set_attr "type"     "imul")
1384    (set_attr "mode"     "SI")
1385    (set_attr "length"   "1")])
1387 ;; Floating point multiply accumulate instructions.
1389 (define_insn ""
1390   [(set (match_operand:DF 0 "register_operand" "=f")
1391         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1392                           (match_operand:DF 2 "register_operand" "f"))
1393                  (match_operand:DF 3 "register_operand" "f")))]
1394   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1395   "madd.d\\t%0,%3,%1,%2"
1396   [(set_attr "type"     "fmadd")
1397    (set_attr "mode"     "DF")
1398    (set_attr "length"   "1")])
1400 (define_insn ""
1401   [(set (match_operand:SF 0 "register_operand" "=f")
1402         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1403                           (match_operand:SF 2 "register_operand" "f"))
1404                  (match_operand:SF 3 "register_operand" "f")))]
1405   "mips_isa >= 4 && TARGET_HARD_FLOAT"
1406   "madd.s\\t%0,%3,%1,%2"
1407   [(set_attr "type"     "fmadd")
1408    (set_attr "mode"     "SF")
1409    (set_attr "length"   "1")])
1411 (define_insn ""
1412   [(set (match_operand:DF 0 "register_operand" "=f")
1413         (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1414                            (match_operand:DF 2 "register_operand" "f"))
1415                   (match_operand:DF 3 "register_operand" "f")))]
1416   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1417   "msub.d\\t%0,%3,%1,%2"
1418   [(set_attr "type"     "fmadd")
1419    (set_attr "mode"     "DF")
1420    (set_attr "length"   "1")])
1422 (define_insn ""
1423   [(set (match_operand:SF 0 "register_operand" "=f")
1424         (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1425                            (match_operand:SF 2 "register_operand" "f"))
1426                   (match_operand:SF 3 "register_operand" "f")))]
1427                   
1428   "mips_isa >= 4 && TARGET_HARD_FLOAT"
1429   "msub.s\\t%0,%3,%1,%2"
1430   [(set_attr "type"     "fmadd")
1431    (set_attr "mode"     "SF")
1432    (set_attr "length"   "1")])
1434 (define_insn ""
1435   [(set (match_operand:DF 0 "register_operand" "=f")
1436         (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
1437                                   (match_operand:DF 2 "register_operand" "f"))
1438                          (match_operand:DF 3 "register_operand" "f"))))]
1439   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1440   "nmadd.d\\t%0,%3,%1,%2"
1441   [(set_attr "type"     "fmadd")
1442    (set_attr "mode"     "DF")
1443    (set_attr "length"   "1")])
1445 (define_insn ""
1446   [(set (match_operand:SF 0 "register_operand" "=f")
1447         (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
1448                                   (match_operand:SF 2 "register_operand" "f"))
1449                          (match_operand:SF 3 "register_operand" "f"))))]
1450   "mips_isa >= 4 && TARGET_HARD_FLOAT"
1451   "nmadd.s\\t%0,%3,%1,%2"
1452   [(set_attr "type"     "fmadd")
1453    (set_attr "mode"     "SF")
1454    (set_attr "length"   "1")])
1456 (define_insn ""
1457   [(set (match_operand:DF 0 "register_operand" "=f")
1458         (minus:DF (match_operand:DF 1 "register_operand" "f")
1459                   (mult:DF (match_operand:DF 2 "register_operand" "f")
1460                            (match_operand:DF 3 "register_operand" "f"))))]
1461   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1462   "nmsub.d\\t%0,%1,%2,%3"
1463   [(set_attr "type"     "fmadd")
1464    (set_attr "mode"     "DF")
1465    (set_attr "length"   "1")])
1467 (define_insn ""
1468   [(set (match_operand:SF 0 "register_operand" "=f")
1469         (minus:SF (match_operand:SF 1 "register_operand" "f")
1470                   (mult:SF (match_operand:SF 2 "register_operand" "f")
1471                            (match_operand:SF 3 "register_operand" "f"))))]
1472   "mips_isa >= 4 && TARGET_HARD_FLOAT"
1473   "nmsub.s\\t%0,%1,%2,%3"
1474   [(set_attr "type"     "fmadd")
1475    (set_attr "mode"     "SF")
1476    (set_attr "length"   "1")])
1479 ;;  ....................
1481 ;;      DIVISION and REMAINDER
1483 ;;  ....................
1486 (define_insn "divdf3"
1487   [(set (match_operand:DF 0 "register_operand" "=f")
1488         (div:DF (match_operand:DF 1 "register_operand" "f")
1489                 (match_operand:DF 2 "register_operand" "f")))]
1490   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1491   "div.d\\t%0,%1,%2"
1492   [(set_attr "type"     "fdiv")
1493    (set_attr "mode"     "DF")
1494    (set_attr "length"   "1")])
1496 (define_insn "divsf3"
1497   [(set (match_operand:SF 0 "register_operand" "=f")
1498         (div:SF (match_operand:SF 1 "register_operand" "f")
1499                 (match_operand:SF 2 "register_operand" "f")))]
1500   "TARGET_HARD_FLOAT"
1501   "div.s\\t%0,%1,%2"
1502   [(set_attr "type"     "fdiv")
1503    (set_attr "mode"     "SF")
1504    (set_attr "length"   "1")])
1506 (define_insn ""
1507   [(set (match_operand:DF 0 "register_operand" "=f")
1508         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
1509                 (match_operand:DF 2 "register_operand" "f")))]
1510   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_fast_math"
1511   "recip.d\\t%0,%2"
1512   [(set_attr "type"     "fdiv")
1513    (set_attr "mode"     "DF")
1514    (set_attr "length"   "1")])
1516 (define_insn ""
1517   [(set (match_operand:SF 0 "register_operand" "=f")
1518         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
1519                 (match_operand:SF 2 "register_operand" "f")))]
1520   "mips_isa >= 4 && TARGET_HARD_FLOAT && flag_fast_math"
1521   "recip.s\\t%0,%2"
1522   [(set_attr "type"     "fdiv")
1523    (set_attr "mode"     "SF")
1524    (set_attr "length"   "1")])
1526 ;; If optimizing, prefer the divmod functions over separate div and
1527 ;; mod functions, since this will allow using one instruction for both
1528 ;; the quotient and remainder.  At present, the divmod is not moved out
1529 ;; of loops if it is constant within the loop, so allow -mdebugc to
1530 ;; use the old method of doing things.
1532 ;; 64 is the multiply/divide hi register
1533 ;; 65 is the multiply/divide lo register
1535 ;; ??? We can't accept constants here, because the MIPS assembler will replace
1536 ;; a divide by power of 2 with a shift, and then the remainder is no longer
1537 ;; available.
1539 (define_insn "divmodsi4"
1540   [(set (match_operand:SI 0 "register_operand" "=d")
1541         (div:SI (match_operand:SI 1 "register_operand" "d")
1542                 (match_operand:SI 2 "register_operand" "d")))
1543    (set (match_operand:SI 3 "register_operand" "=d")
1544         (mod:SI (match_dup 1)
1545                 (match_dup 2)))
1546    (clobber (match_scratch:SI 4 "=l"))
1547    (clobber (match_scratch:SI 5 "=h"))
1548    (clobber (match_scratch:SI 6 "=a"))]
1549   "optimize"
1550   "*
1552   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1553     return \"div\\t%0,%1,%2\";
1555   if (find_reg_note (insn, REG_UNUSED, operands[0]))
1556     return \"rem\\t%3,%1,%2\";
1558   return \"div\\t%0,%1,%2\;mfhi\\t%3\";
1560   [(set_attr "type"     "idiv")
1561    (set_attr "mode"     "SI")
1562    (set_attr "length"   "14")])         ;; various tests for dividing by 0 and such
1564 (define_insn "divmoddi4"
1565   [(set (match_operand:DI 0 "register_operand" "=d")
1566         (div:DI (match_operand:DI 1 "se_register_operand" "d")
1567                 (match_operand:DI 2 "se_register_operand" "d")))
1568    (set (match_operand:DI 3 "register_operand" "=d")
1569         (mod:DI (match_dup 1)
1570                 (match_dup 2)))
1571    (clobber (match_scratch:DI 4 "=l"))
1572    (clobber (match_scratch:DI 5 "=h"))
1573    (clobber (match_scratch:DI 6 "=a"))]
1574   "TARGET_64BIT && optimize"
1575   "*
1577   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1578     return \"ddiv\\t%0,%1,%2\";
1580   if (find_reg_note (insn, REG_UNUSED, operands[0]))
1581     return \"drem\\t%3,%1,%2\";
1583   return \"ddiv\\t%0,%1,%2\;mfhi\\t%3\";
1585   [(set_attr "type"     "idiv")
1586    (set_attr "mode"     "DI")
1587    (set_attr "length"   "15")])         ;; various tests for dividing by 0 and such
1589 (define_insn "udivmodsi4"
1590   [(set (match_operand:SI 0 "register_operand" "=d")
1591         (udiv:SI (match_operand:SI 1 "register_operand" "d")
1592                  (match_operand:SI 2 "register_operand" "d")))
1593    (set (match_operand:SI 3 "register_operand" "=d")
1594         (umod:SI (match_dup 1)
1595                  (match_dup 2)))
1596    (clobber (match_scratch:SI 4 "=l"))
1597    (clobber (match_scratch:SI 5 "=h"))
1598    (clobber (match_scratch:SI 6 "=a"))]
1599   "optimize"
1600   "*
1602   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1603     return \"divu\\t%0,%1,%2\";
1605   if (find_reg_note (insn, REG_UNUSED, operands[0]))
1606     return \"remu\\t%3,%1,%2\";
1608   return \"divu\\t%0,%1,%2\;mfhi\\t%3\";
1610   [(set_attr "type"     "idiv")
1611    (set_attr "mode"     "SI")
1612    (set_attr "length"   "8")])          ;; various tests for dividing by 0 and such
1614 (define_insn "udivmoddi4"
1615   [(set (match_operand:DI 0 "register_operand" "=d")
1616         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
1617                  (match_operand:DI 2 "se_register_operand" "d")))
1618    (set (match_operand:DI 3 "register_operand" "=d")
1619         (umod:DI (match_dup 1)
1620                  (match_dup 2)))
1621    (clobber (match_scratch:DI 4 "=l"))
1622    (clobber (match_scratch:DI 5 "=h"))
1623    (clobber (match_scratch:DI 6 "=a"))]
1624   "TARGET_64BIT && optimize"
1625   "*
1627   if (find_reg_note (insn, REG_UNUSED, operands[3]))
1628     return \"ddivu\\t%0,%1,%2\";
1630   if (find_reg_note (insn, REG_UNUSED, operands[0]))
1631     return \"dremu\\t%3,%1,%2\";
1633   return \"ddivu\\t%0,%1,%2\;mfhi\\t%3\";
1635   [(set_attr "type"     "idiv")
1636    (set_attr "mode"     "DI")
1637    (set_attr "length"   "8")])          ;; various tests for dividing by 0 and such
1639 (define_insn "divsi3"
1640   [(set (match_operand:SI 0 "register_operand" "=d")
1641         (div:SI (match_operand:SI 1 "register_operand" "d")
1642                 (match_operand:SI 2 "nonmemory_operand" "di")))
1643    (clobber (match_scratch:SI 3 "=l"))
1644    (clobber (match_scratch:SI 4 "=h"))
1645    (clobber (match_scratch:SI 6 "=a"))]
1646   "!optimize"
1647   "div\\t%0,%1,%2"
1648   [(set_attr "type"     "idiv")
1649    (set_attr "mode"     "SI")
1650    (set_attr "length"   "13")])         ;; various tests for dividing by 0 and such
1652 (define_insn "divdi3"
1653   [(set (match_operand:DI 0 "register_operand" "=d")
1654         (div:DI (match_operand:DI 1 "se_register_operand" "d")
1655                 (match_operand:DI 2 "se_nonmemory_operand" "di")))
1656    (clobber (match_scratch:DI 3 "=l"))
1657    (clobber (match_scratch:DI 4 "=h"))
1658    (clobber (match_scratch:DI 6 "=a"))]
1659   "TARGET_64BIT && !optimize"
1660   "ddiv\\t%0,%1,%2"
1661   [(set_attr "type"     "idiv")
1662    (set_attr "mode"     "DI")
1663    (set_attr "length"   "14")])         ;; various tests for dividing by 0 and such
1665 (define_insn "modsi3"
1666   [(set (match_operand:SI 0 "register_operand" "=d")
1667         (mod:SI (match_operand:SI 1 "register_operand" "d")
1668                 (match_operand:SI 2 "nonmemory_operand" "di")))
1669    (clobber (match_scratch:SI 3 "=l"))
1670    (clobber (match_scratch:SI 4 "=h"))
1671    (clobber (match_scratch:SI 6 "=a"))]
1672   "!optimize"
1673   "rem\\t%0,%1,%2"
1674   [(set_attr "type"     "idiv")
1675    (set_attr "mode"     "SI")
1676    (set_attr "length"   "13")])         ;; various tests for dividing by 0 and such
1678 (define_insn "moddi3"
1679   [(set (match_operand:DI 0 "register_operand" "=d")
1680         (mod:DI (match_operand:DI 1 "se_register_operand" "d")
1681                 (match_operand:DI 2 "se_nonmemory_operand" "di")))
1682    (clobber (match_scratch:DI 3 "=l"))
1683    (clobber (match_scratch:DI 4 "=h"))
1684    (clobber (match_scratch:DI 6 "=a"))]
1685   "TARGET_64BIT && !optimize"
1686   "drem\\t%0,%1,%2"
1687   [(set_attr "type"     "idiv")
1688    (set_attr "mode"     "DI")
1689    (set_attr "length"   "14")])         ;; various tests for dividing by 0 and such
1691 (define_insn "udivsi3"
1692   [(set (match_operand:SI 0 "register_operand" "=d")
1693         (udiv:SI (match_operand:SI 1 "register_operand" "d")
1694                  (match_operand:SI 2 "nonmemory_operand" "di")))
1695    (clobber (match_scratch:SI 3 "=l"))
1696    (clobber (match_scratch:SI 4 "=h"))
1697    (clobber (match_scratch:SI 6 "=a"))]
1698   "!optimize"
1699   "divu\\t%0,%1,%2"
1700   [(set_attr "type"     "idiv")
1701    (set_attr "mode"     "SI")
1702    (set_attr "length"   "7")])          ;; various tests for dividing by 0 and such
1704 (define_insn "udivdi3"
1705   [(set (match_operand:DI 0 "register_operand" "=d")
1706         (udiv:DI (match_operand:DI 1 "se_register_operand" "d")
1707                  (match_operand:DI 2 "se_nonmemory_operand" "di")))
1708    (clobber (match_scratch:DI 3 "=l"))
1709    (clobber (match_scratch:DI 4 "=h"))
1710    (clobber (match_scratch:DI 6 "=a"))]
1711   "TARGET_64BIT && !optimize"
1712   "ddivu\\t%0,%1,%2"
1713   [(set_attr "type"     "idiv")
1714    (set_attr "mode"     "DI")
1715    (set_attr "length"   "7")])          ;; various tests for dividing by 0 and such
1717 (define_insn "umodsi3"
1718   [(set (match_operand:SI 0 "register_operand" "=d")
1719         (umod:SI (match_operand:SI 1 "register_operand" "d")
1720                  (match_operand:SI 2 "nonmemory_operand" "di")))
1721    (clobber (match_scratch:SI 3 "=l"))
1722    (clobber (match_scratch:SI 4 "=h"))
1723    (clobber (match_scratch:SI 6 "=a"))]
1724   "!optimize"
1725   "remu\\t%0,%1,%2"
1726   [(set_attr "type"     "idiv")
1727    (set_attr "mode"     "SI")
1728    (set_attr "length"   "7")])          ;; various tests for dividing by 0 and such
1730 (define_insn "umoddi3"
1731   [(set (match_operand:DI 0 "register_operand" "=d")
1732         (umod:DI (match_operand:DI 1 "se_register_operand" "d")
1733                  (match_operand:DI 2 "se_nonmemory_operand" "di")))
1734    (clobber (match_scratch:DI 3 "=l"))
1735    (clobber (match_scratch:DI 4 "=h"))
1736    (clobber (match_scratch:DI 6 "=a"))]
1737   "TARGET_64BIT && !optimize"
1738   "dremu\\t%0,%1,%2"
1739   [(set_attr "type"     "idiv")
1740    (set_attr "mode"     "DI")
1741    (set_attr "length"   "7")])          ;; various tests for dividing by 0 and such
1745 ;;  ....................
1747 ;;      SQUARE ROOT
1749 ;;  ....................
1751 (define_insn "sqrtdf2"
1752   [(set (match_operand:DF 0 "register_operand" "=f")
1753         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
1754   "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
1755   "sqrt.d\\t%0,%1"
1756   [(set_attr "type"     "fsqrt")
1757    (set_attr "mode"     "DF")
1758    (set_attr "length"   "1")])
1760 (define_insn "sqrtsf2"
1761   [(set (match_operand:SF 0 "register_operand" "=f")
1762         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
1763   "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
1764   "sqrt.s\\t%0,%1"
1765   [(set_attr "type"     "fsqrt")
1766    (set_attr "mode"     "SF")
1767    (set_attr "length"   "1")])
1769 (define_insn ""
1770   [(set (match_operand:DF 0 "register_operand" "=f")
1771         (div:DF (match_operand:DF 1 "const_float_1_operand" "")
1772                 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
1773   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_fast_math"
1774   "rsqrt.d\\t%0,%2"
1775   [(set_attr "type"     "fsqrt")
1776    (set_attr "mode"     "DF")
1777    (set_attr "length"   "1")])
1779 (define_insn ""
1780   [(set (match_operand:SF 0 "register_operand" "=f")
1781         (div:SF (match_operand:SF 1 "const_float_1_operand" "")
1782                 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
1783   "mips_isa >= 4 && TARGET_HARD_FLOAT && flag_fast_math"
1784   "rsqrt.s\\t%0,%2"
1785   [(set_attr "type"     "fsqrt")
1786    (set_attr "mode"     "SF")
1787    (set_attr "length"   "1")])
1791 ;;  ....................
1793 ;;      ABSOLUTE VALUE
1795 ;;  ....................
1797 ;; Do not use the integer abs macro instruction, since that signals an
1798 ;; exception on -2147483648 (sigh).
1800 (define_insn "abssi2"
1801   [(set (match_operand:SI 0 "register_operand" "=d")
1802         (abs:SI (match_operand:SI 1 "register_operand" "d")))]
1803   ""
1804   "*
1806   dslots_jump_total++;
1807   dslots_jump_filled++;
1808   operands[2] = const0_rtx;
1810   if (REGNO (operands[0]) == REGNO (operands[1]))
1811     {
1812       if (GENERATE_BRANCHLIKELY)
1813         return \"%(bltzl\\t%1,1f\\n\\tsubu\\t%0,%z2,%0\\n1:%)\";
1814       else
1815         return \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n1:\";
1816     }     
1817   else
1818     return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n1:%)\";
1820   [(set_attr "type"     "multi")
1821    (set_attr "mode"     "SI")
1822    (set_attr "length"   "3")])
1824 (define_insn "absdi2"
1825   [(set (match_operand:DI 0 "register_operand" "=d")
1826         (abs:DI (match_operand:DI 1 "se_register_operand" "d")))]
1827   "TARGET_64BIT"
1828   "*
1830   dslots_jump_total++;
1831   dslots_jump_filled++;
1832   operands[2] = const0_rtx;
1834   if (REGNO (operands[0]) == REGNO (operands[1]))
1835     return \"%(bltzl\\t%1,1f\\n\\tdsubu\\t%0,%z2,%0\\n1:%)\";
1836   else
1837     return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tdsubu\\t%0,%z2,%0\\n1:%)\";
1839   [(set_attr "type"     "multi")
1840    (set_attr "mode"     "DI")
1841    (set_attr "length"   "3")])
1843 (define_insn "absdf2"
1844   [(set (match_operand:DF 0 "register_operand" "=f")
1845         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
1846   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1847   "abs.d\\t%0,%1"
1848   [(set_attr "type"     "fabs")
1849    (set_attr "mode"     "DF")
1850    (set_attr "length"   "1")])
1852 (define_insn "abssf2"
1853   [(set (match_operand:SF 0 "register_operand" "=f")
1854         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
1855   "TARGET_HARD_FLOAT"
1856   "abs.s\\t%0,%1"
1857   [(set_attr "type"     "fabs")
1858    (set_attr "mode"     "SF")
1859    (set_attr "length"   "1")])
1863 ;;  ....................
1865 ;;      FIND FIRST BIT INSTRUCTION
1867 ;;  ....................
1870 (define_insn "ffssi2"
1871   [(set (match_operand:SI 0 "register_operand" "=&d")
1872         (ffs:SI (match_operand:SI 1 "register_operand" "d")))
1873    (clobber (match_scratch:SI 2 "=&d"))
1874    (clobber (match_scratch:SI 3 "=&d"))]
1875   ""
1876   "*
1878   dslots_jump_total += 2;
1879   dslots_jump_filled += 2;
1880   operands[4] = const0_rtx;
1882   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
1883     return \"%(\\
1884 move\\t%0,%z4\\n\\
1885 \\tbeq\\t%1,%z4,2f\\n\\
1886 1:\\tand\\t%2,%1,0x0001\\n\\
1887 \\taddu\\t%0,%0,1\\n\\
1888 \\tbeq\\t%2,%z4,1b\\n\\
1889 \\tsrl\\t%1,%1,1\\n\\
1890 2:%)\";
1892   return \"%(\\
1893 move\\t%0,%z4\\n\\
1894 \\tmove\\t%3,%1\\n\\
1895 \\tbeq\\t%3,%z4,2f\\n\\
1896 1:\\tand\\t%2,%3,0x0001\\n\\
1897 \\taddu\\t%0,%0,1\\n\\
1898 \\tbeq\\t%2,%z4,1b\\n\\
1899 \\tsrl\\t%3,%3,1\\n\\
1900 2:%)\";
1902   [(set_attr "type"     "multi")
1903    (set_attr "mode"     "SI")
1904    (set_attr "length"   "6")])
1906 (define_insn "ffsdi2"
1907   [(set (match_operand:DI 0 "register_operand" "=&d")
1908         (ffs:DI (match_operand:DI 1 "se_register_operand" "d")))
1909    (clobber (match_scratch:DI 2 "=&d"))
1910    (clobber (match_scratch:DI 3 "=&d"))]
1911   "TARGET_64BIT"
1912   "*
1914   dslots_jump_total += 2;
1915   dslots_jump_filled += 2;
1916   operands[4] = const0_rtx;
1918   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
1919     return \"%(\\
1920 move\\t%0,%z4\\n\\
1921 \\tbeq\\t%1,%z4,2f\\n\\
1922 1:\\tand\\t%2,%1,0x0001\\n\\
1923 \\tdaddu\\t%0,%0,1\\n\\
1924 \\tbeq\\t%2,%z4,1b\\n\\
1925 \\tdsrl\\t%1,%1,1\\n\\
1926 2:%)\";
1928   return \"%(\\
1929 move\\t%0,%z4\\n\\
1930 \\tmove\\t%3,%1\\n\\
1931 \\tbeq\\t%3,%z4,2f\\n\\
1932 1:\\tand\\t%2,%3,0x0001\\n\\
1933 \\tdaddu\\t%0,%0,1\\n\\
1934 \\tbeq\\t%2,%z4,1b\\n\\
1935 \\tdsrl\\t%3,%3,1\\n\\
1936 2:%)\";
1938   [(set_attr "type"     "multi")
1939    (set_attr "mode"     "DI")
1940    (set_attr "length"   "6")])
1944 ;;  ....................
1946 ;;      NEGATION and ONE'S COMPLEMENT
1948 ;;  ....................
1950 (define_insn "negsi2"
1951   [(set (match_operand:SI 0 "register_operand" "=d")
1952         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
1953   ""
1954   "*
1956   operands[2] = const0_rtx;
1957   return \"subu\\t%0,%z2,%1\";
1959   [(set_attr "type"     "arith")
1960    (set_attr "mode"     "SI")
1961    (set_attr "length"   "1")])
1963 (define_expand "negdi2"
1964   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
1965                    (neg:DI (match_operand:DI 1 "se_register_operand" "d")))
1966               (clobber (match_dup 2))])]
1967   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
1968   "
1970   if (TARGET_64BIT)
1971     {
1972       emit_insn (gen_negdi2_internal_2 (operands[0], operands[1]));
1973       DONE;
1974     }
1976   operands[2] = gen_reg_rtx (SImode);
1979 (define_insn "negdi2_internal"
1980   [(set (match_operand:DI 0 "register_operand" "=d")
1981         (neg:DI (match_operand:DI 1 "register_operand" "d")))
1982    (clobber (match_operand:SI 2 "register_operand" "=d"))]
1983   "! TARGET_64BIT && !TARGET_DEBUG_G_MODE"
1984   "*
1986   operands[3] = const0_rtx;
1987   return \"subu\\t%L0,%z3,%L1\;subu\\t%M0,%z3,%M1\;sltu\\t%2,%z3,%L0\;subu\\t%M0,%M0,%2\";
1989   [(set_attr "type"     "darith")
1990    (set_attr "mode"     "DI")
1991    (set_attr "length"   "4")])
1993 (define_insn "negdi2_internal_2"
1994   [(set (match_operand:DI 0 "register_operand" "=d")
1995         (neg:DI (match_operand:DI 1 "se_register_operand" "d")))]
1996   "TARGET_64BIT"
1997   "*
1999   operands[2] = const0_rtx;
2000   return \"dsubu\\t%0,%z2,%1\";
2002   [(set_attr "type"     "arith")
2003    (set_attr "mode"     "DI")
2004    (set_attr "length"   "1")])
2006 (define_insn "negdf2"
2007   [(set (match_operand:DF 0 "register_operand" "=f")
2008         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
2009   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2010   "neg.d\\t%0,%1"
2011   [(set_attr "type"     "fneg")
2012    (set_attr "mode"     "DF")
2013    (set_attr "length"   "1")])
2015 (define_insn "negsf2"
2016   [(set (match_operand:SF 0 "register_operand" "=f")
2017         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2018   "TARGET_HARD_FLOAT"
2019   "neg.s\\t%0,%1"
2020   [(set_attr "type"     "fneg")
2021    (set_attr "mode"     "SF")
2022    (set_attr "length"   "1")])
2024 (define_insn "one_cmplsi2"
2025   [(set (match_operand:SI 0 "register_operand" "=d")
2026         (not:SI (match_operand:SI 1 "register_operand" "d")))]
2027   ""
2028   "*
2030   operands[2] = const0_rtx;
2031   return \"nor\\t%0,%z2,%1\";
2033   [(set_attr "type"     "arith")
2034    (set_attr "mode"     "SI")
2035    (set_attr "length"   "1")])
2037 (define_insn "one_cmpldi2"
2038   [(set (match_operand:DI 0 "register_operand" "=d")
2039         (not:DI (match_operand:DI 1 "se_register_operand" "d")))]
2040   ""
2041   "*
2043   operands[2] = const0_rtx;
2044   if (TARGET_64BIT)
2045     return \"nor\\t%0,%z2,%1\";
2046   return \"nor\\t%M0,%z2,%M1\;nor\\t%L0,%z2,%L1\";
2048   [(set_attr "type"     "darith")
2049    (set_attr "mode"     "DI")
2050    (set (attr "length")
2051         (if_then_else (ge (symbol_ref "mips_isa") (const_int 3))
2052                        (const_int 1)
2053                        (const_int 2)))])
2055 (define_split
2056   [(set (match_operand:DI 0 "register_operand" "")
2057         (not:DI (match_operand:DI 1 "register_operand" "")))]
2058   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2059    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
2060    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
2062   [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0)))
2063    (set (subreg:SI (match_dup 0) 1) (not:SI (subreg:SI (match_dup 1) 1)))]
2064   "")
2068 ;;  ....................
2070 ;;      LOGICAL
2072 ;;  ....................
2075 (define_insn "andsi3"
2076   [(set (match_operand:SI 0 "register_operand" "=d,d")
2077         (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2078                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2079   ""
2080   "@
2081    and\\t%0,%1,%2
2082    andi\\t%0,%1,%x2"
2083   [(set_attr "type"     "arith")
2084    (set_attr "mode"     "SI")
2085    (set_attr "length"   "1")])
2087 (define_insn "anddi3"
2088   [(set (match_operand:DI 0 "register_operand" "=d")
2089         (and:DI (match_operand:DI 1 "se_register_operand" "d")
2090                 (match_operand:DI 2 "se_register_operand" "d")))]
2091   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
2092   "*
2094   if (TARGET_64BIT)
2095     return \"and\\t%0,%1,%2\";
2096   return \"and\\t%M0,%M1,%M2\;and\\t%L0,%L1,%L2\";
2098   [(set_attr "type"     "darith")
2099    (set_attr "mode"     "DI")
2100    (set (attr "length")
2101         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
2102                        (const_int 1)
2103                        (const_int 2)))])
2105 (define_split
2106   [(set (match_operand:DI 0 "register_operand" "")
2107         (and:DI (match_operand:DI 1 "register_operand" "")
2108                 (match_operand:DI 2 "register_operand" "")))]
2109   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2110    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
2111    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
2112    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
2114   [(set (subreg:SI (match_dup 0) 0) (and:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
2115    (set (subreg:SI (match_dup 0) 1) (and:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
2116   "")
2118 (define_insn "anddi3_internal1"
2119   [(set (match_operand:DI 0 "register_operand" "=d,d")
2120         (and:DI (match_operand:DI 1 "se_register_operand" "%d,d")
2121                 (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
2122   "TARGET_64BIT"
2123   "@
2124    and\\t%0,%1,%2
2125    andi\\t%0,%1,%x2"
2126   [(set_attr "type"     "arith")
2127    (set_attr "mode"     "DI")
2128    (set_attr "length"   "1")])
2130 (define_insn "iorsi3"
2131   [(set (match_operand:SI 0 "register_operand" "=d,d")
2132         (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2133                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2134   ""
2135   "@
2136    or\\t%0,%1,%2
2137    ori\\t%0,%1,%x2"
2138   [(set_attr "type"     "arith")
2139    (set_attr "mode"     "SI")
2140    (set_attr "length"   "1")])
2142 ;;; ??? There is no iordi3 pattern which accepts 'K' constants when
2143 ;;; TARGET_64BIT
2145 (define_insn "iordi3"
2146   [(set (match_operand:DI 0 "register_operand" "=d")
2147         (ior:DI (match_operand:DI 1 "se_register_operand" "d")
2148                 (match_operand:DI 2 "se_register_operand" "d")))]
2149   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
2150   "*
2152   if (TARGET_64BIT)
2153     return \"or\\t%0,%1,%2\";
2154   return \"or\\t%M0,%M1,%M2\;or\\t%L0,%L1,%L2\";
2156   [(set_attr "type"     "darith")
2157    (set_attr "mode"     "DI")
2158    (set (attr "length")
2159         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
2160                        (const_int 1)
2161                        (const_int 2)))])
2163 (define_split
2164   [(set (match_operand:DI 0 "register_operand" "")
2165         (ior:DI (match_operand:DI 1 "register_operand" "")
2166                 (match_operand:DI 2 "register_operand" "")))]
2167   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2168    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
2169    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
2170    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
2172   [(set (subreg:SI (match_dup 0) 0) (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
2173    (set (subreg:SI (match_dup 0) 1) (ior:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
2174   "")
2176 (define_insn "xorsi3"
2177   [(set (match_operand:SI 0 "register_operand" "=d,d")
2178         (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2179                 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2180   ""
2181   "@
2182    xor\\t%0,%1,%2
2183    xori\\t%0,%1,%x2"
2184   [(set_attr "type"     "arith")
2185    (set_attr "mode"     "SI")
2186    (set_attr "length"   "1")])
2188 ;; ??? If delete the 32-bit long long patterns, then could merge this with
2189 ;; the following xordi3_internal pattern.
2190 (define_insn "xordi3"
2191   [(set (match_operand:DI 0 "register_operand" "=d")
2192         (xor:DI (match_operand:DI 1 "se_register_operand" "d")
2193                 (match_operand:DI 2 "se_register_operand" "d")))]
2194   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
2195   "*
2197   if (TARGET_64BIT)
2198     return \"xor\\t%0,%1,%2\";
2199   return \"xor\\t%M0,%M1,%M2\;xor\\t%L0,%L1,%L2\";
2201   [(set_attr "type"     "darith")
2202    (set_attr "mode"     "DI")
2203    (set (attr "length")
2204         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
2205                        (const_int 1)
2206                        (const_int 2)))])
2208 (define_split
2209   [(set (match_operand:DI 0 "register_operand" "")
2210         (xor:DI (match_operand:DI 1 "register_operand" "")
2211                 (match_operand:DI 2 "register_operand" "")))]
2212   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2213    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
2214    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
2215    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
2217   [(set (subreg:SI (match_dup 0) 0) (xor:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0)))
2218    (set (subreg:SI (match_dup 0) 1) (xor:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))]
2219   "")
2221 (define_insn "xordi3_immed"
2222   [(set (match_operand:DI 0 "register_operand" "d")
2223         (xor:DI (match_operand:DI 1 "se_register_operand" "d")
2224                 (match_operand:DI 2 "se_uns_arith_operand" "K")))]
2225   "TARGET_64BIT"
2226   "xori\\t%0,%1,%x2"
2227   [(set_attr "type"     "arith")
2228    (set_attr "mode"     "DI")
2229    (set_attr "length"   "1")])
2231 (define_insn "*norsi3"
2232   [(set (match_operand:SI 0 "register_operand" "=d")
2233         (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
2234                 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
2235   ""
2236   "nor\\t%0,%z1,%z2"
2237   [(set_attr "type"     "arith")
2238    (set_attr "mode"     "SI")
2239    (set_attr "length"   "1")])
2241 (define_insn "*nordi3"
2242   [(set (match_operand:DI 0 "register_operand" "=d")
2243         (and:DI (not:DI (match_operand:DI 1 "se_register_operand" "d"))
2244                 (not:DI (match_operand:DI 2 "se_register_operand" "d"))))]
2245   ""
2246   "*
2248   if (TARGET_64BIT)
2249     return \"nor\\t%0,%z1,%z2\";
2250   return \"nor\\t%M0,%M1,%M2\;nor\\t%L0,%L1,%L2\";
2252   [(set_attr "type"     "darith")
2253    (set_attr "mode"     "DI")
2254    (set (attr "length")
2255         (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0))
2256                        (const_int 1)
2257                        (const_int 2)))])
2259 (define_split
2260   [(set (match_operand:DI 0 "register_operand" "")
2261         (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
2262                 (not:DI (match_operand:DI 2 "register_operand" ""))))]
2263   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
2264    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
2265    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
2266    && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
2268   [(set (subreg:SI (match_dup 0) 0) (and:SI (not:SI (subreg:SI (match_dup 1) 0)) (not:SI (subreg:SI (match_dup 2) 0))))
2269    (set (subreg:SI (match_dup 0) 1) (and:SI (not:SI (subreg:SI (match_dup 1) 1)) (not:SI (subreg:SI (match_dup 2) 1))))]
2270   "")
2273 ;;  ....................
2275 ;;      TRUNCATION
2277 ;;  ....................
2279 (define_insn "truncdfsf2"
2280   [(set (match_operand:SF 0 "register_operand" "=f")
2281         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2282   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2283   "cvt.s.d\\t%0,%1"
2284   [(set_attr "type"     "fcvt")
2285    (set_attr "mode"     "SF")
2286    (set_attr "length"   "1")])
2288 (define_insn "truncdisi2"
2289   [(set (match_operand:SI 0 "register_operand" "=d")
2290         (truncate:SI (match_operand:DI 1 "se_register_operand" "d")))]
2291   "TARGET_64BIT"
2292   "dsll\\t%0,%1,32\;dsra\\t%0,%0,32"
2293   [(set_attr "type"     "darith")
2294    (set_attr "mode"     "SI")
2295    (set_attr "length"   "2")])
2297 (define_insn "truncdihi2"
2298   [(set (match_operand:HI 0 "register_operand" "=d")
2299         (truncate:HI (match_operand:DI 1 "se_register_operand" "d")))]
2300   "TARGET_64BIT"
2301   "andi\\t%0,%1,0xffff"
2302   [(set_attr "type"     "darith")
2303    (set_attr "mode"     "HI")
2304    (set_attr "length"   "1")])
2306 (define_insn "truncdiqi2"
2307   [(set (match_operand:QI 0 "register_operand" "=d")
2308         (truncate:QI (match_operand:DI 1 "se_register_operand" "d")))]
2309   "TARGET_64BIT"
2310   "andi\\t%0,%1,0x00ff"
2311   [(set_attr "type"     "darith")
2312    (set_attr "mode"     "QI")
2313    (set_attr "length"   "1")])
2315 ;; Combiner patterns to optimize shift/truncate combinations.
2316 (define_insn ""
2317   [(set (match_operand:SI 0 "register_operand" "=d")
2318         (truncate:SI (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
2319                                   (match_operand:DI 2 "small_int" "I"))))]
2320   "TARGET_64BIT"
2321   "*
2323   int shift_amt = INTVAL (operands[2]) & 0x3f;
2325   if (shift_amt < 32)
2326     {
2327       operands[2] = GEN_INT (32 - shift_amt);
2328       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
2329     }
2330   else
2331     {
2332       operands[2] = GEN_INT (shift_amt);
2333       return \"dsra\\t%0,%1,%2\";
2334     }
2336   [(set_attr "type"     "darith")
2337    (set_attr "mode"     "SI")
2338    (set_attr "length"   "2")])
2339         
2340 (define_insn ""
2341   [(set (match_operand:SI 0 "register_operand" "=d")
2342         (truncate:SI (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
2343                                   (match_operand:DI 2 "small_int" "I"))))]
2344   "TARGET_64BIT"
2345   "*
2347   int shift_amt = INTVAL (operands[2]) & 0x3f;
2349   if (shift_amt < 32)
2350     {
2351       operands[2] = GEN_INT (32 - shift_amt);
2352       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
2353     }
2354   else if (shift_amt == 32)
2355     return \"dsra\\t%0,%1,32\";
2356   else
2357     {
2358       operands[2] = GEN_INT (shift_amt);
2359       return \"dsrl\\t%0,%1,%2\";
2360     }
2362   [(set_attr "type"     "darith")
2363    (set_attr "mode"     "SI")
2364    (set_attr "length"   "2")])
2366 (define_insn ""
2367   [(set (match_operand:SI 0 "register_operand" "=d")
2368         (truncate:SI (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
2369                                 (match_operand:DI 2 "small_int" "I"))))]
2370   "TARGET_64BIT"
2371   "*
2373   int shift_amt = INTVAL (operands[2]) & 0x3f;
2375   if (shift_amt < 32)
2376     {
2377       operands[2] = GEN_INT (32 + shift_amt);
2378       return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\";
2379     }
2380   else
2381     return \"move\\t%0,%.\";
2383   [(set_attr "type"     "darith")
2384    (set_attr "mode"     "SI")
2385    (set_attr "length"   "2")])
2387 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2389 (define_insn ""
2390   [(set (match_operand:SI 0 "register_operand" "=d")
2391         (zero_extend:SI (truncate:HI
2392                          (match_operand:DI 1 "se_register_operand" "d"))))]
2393   "TARGET_64BIT"
2394   "andi\\t%0,%1,0xffff"
2395   [(set_attr "type"     "darith")
2396    (set_attr "mode"     "SI")
2397    (set_attr "length"   "1")])
2399 (define_insn ""
2400   [(set (match_operand:SI 0 "register_operand" "=d")
2401         (zero_extend:SI (truncate:QI
2402                          (match_operand:DI 1 "se_register_operand" "d"))))]
2403   "TARGET_64BIT"
2404   "andi\\t%0,%1,0xff"
2405   [(set_attr "type"     "darith")
2406    (set_attr "mode"     "SI")
2407    (set_attr "length"   "1")])
2409 (define_insn ""
2410   [(set (match_operand:HI 0 "register_operand" "=d")
2411         (zero_extend:HI (truncate:QI
2412                          (match_operand:DI 1 "se_register_operand" "d"))))]
2413   "TARGET_64BIT"
2414   "andi\\t%0,%1,0xff"
2415   [(set_attr "type"     "darith")
2416    (set_attr "mode"     "HI")
2417    (set_attr "length"   "1")])
2420 ;;  ....................
2422 ;;      ZERO EXTENSION
2424 ;;  ....................
2426 ;; Extension insns.
2427 ;; Those for integer source operand are ordered widest source type first.
2429 (define_expand "zero_extendsidi2"
2430   [(set (match_operand:DI 0 "register_operand" "")
2431         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
2432   "TARGET_64BIT"
2433   "
2435   if (optimize && GET_CODE (operands[1]) == MEM)
2436     operands[1] = force_not_mem (operands[1]);
2438   if (GET_CODE (operands[1]) != MEM)
2439     {
2440       rtx op1   = gen_lowpart (DImode, operands[1]);
2441       rtx temp  = gen_reg_rtx (DImode);
2442       rtx shift = GEN_INT (32);
2444       emit_insn (gen_ashldi3 (temp, op1, shift));
2445       emit_insn (gen_lshrdi3 (operands[0], temp, shift));
2446       DONE;
2447     }
2450 (define_insn "zero_extendsidi2_internal"
2451   [(set (match_operand:DI 0 "register_operand" "=d,d")
2452         (zero_extend:DI (match_operand:SI 1 "memory_operand" "R,m")))]
2453   "TARGET_64BIT"
2454   "* return mips_move_1word (operands, insn, TRUE);"
2455   [(set_attr "type"     "load")
2456    (set_attr "mode"     "DI")
2457    (set_attr "length"   "1,2")])
2459 (define_insn "zero_extendhisi2"
2460   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
2461         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
2462   ""
2463   "*
2465   if (which_alternative == 0)
2466     return \"andi\\t%0,%1,0xffff\";
2467   else
2468     return mips_move_1word (operands, insn, TRUE);
2470   [(set_attr "type"     "arith,load,load")
2471    (set_attr "mode"     "SI")
2472    (set_attr "length"   "1,1,2")])
2474 (define_insn "zero_extendhidi2"
2475   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
2476         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
2477   "TARGET_64BIT"
2478   "*
2480   if (which_alternative == 0)
2481     return \"andi\\t%0,%1,0xffff\";
2482   else
2483     return mips_move_1word (operands, insn, TRUE);
2485   [(set_attr "type"     "arith,load,load")
2486    (set_attr "mode"     "DI")
2487    (set_attr "length"   "1,1,2")])
2489 (define_insn "zero_extendqihi2"
2490   [(set (match_operand:HI 0 "register_operand" "=d,d,d")
2491         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
2492   ""
2493   "*
2495   if (which_alternative == 0)
2496     return \"andi\\t%0,%1,0x00ff\";
2497   else
2498     return mips_move_1word (operands, insn, TRUE);
2500   [(set_attr "type"     "arith,load,load")
2501    (set_attr "mode"     "HI")
2502    (set_attr "length"   "1,1,2")])
2504 (define_insn "zero_extendqisi2"
2505   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
2506         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
2507   ""
2508   "*
2510   if (which_alternative == 0)
2511     return \"andi\\t%0,%1,0x00ff\";
2512   else
2513     return mips_move_1word (operands, insn, TRUE);
2515   [(set_attr "type"     "arith,load,load")
2516    (set_attr "mode"     "SI")
2517    (set_attr "length"   "1,1,2")])
2519 (define_insn "zero_extendqidi2"
2520   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
2521         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
2522   "TARGET_64BIT"
2523   "*
2525   if (which_alternative == 0)
2526     return \"andi\\t%0,%1,0x00ff\";
2527   else
2528     return mips_move_1word (operands, insn, TRUE);
2530   [(set_attr "type"     "arith,load,load")
2531    (set_attr "mode"     "DI")
2532    (set_attr "length"   "1,1,2")])
2534 ;; These can be created when a paradoxical subreg operand with an implicit
2535 ;; sign_extend operator is reloaded.  Because of the subreg, this is really
2536 ;; a zero extend.
2537 ;; ??? It might be possible to eliminate the need for these patterns by adding
2538 ;; more support to reload for implicit sign_extend operators.
2539 (define_insn "*paradoxical_extendhidi2"
2540   [(set (match_operand:DI 0 "register_operand" "=d,d")
2541         (sign_extend:DI
2542          (subreg:SI (match_operand:HI 1 "memory_operand" "R,m") 0)))]
2543   "TARGET_64BIT"
2544   "*
2546   return mips_move_1word (operands, insn, TRUE);
2548   [(set_attr "type"     "load,load")
2549    (set_attr "mode"     "DI")
2550    (set_attr "length"   "1,2")])
2552 (define_insn "*paradoxical_extendqidi2"
2553   [(set (match_operand:DI 0 "register_operand" "=d,d")
2554         (sign_extend:DI
2555          (subreg:SI (match_operand:QI 1 "memory_operand" "R,m") 0)))]
2556   "TARGET_64BIT"
2557   "*
2559   return mips_move_1word (operands, insn, TRUE);
2561   [(set_attr "type"     "load,load")
2562    (set_attr "mode"     "DI")
2563    (set_attr "length"   "1,2")])
2566 ;;  ....................
2568 ;;      SIGN EXTENSION
2570 ;;  ....................
2572 ;; Extension insns.
2573 ;; Those for integer source operand are ordered widest source type first.
2575 ;; In 64 bit mode, 32 bit values in general registers are always
2576 ;; correctly sign extended.  That means that if the target is a
2577 ;; general register, we can sign extend from SImode to DImode just by
2578 ;; doing a move.
2580 (define_insn "extendsidi2"
2581   [(set (match_operand:DI 0 "register_operand" "=d,*d,d,d")
2582         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,*x,R,m")))]
2583   "TARGET_64BIT"
2584   "* return mips_move_1word (operands, insn, FALSE);"
2585   [(set_attr "type"     "move,hilo,load,load")
2586    (set_attr "mode"     "DI")
2587    (set_attr "length"   "1,1,1,2")])
2589 ;; These patterns originally accepted general_operands, however, slightly
2590 ;; better code is generated by only accepting register_operands, and then
2591 ;; letting combine generate the lh and lb insns.
2593 (define_expand "extendhidi2"
2594   [(set (match_operand:DI 0 "register_operand" "")
2595         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
2596   "TARGET_64BIT"
2597   "
2599   if (optimize && GET_CODE (operands[1]) == MEM)
2600     operands[1] = force_not_mem (operands[1]);
2602   if (GET_CODE (operands[1]) != MEM)
2603     {
2604       rtx op1   = gen_lowpart (DImode, operands[1]);
2605       rtx temp  = gen_reg_rtx (DImode);
2606       rtx shift = GEN_INT (48);
2608       emit_insn (gen_ashldi3 (temp, op1, shift));
2609       emit_insn (gen_ashrdi3 (operands[0], temp, shift));
2610       DONE;
2611     }
2614 (define_insn "extendhidi2_internal"
2615   [(set (match_operand:DI 0 "register_operand" "=d,d")
2616         (sign_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
2617   "TARGET_64BIT"
2618   "* return mips_move_1word (operands, insn, FALSE);"
2619   [(set_attr "type"     "load")
2620    (set_attr "mode"     "DI")
2621    (set_attr "length"   "1,2")])
2623 (define_expand "extendhisi2"
2624   [(set (match_operand:SI 0 "register_operand" "")
2625         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2626   ""
2627   "
2629   if (optimize && GET_CODE (operands[1]) == MEM)
2630     operands[1] = force_not_mem (operands[1]);
2632   if (GET_CODE (operands[1]) != MEM)
2633     {
2634       rtx op1   = gen_lowpart (SImode, operands[1]);
2635       rtx temp  = gen_reg_rtx (SImode);
2636       rtx shift = GEN_INT (16);
2638       emit_insn (gen_ashlsi3 (temp, op1, shift));
2639       emit_insn (gen_ashrsi3 (operands[0], temp, shift));
2640       DONE;
2641     }
2644 (define_insn "extendhisi2_internal"
2645   [(set (match_operand:SI 0 "register_operand" "=d,d")
2646         (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
2647   ""
2648   "* return mips_move_1word (operands, insn, FALSE);"
2649   [(set_attr "type"     "load")
2650    (set_attr "mode"     "SI")
2651    (set_attr "length"   "1,2")])
2653 (define_expand "extendqihi2"
2654   [(set (match_operand:HI 0 "register_operand" "")
2655         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
2656   ""
2657   "
2659   if (optimize && GET_CODE (operands[1]) == MEM)
2660     operands[1] = force_not_mem (operands[1]);
2662   if (GET_CODE (operands[1]) != MEM)
2663     {
2664       rtx op0   = gen_lowpart (SImode, operands[0]);
2665       rtx op1   = gen_lowpart (SImode, operands[1]);
2666       rtx temp  = gen_reg_rtx (SImode);
2667       rtx shift = GEN_INT (24);
2669       emit_insn (gen_ashlsi3 (temp, op1, shift));
2670       emit_insn (gen_ashrsi3 (op0, temp, shift));
2671       DONE;
2672     }
2675 (define_insn "extendqihi2_internal"
2676   [(set (match_operand:HI 0 "register_operand" "=d,d")
2677         (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
2678   ""
2679   "* return mips_move_1word (operands, insn, FALSE);"
2680   [(set_attr "type"     "load")
2681    (set_attr "mode"     "SI")
2682    (set_attr "length"   "1,2")])
2685 (define_expand "extendqisi2"
2686   [(set (match_operand:SI 0 "register_operand" "")
2687         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
2688   ""
2689   "
2691   if (optimize && GET_CODE (operands[1]) == MEM)
2692     operands[1] = force_not_mem (operands[1]);
2694   if (GET_CODE (operands[1]) != MEM)
2695     {
2696       rtx op1   = gen_lowpart (SImode, operands[1]);
2697       rtx temp  = gen_reg_rtx (SImode);
2698       rtx shift = GEN_INT (24);
2700       emit_insn (gen_ashlsi3 (temp, op1, shift));
2701       emit_insn (gen_ashrsi3 (operands[0], temp, shift));
2702       DONE;
2703     }
2706 (define_insn "extendqisi2_insn"
2707   [(set (match_operand:SI 0 "register_operand" "=d,d")
2708         (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
2709   ""
2710   "* return mips_move_1word (operands, insn, FALSE);"
2711   [(set_attr "type"     "load")
2712    (set_attr "mode"     "SI")
2713    (set_attr "length"   "1,2")])
2715 (define_expand "extendqidi2"
2716   [(set (match_operand:DI 0 "register_operand" "")
2717         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
2718   "TARGET_64BIT"
2719   "
2721   if (optimize && GET_CODE (operands[1]) == MEM)
2722     operands[1] = force_not_mem (operands[1]);
2724   if (GET_CODE (operands[1]) != MEM)
2725     {
2726       rtx op1   = gen_lowpart (DImode, operands[1]);
2727       rtx temp  = gen_reg_rtx (DImode);
2728       rtx shift = GEN_INT (56);
2730       emit_insn (gen_ashldi3 (temp, op1, shift));
2731       emit_insn (gen_ashrdi3 (operands[0], temp, shift));
2732       DONE;
2733     }
2736 (define_insn "extendqidi2_insn"
2737   [(set (match_operand:DI 0 "register_operand" "=d,d")
2738         (sign_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
2739   "TARGET_64BIT"
2740   "* return mips_move_1word (operands, insn, FALSE);"
2741   [(set_attr "type"     "load")
2742    (set_attr "mode"     "DI")
2743    (set_attr "length"   "1,2")])
2746 (define_insn "extendsfdf2"
2747   [(set (match_operand:DF 0 "register_operand" "=f")
2748         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2749   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2750   "cvt.d.s\\t%0,%1"
2751   [(set_attr "type"     "fcvt")
2752    (set_attr "mode"     "DF")
2753    (set_attr "length"   "1")])
2758 ;;  ....................
2760 ;;      CONVERSIONS
2762 ;;  ....................
2764 ;; The SImode scratch register can not be shared with address regs used for
2765 ;; operand zero, because then the address in the move instruction will be
2766 ;; clobbered.  We mark the scratch register as early clobbered to prevent this.
2768 ;; We need the ?X in alternative 1 so that it will be choosen only if the
2769 ;; destination is a floating point register.  Otherwise, alternative 1 can
2770 ;; have lower cost than alternative 0 (because there is one less loser), and
2771 ;; can be choosen when it won't work (because integral reloads into FP
2772 ;; registers are not supported).
2774 (define_insn "fix_truncdfsi2"
2775   [(set (match_operand:SI 0 "general_operand" "=d,*f,R,o")
2776         (fix:SI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
2777    (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
2778    (clobber (match_scratch:DF 3 "=f,?*X,f,f"))]
2779   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2780   "*
2782   rtx xoperands[10];
2784   if (which_alternative == 1)
2785     return \"trunc.w.d %0,%1,%2\";
2787   output_asm_insn (\"trunc.w.d %3,%1,%2\", operands);
2789   xoperands[0] = operands[0];
2790   xoperands[1] = operands[3];
2791   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
2792   return \"\";
2794   [(set_attr "type"     "fcvt")
2795    (set_attr "mode"     "DF")
2796    (set_attr "length"   "11,9,10,11")])
2799 (define_insn "fix_truncsfsi2"
2800   [(set (match_operand:SI 0 "general_operand" "=d,*f,R,o")
2801         (fix:SI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
2802    (clobber (match_scratch:SI 2 "=d,*d,&d,&d"))
2803    (clobber (match_scratch:SF 3 "=f,?*X,f,f"))]
2804   "TARGET_HARD_FLOAT"
2805   "*
2807   rtx xoperands[10];
2809   if (which_alternative == 1)
2810     return \"trunc.w.s %0,%1,%2\";
2812   output_asm_insn (\"trunc.w.s %3,%1,%2\", operands);
2814   xoperands[0] = operands[0];
2815   xoperands[1] = operands[3];
2816   output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
2817   return \"\";
2819   [(set_attr "type"     "fcvt")
2820    (set_attr "mode"     "SF")
2821    (set_attr "length"   "11,9,10,11")])
2824 ;;; ??? trunc.l.d is mentioned in the appendix of the 1993 r4000/r4600 manuals
2825 ;;; but not in the chapter that describes the FPU.  It is not mentioned at all
2826 ;;; in the 1991 manuals.  The r4000 at Cygnus does not have this instruction.
2828 ;;; Deleting this means that we now need two libgcc2.a libraries.  One for
2829 ;;; the 32 bit calling convention and one for the 64 bit calling convention.
2831 ;;; If this is disabled, then fixuns_truncdfdi2 must be disabled also.
2833 (define_insn "fix_truncdfdi2"
2834   [(set (match_operand:DI 0 "general_operand" "=d,*f,R,o")
2835         (fix:DI (match_operand:DF 1 "register_operand" "f,*f,f,f")))
2836    (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
2837   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2838   "*
2840   rtx xoperands[10];
2842   if (which_alternative == 1)
2843     return \"trunc.l.d %0,%1\";
2845   output_asm_insn (\"trunc.l.d %2,%1\", operands);
2847   xoperands[0] = operands[0];
2848   xoperands[1] = operands[2];
2849   output_asm_insn (mips_move_2words (xoperands, insn, FALSE), xoperands);
2850   return \"\";
2852   [(set_attr "type"     "fcvt")
2853    (set_attr "mode"     "DF")
2854    (set_attr "length"   "2,1,2,3")])
2857 ;;; ??? trunc.l.s is mentioned in the appendix of the 1993 r4000/r4600 manuals
2858 ;;; but not in the chapter that describes the FPU.  It is not mentioned at all
2859 ;;; in the 1991 manuals.  The r4000 at Cygnus does not have this instruction.
2860 (define_insn "fix_truncsfdi2"
2861   [(set (match_operand:DI 0 "general_operand" "=d,*f,R,o")
2862         (fix:DI (match_operand:SF 1 "register_operand" "f,*f,f,f")))
2863    (clobber (match_scratch:DF 2 "=f,?*X,f,f"))]
2864   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2865   "*
2867   rtx xoperands[10];
2869   if (which_alternative == 1)
2870     return \"trunc.l.s %0,%1\";
2872   output_asm_insn (\"trunc.l.s %2,%1\", operands);
2874   xoperands[0] = operands[0];
2875   xoperands[1] = operands[2];
2876   output_asm_insn (mips_move_2words (xoperands, insn, FALSE), xoperands);
2877   return \"\";
2879   [(set_attr "type"     "fcvt")
2880    (set_attr "mode"     "SF")
2881    (set_attr "length"   "2,1,2,3")])
2884 (define_insn "floatsidf2"
2885   [(set (match_operand:DF 0 "register_operand" "=f,f,f")
2886         (float:DF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
2887   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2888   "*
2890   dslots_load_total++;
2891   if (GET_CODE (operands[1]) == MEM)
2892     return \"l.s\\t%0,%1%#\;cvt.d.w\\t%0,%0\";
2894   return \"mtc1\\t%1,%0%#\;cvt.d.w\\t%0,%0\";
2896   [(set_attr "type"     "fcvt")
2897    (set_attr "mode"     "DF")
2898    (set_attr "length"   "3,4,3")])
2901 (define_insn "floatdidf2"
2902   [(set (match_operand:DF 0 "register_operand" "=f,f,f")
2903         (float:DF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
2904   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2905   "*
2907   dslots_load_total++;
2908   if (GET_CODE (operands[1]) == MEM)
2909     return \"l.d\\t%0,%1%#\;cvt.d.l\\t%0,%0\";
2911   return \"dmtc1\\t%1,%0%#\;cvt.d.l\\t%0,%0\";
2913   [(set_attr "type"     "fcvt")
2914    (set_attr "mode"     "DF")
2915    (set_attr "length"   "3,4,3")])
2918 (define_insn "floatsisf2"
2919   [(set (match_operand:SF 0 "register_operand" "=f,f,f")
2920         (float:SF (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
2921   "TARGET_HARD_FLOAT"
2922   "*
2924   dslots_load_total++;
2925   if (GET_CODE (operands[1]) == MEM)
2926     return \"l.s\\t%0,%1%#\;cvt.s.w\\t%0,%0\";
2928   return \"mtc1\\t%1,%0%#\;cvt.s.w\\t%0,%0\";
2930   [(set_attr "type"     "fcvt")
2931    (set_attr "mode"     "SF")
2932    (set_attr "length"   "3,4,3")])
2935 (define_insn "floatdisf2"
2936   [(set (match_operand:SF 0 "register_operand" "=f,f,f")
2937         (float:SF (match_operand:DI 1 "se_nonimmediate_operand" "d,R,m")))]
2938   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2939   "*
2941   dslots_load_total++;
2942   if (GET_CODE (operands[1]) == MEM)
2943     return \"l.d\\t%0,%1%#\;cvt.s.l\\t%0,%0\";
2945   return \"dmtc1\\t%1,%0%#\;cvt.s.l\\t%0,%0\";
2947   [(set_attr "type"     "fcvt")
2948    (set_attr "mode"     "SF")
2949    (set_attr "length"   "3,4,3")])
2952 (define_expand "fixuns_truncdfsi2"
2953   [(set (match_operand:SI 0 "register_operand" "")
2954         (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
2955   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2956   "
2958   rtx reg1 = gen_reg_rtx (DFmode);
2959   rtx reg2 = gen_reg_rtx (DFmode);
2960   rtx reg3 = gen_reg_rtx (SImode);
2961   rtx label1 = gen_label_rtx ();
2962   rtx label2 = gen_label_rtx ();
2963   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
2965   if (reg1)                     /* turn off complaints about unreached code */
2966     {
2967       emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
2968       do_pending_stack_adjust ();
2970       emit_insn (gen_cmpdf (operands[1], reg1));
2971       emit_jump_insn (gen_bge (label1));
2973       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2974       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2975                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
2976       emit_barrier ();
2978       emit_label (label1);
2979       emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2980       emit_move_insn (reg3, GEN_INT (0x80000000));
2982       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
2983       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2985       emit_label (label2);
2987       /* allow REG_NOTES to be set on last insn (labels don't have enough
2988          fields, and can't be used for REG_NOTES anyway).  */
2989       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2990       DONE;
2991     }
2995 (define_expand "fixuns_truncdfdi2"
2996   [(set (match_operand:DI 0 "register_operand" "")
2997         (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
2998   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2999   "
3001   rtx reg1 = gen_reg_rtx (DFmode);
3002   rtx reg2 = gen_reg_rtx (DFmode);
3003   rtx reg3 = gen_reg_rtx (DImode);
3004   rtx label1 = gen_label_rtx ();
3005   rtx label2 = gen_label_rtx ();
3006   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
3008   if (reg1)                     /* turn off complaints about unreached code */
3009     {
3010       emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
3011       do_pending_stack_adjust ();
3013       emit_insn (gen_cmpdf (operands[1], reg1));
3014       emit_jump_insn (gen_bge (label1));
3016       emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3017       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3018                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
3019       emit_barrier ();
3021       emit_label (label1);
3022       emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3023       emit_move_insn (reg3, GEN_INT (0x80000000));
3024       emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3026       emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3027       emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3029       emit_label (label2);
3031       /* allow REG_NOTES to be set on last insn (labels don't have enough
3032          fields, and can't be used for REG_NOTES anyway).  */
3033       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3034       DONE;
3035     }
3039 (define_expand "fixuns_truncsfsi2"
3040   [(set (match_operand:SI 0 "register_operand" "")
3041         (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
3042   "TARGET_HARD_FLOAT"
3043   "
3045   rtx reg1 = gen_reg_rtx (SFmode);
3046   rtx reg2 = gen_reg_rtx (SFmode);
3047   rtx reg3 = gen_reg_rtx (SImode);
3048   rtx label1 = gen_label_rtx ();
3049   rtx label2 = gen_label_rtx ();
3050   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
3052   if (reg1)                     /* turn off complaints about unreached code */
3053     {
3054       emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
3055       do_pending_stack_adjust ();
3057       emit_insn (gen_cmpsf (operands[1], reg1));
3058       emit_jump_insn (gen_bge (label1));
3060       emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3061       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3062                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
3063       emit_barrier ();
3065       emit_label (label1);
3066       emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3067       emit_move_insn (reg3, GEN_INT (0x80000000));
3069       emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3070       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3072       emit_label (label2);
3074       /* allow REG_NOTES to be set on last insn (labels don't have enough
3075          fields, and can't be used for REG_NOTES anyway).  */
3076       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3077       DONE;
3078     }
3082 (define_expand "fixuns_truncsfdi2"
3083   [(set (match_operand:DI 0 "register_operand" "")
3084         (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
3085   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3086   "
3088   rtx reg1 = gen_reg_rtx (SFmode);
3089   rtx reg2 = gen_reg_rtx (SFmode);
3090   rtx reg3 = gen_reg_rtx (DImode);
3091   rtx label1 = gen_label_rtx ();
3092   rtx label2 = gen_label_rtx ();
3093   REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 63);
3095   if (reg1)                     /* turn off complaints about unreached code */
3096     {
3097       emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
3098       do_pending_stack_adjust ();
3100       emit_insn (gen_cmpsf (operands[1], reg1));
3101       emit_jump_insn (gen_bge (label1));
3103       emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3104       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3105                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
3106       emit_barrier ();
3108       emit_label (label1);
3109       emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3110       emit_move_insn (reg3, GEN_INT (0x80000000));
3111       emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3113       emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3114       emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3116       emit_label (label2);
3118       /* allow REG_NOTES to be set on last insn (labels don't have enough
3119          fields, and can't be used for REG_NOTES anyway).  */
3120       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3121       DONE;
3122     }
3127 ;;  ....................
3129 ;;      DATA MOVEMENT
3131 ;;  ....................
3133 ;; Bit field extract patterns which use lwl/lwr.
3135 ;; ??? There should be DImode variants for 64 bit code, but the current
3136 ;; bitfield scheme can't handle that.  We would need to add new optabs
3137 ;; in order to make that work.
3139 ;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
3140 ;; It isn't clear whether this will give better code.
3142 (define_expand "extv"
3143   [(set (match_operand:SI 0 "register_operand" "")
3144         (sign_extract:SI (match_operand:QI 1 "memory_operand" "")
3145                          (match_operand:SI 2 "immediate_operand" "")
3146                          (match_operand:SI 3 "immediate_operand" "")))]
3147   ""
3148   "
3150   /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
3151      then fail.  */
3152   if (INTVAL (operands[2]) != 32 || (INTVAL (operands[3]) % 8) != 0)
3153     FAIL;
3155   /* This can happen for a 64 bit target, when extracting a value from
3156      a 64 bit union member.  extract_bit_field doesn't verify that our
3157      source matches the predicate, so we force it to be a MEM here.  */
3158   if (GET_CODE (operands[1]) != MEM)
3159     FAIL;
3161   /* Change the mode to BLKmode for aliasing purposes.  */
3162   operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
3164   /* Otherwise, emit a lwl/lwr pair to load the value.  */
3165   emit_insn (gen_movsi_ulw (operands[0], operands[1]));
3166   DONE;
3169 (define_expand "extzv"
3170   [(set (match_operand:SI 0 "register_operand" "")
3171         (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
3172                          (match_operand:SI 2 "immediate_operand" "")
3173                          (match_operand:SI 3 "immediate_operand" "")))]
3174   ""
3175   "
3177   /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
3178      then fail.  */
3179   if (INTVAL (operands[2]) != 32 || (INTVAL (operands[3]) % 8) != 0)
3180     FAIL;
3182   /* This can happen for a 64 bit target, when extracting a value from
3183      a 64 bit union member.  extract_bit_field doesn't verify that our
3184      source matches the predicate, so we force it to be a MEM here.  */
3185   if (GET_CODE (operands[1]) != MEM)
3186     FAIL;
3188   /* Change the mode to BLKmode for aliasing purposes.  */
3189   operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
3191   /* Otherwise, emit a lwl/lwr pair to load the value.  */
3192   emit_insn (gen_movsi_ulw (operands[0], operands[1]));
3193   DONE;
3196 (define_expand "insv"
3197   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
3198                          (match_operand:SI 1 "immediate_operand" "")
3199                          (match_operand:SI 2 "immediate_operand" ""))
3200         (match_operand:SI 3 "register_operand" ""))]
3201   ""
3202   "
3204   /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
3205      then fail.  */
3206   if (INTVAL (operands[1]) != 32 || (INTVAL (operands[2]) % 8) != 0)
3207     FAIL;
3209   /* This can happen for a 64 bit target, when storing into a 32 bit union
3210      member.  store_bit_field doesn't verify that our target matches the
3211      predicate, so we force it to be a MEM here.  */
3212   if (GET_CODE (operands[0]) != MEM)
3213     FAIL;
3215   /* Change the mode to BLKmode for aliasing purposes.  */
3216   operands[0] = change_address (operands[0], BLKmode, XEXP (operands[0], 0));
3218   /* Otherwise, emit a swl/swr pair to load the value.  */
3219   emit_insn (gen_movsi_usw (operands[0], operands[3]));
3220   DONE;
3223 ;; unaligned word moves generated by the bit field patterns
3225 (define_insn "movsi_ulw"
3226   [(set (match_operand:SI 0 "register_operand" "=&d,&d")
3227         (unspec:SI [(match_operand:BLK 1 "general_operand" "R,o")] 0))]
3228   ""
3229   "*
3231   rtx offset = const0_rtx;
3232   rtx addr = XEXP (operands[1], 0);
3233   rtx mem_addr = eliminate_constant_term (addr, &offset);
3234   char *ret;
3236   if (TARGET_STATS)
3237     mips_count_memory_refs (operands[1], 2);
3239   /* The stack/frame pointers are always aligned, so we can convert
3240      to the faster lw if we are referencing an aligned stack location.  */
3242   if ((INTVAL (offset) & 3) == 0
3243       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
3244     ret = \"lw\\t%0,%1\";
3245   else
3246     ret = \"ulw\\t%0,%1\";
3248   return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
3250   [(set_attr "type"     "load,load")
3251    (set_attr "mode"     "SI")
3252    (set_attr "length"   "2,4")])
3254 (define_insn "movsi_usw"
3255   [(set (match_operand:BLK 0 "memory_operand" "=R,o")
3256         (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")] 1))]
3257   ""
3258   "*
3260   rtx offset = const0_rtx;
3261   rtx addr = XEXP (operands[0], 0);
3262   rtx mem_addr = eliminate_constant_term (addr, &offset);
3264   if (TARGET_STATS)
3265     mips_count_memory_refs (operands[0], 2);
3267   /* The stack/frame pointers are always aligned, so we can convert
3268      to the faster sw if we are referencing an aligned stack location.  */
3270   if ((INTVAL (offset) & 3) == 0
3271       && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
3272     return \"sw\\t%1,%0\";
3274   return \"usw\\t%z1,%0\";
3276   [(set_attr "type"     "store")
3277    (set_attr "mode"     "SI")
3278    (set_attr "length"   "2,4")])
3280 ;; These two patterns support loading addresses with two instructions instead
3281 ;; of using the macro instruction la.
3283 ;; ??? mips_move_1word has support for HIGH, so this pattern may be
3284 ;; unnecessary.
3286 (define_insn "high"
3287   [(set (match_operand:SI 0 "register_operand" "=r")
3288         (high:SI (match_operand:SI 1 "immediate_operand" "")))]
3289   "mips_split_addresses"
3290   "lui\\t%0,%%hi(%1) # high"
3291   [(set_attr "type"     "move")
3292    (set_attr "length"   "1")])
3294 (define_insn "low"
3295   [(set (match_operand:SI 0 "register_operand" "=r")
3296         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
3297                    (match_operand:SI 2 "immediate_operand" "")))]
3298   "mips_split_addresses"
3299   "addiu\\t%0,%1,%%lo(%2) # low"
3300   [(set_attr "type"     "arith")
3301    (set_attr "mode"     "SI")
3302    (set_attr "length"   "1")])
3304 ;; 64-bit integer moves
3306 ;; Unlike most other insns, the move insns can't be split with
3307 ;; different predicates, because register spilling and other parts of
3308 ;; the compiler, have memoized the insn number already.
3310 (define_expand "movdi"
3311   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3312         (match_operand:DI 1 "general_operand" ""))]
3313   ""
3314   "
3316   if (mips_split_addresses && mips_check_split (operands[1], DImode))
3317     {
3318       enum machine_mode mode = GET_MODE (operands[0]);
3319       rtx tem = ((reload_in_progress | reload_completed)
3320                  ? operands[0] : gen_reg_rtx (mode));
3322       emit_insn (gen_rtx_SET (VOIDmode, tem,
3323                               gen_rtx_HIGH (mode, operands[1])));
3325       operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]);
3326     }
3328   /* If we are generating embedded PIC code, and we are referring to a
3329      symbol in the .text section, we must use an offset from the start
3330      of the function.  */
3331   if (TARGET_EMBEDDED_PIC
3332       && (GET_CODE (operands[1]) == LABEL_REF
3333           || (GET_CODE (operands[1]) == SYMBOL_REF
3334               && ! SYMBOL_REF_FLAG (operands[1]))))
3335     {
3336       rtx temp;
3338       temp = embedded_pic_offset (operands[1]);
3339       temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_rtx,
3340                            force_reg (DImode, temp));
3341       emit_move_insn (operands[0], force_reg (DImode, temp));
3342       DONE;
3343     }
3345   /* If operands[1] is a constant address illegal for pic, then we need to
3346      handle it just like LEGITIMIZE_ADDRESS does.  */
3347   if (flag_pic && pic_address_needs_scratch (operands[1]))
3348     {
3349       rtx temp = force_reg (DImode, XEXP (XEXP (operands[1], 0), 0));
3350       rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
3352       if (! SMALL_INT (temp2))
3353         temp2 = force_reg (DImode, temp2);
3355       emit_move_insn (operands[0], gen_rtx_PLUS (DImode, temp, temp2));
3356       DONE;
3357     }
3359   if ((reload_in_progress | reload_completed) == 0
3360       && !register_operand (operands[0], DImode)
3361       && !register_operand (operands[1], DImode)
3362       && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
3363       && operands[1] != CONST0_RTX (DImode))
3364     {
3365       rtx temp = force_reg (DImode, operands[1]);
3366       emit_move_insn (operands[0], temp);
3367       DONE;
3368     }
3371 (define_insn "movdi_internal"
3372   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*x,*d,*x")
3373         (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,J,*x,*d"))]
3374   "!TARGET_64BIT
3375    && (register_operand (operands[0], DImode)
3376        || register_operand (operands[1], DImode)
3377        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
3378        || operands[1] == CONST0_RTX (DImode))"
3379   "* return mips_move_2words (operands, insn); "
3380   [(set_attr "type"     "move,arith,load,load,store,store,hilo,hilo,hilo")
3381    (set_attr "mode"     "DI")
3382    (set_attr "length"   "2,4,2,4,2,4,2,2,2")])
3384 (define_split
3385   [(set (match_operand:DI 0 "register_operand" "")
3386         (match_operand:DI 1 "register_operand" ""))]
3387   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
3388    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
3389    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
3391   [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
3392    (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
3393   "")
3395 (define_insn "movdi_internal2"
3396   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*x,*d,*x,*a")
3397         (match_operand:DI 1 "movdi_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,J,*x,*d,*J"))]
3398   "TARGET_64BIT
3399    && (register_operand (operands[0], DImode)
3400        || se_register_operand (operands[1], DImode)
3401        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
3402        || operands[1] == CONST0_RTX (DImode))"
3403   "* return mips_move_2words (operands, insn); "
3404   [(set_attr "type"     "move,load,arith,arith,load,load,store,store,hilo,hilo,hilo,hilo")
3405    (set_attr "mode"     "DI")
3406    (set_attr "length"   "1,2,1,2,1,2,1,2,1,1,1,2")])
3408 ;; Handle input reloads in DImode.
3409 ;; This is mainly to handle reloading HILO_REGNUM.  Note that we may
3410 ;; see it as the source or the destination, depending upon which way
3411 ;; reload handles the instruction.
3412 ;; Making the second operand TImode is a trick.  The compiler may
3413 ;; reuse the same register for operand 0 and operand 2.  Using TImode
3414 ;; gives us two registers, so we can always use the one which is not
3415 ;; used.
3417 (define_expand "reload_indi"
3418   [(set (match_operand:DI 0 "register_operand" "=b")
3419         (match_operand:DI 1 "" "b"))
3420    (clobber (match_operand:TI 2 "register_operand" "=&d"))]
3421   "TARGET_64BIT"
3422   "
3424   rtx scratch = gen_rtx_REG (DImode,
3425                              (REGNO (operands[0]) == REGNO (operands[2]) 
3426                               ? REGNO (operands[2]) + 1
3427                               : REGNO (operands[2])));
3429   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
3430     {
3431       if (GET_CODE (operands[1]) == MEM)
3432         {
3433           rtx memword, offword, hiword, loword;
3434           rtx addr = find_replacement (&XEXP (operands[1], 0));
3435           rtx op1 = change_address (operands[1], VOIDmode, addr);
3437           scratch = gen_rtx_REG (SImode, REGNO (scratch));
3438           memword = change_address (op1, SImode, NULL_RTX);
3439           offword = change_address (adj_offsettable_operand (op1, 4),
3440                                     SImode, NULL_RTX);
3441           if (BYTES_BIG_ENDIAN)
3442             {
3443               hiword = memword;
3444               loword = offword;
3445             }
3446           else
3447             {
3448               hiword = offword;
3449               loword = memword;
3450             }
3451           emit_move_insn (scratch, hiword);
3452           emit_move_insn (gen_rtx_REG (SImode, 64), scratch);
3453           emit_move_insn (scratch, loword);
3454           emit_move_insn (gen_rtx_REG (SImode, 65), scratch);
3455         }
3456       else
3457         {
3458           emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
3459           emit_insn (gen_movdi (gen_rtx_REG (DImode, 64), scratch));
3460           emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
3461           emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
3462           emit_insn (gen_movdi (gen_rtx_REG (DImode, 65), scratch));
3463         }
3464       DONE;
3465     }
3466   if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
3467     {
3468       emit_insn (gen_movdi (scratch, gen_rtx_REG (DImode, 65)));
3469       emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
3470       emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
3471       emit_insn (gen_movdi (operands[0], gen_rtx_REG (DImode, 64)));
3472       emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
3473       emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
3474       DONE;
3475     }
3476   /* This handles moves between a float register and HI/LO.  */
3477   emit_move_insn (scratch, operands[1]);
3478   emit_move_insn (operands[0], scratch);
3479   DONE;
3482 ;; Handle output reloads in DImode.
3484 (define_expand "reload_outdi"
3485   [(set (match_operand:DI 0 "" "=b")
3486         (match_operand:DI 1 "se_register_operand" "b"))
3487    (clobber (match_operand:DI 2 "register_operand" "=&d"))]
3488   "TARGET_64BIT"
3489   "
3491   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
3492     {
3493       emit_insn (gen_ashrdi3 (operands[2], operands[1], GEN_INT (32)));
3494       emit_insn (gen_movdi (gen_rtx_REG (DImode, 64), operands[2]));
3495       emit_insn (gen_ashldi3 (operands[2], operands[1], GEN_INT (32)));
3496       emit_insn (gen_ashrdi3 (operands[2], operands[2], GEN_INT (32)));
3497       emit_insn (gen_movdi (gen_rtx_REG (DImode, 65), operands[2]));
3498       DONE;
3499     }
3500   if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
3501     {
3502       if (GET_CODE (operands[0]) == MEM)
3503         {
3504           rtx scratch, memword, offword, hiword, loword;
3505           rtx addr = find_replacement (&XEXP (operands[0], 0));
3506           rtx op0 = change_address (operands[0], VOIDmode, addr);
3508           scratch = gen_rtx_REG (SImode, REGNO (operands[2]));
3509           memword = change_address (op0, SImode, NULL_RTX);
3510           offword = change_address (adj_offsettable_operand (op0, 4),
3511                                     SImode, NULL_RTX);
3512           if (BYTES_BIG_ENDIAN)
3513             {
3514               hiword = memword;
3515               loword = offword;
3516             }
3517           else
3518             {
3519               hiword = offword;
3520               loword = memword;
3521             }
3522           emit_move_insn (scratch, gen_rtx_REG (SImode, 64));
3523           emit_move_insn (hiword, scratch);
3524           emit_move_insn (scratch, gen_rtx_REG (SImode, 65));
3525           emit_move_insn (loword, scratch);
3526         }
3527       else
3528         {
3529           emit_insn (gen_movdi (operands[2], gen_rtx_REG (DImode, 65)));
3530           emit_insn (gen_ashldi3 (operands[2], operands[2], GEN_INT (32)));
3531           emit_insn (gen_lshrdi3 (operands[2], operands[2], GEN_INT (32)));
3532           emit_insn (gen_movdi (operands[0], gen_rtx_REG (DImode, 64)));
3533           emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
3534           emit_insn (gen_iordi3 (operands[0], operands[0], operands[2]));
3535         }
3536       DONE;
3537     }
3538   /* This handles moves between a float register and HI/LO.  */
3539   emit_move_insn (operands[2], operands[1]);
3540   emit_move_insn (operands[0], operands[2]);
3541   DONE;
3544 ;; 32-bit Integer moves
3546 (define_split
3547   [(set (match_operand:SI 0 "register_operand" "")
3548         (match_operand:SI 1 "large_int" ""))]
3549   "!TARGET_DEBUG_D_MODE"
3550   [(set (match_dup 0)
3551         (match_dup 2))
3552    (set (match_dup 0)
3553         (ior:SI (match_dup 0)
3554                 (match_dup 3)))]
3555   "
3557   operands[2] = GEN_INT (INTVAL (operands[1]) & 0xffff0000);
3558   operands[3] = GEN_INT (INTVAL (operands[1]) & 0x0000ffff);
3561 ;; Unlike most other insns, the move insns can't be split with
3562 ;; different predicates, because register spilling and other parts of
3563 ;; the compiler, have memoized the insn number already.
3565 (define_expand "movsi"
3566   [(set (match_operand:SI 0 "nonimmediate_operand" "")
3567         (match_operand:SI 1 "general_operand" ""))]
3568   ""
3569   "
3571   if (mips_split_addresses && mips_check_split (operands[1], SImode))
3572     {
3573       enum machine_mode mode = GET_MODE (operands[0]);
3574       rtx tem = ((reload_in_progress | reload_completed)
3575                  ? operands[0] : gen_reg_rtx (mode));
3577       emit_insn (gen_rtx_SET (VOIDmode, tem,
3578                               gen_rtx_HIGH (mode, operands[1])));
3580       operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]);
3581     }
3583   /* If we are generating embedded PIC code, and we are referring to a
3584      symbol in the .text section, we must use an offset from the start
3585      of the function.  */
3586   if (TARGET_EMBEDDED_PIC
3587       && (GET_CODE (operands[1]) == LABEL_REF
3588           || (GET_CODE (operands[1]) == SYMBOL_REF
3589               && ! SYMBOL_REF_FLAG (operands[1]))))
3590     {
3591       rtx temp;
3593       temp = embedded_pic_offset (operands[1]);
3594       temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_rtx,
3595                            force_reg (SImode, temp));
3596       emit_move_insn (operands[0], force_reg (SImode, temp));
3597       DONE;
3598     }
3600   /* If operands[1] is a constant address invalid for pic, then we need to
3601      handle it just like LEGITIMIZE_ADDRESS does.  */
3602   if (flag_pic && pic_address_needs_scratch (operands[1]))
3603     {
3604       rtx temp = force_reg (SImode, XEXP (XEXP (operands[1], 0), 0));
3605       rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
3607       if (! SMALL_INT (temp2))
3608         temp2 = force_reg (SImode, temp2);
3610       emit_move_insn (operands[0], gen_rtx_PLUS (SImode, temp, temp2));
3611       DONE;
3612     }
3614   if ((reload_in_progress | reload_completed) == 0
3615       && !register_operand (operands[0], SImode)
3616       && !register_operand (operands[1], SImode)
3617       && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))
3618     {
3619       rtx temp = force_reg (SImode, operands[1]);
3620       emit_move_insn (operands[0], temp);
3621       DONE;
3622     }
3625 ;; The difference between these two is whether or not ints are allowed
3626 ;; in FP registers (off by default, use -mdebugh to enable).
3628 (define_insn "movsi_internal1"
3629   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*f*z,*f,*f,*f,*R,*m,*x,*x,*d,*d")
3630         (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*f*z,*d,*f,*R,*m,*f,*f,J,*d,*x,*a"))]
3631   "TARGET_DEBUG_H_MODE
3632    && (register_operand (operands[0], SImode)
3633        || register_operand (operands[1], SImode)
3634        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3635   "* return mips_move_1word (operands, insn, FALSE);"
3636   [(set_attr "type"     "move,load,arith,arith,load,load,store,store,xfer,xfer,move,load,load,store,store,hilo,hilo,hilo,hilo")
3637    (set_attr "mode"     "SI")
3638    (set_attr "length"   "1,2,1,2,1,2,1,2,1,1,1,1,2,1,2,1,1,1,1")])
3640 (define_insn "movsi_internal2"
3641   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*z,*x,*d,*x,*d")
3642         (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,J,*x,*d,*a"))]
3643   "!TARGET_DEBUG_H_MODE
3644    && (register_operand (operands[0], SImode)
3645        || register_operand (operands[1], SImode)
3646        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3647   "* return mips_move_1word (operands, insn, FALSE);"
3648   [(set_attr "type"     "move,load,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo,hilo,hilo")
3649    (set_attr "mode"     "SI")
3650    (set_attr "length"   "1,2,1,2,1,2,1,2,1,1,1,1,1,1")])
3652 ;; Reload HILO_REGNUM in SI mode.  This needs a scratch register in
3653 ;; order to set the sign bit correctly in the HI register.
3655 (define_expand "reload_outsi"
3656   [(set (match_operand:SI 0 "general_operand" "=b")
3657         (match_operand:SI 1 "register_operand" "d"))
3658    (clobber (match_operand:SI 2 "register_operand" "=&d"))]
3659   "TARGET_64BIT"
3660   "
3662   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
3663     {
3664       emit_insn (gen_movsi (gen_rtx_REG (SImode, 65), operands[1]));
3665       emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31)));
3666       emit_insn (gen_movsi (gen_rtx_REG (SImode, 64), operands[2]));
3667       DONE;
3668     }
3669   /* This handles moves between a float register and HI/LO.  */
3670   emit_move_insn (operands[2], operands[1]);
3671   emit_move_insn (operands[0], operands[2]);
3672   DONE;
3675 ;; This insn handles moving CCmode values.  It's really just a
3676 ;; slightly simplified copy of movsi_internal2, with additional cases
3677 ;; to move a condition register to a general register and to move
3678 ;; between the general registers and the floating point registers.
3680 (define_insn "movcc"
3681   [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*d,*R,*m,*d,*f,*f,*f,*f,*R,*m")
3682         (match_operand:CC 1 "general_operand" "z,*d,*R,*m,*d,*d,*f,*d,*f,*R,*m,*f,*f"))]
3683   "mips_isa >= 4 && TARGET_HARD_FLOAT"
3684   "* return mips_move_1word (operands, insn, FALSE);"
3685   [(set_attr "type"     "move,move,load,load,store,store,xfer,xfer,move,load,load,store,store")
3686    (set_attr "mode"     "SI")
3687    (set_attr "length"   "2,1,1,2,1,2,1,1,1,1,2,1,2")])
3689 ;; Reload condition code registers.  These need scratch registers.
3691 (define_expand "reload_incc"
3692   [(set (match_operand:CC 0 "register_operand" "=z")
3693         (match_operand:CC 1 "general_operand" "z"))
3694    (clobber (match_operand:TF 2 "register_operand" "=&f"))]
3695   "mips_isa >= 4 && TARGET_HARD_FLOAT"
3696   "
3698   rtx source;
3699   rtx fp1, fp2;
3701   /* This is called when are copying some value into a condition code
3702      register.  Operand 0 is the condition code register.  Operand 1
3703      is the source.  Operand 2 is a scratch register; we use TFmode
3704      because we actually need two floating point registers.  */
3705   if (! ST_REG_P (true_regnum (operands[0]))
3706       || ! FP_REG_P (true_regnum (operands[2])))
3707     abort ();
3709   /* We need to get the source in SFmode so that the insn is
3710      recognized.  */
3711   if (GET_CODE (operands[1]) == MEM)
3712     source = change_address (operands[1], SFmode, NULL_RTX);
3713   else if (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG)
3714     source = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3715   else
3716     source = operands[1];
3718   fp1 = gen_rtx_REG (SFmode, REGNO (operands[2]));
3719   fp2 = gen_rtx_REG (SFmode, REGNO (operands[2]) + 1);
3721   emit_insn (gen_move_insn (fp1, source));
3722   emit_insn (gen_move_insn (fp2, gen_rtx_REG (SFmode, 0)));
3723   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3724                           gen_rtx_LT (CCmode, fp2, fp1)));
3726   DONE;
3729 (define_expand "reload_outcc"
3730   [(set (match_operand:CC 0 "general_operand" "=z")
3731         (match_operand:CC 1 "register_operand" "z"))
3732    (clobber (match_operand:CC 2 "register_operand" "=&d"))]
3733   "mips_isa >= 4 && TARGET_HARD_FLOAT"
3734   "
3736   /* This is called when we are copying a condition code register out
3737      to save it somewhere.  Operand 0 should be the location we are
3738      going to save it to.  Operand 1 should be the condition code
3739      register.  Operand 2 should be a scratch general purpose register
3740      created for us by reload.  The mips_secondary_reload_class
3741      function should have told reload that we don't need a scratch
3742      register if the destination is a general purpose register anyhow.  */
3743   if (ST_REG_P (true_regnum (operands[0]))
3744       || GP_REG_P (true_regnum (operands[0]))
3745       || ! ST_REG_P (true_regnum (operands[1]))
3746       || ! GP_REG_P (true_regnum (operands[2])))
3747     abort ();
3749   /* All we have to do is copy the value from the condition code to
3750      the data register, which movcc can handle, and then store the
3751      value into the real final destination.  */
3752   emit_insn (gen_move_insn (operands[2], operands[1]));
3753   emit_insn (gen_move_insn (operands[0], operands[2]));
3755   DONE;
3758 ;; MIPS4 supports loading and storing a floating point register from
3759 ;; the sum of two general registers.  We use two versions for each of
3760 ;; these four instructions: one where the two general registers are
3761 ;; SImode, and one where they are DImode.  This is because general
3762 ;; registers will be in SImode when they hold 32 bit values, but,
3763 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
3764 ;; instructions will still work correctly.
3766 ;; ??? Perhaps it would be better to support these instructions by
3767 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends.  However, since
3768 ;; these instructions can only be used to load and store floating
3769 ;; point registers, that would probably cause trouble in reload.
3771 (define_insn ""
3772   [(set (match_operand:SF 0 "register_operand" "=f")
3773         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
3774                          (match_operand:SI 2 "register_operand" "d"))))]
3775   "mips_isa >= 4 && TARGET_HARD_FLOAT"
3776   "lwxc1\\t%0,%1(%2)"
3777   [(set_attr "type"     "load")
3778    (set_attr "mode"     "SF")
3779    (set_attr "length"   "1")])
3781 (define_insn ""
3782   [(set (match_operand:SF 0 "register_operand" "=f")
3783         (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
3784                          (match_operand:DI 2 "se_register_operand" "d"))))]
3785   "mips_isa >= 4 && TARGET_HARD_FLOAT"
3786   "lwxc1\\t%0,%1(%2)"
3787   [(set_attr "type"     "load")
3788    (set_attr "mode"     "SF")
3789    (set_attr "length"   "1")])
3791 (define_insn ""
3792   [(set (match_operand:DF 0 "register_operand" "=f")
3793         (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
3794                          (match_operand:SI 2 "register_operand" "d"))))]
3795   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3796   "ldxc1\\t%0,%1(%2)"
3797   [(set_attr "type"     "load")
3798    (set_attr "mode"     "DF")
3799    (set_attr "length"   "1")])
3801 (define_insn ""
3802   [(set (match_operand:DF 0 "register_operand" "=f")
3803         (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
3804                          (match_operand:DI 2 "se_register_operand" "d"))))]
3805   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3806   "ldxc1\\t%0,%1(%2)"
3807   [(set_attr "type"     "load")
3808    (set_attr "mode"     "DF")
3809    (set_attr "length"   "1")])
3811 (define_insn ""
3812   [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
3813                          (match_operand:SI 2 "register_operand" "d")))
3814         (match_operand:SF 0 "register_operand" "f"))]
3815   "mips_isa >= 4 && TARGET_HARD_FLOAT"
3816   "swxc1\\t%0,%1(%2)"
3817   [(set_attr "type"     "store")
3818    (set_attr "mode"     "SF")
3819    (set_attr "length"   "1")])
3821 (define_insn ""
3822   [(set (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
3823                          (match_operand:DI 2 "se_register_operand" "d")))
3824         (match_operand:SF 0 "register_operand" "f"))]
3825   "mips_isa >= 4 && TARGET_HARD_FLOAT"
3826   "swxc1\\t%0,%1(%2)"
3827   [(set_attr "type"     "store")
3828    (set_attr "mode"     "SF")
3829    (set_attr "length"   "1")])
3831 (define_insn ""
3832   [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
3833                          (match_operand:SI 2 "register_operand" "d")))
3834         (match_operand:DF 0 "register_operand" "f"))]
3835   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3836   "sdxc1\\t%0,%1(%2)"
3837   [(set_attr "type"     "store")
3838    (set_attr "mode"     "DF")
3839    (set_attr "length"   "1")])
3841 (define_insn ""
3842   [(set (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d")
3843                          (match_operand:DI 2 "se_register_operand" "d")))
3844         (match_operand:DF 0 "register_operand" "f"))]
3845   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3846   "sdxc1\\t%0,%1(%2)"
3847   [(set_attr "type"     "store")
3848    (set_attr "mode"     "DF")
3849    (set_attr "length"   "1")])
3851 ;; 16-bit Integer moves
3853 ;; Unlike most other insns, the move insns can't be split with
3854 ;; different predicates, because register spilling and other parts of
3855 ;; the compiler, have memoized the insn number already.
3856 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
3858 (define_expand "movhi"
3859   [(set (match_operand:HI 0 "nonimmediate_operand" "")
3860         (match_operand:HI 1 "general_operand" ""))]
3861   ""
3862   "
3864   if ((reload_in_progress | reload_completed) == 0
3865       && !register_operand (operands[0], HImode)
3866       && !register_operand (operands[1], HImode)
3867       && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))
3868     {
3869       rtx temp = force_reg (HImode, operands[1]);
3870       emit_move_insn (operands[0], temp);
3871       DONE;
3872     }
3875 ;; The difference between these two is whether or not ints are allowed
3876 ;; in FP registers (off by default, use -mdebugh to enable).
3878 (define_insn "movhi_internal1"
3879   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f*z,*x,*d")
3880         (match_operand:HI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
3881   "TARGET_DEBUG_H_MODE
3882    && (register_operand (operands[0], HImode)
3883        || register_operand (operands[1], HImode)
3884        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3885   "* return mips_move_1word (operands, insn, TRUE);"
3886   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
3887    (set_attr "mode"     "HI")
3888    (set_attr "length"   "1,1,1,2,1,2,1,1,1,1,1")])
3890 (define_insn "movhi_internal2"
3891   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
3892         (match_operand:HI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
3893   "!TARGET_DEBUG_H_MODE
3894    && (register_operand (operands[0], HImode)
3895        || register_operand (operands[1], HImode)
3896        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3897   "* return mips_move_1word (operands, insn, TRUE);"
3898   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
3899    (set_attr "mode"     "HI")
3900    (set_attr "length"   "1,1,1,2,1,2,1,1,1,1")])
3903 ;; 8-bit Integer moves
3905 ;; Unlike most other insns, the move insns can't be split with
3906 ;; different predicates, because register spilling and other parts of
3907 ;; the compiler, have memoized the insn number already.
3908 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
3910 (define_expand "movqi"
3911   [(set (match_operand:QI 0 "nonimmediate_operand" "")
3912         (match_operand:QI 1 "general_operand" ""))]
3913   ""
3914   "
3916   if ((reload_in_progress | reload_completed) == 0
3917       && !register_operand (operands[0], QImode)
3918       && !register_operand (operands[1], QImode)
3919       && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))
3920     {
3921       rtx temp = force_reg (QImode, operands[1]);
3922       emit_move_insn (operands[0], temp);
3923       DONE;
3924     }
3927 ;; The difference between these two is whether or not ints are allowed
3928 ;; in FP registers (off by default, use -mdebugh to enable).
3930 (define_insn "movqi_internal1"
3931   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
3932         (match_operand:QI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
3933   "TARGET_DEBUG_H_MODE
3934    && (register_operand (operands[0], QImode)
3935        || register_operand (operands[1], QImode)
3936        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3937   "* return mips_move_1word (operands, insn, TRUE);"
3938   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
3939    (set_attr "mode"     "QI")
3940    (set_attr "length"   "1,1,1,2,1,2,1,1,1,1,1")])
3942 (define_insn "movqi_internal2"
3943   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
3944         (match_operand:QI 1 "general_operand"       "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
3945   "!TARGET_DEBUG_H_MODE
3946    && (register_operand (operands[0], QImode)
3947        || register_operand (operands[1], QImode)
3948        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
3949   "* return mips_move_1word (operands, insn, TRUE);"
3950   [(set_attr "type"     "move,arith,load,load,store,store,xfer,xfer,hilo,hilo")
3951    (set_attr "mode"     "QI")
3952    (set_attr "length"   "1,1,1,2,1,2,1,1,1,1")])
3955 ;; 32-bit floating point moves
3957 (define_expand "movsf"
3958   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3959         (match_operand:SF 1 "general_operand" ""))]
3960   ""
3961   "
3963   if ((reload_in_progress | reload_completed) == 0
3964       && !register_operand (operands[0], SFmode)
3965       && !register_operand (operands[1], SFmode)
3966       && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
3967       && operands[1] != CONST0_RTX (SFmode))
3968     {
3969       rtx temp = force_reg (SFmode, operands[1]);
3970       emit_move_insn (operands[0], temp);
3971       DONE;
3972     }
3975 (define_insn "movsf_internal1"
3976   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m")
3977         (match_operand:SF 1 "general_operand" "f,G,R,Fm,fG,fG,*d,*f,*G*d,*R,*F*m,*d,*d"))]
3978   "TARGET_HARD_FLOAT
3979    && (register_operand (operands[0], SFmode)
3980        || register_operand (operands[1], SFmode)
3981        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
3982        || operands[1] == CONST0_RTX (SFmode))"
3983   "* return mips_move_1word (operands, insn, FALSE);"
3984   [(set_attr "type"     "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store")
3985    (set_attr "mode"     "SF")
3986    (set_attr "length"   "1,1,1,2,1,2,1,1,1,1,2,1,2")])
3989 (define_insn "movsf_internal2"
3990   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,R,m")
3991         (match_operand:SF 1 "general_operand" "      Gd,R,Fm,d,d"))]
3992   "TARGET_SOFT_FLOAT
3993    && (register_operand (operands[0], SFmode)
3994        || register_operand (operands[1], SFmode)
3995        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
3996        || operands[1] == CONST0_RTX (SFmode))"
3997   "* return mips_move_1word (operands, insn, FALSE);"
3998   [(set_attr "type"     "move,load,load,store,store")
3999    (set_attr "mode"     "SF")
4000    (set_attr "length"   "1,1,2,1,2")])
4003 ;; 64-bit floating point moves
4005 (define_expand "movdf"
4006   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4007         (match_operand:DF 1 "general_operand" ""))]
4008   ""
4009   "
4011   if ((reload_in_progress | reload_completed) == 0
4012       && !register_operand (operands[0], DFmode)
4013       && !register_operand (operands[1], DFmode)
4014       && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
4015       && operands[1] != CONST0_RTX (DFmode))
4016     {
4017       rtx temp = force_reg (DFmode, operands[1]);
4018       emit_move_insn (operands[0], temp);
4019       DONE;
4020     }
4023 (define_insn "movdf_internal1"
4024   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,o,f,*f,*d,*d,*d,*d,*R,*o")
4025         (match_operand:DF 1 "general_operand" "f,R,o,fG,fG,F,*d,*f,*d*G,*R,*o*F,*d,*d"))]
4026   "TARGET_HARD_FLOAT && !(TARGET_FLOAT64 && !TARGET_64BIT)
4027    && TARGET_DOUBLE_FLOAT
4028    && (register_operand (operands[0], DFmode)
4029        || register_operand (operands[1], DFmode)
4030        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
4031        || operands[1] == CONST0_RTX (DFmode))"
4032   "* return mips_move_2words (operands, insn); "
4033   [(set_attr "type"     "move,load,load,store,store,load,xfer,xfer,move,load,load,store,store")
4034    (set_attr "mode"     "DF")
4035    (set_attr "length"   "1,2,4,2,4,4,2,2,2,2,4,2,4")])
4037 (define_insn "movdf_internal1a"
4038   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,R,R,o,o,f,*d,*d,*d,*o,*R")
4039         (match_operand:DF 1 "general_operand"      " f,o,f,G,f,G,F,*F,*o,*R,*d,*d"))]
4040   "TARGET_HARD_FLOAT && (TARGET_FLOAT64 && !TARGET_64BIT)
4041    && TARGET_DOUBLE_FLOAT
4042    && (register_operand (operands[0], DFmode)
4043        || register_operand (operands[1], DFmode))
4044        || (GET_CODE (operands [0]) == MEM
4045            && ((GET_CODE (operands[1]) == CONST_INT
4046                 && INTVAL (operands[1]) == 0)
4047                || operands[1] == CONST0_RTX (DFmode)))"
4048   "* return mips_move_2words (operands, insn); "
4049   [(set_attr "type"     "move,load,store,store,store,store,load,load,load,load,store,store")
4050    (set_attr "mode"     "DF")
4051    (set_attr "length"   "1,2,1,1,2,2,2,2,2,1,2,1")])
4053 (define_insn "movdf_internal2"
4054   [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,R,o")
4055         (match_operand:DF 1 "general_operand" "dG,R,oF,d,d"))]
4056   "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT)
4057    && (register_operand (operands[0], DFmode)
4058        || register_operand (operands[1], DFmode)
4059        || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
4060        || operands[1] == CONST0_RTX (DFmode))"
4061   "* return mips_move_2words (operands, insn); "
4062   [(set_attr "type"     "move,load,load,store,store")
4063    (set_attr "mode"     "DF")
4064    (set_attr "length"   "2,2,4,2,4")])
4066 (define_split
4067   [(set (match_operand:DF 0 "register_operand" "")
4068         (match_operand:DF 1 "register_operand" ""))]
4069   "reload_completed && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4070    && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
4071    && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))"
4072   [(set (subreg:SI (match_dup 0) 0) (subreg:SI (match_dup 1) 0))
4073    (set (subreg:SI (match_dup 0) 1) (subreg:SI (match_dup 1) 1))]
4074   "")
4076 ;; Instructions to load the global pointer register.
4077 ;; This is volatile to make sure that the scheduler won't move any symbol_ref
4078 ;; uses in front of it.  All symbol_refs implicitly use the gp reg.
4080 (define_insn "loadgp"
4081   [(set (reg:DI 28)
4082         (unspec_volatile:DI [(match_operand:DI 0 "address_operand" "")
4083                              (match_operand:DI 1 "register_operand" "")] 2))
4084    (clobber (reg:DI 1))]
4085   ""
4086   "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%a0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%a0)))\\n\\tdaddu\\t$gp,$1,%1%]"
4087   [(set_attr "type"     "move")
4088    (set_attr "mode"     "DI")
4089    (set_attr "length"   "3")])
4091 ;; Block moves, see mips.c for more details.
4092 ;; Argument 0 is the destination
4093 ;; Argument 1 is the source
4094 ;; Argument 2 is the length
4095 ;; Argument 3 is the alignment
4097 (define_expand "movstrsi"
4098   [(parallel [(set (match_operand:BLK 0 "general_operand" "")
4099                    (match_operand:BLK 1 "general_operand" ""))
4100               (use (match_operand:SI 2 "arith32_operand" ""))
4101               (use (match_operand:SI 3 "immediate_operand" ""))])]
4102   ""
4103   "
4105   if (operands[0])              /* avoid unused code messages */
4106     {
4107       expand_block_move (operands);
4108       DONE;
4109     }
4112 ;; Insn generated by block moves
4114 (define_insn "movstrsi_internal"
4115   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
4116         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
4117    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
4118    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
4119    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
4120    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
4121    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
4122    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
4123    (use (const_int 0))]                                 ;; normal block move
4124   ""
4125   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NORMAL);"
4126   [(set_attr "type"     "store")
4127    (set_attr "mode"     "none")
4128    (set_attr "length"   "20")])
4130 ;; Split a block move into 2 parts, the first part is everything
4131 ;; except for the last move, and the second part is just the last
4132 ;; store, which is exactly 1 instruction (ie, not a usw), so it can
4133 ;; fill a delay slot.  This also prevents a bug in delayed branches
4134 ;; from showing up, which reuses one of the registers in our clobbers.
4136 (define_split
4137   [(set (mem:BLK (match_operand:SI 0 "register_operand" ""))
4138         (mem:BLK (match_operand:SI 1 "register_operand" "")))
4139    (clobber (match_operand:SI 4 "register_operand" ""))
4140    (clobber (match_operand:SI 5 "register_operand" ""))
4141    (clobber (match_operand:SI 6 "register_operand" ""))
4142    (clobber (match_operand:SI 7 "register_operand" ""))
4143    (use (match_operand:SI 2 "small_int" ""))
4144    (use (match_operand:SI 3 "small_int" ""))
4145    (use (const_int 0))]
4147   "reload_completed && !TARGET_DEBUG_D_MODE && INTVAL (operands[2]) > 0"
4149   ;; All but the last move
4150   [(parallel [(set (mem:BLK (match_dup 0))
4151                    (mem:BLK (match_dup 1)))
4152               (clobber (match_dup 4))
4153               (clobber (match_dup 5))
4154               (clobber (match_dup 6))
4155               (clobber (match_dup 7))
4156               (use (match_dup 2))
4157               (use (match_dup 3))
4158               (use (const_int 1))])
4160    ;; The last store, so it can fill a delay slot
4161    (parallel [(set (mem:BLK (match_dup 0))
4162                    (mem:BLK (match_dup 1)))
4163               (clobber (match_dup 4))
4164               (clobber (match_dup 5))
4165               (clobber (match_dup 6))
4166               (clobber (match_dup 7))
4167               (use (match_dup 2))
4168               (use (match_dup 3))
4169               (use (const_int 2))])]
4171   "")
4173 (define_insn "movstrsi_internal2"
4174   [(set (match_operand:BLK 0 "memory_operand" "=o")     ;; destination
4175         (match_operand:BLK 1 "memory_operand" "o"))     ;; source
4176    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
4177    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
4178    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
4179    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
4180    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
4181    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
4182    (use (const_int 1))]                                 ;; all but last store
4183   ""
4184   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_NOT_LAST);"
4185   [(set_attr "type"     "store")
4186    (set_attr "mode"     "none")
4187    (set_attr "length"   "20")])
4189 (define_insn "movstrsi_internal3"
4190   [(set (match_operand:BLK 0 "memory_operand" "=Ro")    ;; destination
4191         (match_operand:BLK 1 "memory_operand" "Ro"))    ;; source
4192    (clobber (match_scratch:SI 4 "=&d"))                 ;; temp 1
4193    (clobber (match_scratch:SI 5 "=&d"))                 ;; temp 2
4194    (clobber (match_scratch:SI 6 "=&d"))                 ;; temp 3
4195    (clobber (match_scratch:SI 7 "=&d"))                 ;; temp 4
4196    (use (match_operand:SI 2 "small_int" "I"))           ;; # bytes to move
4197    (use (match_operand:SI 3 "small_int" "I"))           ;; alignment
4198    (use (const_int 2))]                                 ;; just last store of block move
4199   ""
4200   "* return output_block_move (insn, operands, 4, BLOCK_MOVE_LAST);"
4201   [(set_attr "type"     "store")
4202    (set_attr "mode"     "none")
4203    (set_attr "length"   "1")])
4207 ;;  ....................
4209 ;;      SHIFTS
4211 ;;  ....................
4213 (define_insn "ashlsi3"
4214   [(set (match_operand:SI 0 "register_operand" "=d")
4215         (ashift:SI (match_operand:SI 1 "register_operand" "d")
4216                    (match_operand:SI 2 "arith_operand" "dI")))]
4217   ""
4218   "*
4220   if (GET_CODE (operands[2]) == CONST_INT)
4221     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4223   return \"sll\\t%0,%1,%2\";
4225   [(set_attr "type"     "arith")
4226    (set_attr "mode"     "SI")
4227    (set_attr "length"   "1")])
4230 (define_expand "ashldi3"
4231   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4232                    (ashift:DI (match_operand:DI 1 "se_register_operand" "")
4233                               (match_operand:SI 2 "arith_operand" "")))
4234               (clobber (match_dup  3))])]
4235   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
4236   "
4238   if (TARGET_64BIT)
4239     {
4240       emit_insn (gen_ashldi3_internal4 (operands[0], operands[1],
4241                                         operands[2]));
4242       DONE;
4243     }
4245   operands[3] = gen_reg_rtx (SImode);
4249 (define_insn "ashldi3_internal"
4250   [(set (match_operand:DI 0 "register_operand" "=&d")
4251         (ashift:DI (match_operand:DI 1 "register_operand" "d")
4252                    (match_operand:SI 2 "register_operand" "d")))
4253    (clobber (match_operand:SI 3 "register_operand" "=d"))]
4254   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
4255   "* 
4257   operands[4] = const0_rtx;
4258   dslots_jump_total += 3;
4259   dslots_jump_filled += 2;
4261   return \"sll\\t%3,%2,26\\n\\
4262 \\tbgez\\t%3,1f\\n\\
4263 \\tsll\\t%M0,%L1,%2\\n\\
4264 \\t%(b\\t3f\\n\\
4265 \\tmove\\t%L0,%z4%)\\n\\
4266 \\n\\
4267 1:\\n\\
4268 \\t%(beq\\t%3,%z4,2f\\n\\
4269 \\tsll\\t%M0,%M1,%2%)\\n\\
4270 \\n\\
4271 \\tsubu\\t%3,%z4,%2\\n\\
4272 \\tsrl\\t%3,%L1,%3\\n\\
4273 \\tor\\t%M0,%M0,%3\\n\\
4274 2:\\n\\
4275 \\tsll\\t%L0,%L1,%2\\n\\
4276 3:\";
4278   [(set_attr "type"     "darith")
4279    (set_attr "mode"     "SI")
4280    (set_attr "length"   "12")])
4283 (define_insn "ashldi3_internal2"
4284   [(set (match_operand:DI 0 "register_operand" "=d")
4285         (ashift:DI (match_operand:DI 1 "register_operand" "d")
4286                    (match_operand:SI 2 "small_int" "IJK")))
4287    (clobber (match_operand:SI 3 "register_operand" "=d"))]
4288   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
4289   "*
4291   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4292   operands[4] = const0_rtx;
4293   return \"sll\\t%M0,%L1,%2\;move\\t%L0,%z4\";
4295   [(set_attr "type"     "darith")
4296    (set_attr "mode"     "DI")
4297    (set_attr "length"   "2")])
4300 (define_split
4301   [(set (match_operand:DI 0 "register_operand" "")
4302         (ashift:DI (match_operand:DI 1 "register_operand" "")
4303                    (match_operand:SI 2 "small_int" "")))
4304    (clobber (match_operand:SI 3 "register_operand" ""))]
4305   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4306    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4307    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4308    && (INTVAL (operands[2]) & 32) != 0"
4310   [(set (subreg:SI (match_dup 0) 1) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
4311    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
4313   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
4316 (define_split
4317   [(set (match_operand:DI 0 "register_operand" "")
4318         (ashift:DI (match_operand:DI 1 "register_operand" "")
4319                    (match_operand:SI 2 "small_int" "")))
4320    (clobber (match_operand:SI 3 "register_operand" ""))]
4321   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4322    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4323    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4324    && (INTVAL (operands[2]) & 32) != 0"
4326   [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
4327    (set (subreg:SI (match_dup 0) 1) (const_int 0))]
4329   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
4332 (define_insn "ashldi3_internal3"
4333   [(set (match_operand:DI 0 "register_operand" "=d")
4334         (ashift:DI (match_operand:DI 1 "register_operand" "d")
4335                    (match_operand:SI 2 "small_int" "IJK")))
4336    (clobber (match_operand:SI 3 "register_operand" "=d"))]
4337   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE
4338    && (INTVAL (operands[2]) & 63) < 32
4339    && (INTVAL (operands[2]) & 63) != 0"
4340   "*
4342   int amount = INTVAL (operands[2]);
4344   operands[2] = GEN_INT (amount & 31);
4345   operands[4] = const0_rtx;
4346   operands[5] = GEN_INT ((-amount) & 31);
4348   return \"sll\\t%M0,%M1,%2\;srl\\t%3,%L1,%5\;or\\t%M0,%M0,%3\;sll\\t%L0,%L1,%2\";
4350   [(set_attr "type"     "darith")
4351    (set_attr "mode"     "DI")
4352    (set_attr "length"   "4")])
4355 (define_split
4356   [(set (match_operand:DI 0 "register_operand" "")
4357         (ashift:DI (match_operand:DI 1 "register_operand" "")
4358                    (match_operand:SI 2 "small_int" "")))
4359    (clobber (match_operand:SI 3 "register_operand" ""))]
4360   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4361    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4362    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4363    && (INTVAL (operands[2]) & 63) < 32
4364    && (INTVAL (operands[2]) & 63) != 0"
4366   [(set (subreg:SI (match_dup 0) 1)
4367         (ashift:SI (subreg:SI (match_dup 1) 1)
4368                    (match_dup 2)))
4370    (set (match_dup 3)
4371         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
4372                      (match_dup 4)))
4374    (set (subreg:SI (match_dup 0) 1)
4375         (ior:SI (subreg:SI (match_dup 0) 1)
4376                 (match_dup 3)))
4378    (set (subreg:SI (match_dup 0) 0)
4379         (ashift:SI (subreg:SI (match_dup 1) 0)
4380                    (match_dup 2)))]
4381   "
4383   int amount = INTVAL (operands[2]);
4384   operands[2] = GEN_INT (amount & 31);
4385   operands[4] = GEN_INT ((-amount) & 31);
4389 (define_split
4390   [(set (match_operand:DI 0 "register_operand" "")
4391         (ashift:DI (match_operand:DI 1 "register_operand" "")
4392                    (match_operand:SI 2 "small_int" "")))
4393    (clobber (match_operand:SI 3 "register_operand" ""))]
4394   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4395    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4396    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4397    && (INTVAL (operands[2]) & 63) < 32
4398    && (INTVAL (operands[2]) & 63) != 0"
4400   [(set (subreg:SI (match_dup 0) 0)
4401         (ashift:SI (subreg:SI (match_dup 1) 0)
4402                    (match_dup 2)))
4404    (set (match_dup 3)
4405         (lshiftrt:SI (subreg:SI (match_dup 1) 1)
4406                      (match_dup 4)))
4408    (set (subreg:SI (match_dup 0) 0)
4409         (ior:SI (subreg:SI (match_dup 0) 0)
4410                 (match_dup 3)))
4412    (set (subreg:SI (match_dup 0) 1)
4413         (ashift:SI (subreg:SI (match_dup 1) 1)
4414                    (match_dup 2)))]
4415   "
4417   int amount = INTVAL (operands[2]);
4418   operands[2] = GEN_INT (amount & 31);
4419   operands[4] = GEN_INT ((-amount) & 31);
4423 (define_insn "ashldi3_internal4"
4424   [(set (match_operand:DI 0 "register_operand" "=d")
4425         (ashift:DI (match_operand:DI 1 "se_register_operand" "d")
4426                    (match_operand:SI 2 "arith_operand" "dI")))]
4427   "TARGET_64BIT"
4428   "*
4430   if (GET_CODE (operands[2]) == CONST_INT)
4431     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4433   return \"dsll\\t%0,%1,%2\";
4435   [(set_attr "type"     "arith")
4436    (set_attr "mode"     "DI")
4437    (set_attr "length"   "1")])
4440 (define_insn "ashrsi3"
4441   [(set (match_operand:SI 0 "register_operand" "=d")
4442         (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
4443                      (match_operand:SI 2 "arith_operand" "dI")))]
4444   ""
4445   "*
4447   if (GET_CODE (operands[2]) == CONST_INT)
4448     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4450   return \"sra\\t%0,%1,%2\";
4452   [(set_attr "type"     "arith")
4453    (set_attr "mode"     "SI")
4454    (set_attr "length"   "1")])
4457 (define_expand "ashrdi3"
4458   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4459                    (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "")
4460                                 (match_operand:SI 2 "arith_operand" "")))
4461               (clobber (match_dup  3))])]
4462   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
4463   "
4465   if (TARGET_64BIT)
4466     {
4467       emit_insn (gen_ashrdi3_internal4 (operands[0], operands[1],
4468                                         operands[2]));
4469       DONE;
4470     }
4472   operands[3] = gen_reg_rtx (SImode);
4476 (define_insn "ashrdi3_internal"
4477   [(set (match_operand:DI 0 "register_operand" "=&d")
4478         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
4479                      (match_operand:SI 2 "register_operand" "d")))
4480    (clobber (match_operand:SI 3 "register_operand" "=d"))]
4481   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
4482   "* 
4484   operands[4] = const0_rtx;
4485   dslots_jump_total += 3;
4486   dslots_jump_filled += 2;
4488   return \"sll\\t%3,%2,26\\n\\
4489 \\tbgez\\t%3,1f\\n\\
4490 \\tsra\\t%L0,%M1,%2\\n\\
4491 \\t%(b\\t3f\\n\\
4492 \\tsra\\t%M0,%M1,31%)\\n\\
4493 \\n\\
4494 1:\\n\\
4495 \\t%(beq\\t%3,%z4,2f\\n\\
4496 \\tsrl\\t%L0,%L1,%2%)\\n\\
4497 \\n\\
4498 \\tsubu\\t%3,%z4,%2\\n\\
4499 \\tsll\\t%3,%M1,%3\\n\\
4500 \\tor\\t%L0,%L0,%3\\n\\
4501 2:\\n\\
4502 \\tsra\\t%M0,%M1,%2\\n\\
4503 3:\";
4505   [(set_attr "type"     "darith")
4506    (set_attr "mode"     "DI")
4507    (set_attr "length"   "12")])
4510 (define_insn "ashrdi3_internal2"
4511   [(set (match_operand:DI 0 "register_operand" "=d")
4512         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
4513                      (match_operand:SI 2 "small_int" "IJK")))
4514    (clobber (match_operand:SI 3 "register_operand" "=d"))]
4515   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
4516   "*
4518   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4519   return \"sra\\t%L0,%M1,%2\;sra\\t%M0,%M1,31\";
4521   [(set_attr "type"     "darith")
4522    (set_attr "mode"     "DI")
4523    (set_attr "length"   "2")])
4526 (define_split
4527   [(set (match_operand:DI 0 "register_operand" "")
4528         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4529                      (match_operand:SI 2 "small_int" "")))
4530    (clobber (match_operand:SI 3 "register_operand" ""))]
4531   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4532    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4533    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4534    && (INTVAL (operands[2]) & 32) != 0"
4536   [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
4537    (set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 1) (const_int 31)))]
4539   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
4542 (define_split
4543   [(set (match_operand:DI 0 "register_operand" "")
4544         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4545                      (match_operand:SI 2 "small_int" "")))
4546    (clobber (match_operand:SI 3 "register_operand" ""))]
4547   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4548    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4549    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4550    && (INTVAL (operands[2]) & 32) != 0"
4552   [(set (subreg:SI (match_dup 0) 1) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
4553    (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
4555   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
4558 (define_insn "ashrdi3_internal3"
4559   [(set (match_operand:DI 0 "register_operand" "=d")
4560         (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
4561                      (match_operand:SI 2 "small_int" "IJK")))
4562    (clobber (match_operand:SI 3 "register_operand" "=d"))]
4563   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE
4564    && (INTVAL (operands[2]) & 63) < 32
4565    && (INTVAL (operands[2]) & 63) != 0"
4566   "*
4568   int amount = INTVAL (operands[2]);
4570   operands[2] = GEN_INT (amount & 31);
4571   operands[4] = GEN_INT ((-amount) & 31);
4573   return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;sra\\t%M0,%M1,%2\";
4575   [(set_attr "type"     "darith")
4576    (set_attr "mode"     "DI")
4577    (set_attr "length"   "4")])
4580 (define_split
4581   [(set (match_operand:DI 0 "register_operand" "")
4582         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4583                      (match_operand:SI 2 "small_int" "")))
4584    (clobber (match_operand:SI 3 "register_operand" ""))]
4585   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4586    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4587    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4588    && (INTVAL (operands[2]) & 63) < 32
4589    && (INTVAL (operands[2]) & 63) != 0"
4591   [(set (subreg:SI (match_dup 0) 0)
4592         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
4593                      (match_dup 2)))
4595    (set (match_dup 3)
4596         (ashift:SI (subreg:SI (match_dup 1) 1)
4597                    (match_dup 4)))
4599    (set (subreg:SI (match_dup 0) 0)
4600         (ior:SI (subreg:SI (match_dup 0) 0)
4601                 (match_dup 3)))
4603    (set (subreg:SI (match_dup 0) 1)
4604         (ashiftrt:SI (subreg:SI (match_dup 1) 1)
4605                      (match_dup 2)))]
4606   "
4608   int amount = INTVAL (operands[2]);
4609   operands[2] = GEN_INT (amount & 31);
4610   operands[4] = GEN_INT ((-amount) & 31);
4614 (define_split
4615   [(set (match_operand:DI 0 "register_operand" "")
4616         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4617                      (match_operand:SI 2 "small_int" "")))
4618    (clobber (match_operand:SI 3 "register_operand" ""))]
4619   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4620    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4621    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4622    && (INTVAL (operands[2]) & 63) < 32
4623    && (INTVAL (operands[2]) & 63) != 0"
4625   [(set (subreg:SI (match_dup 0) 1)
4626         (lshiftrt:SI (subreg:SI (match_dup 1) 1)
4627                      (match_dup 2)))
4629    (set (match_dup 3)
4630         (ashift:SI (subreg:SI (match_dup 1) 0)
4631                    (match_dup 4)))
4633    (set (subreg:SI (match_dup 0) 1)
4634         (ior:SI (subreg:SI (match_dup 0) 1)
4635                 (match_dup 3)))
4637    (set (subreg:SI (match_dup 0) 0)
4638         (ashiftrt:SI (subreg:SI (match_dup 1) 0)
4639                      (match_dup 2)))]
4640   "
4642   int amount = INTVAL (operands[2]);
4643   operands[2] = GEN_INT (amount & 31);
4644   operands[4] = GEN_INT ((-amount) & 31);
4648 (define_insn "ashrdi3_internal4"
4649   [(set (match_operand:DI 0 "register_operand" "=d")
4650         (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
4651                      (match_operand:SI 2 "arith_operand" "dI")))]
4652   "TARGET_64BIT"
4653   "*
4655   if (GET_CODE (operands[2]) == CONST_INT)
4656     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4658   return \"dsra\\t%0,%1,%2\";
4660   [(set_attr "type"     "arith")
4661    (set_attr "mode"     "DI")
4662    (set_attr "length"   "1")])
4665 (define_insn "lshrsi3"
4666   [(set (match_operand:SI 0 "register_operand" "=d")
4667         (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
4668                      (match_operand:SI 2 "arith_operand" "dI")))]
4669   ""
4670   "*
4672   if (GET_CODE (operands[2]) == CONST_INT)
4673     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4675   return \"srl\\t%0,%1,%2\";
4677   [(set_attr "type"     "arith")
4678    (set_attr "mode"     "SI")
4679    (set_attr "length"   "1")])
4682 (define_expand "lshrdi3"
4683   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4684                    (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "")
4685                                 (match_operand:SI 2 "arith_operand" "")))
4686               (clobber (match_dup  3))])]
4687   "TARGET_64BIT || !TARGET_DEBUG_G_MODE"
4688   "
4690   if (TARGET_64BIT)
4691     {
4692       emit_insn (gen_lshrdi3_internal4 (operands[0], operands[1],
4693                                         operands[2]));
4694       DONE;
4695     }
4697   operands[3] = gen_reg_rtx (SImode);
4701 (define_insn "lshrdi3_internal"
4702   [(set (match_operand:DI 0 "register_operand" "=&d")
4703         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
4704                      (match_operand:SI 2 "register_operand" "d")))
4705    (clobber (match_operand:SI 3 "register_operand" "=d"))]
4706   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE"
4707   "* 
4709   operands[4] = const0_rtx;
4710   dslots_jump_total += 3;
4711   dslots_jump_filled += 2;
4713   return \"sll\\t%3,%2,26\\n\\
4714 \\tbgez\\t%3,1f\\n\\
4715 \\tsrl\\t%L0,%M1,%2\\n\\
4716 \\t%(b\\t3f\\n\\
4717 \\tmove\\t%M0,%z4%)\\n\\
4718 \\n\\
4719 1:\\n\\
4720 \\t%(beq\\t%3,%z4,2f\\n\\
4721 \\tsrl\\t%L0,%L1,%2%)\\n\\
4722 \\n\\
4723 \\tsubu\\t%3,%z4,%2\\n\\
4724 \\tsll\\t%3,%M1,%3\\n\\
4725 \\tor\\t%L0,%L0,%3\\n\\
4726 2:\\n\\
4727 \\tsrl\\t%M0,%M1,%2\\n\\
4728 3:\";
4730   [(set_attr "type"     "darith")
4731    (set_attr "mode"     "DI")
4732    (set_attr "length"   "12")])
4735 (define_insn "lshrdi3_internal2"
4736   [(set (match_operand:DI 0 "register_operand" "=d")
4737         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
4738                      (match_operand:SI 2 "small_int" "IJK")))
4739    (clobber (match_operand:SI 3 "register_operand" "=d"))]
4740   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
4741   "*
4743   operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4744   operands[4] = const0_rtx;
4745   return \"srl\\t%L0,%M1,%2\;move\\t%M0,%z4\";
4747   [(set_attr "type"     "darith")
4748    (set_attr "mode"     "DI")
4749    (set_attr "length"   "2")])
4752 (define_split
4753   [(set (match_operand:DI 0 "register_operand" "")
4754         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
4755                      (match_operand:SI 2 "small_int" "")))
4756    (clobber (match_operand:SI 3 "register_operand" ""))]
4757   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4758    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4759    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4760    && (INTVAL (operands[2]) & 32) != 0"
4762   [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 1) (match_dup 2)))
4763    (set (subreg:SI (match_dup 0) 1) (const_int 0))]
4765   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
4768 (define_split
4769   [(set (match_operand:DI 0 "register_operand" "")
4770         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
4771                      (match_operand:SI 2 "small_int" "")))
4772    (clobber (match_operand:SI 3 "register_operand" ""))]
4773   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4774    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4775    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4776    && (INTVAL (operands[2]) & 32) != 0"
4778   [(set (subreg:SI (match_dup 0) 1) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
4779    (set (subreg:SI (match_dup 0) 0) (const_int 0))]
4781   "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
4784 (define_insn "lshrdi3_internal3"
4785   [(set (match_operand:DI 0 "register_operand" "=d")
4786         (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
4787                    (match_operand:SI 2 "small_int" "IJK")))
4788    (clobber (match_operand:SI 3 "register_operand" "=d"))]
4789   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE
4790    && (INTVAL (operands[2]) & 63) < 32
4791    && (INTVAL (operands[2]) & 63) != 0"
4792   "*
4794   int amount = INTVAL (operands[2]);
4796   operands[2] = GEN_INT (amount & 31);
4797   operands[4] = GEN_INT ((-amount) & 31);
4799   return \"srl\\t%L0,%L1,%2\;sll\\t%3,%M1,%4\;or\\t%L0,%L0,%3\;srl\\t%M0,%M1,%2\";
4801   [(set_attr "type"     "darith")
4802    (set_attr "mode"     "DI")
4803    (set_attr "length"   "4")])
4806 (define_split
4807   [(set (match_operand:DI 0 "register_operand" "")
4808         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
4809                      (match_operand:SI 2 "small_int" "")))
4810    (clobber (match_operand:SI 3 "register_operand" ""))]
4811   "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4812    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4813    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4814    && (INTVAL (operands[2]) & 63) < 32
4815    && (INTVAL (operands[2]) & 63) != 0"
4817   [(set (subreg:SI (match_dup 0) 0)
4818         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
4819                      (match_dup 2)))
4821    (set (match_dup 3)
4822         (ashift:SI (subreg:SI (match_dup 1) 1)
4823                    (match_dup 4)))
4825    (set (subreg:SI (match_dup 0) 0)
4826         (ior:SI (subreg:SI (match_dup 0) 0)
4827                 (match_dup 3)))
4829    (set (subreg:SI (match_dup 0) 1)
4830         (lshiftrt:SI (subreg:SI (match_dup 1) 1)
4831                      (match_dup 2)))]
4832   "
4834   int amount = INTVAL (operands[2]);
4835   operands[2] = GEN_INT (amount & 31);
4836   operands[4] = GEN_INT ((-amount) & 31);
4840 (define_split
4841   [(set (match_operand:DI 0 "register_operand" "")
4842         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
4843                      (match_operand:SI 2 "small_int" "")))
4844    (clobber (match_operand:SI 3 "register_operand" ""))]
4845   "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
4846    && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
4847    && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4848    && (INTVAL (operands[2]) & 63) < 32
4849    && (INTVAL (operands[2]) & 63) != 0"
4851   [(set (subreg:SI (match_dup 0) 1)
4852         (lshiftrt:SI (subreg:SI (match_dup 1) 1)
4853                      (match_dup 2)))
4855    (set (match_dup 3)
4856         (ashift:SI (subreg:SI (match_dup 1) 0)
4857                    (match_dup 4)))
4859    (set (subreg:SI (match_dup 0) 1)
4860         (ior:SI (subreg:SI (match_dup 0) 1)
4861                 (match_dup 3)))
4863    (set (subreg:SI (match_dup 0) 0)
4864         (lshiftrt:SI (subreg:SI (match_dup 1) 0)
4865                      (match_dup 2)))]
4866   "
4868   int amount = INTVAL (operands[2]);
4869   operands[2] = GEN_INT (amount & 31);
4870   operands[4] = GEN_INT ((-amount) & 31);
4874 (define_insn "lshrdi3_internal4"
4875   [(set (match_operand:DI 0 "register_operand" "=d")
4876         (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d")
4877                      (match_operand:SI 2 "arith_operand" "dI")))]
4878   "TARGET_64BIT"
4879   "*
4881   if (GET_CODE (operands[2]) == CONST_INT)
4882     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4884   return \"dsrl\\t%0,%1,%2\";
4886   [(set_attr "type"     "arith")
4887    (set_attr "mode"     "DI")
4888    (set_attr "length"   "1")])
4892 ;;  ....................
4894 ;;      COMPARISONS
4896 ;;  ....................
4898 ;; Flow here is rather complex:
4900 ;;  1)  The cmp{si,di,sf,df} routine is called.  It deposits the
4901 ;;      arguments into the branch_cmp array, and the type into
4902 ;;      branch_type.  No RTL is generated.
4904 ;;  2)  The appropriate branch define_expand is called, which then
4905 ;;      creates the appropriate RTL for the comparison and branch.
4906 ;;      Different CC modes are used, based on what type of branch is
4907 ;;      done, so that we can constrain things appropriately.  There
4908 ;;      are assumptions in the rest of GCC that break if we fold the
4909 ;;      operands into the branchs for integer operations, and use cc0
4910 ;;      for floating point, so we use the fp status register instead.
4911 ;;      If needed, an appropriate temporary is created to hold the
4912 ;;      of the integer compare.
4914 (define_expand "cmpsi"
4915   [(set (cc0)
4916         (compare:CC (match_operand:SI 0 "register_operand" "")
4917                     (match_operand:SI 1 "arith_operand" "")))]
4918   ""
4919   "
4921   if (operands[0])              /* avoid unused code message */
4922     {
4923       branch_cmp[0] = operands[0];
4924       branch_cmp[1] = operands[1];
4925       branch_type = CMP_SI;
4926       DONE;
4927     }
4930 (define_expand "tstsi"
4931   [(set (cc0)
4932         (match_operand:SI 0 "register_operand" ""))]
4933   ""
4934   "
4936   if (operands[0])              /* avoid unused code message */
4937     {
4938       branch_cmp[0] = operands[0];
4939       branch_cmp[1] = const0_rtx;
4940       branch_type = CMP_SI;
4941       DONE;
4942     }
4945 (define_expand "cmpdi"
4946   [(set (cc0)
4947         (compare:CC (match_operand:DI 0 "se_register_operand" "")
4948                     (match_operand:DI 1 "se_arith_operand" "")))]
4949   "TARGET_64BIT"
4950   "
4952   if (operands[0])              /* avoid unused code message */
4953     {
4954       branch_cmp[0] = operands[0];
4955       branch_cmp[1] = operands[1];
4956       branch_type = CMP_DI;
4957       DONE;
4958     }
4961 (define_expand "tstdi"
4962   [(set (cc0)
4963         (match_operand:DI 0 "se_register_operand" ""))]
4964   "TARGET_64BIT"
4965   "
4967   if (operands[0])              /* avoid unused code message */
4968     {
4969       branch_cmp[0] = operands[0];
4970       branch_cmp[1] = const0_rtx;
4971       branch_type = CMP_DI;
4972       DONE;
4973     }
4976 (define_expand "cmpdf"
4977   [(set (cc0)
4978         (compare:CC (match_operand:DF 0 "register_operand" "")
4979                     (match_operand:DF 1 "register_operand" "")))]
4980   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4981   "
4983   if (operands[0])              /* avoid unused code message */
4984     {
4985       branch_cmp[0] = operands[0];
4986       branch_cmp[1] = operands[1];
4987       branch_type = CMP_DF;
4988       DONE;
4989     }
4992 (define_expand "cmpsf"
4993   [(set (cc0)
4994         (compare:CC (match_operand:SF 0 "register_operand" "")
4995                     (match_operand:SF 1 "register_operand" "")))]
4996   "TARGET_HARD_FLOAT"
4997   "
4999   if (operands[0])              /* avoid unused code message */
5000     {
5001       branch_cmp[0] = operands[0];
5002       branch_cmp[1] = operands[1];
5003       branch_type = CMP_SF;
5004       DONE;
5005     }
5010 ;;  ....................
5012 ;;      CONDITIONAL BRANCHES
5014 ;;  ....................
5016 (define_insn "branch_fp_ne"
5017   [(set (pc)
5018         (if_then_else (ne:CC (match_operand:CC 0 "register_operand" "z")
5019                              (const_int 0))
5020                       (match_operand 1 "pc_or_label_operand" "")
5021                       (match_operand 2 "pc_or_label_operand" "")))]
5022   "TARGET_HARD_FLOAT"
5023   "*
5025   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
5026   return (operands[1] != pc_rtx) ? \"%*bc1t%?\\t%Z0%1\" : \"%*bc1f%?\\t%Z0%2\";
5028   [(set_attr "type"     "branch")
5029    (set_attr "mode"     "none")
5030    (set_attr "length"   "1")])
5032 (define_insn "branch_fp_eq"
5033   [(set (pc)
5034         (if_then_else (eq:CC (match_operand:CC 0 "register_operand" "z")
5035                              (const_int 0))
5036                       (match_operand 1 "pc_or_label_operand" "")
5037                       (match_operand 2 "pc_or_label_operand" "")))]
5038   "TARGET_HARD_FLOAT"
5039   "*
5041   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
5042   return (operands[1] != pc_rtx) ? \"%*bc1f%?\\t%Z0%1\" : \"%*bc1t%?\\t%Z0%2\";
5044   [(set_attr "type"     "branch")
5045    (set_attr "mode"     "none")
5046    (set_attr "length"   "1")])
5048 (define_insn "branch_zero"
5049   [(set (pc)
5050         (if_then_else (match_operator:SI 0 "cmp_op"
5051                                          [(match_operand:SI 1 "register_operand" "d")
5052                                           (const_int 0)])
5053         (match_operand 2 "pc_or_label_operand" "")
5054         (match_operand 3 "pc_or_label_operand" "")))]
5055   ""
5056   "*
5058   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
5059   if (operands[2] != pc_rtx)
5060     {                           /* normal jump */
5061       switch (GET_CODE (operands[0]))
5062         {
5063         case EQ:  return \"%*beq%?\\t%z1,%.,%2\";
5064         case NE:  return \"%*bne%?\\t%z1,%.,%2\";
5065         case GTU: return \"%*bne%?\\t%z1,%.,%2\";
5066         case LEU: return \"%*beq%?\\t%z1,%.,%2\";
5067         case GEU: return \"%*j\\t%2\";
5068         case LTU: return \"%*bne%?\\t%.,%.,%2\";
5069         }
5071       return \"%*b%C0z%?\\t%z1,%2\";
5072     }
5073   else
5074     {                           /* inverted jump */
5075       switch (GET_CODE (operands[0]))
5076         {
5077         case EQ:  return \"%*bne%?\\t%z1,%.,%3\";
5078         case NE:  return \"%*beq%?\\t%z1,%.,%3\";
5079         case GTU: return \"%*beq%?\\t%z1,%.,%3\";
5080         case LEU: return \"%*bne%?\\t%z1,%.,%3\";
5081         case GEU: return \"%*beq%?\\t%.,%.,%3\";
5082         case LTU: return \"%*j\\t%3\";
5083         }
5085       return \"%*b%N0z%?\\t%z1,%3\";
5086     }
5088   [(set_attr "type"     "branch")
5089    (set_attr "mode"     "none")
5090    (set_attr "length"   "1")])
5093 (define_insn "branch_zero_di"
5094   [(set (pc)
5095         (if_then_else (match_operator:DI 0 "cmp_op"
5096                                          [(match_operand:DI 1 "se_register_operand" "d")
5097                                           (const_int 0)])
5098         (match_operand 2 "pc_or_label_operand" "")
5099         (match_operand 3 "pc_or_label_operand" "")))]
5100   ""
5101   "*
5103   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
5104   if (operands[2] != pc_rtx)
5105     {                           /* normal jump */
5106       switch (GET_CODE (operands[0]))
5107         {
5108         case EQ:  return \"%*beq%?\\t%z1,%.,%2\";
5109         case NE:  return \"%*bne%?\\t%z1,%.,%2\";
5110         case GTU: return \"%*bne%?\\t%z1,%.,%2\";
5111         case LEU: return \"%*beq%?\\t%z1,%.,%2\";
5112         case GEU: return \"%*j\\t%2\";
5113         case LTU: return \"%*bne%?\\t%.,%.,%2\";
5114         }
5116       return \"%*b%C0z%?\\t%z1,%2\";
5117     }
5118   else
5119     {                           /* inverted jump */
5120       switch (GET_CODE (operands[0]))
5121         {
5122         case EQ:  return \"%*bne%?\\t%z1,%.,%3\";
5123         case NE:  return \"%*beq%?\\t%z1,%.,%3\";
5124         case GTU: return \"%*beq%?\\t%z1,%.,%3\";
5125         case LEU: return \"%*bne%?\\t%z1,%.,%3\";
5126         case GEU: return \"%*beq%?\\t%.,%.,%3\";
5127         case LTU: return \"%*j\\t%3\";
5128         }
5130       return \"%*b%N0z%?\\t%z1,%3\";
5131     }
5133   [(set_attr "type"     "branch")
5134    (set_attr "mode"     "none")
5135    (set_attr "length"   "1")])
5138 (define_insn "branch_equality"
5139   [(set (pc)
5140         (if_then_else (match_operator:SI 0 "equality_op"
5141                                          [(match_operand:SI 1 "register_operand" "d")
5142                                           (match_operand:SI 2 "register_operand" "d")])
5143         (match_operand 3 "pc_or_label_operand" "")
5144         (match_operand 4 "pc_or_label_operand" "")))]
5145   ""
5146   "*
5148   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
5149   return (operands[3] != pc_rtx)
5150         ? \"%*b%C0%?\\t%z1,%z2,%3\"
5151         : \"%*b%N0%?\\t%z1,%z2,%4\";
5153   [(set_attr "type"     "branch")
5154    (set_attr "mode"     "none")
5155    (set_attr "length"   "1")])
5158 (define_insn "branch_equality_di"
5159   [(set (pc)
5160         (if_then_else (match_operator:DI 0 "equality_op"
5161                                          [(match_operand:DI 1 "se_register_operand" "d")
5162                                           (match_operand:DI 2 "se_register_operand" "d")])
5163         (match_operand 3 "pc_or_label_operand" "")
5164         (match_operand 4 "pc_or_label_operand" "")))]
5165   ""
5166   "*
5168   mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
5169   return (operands[3] != pc_rtx)
5170         ? \"%*b%C0%?\\t%z1,%z2,%3\"
5171         : \"%*b%N0%?\\t%z1,%z2,%4\";
5173   [(set_attr "type"     "branch")
5174    (set_attr "mode"     "none")
5175    (set_attr "length"   "1")])
5178 (define_expand "beq"
5179   [(set (pc)
5180         (if_then_else (eq:CC (cc0)
5181                              (const_int 0))
5182                       (label_ref (match_operand 0 "" ""))
5183                       (pc)))]
5184   ""
5185   "
5187   if (operands[0])              /* avoid unused code warning */
5188     {
5189       gen_conditional_branch (operands, EQ);
5190       DONE;
5191     }
5194 (define_expand "bne"
5195   [(set (pc)
5196         (if_then_else (ne:CC (cc0)
5197                              (const_int 0))
5198                       (label_ref (match_operand 0 "" ""))
5199                       (pc)))]
5200   ""
5201   "
5203   if (operands[0])              /* avoid unused code warning */
5204     {
5205       gen_conditional_branch (operands, NE);
5206       DONE;
5207     }
5210 (define_expand "bgt"
5211   [(set (pc)
5212         (if_then_else (gt:CC (cc0)
5213                              (const_int 0))
5214                       (label_ref (match_operand 0 "" ""))
5215                       (pc)))]
5216   ""
5217   "
5219   if (operands[0])              /* avoid unused code warning */
5220     {
5221       gen_conditional_branch (operands, GT);
5222       DONE;
5223     }
5226 (define_expand "bge"
5227   [(set (pc)
5228         (if_then_else (ge:CC (cc0)
5229                              (const_int 0))
5230                       (label_ref (match_operand 0 "" ""))
5231                       (pc)))]
5232   ""
5233   "
5235   if (operands[0])              /* avoid unused code warning */
5236     {
5237       gen_conditional_branch (operands, GE);
5238       DONE;
5239     }
5242 (define_expand "blt"
5243   [(set (pc)
5244         (if_then_else (lt:CC (cc0)
5245                              (const_int 0))
5246                       (label_ref (match_operand 0 "" ""))
5247                       (pc)))]
5248   ""
5249   "
5251   if (operands[0])              /* avoid unused code warning */
5252     {
5253       gen_conditional_branch (operands, LT);
5254       DONE;
5255     }
5258 (define_expand "ble"
5259   [(set (pc)
5260         (if_then_else (le:CC (cc0)
5261                              (const_int 0))
5262                       (label_ref (match_operand 0 "" ""))
5263                       (pc)))]
5264   ""
5265   "
5267   if (operands[0])              /* avoid unused code warning */
5268     {
5269       gen_conditional_branch (operands, LE);
5270       DONE;
5271     }
5274 (define_expand "bgtu"
5275   [(set (pc)
5276         (if_then_else (gtu:CC (cc0)
5277                               (const_int 0))
5278                       (label_ref (match_operand 0 "" ""))
5279                       (pc)))]
5280   ""
5281   "
5283   if (operands[0])              /* avoid unused code warning */
5284     {
5285       gen_conditional_branch (operands, GTU);
5286       DONE;
5287     }
5290 (define_expand "bgeu"
5291   [(set (pc)
5292         (if_then_else (geu:CC (cc0)
5293                               (const_int 0))
5294                       (label_ref (match_operand 0 "" ""))
5295                       (pc)))]
5296   ""
5297   "
5299   if (operands[0])              /* avoid unused code warning */
5300     {
5301       gen_conditional_branch (operands, GEU);
5302       DONE;
5303     }
5307 (define_expand "bltu"
5308   [(set (pc)
5309         (if_then_else (ltu:CC (cc0)
5310                               (const_int 0))
5311                       (label_ref (match_operand 0 "" ""))
5312                       (pc)))]
5313   ""
5314   "
5316   if (operands[0])              /* avoid unused code warning */
5317     {
5318       gen_conditional_branch (operands, LTU);
5319       DONE;
5320     }
5323 (define_expand "bleu"
5324   [(set (pc)
5325         (if_then_else (leu:CC (cc0)
5326                               (const_int 0))
5327                       (label_ref (match_operand 0 "" ""))
5328                       (pc)))]
5329   ""
5330   "
5332   if (operands[0])              /* avoid unused code warning */
5333     {
5334       gen_conditional_branch (operands, LEU);
5335       DONE;
5336     }
5341 ;;  ....................
5343 ;;      SETTING A REGISTER FROM A COMPARISON
5345 ;;  ....................
5347 (define_expand "seq"
5348   [(set (match_operand:SI 0 "register_operand" "=d")
5349         (eq:SI (match_dup 1)
5350                (match_dup 2)))]
5351   ""
5352   "
5354   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5355     FAIL;
5357   /* set up operands from compare.  */
5358   operands[1] = branch_cmp[0];
5359   operands[2] = branch_cmp[1];
5361   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5362     {
5363       gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
5364       DONE;
5365     }
5367   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
5368     operands[2] = force_reg (SImode, operands[2]);
5370   /* fall through and generate default code */
5374 (define_insn "seq_si_zero"
5375   [(set (match_operand:SI 0 "register_operand" "=d")
5376         (eq:SI (match_operand:SI 1 "register_operand" "d")
5377                (const_int 0)))]
5378   ""
5379   "sltu\\t%0,%1,1"
5380   [(set_attr "type"     "arith")
5381    (set_attr "mode"     "SI")
5382    (set_attr "length"   "1")])
5384 (define_insn "seq_di_zero"
5385   [(set (match_operand:DI 0 "register_operand" "=d")
5386         (eq:DI (match_operand:DI 1 "se_register_operand" "d")
5387                (const_int 0)))]
5388   "TARGET_64BIT"
5389   "sltu\\t%0,%1,1"
5390   [(set_attr "type"     "arith")
5391    (set_attr "mode"     "DI")
5392    (set_attr "length"   "1")])
5394 (define_insn "seq_si"
5395   [(set (match_operand:SI 0 "register_operand" "=d,d")
5396         (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
5397                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
5398   "TARGET_DEBUG_C_MODE"
5399   "@
5400    xor\\t%0,%1,%2\;sltu\\t%0,%0,1
5401    xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
5402   [(set_attr "type"     "arith")
5403    (set_attr "mode"     "SI")
5404    (set_attr "length"   "2")])
5406 (define_split
5407   [(set (match_operand:SI 0 "register_operand" "")
5408         (eq:SI (match_operand:SI 1 "register_operand" "")
5409                (match_operand:SI 2 "uns_arith_operand" "")))]
5410   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
5411     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
5412   [(set (match_dup 0)
5413         (xor:SI (match_dup 1)
5414                 (match_dup 2)))
5415    (set (match_dup 0)
5416         (ltu:SI (match_dup 0)
5417                 (const_int 1)))]
5418   "")
5420 (define_insn "seq_di"
5421   [(set (match_operand:DI 0 "register_operand" "=d,d")
5422         (eq:DI (match_operand:DI 1 "se_register_operand" "%d,d")
5423                (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
5424   "TARGET_64BIT && TARGET_DEBUG_C_MODE"
5425   "@
5426    xor\\t%0,%1,%2\;sltu\\t%0,%0,1
5427    xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
5428   [(set_attr "type"     "arith")
5429    (set_attr "mode"     "DI")
5430    (set_attr "length"   "2")])
5432 (define_split
5433   [(set (match_operand:DI 0 "register_operand" "")
5434         (eq:DI (match_operand:DI 1 "se_register_operand" "")
5435                (match_operand:DI 2 "se_uns_arith_operand" "")))]
5436   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
5437     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
5438   [(set (match_dup 0)
5439         (xor:DI (match_dup 1)
5440                 (match_dup 2)))
5441    (set (match_dup 0)
5442         (ltu:DI (match_dup 0)
5443                 (const_int 1)))]
5444   "")
5446 (define_expand "sne"
5447   [(set (match_operand:SI 0 "register_operand" "=d")
5448         (ne:SI (match_dup 1)
5449                (match_dup 2)))]
5450   ""
5451   "
5453   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5454     FAIL;
5456   /* set up operands from compare.  */
5457   operands[1] = branch_cmp[0];
5458   operands[2] = branch_cmp[1];
5460   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5461     {
5462       gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
5463       DONE;
5464     }
5466   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
5467     operands[2] = force_reg (SImode, operands[2]);
5469   /* fall through and generate default code */
5472 (define_insn "sne_si_zero"
5473   [(set (match_operand:SI 0 "register_operand" "=d")
5474         (ne:SI (match_operand:SI 1 "register_operand" "d")
5475                (const_int 0)))]
5476   ""
5477   "sltu\\t%0,%.,%1"
5478   [(set_attr "type"     "arith")
5479    (set_attr "mode"     "SI")
5480    (set_attr "length"   "1")])
5482 (define_insn "sne_di_zero"
5483   [(set (match_operand:DI 0 "register_operand" "=d")
5484         (ne:DI (match_operand:DI 1 "se_register_operand" "d")
5485                (const_int 0)))]
5486   "TARGET_64BIT"
5487   "sltu\\t%0,%.,%1"
5488   [(set_attr "type"     "arith")
5489    (set_attr "mode"     "DI")
5490    (set_attr "length"   "1")])
5492 (define_insn "sne_si"
5493   [(set (match_operand:SI 0 "register_operand" "=d,d")
5494         (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
5495                (match_operand:SI 2 "uns_arith_operand" "d,K")))]
5496   "TARGET_DEBUG_C_MODE"
5497   "@
5498     xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
5499     xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
5500   [(set_attr "type"     "arith")
5501    (set_attr "mode"     "SI")
5502    (set_attr "length"   "2")])
5504 (define_split
5505   [(set (match_operand:SI 0 "register_operand" "")
5506         (ne:SI (match_operand:SI 1 "register_operand" "")
5507                (match_operand:SI 2 "uns_arith_operand" "")))]
5508   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
5509     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
5510   [(set (match_dup 0)
5511         (xor:SI (match_dup 1)
5512                 (match_dup 2)))
5513    (set (match_dup 0)
5514         (gtu:SI (match_dup 0)
5515                 (const_int 0)))]
5516   "")
5518 (define_insn "sne_di"
5519   [(set (match_operand:DI 0 "register_operand" "=d,d")
5520         (ne:DI (match_operand:DI 1 "se_register_operand" "%d,d")
5521                (match_operand:DI 2 "se_uns_arith_operand" "d,K")))]
5522   "TARGET_64BIT && TARGET_DEBUG_C_MODE"
5523   "@
5524     xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
5525     xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
5526   [(set_attr "type"     "arith")
5527    (set_attr "mode"     "DI")
5528    (set_attr "length"   "2")])
5530 (define_split
5531   [(set (match_operand:DI 0 "register_operand" "")
5532         (ne:DI (match_operand:DI 1 "se_register_operand" "")
5533                (match_operand:DI 2 "se_uns_arith_operand" "")))]
5534   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
5535     && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
5536   [(set (match_dup 0)
5537         (xor:DI (match_dup 1)
5538                 (match_dup 2)))
5539    (set (match_dup 0)
5540         (gtu:DI (match_dup 0)
5541                 (const_int 0)))]
5542   "")
5544 (define_expand "sgt"
5545   [(set (match_operand:SI 0 "register_operand" "=d")
5546         (gt:SI (match_dup 1)
5547                (match_dup 2)))]
5548   ""
5549   "
5551   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5552     FAIL;
5554   /* set up operands from compare.  */
5555   operands[1] = branch_cmp[0];
5556   operands[2] = branch_cmp[1];
5558   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5559     {
5560       gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
5561       DONE;
5562     }
5564   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
5565     operands[2] = force_reg (SImode, operands[2]);
5567   /* fall through and generate default code */
5570 (define_insn "sgt_si"
5571   [(set (match_operand:SI 0 "register_operand" "=d")
5572         (gt:SI (match_operand:SI 1 "register_operand" "d")
5573                (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
5574   ""
5575   "slt\\t%0,%z2,%1"
5576   [(set_attr "type"     "arith")
5577    (set_attr "mode"     "SI")
5578    (set_attr "length"   "1")])
5580 (define_insn "sgt_di"
5581   [(set (match_operand:DI 0 "register_operand" "=d")
5582         (gt:DI (match_operand:DI 1 "se_register_operand" "d")
5583                (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
5584   "TARGET_64BIT"
5585   "slt\\t%0,%z2,%1"
5586   [(set_attr "type"     "arith")
5587    (set_attr "mode"     "DI")
5588    (set_attr "length"   "1")])
5590 (define_expand "sge"
5591   [(set (match_operand:SI 0 "register_operand" "=d")
5592         (ge:SI (match_dup 1)
5593                (match_dup 2)))]
5594   ""
5595   "
5597   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5598     FAIL;
5600   /* set up operands from compare.  */
5601   operands[1] = branch_cmp[0];
5602   operands[2] = branch_cmp[1];
5604   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5605     {
5606       gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
5607       DONE;
5608     }
5610   /* fall through and generate default code */
5613 (define_insn "sge_si"
5614   [(set (match_operand:SI 0 "register_operand" "=d")
5615         (ge:SI (match_operand:SI 1 "register_operand" "d")
5616                (match_operand:SI 2 "arith_operand" "dI")))]
5617   "TARGET_DEBUG_C_MODE"
5618   "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
5619   [(set_attr "type"     "arith")
5620    (set_attr "mode"     "SI")
5621    (set_attr "length"   "2")])
5623 (define_split
5624   [(set (match_operand:SI 0 "register_operand" "")
5625         (ge:SI (match_operand:SI 1 "register_operand" "")
5626                (match_operand:SI 2 "arith_operand" "")))]
5627   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5628   [(set (match_dup 0)
5629         (lt:SI (match_dup 1)
5630                (match_dup 2)))
5631    (set (match_dup 0)
5632         (xor:SI (match_dup 0)
5633                 (const_int 1)))]
5634   "")
5636 (define_insn "sge_di"
5637   [(set (match_operand:DI 0 "register_operand" "=d")
5638         (ge:DI (match_operand:DI 1 "se_register_operand" "d")
5639                (match_operand:DI 2 "se_arith_operand" "dI")))]
5640   "TARGET_64BIT && TARGET_DEBUG_C_MODE"
5641   "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
5642   [(set_attr "type"     "arith")
5643    (set_attr "mode"     "DI")
5644    (set_attr "length"   "2")])
5646 (define_split
5647   [(set (match_operand:DI 0 "register_operand" "")
5648         (ge:DI (match_operand:DI 1 "se_register_operand" "")
5649                (match_operand:DI 2 "se_arith_operand" "")))]
5650   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5651   [(set (match_dup 0)
5652         (lt:DI (match_dup 1)
5653                (match_dup 2)))
5654    (set (match_dup 0)
5655         (xor:DI (match_dup 0)
5656                 (const_int 1)))]
5657   "")
5659 (define_expand "slt"
5660   [(set (match_operand:SI 0 "register_operand" "=d")
5661         (lt:SI (match_dup 1)
5662                (match_dup 2)))]
5663   ""
5664   "
5666   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5667     FAIL;
5669   /* set up operands from compare.  */
5670   operands[1] = branch_cmp[0];
5671   operands[2] = branch_cmp[1];
5673   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5674     {
5675       gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
5676       DONE;
5677     }
5679   /* fall through and generate default code */
5682 (define_insn "slt_si"
5683   [(set (match_operand:SI 0 "register_operand" "=d")
5684         (lt:SI (match_operand:SI 1 "register_operand" "d")
5685                (match_operand:SI 2 "arith_operand" "dI")))]
5686   ""
5687   "slt\\t%0,%1,%2"
5688   [(set_attr "type"     "arith")
5689    (set_attr "mode"     "SI")
5690    (set_attr "length"   "1")])
5692 (define_insn "slt_di"
5693   [(set (match_operand:DI 0 "register_operand" "=d")
5694         (lt:DI (match_operand:DI 1 "se_register_operand" "d")
5695                (match_operand:DI 2 "se_arith_operand" "dI")))]
5696   "TARGET_64BIT"
5697   "slt\\t%0,%1,%2"
5698   [(set_attr "type"     "arith")
5699    (set_attr "mode"     "DI")
5700    (set_attr "length"   "1")])
5702 (define_expand "sle"
5703   [(set (match_operand:SI 0 "register_operand" "=d")
5704         (le:SI (match_dup 1)
5705                (match_dup 2)))]
5706   ""
5707   "
5709   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5710     FAIL;
5712   /* set up operands from compare.  */
5713   operands[1] = branch_cmp[0];
5714   operands[2] = branch_cmp[1];
5716   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5717     {
5718       gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
5719       DONE;
5720     }
5722   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
5723     operands[2] = force_reg (SImode, operands[2]);
5725   /* fall through and generate default code */
5728 (define_insn "sle_si_const"
5729   [(set (match_operand:SI 0 "register_operand" "=d")
5730         (le:SI (match_operand:SI 1 "register_operand" "d")
5731                (match_operand:SI 2 "small_int" "I")))]
5732   "INTVAL (operands[2]) < 32767"
5733   "*
5735   operands[2] = GEN_INT (INTVAL (operands[2])+1);
5736   return \"slt\\t%0,%1,%2\";
5738   [(set_attr "type"     "arith")
5739    (set_attr "mode"     "SI")
5740    (set_attr "length"   "1")])
5742 (define_insn "sle_di_const"
5743   [(set (match_operand:DI 0 "register_operand" "=d")
5744         (le:DI (match_operand:DI 1 "se_register_operand" "d")
5745                (match_operand:DI 2 "small_int" "I")))]
5746   "TARGET_64BIT && INTVAL (operands[2]) < 32767"
5747   "*
5749   operands[2] = GEN_INT (INTVAL (operands[2])+1);
5750   return \"slt\\t%0,%1,%2\";
5752   [(set_attr "type"     "arith")
5753    (set_attr "mode"     "DI")
5754    (set_attr "length"   "1")])
5756 (define_insn "sle_si_reg"
5757   [(set (match_operand:SI 0 "register_operand" "=d")
5758         (le:SI (match_operand:SI 1 "register_operand" "d")
5759                (match_operand:SI 2 "register_operand" "d")))]
5760   "TARGET_DEBUG_C_MODE"
5761   "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
5762   [(set_attr "type"     "arith")
5763    (set_attr "mode"     "SI")
5764    (set_attr "length"   "2")])
5766 (define_split
5767   [(set (match_operand:SI 0 "register_operand" "")
5768         (le:SI (match_operand:SI 1 "register_operand" "")
5769                (match_operand:SI 2 "register_operand" "")))]
5770   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5771   [(set (match_dup 0)
5772         (lt:SI (match_dup 2)
5773                (match_dup 1)))
5774    (set (match_dup 0)
5775         (xor:SI (match_dup 0)
5776                 (const_int 1)))]
5777   "")
5779 (define_insn "sle_di_reg"
5780   [(set (match_operand:DI 0 "register_operand" "=d")
5781         (le:DI (match_operand:DI 1 "se_register_operand" "d")
5782                (match_operand:DI 2 "se_register_operand" "d")))]
5783   "TARGET_64BIT && TARGET_DEBUG_C_MODE"
5784   "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
5785   [(set_attr "type"     "arith")
5786    (set_attr "mode"     "DI")
5787    (set_attr "length"   "2")])
5789 (define_split
5790   [(set (match_operand:DI 0 "register_operand" "")
5791         (le:DI (match_operand:DI 1 "se_register_operand" "")
5792                (match_operand:DI 2 "se_register_operand" "")))]
5793   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5794   [(set (match_dup 0)
5795         (lt:DI (match_dup 2)
5796                (match_dup 1)))
5797    (set (match_dup 0)
5798         (xor:DI (match_dup 0)
5799                 (const_int 1)))]
5800   "")
5802 (define_expand "sgtu"
5803   [(set (match_operand:SI 0 "register_operand" "=d")
5804         (gtu:SI (match_dup 1)
5805                 (match_dup 2)))]
5806   ""
5807   "
5809   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5810     FAIL;
5812   /* set up operands from compare.  */
5813   operands[1] = branch_cmp[0];
5814   operands[2] = branch_cmp[1];
5816   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5817     {
5818       gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
5819       DONE;
5820     }
5822   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
5823     operands[2] = force_reg (SImode, operands[2]);
5825   /* fall through and generate default code */
5828 (define_insn "sgtu_si"
5829   [(set (match_operand:SI 0 "register_operand" "=d")
5830         (gtu:SI (match_operand:SI 1 "register_operand" "d")
5831                 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
5832   ""
5833   "sltu\\t%0,%z2,%1"
5834   [(set_attr "type"     "arith")
5835    (set_attr "mode"     "SI")
5836    (set_attr "length"   "1")])
5838 (define_insn "sgtu_di"
5839   [(set (match_operand:DI 0 "register_operand" "=d")
5840         (gtu:DI (match_operand:DI 1 "se_register_operand" "d")
5841                 (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))]
5842   "TARGET_64BIT"
5843   "sltu\\t%0,%z2,%1"
5844   [(set_attr "type"     "arith")
5845    (set_attr "mode"     "DI")
5846    (set_attr "length"   "1")])
5848 (define_expand "sgeu"
5849   [(set (match_operand:SI 0 "register_operand" "=d")
5850         (geu:SI (match_dup 1)
5851                 (match_dup 2)))]
5852   ""
5853   "
5855   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5856     FAIL;
5858   /* set up operands from compare.  */
5859   operands[1] = branch_cmp[0];
5860   operands[2] = branch_cmp[1];
5862   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5863     {
5864       gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
5865       DONE;
5866     }
5868   /* fall through and generate default code */
5871 (define_insn "sgeu_si"
5872   [(set (match_operand:SI 0 "register_operand" "=d")
5873         (geu:SI (match_operand:SI 1 "register_operand" "d")
5874                 (match_operand:SI 2 "arith_operand" "dI")))]
5875   "TARGET_DEBUG_C_MODE"
5876   "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
5877   [(set_attr "type"     "arith")
5878    (set_attr "mode"     "SI")
5879    (set_attr "length"   "2")])
5881 (define_split
5882   [(set (match_operand:SI 0 "register_operand" "")
5883         (geu:SI (match_operand:SI 1 "register_operand" "")
5884                 (match_operand:SI 2 "arith_operand" "")))]
5885   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5886   [(set (match_dup 0)
5887         (ltu:SI (match_dup 1)
5888                 (match_dup 2)))
5889    (set (match_dup 0)
5890         (xor:SI (match_dup 0)
5891                 (const_int 1)))]
5892   "")
5894 (define_insn "sgeu_di"
5895   [(set (match_operand:DI 0 "register_operand" "=d")
5896         (geu:DI (match_operand:DI 1 "se_register_operand" "d")
5897                 (match_operand:DI 2 "se_arith_operand" "dI")))]
5898   "TARGET_64BIT && TARGET_DEBUG_C_MODE"
5899   "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
5900   [(set_attr "type"     "arith")
5901    (set_attr "mode"     "DI")
5902    (set_attr "length"   "2")])
5904 (define_split
5905   [(set (match_operand:DI 0 "register_operand" "")
5906         (geu:DI (match_operand:DI 1 "se_register_operand" "")
5907                 (match_operand:DI 2 "se_arith_operand" "")))]
5908   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
5909   [(set (match_dup 0)
5910         (ltu:DI (match_dup 1)
5911                 (match_dup 2)))
5912    (set (match_dup 0)
5913         (xor:DI (match_dup 0)
5914                 (const_int 1)))]
5915   "")
5917 (define_expand "sltu"
5918   [(set (match_operand:SI 0 "register_operand" "=d")
5919         (ltu:SI (match_dup 1)
5920                 (match_dup 2)))]
5921   ""
5922   "
5924   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5925     FAIL;
5927   /* set up operands from compare.  */
5928   operands[1] = branch_cmp[0];
5929   operands[2] = branch_cmp[1];
5931   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5932     {
5933       gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
5934       DONE;
5935     }
5937   /* fall through and generate default code */
5940 (define_insn "sltu_si"
5941   [(set (match_operand:SI 0 "register_operand" "=d")
5942         (ltu:SI (match_operand:SI 1 "register_operand" "d")
5943                 (match_operand:SI 2 "arith_operand" "dI")))]
5944   ""
5945   "sltu\\t%0,%1,%2"
5946   [(set_attr "type"     "arith")
5947    (set_attr "mode"     "SI")
5948    (set_attr "length"   "1")])
5950 (define_insn "sltu_di"
5951   [(set (match_operand:DI 0 "register_operand" "=d")
5952         (ltu:DI (match_operand:DI 1 "se_register_operand" "d")
5953                 (match_operand:DI 2 "se_arith_operand" "dI")))]
5954   "TARGET_64BIT"
5955   "sltu\\t%0,%1,%2"
5956   [(set_attr "type"     "arith")
5957    (set_attr "mode"     "DI")
5958    (set_attr "length"   "1")])
5960 (define_expand "sleu"
5961   [(set (match_operand:SI 0 "register_operand" "=d")
5962         (leu:SI (match_dup 1)
5963                 (match_dup 2)))]
5964   ""
5965   "
5967   if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
5968     FAIL;
5970   /* set up operands from compare.  */
5971   operands[1] = branch_cmp[0];
5972   operands[2] = branch_cmp[1];
5974   if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
5975     {
5976       gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
5977       DONE;
5978     }
5980   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
5981     operands[2] = force_reg (SImode, operands[2]);
5983   /* fall through and generate default code */
5986 (define_insn "sleu_si_const"
5987   [(set (match_operand:SI 0 "register_operand" "=d")
5988         (leu:SI (match_operand:SI 1 "register_operand" "d")
5989                 (match_operand:SI 2 "small_int" "I")))]
5990   "INTVAL (operands[2]) < 32767"
5991   "*
5993   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5994   return \"sltu\\t%0,%1,%2\";
5996   [(set_attr "type"     "arith")
5997    (set_attr "mode"     "SI")
5998    (set_attr "length"   "1")])
6000 (define_insn "sleu_di_const"
6001   [(set (match_operand:DI 0 "register_operand" "=d")
6002         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
6003                 (match_operand:DI 2 "small_int" "I")))]
6004   "TARGET_64BIT && INTVAL (operands[2]) < 32767"
6005   "*
6007   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
6008   return \"sltu\\t%0,%1,%2\";
6010   [(set_attr "type"     "arith")
6011    (set_attr "mode"     "DI")
6012    (set_attr "length"   "1")])
6014 (define_insn "sleu_si_reg"
6015   [(set (match_operand:SI 0 "register_operand" "=d")
6016         (leu:SI (match_operand:SI 1 "register_operand" "d")
6017                 (match_operand:SI 2 "register_operand" "d")))]
6018   "TARGET_DEBUG_C_MODE"
6019   "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
6020   [(set_attr "type"     "arith")
6021    (set_attr "mode"     "SI")
6022    (set_attr "length"   "2")])
6024 (define_split
6025   [(set (match_operand:SI 0 "register_operand" "")
6026         (leu:SI (match_operand:SI 1 "register_operand" "")
6027                 (match_operand:SI 2 "register_operand" "")))]
6028   "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
6029   [(set (match_dup 0)
6030         (ltu:SI (match_dup 2)
6031                 (match_dup 1)))
6032    (set (match_dup 0)
6033         (xor:SI (match_dup 0)
6034                 (const_int 1)))]
6035   "")
6037 (define_insn "sleu_di_reg"
6038   [(set (match_operand:DI 0 "register_operand" "=d")
6039         (leu:DI (match_operand:DI 1 "se_register_operand" "d")
6040                 (match_operand:DI 2 "se_register_operand" "d")))]
6041   "TARGET_64BIT && TARGET_DEBUG_C_MODE"
6042   "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
6043   [(set_attr "type"     "arith")
6044    (set_attr "mode"     "DI")
6045    (set_attr "length"   "2")])
6047 (define_split
6048   [(set (match_operand:DI 0 "register_operand" "")
6049         (leu:DI (match_operand:DI 1 "se_register_operand" "")
6050                 (match_operand:DI 2 "se_register_operand" "")))]
6051   "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
6052   [(set (match_dup 0)
6053         (ltu:DI (match_dup 2)
6054                 (match_dup 1)))
6055    (set (match_dup 0)
6056         (xor:DI (match_dup 0)
6057                 (const_int 1)))]
6058   "")
6062 ;;  ....................
6064 ;;      FLOATING POINT COMPARISONS
6066 ;;  ....................
6068 (define_insn "seq_df"
6069   [(set (match_operand:CC 0 "register_operand" "=z")
6070         (eq:CC (match_operand:DF 1 "register_operand" "f")
6071                (match_operand:DF 2 "register_operand" "f")))]
6072   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6073   "*
6075   return mips_fill_delay_slot (\"c.eq.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
6077  [(set_attr "type"      "fcmp")
6078   (set_attr "mode"      "FPSW")
6079   (set_attr "length"    "1")])
6081 (define_insn "slt_df"
6082   [(set (match_operand:CC 0 "register_operand" "=z")
6083         (lt:CC (match_operand:DF 1 "register_operand" "f")
6084                (match_operand:DF 2 "register_operand" "f")))]
6085   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6086   "*
6088   return mips_fill_delay_slot (\"c.lt.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
6090  [(set_attr "type"      "fcmp")
6091   (set_attr "mode"      "FPSW")
6092   (set_attr "length"    "1")])
6094 (define_insn "sle_df"
6095   [(set (match_operand:CC 0 "register_operand" "=z")
6096         (le:CC (match_operand:DF 1 "register_operand" "f")
6097                (match_operand:DF 2 "register_operand" "f")))]
6098   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6099   "*
6101   return mips_fill_delay_slot (\"c.le.d\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
6103  [(set_attr "type"      "fcmp")
6104   (set_attr "mode"      "FPSW")
6105   (set_attr "length"    "1")])
6107 (define_insn "sgt_df"
6108   [(set (match_operand:CC 0 "register_operand" "=z")
6109         (gt:CC (match_operand:DF 1 "register_operand" "f")
6110                (match_operand:DF 2 "register_operand" "f")))]
6111   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6112   "*
6114   return mips_fill_delay_slot (\"c.lt.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
6116  [(set_attr "type"      "fcmp")
6117   (set_attr "mode"      "FPSW")
6118   (set_attr "length"    "1")])
6120 (define_insn "sge_df"
6121   [(set (match_operand:CC 0 "register_operand" "=z")
6122         (ge:CC (match_operand:DF 1 "register_operand" "f")
6123                (match_operand:DF 2 "register_operand" "f")))]
6124   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6125   "*
6127   return mips_fill_delay_slot (\"c.le.d\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
6129  [(set_attr "type"      "fcmp")
6130   (set_attr "mode"      "FPSW")
6131   (set_attr "length"    "1")])
6133 (define_insn "seq_sf"
6134   [(set (match_operand:CC 0 "register_operand" "=z")
6135         (eq:CC (match_operand:SF 1 "register_operand" "f")
6136                (match_operand:SF 2 "register_operand" "f")))]
6137   "TARGET_HARD_FLOAT"
6138   "*
6140   return mips_fill_delay_slot (\"c.eq.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
6142  [(set_attr "type"      "fcmp")
6143   (set_attr "mode"      "FPSW")
6144   (set_attr "length"    "1")])
6146 (define_insn "slt_sf"
6147   [(set (match_operand:CC 0 "register_operand" "=z")
6148         (lt:CC (match_operand:SF 1 "register_operand" "f")
6149                (match_operand:SF 2 "register_operand" "f")))]
6150   "TARGET_HARD_FLOAT"
6151   "*
6153   return mips_fill_delay_slot (\"c.lt.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
6155  [(set_attr "type"      "fcmp")
6156   (set_attr "mode"      "FPSW")
6157   (set_attr "length"    "1")])
6159 (define_insn "sle_sf"
6160   [(set (match_operand:CC 0 "register_operand" "=z")
6161         (le:CC (match_operand:SF 1 "register_operand" "f")
6162                (match_operand:SF 2 "register_operand" "f")))]
6163   "TARGET_HARD_FLOAT"
6164   "*
6166   return mips_fill_delay_slot (\"c.le.s\\t%Z0%1,%2\", DELAY_FCMP, operands, insn);
6168  [(set_attr "type"      "fcmp")
6169   (set_attr "mode"      "FPSW")
6170   (set_attr "length"    "1")])
6172 (define_insn "sgt_sf"
6173   [(set (match_operand:CC 0 "register_operand" "=z")
6174         (gt:CC (match_operand:SF 1 "register_operand" "f")
6175                (match_operand:SF 2 "register_operand" "f")))]
6176   "TARGET_HARD_FLOAT"
6177   "*
6179   return mips_fill_delay_slot (\"c.lt.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
6181  [(set_attr "type"      "fcmp")
6182   (set_attr "mode"      "FPSW")
6183   (set_attr "length"    "1")])
6185 (define_insn "sge_sf"
6186   [(set (match_operand:CC 0 "register_operand" "=z")
6187         (ge:CC (match_operand:SF 1 "register_operand" "f")
6188                (match_operand:SF 2 "register_operand" "f")))]
6189   "TARGET_HARD_FLOAT"
6190   "*
6192   return mips_fill_delay_slot (\"c.le.s\\t%Z0%2,%1\", DELAY_FCMP, operands, insn);
6194  [(set_attr "type"      "fcmp")
6195   (set_attr "mode"      "FPSW")
6196   (set_attr "length"    "1")])
6200 ;;  ....................
6202 ;;      UNCONDITIONAL BRANCHES
6204 ;;  ....................
6206 ;; Unconditional branches.
6208 (define_insn "jump"
6209   [(set (pc)
6210         (label_ref (match_operand 0 "" "")))]
6211   ""
6212   "*
6214   if (GET_CODE (operands[0]) == REG)
6215     return \"%*j\\t%0\";
6216   /* ??? I don't know why this is necessary.  This works around an
6217      assembler problem that appears when a label is defined, then referenced
6218      in a switch table, then used in a `j' instruction.  */
6219   else if (mips_abi != ABI_32)
6220     return \"%*b\\t%l0\";
6221   else  
6222     return \"%*j\\t%l0\";
6224   [(set_attr "type"     "jump")
6225    (set_attr "mode"     "none")
6226    (set_attr "length"   "1")])
6228 (define_expand "indirect_jump"
6229   [(set (pc) (match_operand 0 "register_operand" "d"))]
6230   ""
6231   "
6233   rtx dest;
6235   if (operands[0])              /* eliminate unused code warnings */
6236     {
6237       dest = operands[0];
6238       if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
6239         operands[0] = copy_to_mode_reg (Pmode, dest);
6241       if (!TARGET_LONG64)
6242         emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
6243       else
6244         emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
6246       DONE;
6247     }
6250 (define_insn "indirect_jump_internal1"
6251   [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
6252   "!TARGET_LONG64"
6253   "%*j\\t%0"
6254   [(set_attr "type"     "jump")
6255    (set_attr "mode"     "none")
6256    (set_attr "length"   "1")])
6258 (define_insn "indirect_jump_internal2"
6259   [(set (pc) (match_operand:DI 0 "se_register_operand" "d"))]
6260   "TARGET_LONG64"
6261   "%*j\\t%0"
6262   [(set_attr "type"     "jump")
6263    (set_attr "mode"     "none")
6264    (set_attr "length"   "1")])
6266 (define_expand "tablejump"
6267   [(set (pc)
6268         (match_operand 0 "register_operand" "d"))
6269    (use (label_ref (match_operand 1 "" "")))]
6270   ""
6271   "
6273   rtx dest;
6275   if (operands[0])              /* eliminate unused code warnings */
6276     {
6277       if (GET_MODE (operands[0]) != Pmode)
6278         abort ();
6280       if (! flag_pic)
6281         {
6282           if (!TARGET_LONG64)
6283             emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
6284           else
6285             emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
6286         }
6287       else
6288         {
6289           if (!TARGET_LONG64)
6290             emit_jump_insn (gen_tablejump_internal3 (operands[0], operands[1]));
6291           else
6292             emit_jump_insn (gen_tablejump_internal4 (operands[0], operands[1]));
6293         }
6295       DONE;
6296     }
6299 (define_insn "tablejump_internal1"
6300   [(set (pc)
6301         (match_operand:SI 0 "register_operand" "d"))
6302    (use (label_ref (match_operand 1 "" "")))]
6303   "!TARGET_LONG64"
6304   "%*j\\t%0"
6305   [(set_attr "type"     "jump")
6306    (set_attr "mode"     "none")
6307    (set_attr "length"   "1")])
6309 (define_insn "tablejump_internal2"
6310   [(set (pc)
6311         (match_operand:DI 0 "se_register_operand" "d"))
6312    (use (label_ref (match_operand 1 "" "")))]
6313   "TARGET_LONG64"
6314   "%*j\\t%0"
6315   [(set_attr "type"     "jump")
6316    (set_attr "mode"     "none")
6317    (set_attr "length"   "1")])
6319 (define_expand "tablejump_internal3"
6320   [(set (pc)
6321         (plus:SI (match_operand:SI 0 "register_operand" "d")
6322                  (label_ref:SI (match_operand:SI 1 "" ""))))]
6323   ""
6324   "")
6326 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC.  Otherwise
6327 ;;; it is not valid.
6329 ;;; ??? The length depends on the ABI.  It is two for o32, and one for n32.
6330 ;;; We just use the conservative number here.
6332 (define_insn ""
6333   [(set (pc)
6334         (plus:SI (match_operand:SI 0 "register_operand" "d")
6335                  (label_ref:SI (match_operand:SI 1 "" ""))))]
6336   "!TARGET_LONG64 && next_active_insn (insn) != 0
6337    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
6338    && PREV_INSN (next_active_insn (insn)) == operands[1]"
6339   "*
6341   /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic.  */
6342   if (mips_abi == ABI_32)
6343     output_asm_insn (\".cpadd\\t%0\", operands);
6344   return \"%*j\\t%0\";
6346   [(set_attr "type"     "jump")
6347    (set_attr "mode"     "none")
6348    (set_attr "length"   "2")])
6350 (define_expand "tablejump_internal4"
6351   [(set (pc)
6352         (plus:DI (match_operand:DI 0 "se_register_operand" "d")
6353                  (label_ref:DI (match_operand:SI 1 "" ""))))]
6354   ""
6355   "")
6357 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC.  Otherwise
6358 ;;; it is not valid.
6360 (define_insn ""
6361   [(set (pc)
6362         (plus:DI (match_operand:DI 0 "se_register_operand" "d")
6363                  (label_ref:DI (match_operand:SI 1 "" ""))))]
6364   "TARGET_LONG64 && next_active_insn (insn) != 0
6365    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
6366    && PREV_INSN (next_active_insn (insn)) == operands[1]"
6367   "%*j\\t%0"
6368   [(set_attr "type"     "jump")
6369    (set_attr "mode"     "none")
6370    (set_attr "length"   "1")])
6372 ;; Implement a switch statement when generating embedded PIC code.
6373 ;; Switches are implemented by `tablejump' when not using -membedded-pic.
6375 (define_expand "casesi"
6376   [(set (match_dup 5)
6377         (minus:SI (match_operand:SI 0 "register_operand" "d")
6378                   (match_operand:SI 1 "arith_operand" "dI")))
6379    (set (cc0)
6380         (compare:CC (match_dup 5)
6381                     (match_operand:SI 2 "arith_operand" "")))
6382    (set (pc)
6383         (if_then_else (gtu (cc0)
6384                            (const_int 0))
6385                       (label_ref (match_operand 4 "" ""))
6386                       (pc)))
6387    (parallel
6388     [(set (pc)
6389           (mem:SI (plus:SI (mult:SI (match_dup 5)
6390                                     (const_int 4))
6391                            (label_ref (match_operand 3 "" "")))))
6392      (clobber (match_scratch:SI 6 ""))
6393      (clobber (reg:SI 31))])]
6394   "TARGET_EMBEDDED_PIC"
6395   "
6397   /* We need slightly different code for eight byte table entries.  */
6398   if (TARGET_LONG64)
6399     abort ();
6401   if (operands[0])
6402     {
6403       rtx reg = gen_reg_rtx (SImode);
6405       /* If the index is too large, go to the default label.  */
6406       emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
6407       emit_insn (gen_cmpsi (reg, operands[2]));
6408       emit_insn (gen_bgtu (operands[4]));
6410       /* Do the PIC jump.  */
6411       emit_insn (gen_casesi_internal (reg, operands[3], gen_reg_rtx (SImode)));
6413       DONE;
6414     }
6417 ;; An embedded PIC switch statement looks like this:
6418 ;;      bal     $LS1
6419 ;;      sll     $reg,$index,2
6420 ;; $LS1:
6421 ;;      addu    $reg,$reg,$31
6422 ;;      lw      $reg,$L1-$LS1($reg)
6423 ;;      addu    $reg,$reg,$31
6424 ;;      j       $reg
6425 ;; $L1:
6426 ;;      .word   case1-$LS1
6427 ;;      .word   case2-$LS1
6428 ;;      ...
6430 (define_insn "casesi_internal"
6431   [(set (pc)
6432         (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
6433                                   (const_int 4))
6434                          (label_ref (match_operand 1 "" "")))))
6435    (clobber (match_operand:SI 2 "register_operand" "d"))
6436    (clobber (reg:SI 31))]
6437   "TARGET_EMBEDDED_PIC"
6438   "*
6440   output_asm_insn (\"%(bal\\t%S1\;sll\\t%0,2\\n%S1:\", operands);
6441   output_asm_insn (\"addu\\t%0,%0,$31%)\", operands);
6442   output_asm_insn (\"lw\\t%0,%1-%S1(%0)\;addu\\t%0,%0,$31\", operands);
6443   return \"j\\t%0\";
6445   [(set_attr "type"     "jump")
6446    (set_attr "mode"     "none")
6447    (set_attr "length"   "6")])
6449 ;; ??? This is a hack to work around a problem with expand_builtin_setjmp.
6450 ;; It restores the frame pointer, and then does a call to restore the global
6451 ;; pointer (gp) register.  The call insn implicitly (via the assembler) reloads
6452 ;; gp from the stack.  However, call insns do not depend on $fp, so it is
6453 ;; possible for the instruction scheduler to move the fp restore after the
6454 ;; call, which then causes gp to be corrupted.  We fix this by emitting a
6455 ;; scheduler barrier.  A better fix is to put code here that restores the
6456 ;; $gp, and then the call is unnecessary.  This is only a problem when PIC
6457 ;; (TARGET_ABICALLS), and only when the gp register is caller-saved
6458 ;; (irix5/o32, but not irix6/n32/n64).
6460 (define_expand "nonlocal_goto_receiver"
6461   [(const_int 0)]
6462   ""
6463   "
6465   emit_insn (gen_blockage ());
6468 ;; For n32/n64, we need to restore gp after a builtin setjmp.   We do this
6469 ;; by making use of the fact that we've just called __dummy.
6470 ;; ??? Note that nothing guarantees that we're *right* after the return, but
6471 ;; we usually are.  There seems to be no way to make that guarantee.
6473 (define_expand "builtin_setjmp_receiver"
6474   [(const_int 0)]
6475   "TARGET_ABICALLS && mips_abi != ABI_32"
6476   "
6478   rtx label = gen_label_rtx ();
6480   emit_label (label);
6481   emit_insn (gen_loadgp (gen_rtx_LABEL_REF (Pmode, label),
6482                          gen_rtx_REG (DImode, 31)));
6483   emit_insn (gen_blockage ());
6487 ;;  ....................
6489 ;;      Function prologue/epilogue
6491 ;;  ....................
6494 (define_expand "prologue"
6495   [(const_int 1)]
6496   ""
6497   "
6499   if (mips_isa >= 0)            /* avoid unused code warnings */
6500     {
6501       mips_expand_prologue ();
6502       DONE;
6503     }
6506 ;; Block any insns from being moved before this point, since the
6507 ;; profiling call to mcount can use various registers that aren't
6508 ;; saved or used to pass arguments.
6510 (define_insn "blockage"
6511   [(unspec_volatile [(const_int 0)] 0)]
6512   ""
6513   ""
6514   [(set_attr "type"     "unknown")
6515    (set_attr "mode"     "none")
6516    (set_attr "length"   "0")])
6518 (define_expand "epilogue"
6519   [(const_int 2)]
6520   ""
6521   "
6523   if (mips_isa >= 0)            /* avoid unused code warnings */
6524     {
6525       mips_expand_epilogue ();
6526       DONE;
6527     }
6530 ;; Trivial return.  Make it look like a normal return insn as that
6531 ;; allows jump optimizations to work better .
6532 (define_insn "return"
6533   [(return)]
6534   "mips_can_use_return_insn ()"
6535   "%*j\\t$31"
6536   [(set_attr "type"     "jump")
6537    (set_attr "mode"     "none")
6538    (set_attr "length"   "1")])
6540 ;; Normal return.
6541 (define_insn "return_internal"
6542   [(use (reg:SI 31))
6543    (return)]
6544   ""
6545   "%*j\\t$31"
6546   [(set_attr "type"     "jump")
6547    (set_attr "mode"     "none")
6548    (set_attr "length"   "1")])
6549   
6550 ;; When generating embedded PIC code we need to get the address of the
6551 ;; current function.  This specialized instruction does just that.
6553 (define_insn "get_fnaddr"
6554   [(set (match_operand 0 "register_operand" "=d")
6555         (unspec [(match_operand 1 "" "")] 1))
6556    (clobber (reg:SI 31))]
6557   "TARGET_EMBEDDED_PIC
6558    && GET_CODE (operands[1]) == SYMBOL_REF"
6559   "%($LF%= = . + 8\;bal\\t$LF%=\;la\\t%0,%1-$LF%=%)\;addu\\t%0,%0,$31"
6560   [(set_attr "type"     "call")
6561    (set_attr "mode"     "none")
6562    (set_attr "length"   "4")])
6566 ;;  ....................
6568 ;;      FUNCTION CALLS
6570 ;;  ....................
6572 ;; calls.c now passes a third argument, make saber happy
6574 (define_expand "call"
6575   [(parallel [(call (match_operand 0 "memory_operand" "m")
6576                     (match_operand 1 "" "i"))
6577               (clobber (reg:SI 31))
6578               (use (match_operand 2 "" ""))             ;; next_arg_reg
6579               (use (match_operand 3 "" ""))])]          ;; struct_value_size_rtx
6580   ""
6581   "
6583   rtx addr;
6585   if (operands[0])              /* eliminate unused code warnings */
6586     {
6587       addr = XEXP (operands[0], 0);
6588       if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
6589           || ! call_insn_operand (addr, VOIDmode))
6590         XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
6592       /* In order to pass small structures by value in registers
6593          compatibly with the MIPS compiler, we need to shift the value
6594          into the high part of the register.  Function_arg has encoded
6595          a PARALLEL rtx, holding a vector of adjustments to be made
6596          as the next_arg_reg variable, so we split up the insns,
6597          and emit them separately.  */
6599       if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL)
6600         {
6601           rtvec adjust = XVEC (operands[2], 0);
6602           int num = GET_NUM_ELEM (adjust);
6603           int i;
6605           for (i = 0; i < num; i++)
6606             emit_insn (RTVEC_ELT (adjust, i));
6607         }
6609       emit_call_insn (gen_call_internal0 (operands[0], operands[1],
6610                                           gen_rtx_REG (SImode,
6611                                                        GP_REG_FIRST + 31)));
6612       DONE;
6613     }
6616 (define_expand "call_internal0"
6617   [(parallel [(call (match_operand 0 "" "")
6618                     (match_operand 1 "" ""))
6619               (clobber (match_operand:SI 2 "" ""))])]
6620   ""
6621   "")
6623 (define_insn "call_internal1"
6624   [(call (mem (match_operand 0 "call_insn_operand" "ri"))
6625          (match_operand 1 "" "i"))
6626    (clobber (match_operand:SI 2 "register_operand" "=d"))]
6627   "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
6628   "*
6630   register rtx target = operands[0];
6632   if (GET_CODE (target) == SYMBOL_REF)
6633     return \"%*jal\\t%0\";
6634   else if (GET_CODE (target) == CONST_INT)
6635     return \"%[li\\t%@,%0\\n\\t%*jal\\t%2,%@%]\";
6636   else
6637     return \"%*jal\\t%2,%0\";
6639   [(set_attr "type"     "call")
6640    (set_attr "mode"     "none")
6641    (set_attr "length"   "1")])
6643 (define_insn "call_internal2"
6644   [(call (mem (match_operand 0 "call_insn_operand" "ri"))
6645          (match_operand 1 "" "i"))
6646    (clobber (match_operand:SI 2 "register_operand" "=d"))]
6647   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
6648   "*
6650   register rtx target = operands[0];
6652   if (GET_CODE (target) == SYMBOL_REF)
6653     {
6654       if (GET_MODE (target) == SImode)
6655         return \"la\\t%^,%0\\n\\tjal\\t%2,%^\";
6656       else
6657         return \"dla\\t%^,%0\\n\\tjal\\t%2,%^\";
6658     }
6659   else if (GET_CODE (target) == CONST_INT)
6660     return \"li\\t%^,%0\\n\\tjal\\t%2,%^\";
6661   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
6662     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
6663   else
6664     return \"jal\\t%2,%0\";
6666   [(set_attr "type"     "call")
6667    (set_attr "mode"     "none")
6668    (set_attr "length"   "2")])
6670 (define_insn "call_internal3a"
6671   [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
6672          (match_operand 1 "" "i"))
6673    (clobber (match_operand:SI 2 "register_operand" "=d"))]
6674   "!TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
6675   "%*jal\\t%2,%0"
6676   [(set_attr "type"     "call")
6677    (set_attr "mode"     "none")
6678    (set_attr "length"   "1")])
6680 (define_insn "call_internal3b"
6681   [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
6682          (match_operand 1 "" "i"))
6683    (clobber (match_operand:SI 2 "register_operand" "=d"))]
6684   "TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
6685   "%*jal\\t%2,%0"
6686   [(set_attr "type"     "call")
6687    (set_attr "mode"     "none")
6688    (set_attr "length"   "1")])
6690 (define_insn "call_internal4a"
6691   [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
6692          (match_operand 1 "" "i"))
6693    (clobber (match_operand:SI 2 "register_operand" "=d"))]
6694   "!TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
6695   "*
6697   if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
6698     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
6699   else
6700     return \"jal\\t%2,%0\";
6702   [(set_attr "type"     "call")
6703    (set_attr "mode"     "none")
6704    (set_attr "length"   "2")])
6706 (define_insn "call_internal4b"
6707   [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r"))
6708          (match_operand 1 "" "i"))
6709    (clobber (match_operand:SI 2 "register_operand" "=d"))]
6710   "TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
6711   "*
6713   if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
6714     return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
6715   else
6716     return \"jal\\t%2,%0\";
6718   [(set_attr "type"     "call")
6719    (set_attr "mode"     "none")
6720    (set_attr "length"   "2")])
6722 ;; calls.c now passes a fourth argument, make saber happy
6724 (define_expand "call_value"
6725   [(parallel [(set (match_operand 0 "register_operand" "=df")
6726                    (call (match_operand 1 "memory_operand" "m")
6727                          (match_operand 2 "" "i")))
6728               (clobber (reg:SI 31))
6729               (use (match_operand 3 "" ""))])]          ;; next_arg_reg
6730   ""
6731   "
6733   rtx addr;
6735   if (operands[0])              /* eliminate unused code warning */
6736     {
6737       addr = XEXP (operands[1], 0);
6738       if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
6739           || ! call_insn_operand (addr, VOIDmode))
6740         XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
6742       /* In order to pass small structures by value in registers
6743          compatibly with the MIPS compiler, we need to shift the value
6744          into the high part of the register.  Function_arg has encoded
6745          a PARALLEL rtx, holding a vector of adjustments to be made
6746          as the next_arg_reg variable, so we split up the insns,
6747          and emit them separately.  */
6749       if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL)
6750         {
6751           rtvec adjust = XVEC (operands[3], 0);
6752           int num = GET_NUM_ELEM (adjust);
6753           int i;
6755           for (i = 0; i < num; i++)
6756             emit_insn (RTVEC_ELT (adjust, i));
6757         }
6759       /* Handle Irix6 function calls that have multiple non-contiguous
6760          results.  */
6761       if (GET_CODE (operands[0]) == PARALLEL && XVECLEN (operands[0], 0) > 1)
6762         {
6763           emit_call_insn (gen_call_value_multiple_internal0
6764                           (XEXP (XVECEXP (operands[0], 0, 0), 0),
6765                            operands[1], operands[2],
6766                            XEXP (XVECEXP (operands[0], 0, 1), 0),
6767                            gen_rtx_REG (SImode, GP_REG_FIRST + 31)));
6768           DONE;
6769         }
6771       /* We have a call returning a DImode structure in an FP reg.
6772          Strip off the now unnecessary PARALLEL.  */
6773       if (GET_CODE (operands[0]) == PARALLEL)
6774         operands[0] = XEXP (XVECEXP (operands[0], 0, 0), 0);
6776       emit_call_insn (gen_call_value_internal0 (operands[0], operands[1], operands[2],
6777                                                 gen_rtx_REG (SImode,
6778                                                              GP_REG_FIRST + 31)));
6780       DONE;
6781     }
6784 (define_expand "call_value_internal0"
6785   [(parallel [(set (match_operand 0 "" "")
6786                    (call (match_operand 1 "" "")
6787                          (match_operand 2 "" "")))
6788               (clobber (match_operand:SI 3 "" ""))])]
6789   ""
6790   "")
6792 (define_insn "call_value_internal1"
6793   [(set (match_operand 0 "register_operand" "=df")
6794         (call (mem (match_operand 1 "call_insn_operand" "ri"))
6795               (match_operand 2 "" "i")))
6796    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6797   "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
6798   "*
6800   register rtx target = operands[1];
6802   if (GET_CODE (target) == SYMBOL_REF)
6803     return \"%*jal\\t%1\";
6804   else if (GET_CODE (target) == CONST_INT)
6805     return \"%[li\\t%@,%1\\n\\t%*jal\\t%3,%@%]\";
6806   else
6807     return \"%*jal\\t%3,%1\";
6809   [(set_attr "type"     "call")
6810    (set_attr "mode"     "none")
6811    (set_attr "length"   "1")])
6813 (define_insn "call_value_internal2"
6814   [(set (match_operand 0 "register_operand" "=df")
6815         (call (mem (match_operand 1 "call_insn_operand" "ri"))
6816               (match_operand 2 "" "i")))
6817    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6818   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
6819   "*
6821   register rtx target = operands[1];
6823   if (GET_CODE (target) == SYMBOL_REF)
6824     {
6825       if (GET_MODE (target) == SImode)
6826         return \"la\\t%^,%1\\n\\tjal\\t%3,%^\";
6827       else
6828         return \"dla\\t%^,%1\\n\\tjal\\t%3,%^\";
6829     }
6830   else if (GET_CODE (target) == CONST_INT)
6831     return \"li\\t%^,%1\\n\\tjal\\t%3,%^\";
6832   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
6833     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
6834   else
6835     return \"jal\\t%3,%1\";
6837   [(set_attr "type"     "call")
6838    (set_attr "mode"     "none")
6839    (set_attr "length"   "2")])
6841 (define_insn "call_value_internal3a"
6842   [(set (match_operand 0 "register_operand" "=df")
6843         (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
6844               (match_operand 2 "" "i")))
6845    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6846   "!TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
6847   "%*jal\\t%3,%1"
6848   [(set_attr "type"     "call")
6849    (set_attr "mode"     "none")
6850    (set_attr "length"   "1")])
6852 (define_insn "call_value_internal3b"
6853   [(set (match_operand 0 "register_operand" "=df")
6854         (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
6855               (match_operand 2 "" "i")))
6856    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6857   "TARGET_LONG64 && !TARGET_ABICALLS && TARGET_LONG_CALLS"
6858   "%*jal\\t%3,%1"
6859   [(set_attr "type"     "call")
6860    (set_attr "mode"     "none")
6861    (set_attr "length"   "1")])
6863 (define_insn "call_value_internal4a"
6864   [(set (match_operand 0 "register_operand" "=df")
6865         (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
6866               (match_operand 2 "" "i")))
6867    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6868   "!TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
6869   "*
6871   if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
6872     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
6873   else
6874     return \"jal\\t%3,%1\";
6876   [(set_attr "type"     "call")
6877    (set_attr "mode"     "none")
6878    (set_attr "length"   "2")])
6880 (define_insn "call_value_internal4b"
6881   [(set (match_operand 0 "register_operand" "=df")
6882         (call (mem:DI (match_operand:DI 1 "se_register_operand" "r"))
6883               (match_operand 2 "" "i")))
6884    (clobber (match_operand:SI 3 "register_operand" "=d"))]
6885   "TARGET_LONG64 && TARGET_ABICALLS && TARGET_LONG_CALLS"
6886   "*
6888   if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
6889     return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
6890   else
6891     return \"jal\\t%3,%1\";
6893   [(set_attr "type"     "call")
6894    (set_attr "mode"     "none")
6895    (set_attr "length"   "2")])
6897 (define_expand "call_value_multiple_internal0"
6898   [(parallel [(set (match_operand 0 "" "")
6899                    (call (match_operand 1 "" "")
6900                          (match_operand 2 "" "")))
6901               (set (match_operand 3 "" "")
6902                    (call (match_dup 1)
6903                          (match_dup 2)))
6904               (clobber (match_operand:SI 4 "" ""))])]
6905   ""
6906   "")
6908 ;; ??? May eventually need all 6 versions of the call patterns with multiple
6909 ;; return values.
6911 (define_insn "call_value_multiple_internal2"
6912   [(set (match_operand 0 "register_operand" "=df")
6913         (call (mem (match_operand 1 "call_insn_operand" "ri"))
6914               (match_operand 2 "" "i")))
6915    (set (match_operand 3 "register_operand" "=df")
6916         (call (mem (match_dup 1))
6917               (match_dup 2)))
6918    (clobber (match_operand:SI 4 "register_operand" "=d"))]
6919   "TARGET_ABICALLS && !TARGET_LONG_CALLS"
6920   "*
6922   register rtx target = operands[1];
6924   if (GET_CODE (target) == SYMBOL_REF)
6925     {
6926       if (GET_MODE (target) == SImode)
6927         return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
6928       else
6929         return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
6930     }
6931   else if (GET_CODE (target) == CONST_INT)
6932     return \"li\\t%^,%1\\n\\tjal\\t%4,%^\";
6933   else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
6934     return \"move\\t%^,%1\\n\\tjal\\t%4,%^\";
6935   else
6936     return \"jal\\t%4,%1\";
6938   [(set_attr "type"     "call")
6939    (set_attr "mode"     "none")
6940    (set_attr "length"   "2")])
6943 ;; Call subroutine returning any type.
6945 (define_expand "untyped_call"
6946   [(parallel [(call (match_operand 0 "" "")
6947                     (const_int 0))
6948               (match_operand 1 "" "")
6949               (match_operand 2 "" "")])]
6950   ""
6951   "
6953   if (operands[0])              /* silence statement not reached warnings */
6954     {
6955       int i;
6957       emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
6959       for (i = 0; i < XVECLEN (operands[2], 0); i++)
6960         {
6961           rtx set = XVECEXP (operands[2], 0, i);
6962           emit_move_insn (SET_DEST (set), SET_SRC (set));
6963         }
6965       emit_insn (gen_blockage ());
6966       DONE;
6967     }
6971 ;;  ....................
6973 ;;      MISC.
6975 ;;  ....................
6978 (define_insn "nop"
6979   [(const_int 0)]
6980   ""
6981   "%(nop%)"
6982   [(set_attr "type"     "nop")
6983    (set_attr "mode"     "none")
6984    (set_attr "length"   "1")])
6986 ;; The MIPS chip does not seem to require stack probes.
6988 ;; (define_expand "probe"
6989 ;;   [(set (match_dup 0)
6990 ;;      (match_dup 1))]
6991 ;;   ""
6992 ;;   "
6993 ;; {
6994 ;;   operands[0] = gen_reg_rtx (SImode);
6995 ;;   operands[1] = gen_rtx_MEM (SImode, stack_pointer_rtx);
6996 ;;   MEM_VOLATILE_P (operands[1]) = TRUE;
6997 ;; 
6998 ;;   /* fall through and generate default code */
6999 ;; }")
7003 ;; MIPS4 Conditional move instructions.
7005 (define_insn ""
7006   [(set (match_operand:SI 0 "register_operand" "=d,d")
7007         (if_then_else:SI
7008          (match_operator 4 "equality_op"
7009                          [(match_operand:SI 1 "register_operand" "d,d")
7010                           (const_int 0)])
7011          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
7012          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
7013   "mips_isa >= 4"
7014   "@
7015     mov%B4\\t%0,%z2,%1
7016     mov%b4\\t%0,%z3,%1"
7017   [(set_attr "type" "move")
7018    (set_attr "mode" "SI")])
7020 (define_insn ""
7021   [(set (match_operand:SI 0 "register_operand" "=d,d")
7022         (if_then_else:SI
7023          (match_operator 4 "equality_op"
7024                          [(match_operand:DI 1 "se_register_operand" "d,d")
7025                           (const_int 0)])
7026          (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
7027          (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
7028   "mips_isa >= 4"
7029   "@
7030     mov%B4\\t%0,%z2,%1
7031     mov%b4\\t%0,%z3,%1"
7032   [(set_attr "type" "move")
7033    (set_attr "mode" "SI")])
7035 (define_insn ""
7036   [(set (match_operand:SI 0 "register_operand" "=d,d")
7037         (if_then_else:SI
7038          (match_operator 3 "equality_op" [(match_operand:CC 4
7039                                                             "register_operand"
7040                                                             "z,z")
7041                                           (const_int 0)])
7042          (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
7043          (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
7044   "mips_isa >= 4 && TARGET_HARD_FLOAT"
7045   "@
7046     mov%T3\\t%0,%z1,%4
7047     mov%t3\\t%0,%z2,%4"
7048   [(set_attr "type" "move")
7049    (set_attr "mode" "SI")])
7051 (define_insn ""
7052   [(set (match_operand:DI 0 "register_operand" "=d,d")
7053         (if_then_else:DI
7054          (match_operator 4 "equality_op"
7055                          [(match_operand:SI 1 "register_operand" "d,d")
7056                           (const_int 0)])
7057          (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
7058          (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
7059   "mips_isa >= 4"
7060   "@
7061     mov%B4\\t%0,%z2,%1
7062     mov%b4\\t%0,%z3,%1"
7063   [(set_attr "type" "move")
7064    (set_attr "mode" "DI")])
7066 (define_insn ""
7067   [(set (match_operand:DI 0 "register_operand" "=d,d")
7068         (if_then_else:DI
7069          (match_operator 4 "equality_op"
7070                          [(match_operand:DI 1 "se_register_operand" "d,d")
7071                           (const_int 0)])
7072          (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0")
7073          (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))]
7074   "mips_isa >= 4"
7075   "@
7076     mov%B4\\t%0,%z2,%1
7077     mov%b4\\t%0,%z3,%1"
7078   [(set_attr "type" "move")
7079    (set_attr "mode" "DI")])
7081 (define_insn ""
7082   [(set (match_operand:DI 0 "register_operand" "=d,d")
7083         (if_then_else:DI
7084          (match_operator 3 "equality_op" [(match_operand:CC 4
7085                                                             "register_operand"
7086                                                             "z,z")
7087                                           (const_int 0)])
7088          (match_operand:DI 1 "se_reg_or_0_operand" "dJ,0")
7089          (match_operand:DI 2 "se_reg_or_0_operand" "0,dJ")))]
7090   "mips_isa >= 4 && TARGET_HARD_FLOAT"
7091   "@
7092     mov%T3\\t%0,%z1,%4
7093     mov%t3\\t%0,%z2,%4"
7094   [(set_attr "type" "move")
7095    (set_attr "mode" "DI")])
7097 (define_insn ""
7098   [(set (match_operand:SF 0 "register_operand" "=f,f")
7099         (if_then_else:SF
7100          (match_operator 4 "equality_op"
7101                          [(match_operand:SI 1 "register_operand" "d,d")
7102                           (const_int 0)])
7103          (match_operand:SF 2 "register_operand" "f,0")
7104          (match_operand:SF 3 "register_operand" "0,f")))]
7105   "mips_isa >= 4 && TARGET_HARD_FLOAT"
7106   "@
7107     mov%B4.s\\t%0,%2,%1
7108     mov%b4.s\\t%0,%3,%1"
7109   [(set_attr "type" "move")
7110    (set_attr "mode" "SF")])
7112 (define_insn ""
7113   [(set (match_operand:SF 0 "register_operand" "=f,f")
7114         (if_then_else:SF
7115          (match_operator 3 "equality_op" [(match_operand:CC 4
7116                                                             "register_operand"
7117                                                             "z,z")
7118                                           (const_int 0)])
7119          (match_operand:SF 1 "register_operand" "f,0")
7120          (match_operand:SF 2 "register_operand" "0,f")))]
7121   "mips_isa >= 4 && TARGET_HARD_FLOAT"
7122   "@
7123     mov%T3.s\\t%0,%1,%4
7124     mov%t3.s\\t%0,%2,%4"
7125   [(set_attr "type" "move")
7126    (set_attr "mode" "SF")])
7128 (define_insn ""
7129   [(set (match_operand:DF 0 "register_operand" "=f,f")
7130         (if_then_else:DF
7131          (match_operator 4 "equality_op"
7132                          [(match_operand:SI 1 "register_operand" "d,d")
7133                           (const_int 0)])
7134          (match_operand:DF 2 "register_operand" "f,0")
7135          (match_operand:DF 3 "register_operand" "0,f")))]
7136   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7137   "@
7138     mov%B4.d\\t%0,%2,%1
7139     mov%b4.d\\t%0,%3,%1"
7140   [(set_attr "type" "move")
7141    (set_attr "mode" "DF")])
7143 (define_insn ""
7144   [(set (match_operand:DF 0 "register_operand" "=f,f")
7145         (if_then_else:DF
7146          (match_operator 3 "equality_op" [(match_operand:CC 4
7147                                                             "register_operand"
7148                                                             "z,z")
7149                                           (const_int 0)])
7150          (match_operand:DF 1 "register_operand" "f,0")
7151          (match_operand:DF 2 "register_operand" "0,f")))]
7152   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7153   "@
7154     mov%T3.d\\t%0,%1,%4
7155     mov%t3.d\\t%0,%2,%4"
7156   [(set_attr "type" "move")
7157    (set_attr "mode" "DF")])
7159 ;; These are the main define_expand's used to make conditional moves.
7161 (define_expand "movsicc"
7162   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
7163    (set (match_operand:SI 0 "register_operand" "")
7164         (if_then_else:SI (match_dup 5)
7165                          (match_operand:SI 2 "reg_or_0_operand" "")
7166                          (match_operand:SI 3 "reg_or_0_operand" "")))]
7167   "mips_isa >= 4"
7168   "
7170   gen_conditional_move (operands);
7171   DONE;
7174 (define_expand "movdicc"
7175   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
7176    (set (match_operand:DI 0 "register_operand" "")
7177         (if_then_else:DI (match_dup 5)
7178                          (match_operand:DI 2 "se_reg_or_0_operand" "")
7179                          (match_operand:DI 3 "se_reg_or_0_operand" "")))]
7180   "mips_isa >= 4"
7181   "
7183   gen_conditional_move (operands);
7184   DONE;
7187 (define_expand "movsfcc"
7188   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
7189    (set (match_operand:SF 0 "register_operand" "")
7190         (if_then_else:SF (match_dup 5)
7191                          (match_operand:SF 2 "register_operand" "")
7192                          (match_operand:SF 3 "register_operand" "")))]
7193   "mips_isa >= 4 && TARGET_HARD_FLOAT"
7194   "
7196   gen_conditional_move (operands);
7197   DONE;
7200 (define_expand "movdfcc"
7201   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
7202    (set (match_operand:DF 0 "register_operand" "")
7203         (if_then_else:DF (match_dup 5)
7204                          (match_operand:DF 2 "register_operand" "")
7205                          (match_operand:DF 3 "register_operand" "")))]
7206   "mips_isa >= 4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7207   "
7209   gen_conditional_move (operands);
7210   DONE;