OSDN Git Service

54bc7c3e251e274efb5263de8b44da86de4eb701
[pf3gnuchains/gcc-fork.git] / gcc / config / mips / mips.md
1 ;;  Mips.md          Machine Description for MIPS based processors
2 ;;  Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;;  1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 ;;  Contributed by   A. Lichnewsky, lich@inria.inria.fr
5 ;;  Changes by       Michael Meissner, meissner@osf.org
6 ;;  64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
7 ;;  Brendan Eich, brendan@microunity.com.
8
9 ;; This file is part of GCC.
10
11 ;; GCC is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; any later version.
15
16 ;; GCC is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;; GNU General Public License for more details.
20
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING.  If not, write to
23 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.
25
26 (define_constants
27   [(UNSPEC_LOAD_DF_LOW           0)
28    (UNSPEC_LOAD_DF_HIGH          1)
29    (UNSPEC_STORE_DF_HIGH         2)
30    (UNSPEC_GET_FNADDR            3)
31    (UNSPEC_BLOCKAGE              4)
32    (UNSPEC_CPRESTORE             5)
33    (UNSPEC_EH_RECEIVER           6)
34    (UNSPEC_EH_RETURN             7)
35    (UNSPEC_CONSTTABLE_INT        8)
36    (UNSPEC_CONSTTABLE_FLOAT      9)
37    (UNSPEC_ALIGN                14)
38    (UNSPEC_HIGH                 17)
39    (UNSPEC_LOAD_LEFT            18)
40    (UNSPEC_LOAD_RIGHT           19)
41    (UNSPEC_STORE_LEFT           20)
42    (UNSPEC_STORE_RIGHT          21)
43    (UNSPEC_LOADGP               22)
44    (UNSPEC_LOAD_CALL            23)
45    (UNSPEC_LOAD_GOT             24)
46    (UNSPEC_GP                   25)
47    (UNSPEC_MFHILO               26)
48
49    (UNSPEC_ADDRESS_FIRST        100)
50
51    (FAKE_CALL_REGNO             79)
52
53    ;; For MIPS Paired-Singled Floating Point Instructions.
54
55    (UNSPEC_MOVE_TF_PS           200)
56    (UNSPEC_C                    201)
57
58    ;; MIPS64/MIPS32R2 alnv.ps
59    (UNSPEC_ALNV_PS              202)
60
61    ;; MIPS-3D instructions
62    (UNSPEC_CABS                 203)
63
64    (UNSPEC_ADDR_PS              204)
65    (UNSPEC_CVT_PW_PS            205)
66    (UNSPEC_CVT_PS_PW            206)
67    (UNSPEC_MULR_PS              207)
68
69    (UNSPEC_RSQRT1               208)
70    (UNSPEC_RSQRT2               209)
71    (UNSPEC_RECIP1               210)
72    (UNSPEC_RECIP2               211)
73   ]
74 )
75
76 (include "predicates.md")
77 \f
78 ;; ....................
79 ;;
80 ;;      Attributes
81 ;;
82 ;; ....................
83
84 (define_attr "got" "unset,xgot_high,load"
85   (const_string "unset"))
86
87 ;; For jal instructions, this attribute is DIRECT when the target address
88 ;; is symbolic and INDIRECT when it is a register.
89 (define_attr "jal" "unset,direct,indirect"
90   (const_string "unset"))
91
92 ;; This attribute is YES if the instruction is a jal macro (not a
93 ;; real jal instruction).
94 ;;
95 ;; jal is always a macro in SVR4 PIC since it includes an instruction to
96 ;; restore $gp.  Direct jals are also macros in NewABI PIC since they
97 ;; load the target address into $25.
98 (define_attr "jal_macro" "no,yes"
99   (cond [(eq_attr "jal" "direct")
100          (symbol_ref "TARGET_ABICALLS != 0")
101          (eq_attr "jal" "indirect")
102          (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")]
103         (const_string "no")))
104
105 ;; Classification of each insn.
106 ;; branch       conditional branch
107 ;; jump         unconditional jump
108 ;; call         unconditional call
109 ;; load         load instruction(s)
110 ;; fpload       floating point load
111 ;; fpidxload    floating point indexed load
112 ;; store        store instruction(s)
113 ;; fpstore      floating point store
114 ;; fpidxstore   floating point indexed store
115 ;; prefetch     memory prefetch (register + offset)
116 ;; prefetchx    memory indexed prefetch (register + register)
117 ;; condmove     conditional moves
118 ;; xfer         transfer to/from coprocessor
119 ;; mthilo       transfer to hi/lo registers
120 ;; mfhilo       transfer from hi/lo registers
121 ;; const        load constant
122 ;; arith        integer arithmetic and logical instructions
123 ;; shift        integer shift instructions
124 ;; slt          set less than instructions
125 ;; clz          the clz and clo instructions
126 ;; trap         trap if instructions
127 ;; imul         integer multiply
128 ;; imadd        integer multiply-add
129 ;; idiv         integer divide
130 ;; fmove        floating point register move
131 ;; fadd         floating point add/subtract
132 ;; fmul         floating point multiply
133 ;; fmadd        floating point multiply-add
134 ;; fdiv         floating point divide
135 ;; frdiv        floating point reciprocal divide
136 ;; frdiv1       floating point reciprocal divide step 1
137 ;; frdiv2       floating point reciprocal divide step 2
138 ;; fabs         floating point absolute value
139 ;; fneg         floating point negation
140 ;; fcmp         floating point compare
141 ;; fcvt         floating point convert
142 ;; fsqrt        floating point square root
143 ;; frsqrt       floating point reciprocal square root
144 ;; frsqrt1      floating point reciprocal square root step1
145 ;; frsqrt2      floating point reciprocal square root step2
146 ;; multi        multiword sequence (or user asm statements)
147 ;; nop          no operation
148 (define_attr "type"
149   "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,xfer,mthilo,mfhilo,const,arith,shift,slt,clz,trap,imul,imadd,idiv,fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,frsqrt1,frsqrt2,multi,nop"
150   (cond [(eq_attr "jal" "!unset") (const_string "call")
151          (eq_attr "got" "load") (const_string "load")]
152         (const_string "unknown")))
153
154 ;; Main data type used by the insn
155 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
156   (const_string "unknown"))
157
158 ;; Is this an extended instruction in mips16 mode?
159 (define_attr "extended_mips16" "no,yes"
160   (const_string "no"))
161
162 ;; Length of instruction in bytes.
163 (define_attr "length" ""
164    (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
165           ;; If a branch is outside this range, we have a choice of two
166           ;; sequences.  For PIC, an out-of-range branch like:
167           ;;
168           ;;    bne     r1,r2,target
169           ;;    dslot
170           ;;
171           ;; becomes the equivalent of:
172           ;;
173           ;;    beq     r1,r2,1f
174           ;;    dslot
175           ;;    la      $at,target
176           ;;    jr      $at
177           ;;    nop
178           ;; 1:
179           ;;
180           ;; where the load address can be up to three instructions long
181           ;; (lw, nop, addiu).
182           ;;
183           ;; The non-PIC case is similar except that we use a direct
184           ;; jump instead of an la/jr pair.  Since the target of this
185           ;; jump is an absolute 28-bit bit address (the other bits
186           ;; coming from the address of the delay slot) this form cannot
187           ;; cross a 256MB boundary.  We could provide the option of
188           ;; using la/jr in this case too, but we do not do so at
189           ;; present.
190           ;;
191           ;; Note that this value does not account for the delay slot
192           ;; instruction, whose length is added separately.  If the RTL
193           ;; pattern has no explicit delay slot, mips_adjust_insn_length
194           ;; will add the length of the implicit nop.  The values for
195           ;; forward and backward branches will be different as well.
196           (eq_attr "type" "branch")
197           (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
198                       (le (minus (pc) (match_dup 1)) (const_int 131068)))
199                   (const_int 4)
200                  (ne (symbol_ref "flag_pic") (const_int 0))
201                  (const_int 24)
202                  ] (const_int 12))
203
204           (eq_attr "got" "load")
205           (const_int 4)
206           (eq_attr "got" "xgot_high")
207           (const_int 8)
208
209           (eq_attr "type" "const")
210           (symbol_ref "mips_const_insns (operands[1]) * 4")
211           (eq_attr "type" "load,fpload")
212           (symbol_ref "mips_fetch_insns (operands[1]) * 4")
213           (eq_attr "type" "store,fpstore")
214           (symbol_ref "mips_fetch_insns (operands[0]) * 4")
215
216           ;; In the worst case, a call macro will take 8 instructions:
217           ;;
218           ;;     lui $25,%call_hi(FOO)
219           ;;     addu $25,$25,$28
220           ;;     lw $25,%call_lo(FOO)($25)
221           ;;     nop
222           ;;     jalr $25
223           ;;     nop
224           ;;     lw $gp,X($sp)
225           ;;     nop
226           (eq_attr "jal_macro" "yes")
227           (const_int 32)
228
229           (and (eq_attr "extended_mips16" "yes")
230                (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
231           (const_int 8)
232
233           ;; Various VR4120 errata require a nop to be inserted after a macc
234           ;; instruction.  The assembler does this for us, so account for
235           ;; the worst-case length here.
236           (and (eq_attr "type" "imadd")
237                (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
238           (const_int 8)
239
240           ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
241           ;; the result of the second one is missed.  The assembler should work
242           ;; around this by inserting a nop after the first dmult.
243           (and (eq_attr "type" "imul")
244                (and (eq_attr "mode" "DI")
245                     (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
246           (const_int 8)
247
248           (eq_attr "type" "idiv")
249           (symbol_ref "mips_idiv_insns () * 4")
250           ] (const_int 4)))
251
252 ;; Attribute describing the processor.  This attribute must match exactly
253 ;; with the processor_type enumeration in mips.h.
254 (define_attr "cpu"
255   "default,4kc,5kc,20kc,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sr71000"
256   (const (symbol_ref "mips_tune")))
257
258 ;; The type of hardware hazard associated with this instruction.
259 ;; DELAY means that the next instruction cannot read the result
260 ;; of this one.  HILO means that the next two instructions cannot
261 ;; write to HI or LO.
262 (define_attr "hazard" "none,delay,hilo"
263   (cond [(and (eq_attr "type" "load,fpload,fpidxload")
264               (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
265          (const_string "delay")
266
267          (and (eq_attr "type" "xfer")
268               (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
269          (const_string "delay")
270
271          (and (eq_attr "type" "fcmp")
272               (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
273          (const_string "delay")
274
275          ;; The r4000 multiplication patterns include an mflo instruction.
276          (and (eq_attr "type" "imul")
277               (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0)))
278          (const_string "hilo")
279
280          (and (eq_attr "type" "mfhilo")
281               (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)))
282          (const_string "hilo")]
283         (const_string "none")))
284
285 ;; Is it a single instruction?
286 (define_attr "single_insn" "no,yes"
287   (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
288
289 ;; Can the instruction be put into a delay slot?
290 (define_attr "can_delay" "no,yes"
291   (if_then_else (and (eq_attr "type" "!branch,call,jump")
292                      (and (eq_attr "hazard" "none")
293                           (eq_attr "single_insn" "yes")))
294                 (const_string "yes")
295                 (const_string "no")))
296
297 ;; Attribute defining whether or not we can use the branch-likely instructions
298 (define_attr "branch_likely" "no,yes"
299   (const
300    (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
301                  (const_string "yes")
302                  (const_string "no"))))
303
304 ;; True if an instruction might assign to hi or lo when reloaded.
305 ;; This is used by the TUNE_MACC_CHAINS code.
306 (define_attr "may_clobber_hilo" "no,yes"
307   (if_then_else (eq_attr "type" "imul,imadd,idiv,mthilo")
308                 (const_string "yes")
309                 (const_string "no")))
310
311 ;; Describe a user's asm statement.
312 (define_asm_attributes
313   [(set_attr "type" "multi")])
314 \f
315 ;; This mode macro allows 32-bit and 64-bit GPR patterns to be generated
316 ;; from the same template.
317 (define_mode_macro GPR [SI (DI "TARGET_64BIT")])
318
319 ;; This mode macro allows :P to be used for patterns that operate on
320 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
321 (define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
322
323 ;; This mode macro allows :MOVECC to be used anywhere that a
324 ;; conditional-move-type condition is needed.
325 (define_mode_macro MOVECC [SI (DI "TARGET_64BIT") (CC "TARGET_HARD_FLOAT")])
326
327 ;; This mode macro allows :ANYF to be used wherever a scalar or vector
328 ;; floating-point mode is allowed.
329 (define_mode_macro ANYF [(SF "TARGET_HARD_FLOAT")
330                          (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
331                          (V2SF "TARGET_PAIRED_SINGLE_FLOAT")])
332
333 ;; Like ANYF, but only applies to scalar modes.
334 (define_mode_macro SCALARF [(SF "TARGET_HARD_FLOAT")
335                             (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")])
336
337 ;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
338 ;; 32-bit version and "dsubu" in the 64-bit version.
339 (define_mode_attr d [(SI "") (DI "d")])
340
341 ;; Mode attributes for GPR loads and stores.
342 (define_mode_attr load [(SI "lw") (DI "ld")])
343 (define_mode_attr store [(SI "sw") (DI "sd")])
344
345 ;; Similarly for MIPS IV indexed FPR loads and stores.
346 (define_mode_attr loadx [(SF "lwxc1") (DF "ldxc1")])
347 (define_mode_attr storex [(SF "swxc1") (DF "sdxc1")])
348
349 ;; The unextended ranges of the MIPS16 addiu and daddiu instructions
350 ;; are different.  Some forms of unextended addiu have an 8-bit immediate
351 ;; field but the equivalent daddiu has only a 5-bit field.
352 (define_mode_attr si8_di5 [(SI "8") (DI "5")])
353
354 ;; This attribute gives the best constraint to use for registers of
355 ;; a given mode.
356 (define_mode_attr reg [(SI "d") (DI "d") (CC "z")])
357
358 ;; This attribute gives the format suffix for floating-point operations.
359 (define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")])
360
361 ;; This attribute gives the upper-case mode name for one unit of a
362 ;; floating-point mode.
363 (define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")])
364
365 ;; This attribute works around the early SB-1 rev2 core "F2" erratum:
366 ;;
367 ;; In certain cases, div.s and div.ps may have a rounding error
368 ;; and/or wrong inexact flag.
369 ;;
370 ;; Therefore, we only allow div.s if not working around SB-1 rev2
371 ;; errata or if a slight loss of precision is OK.
372 (define_mode_attr divide_condition
373   [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations")])
374
375 ;; This code macro allows all branch instructions to be generated from
376 ;; a single define_expand template.
377 (define_code_macro any_cond [unordered ordered unlt unge uneq ltgt unle ungt
378                              eq ne gt ge lt le gtu geu ltu leu])
379
380 ;; This code macro allows signed and unsigned widening multiplications
381 ;; to use the same template.
382 (define_code_macro any_extend [sign_extend zero_extend])
383
384 ;; This code macro allows the three shift instructions to be generated
385 ;; from the same template.
386 (define_code_macro any_shift [ashift ashiftrt lshiftrt])
387
388 ;; This code macro allows all native floating-point comparisons to be
389 ;; generated from the same template.
390 (define_code_macro fcond [unordered uneq unlt unle eq lt le])
391
392 ;; <u> expands to an empty string when doing a signed operation and
393 ;; "u" when doing an unsigned operation.
394 (define_code_attr u [(sign_extend "") (zero_extend "u")])
395
396 ;; <su> is like <u>, but the signed form expands to "s" rather than "".
397 (define_code_attr su [(sign_extend "s") (zero_extend "u")])
398
399 ;; <optab> expands to the name of the optab for a particular code.
400 (define_code_attr optab [(ashift "ashl")
401                          (ashiftrt "ashr")
402                          (lshiftrt "lshr")])
403
404 ;; <insn> expands to the name of the insn that implements a particular code.
405 (define_code_attr insn [(ashift "sll")
406                         (ashiftrt "sra")
407                         (lshiftrt "srl")])
408
409 ;; <fcond> is the c.cond.fmt condition associated with a particular code.
410 (define_code_attr fcond [(unordered "un")
411                          (uneq "ueq")
412                          (unlt "ult")
413                          (unle "ule")
414                          (eq "eq")
415                          (lt "lt")
416                          (le "le")])
417 \f
418 ;; .........................
419 ;;
420 ;;      Branch, call and jump delay slots
421 ;;
422 ;; .........................
423
424 (define_delay (and (eq_attr "type" "branch")
425                    (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
426   [(eq_attr "can_delay" "yes")
427    (nil)
428    (and (eq_attr "branch_likely" "yes")
429         (eq_attr "can_delay" "yes"))])
430
431 (define_delay (eq_attr "type" "jump")
432   [(eq_attr "can_delay" "yes")
433    (nil)
434    (nil)])
435
436 (define_delay (and (eq_attr "type" "call")
437                    (eq_attr "jal_macro" "no"))
438   [(eq_attr "can_delay" "yes")
439    (nil)
440    (nil)])
441 \f
442 ;; Pipeline descriptions.
443 ;;
444 ;; generic.md provides a fallback for processors without a specific
445 ;; pipeline description.  It is derived from the old define_function_unit
446 ;; version and uses the "alu" and "imuldiv" units declared below.
447 ;;
448 ;; Some of the processor-specific files are also derived from old
449 ;; define_function_unit descriptions and simply override the parts of
450 ;; generic.md that don't apply.  The other processor-specific files
451 ;; are self-contained.
452 (define_automaton "alu,imuldiv")
453
454 (define_cpu_unit "alu" "alu")
455 (define_cpu_unit "imuldiv" "imuldiv")
456
457 (include "3000.md")
458 (include "4000.md")
459 (include "4100.md")
460 (include "4130.md")
461 (include "4300.md")
462 (include "4600.md")
463 (include "5000.md")
464 (include "5400.md")
465 (include "5500.md")
466 (include "6000.md")
467 (include "7000.md")
468 (include "9000.md")
469 (include "sb1.md")
470 (include "sr71k.md")
471 (include "generic.md")
472 \f
473 ;;
474 ;;  ....................
475 ;;
476 ;;      CONDITIONAL TRAPS
477 ;;
478 ;;  ....................
479 ;;
480
481 (define_insn "trap"
482   [(trap_if (const_int 1) (const_int 0))]
483   ""
484 {
485   if (ISA_HAS_COND_TRAP)
486     return "teq\t$0,$0";
487   else if (TARGET_MIPS16)
488     return "break 0";
489   else
490     return "break";
491 }
492   [(set_attr "type" "trap")])
493
494 (define_expand "conditional_trap"
495   [(trap_if (match_operator 0 "comparison_operator"
496                             [(match_dup 2) (match_dup 3)])
497             (match_operand 1 "const_int_operand"))]
498   "ISA_HAS_COND_TRAP"
499 {
500   if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) == MODE_INT
501       && operands[1] == const0_rtx)
502     {
503       mips_gen_conditional_trap (operands);
504       DONE;
505     }
506   else
507     FAIL;
508 })
509
510 (define_insn "*conditional_trap<mode>"
511   [(trap_if (match_operator:GPR 0 "trap_comparison_operator"
512                                 [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
513                                  (match_operand:GPR 2 "arith_operand" "dI")])
514             (const_int 0))]
515   "ISA_HAS_COND_TRAP"
516   "t%C0\t%z1,%2"
517   [(set_attr "type" "trap")])
518 \f
519 ;;
520 ;;  ....................
521 ;;
522 ;;      ADDITION
523 ;;
524 ;;  ....................
525 ;;
526
527 (define_insn "add<mode>3"
528   [(set (match_operand:ANYF 0 "register_operand" "=f")
529         (plus:ANYF (match_operand:ANYF 1 "register_operand" "f")
530                    (match_operand:ANYF 2 "register_operand" "f")))]
531   ""
532   "add.<fmt>\t%0,%1,%2"
533   [(set_attr "type" "fadd")
534    (set_attr "mode" "<UNITMODE>")])
535
536 (define_expand "add<mode>3"
537   [(set (match_operand:GPR 0 "register_operand")
538         (plus:GPR (match_operand:GPR 1 "register_operand")
539                   (match_operand:GPR 2 "arith_operand")))]
540   "")
541
542 (define_insn "*add<mode>3"
543   [(set (match_operand:GPR 0 "register_operand" "=d,d")
544         (plus:GPR (match_operand:GPR 1 "register_operand" "d,d")
545                   (match_operand:GPR 2 "arith_operand" "d,Q")))]
546   "!TARGET_MIPS16"
547   "@
548     <d>addu\t%0,%1,%2
549     <d>addiu\t%0,%1,%2"
550   [(set_attr "type" "arith")
551    (set_attr "mode" "<MODE>")])
552
553 ;; We need to recognize MIPS16 stack pointer additions explicitly, since
554 ;; we don't have a constraint for $sp.  These insns will be generated by
555 ;; the save_restore_insns functions.
556
557 (define_insn "*add<mode>3_sp1"
558   [(set (reg:GPR 29)
559         (plus:GPR (reg:GPR 29)
560                   (match_operand:GPR 0 "const_arith_operand" "")))]
561   "TARGET_MIPS16"
562   "<d>addiu\t%$,%$,%0"
563   [(set_attr "type" "arith")
564    (set_attr "mode" "<MODE>")
565    (set (attr "length") (if_then_else (match_operand 0 "m16_simm8_8")
566                                       (const_int 4)
567                                       (const_int 8)))])
568
569 (define_insn "*add<mode>3_sp2"
570   [(set (match_operand:GPR 0 "register_operand" "=d")
571         (plus:GPR (reg:GPR 29)
572                   (match_operand:GPR 1 "const_arith_operand" "")))]
573   "TARGET_MIPS16"
574   "<d>addiu\t%0,%$,%1"
575   [(set_attr "type" "arith")
576    (set_attr "mode" "<MODE>")
577    (set (attr "length") (if_then_else (match_operand 1 "m16_uimm<si8_di5>_4")
578                                       (const_int 4)
579                                       (const_int 8)))])
580
581 (define_insn "*add<mode>3_mips16"
582   [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
583         (plus:GPR (match_operand:GPR 1 "register_operand" "0,d,d")
584                   (match_operand:GPR 2 "arith_operand" "Q,O,d")))]
585   "TARGET_MIPS16"
586   "@
587     <d>addiu\t%0,%2
588     <d>addiu\t%0,%1,%2
589     <d>addu\t%0,%1,%2"
590   [(set_attr "type" "arith")
591    (set_attr "mode" "<MODE>")
592    (set_attr_alternative "length"
593                 [(if_then_else (match_operand 2 "m16_simm<si8_di5>_1")
594                                (const_int 4)
595                                (const_int 8))
596                  (if_then_else (match_operand 2 "m16_simm4_1")
597                                (const_int 4)
598                                (const_int 8))
599                  (const_int 4)])])
600
601
602 ;; On the mips16, we can sometimes split an add of a constant which is
603 ;; a 4 byte instruction into two adds which are both 2 byte
604 ;; instructions.  There are two cases: one where we are adding a
605 ;; constant plus a register to another register, and one where we are
606 ;; simply adding a constant to a register.
607
608 (define_split
609   [(set (match_operand:SI 0 "register_operand")
610         (plus:SI (match_dup 0)
611                  (match_operand:SI 1 "const_int_operand")))]
612   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
613    && GET_CODE (operands[0]) == REG
614    && M16_REG_P (REGNO (operands[0]))
615    && GET_CODE (operands[1]) == CONST_INT
616    && ((INTVAL (operands[1]) > 0x7f
617         && INTVAL (operands[1]) <= 0x7f + 0x7f)
618        || (INTVAL (operands[1]) < - 0x80
619            && INTVAL (operands[1]) >= - 0x80 - 0x80))"
620   [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
621    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
622 {
623   HOST_WIDE_INT val = INTVAL (operands[1]);
624
625   if (val >= 0)
626     {
627       operands[1] = GEN_INT (0x7f);
628       operands[2] = GEN_INT (val - 0x7f);
629     }
630   else
631     {
632       operands[1] = GEN_INT (- 0x80);
633       operands[2] = GEN_INT (val + 0x80);
634     }
635 })
636
637 (define_split
638   [(set (match_operand:SI 0 "register_operand")
639         (plus:SI (match_operand:SI 1 "register_operand")
640                  (match_operand:SI 2 "const_int_operand")))]
641   "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
642    && GET_CODE (operands[0]) == REG
643    && M16_REG_P (REGNO (operands[0]))
644    && GET_CODE (operands[1]) == REG
645    && M16_REG_P (REGNO (operands[1]))
646    && REGNO (operands[0]) != REGNO (operands[1])
647    && GET_CODE (operands[2]) == CONST_INT
648    && ((INTVAL (operands[2]) > 0x7
649         && INTVAL (operands[2]) <= 0x7 + 0x7f)
650        || (INTVAL (operands[2]) < - 0x8
651            && INTVAL (operands[2]) >= - 0x8 - 0x80))"
652   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
653    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
654 {
655   HOST_WIDE_INT val = INTVAL (operands[2]);
656
657   if (val >= 0)
658     {
659       operands[2] = GEN_INT (0x7);
660       operands[3] = GEN_INT (val - 0x7);
661     }
662   else
663     {
664       operands[2] = GEN_INT (- 0x8);
665       operands[3] = GEN_INT (val + 0x8);
666     }
667 })
668
669 (define_split
670   [(set (match_operand:DI 0 "register_operand")
671         (plus:DI (match_dup 0)
672                  (match_operand:DI 1 "const_int_operand")))]
673   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
674    && GET_CODE (operands[0]) == REG
675    && M16_REG_P (REGNO (operands[0]))
676    && GET_CODE (operands[1]) == CONST_INT
677    && ((INTVAL (operands[1]) > 0xf
678         && INTVAL (operands[1]) <= 0xf + 0xf)
679        || (INTVAL (operands[1]) < - 0x10
680            && INTVAL (operands[1]) >= - 0x10 - 0x10))"
681   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
682    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
683 {
684   HOST_WIDE_INT val = INTVAL (operands[1]);
685
686   if (val >= 0)
687     {
688       operands[1] = GEN_INT (0xf);
689       operands[2] = GEN_INT (val - 0xf);
690     }
691   else
692     {
693       operands[1] = GEN_INT (- 0x10);
694       operands[2] = GEN_INT (val + 0x10);
695     }
696 })
697
698 (define_split
699   [(set (match_operand:DI 0 "register_operand")
700         (plus:DI (match_operand:DI 1 "register_operand")
701                  (match_operand:DI 2 "const_int_operand")))]
702   "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
703    && GET_CODE (operands[0]) == REG
704    && M16_REG_P (REGNO (operands[0]))
705    && GET_CODE (operands[1]) == REG
706    && M16_REG_P (REGNO (operands[1]))
707    && REGNO (operands[0]) != REGNO (operands[1])
708    && GET_CODE (operands[2]) == CONST_INT
709    && ((INTVAL (operands[2]) > 0x7
710         && INTVAL (operands[2]) <= 0x7 + 0xf)
711        || (INTVAL (operands[2]) < - 0x8
712            && INTVAL (operands[2]) >= - 0x8 - 0x10))"
713   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
714    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
715 {
716   HOST_WIDE_INT val = INTVAL (operands[2]);
717
718   if (val >= 0)
719     {
720       operands[2] = GEN_INT (0x7);
721       operands[3] = GEN_INT (val - 0x7);
722     }
723   else
724     {
725       operands[2] = GEN_INT (- 0x8);
726       operands[3] = GEN_INT (val + 0x8);
727     }
728 })
729
730 (define_insn "*addsi3_extended"
731   [(set (match_operand:DI 0 "register_operand" "=d,d")
732         (sign_extend:DI
733              (plus:SI (match_operand:SI 1 "register_operand" "d,d")
734                       (match_operand:SI 2 "arith_operand" "d,Q"))))]
735   "TARGET_64BIT && !TARGET_MIPS16"
736   "@
737     addu\t%0,%1,%2
738     addiu\t%0,%1,%2"
739   [(set_attr "type" "arith")
740    (set_attr "mode" "SI")])
741
742 ;; Split this insn so that the addiu splitters can have a crack at it.
743 ;; Use a conservative length estimate until the split.
744 (define_insn_and_split "*addsi3_extended_mips16"
745   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
746         (sign_extend:DI
747              (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
748                       (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
749   "TARGET_64BIT && TARGET_MIPS16"
750   "#"
751   "&& reload_completed"
752   [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))]
753   { operands[3] = gen_lowpart (SImode, operands[0]); }
754   [(set_attr "type" "arith")
755    (set_attr "mode" "SI")
756    (set_attr "extended_mips16" "yes")])
757 \f
758 ;;
759 ;;  ....................
760 ;;
761 ;;      SUBTRACTION
762 ;;
763 ;;  ....................
764 ;;
765
766 (define_insn "sub<mode>3"
767   [(set (match_operand:ANYF 0 "register_operand" "=f")
768         (minus:ANYF (match_operand:ANYF 1 "register_operand" "f")
769                     (match_operand:ANYF 2 "register_operand" "f")))]
770   ""
771   "sub.<fmt>\t%0,%1,%2"
772   [(set_attr "type" "fadd")
773    (set_attr "mode" "<UNITMODE>")])
774
775 (define_insn "sub<mode>3"
776   [(set (match_operand:GPR 0 "register_operand" "=d")
777         (minus:GPR (match_operand:GPR 1 "register_operand" "d")
778                    (match_operand:GPR 2 "register_operand" "d")))]
779   ""
780   "<d>subu\t%0,%1,%2"
781   [(set_attr "type" "arith")
782    (set_attr "mode" "<MODE>")])
783
784 (define_insn "*subsi3_extended"
785   [(set (match_operand:DI 0 "register_operand" "=d")
786         (sign_extend:DI
787             (minus:SI (match_operand:SI 1 "register_operand" "d")
788                       (match_operand:SI 2 "register_operand" "d"))))]
789   "TARGET_64BIT"
790   "subu\t%0,%1,%2"
791   [(set_attr "type" "arith")
792    (set_attr "mode" "DI")])
793 \f
794 ;;
795 ;;  ....................
796 ;;
797 ;;      MULTIPLICATION
798 ;;
799 ;;  ....................
800 ;;
801
802 (define_expand "mul<mode>3"
803   [(set (match_operand:SCALARF 0 "register_operand")
804         (mult:SCALARF (match_operand:SCALARF 1 "register_operand")
805                       (match_operand:SCALARF 2 "register_operand")))]
806   ""
807   "")
808
809 (define_insn "*mul<mode>3"
810   [(set (match_operand:SCALARF 0 "register_operand" "=f")
811         (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
812                       (match_operand:SCALARF 2 "register_operand" "f")))]
813   "!TARGET_4300_MUL_FIX"
814   "mul.<fmt>\t%0,%1,%2"
815   [(set_attr "type" "fmul")
816    (set_attr "mode" "<MODE>")])
817
818 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
819 ;; operands may corrupt immediately following multiplies. This is a
820 ;; simple fix to insert NOPs.
821
822 (define_insn "*mul<mode>3_r4300"
823   [(set (match_operand:SCALARF 0 "register_operand" "=f")
824         (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
825                       (match_operand:SCALARF 2 "register_operand" "f")))]
826   "TARGET_4300_MUL_FIX"
827   "mul.<fmt>\t%0,%1,%2\;nop"
828   [(set_attr "type" "fmul")
829    (set_attr "mode" "<MODE>")
830    (set_attr "length" "8")])
831
832 (define_insn "mulv2sf3"
833   [(set (match_operand:V2SF 0 "register_operand" "=f")
834         (mult:V2SF (match_operand:V2SF 1 "register_operand" "f")
835                    (match_operand:V2SF 2 "register_operand" "f")))]
836   "TARGET_PAIRED_SINGLE_FLOAT"
837   "mul.ps\t%0,%1,%2"
838   [(set_attr "type" "fmul")
839    (set_attr "mode" "SF")])
840
841 ;; The original R4000 has a cpu bug.  If a double-word or a variable
842 ;; shift executes while an integer multiplication is in progress, the
843 ;; shift may give an incorrect result.  Avoid this by keeping the mflo
844 ;; with the mult on the R4000.
845 ;;
846 ;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
847 ;; (also valid for MIPS R4000MC processors):
848 ;;
849 ;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to
850 ;;      this errata description.
851 ;;      The following code sequence causes the R4000 to incorrectly
852 ;;      execute the Double Shift Right Arithmetic 32 (dsra32)
853 ;;      instruction.  If the dsra32 instruction is executed during an
854 ;;      integer multiply, the dsra32 will only shift by the amount in
855 ;;      specified in the instruction rather than the amount plus 32
856 ;;      bits.
857 ;;      instruction 1:          mult    rs,rt           integer multiply
858 ;;      instruction 2-12:       dsra32  rd,rt,rs        doubleword shift
859 ;;                                                      right arithmetic + 32
860 ;;      Workaround: A dsra32 instruction placed after an integer
861 ;;      multiply should not be one of the 11 instructions after the
862 ;;      multiply instruction."
863 ;;
864 ;; and:
865 ;;
866 ;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by
867 ;;      the following description.
868 ;;      All extended shifts (shift by n+32) and variable shifts (32 and
869 ;;      64-bit versions) may produce incorrect results under the
870 ;;      following conditions:
871 ;;      1) An integer multiply is currently executing
872 ;;      2) These types of shift instructions are executed immediately
873 ;;         following an integer divide instruction.
874 ;;      Workaround:
875 ;;      1) Make sure no integer multiply is running wihen these
876 ;;         instruction are executed.  If this cannot be predicted at
877 ;;         compile time, then insert a "mfhi" to R0 instruction
878 ;;         immediately after the integer multiply instruction.  This
879 ;;         will cause the integer multiply to complete before the shift
880 ;;         is executed.
881 ;;      2) Separate integer divide and these two classes of shift
882 ;;         instructions by another instruction or a noop."
883 ;;
884 ;; These processors have PRId values of 0x00004220 and 0x00004300,
885 ;; respectively.
886
887 (define_expand "mul<mode>3"
888   [(set (match_operand:GPR 0 "register_operand")
889         (mult:GPR (match_operand:GPR 1 "register_operand")
890                   (match_operand:GPR 2 "register_operand")))]
891   ""
892 {
893   if (GENERATE_MULT3_<MODE>)
894     emit_insn (gen_mul<mode>3_mult3 (operands[0], operands[1], operands[2]));
895   else if (!TARGET_FIX_R4000)
896     emit_insn (gen_mul<mode>3_internal (operands[0], operands[1],
897                                         operands[2]));
898   else
899     emit_insn (gen_mul<mode>3_r4000 (operands[0], operands[1], operands[2]));
900   DONE;
901 })
902
903 (define_insn "mulsi3_mult3"
904   [(set (match_operand:SI 0 "register_operand" "=d,l")
905         (mult:SI (match_operand:SI 1 "register_operand" "d,d")
906                  (match_operand:SI 2 "register_operand" "d,d")))
907    (clobber (match_scratch:SI 3 "=h,h"))
908    (clobber (match_scratch:SI 4 "=l,X"))]
909   "GENERATE_MULT3_SI"
910 {
911   if (which_alternative == 1)
912     return "mult\t%1,%2";
913   if (TARGET_MAD
914       || TARGET_MIPS5400
915       || TARGET_MIPS5500
916       || TARGET_MIPS7000
917       || TARGET_MIPS9000
918       || ISA_MIPS32
919       || ISA_MIPS32R2
920       || ISA_MIPS64)
921     return "mul\t%0,%1,%2";
922   return "mult\t%0,%1,%2";
923 }
924   [(set_attr "type" "imul")
925    (set_attr "mode" "SI")])
926
927 (define_insn "muldi3_mult3"
928   [(set (match_operand:DI 0 "register_operand" "=d")
929         (mult:DI (match_operand:DI 1 "register_operand" "d")
930                  (match_operand:DI 2 "register_operand" "d")))
931    (clobber (match_scratch:DI 3 "=h"))
932    (clobber (match_scratch:DI 4 "=l"))]
933   "TARGET_64BIT && GENERATE_MULT3_DI"
934   "dmult\t%0,%1,%2"
935   [(set_attr "type" "imul")
936    (set_attr "mode" "DI")])
937
938 ;; If a register gets allocated to LO, and we spill to memory, the reload
939 ;; will include a move from LO to a GPR.  Merge it into the multiplication
940 ;; if it can set the GPR directly.
941 ;;
942 ;; Operand 0: LO
943 ;; Operand 1: GPR (1st multiplication operand)
944 ;; Operand 2: GPR (2nd multiplication operand)
945 ;; Operand 3: HI
946 ;; Operand 4: GPR (destination)
947 (define_peephole2
948   [(parallel
949        [(set (match_operand:SI 0 "register_operand")
950              (mult:SI (match_operand:SI 1 "register_operand")
951                       (match_operand:SI 2 "register_operand")))
952         (clobber (match_operand:SI 3 "register_operand"))
953         (clobber (scratch:SI))])
954    (set (match_operand:SI 4 "register_operand")
955         (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
956   "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"
957   [(parallel
958        [(set (match_dup 4)
959              (mult:SI (match_dup 1)
960                       (match_dup 2)))
961         (clobber (match_dup 3))
962         (clobber (match_dup 0))])])
963
964 (define_insn "mul<mode>3_internal"
965   [(set (match_operand:GPR 0 "register_operand" "=l")
966         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
967                   (match_operand:GPR 2 "register_operand" "d")))
968    (clobber (match_scratch:GPR 3 "=h"))]
969   "!TARGET_FIX_R4000"
970   "<d>mult\t%1,%2"
971   [(set_attr "type" "imul")
972    (set_attr "mode" "<MODE>")])
973
974 (define_insn "mul<mode>3_r4000"
975   [(set (match_operand:GPR 0 "register_operand" "=d")
976         (mult:GPR (match_operand:GPR 1 "register_operand" "d")
977                   (match_operand:GPR 2 "register_operand" "d")))
978    (clobber (match_scratch:GPR 3 "=h"))
979    (clobber (match_scratch:GPR 4 "=l"))]
980   "TARGET_FIX_R4000"
981   "<d>mult\t%1,%2\;mflo\t%0"
982   [(set_attr "type" "imul")
983    (set_attr "mode" "<MODE>")
984    (set_attr "length" "8")])
985
986 ;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
987 ;; of "mult; mflo".  They have the same latency, but the first form gives
988 ;; us an extra cycle to compute the operands.
989
990 ;; Operand 0: LO
991 ;; Operand 1: GPR (1st multiplication operand)
992 ;; Operand 2: GPR (2nd multiplication operand)
993 ;; Operand 3: HI
994 ;; Operand 4: GPR (destination)
995 (define_peephole2
996   [(parallel
997        [(set (match_operand:SI 0 "register_operand")
998              (mult:SI (match_operand:SI 1 "register_operand")
999                       (match_operand:SI 2 "register_operand")))
1000         (clobber (match_operand:SI 3 "register_operand"))])
1001    (set (match_operand:SI 4 "register_operand")
1002         (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
1003   "ISA_HAS_MACC && !GENERATE_MULT3_SI"
1004   [(set (match_dup 0)
1005         (const_int 0))
1006    (parallel
1007        [(set (match_dup 0)
1008              (plus:SI (mult:SI (match_dup 1)
1009                                (match_dup 2))
1010                       (match_dup 0)))
1011         (set (match_dup 4)
1012              (plus:SI (mult:SI (match_dup 1)
1013                                (match_dup 2))
1014                       (match_dup 0)))
1015         (clobber (match_dup 3))])])
1016
1017 ;; Multiply-accumulate patterns
1018
1019 ;; For processors that can copy the output to a general register:
1020 ;;
1021 ;; The all-d alternative is needed because the combiner will find this
1022 ;; pattern and then register alloc/reload will move registers around to
1023 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1024 ;;
1025 ;; The last alternative should be made slightly less desirable, but adding
1026 ;; "?" to the constraint is too strong, and causes values to be loaded into
1027 ;; LO even when that's more costly.  For now, using "*d" mostly does the
1028 ;; trick.
1029 (define_insn "*mul_acc_si"
1030   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1031         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1032                           (match_operand:SI 2 "register_operand" "d,d,d"))
1033                  (match_operand:SI 3 "register_operand" "0,l,*d")))
1034    (clobber (match_scratch:SI 4 "=h,h,h"))
1035    (clobber (match_scratch:SI 5 "=X,3,l"))
1036    (clobber (match_scratch:SI 6 "=X,X,&d"))]
1037   "(TARGET_MIPS3900
1038    || ISA_HAS_MADD_MSUB)
1039    && !TARGET_MIPS16"
1040 {
1041   static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
1042   if (which_alternative == 2)
1043     return "#";
1044   if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1045     return "#";
1046   return madd[which_alternative];
1047 }
1048   [(set_attr "type"     "imadd,imadd,multi")
1049    (set_attr "mode"     "SI")
1050    (set_attr "length"   "4,4,8")])
1051
1052 ;; Split the above insn if we failed to get LO allocated.
1053 (define_split
1054   [(set (match_operand:SI 0 "register_operand")
1055         (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1056                           (match_operand:SI 2 "register_operand"))
1057                  (match_operand:SI 3 "register_operand")))
1058    (clobber (match_scratch:SI 4))
1059    (clobber (match_scratch:SI 5))
1060    (clobber (match_scratch:SI 6))]
1061   "reload_completed && !TARGET_DEBUG_D_MODE
1062    && GP_REG_P (true_regnum (operands[0]))
1063    && GP_REG_P (true_regnum (operands[3]))"
1064   [(parallel [(set (match_dup 6)
1065                    (mult:SI (match_dup 1) (match_dup 2)))
1066               (clobber (match_dup 4))
1067               (clobber (match_dup 5))])
1068    (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1069   "")
1070
1071 ;; Splitter to copy result of MADD to a general register
1072 (define_split
1073   [(set (match_operand:SI                   0 "register_operand")
1074         (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
1075                           (match_operand:SI 2 "register_operand"))
1076                  (match_operand:SI          3 "register_operand")))
1077    (clobber (match_scratch:SI               4))
1078    (clobber (match_scratch:SI               5))
1079    (clobber (match_scratch:SI               6))]
1080   "reload_completed && !TARGET_DEBUG_D_MODE
1081    && GP_REG_P (true_regnum (operands[0]))
1082    && true_regnum (operands[3]) == LO_REGNUM"
1083   [(parallel [(set (match_dup 3)
1084                    (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1085                             (match_dup 3)))
1086               (clobber (match_dup 4))
1087               (clobber (match_dup 5))
1088               (clobber (match_dup 6))])
1089    (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1090   "")
1091
1092 (define_insn "*macc"
1093   [(set (match_operand:SI 0 "register_operand" "=l,d")
1094         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1095                           (match_operand:SI 2 "register_operand" "d,d"))
1096                  (match_operand:SI 3 "register_operand" "0,l")))
1097    (clobber (match_scratch:SI 4 "=h,h"))
1098    (clobber (match_scratch:SI 5 "=X,3"))]
1099   "ISA_HAS_MACC"
1100 {
1101   if (which_alternative == 1)
1102     return "macc\t%0,%1,%2";
1103   else if (TARGET_MIPS5500)
1104     return "madd\t%1,%2";
1105   else
1106     /* The VR4130 assumes that there is a two-cycle latency between a macc
1107        that "writes" to $0 and an instruction that reads from it.  We avoid
1108        this by assigning to $1 instead.  */
1109     return "%[macc\t%@,%1,%2%]";
1110 }
1111   [(set_attr "type" "imadd")
1112    (set_attr "mode" "SI")])
1113
1114 (define_insn "*msac"
1115   [(set (match_operand:SI 0 "register_operand" "=l,d")
1116         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1117                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1118                            (match_operand:SI 3 "register_operand" "d,d"))))
1119    (clobber (match_scratch:SI 4 "=h,h"))
1120    (clobber (match_scratch:SI 5 "=X,1"))]
1121   "ISA_HAS_MSAC"
1122 {
1123   if (which_alternative == 1)
1124     return "msac\t%0,%2,%3";
1125   else if (TARGET_MIPS5500)
1126     return "msub\t%2,%3";
1127   else
1128     return "msac\t$0,%2,%3";
1129 }
1130   [(set_attr "type"     "imadd")
1131    (set_attr "mode"     "SI")])
1132
1133 ;; An msac-like instruction implemented using negation and a macc.
1134 (define_insn_and_split "*msac_using_macc"
1135   [(set (match_operand:SI 0 "register_operand" "=l,d")
1136         (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1137                   (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1138                            (match_operand:SI 3 "register_operand" "d,d"))))
1139    (clobber (match_scratch:SI 4 "=h,h"))
1140    (clobber (match_scratch:SI 5 "=X,1"))
1141    (clobber (match_scratch:SI 6 "=d,d"))]
1142   "ISA_HAS_MACC && !ISA_HAS_MSAC"
1143   "#"
1144   "&& reload_completed"
1145   [(set (match_dup 6)
1146         (neg:SI (match_dup 3)))
1147    (parallel
1148        [(set (match_dup 0)
1149              (plus:SI (mult:SI (match_dup 2)
1150                                (match_dup 6))
1151                       (match_dup 1)))
1152         (clobber (match_dup 4))
1153         (clobber (match_dup 5))])]
1154   ""
1155   [(set_attr "type"     "imadd")
1156    (set_attr "length"   "8")])
1157
1158 ;; Patterns generated by the define_peephole2 below.
1159
1160 (define_insn "*macc2"
1161   [(set (match_operand:SI 0 "register_operand" "=l")
1162         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1163                           (match_operand:SI 2 "register_operand" "d"))
1164                  (match_dup 0)))
1165    (set (match_operand:SI 3 "register_operand" "=d")
1166         (plus:SI (mult:SI (match_dup 1)
1167                           (match_dup 2))
1168                  (match_dup 0)))
1169    (clobber (match_scratch:SI 4 "=h"))]
1170   "ISA_HAS_MACC && reload_completed"
1171   "macc\t%3,%1,%2"
1172   [(set_attr "type"     "imadd")
1173    (set_attr "mode"     "SI")])
1174
1175 (define_insn "*msac2"
1176   [(set (match_operand:SI 0 "register_operand" "=l")
1177         (minus:SI (match_dup 0)
1178                   (mult:SI (match_operand:SI 1 "register_operand" "d")
1179                            (match_operand:SI 2 "register_operand" "d"))))
1180    (set (match_operand:SI 3 "register_operand" "=d")
1181         (minus:SI (match_dup 0)
1182                   (mult:SI (match_dup 1)
1183                            (match_dup 2))))
1184    (clobber (match_scratch:SI 4 "=h"))]
1185   "ISA_HAS_MSAC && reload_completed"
1186   "msac\t%3,%1,%2"
1187   [(set_attr "type"     "imadd")
1188    (set_attr "mode"     "SI")])
1189
1190 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1191 ;; Similarly msac.
1192 ;;
1193 ;; Operand 0: LO
1194 ;; Operand 1: macc/msac
1195 ;; Operand 2: HI
1196 ;; Operand 3: GPR (destination)
1197 (define_peephole2
1198   [(parallel
1199        [(set (match_operand:SI 0 "register_operand")
1200              (match_operand:SI 1 "macc_msac_operand"))
1201         (clobber (match_operand:SI 2 "register_operand"))
1202         (clobber (scratch:SI))])
1203    (set (match_operand:SI 3 "register_operand")
1204         (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
1205   ""
1206   [(parallel [(set (match_dup 0)
1207                    (match_dup 1))
1208               (set (match_dup 3)
1209                    (match_dup 1))
1210               (clobber (match_dup 2))])]
1211   "")
1212
1213 ;; When we have a three-address multiplication instruction, it should
1214 ;; be faster to do a separate multiply and add, rather than moving
1215 ;; something into LO in order to use a macc instruction.
1216 ;;
1217 ;; This peephole needs a scratch register to cater for the case when one
1218 ;; of the multiplication operands is the same as the destination.
1219 ;;
1220 ;; Operand 0: GPR (scratch)
1221 ;; Operand 1: LO
1222 ;; Operand 2: GPR (addend)
1223 ;; Operand 3: GPR (destination)
1224 ;; Operand 4: macc/msac
1225 ;; Operand 5: HI
1226 ;; Operand 6: new multiplication
1227 ;; Operand 7: new addition/subtraction
1228 (define_peephole2
1229   [(match_scratch:SI 0 "d")
1230    (set (match_operand:SI 1 "register_operand")
1231         (match_operand:SI 2 "register_operand"))
1232    (match_dup 0)
1233    (parallel
1234        [(set (match_operand:SI 3 "register_operand")
1235              (match_operand:SI 4 "macc_msac_operand"))
1236         (clobber (match_operand:SI 5 "register_operand"))
1237         (clobber (match_dup 1))])]
1238   "GENERATE_MULT3_SI
1239    && true_regnum (operands[1]) == LO_REGNUM
1240    && peep2_reg_dead_p (2, operands[1])
1241    && GP_REG_P (true_regnum (operands[3]))"
1242   [(parallel [(set (match_dup 0)
1243                    (match_dup 6))
1244               (clobber (match_dup 5))
1245               (clobber (match_dup 1))])
1246    (set (match_dup 3)
1247         (match_dup 7))]
1248 {
1249   operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1250   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1251                                 operands[2], operands[0]);
1252 })
1253
1254 ;; Same as above, except LO is the initial target of the macc.
1255 ;;
1256 ;; Operand 0: GPR (scratch)
1257 ;; Operand 1: LO
1258 ;; Operand 2: GPR (addend)
1259 ;; Operand 3: macc/msac
1260 ;; Operand 4: HI
1261 ;; Operand 5: GPR (destination)
1262 ;; Operand 6: new multiplication
1263 ;; Operand 7: new addition/subtraction
1264 (define_peephole2
1265   [(match_scratch:SI 0 "d")
1266    (set (match_operand:SI 1 "register_operand")
1267         (match_operand:SI 2 "register_operand"))
1268    (match_dup 0)
1269    (parallel
1270        [(set (match_dup 1)
1271              (match_operand:SI 3 "macc_msac_operand"))
1272         (clobber (match_operand:SI 4 "register_operand"))
1273         (clobber (scratch:SI))])
1274    (match_dup 0)
1275    (set (match_operand:SI 5 "register_operand")
1276         (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
1277   "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])"
1278   [(parallel [(set (match_dup 0)
1279                    (match_dup 6))
1280               (clobber (match_dup 4))
1281               (clobber (match_dup 1))])
1282    (set (match_dup 5)
1283         (match_dup 7))]
1284 {
1285   operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
1286   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
1287                                 operands[2], operands[0]);
1288 })
1289
1290 (define_insn "*mul_sub_si"
1291   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1292         (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1293                   (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1294                            (match_operand:SI 3 "register_operand" "d,d,d"))))
1295    (clobber (match_scratch:SI 4 "=h,h,h"))
1296    (clobber (match_scratch:SI 5 "=X,1,l"))
1297    (clobber (match_scratch:SI 6 "=X,X,&d"))]
1298   "ISA_HAS_MADD_MSUB"
1299   "@
1300    msub\t%2,%3
1301    #
1302    #"
1303   [(set_attr "type"     "imadd,multi,multi")
1304    (set_attr "mode"     "SI")
1305    (set_attr "length"   "4,8,8")])
1306
1307 ;; Split the above insn if we failed to get LO allocated.
1308 (define_split
1309   [(set (match_operand:SI 0 "register_operand")
1310         (minus:SI (match_operand:SI 1 "register_operand")
1311                   (mult:SI (match_operand:SI 2 "register_operand")
1312                            (match_operand:SI 3 "register_operand"))))
1313    (clobber (match_scratch:SI 4))
1314    (clobber (match_scratch:SI 5))
1315    (clobber (match_scratch:SI 6))]
1316   "reload_completed && !TARGET_DEBUG_D_MODE
1317    && GP_REG_P (true_regnum (operands[0]))
1318    && GP_REG_P (true_regnum (operands[1]))"
1319   [(parallel [(set (match_dup 6)
1320                    (mult:SI (match_dup 2) (match_dup 3)))
1321               (clobber (match_dup 4))
1322               (clobber (match_dup 5))])
1323    (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1324   "")
1325
1326 ;; Splitter to copy result of MSUB to a general register
1327 (define_split
1328   [(set (match_operand:SI 0 "register_operand")
1329         (minus:SI (match_operand:SI 1 "register_operand")
1330                   (mult:SI (match_operand:SI 2 "register_operand")
1331                            (match_operand:SI 3 "register_operand"))))
1332    (clobber (match_scratch:SI 4))
1333    (clobber (match_scratch:SI 5))
1334    (clobber (match_scratch:SI 6))]
1335   "reload_completed && !TARGET_DEBUG_D_MODE
1336    && GP_REG_P (true_regnum (operands[0]))
1337    && true_regnum (operands[1]) == LO_REGNUM"
1338   [(parallel [(set (match_dup 1)
1339                    (minus:SI (match_dup 1)
1340                              (mult:SI (match_dup 2) (match_dup 3))))
1341               (clobber (match_dup 4))
1342               (clobber (match_dup 5))
1343               (clobber (match_dup 6))])
1344    (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
1345   "")
1346
1347 (define_insn "*muls"
1348   [(set (match_operand:SI                  0 "register_operand" "=l,d")
1349         (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1350                          (match_operand:SI 2 "register_operand" "d,d"))))
1351    (clobber (match_scratch:SI              3                    "=h,h"))
1352    (clobber (match_scratch:SI              4                    "=X,l"))]
1353   "ISA_HAS_MULS"
1354   "@
1355    muls\t$0,%1,%2
1356    muls\t%0,%1,%2"
1357   [(set_attr "type"     "imul")
1358    (set_attr "mode"     "SI")])
1359
1360 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1361
1362 (define_expand "<u>mulsidi3"
1363   [(parallel
1364       [(set (match_operand:DI 0 "register_operand")
1365             (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1366                      (any_extend:DI (match_operand:SI 2 "register_operand"))))
1367        (clobber (scratch:DI))
1368        (clobber (scratch:DI))
1369        (clobber (scratch:DI))])]
1370   "!TARGET_64BIT || !TARGET_FIX_R4000"
1371 {
1372   if (!TARGET_64BIT)
1373     {
1374       if (!TARGET_FIX_R4000)
1375         emit_insn (gen_<u>mulsidi3_32bit_internal (operands[0], operands[1],
1376                                                    operands[2]));
1377       else
1378         emit_insn (gen_<u>mulsidi3_32bit_r4000 (operands[0], operands[1],
1379                                                 operands[2]));
1380       DONE;
1381     }
1382 })
1383
1384 (define_insn "<u>mulsidi3_32bit_internal"
1385   [(set (match_operand:DI 0 "register_operand" "=x")
1386         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1387                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1388   "!TARGET_64BIT && !TARGET_FIX_R4000"
1389   "mult<u>\t%1,%2"
1390   [(set_attr "type" "imul")
1391    (set_attr "mode" "SI")])
1392
1393 (define_insn "<u>mulsidi3_32bit_r4000"
1394   [(set (match_operand:DI 0 "register_operand" "=d")
1395         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1396                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1397    (clobber (match_scratch:DI 3 "=x"))]
1398   "!TARGET_64BIT && TARGET_FIX_R4000"
1399   "mult\t%1,%2\;mflo\t%L0;mfhi\t%M0"
1400   [(set_attr "type" "imul")
1401    (set_attr "mode" "SI")
1402    (set_attr "length" "12")])
1403
1404 (define_insn_and_split "*<u>mulsidi3_64bit"
1405   [(set (match_operand:DI 0 "register_operand" "=d")
1406         (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1407                  (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))
1408    (clobber (match_scratch:DI 3 "=l"))
1409    (clobber (match_scratch:DI 4 "=h"))
1410    (clobber (match_scratch:DI 5 "=d"))]
1411   "TARGET_64BIT && !TARGET_FIX_R4000"
1412   "#"
1413   "&& reload_completed"
1414   [(parallel
1415        [(set (match_dup 3)
1416              (sign_extend:DI
1417                 (mult:SI (match_dup 1)
1418                          (match_dup 2))))
1419         (set (match_dup 4)
1420              (ashiftrt:DI
1421                 (mult:DI (any_extend:DI (match_dup 1))
1422                          (any_extend:DI (match_dup 2)))
1423                 (const_int 32)))])
1424
1425    ;; OP5 <- LO, OP0 <- HI
1426    (set (match_dup 5) (unspec:DI [(match_dup 3) (match_dup 4)] UNSPEC_MFHILO))
1427    (set (match_dup 0) (unspec:DI [(match_dup 4) (match_dup 3)] UNSPEC_MFHILO))
1428
1429    ;; Zero-extend OP5.
1430    (set (match_dup 5)
1431         (ashift:DI (match_dup 5)
1432                    (const_int 32)))
1433    (set (match_dup 5)
1434         (lshiftrt:DI (match_dup 5)
1435                      (const_int 32)))
1436
1437    ;; Shift OP0 into place.
1438    (set (match_dup 0)
1439         (ashift:DI (match_dup 0)
1440                    (const_int 32)))
1441
1442    ;; OR the two halves together
1443    (set (match_dup 0)
1444         (ior:DI (match_dup 0)
1445                 (match_dup 5)))]
1446   ""
1447   [(set_attr "type" "imul")
1448    (set_attr "mode" "SI")
1449    (set_attr "length" "24")])
1450
1451 (define_insn "*<u>mulsidi3_64bit_parts"
1452   [(set (match_operand:DI 0 "register_operand" "=l")
1453         (sign_extend:DI
1454            (mult:SI (match_operand:SI 2 "register_operand" "d")
1455                     (match_operand:SI 3 "register_operand" "d"))))
1456    (set (match_operand:DI 1 "register_operand" "=h")
1457         (ashiftrt:DI
1458            (mult:DI (any_extend:DI (match_dup 2))
1459                     (any_extend:DI (match_dup 3)))
1460            (const_int 32)))]
1461   "TARGET_64BIT && !TARGET_FIX_R4000"
1462   "mult<u>\t%2,%3"
1463   [(set_attr "type" "imul")
1464    (set_attr "mode" "SI")])
1465
1466 ;; Widening multiply with negation.
1467 (define_insn "*muls<u>_di"
1468   [(set (match_operand:DI 0 "register_operand" "=x")
1469         (neg:DI
1470          (mult:DI
1471           (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1472           (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1473   "!TARGET_64BIT && ISA_HAS_MULS"
1474   "muls<u>\t$0,%1,%2"
1475   [(set_attr "type" "imul")
1476    (set_attr "mode" "SI")])
1477
1478 (define_insn "*msac<u>_di"
1479   [(set (match_operand:DI 0 "register_operand" "=x")
1480         (minus:DI
1481            (match_operand:DI 3 "register_operand" "0")
1482            (mult:DI
1483               (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1484               (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
1485   "!TARGET_64BIT && ISA_HAS_MSAC"
1486 {
1487   if (TARGET_MIPS5500)
1488     return "msub<u>\t%1,%2";
1489   else
1490     return "msac<u>\t$0,%1,%2";
1491 }
1492   [(set_attr "type" "imadd")
1493    (set_attr "mode" "SI")])
1494
1495 ;; _highpart patterns
1496
1497 (define_expand "<su>mulsi3_highpart"
1498   [(set (match_operand:SI 0 "register_operand")
1499         (truncate:SI
1500          (lshiftrt:DI
1501           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
1502                    (any_extend:DI (match_operand:SI 2 "register_operand")))
1503           (const_int 32))))]
1504   "ISA_HAS_MULHI || !TARGET_FIX_R4000"
1505 {
1506   if (ISA_HAS_MULHI)
1507     emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0],
1508                                                        operands[1],
1509                                                        operands[2]));
1510   else
1511     emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1],
1512                                                  operands[2]));
1513   DONE;
1514 })
1515
1516 (define_insn "<su>mulsi3_highpart_internal"
1517   [(set (match_operand:SI 0 "register_operand" "=h")
1518         (truncate:SI
1519          (lshiftrt:DI
1520           (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1521                    (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1522           (const_int 32))))
1523    (clobber (match_scratch:SI 3 "=l"))]
1524   "!ISA_HAS_MULHI && !TARGET_FIX_R4000"
1525   "mult<u>\t%1,%2"
1526   [(set_attr "type" "imul")
1527    (set_attr "mode" "SI")])
1528
1529 (define_insn "<su>mulsi3_highpart_mulhi_internal"
1530   [(set (match_operand:SI 0 "register_operand" "=h,d")
1531         (truncate:SI
1532          (lshiftrt:DI
1533           (mult:DI
1534            (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1535            (any_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
1536           (const_int 32))))
1537    (clobber (match_scratch:SI 3 "=l,l"))
1538    (clobber (match_scratch:SI 4 "=X,h"))]
1539   "ISA_HAS_MULHI"
1540   "@
1541    mult<u>\t%1,%2
1542    mulhi<u>\t%0,%1,%2"
1543   [(set_attr "type" "imul")
1544    (set_attr "mode" "SI")])
1545
1546 (define_insn "*<su>mulsi3_highpart_neg_mulhi_internal"
1547   [(set (match_operand:SI 0 "register_operand" "=h,d")
1548         (truncate:SI
1549          (lshiftrt:DI
1550           (neg:DI
1551            (mult:DI
1552             (any_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
1553             (any_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
1554           (const_int 32))))
1555    (clobber (match_scratch:SI 3 "=l,l"))
1556    (clobber (match_scratch:SI 4 "=X,h"))]
1557   "ISA_HAS_MULHI"
1558   "@
1559    mulshi<u>\t%.,%1,%2
1560    mulshi<u>\t%0,%1,%2"
1561   [(set_attr "type" "imul")
1562    (set_attr "mode" "SI")])
1563
1564 ;; Disable unsigned multiplication for -mfix-vr4120.  This is for VR4120
1565 ;; errata MD(0), which says that dmultu does not always produce the
1566 ;; correct result.
1567 (define_insn "<su>muldi3_highpart"
1568   [(set (match_operand:DI 0 "register_operand" "=h")
1569         (truncate:DI
1570          (lshiftrt:TI
1571           (mult:TI
1572            (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
1573            (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
1574           (const_int 64))))
1575    (clobber (match_scratch:DI 3 "=l"))]
1576   "TARGET_64BIT && !TARGET_FIX_R4000
1577    && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
1578   "dmult<u>\t%1,%2"
1579   [(set_attr "type" "imul")
1580    (set_attr "mode" "DI")])
1581
1582 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
1583 ;; instruction.  The HI/LO registers are used as a 64 bit accumulator.
1584
1585 (define_insn "madsi"
1586   [(set (match_operand:SI 0 "register_operand" "+l")
1587         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1588                           (match_operand:SI 2 "register_operand" "d"))
1589                  (match_dup 0)))
1590    (clobber (match_scratch:SI 3 "=h"))]
1591   "TARGET_MAD"
1592   "mad\t%1,%2"
1593   [(set_attr "type"     "imadd")
1594    (set_attr "mode"     "SI")])
1595
1596 (define_insn "*<su>mul_acc_di"
1597   [(set (match_operand:DI 0 "register_operand" "=x")
1598         (plus:DI
1599          (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
1600                   (any_extend:DI (match_operand:SI 2 "register_operand" "d")))
1601          (match_operand:DI 3 "register_operand" "0")))]
1602   "(TARGET_MAD || ISA_HAS_MACC)
1603    && !TARGET_64BIT"
1604 {
1605   if (TARGET_MAD)
1606     return "mad<u>\t%1,%2";
1607   else if (TARGET_MIPS5500)
1608     return "madd<u>\t%1,%2";
1609   else
1610     /* See comment in *macc.  */
1611     return "%[macc<u>\t%@,%1,%2%]";
1612 }
1613   [(set_attr "type" "imadd")
1614    (set_attr "mode" "SI")])
1615
1616 ;; Floating point multiply accumulate instructions.
1617
1618 (define_insn "*madd<mode>"
1619   [(set (match_operand:ANYF 0 "register_operand" "=f")
1620         (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1621                               (match_operand:ANYF 2 "register_operand" "f"))
1622                    (match_operand:ANYF 3 "register_operand" "f")))]
1623   "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1624   "madd.<fmt>\t%0,%3,%1,%2"
1625   [(set_attr "type" "fmadd")
1626    (set_attr "mode" "<UNITMODE>")])
1627
1628 (define_insn "*msub<mode>"
1629   [(set (match_operand:ANYF 0 "register_operand" "=f")
1630         (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1631                                (match_operand:ANYF 2 "register_operand" "f"))
1632                     (match_operand:ANYF 3 "register_operand" "f")))]
1633   "ISA_HAS_FP4 && TARGET_FUSED_MADD"
1634   "msub.<fmt>\t%0,%3,%1,%2"
1635   [(set_attr "type" "fmadd")
1636    (set_attr "mode" "<UNITMODE>")])
1637
1638 (define_insn "*nmadd<mode>"
1639   [(set (match_operand:ANYF 0 "register_operand" "=f")
1640         (neg:ANYF (plus:ANYF
1641                    (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
1642                               (match_operand:ANYF 2 "register_operand" "f"))
1643                    (match_operand:ANYF 3 "register_operand" "f"))))]
1644   "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1645    && HONOR_SIGNED_ZEROS (<MODE>mode)"
1646   "nmadd.<fmt>\t%0,%3,%1,%2"
1647   [(set_attr "type" "fmadd")
1648    (set_attr "mode" "<UNITMODE>")])
1649
1650 (define_insn "*nmadd<mode>_fastmath"
1651   [(set (match_operand:ANYF 0 "register_operand" "=f")
1652         (minus:ANYF
1653          (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
1654                     (match_operand:ANYF 2 "register_operand" "f"))
1655          (match_operand:ANYF 3 "register_operand" "f")))]
1656   "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1657    && !HONOR_SIGNED_ZEROS (<MODE>mode)"
1658   "nmadd.<fmt>\t%0,%3,%1,%2"
1659   [(set_attr "type" "fmadd")
1660    (set_attr "mode" "<UNITMODE>")])
1661
1662 (define_insn "*nmsub<mode>"
1663   [(set (match_operand:ANYF 0 "register_operand" "=f")
1664         (neg:ANYF (minus:ANYF
1665                    (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1666                               (match_operand:ANYF 3 "register_operand" "f"))
1667                    (match_operand:ANYF 1 "register_operand" "f"))))]
1668   "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1669    && HONOR_SIGNED_ZEROS (<MODE>mode)"
1670   "nmsub.<fmt>\t%0,%1,%2,%3"
1671   [(set_attr "type" "fmadd")
1672    (set_attr "mode" "<UNITMODE>")])
1673
1674 (define_insn "*nmsub<mode>_fastmath"
1675   [(set (match_operand:ANYF 0 "register_operand" "=f")
1676         (minus:ANYF
1677          (match_operand:ANYF 1 "register_operand" "f")
1678          (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
1679                     (match_operand:ANYF 3 "register_operand" "f"))))]
1680   "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
1681    && !HONOR_SIGNED_ZEROS (<MODE>mode)"
1682   "nmsub.<fmt>\t%0,%1,%2,%3"
1683   [(set_attr "type" "fmadd")
1684    (set_attr "mode" "<UNITMODE>")])
1685 \f
1686 ;;
1687 ;;  ....................
1688 ;;
1689 ;;      DIVISION and REMAINDER
1690 ;;
1691 ;;  ....................
1692 ;;
1693
1694 (define_expand "div<mode>3"
1695   [(set (match_operand:SCALARF 0 "register_operand")
1696         (div:SCALARF (match_operand:SCALARF 1 "reg_or_1_operand")
1697                      (match_operand:SCALARF 2 "register_operand")))]
1698   "<divide_condition>"
1699 {
1700   if (const_1_operand (operands[1], <MODE>mode))
1701     if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
1702       operands[1] = force_reg (<MODE>mode, operands[1]);
1703 })
1704
1705 ;; These patterns work around the early SB-1 rev2 core "F1" erratum:
1706 ;;
1707 ;; If an mfc1 or dmfc1 happens to access the floating point register
1708 ;; file at the same time a long latency operation (div, sqrt, recip,
1709 ;; sqrt) iterates an intermediate result back through the floating
1710 ;; point register file bypass, then instead returning the correct
1711 ;; register value the mfc1 or dmfc1 operation returns the intermediate
1712 ;; result of the long latency operation.
1713 ;;
1714 ;; The workaround is to insert an unconditional 'mov' from/to the
1715 ;; long latency op destination register.
1716
1717 (define_insn "*div<mode>3"
1718   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1719         (div:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
1720                      (match_operand:SCALARF 2 "register_operand" "f")))]
1721   "<divide_condition>"
1722 {
1723   if (TARGET_FIX_SB1)
1724     return "div.<fmt>\t%0,%1,%2\;mov.<fmt>\t%0,%0";
1725   else
1726     return "div.<fmt>\t%0,%1,%2";
1727 }
1728   [(set_attr "type" "fdiv")
1729    (set_attr "mode" "<MODE>")
1730    (set (attr "length")
1731         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1732                       (const_int 8)
1733                       (const_int 4)))])
1734
1735 (define_insn "*recip<mode>3"
1736   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1737         (div:SCALARF (match_operand:SCALARF 1 "const_1_operand" "")
1738                      (match_operand:SCALARF 2 "register_operand" "f")))]
1739   "ISA_HAS_FP4 && flag_unsafe_math_optimizations"
1740 {
1741   if (TARGET_FIX_SB1)
1742     return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1743   else
1744     return "recip.<fmt>\t%0,%2";
1745 }
1746   [(set_attr "type" "frdiv")
1747    (set_attr "mode" "<MODE>")
1748    (set (attr "length")
1749         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1750                       (const_int 8)
1751                       (const_int 4)))])
1752
1753 ;; VR4120 errata MD(A1): signed division instructions do not work correctly
1754 ;; with negative operands.  We use special libgcc functions instead.
1755 (define_insn "divmod<mode>4"
1756   [(set (match_operand:GPR 0 "register_operand" "=l")
1757         (div:GPR (match_operand:GPR 1 "register_operand" "d")
1758                  (match_operand:GPR 2 "register_operand" "d")))
1759    (set (match_operand:GPR 3 "register_operand" "=h")
1760         (mod:GPR (match_dup 1)
1761                  (match_dup 2)))]
1762   "!TARGET_FIX_VR4120"
1763   { return mips_output_division ("<d>div\t$0,%1,%2", operands); }
1764   [(set_attr "type" "idiv")
1765    (set_attr "mode" "<MODE>")])
1766
1767 (define_insn "udivmod<mode>4"
1768   [(set (match_operand:GPR 0 "register_operand" "=l")
1769         (udiv:GPR (match_operand:GPR 1 "register_operand" "d")
1770                   (match_operand:GPR 2 "register_operand" "d")))
1771    (set (match_operand:GPR 3 "register_operand" "=h")
1772         (umod:GPR (match_dup 1)
1773                   (match_dup 2)))]
1774   ""
1775   { return mips_output_division ("<d>divu\t$0,%1,%2", operands); }
1776   [(set_attr "type" "idiv")
1777    (set_attr "mode" "<MODE>")])
1778 \f
1779 ;;
1780 ;;  ....................
1781 ;;
1782 ;;      SQUARE ROOT
1783 ;;
1784 ;;  ....................
1785
1786 ;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
1787 ;; "*div[sd]f3" comment for details).
1788
1789 (define_insn "sqrt<mode>2"
1790   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1791         (sqrt:SCALARF (match_operand:SCALARF 1 "register_operand" "f")))]
1792   "HAVE_SQRT_P()"
1793 {
1794   if (TARGET_FIX_SB1)
1795     return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0";
1796   else
1797     return "sqrt.<fmt>\t%0,%1";
1798 }
1799   [(set_attr "type" "fsqrt")
1800    (set_attr "mode" "<MODE>")
1801    (set (attr "length")
1802         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1803                       (const_int 8)
1804                       (const_int 4)))])
1805
1806 (define_insn "*rsqrt<mode>a"
1807   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1808         (div:SCALARF
1809          (match_operand:SCALARF 1 "const_1_operand" "")
1810          (sqrt:SCALARF (match_operand:SCALARF 2 "register_operand" "f"))))]
1811   "ISA_HAS_FP4 && flag_unsafe_math_optimizations"
1812 {
1813   if (TARGET_FIX_SB1)
1814     return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1815   else
1816     return "rsqrt.<fmt>\t%0,%2";
1817 }
1818   [(set_attr "type" "frsqrt")
1819    (set_attr "mode" "<MODE>")
1820    (set (attr "length")
1821         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1822                       (const_int 8)
1823                       (const_int 4)))])
1824
1825 (define_insn "*rsqrt<mode>b"
1826   [(set (match_operand:SCALARF 0 "register_operand" "=f")
1827         (sqrt:SCALARF
1828          (div:SCALARF (match_operand:SCALARF 1 "const_1_operand" "")
1829                       (match_operand:SCALARF 2 "register_operand" "f"))))]
1830   "ISA_HAS_FP4 && flag_unsafe_math_optimizations"
1831 {
1832   if (TARGET_FIX_SB1)
1833     return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
1834   else
1835     return "rsqrt.<fmt>\t%0,%2";
1836 }
1837   [(set_attr "type" "frsqrt")
1838    (set_attr "mode" "<MODE>")
1839    (set (attr "length")
1840         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
1841                       (const_int 8)
1842                       (const_int 4)))])
1843 \f
1844 ;;
1845 ;;  ....................
1846 ;;
1847 ;;      ABSOLUTE VALUE
1848 ;;
1849 ;;  ....................
1850
1851 ;; Do not use the integer abs macro instruction, since that signals an
1852 ;; exception on -2147483648 (sigh).
1853
1854 (define_insn "abs<mode>2"
1855   [(set (match_operand:GPR 0 "register_operand" "=d")
1856         (abs:GPR (match_operand:GPR 1 "register_operand" "d")))]
1857   "!TARGET_MIPS16"
1858 {
1859   if (REGNO (operands[0]) == REGNO (operands[1]) && GENERATE_BRANCHLIKELY)
1860     return "%(bltzl\t%1,1f\;<d>subu\t%0,%.,%0\n%~1:%)";
1861   else
1862     return "%(bgez\t%1,1f\;move\t%0,%1\;<d>subu\t%0,%.,%0\n%~1:%)";
1863 }
1864   [(set_attr "type" "multi")
1865    (set_attr "mode" "<MODE>")
1866    (set_attr "length" "12")])
1867
1868 (define_insn "abs<mode>2"
1869   [(set (match_operand:ANYF 0 "register_operand" "=f")
1870         (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
1871   ""
1872   "abs.<fmt>\t%0,%1"
1873   [(set_attr "type" "fabs")
1874    (set_attr "mode" "<UNITMODE>")])
1875 \f
1876 ;;
1877 ;;  ....................
1878 ;;
1879 ;;      FIND FIRST BIT INSTRUCTION
1880 ;;
1881 ;;  ....................
1882 ;;
1883
1884 (define_insn "ffs<mode>2"
1885   [(set (match_operand:GPR 0 "register_operand" "=&d")
1886         (ffs:GPR (match_operand:GPR 1 "register_operand" "d")))
1887    (clobber (match_scratch:GPR 2 "=&d"))
1888    (clobber (match_scratch:GPR 3 "=&d"))]
1889   "!TARGET_MIPS16"
1890 {
1891   if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
1892     return "%(\
1893 move\t%0,%.\;\
1894 beq\t%1,%.,2f\n\
1895 %~1:\tand\t%2,%1,0x0001\;\
1896 <d>addu\t%0,%0,1\;\
1897 beq\t%2,%.,1b\;\
1898 <d>srl\t%1,%1,1\n\
1899 %~2:%)";
1900
1901   return "%(\
1902 move\t%0,%.\;\
1903 move\t%3,%1\;\
1904 beq\t%3,%.,2f\n\
1905 %~1:\tand\t%2,%3,0x0001\;\
1906 <d>addu\t%0,%0,1\;\
1907 beq\t%2,%.,1b\;\
1908 <d>srl\t%3,%3,1\n\
1909 %~2:%)";
1910 }
1911   [(set_attr "type" "multi")
1912    (set_attr "mode" "<MODE>")
1913    (set_attr "length" "28")])
1914 \f
1915 ;;
1916 ;;  ...................
1917 ;;
1918 ;;  Count leading zeroes.
1919 ;;
1920 ;;  ...................
1921 ;;
1922
1923 (define_insn "clz<mode>2"
1924   [(set (match_operand:GPR 0 "register_operand" "=d")
1925         (clz:GPR (match_operand:GPR 1 "register_operand" "d")))]
1926   "ISA_HAS_CLZ_CLO"
1927   "<d>clz\t%0,%1"
1928   [(set_attr "type" "clz")
1929    (set_attr "mode" "<MODE>")])
1930 \f
1931 ;;
1932 ;;  ....................
1933 ;;
1934 ;;      NEGATION and ONE'S COMPLEMENT
1935 ;;
1936 ;;  ....................
1937
1938 (define_insn "negsi2"
1939   [(set (match_operand:SI 0 "register_operand" "=d")
1940         (neg:SI (match_operand:SI 1 "register_operand" "d")))]
1941   ""
1942 {
1943   if (TARGET_MIPS16)
1944     return "neg\t%0,%1";
1945   else
1946     return "subu\t%0,%.,%1";
1947 }
1948   [(set_attr "type"     "arith")
1949    (set_attr "mode"     "SI")])
1950
1951 (define_insn "negdi2"
1952   [(set (match_operand:DI 0 "register_operand" "=d")
1953         (neg:DI (match_operand:DI 1 "register_operand" "d")))]
1954   "TARGET_64BIT && !TARGET_MIPS16"
1955   "dsubu\t%0,%.,%1"
1956   [(set_attr "type"     "arith")
1957    (set_attr "mode"     "DI")])
1958
1959 (define_insn "neg<mode>2"
1960   [(set (match_operand:ANYF 0 "register_operand" "=f")
1961         (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
1962   ""
1963   "neg.<fmt>\t%0,%1"
1964   [(set_attr "type" "fneg")
1965    (set_attr "mode" "<UNITMODE>")])
1966
1967 (define_insn "one_cmpl<mode>2"
1968   [(set (match_operand:GPR 0 "register_operand" "=d")
1969         (not:GPR (match_operand:GPR 1 "register_operand" "d")))]
1970   ""
1971 {
1972   if (TARGET_MIPS16)
1973     return "not\t%0,%1";
1974   else
1975     return "nor\t%0,%.,%1";
1976 }
1977   [(set_attr "type" "arith")
1978    (set_attr "mode" "<MODE>")])
1979 \f
1980 ;;
1981 ;;  ....................
1982 ;;
1983 ;;      LOGICAL
1984 ;;
1985 ;;  ....................
1986 ;;
1987
1988 ;; Many of these instructions use trivial define_expands, because we
1989 ;; want to use a different set of constraints when TARGET_MIPS16.
1990
1991 (define_expand "and<mode>3"
1992   [(set (match_operand:GPR 0 "register_operand")
1993         (and:GPR (match_operand:GPR 1 "register_operand")
1994                  (match_operand:GPR 2 "uns_arith_operand")))]
1995   ""
1996 {
1997   if (TARGET_MIPS16)
1998     operands[2] = force_reg (<MODE>mode, operands[2]);
1999 })
2000
2001 (define_insn "*and<mode>3"
2002   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2003         (and:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2004                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2005   "!TARGET_MIPS16"
2006   "@
2007    and\t%0,%1,%2
2008    andi\t%0,%1,%x2"
2009   [(set_attr "type" "arith")
2010    (set_attr "mode" "<MODE>")])
2011
2012 (define_insn "*and<mode>3_mips16"
2013   [(set (match_operand:GPR 0 "register_operand" "=d")
2014         (and:GPR (match_operand:GPR 1 "register_operand" "%0")
2015                  (match_operand:GPR 2 "register_operand" "d")))]
2016   "TARGET_MIPS16"
2017   "and\t%0,%2"
2018   [(set_attr "type" "arith")
2019    (set_attr "mode" "<MODE>")])
2020
2021 (define_expand "ior<mode>3"
2022   [(set (match_operand:GPR 0 "register_operand")
2023         (ior:GPR (match_operand:GPR 1 "register_operand")
2024                  (match_operand:GPR 2 "uns_arith_operand")))]
2025   ""
2026 {
2027   if (TARGET_MIPS16)
2028     operands[2] = force_reg (<MODE>mode, operands[2]);
2029 })
2030
2031 (define_insn "*ior<mode>3"
2032   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2033         (ior:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2034                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2035   "!TARGET_MIPS16"
2036   "@
2037    or\t%0,%1,%2
2038    ori\t%0,%1,%x2"
2039   [(set_attr "type" "arith")
2040    (set_attr "mode" "<MODE>")])
2041
2042 (define_insn "*ior<mode>3_mips16"
2043   [(set (match_operand:GPR 0 "register_operand" "=d")
2044         (ior:GPR (match_operand:GPR 1 "register_operand" "%0")
2045                  (match_operand:GPR 2 "register_operand" "d")))]
2046   "TARGET_MIPS16"
2047   "or\t%0,%2"
2048   [(set_attr "type" "arith")
2049    (set_attr "mode" "<MODE>")])
2050
2051 (define_expand "xor<mode>3"
2052   [(set (match_operand:GPR 0 "register_operand")
2053         (xor:GPR (match_operand:GPR 1 "register_operand")
2054                  (match_operand:GPR 2 "uns_arith_operand")))]
2055   ""
2056   "")
2057
2058 (define_insn ""
2059   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2060         (xor:GPR (match_operand:GPR 1 "register_operand" "%d,d")
2061                  (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
2062   "!TARGET_MIPS16"
2063   "@
2064    xor\t%0,%1,%2
2065    xori\t%0,%1,%x2"
2066   [(set_attr "type" "arith")
2067    (set_attr "mode" "<MODE>")])
2068
2069 (define_insn ""
2070   [(set (match_operand:GPR 0 "register_operand" "=d,t,t")
2071         (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
2072                  (match_operand:GPR 2 "uns_arith_operand" "d,K,d")))]
2073   "TARGET_MIPS16"
2074   "@
2075    xor\t%0,%2
2076    cmpi\t%1,%2
2077    cmp\t%1,%2"
2078   [(set_attr "type" "arith")
2079    (set_attr "mode" "<MODE>")
2080    (set_attr_alternative "length"
2081                 [(const_int 4)
2082                  (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
2083                                (const_int 4)
2084                                (const_int 8))
2085                  (const_int 4)])])
2086
2087 (define_insn "*nor<mode>3"
2088   [(set (match_operand:GPR 0 "register_operand" "=d")
2089         (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
2090                  (not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
2091   "!TARGET_MIPS16"
2092   "nor\t%0,%1,%2"
2093   [(set_attr "type" "arith")
2094    (set_attr "mode" "<MODE>")])
2095 \f
2096 ;;
2097 ;;  ....................
2098 ;;
2099 ;;      TRUNCATION
2100 ;;
2101 ;;  ....................
2102
2103
2104
2105 (define_insn "truncdfsf2"
2106   [(set (match_operand:SF 0 "register_operand" "=f")
2107         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2108   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2109   "cvt.s.d\t%0,%1"
2110   [(set_attr "type"     "fcvt")
2111    (set_attr "mode"     "SF")])
2112
2113 ;; Integer truncation patterns.  Truncating SImode values to smaller
2114 ;; modes is a no-op, as it is for most other GCC ports.  Truncating
2115 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
2116 ;; need to make sure that the lower 32 bits are properly sign-extended
2117 ;; (see TRULY_NOOP_TRUNCATION).  Truncating DImode values into modes
2118 ;; smaller than SImode is equivalent to two separate truncations:
2119 ;;
2120 ;;                        A       B
2121 ;;    DI ---> HI  ==  DI ---> SI ---> HI
2122 ;;    DI ---> QI  ==  DI ---> SI ---> QI
2123 ;;
2124 ;; Step A needs a real instruction but step B does not.
2125
2126 (define_insn "truncdisi2"
2127   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
2128         (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
2129   "TARGET_64BIT"
2130   "@
2131     sll\t%0,%1,0
2132     sw\t%1,%0"
2133   [(set_attr "type" "shift,store")
2134    (set_attr "mode" "SI")
2135    (set_attr "extended_mips16" "yes,*")])
2136
2137 (define_insn "truncdihi2"
2138   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
2139         (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
2140   "TARGET_64BIT"
2141   "@
2142     sll\t%0,%1,0
2143     sh\t%1,%0"
2144   [(set_attr "type" "shift,store")
2145    (set_attr "mode" "SI")
2146    (set_attr "extended_mips16" "yes,*")])
2147
2148 (define_insn "truncdiqi2"
2149   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
2150         (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
2151   "TARGET_64BIT"
2152   "@
2153     sll\t%0,%1,0
2154     sb\t%1,%0"
2155   [(set_attr "type" "shift,store")
2156    (set_attr "mode" "SI")
2157    (set_attr "extended_mips16" "yes,*")])
2158
2159 ;; Combiner patterns to optimize shift/truncate combinations.
2160
2161 (define_insn ""
2162   [(set (match_operand:SI 0 "register_operand" "=d")
2163         (truncate:SI
2164           (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
2165                        (match_operand:DI 2 "const_arith_operand" ""))))]
2166   "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
2167   "dsra\t%0,%1,%2"
2168   [(set_attr "type" "shift")
2169    (set_attr "mode" "SI")])
2170
2171 (define_insn ""
2172   [(set (match_operand:SI 0 "register_operand" "=d")
2173         (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
2174                                   (const_int 32))))]
2175   "TARGET_64BIT && !TARGET_MIPS16"
2176   "dsra\t%0,%1,32"
2177   [(set_attr "type" "shift")
2178    (set_attr "mode" "SI")])
2179
2180
2181 ;; Combiner patterns for truncate/sign_extend combinations.  They use
2182 ;; the shift/truncate patterns above.
2183
2184 (define_insn_and_split ""
2185   [(set (match_operand:SI 0 "register_operand" "=d")
2186         (sign_extend:SI
2187             (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
2188   "TARGET_64BIT && !TARGET_MIPS16"
2189   "#"
2190   "&& reload_completed"
2191   [(set (match_dup 2)
2192         (ashift:DI (match_dup 1)
2193                    (const_int 48)))
2194    (set (match_dup 0)
2195         (truncate:SI (ashiftrt:DI (match_dup 2)
2196                                   (const_int 48))))]
2197   { operands[2] = gen_lowpart (DImode, operands[0]); })
2198
2199 (define_insn_and_split ""
2200   [(set (match_operand:SI 0 "register_operand" "=d")
2201         (sign_extend:SI
2202             (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
2203   "TARGET_64BIT && !TARGET_MIPS16"
2204   "#"
2205   "&& reload_completed"
2206   [(set (match_dup 2)
2207         (ashift:DI (match_dup 1)
2208                    (const_int 56)))
2209    (set (match_dup 0)
2210         (truncate:SI (ashiftrt:DI (match_dup 2)
2211                                   (const_int 56))))]
2212   { operands[2] = gen_lowpart (DImode, operands[0]); })
2213
2214
2215 ;; Combiner patterns to optimize truncate/zero_extend combinations.
2216
2217 (define_insn ""
2218   [(set (match_operand:SI 0 "register_operand" "=d")
2219         (zero_extend:SI (truncate:HI
2220                          (match_operand:DI 1 "register_operand" "d"))))]
2221   "TARGET_64BIT && !TARGET_MIPS16"
2222   "andi\t%0,%1,0xffff"
2223   [(set_attr "type"     "arith")
2224    (set_attr "mode"     "SI")])
2225
2226 (define_insn ""
2227   [(set (match_operand:SI 0 "register_operand" "=d")
2228         (zero_extend:SI (truncate:QI
2229                          (match_operand:DI 1 "register_operand" "d"))))]
2230   "TARGET_64BIT && !TARGET_MIPS16"
2231   "andi\t%0,%1,0xff"
2232   [(set_attr "type"     "arith")
2233    (set_attr "mode"     "SI")])
2234
2235 (define_insn ""
2236   [(set (match_operand:HI 0 "register_operand" "=d")
2237         (zero_extend:HI (truncate:QI
2238                          (match_operand:DI 1 "register_operand" "d"))))]
2239   "TARGET_64BIT && !TARGET_MIPS16"
2240   "andi\t%0,%1,0xff"
2241   [(set_attr "type"     "arith")
2242    (set_attr "mode"     "HI")])
2243 \f
2244 ;;
2245 ;;  ....................
2246 ;;
2247 ;;      ZERO EXTENSION
2248 ;;
2249 ;;  ....................
2250
2251 ;; Extension insns.
2252 ;; Those for integer source operand are ordered widest source type first.
2253
2254 (define_insn_and_split "zero_extendsidi2"
2255   [(set (match_operand:DI 0 "register_operand" "=d")
2256         (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
2257   "TARGET_64BIT"
2258   "#"
2259   "&& reload_completed"
2260   [(set (match_dup 0)
2261         (ashift:DI (match_dup 1) (const_int 32)))
2262    (set (match_dup 0)
2263         (lshiftrt:DI (match_dup 0) (const_int 32)))]
2264   "operands[1] = gen_lowpart (DImode, operands[1]);"
2265   [(set_attr "type" "multi")
2266    (set_attr "mode" "DI")
2267    (set_attr "length" "8")])
2268
2269 (define_insn "*zero_extendsidi2_mem"
2270   [(set (match_operand:DI 0 "register_operand" "=d")
2271         (zero_extend:DI (match_operand:SI 1 "memory_operand" "W")))]
2272   "TARGET_64BIT"
2273   "lwu\t%0,%1"
2274   [(set_attr "type"     "load")
2275    (set_attr "mode"     "DI")])
2276
2277 (define_expand "zero_extendhisi2"
2278   [(set (match_operand:SI 0 "register_operand")
2279         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2280   ""
2281 {
2282   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2283     {
2284       rtx op = gen_lowpart (SImode, operands[1]);
2285       rtx temp = force_reg (SImode, GEN_INT (0xffff));
2286
2287       emit_insn (gen_andsi3 (operands[0], op, temp));
2288       DONE;
2289     }
2290 })
2291
2292 (define_insn ""
2293   [(set (match_operand:SI 0 "register_operand" "=d,d")
2294         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2295   "!TARGET_MIPS16"
2296   "@
2297    andi\t%0,%1,0xffff
2298    lhu\t%0,%1"
2299   [(set_attr "type"     "arith,load")
2300    (set_attr "mode"     "SI")
2301    (set_attr "length"   "4,*")])
2302
2303 (define_insn ""
2304   [(set (match_operand:SI 0 "register_operand" "=d")
2305         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2306   "TARGET_MIPS16"
2307   "lhu\t%0,%1"
2308   [(set_attr "type"     "load")
2309    (set_attr "mode"     "SI")])
2310
2311 (define_expand "zero_extendhidi2"
2312   [(set (match_operand:DI 0 "register_operand")
2313         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2314   "TARGET_64BIT"
2315 {
2316   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2317     {
2318       rtx op = gen_lowpart (DImode, operands[1]);
2319       rtx temp = force_reg (DImode, GEN_INT (0xffff));
2320
2321       emit_insn (gen_anddi3 (operands[0], op, temp));
2322       DONE;
2323     }
2324 })
2325
2326 (define_insn ""
2327   [(set (match_operand:DI 0 "register_operand" "=d,d")
2328         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2329   "TARGET_64BIT && !TARGET_MIPS16"
2330   "@
2331    andi\t%0,%1,0xffff
2332    lhu\t%0,%1"
2333   [(set_attr "type"     "arith,load")
2334    (set_attr "mode"     "DI")
2335    (set_attr "length"   "4,*")])
2336
2337 (define_insn ""
2338   [(set (match_operand:DI 0 "register_operand" "=d")
2339         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2340   "TARGET_64BIT && TARGET_MIPS16"
2341   "lhu\t%0,%1"
2342   [(set_attr "type"     "load")
2343    (set_attr "mode"     "DI")])
2344
2345 (define_expand "zero_extendqihi2"
2346   [(set (match_operand:HI 0 "register_operand")
2347         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2348   ""
2349 {
2350   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2351     {
2352       rtx op0 = gen_lowpart (SImode, operands[0]);
2353       rtx op1 = gen_lowpart (SImode, operands[1]);
2354       rtx temp = force_reg (SImode, GEN_INT (0xff));
2355
2356       emit_insn (gen_andsi3 (op0, op1, temp));
2357       DONE;
2358     }
2359 })
2360
2361 (define_insn ""
2362   [(set (match_operand:HI 0 "register_operand" "=d,d")
2363         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2364   "!TARGET_MIPS16"
2365   "@
2366    andi\t%0,%1,0x00ff
2367    lbu\t%0,%1"
2368   [(set_attr "type"     "arith,load")
2369    (set_attr "mode"     "HI")
2370    (set_attr "length"   "4,*")])
2371
2372 (define_insn ""
2373   [(set (match_operand:HI 0 "register_operand" "=d")
2374         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2375   "TARGET_MIPS16"
2376   "lbu\t%0,%1"
2377   [(set_attr "type"     "load")
2378    (set_attr "mode"     "HI")])
2379
2380 (define_expand "zero_extendqisi2"
2381   [(set (match_operand:SI 0 "register_operand")
2382         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
2383   ""
2384 {
2385   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2386     {
2387       rtx op = gen_lowpart (SImode, operands[1]);
2388       rtx temp = force_reg (SImode, GEN_INT (0xff));
2389
2390       emit_insn (gen_andsi3 (operands[0], op, temp));
2391       DONE;
2392     }
2393 })
2394
2395 (define_insn ""
2396   [(set (match_operand:SI 0 "register_operand" "=d,d")
2397         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2398   "!TARGET_MIPS16"
2399   "@
2400    andi\t%0,%1,0x00ff
2401    lbu\t%0,%1"
2402   [(set_attr "type"     "arith,load")
2403    (set_attr "mode"     "SI")
2404    (set_attr "length"   "4,*")])
2405
2406 (define_insn ""
2407   [(set (match_operand:SI 0 "register_operand" "=d")
2408         (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2409   "TARGET_MIPS16"
2410   "lbu\t%0,%1"
2411   [(set_attr "type"     "load")
2412    (set_attr "mode"     "SI")])
2413
2414 (define_expand "zero_extendqidi2"
2415   [(set (match_operand:DI 0 "register_operand")
2416         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
2417   "TARGET_64BIT"
2418 {
2419   if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
2420     {
2421       rtx op = gen_lowpart (DImode, operands[1]);
2422       rtx temp = force_reg (DImode, GEN_INT (0xff));
2423
2424       emit_insn (gen_anddi3 (operands[0], op, temp));
2425       DONE;
2426     }
2427 })
2428
2429 (define_insn ""
2430   [(set (match_operand:DI 0 "register_operand" "=d,d")
2431         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2432   "TARGET_64BIT && !TARGET_MIPS16"
2433   "@
2434    andi\t%0,%1,0x00ff
2435    lbu\t%0,%1"
2436   [(set_attr "type"     "arith,load")
2437    (set_attr "mode"     "DI")
2438    (set_attr "length"   "4,*")])
2439
2440 (define_insn ""
2441   [(set (match_operand:DI 0 "register_operand" "=d")
2442         (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
2443   "TARGET_64BIT && TARGET_MIPS16"
2444   "lbu\t%0,%1"
2445   [(set_attr "type"     "load")
2446    (set_attr "mode"     "DI")])
2447 \f
2448 ;;
2449 ;;  ....................
2450 ;;
2451 ;;      SIGN EXTENSION
2452 ;;
2453 ;;  ....................
2454
2455 ;; Extension insns.
2456 ;; Those for integer source operand are ordered widest source type first.
2457
2458 ;; When TARGET_64BIT, all SImode integer registers should already be in
2459 ;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2).  We can
2460 ;; therefore get rid of register->register instructions if we constrain
2461 ;; the source to be in the same register as the destination.
2462 ;;
2463 ;; The register alternative has type "arith" so that the pre-reload
2464 ;; scheduler will treat it as a move.  This reflects what happens if
2465 ;; the register alternative needs a reload.
2466 (define_insn_and_split "extendsidi2"
2467   [(set (match_operand:DI 0 "register_operand" "=d,d")
2468         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))]
2469   "TARGET_64BIT"
2470   "@
2471    #
2472    lw\t%0,%1"
2473   "&& reload_completed && register_operand (operands[1], VOIDmode)"
2474   [(const_int 0)]
2475 {
2476   emit_note (NOTE_INSN_DELETED);
2477   DONE;
2478 }
2479   [(set_attr "type" "arith,load")
2480    (set_attr "mode" "DI")])
2481
2482 ;; These patterns originally accepted general_operands, however, slightly
2483 ;; better code is generated by only accepting register_operands, and then
2484 ;; letting combine generate the lh and lb insns.
2485
2486 ;; These expanders originally put values in registers first. We split
2487 ;; all non-mem patterns after reload.
2488
2489 (define_expand "extendhidi2"
2490   [(set (match_operand:DI 0 "register_operand")
2491         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
2492   "TARGET_64BIT"
2493   "")
2494
2495 (define_insn "*extendhidi2"
2496   [(set (match_operand:DI 0 "register_operand" "=d")
2497         (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
2498   "TARGET_64BIT"
2499   "#")
2500
2501 (define_split
2502   [(set (match_operand:DI 0 "register_operand")
2503         (sign_extend:DI (match_operand:HI 1 "register_operand")))]
2504   "TARGET_64BIT && reload_completed"
2505   [(set (match_dup 0)
2506         (ashift:DI (match_dup 1) (const_int 48)))
2507    (set (match_dup 0)
2508         (ashiftrt:DI (match_dup 0) (const_int 48)))]
2509   "operands[1] = gen_lowpart (DImode, operands[1]);")
2510
2511 (define_insn "*extendhidi2_mem"
2512   [(set (match_operand:DI 0 "register_operand" "=d")
2513         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2514   "TARGET_64BIT"
2515   "lh\t%0,%1"
2516   [(set_attr "type"     "load")
2517    (set_attr "mode"     "DI")])
2518
2519 (define_expand "extendhisi2"
2520   [(set (match_operand:SI 0 "register_operand")
2521         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
2522   ""
2523 {
2524   if (ISA_HAS_SEB_SEH)
2525     {
2526       emit_insn (gen_extendhisi2_hw (operands[0],
2527                                      force_reg (HImode, operands[1])));
2528       DONE;
2529     }
2530 })
2531
2532 (define_insn "*extendhisi2"
2533   [(set (match_operand:SI 0 "register_operand" "=d")
2534         (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
2535   ""
2536   "#")
2537
2538 (define_split
2539   [(set (match_operand:SI 0 "register_operand")
2540         (sign_extend:SI (match_operand:HI 1 "register_operand")))]
2541   "reload_completed"
2542   [(set (match_dup 0)
2543         (ashift:SI (match_dup 1) (const_int 16)))
2544    (set (match_dup 0)
2545         (ashiftrt:SI (match_dup 0) (const_int 16)))]
2546   "operands[1] = gen_lowpart (SImode, operands[1]);")
2547
2548 (define_insn "extendhisi2_mem"
2549   [(set (match_operand:SI 0 "register_operand" "=d")
2550         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2551   ""
2552   "lh\t%0,%1"
2553   [(set_attr "type"     "load")
2554    (set_attr "mode"     "SI")])
2555
2556 (define_insn "extendhisi2_hw"
2557   [(set (match_operand:SI 0 "register_operand" "=r")
2558         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
2559   "ISA_HAS_SEB_SEH"
2560   "seh\t%0,%1"
2561   [(set_attr "type" "arith")
2562    (set_attr "mode" "SI")])
2563
2564 (define_expand "extendqihi2"
2565   [(set (match_operand:HI 0 "register_operand")
2566         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
2567   ""
2568   "")
2569
2570 (define_insn "*extendqihi2"
2571   [(set (match_operand:HI 0 "register_operand" "=d")
2572         (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))]
2573   ""
2574   "#")
2575
2576 (define_split
2577   [(set (match_operand:HI 0 "register_operand")
2578         (sign_extend:HI (match_operand:QI 1 "register_operand")))]
2579   "reload_completed"
2580   [(set (match_dup 0)
2581         (ashift:SI (match_dup 1) (const_int 24)))
2582    (set (match_dup 0)
2583         (ashiftrt:SI (match_dup 0) (const_int 24)))]
2584   "operands[0] = gen_lowpart (SImode, operands[0]);
2585    operands[1] = gen_lowpart (SImode, operands[1]);")
2586
2587 (define_insn "*extendqihi2_internal_mem"
2588   [(set (match_operand:HI 0 "register_operand" "=d")
2589         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2590   ""
2591   "lb\t%0,%1"
2592   [(set_attr "type"     "load")
2593    (set_attr "mode"     "SI")])
2594
2595
2596 (define_expand "extendqisi2"
2597   [(set (match_operand:SI 0 "register_operand")
2598         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
2599   ""
2600 {
2601   if (ISA_HAS_SEB_SEH)
2602     {
2603       emit_insn (gen_extendqisi2_hw (operands[0],
2604                                      force_reg (QImode, operands[1])));
2605       DONE;
2606     }
2607 })
2608
2609 (define_insn "*extendqisi2"
2610   [(set (match_operand:SI 0 "register_operand" "=d")
2611         (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
2612   ""
2613   "#")
2614
2615 (define_split
2616   [(set (match_operand:SI 0 "register_operand")
2617         (sign_extend:SI (match_operand:QI 1 "register_operand")))]
2618   "reload_completed"
2619   [(set (match_dup 0)
2620         (ashift:SI (match_dup 1) (const_int 24)))
2621    (set (match_dup 0)
2622         (ashiftrt:SI (match_dup 0) (const_int 24)))]
2623   "operands[1] = gen_lowpart (SImode, operands[1]);")
2624
2625 (define_insn "*extendqisi2_mem"
2626   [(set (match_operand:SI 0 "register_operand" "=d")
2627         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2628   ""
2629   "lb\t%0,%1"
2630   [(set_attr "type"     "load")
2631    (set_attr "mode"     "SI")])
2632
2633 (define_insn "extendqisi2_hw"
2634   [(set (match_operand:SI 0 "register_operand" "=r")
2635         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
2636   "ISA_HAS_SEB_SEH"
2637   "seb\t%0,%1"
2638   [(set_attr "type" "arith")
2639    (set_attr "mode" "SI")])
2640
2641 (define_expand "extendqidi2"
2642   [(set (match_operand:DI 0 "register_operand")
2643         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
2644   "TARGET_64BIT"
2645   "")
2646
2647 (define_insn "*extendqidi2"
2648   [(set (match_operand:DI 0 "register_operand" "=d")
2649         (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
2650   "TARGET_64BIT"
2651   "#")
2652
2653 (define_split
2654   [(set (match_operand:DI 0 "register_operand")
2655         (sign_extend:DI (match_operand:QI 1 "register_operand")))]
2656   "TARGET_64BIT && reload_completed"
2657   [(set (match_dup 0)
2658         (ashift:DI (match_dup 1) (const_int 56)))
2659    (set (match_dup 0)
2660         (ashiftrt:DI (match_dup 0) (const_int 56)))]
2661   "operands[1] = gen_lowpart (DImode, operands[1]);")
2662
2663 (define_insn "*extendqidi2_mem"
2664   [(set (match_operand:DI 0 "register_operand" "=d")
2665         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
2666   "TARGET_64BIT"
2667   "lb\t%0,%1"
2668   [(set_attr "type"     "load")
2669    (set_attr "mode"     "DI")])
2670
2671 (define_insn "extendsfdf2"
2672   [(set (match_operand:DF 0 "register_operand" "=f")
2673         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2674   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2675   "cvt.d.s\t%0,%1"
2676   [(set_attr "type"     "fcvt")
2677    (set_attr "mode"     "DF")])
2678 \f
2679 ;;
2680 ;;  ....................
2681 ;;
2682 ;;      CONVERSIONS
2683 ;;
2684 ;;  ....................
2685
2686 (define_expand "fix_truncdfsi2"
2687   [(set (match_operand:SI 0 "register_operand")
2688         (fix:SI (match_operand:DF 1 "register_operand")))]
2689   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2690 {
2691   if (!ISA_HAS_TRUNC_W)
2692     {
2693       emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
2694       DONE;
2695     }
2696 })
2697
2698 (define_insn "fix_truncdfsi2_insn"
2699   [(set (match_operand:SI 0 "register_operand" "=f")
2700         (fix:SI (match_operand:DF 1 "register_operand" "f")))]
2701   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
2702   "trunc.w.d %0,%1"
2703   [(set_attr "type"     "fcvt")
2704    (set_attr "mode"     "DF")
2705    (set_attr "length"   "4")])
2706
2707 (define_insn "fix_truncdfsi2_macro"
2708   [(set (match_operand:SI 0 "register_operand" "=f")
2709         (fix:SI (match_operand:DF 1 "register_operand" "f")))
2710    (clobber (match_scratch:DF 2 "=d"))]
2711   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
2712 {
2713   if (set_nomacro)
2714     return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
2715   else
2716     return "trunc.w.d %0,%1,%2";
2717 }
2718   [(set_attr "type"     "fcvt")
2719    (set_attr "mode"     "DF")
2720    (set_attr "length"   "36")])
2721
2722 (define_expand "fix_truncsfsi2"
2723   [(set (match_operand:SI 0 "register_operand")
2724         (fix:SI (match_operand:SF 1 "register_operand")))]
2725   "TARGET_HARD_FLOAT"
2726 {
2727   if (!ISA_HAS_TRUNC_W)
2728     {
2729       emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
2730       DONE;
2731     }
2732 })
2733
2734 (define_insn "fix_truncsfsi2_insn"
2735   [(set (match_operand:SI 0 "register_operand" "=f")
2736         (fix:SI (match_operand:SF 1 "register_operand" "f")))]
2737   "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
2738   "trunc.w.s %0,%1"
2739   [(set_attr "type"     "fcvt")
2740    (set_attr "mode"     "DF")
2741    (set_attr "length"   "4")])
2742
2743 (define_insn "fix_truncsfsi2_macro"
2744   [(set (match_operand:SI 0 "register_operand" "=f")
2745         (fix:SI (match_operand:SF 1 "register_operand" "f")))
2746    (clobber (match_scratch:SF 2 "=d"))]
2747   "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
2748 {
2749   if (set_nomacro)
2750     return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
2751   else
2752     return "trunc.w.s %0,%1,%2";
2753 }
2754   [(set_attr "type"     "fcvt")
2755    (set_attr "mode"     "DF")
2756    (set_attr "length"   "36")])
2757
2758
2759 (define_insn "fix_truncdfdi2"
2760   [(set (match_operand:DI 0 "register_operand" "=f")
2761         (fix:DI (match_operand:DF 1 "register_operand" "f")))]
2762   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2763   "trunc.l.d %0,%1"
2764   [(set_attr "type"     "fcvt")
2765    (set_attr "mode"     "DF")
2766    (set_attr "length"   "4")])
2767
2768
2769 (define_insn "fix_truncsfdi2"
2770   [(set (match_operand:DI 0 "register_operand" "=f")
2771         (fix:DI (match_operand:SF 1 "register_operand" "f")))]
2772   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2773   "trunc.l.s %0,%1"
2774   [(set_attr "type"     "fcvt")
2775    (set_attr "mode"     "SF")
2776    (set_attr "length"   "4")])
2777
2778
2779 (define_insn "floatsidf2"
2780   [(set (match_operand:DF 0 "register_operand" "=f")
2781         (float:DF (match_operand:SI 1 "register_operand" "f")))]
2782   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2783   "cvt.d.w\t%0,%1"
2784   [(set_attr "type"     "fcvt")
2785    (set_attr "mode"     "DF")
2786    (set_attr "length"   "4")])
2787
2788
2789 (define_insn "floatdidf2"
2790   [(set (match_operand:DF 0 "register_operand" "=f")
2791         (float:DF (match_operand:DI 1 "register_operand" "f")))]
2792   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2793   "cvt.d.l\t%0,%1"
2794   [(set_attr "type"     "fcvt")
2795    (set_attr "mode"     "DF")
2796    (set_attr "length"   "4")])
2797
2798
2799 (define_insn "floatsisf2"
2800   [(set (match_operand:SF 0 "register_operand" "=f")
2801         (float:SF (match_operand:SI 1 "register_operand" "f")))]
2802   "TARGET_HARD_FLOAT"
2803   "cvt.s.w\t%0,%1"
2804   [(set_attr "type"     "fcvt")
2805    (set_attr "mode"     "SF")
2806    (set_attr "length"   "4")])
2807
2808
2809 (define_insn "floatdisf2"
2810   [(set (match_operand:SF 0 "register_operand" "=f")
2811         (float:SF (match_operand:DI 1 "register_operand" "f")))]
2812   "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
2813   "cvt.s.l\t%0,%1"
2814   [(set_attr "type"     "fcvt")
2815    (set_attr "mode"     "SF")
2816    (set_attr "length"   "4")])
2817
2818
2819 (define_expand "fixuns_truncdfsi2"
2820   [(set (match_operand:SI 0 "register_operand")
2821         (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
2822   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2823 {
2824   rtx reg1 = gen_reg_rtx (DFmode);
2825   rtx reg2 = gen_reg_rtx (DFmode);
2826   rtx reg3 = gen_reg_rtx (SImode);
2827   rtx label1 = gen_label_rtx ();
2828   rtx label2 = gen_label_rtx ();
2829   REAL_VALUE_TYPE offset;
2830
2831   real_2expN (&offset, 31);
2832
2833   if (reg1)                     /* Turn off complaints about unreached code.  */
2834     {
2835       emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2836       do_pending_stack_adjust ();
2837
2838       emit_insn (gen_cmpdf (operands[1], reg1));
2839       emit_jump_insn (gen_bge (label1));
2840
2841       emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
2842       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2843                                    gen_rtx_LABEL_REF (VOIDmode, label2)));
2844       emit_barrier ();
2845
2846       emit_label (label1);
2847       emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2848       emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2849                                      (BITMASK_HIGH, SImode)));
2850
2851       emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
2852       emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2853
2854       emit_label (label2);
2855
2856       /* Allow REG_NOTES to be set on last insn (labels don't have enough
2857          fields, and can't be used for REG_NOTES anyway).  */
2858       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2859       DONE;
2860     }
2861 })
2862
2863
2864 (define_expand "fixuns_truncdfdi2"
2865   [(set (match_operand:DI 0 "register_operand")
2866         (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
2867   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2868 {
2869   rtx reg1 = gen_reg_rtx (DFmode);
2870   rtx reg2 = gen_reg_rtx (DFmode);
2871   rtx reg3 = gen_reg_rtx (DImode);
2872   rtx label1 = gen_label_rtx ();
2873   rtx label2 = gen_label_rtx ();
2874   REAL_VALUE_TYPE offset;
2875
2876   real_2expN (&offset, 63);
2877
2878   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
2879   do_pending_stack_adjust ();
2880
2881   emit_insn (gen_cmpdf (operands[1], reg1));
2882   emit_jump_insn (gen_bge (label1));
2883
2884   emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
2885   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2886                                gen_rtx_LABEL_REF (VOIDmode, label2)));
2887   emit_barrier ();
2888
2889   emit_label (label1);
2890   emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
2891   emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
2892   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2893
2894   emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
2895   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2896
2897   emit_label (label2);
2898
2899   /* Allow REG_NOTES to be set on last insn (labels don't have enough
2900      fields, and can't be used for REG_NOTES anyway).  */
2901   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2902   DONE;
2903 })
2904
2905
2906 (define_expand "fixuns_truncsfsi2"
2907   [(set (match_operand:SI 0 "register_operand")
2908         (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
2909   "TARGET_HARD_FLOAT"
2910 {
2911   rtx reg1 = gen_reg_rtx (SFmode);
2912   rtx reg2 = gen_reg_rtx (SFmode);
2913   rtx reg3 = gen_reg_rtx (SImode);
2914   rtx label1 = gen_label_rtx ();
2915   rtx label2 = gen_label_rtx ();
2916   REAL_VALUE_TYPE offset;
2917
2918   real_2expN (&offset, 31);
2919
2920   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2921   do_pending_stack_adjust ();
2922
2923   emit_insn (gen_cmpsf (operands[1], reg1));
2924   emit_jump_insn (gen_bge (label1));
2925
2926   emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
2927   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2928                                gen_rtx_LABEL_REF (VOIDmode, label2)));
2929   emit_barrier ();
2930
2931   emit_label (label1);
2932   emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2933   emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
2934                                  (BITMASK_HIGH, SImode)));
2935
2936   emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
2937   emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
2938
2939   emit_label (label2);
2940
2941   /* Allow REG_NOTES to be set on last insn (labels don't have enough
2942      fields, and can't be used for REG_NOTES anyway).  */
2943   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2944   DONE;
2945 })
2946
2947
2948 (define_expand "fixuns_truncsfdi2"
2949   [(set (match_operand:DI 0 "register_operand")
2950         (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
2951   "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
2952 {
2953   rtx reg1 = gen_reg_rtx (SFmode);
2954   rtx reg2 = gen_reg_rtx (SFmode);
2955   rtx reg3 = gen_reg_rtx (DImode);
2956   rtx label1 = gen_label_rtx ();
2957   rtx label2 = gen_label_rtx ();
2958   REAL_VALUE_TYPE offset;
2959
2960   real_2expN (&offset, 63);
2961
2962   emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
2963   do_pending_stack_adjust ();
2964
2965   emit_insn (gen_cmpsf (operands[1], reg1));
2966   emit_jump_insn (gen_bge (label1));
2967
2968   emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
2969   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
2970                                gen_rtx_LABEL_REF (VOIDmode, label2)));
2971   emit_barrier ();
2972
2973   emit_label (label1);
2974   emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
2975   emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
2976   emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
2977
2978   emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
2979   emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
2980
2981   emit_label (label2);
2982
2983   /* Allow REG_NOTES to be set on last insn (labels don't have enough
2984      fields, and can't be used for REG_NOTES anyway).  */
2985   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
2986   DONE;
2987 })
2988 \f
2989 ;;
2990 ;;  ....................
2991 ;;
2992 ;;      DATA MOVEMENT
2993 ;;
2994 ;;  ....................
2995
2996 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
2997
2998 (define_expand "extv"
2999   [(set (match_operand 0 "register_operand")
3000         (sign_extract (match_operand:QI 1 "memory_operand")
3001                       (match_operand 2 "immediate_operand")
3002                       (match_operand 3 "immediate_operand")))]
3003   "!TARGET_MIPS16"
3004 {
3005   if (mips_expand_unaligned_load (operands[0], operands[1],
3006                                   INTVAL (operands[2]),
3007                                   INTVAL (operands[3])))
3008     DONE;
3009   else
3010     FAIL;
3011 })
3012
3013 (define_expand "extzv"
3014   [(set (match_operand 0 "register_operand")
3015         (zero_extract (match_operand:QI 1 "memory_operand")
3016                       (match_operand 2 "immediate_operand")
3017                       (match_operand 3 "immediate_operand")))]
3018   "!TARGET_MIPS16"
3019 {
3020   if (mips_expand_unaligned_load (operands[0], operands[1],
3021                                   INTVAL (operands[2]),
3022                                   INTVAL (operands[3])))
3023     DONE;
3024   else
3025     FAIL;
3026 })
3027
3028 (define_expand "insv"
3029   [(set (zero_extract (match_operand:QI 0 "memory_operand")
3030                       (match_operand 1 "immediate_operand")
3031                       (match_operand 2 "immediate_operand"))
3032         (match_operand 3 "reg_or_0_operand"))]
3033   "!TARGET_MIPS16"
3034 {
3035   if (mips_expand_unaligned_store (operands[0], operands[3],
3036                                    INTVAL (operands[1]),
3037                                    INTVAL (operands[2])))
3038     DONE;
3039   else
3040     FAIL;
3041 })
3042
3043 ;; Unaligned word moves generated by the bit field patterns.
3044 ;;
3045 ;; As far as the rtl is concerned, both the left-part and right-part
3046 ;; instructions can access the whole field.  However, the real operand
3047 ;; refers to just the first or the last byte (depending on endianness).
3048 ;; We therefore use two memory operands to each instruction, one to
3049 ;; describe the rtl effect and one to use in the assembly output.
3050 ;;
3051 ;; Operands 0 and 1 are the rtl-level target and source respectively.
3052 ;; This allows us to use the standard length calculations for the "load"
3053 ;; and "store" type attributes.
3054
3055 (define_insn "mov_<load>l"
3056   [(set (match_operand:GPR 0 "register_operand" "=d")
3057         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3058                      (match_operand:QI 2 "memory_operand" "m")]
3059                     UNSPEC_LOAD_LEFT))]
3060   "!TARGET_MIPS16"
3061   "<load>l\t%0,%2"
3062   [(set_attr "type" "load")
3063    (set_attr "mode" "<MODE>")
3064    (set_attr "hazard" "none")])
3065
3066 (define_insn "mov_<load>r"
3067   [(set (match_operand:GPR 0 "register_operand" "=d")
3068         (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
3069                      (match_operand:QI 2 "memory_operand" "m")
3070                      (match_operand:GPR 3 "register_operand" "0")]
3071                     UNSPEC_LOAD_RIGHT))]
3072   "!TARGET_MIPS16"
3073   "<load>r\t%0,%2"
3074   [(set_attr "type" "load")
3075    (set_attr "mode" "<MODE>")])
3076
3077 (define_insn "mov_<store>l"
3078   [(set (match_operand:BLK 0 "memory_operand" "=m")
3079         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3080                      (match_operand:QI 2 "memory_operand" "m")]
3081                     UNSPEC_STORE_LEFT))]
3082   "!TARGET_MIPS16"
3083   "<store>l\t%z1,%2"
3084   [(set_attr "type" "store")
3085    (set_attr "mode" "<MODE>")])
3086
3087 (define_insn "mov_<store>r"
3088   [(set (match_operand:BLK 0 "memory_operand" "+m")
3089         (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ")
3090                      (match_operand:QI 2 "memory_operand" "m")
3091                      (match_dup 0)]
3092                     UNSPEC_STORE_RIGHT))]
3093   "!TARGET_MIPS16"
3094   "<store>r\t%z1,%2"
3095   [(set_attr "type" "store")
3096    (set_attr "mode" "<MODE>")])
3097
3098 ;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL.
3099 ;; The required value is:
3100 ;;
3101 ;;      (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16)
3102 ;;
3103 ;; which translates to:
3104 ;;
3105 ;;      lui     op0,%highest(op1)
3106 ;;      daddiu  op0,op0,%higher(op1)
3107 ;;      dsll    op0,op0,16
3108 ;;      daddiu  op0,op0,%hi(op1)
3109 ;;      dsll    op0,op0,16
3110 ;;
3111 ;; The split is deferred until after flow2 to allow the peephole2 below
3112 ;; to take effect.
3113 (define_insn_and_split "*lea_high64"
3114   [(set (match_operand:DI 0 "register_operand" "=d")
3115         (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
3116   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3117   "#"
3118   "&& flow2_completed"
3119   [(set (match_dup 0) (high:DI (match_dup 2)))
3120    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
3121    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
3122    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3123    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))]
3124 {
3125   operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3126   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID);
3127 }
3128   [(set_attr "length" "20")])
3129
3130 ;; Use a scratch register to reduce the latency of the above pattern
3131 ;; on superscalar machines.  The optimized sequence is:
3132 ;;
3133 ;;      lui     op1,%highest(op2)
3134 ;;      lui     op0,%hi(op2)
3135 ;;      daddiu  op1,op1,%higher(op2)
3136 ;;      dsll32  op1,op1,0
3137 ;;      daddu   op1,op1,op0
3138 (define_peephole2
3139   [(match_scratch:DI 0 "d")
3140    (set (match_operand:DI 1 "register_operand")
3141         (high:DI (match_operand:DI 2 "general_symbolic_operand")))]
3142   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
3143   [(set (match_dup 1) (high:DI (match_dup 3)))
3144    (set (match_dup 0) (high:DI (match_dup 4)))
3145    (set (match_dup 1) (lo_sum:DI (match_dup 1) (match_dup 3)))
3146    (set (match_dup 1) (ashift:DI (match_dup 1) (const_int 32)))
3147    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 0)))]
3148 {
3149   operands[3] = mips_unspec_address (operands[2], SYMBOL_64_HIGH);
3150   operands[4] = mips_unspec_address (operands[2], SYMBOL_64_LOW);
3151 })
3152
3153 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
3154 ;; SYMBOL_GENERAL X will take 6 cycles.  This next pattern allows combine
3155 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
3156 ;; used once.  We can then use the sequence:
3157 ;;
3158 ;;      lui     op0,%highest(op1)
3159 ;;      lui     op2,%hi(op1)
3160 ;;      daddiu  op0,op0,%higher(op1)
3161 ;;      daddiu  op2,op2,%lo(op1)
3162 ;;      dsll32  op0,op0,0
3163 ;;      daddu   op0,op0,op2
3164 ;;
3165 ;; which takes 4 cycles on most superscalar targets.
3166 (define_insn_and_split "*lea64"
3167   [(set (match_operand:DI 0 "register_operand" "=d")
3168         (match_operand:DI 1 "general_symbolic_operand" ""))
3169    (clobber (match_scratch:DI 2 "=&d"))]
3170   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected"
3171   "#"
3172   "&& reload_completed"
3173   [(set (match_dup 0) (high:DI (match_dup 3)))
3174    (set (match_dup 2) (high:DI (match_dup 4)))
3175    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3)))
3176    (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4)))
3177    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
3178    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
3179 {
3180   operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH);
3181   operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW);
3182 }
3183   [(set_attr "length" "24")])
3184
3185 ;; Insns to fetch a global symbol from a big GOT.
3186
3187 (define_insn_and_split "*xgot_hi<mode>"
3188   [(set (match_operand:P 0 "register_operand" "=d")
3189         (high:P (match_operand:P 1 "global_got_operand" "")))]
3190   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3191   "#"
3192   "&& reload_completed"
3193   [(set (match_dup 0) (high:P (match_dup 2)))
3194    (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))]
3195 {
3196   operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3197   operands[3] = pic_offset_table_rtx;
3198 }
3199   [(set_attr "got" "xgot_high")
3200    (set_attr "mode" "<MODE>")])
3201
3202 (define_insn_and_split "*xgot_lo<mode>"
3203   [(set (match_operand:P 0 "register_operand" "=d")
3204         (lo_sum:P (match_operand:P 1 "register_operand" "d")
3205                   (match_operand:P 2 "global_got_operand" "")))]
3206   "TARGET_EXPLICIT_RELOCS && TARGET_XGOT"
3207   "#"
3208   "&& reload_completed"
3209   [(set (match_dup 0)
3210         (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))]
3211   { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); }
3212   [(set_attr "got" "load")
3213    (set_attr "mode" "<MODE>")])
3214
3215 ;; Insns to fetch a global symbol from a normal GOT.
3216
3217 (define_insn_and_split "*got_disp<mode>"
3218   [(set (match_operand:P 0 "register_operand" "=d")
3219         (match_operand:P 1 "global_got_operand" ""))]
3220   "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
3221   "#"
3222   "&& reload_completed"
3223   [(set (match_dup 0)
3224         (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3225 {
3226   operands[2] = pic_offset_table_rtx;
3227   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL);
3228 }
3229   [(set_attr "got" "load")
3230    (set_attr "mode" "<MODE>")])
3231
3232 ;; Insns for loading the high part of a local symbol.
3233
3234 (define_insn_and_split "*got_page<mode>"
3235   [(set (match_operand:P 0 "register_operand" "=d")
3236         (high:P (match_operand:P 1 "local_got_operand" "")))]
3237   "TARGET_EXPLICIT_RELOCS"
3238   "#"
3239   "&& reload_completed"
3240   [(set (match_dup 0)
3241         (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
3242 {
3243   operands[2] = pic_offset_table_rtx;
3244   operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
3245 }
3246   [(set_attr "got" "load")
3247    (set_attr "mode" "<MODE>")])
3248
3249 ;; Lower-level instructions for loading an address from the GOT.
3250 ;; We could use MEMs, but an unspec gives more optimization
3251 ;; opportunities.
3252
3253 (define_insn "*load_got<mode>"
3254   [(set (match_operand:P 0 "register_operand" "=d")
3255         (unspec:P [(match_operand:P 1 "register_operand" "d")
3256                    (match_operand:P 2 "immediate_operand" "")]
3257                   UNSPEC_LOAD_GOT))]
3258   "TARGET_ABICALLS"
3259   "<load>\t%0,%R2(%1)"
3260   [(set_attr "type" "load")
3261    (set_attr "mode" "<MODE>")
3262    (set_attr "length" "4")])
3263
3264 ;; Instructions for adding the low 16 bits of an address to a register.
3265 ;; Operand 2 is the address: print_operand works out which relocation
3266 ;; should be applied.
3267
3268 (define_insn "*low<mode>"
3269   [(set (match_operand:P 0 "register_operand" "=d")
3270         (lo_sum:P (match_operand:P 1 "register_operand" "d")
3271                   (match_operand:P 2 "immediate_operand" "")))]
3272   "!TARGET_MIPS16"
3273   "<d>addiu\t%0,%1,%R2"
3274   [(set_attr "type" "arith")
3275    (set_attr "mode" "<MODE>")])
3276
3277 (define_insn "*low<mode>_mips16"
3278   [(set (match_operand:P 0 "register_operand" "=d")
3279         (lo_sum:P (match_operand:P 1 "register_operand" "0")
3280                   (match_operand:P 2 "immediate_operand" "")))]
3281   "TARGET_MIPS16"
3282   "<d>addiu\t%0,%R2"
3283   [(set_attr "type" "arith")
3284    (set_attr "mode" "<MODE>")
3285    (set_attr "length" "8")])
3286
3287 ;; 64-bit integer moves
3288
3289 ;; Unlike most other insns, the move insns can't be split with
3290 ;; different predicates, because register spilling and other parts of
3291 ;; the compiler, have memoized the insn number already.
3292
3293 (define_expand "movdi"
3294   [(set (match_operand:DI 0 "")
3295         (match_operand:DI 1 ""))]
3296   ""
3297 {
3298   if (mips_legitimize_move (DImode, operands[0], operands[1]))
3299     DONE;
3300 })
3301
3302 ;; For mips16, we need a special case to handle storing $31 into
3303 ;; memory, since we don't have a constraint to match $31.  This
3304 ;; instruction can be generated by save_restore_insns.
3305
3306 (define_insn "*mov<mode>_ra"
3307   [(set (match_operand:GPR 0 "stack_operand" "=m")
3308         (reg:GPR 31))]
3309   "TARGET_MIPS16"
3310   "<store>\t$31,%0"
3311   [(set_attr "type" "store")
3312    (set_attr "mode" "<MODE>")])
3313
3314 (define_insn "*movdi_32bit"
3315   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*B*C*D,*B*C*D,*d,*m")
3316         (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*x,*d,*m,*B*C*D,*B*C*D"))]
3317   "!TARGET_64BIT && !TARGET_MIPS16
3318    && (register_operand (operands[0], DImode)
3319        || reg_or_0_operand (operands[1], DImode))"
3320   { return mips_output_move (operands[0], operands[1]); }
3321   [(set_attr "type"     "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
3322    (set_attr "mode"     "DI")
3323    (set_attr "length"   "8,16,*,*,8,8,8,*,8,*")])
3324
3325 (define_insn "*movdi_32bit_mips16"
3326   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
3327         (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
3328   "!TARGET_64BIT && TARGET_MIPS16
3329    && (register_operand (operands[0], DImode)
3330        || register_operand (operands[1], DImode))"
3331   { return mips_output_move (operands[0], operands[1]); }
3332   [(set_attr "type"     "arith,arith,arith,arith,arith,load,store,mfhilo")
3333    (set_attr "mode"     "DI")
3334    (set_attr "length"   "8,8,8,8,12,*,*,8")])
3335
3336 (define_insn "*movdi_64bit"
3337   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*x,*B*C*D,*B*C*D,*d,*m")
3338         (match_operand:DI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*J*d,*d,*m,*B*C*D,*B*C*D"))]
3339   "TARGET_64BIT && !TARGET_MIPS16
3340    && (register_operand (operands[0], DImode)
3341        || reg_or_0_operand (operands[1], DImode))"
3342   { return mips_output_move (operands[0], operands[1]); }
3343   [(set_attr "type"     "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
3344    (set_attr "mode"     "DI")
3345    (set_attr "length"   "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
3346
3347 (define_insn "*movdi_64bit_mips16"
3348   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
3349         (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
3350   "TARGET_64BIT && TARGET_MIPS16
3351    && (register_operand (operands[0], DImode)
3352        || register_operand (operands[1], DImode))"
3353   { return mips_output_move (operands[0], operands[1]); }
3354   [(set_attr "type"     "arith,arith,arith,arith,arith,const,load,store")
3355    (set_attr "mode"     "DI")
3356    (set_attr_alternative "length"
3357                 [(const_int 4)
3358                  (const_int 4)
3359                  (const_int 4)
3360                  (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
3361                                (const_int 4)
3362                                (const_int 8))
3363                  (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
3364                                (const_int 8)
3365                                (const_int 12))
3366                  (const_string "*")
3367                  (const_string "*")
3368                  (const_string "*")])])
3369
3370
3371 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
3372 ;; when the original load is a 4 byte instruction but the add and the
3373 ;; load are 2 2 byte instructions.
3374
3375 (define_split
3376   [(set (match_operand:DI 0 "register_operand")
3377         (mem:DI (plus:DI (match_dup 0)
3378                          (match_operand:DI 1 "const_int_operand"))))]
3379   "TARGET_64BIT && TARGET_MIPS16 && reload_completed
3380    && !TARGET_DEBUG_D_MODE
3381    && GET_CODE (operands[0]) == REG
3382    && M16_REG_P (REGNO (operands[0]))
3383    && GET_CODE (operands[1]) == CONST_INT
3384    && ((INTVAL (operands[1]) < 0
3385         && INTVAL (operands[1]) >= -0x10)
3386        || (INTVAL (operands[1]) >= 32 * 8
3387            && INTVAL (operands[1]) <= 31 * 8 + 0x8)
3388        || (INTVAL (operands[1]) >= 0
3389            && INTVAL (operands[1]) < 32 * 8
3390            && (INTVAL (operands[1]) & 7) != 0))"
3391   [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
3392    (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
3393 {
3394   HOST_WIDE_INT val = INTVAL (operands[1]);
3395
3396   if (val < 0)
3397     operands[2] = const0_rtx;
3398   else if (val >= 32 * 8)
3399     {
3400       int off = val & 7;
3401
3402       operands[1] = GEN_INT (0x8 + off);
3403       operands[2] = GEN_INT (val - off - 0x8);
3404     }
3405   else
3406     {
3407       int off = val & 7;
3408
3409       operands[1] = GEN_INT (off);
3410       operands[2] = GEN_INT (val - off);
3411     }
3412 })
3413
3414 ;; 32-bit Integer moves
3415
3416 ;; Unlike most other insns, the move insns can't be split with
3417 ;; different predicates, because register spilling and other parts of
3418 ;; the compiler, have memoized the insn number already.
3419
3420 (define_expand "movsi"
3421   [(set (match_operand:SI 0 "")
3422         (match_operand:SI 1 ""))]
3423   ""
3424 {
3425   if (mips_legitimize_move (SImode, operands[0], operands[1]))
3426     DONE;
3427 })
3428
3429 ;; The difference between these two is whether or not ints are allowed
3430 ;; in FP registers (off by default, use -mdebugh to enable).
3431
3432 (define_insn "*movsi_internal"
3433   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*x,*B*C*D,*B*C*D,*d,*m")
3434         (match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,*J*d,*d,*m,*B*C*D,*B*C*D"))]
3435   "!TARGET_MIPS16
3436    && (register_operand (operands[0], SImode)
3437        || reg_or_0_operand (operands[1], SImode))"
3438   { return mips_output_move (operands[0], operands[1]); }