mips.h (INITIALIZE_TRAMPOLINE): Simplify.
[gcc.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 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 ;; ??? Currently does not have define_function_unit support for the R8000.
27 ;; Must include new entries for fmadd in addition to existing entries.
28
29 (define_constants
30 [(UNSPEC_LOAD_DF_LOW 0)
31 (UNSPEC_LOAD_DF_HIGH 1)
32 (UNSPEC_STORE_DF_HIGH 2)
33 (UNSPEC_GET_FNADDR 3)
34 (UNSPEC_BLOCKAGE 4)
35 (UNSPEC_CPRESTORE 5)
36 (UNSPEC_EH_RECEIVER 6)
37 (UNSPEC_EH_RETURN 7)
38 (UNSPEC_CONSTTABLE_QI 8)
39 (UNSPEC_CONSTTABLE_HI 9)
40 (UNSPEC_CONSTTABLE_SI 10)
41 (UNSPEC_CONSTTABLE_DI 11)
42 (UNSPEC_CONSTTABLE_SF 12)
43 (UNSPEC_CONSTTABLE_DF 13)
44 (UNSPEC_ALIGN_2 14)
45 (UNSPEC_ALIGN_4 15)
46 (UNSPEC_ALIGN_8 16)
47 (UNSPEC_HIGH 17)
48 (UNSPEC_LWL 18)
49 (UNSPEC_LWR 19)
50 (UNSPEC_SWL 20)
51 (UNSPEC_SWR 21)
52 (UNSPEC_LDL 22)
53 (UNSPEC_LDR 23)
54 (UNSPEC_SDL 24)
55 (UNSPEC_SDR 25)
56
57 ;; Constants used in relocation unspecs. RELOC_GOT_PAGE and RELOC_GOT_DISP
58 ;; are really only available for n32 and n64. However, it is convenient
59 ;; to reuse them for SVR4 PIC, where they represent the local and global
60 ;; forms of R_MIPS_GOT16.
61 (RELOC_GOT_HI 100)
62 (RELOC_GOT_LO 101)
63 (RELOC_GOT_PAGE 102)
64 (RELOC_GOT_DISP 103)
65 (RELOC_CALL16 104)
66 (RELOC_CALL_HI 105)
67 (RELOC_CALL_LO 106)
68 (RELOC_LOADGP_HI 107)
69 (RELOC_LOADGP_LO 108)])
70 \f
71 ;; ....................
72 ;;
73 ;; Attributes
74 ;;
75 ;; ....................
76
77 ;; For jal instructions, this attribute is DIRECT when the target address
78 ;; is symbolic and INDIRECT when it is a register.
79 (define_attr "jal" "unset,direct,indirect"
80 (const_string "unset"))
81
82 ;; This attribute is YES if the instruction is a jal macro (not a
83 ;; real jal instruction).
84 ;;
85 ;; jal is always a macro in SVR4 PIC since it includes an instruction to
86 ;; restore $gp. Direct jals are also macros in NewABI PIC since they
87 ;; load the target address into $25.
88 (define_attr "jal_macro" "no,yes"
89 (cond [(eq_attr "jal" "direct")
90 (symbol_ref "TARGET_ABICALLS != 0")
91 (eq_attr "jal" "indirect")
92 (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")]
93 (const_string "no")))
94
95 ;; Classification of each insn.
96 ;; branch conditional branch
97 ;; jump unconditional jump
98 ;; call unconditional call
99 ;; load load instruction(s)
100 ;; store store instruction(s)
101 ;; prefetch memory prefetch (register + offset)
102 ;; prefetchx memory indexed prefetch (register + register)
103 ;; move data movement within same register set
104 ;; condmove conditional moves
105 ;; xfer transfer to/from coprocessor
106 ;; hilo transfer of hi/lo registers
107 ;; arith integer arithmetic instruction
108 ;; darith double precision integer arithmetic instructions
109 ;; const load constant
110 ;; imul integer multiply
111 ;; imadd integer multiply-add
112 ;; idiv integer divide
113 ;; icmp integer compare
114 ;; fadd floating point add/subtract
115 ;; fmul floating point multiply
116 ;; fmadd floating point multiply-add
117 ;; fdiv floating point divide
118 ;; fabs floating point absolute value
119 ;; fneg floating point negation
120 ;; fcmp floating point compare
121 ;; fcvt floating point convert
122 ;; fsqrt floating point square root
123 ;; frsqrt floating point reciprocal square root
124 ;; multi multiword sequence (or user asm statements)
125 ;; nop no operation
126 (define_attr "type"
127 "unknown,branch,jump,call,load,store,prefetch,prefetchx,move,condmove,xfer,hilo,const,arith,darith,imul,imadd,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
128 (cond [(eq_attr "jal" "!unset")
129 (const_string "call")]
130 (const_string "unknown")))
131
132 ;; Main data type used by the insn
133 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW"
134 (const_string "unknown"))
135
136 ;; Is this an extended instruction in mips16 mode?
137 (define_attr "extended_mips16" "no,yes"
138 (const_string "no"))
139
140 ;; Length of instruction in bytes.
141 (define_attr "length" ""
142 (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc].
143 ;; If a branch is outside this range, we have a choice of two
144 ;; sequences. For PIC, an out-of-range branch like:
145 ;;
146 ;; bne r1,r2,target
147 ;; dslot
148 ;;
149 ;; becomes the equivalent of:
150 ;;
151 ;; beq r1,r2,1f
152 ;; dslot
153 ;; la $at,target
154 ;; jr $at
155 ;; nop
156 ;; 1:
157 ;;
158 ;; where the load address can be up to three instructions long
159 ;; (lw, nop, addiu).
160 ;;
161 ;; The non-PIC case is similar except that we use a direct
162 ;; jump instead of an la/jr pair. Since the target of this
163 ;; jump is an absolute 28-bit bit address (the other bits
164 ;; coming from the address of the delay slot) this form cannot
165 ;; cross a 256MB boundary. We could provide the option of
166 ;; using la/jr in this case too, but we do not do so at
167 ;; present.
168 ;;
169 ;; Note that this value does not account for the delay slot
170 ;; instruction, whose length is added separately. If the RTL
171 ;; pattern has no explicit delay slot, mips_adjust_insn_length
172 ;; will add the length of the implicit nop.
173 (eq_attr "type" "branch")
174 (cond [(lt (abs (minus (match_dup 1) (plus (pc) (const_int 4))))
175 (const_int 131072))
176 (const_int 4)
177 (ne (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC")
178 (const_int 0))
179 (const_int 24)
180 ] (const_int 12))
181
182 (eq_attr "type" "const")
183 (symbol_ref "mips_const_insns (operands[1]) * 4")
184 (eq_attr "type" "load")
185 (symbol_ref "mips_fetch_insns (operands[1]) * 4")
186 (eq_attr "type" "store")
187 (symbol_ref "mips_fetch_insns (operands[0]) * 4")
188
189 ;; In the worst case, a call macro will take 8 instructions:
190 ;;
191 ;; lui $25,%call_hi(FOO)
192 ;; addu $25,$25,$28
193 ;; lw $25,%call_lo(FOO)($25)
194 ;; nop
195 ;; jalr $25
196 ;; nop
197 ;; lw $gp,X($sp)
198 ;; nop
199 (eq_attr "jal_macro" "yes")
200 (const_int 32)
201
202 (and (eq_attr "extended_mips16" "yes")
203 (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
204 (const_int 8)
205
206 (and (eq_attr "type" "idiv")
207 (ne (symbol_ref "TARGET_CHECK_ZERO_DIV") (const_int 0)))
208 (cond [(ne (symbol_ref "TARGET_MIPS16") (const_int 0))
209 (const_int 12)]
210 (const_int 16))
211 ] (const_int 4)))
212
213 ;; Attribute describing the processor. This attribute must match exactly
214 ;; with the processor_type enumeration in mips.h.
215 (define_attr "cpu"
216 "default,4kc,5kc,20kc,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sr71000"
217 (const (symbol_ref "mips_tune")))
218
219 ;; The type of hardware hazard associated with this instruction.
220 ;; DELAY means that the next instruction cannot read the result
221 ;; of this one. HILO means that the next two instructions cannot
222 ;; write to HI or LO.
223 (define_attr "hazard" "none,delay,hilo"
224 (cond [(and (eq_attr "type" "load")
225 (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
226 (const_string "delay")
227
228 (and (eq_attr "type" "xfer")
229 (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0)))
230 (const_string "delay")
231
232 (and (eq_attr "type" "fcmp")
233 (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0)))
234 (const_string "delay")
235
236 ;; The r4000 multiplication patterns include an mflo instruction.
237 (and (eq_attr "type" "imul")
238 (ne (symbol_ref "TARGET_MIPS4000") (const_int 0)))
239 (const_string "hilo")
240
241 (and (eq_attr "type" "hilo")
242 (and (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0))
243 (match_operand 1 "hilo_operand" "")))
244 (const_string "hilo")]
245 (const_string "none")))
246
247 ;; Is it a single instruction?
248 (define_attr "single_insn" "no,yes"
249 (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
250
251 ;; Can the instruction be put into a delay slot?
252 (define_attr "can_delay" "no,yes"
253 (if_then_else (and (eq_attr "type" "!branch,call,jump")
254 (and (eq_attr "hazard" "none")
255 (eq_attr "single_insn" "yes")))
256 (const_string "yes")
257 (const_string "no")))
258
259 ;; Attribute defining whether or not we can use the branch-likely instructions
260 (define_attr "branch_likely" "no,yes"
261 (const
262 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0))
263 (const_string "yes")
264 (const_string "no"))))
265
266 ;; Describe a user's asm statement.
267 (define_asm_attributes
268 [(set_attr "type" "multi")])
269 \f
270 ;; .........................
271 ;;
272 ;; Branch, call and jump delay slots
273 ;;
274 ;; .........................
275
276 (define_delay (and (eq_attr "type" "branch")
277 (eq (symbol_ref "TARGET_MIPS16") (const_int 0)))
278 [(eq_attr "can_delay" "yes")
279 (nil)
280 (and (eq_attr "branch_likely" "yes")
281 (eq_attr "can_delay" "yes"))])
282
283 (define_delay (eq_attr "type" "jump")
284 [(eq_attr "can_delay" "yes")
285 (nil)
286 (nil)])
287
288 (define_delay (and (eq_attr "type" "call")
289 (eq_attr "jal_macro" "no"))
290 [(eq_attr "can_delay" "yes")
291 (nil)
292 (nil)])
293 \f
294 ;; .........................
295 ;;
296 ;; Functional units
297 ;;
298 ;; .........................
299
300 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
301 ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
302
303 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
304
305 (define_function_unit "memory" 1 0
306 (and (eq_attr "type" "load")
307 (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4120,r4300,r5000"))
308 3 0)
309
310 (define_function_unit "memory" 1 0
311 (and (eq_attr "type" "load")
312 (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4120,r4300,r5000"))
313 2 0)
314
315 (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
316
317 (define_function_unit "memory" 1 0 (eq_attr "type" "xfer") 2 0)
318
319 (define_function_unit "imuldiv" 1 0
320 (eq_attr "type" "hilo")
321 1 3)
322
323 (define_function_unit "imuldiv" 1 0
324 (and (eq_attr "type" "imul,imadd")
325 (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4120,r4300,r5000"))
326 17 17)
327
328 ;; On them mips16, we want to stronly discourage a mult from appearing
329 ;; after an mflo, since that requires explicit nop instructions. We
330 ;; do this by pretending that mflo ties up the function unit for long
331 ;; enough that the scheduler will ignore load stalls and the like when
332 ;; selecting instructions to between the two instructions.
333
334 (define_function_unit "imuldiv" 1 0
335 (and (eq_attr "type" "hilo") (ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
336 1 5)
337
338 (define_function_unit "imuldiv" 1 0
339 (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r3000,r3900"))
340 12 12)
341
342 (define_function_unit "imuldiv" 1 0
343 (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r4000,r4600"))
344 10 10)
345
346 (define_function_unit "imuldiv" 1 0
347 (and (eq_attr "type" "imul,imadd") (eq_attr "cpu" "r4650"))
348 4 4)
349
350 (define_function_unit "imuldiv" 1 0
351 (and (eq_attr "type" "imul,imadd")
352 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100,r4120")))
353 1 1)
354
355 (define_function_unit "imuldiv" 1 0
356 (and (eq_attr "type" "imul,imadd")
357 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100,r4120")))
358 4 4)
359
360 (define_function_unit "imuldiv" 1 0
361 (and (eq_attr "type" "imul,imadd")
362 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300,r5000")))
363 5 5)
364
365 (define_function_unit "imuldiv" 1 0
366 (and (eq_attr "type" "imul,imadd")
367 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
368 8 8)
369
370 (define_function_unit "imuldiv" 1 0
371 (and (eq_attr "type" "imul,imadd")
372 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
373 9 9)
374
375 (define_function_unit "imuldiv" 1 0
376 (and (eq_attr "type" "idiv")
377 (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4120,r4300,r5000"))
378 38 38)
379
380 (define_function_unit "imuldiv" 1 0
381 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r3000,r3900"))
382 35 35)
383
384 (define_function_unit "imuldiv" 1 0
385 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4600"))
386 42 42)
387
388 (define_function_unit "imuldiv" 1 0
389 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4650"))
390 36 36)
391
392 (define_function_unit "imuldiv" 1 0
393 (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
394 69 69)
395
396 (define_function_unit "imuldiv" 1 0
397 (and (eq_attr "type" "idiv")
398 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100,r4120")))
399 35 35)
400
401 (define_function_unit "imuldiv" 1 0
402 (and (eq_attr "type" "idiv")
403 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100,r4120")))
404 67 67)
405
406 (define_function_unit "imuldiv" 1 0
407 (and (eq_attr "type" "idiv")
408 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
409 37 37)
410
411 (define_function_unit "imuldiv" 1 0
412 (and (eq_attr "type" "idiv")
413 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
414 69 69)
415
416 (define_function_unit "imuldiv" 1 0
417 (and (eq_attr "type" "idiv")
418 (and (eq_attr "mode" "SI") (eq_attr "cpu" "r5000")))
419 36 36)
420
421 (define_function_unit "imuldiv" 1 0
422 (and (eq_attr "type" "idiv")
423 (and (eq_attr "mode" "DI") (eq_attr "cpu" "r5000")))
424 68 68)
425
426 ;; The R4300 does *NOT* have a separate Floating Point Unit, instead
427 ;; the FP hardware is part of the normal ALU circuitry. This means FP
428 ;; instructions affect the pipe-line, and no functional unit
429 ;; parallelism can occur on R4300 processors. To force GCC into coding
430 ;; for only a single functional unit, we force the R4300 FP
431 ;; instructions to be processed in the "imuldiv" unit.
432
433 (define_function_unit "adder" 1 1
434 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
435 3 0)
436
437 (define_function_unit "adder" 1 1
438 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r3000,r3900,r6000"))
439 2 0)
440
441 (define_function_unit "adder" 1 1
442 (and (eq_attr "type" "fcmp") (eq_attr "cpu" "r5000"))
443 1 0)
444
445 (define_function_unit "adder" 1 1
446 (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
447 4 0)
448
449 (define_function_unit "adder" 1 1
450 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r3000,r3900"))
451 2 0)
452
453 (define_function_unit "adder" 1 1
454 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r6000"))
455 3 0)
456
457 (define_function_unit "adder" 1 1
458 (and (eq_attr "type" "fabs,fneg")
459 (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000"))
460 2 0)
461
462 (define_function_unit "adder" 1 1
463 (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "r3000,r3900,r4600,r4650,r5000"))
464 1 0)
465
466 (define_function_unit "mult" 1 1
467 (and (eq_attr "type" "fmul")
468 (and (eq_attr "mode" "SF")
469 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
470 7 0)
471
472 (define_function_unit "mult" 1 1
473 (and (eq_attr "type" "fmul")
474 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900,r5000")))
475 4 0)
476
477 (define_function_unit "mult" 1 1
478 (and (eq_attr "type" "fmul")
479 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
480 5 0)
481
482 (define_function_unit "mult" 1 1
483 (and (eq_attr "type" "fmul")
484 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
485 8 0)
486
487 (define_function_unit "mult" 1 1
488 (and (eq_attr "type" "fmul")
489 (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")))
490 8 0)
491
492 (define_function_unit "mult" 1 1
493 (and (eq_attr "type" "fmul")
494 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900,r5000")))
495 5 0)
496
497 (define_function_unit "mult" 1 1
498 (and (eq_attr "type" "fmul")
499 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
500 6 0)
501
502 (define_function_unit "divide" 1 1
503 (and (eq_attr "type" "fdiv")
504 (and (eq_attr "mode" "SF")
505 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
506 23 0)
507
508 (define_function_unit "divide" 1 1
509 (and (eq_attr "type" "fdiv")
510 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r3000,r3900")))
511 12 0)
512
513 (define_function_unit "divide" 1 1
514 (and (eq_attr "type" "fdiv")
515 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r6000")))
516 15 0)
517
518 (define_function_unit "divide" 1 1
519 (and (eq_attr "type" "fdiv")
520 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
521 32 0)
522
523 (define_function_unit "divide" 1 1
524 (and (eq_attr "type" "fdiv")
525 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
526 21 0)
527
528 (define_function_unit "divide" 1 1
529 (and (eq_attr "type" "fdiv")
530 (and (eq_attr "mode" "DF")
531 (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300")))
532 36 0)
533
534 (define_function_unit "divide" 1 1
535 (and (eq_attr "type" "fdiv")
536 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r3000,r3900")))
537 19 0)
538
539 (define_function_unit "divide" 1 1
540 (and (eq_attr "type" "fdiv")
541 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r6000")))
542 16 0)
543
544 (define_function_unit "divide" 1 1
545 (and (eq_attr "type" "fdiv")
546 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
547 61 0)
548
549 ;;; ??? Is this number right?
550 (define_function_unit "divide" 1 1
551 (and (eq_attr "type" "fsqrt,frsqrt")
552 (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
553 54 0)
554
555 (define_function_unit "divide" 1 1
556 (and (eq_attr "type" "fsqrt,frsqrt")
557 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
558 31 0)
559
560 (define_function_unit "divide" 1 1
561 (and (eq_attr "type" "fsqrt,frsqrt")
562 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r5000")))
563 21 0)
564
565 ;;; ??? Is this number right?
566 (define_function_unit "divide" 1 1
567 (and (eq_attr "type" "fsqrt,frsqrt")
568 (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
569 112 0)
570
571 (define_function_unit "divide" 1 1
572 (and (eq_attr "type" "fsqrt,frsqrt")
573 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
574 60 0)
575
576 (define_function_unit "divide" 1 1
577 (and (eq_attr "type" "fsqrt,frsqrt")
578 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r5000")))
579 36 0)
580
581 ;; R4300 FP instruction classes treated as part of the "imuldiv"
582 ;; functional unit:
583
584 (define_function_unit "imuldiv" 1 0
585 (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
586 3 3)
587
588 (define_function_unit "imuldiv" 1 0
589 (and (eq_attr "type" "fcmp,fabs,fneg") (eq_attr "cpu" "r4300"))
590 1 1)
591
592 (define_function_unit "imuldiv" 1 0
593 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
594 5 5)
595 (define_function_unit "imuldiv" 1 0
596 (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
597 8 8)
598
599 (define_function_unit "imuldiv" 1 0
600 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt"))
601 (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
602 29 29)
603 (define_function_unit "imuldiv" 1 0
604 (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt,frsqrt"))
605 (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
606 58 58)
607 \f
608 ;; Include scheduling descriptions.
609
610 (include "5400.md")
611 (include "5500.md")
612 (include "7000.md")
613 (include "9000.md")
614 (include "sr71k.md")
615 \f
616 ;;
617 ;; ....................
618 ;;
619 ;; CONDITIONAL TRAPS
620 ;;
621 ;; ....................
622 ;;
623
624 (define_insn "trap"
625 [(trap_if (const_int 1) (const_int 0))]
626 ""
627 {
628 if (ISA_HAS_COND_TRAP)
629 return "teq\t$0,$0";
630 /* The IRIX 6 O32 assembler requires the first break operand. */
631 else if (TARGET_MIPS16 || !TARGET_GAS)
632 return "break 0";
633 else
634 return "break";
635 })
636
637 (define_expand "conditional_trap"
638 [(trap_if (match_operator 0 "cmp_op"
639 [(match_dup 2) (match_dup 3)])
640 (match_operand 1 "const_int_operand" ""))]
641 "ISA_HAS_COND_TRAP"
642 {
643 if (operands[1] == const0_rtx)
644 {
645 mips_gen_conditional_trap (operands);
646 DONE;
647 }
648 else
649 FAIL;
650 })
651
652 (define_insn ""
653 [(trap_if (match_operator 0 "trap_cmp_op"
654 [(match_operand:SI 1 "reg_or_0_operand" "dJ")
655 (match_operand:SI 2 "arith_operand" "dI")])
656 (const_int 0))]
657 "ISA_HAS_COND_TRAP"
658 "t%C0\t%z1,%z2")
659
660 (define_insn ""
661 [(trap_if (match_operator 0 "trap_cmp_op"
662 [(match_operand:DI 1 "reg_or_0_operand" "dJ")
663 (match_operand:DI 2 "arith_operand" "dI")])
664 (const_int 0))]
665 "TARGET_64BIT && ISA_HAS_COND_TRAP"
666 "t%C0\t%z1,%z2")
667 \f
668 ;;
669 ;; ....................
670 ;;
671 ;; ADDITION
672 ;;
673 ;; ....................
674 ;;
675
676 (define_insn "adddf3"
677 [(set (match_operand:DF 0 "register_operand" "=f")
678 (plus:DF (match_operand:DF 1 "register_operand" "f")
679 (match_operand:DF 2 "register_operand" "f")))]
680 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
681 "add.d\t%0,%1,%2"
682 [(set_attr "type" "fadd")
683 (set_attr "mode" "DF")])
684
685 (define_insn "addsf3"
686 [(set (match_operand:SF 0 "register_operand" "=f")
687 (plus:SF (match_operand:SF 1 "register_operand" "f")
688 (match_operand:SF 2 "register_operand" "f")))]
689 "TARGET_HARD_FLOAT"
690 "add.s\t%0,%1,%2"
691 [(set_attr "type" "fadd")
692 (set_attr "mode" "SF")])
693
694 (define_expand "addsi3"
695 [(set (match_operand:SI 0 "register_operand" "")
696 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
697 (match_operand:SI 2 "arith_operand" "")))]
698 ""
699 {
700 /* If a large stack adjustment was forced into a register, we may be
701 asked to generate rtx such as:
702
703 (set (reg:SI sp) (plus:SI (reg:SI sp) (reg:SI pseudo)))
704
705 but no such instruction is available in mips16. Handle it by
706 using a temporary. */
707 if (TARGET_MIPS16
708 && REGNO (operands[0]) == STACK_POINTER_REGNUM
709 && ((GET_CODE (operands[1]) == REG
710 && REGNO (operands[1]) != STACK_POINTER_REGNUM)
711 || GET_CODE (operands[2]) != CONST_INT))
712 {
713 rtx tmp = gen_reg_rtx (SImode);
714
715 emit_move_insn (tmp, operands[1]);
716 emit_insn (gen_addsi3 (tmp, tmp, operands[2]));
717 emit_move_insn (operands[0], tmp);
718 DONE;
719 }
720 })
721
722 (define_insn "addsi3_internal"
723 [(set (match_operand:SI 0 "register_operand" "=d,d")
724 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
725 (match_operand:SI 2 "arith_operand" "d,Q")))]
726 "!TARGET_MIPS16"
727 "@
728 addu\t%0,%z1,%2
729 addiu\t%0,%z1,%2"
730 [(set_attr "type" "arith")
731 (set_attr "mode" "SI")])
732
733 ;; For the mips16, we need to recognize stack pointer additions
734 ;; explicitly, since we don't have a constraint for $sp. These insns
735 ;; will be generated by the save_restore_insns functions.
736
737 (define_insn ""
738 [(set (reg:SI 29)
739 (plus:SI (reg:SI 29)
740 (match_operand:SI 0 "small_int" "I")))]
741 "TARGET_MIPS16"
742 "addu\t%$,%$,%0"
743 [(set_attr "type" "arith")
744 (set_attr "mode" "SI")
745 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
746 (const_int 4)
747 (const_int 8)))])
748
749 (define_insn ""
750 [(set (match_operand:SI 0 "register_operand" "=d")
751 (plus:SI (reg:SI 29)
752 (match_operand:SI 1 "small_int" "I")))]
753 "TARGET_MIPS16"
754 "addu\t%0,%$,%1"
755 [(set_attr "type" "arith")
756 (set_attr "mode" "SI")
757 (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4" "")
758 (const_int 4)
759 (const_int 8)))])
760
761 (define_insn ""
762 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
763 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
764 (match_operand:SI 2 "arith_operand" "Q,O,d")))]
765 "TARGET_MIPS16
766 && (GET_CODE (operands[1]) != REG
767 || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
768 || M16_REG_P (REGNO (operands[1]))
769 || REGNO (operands[1]) == ARG_POINTER_REGNUM
770 || REGNO (operands[1]) == FRAME_POINTER_REGNUM
771 || REGNO (operands[1]) == STACK_POINTER_REGNUM)
772 && (GET_CODE (operands[2]) != REG
773 || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
774 || M16_REG_P (REGNO (operands[2]))
775 || REGNO (operands[2]) == ARG_POINTER_REGNUM
776 || REGNO (operands[2]) == FRAME_POINTER_REGNUM
777 || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
778 {
779 if (REGNO (operands[0]) == REGNO (operands[1]))
780 return "addu\t%0,%2";
781 else
782 return "addu\t%0,%1,%2";
783 }
784 [(set_attr "type" "arith")
785 (set_attr "mode" "SI")
786 (set_attr_alternative "length"
787 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
788 (const_int 4)
789 (const_int 8))
790 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
791 (const_int 4)
792 (const_int 8))
793 (const_int 4)])])
794
795
796 ;; On the mips16, we can sometimes split an add of a constant which is
797 ;; a 4 byte instruction into two adds which are both 2 byte
798 ;; instructions. There are two cases: one where we are adding a
799 ;; constant plus a register to another register, and one where we are
800 ;; simply adding a constant to a register.
801
802 (define_split
803 [(set (match_operand:SI 0 "register_operand" "")
804 (plus:SI (match_dup 0)
805 (match_operand:SI 1 "const_int_operand" "")))]
806 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
807 && GET_CODE (operands[0]) == REG
808 && M16_REG_P (REGNO (operands[0]))
809 && GET_CODE (operands[1]) == CONST_INT
810 && ((INTVAL (operands[1]) > 0x7f
811 && INTVAL (operands[1]) <= 0x7f + 0x7f)
812 || (INTVAL (operands[1]) < - 0x80
813 && INTVAL (operands[1]) >= - 0x80 - 0x80))"
814 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
815 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
816 {
817 HOST_WIDE_INT val = INTVAL (operands[1]);
818
819 if (val >= 0)
820 {
821 operands[1] = GEN_INT (0x7f);
822 operands[2] = GEN_INT (val - 0x7f);
823 }
824 else
825 {
826 operands[1] = GEN_INT (- 0x80);
827 operands[2] = GEN_INT (val + 0x80);
828 }
829 })
830
831 (define_split
832 [(set (match_operand:SI 0 "register_operand" "")
833 (plus:SI (match_operand:SI 1 "register_operand" "")
834 (match_operand:SI 2 "const_int_operand" "")))]
835 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
836 && GET_CODE (operands[0]) == REG
837 && M16_REG_P (REGNO (operands[0]))
838 && GET_CODE (operands[1]) == REG
839 && M16_REG_P (REGNO (operands[1]))
840 && REGNO (operands[0]) != REGNO (operands[1])
841 && GET_CODE (operands[2]) == CONST_INT
842 && ((INTVAL (operands[2]) > 0x7
843 && INTVAL (operands[2]) <= 0x7 + 0x7f)
844 || (INTVAL (operands[2]) < - 0x8
845 && INTVAL (operands[2]) >= - 0x8 - 0x80))"
846 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
847 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
848 {
849 HOST_WIDE_INT val = INTVAL (operands[2]);
850
851 if (val >= 0)
852 {
853 operands[2] = GEN_INT (0x7);
854 operands[3] = GEN_INT (val - 0x7);
855 }
856 else
857 {
858 operands[2] = GEN_INT (- 0x8);
859 operands[3] = GEN_INT (val + 0x8);
860 }
861 })
862
863 (define_expand "adddi3"
864 [(parallel [(set (match_operand:DI 0 "register_operand" "")
865 (plus:DI (match_operand:DI 1 "register_operand" "")
866 (match_operand:DI 2 "arith_operand" "")))
867 (clobber (match_dup 3))])]
868 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
869 {
870 /* If a large stack adjustment was forced into a register, we may be
871 asked to generate rtx such as:
872
873 (set (reg:DI sp) (plus:DI (reg:DI sp) (reg:DI pseudo)))
874
875 but no such instruction is available in mips16. Handle it by
876 using a temporary. */
877 if (TARGET_MIPS16
878 && REGNO (operands[0]) == STACK_POINTER_REGNUM
879 && ((GET_CODE (operands[1]) == REG
880 && REGNO (operands[1]) != STACK_POINTER_REGNUM)
881 || GET_CODE (operands[2]) != CONST_INT))
882 {
883 rtx tmp = gen_reg_rtx (DImode);
884
885 emit_move_insn (tmp, operands[1]);
886 emit_insn (gen_addsi3 (tmp, tmp, operands[2]));
887 emit_move_insn (operands[0], tmp);
888 DONE;
889 }
890
891 if (TARGET_64BIT)
892 {
893 emit_insn (gen_adddi3_internal_3 (operands[0], operands[1],
894 operands[2]));
895 DONE;
896 }
897
898 operands[3] = gen_reg_rtx (SImode);
899 })
900
901 (define_insn "adddi3_internal_1"
902 [(set (match_operand:DI 0 "register_operand" "=d,&d")
903 (plus:DI (match_operand:DI 1 "register_operand" "0,d")
904 (match_operand:DI 2 "register_operand" "d,d")))
905 (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
906 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
907 {
908 return (REGNO (operands[0]) == REGNO (operands[1])
909 && REGNO (operands[0]) == REGNO (operands[2]))
910 ? "srl\t%3,%L0,31\;sll\t%M0,%M0,1\;sll\t%L0,%L1,1\;addu\t%M0,%M0,%3"
911 : "addu\t%L0,%L1,%L2\;sltu\t%3,%L0,%L2\;addu\t%M0,%M1,%M2\;addu\t%M0,%M0,%3";
912 }
913 [(set_attr "type" "darith")
914 (set_attr "mode" "DI")
915 (set_attr "length" "16")])
916
917 (define_split
918 [(set (match_operand:DI 0 "register_operand" "")
919 (plus:DI (match_operand:DI 1 "register_operand" "")
920 (match_operand:DI 2 "register_operand" "")))
921 (clobber (match_operand:SI 3 "register_operand" ""))]
922 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
923 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
924 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
925 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
926 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
927 && (REGNO (operands[0]) != REGNO (operands[1])
928 || REGNO (operands[0]) != REGNO (operands[2]))"
929
930 [(set (subreg:SI (match_dup 0) 0)
931 (plus:SI (subreg:SI (match_dup 1) 0)
932 (subreg:SI (match_dup 2) 0)))
933
934 (set (match_dup 3)
935 (ltu:SI (subreg:SI (match_dup 0) 0)
936 (subreg:SI (match_dup 2) 0)))
937
938 (set (subreg:SI (match_dup 0) 4)
939 (plus:SI (subreg:SI (match_dup 1) 4)
940 (subreg:SI (match_dup 2) 4)))
941
942 (set (subreg:SI (match_dup 0) 4)
943 (plus:SI (subreg:SI (match_dup 0) 4)
944 (match_dup 3)))]
945 "")
946
947 (define_split
948 [(set (match_operand:DI 0 "register_operand" "")
949 (plus:DI (match_operand:DI 1 "register_operand" "")
950 (match_operand:DI 2 "register_operand" "")))
951 (clobber (match_operand:SI 3 "register_operand" ""))]
952 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
953 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
954 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
955 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
956 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))
957 && (REGNO (operands[0]) != REGNO (operands[1])
958 || REGNO (operands[0]) != REGNO (operands[2]))"
959
960 [(set (subreg:SI (match_dup 0) 4)
961 (plus:SI (subreg:SI (match_dup 1) 4)
962 (subreg:SI (match_dup 2) 4)))
963
964 (set (match_dup 3)
965 (ltu:SI (subreg:SI (match_dup 0) 4)
966 (subreg:SI (match_dup 2) 4)))
967
968 (set (subreg:SI (match_dup 0) 0)
969 (plus:SI (subreg:SI (match_dup 1) 0)
970 (subreg:SI (match_dup 2) 0)))
971
972 (set (subreg:SI (match_dup 0) 0)
973 (plus:SI (subreg:SI (match_dup 0) 0)
974 (match_dup 3)))]
975 "")
976
977 (define_insn "adddi3_internal_2"
978 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
979 (plus:DI (match_operand:DI 1 "register_operand" "%d,%d,%d")
980 (match_operand:DI 2 "small_int" "P,J,N")))
981 (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))]
982 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
983 "@
984 addu\t%L0,%L1,%2\;sltu\t%3,%L0,%2\;addu\t%M0,%M1,%3
985 move\t%L0,%L1\;move\t%M0,%M1
986 subu\t%L0,%L1,%n2\;sltu\t%3,%L0,%2\;subu\t%M0,%M1,1\;addu\t%M0,%M0,%3"
987 [(set_attr "type" "darith")
988 (set_attr "mode" "DI")
989 (set_attr "length" "12,8,16")])
990
991 (define_split
992 [(set (match_operand:DI 0 "register_operand" "")
993 (plus:DI (match_operand:DI 1 "register_operand" "")
994 (match_operand:DI 2 "small_int" "")))
995 (clobber (match_operand:SI 3 "register_operand" ""))]
996 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
997 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
998 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
999 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1000 && INTVAL (operands[2]) > 0"
1001
1002 [(set (subreg:SI (match_dup 0) 0)
1003 (plus:SI (subreg:SI (match_dup 1) 0)
1004 (match_dup 2)))
1005
1006 (set (match_dup 3)
1007 (ltu:SI (subreg:SI (match_dup 0) 0)
1008 (match_dup 2)))
1009
1010 (set (subreg:SI (match_dup 0) 4)
1011 (plus:SI (subreg:SI (match_dup 1) 4)
1012 (match_dup 3)))]
1013 "")
1014
1015 (define_split
1016 [(set (match_operand:DI 0 "register_operand" "")
1017 (plus:DI (match_operand:DI 1 "register_operand" "")
1018 (match_operand:DI 2 "small_int" "")))
1019 (clobber (match_operand:SI 3 "register_operand" ""))]
1020 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1021 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1022 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1023 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1024 && INTVAL (operands[2]) > 0"
1025
1026 [(set (subreg:SI (match_dup 0) 4)
1027 (plus:SI (subreg:SI (match_dup 1) 4)
1028 (match_dup 2)))
1029
1030 (set (match_dup 3)
1031 (ltu:SI (subreg:SI (match_dup 0) 4)
1032 (match_dup 2)))
1033
1034 (set (subreg:SI (match_dup 0) 0)
1035 (plus:SI (subreg:SI (match_dup 1) 0)
1036 (match_dup 3)))]
1037 "")
1038
1039 (define_insn "adddi3_internal_3"
1040 [(set (match_operand:DI 0 "register_operand" "=d,d")
1041 (plus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")
1042 (match_operand:DI 2 "arith_operand" "d,Q")))]
1043 "TARGET_64BIT && !TARGET_MIPS16"
1044 "@
1045 daddu\t%0,%z1,%2
1046 daddiu\t%0,%z1,%2"
1047 [(set_attr "type" "darith")
1048 (set_attr "mode" "DI")])
1049
1050 ;; For the mips16, we need to recognize stack pointer additions
1051 ;; explicitly, since we don't have a constraint for $sp. These insns
1052 ;; will be generated by the save_restore_insns functions.
1053
1054 (define_insn ""
1055 [(set (reg:DI 29)
1056 (plus:DI (reg:DI 29)
1057 (match_operand:DI 0 "small_int" "I")))]
1058 "TARGET_MIPS16 && TARGET_64BIT"
1059 "daddu\t%$,%$,%0"
1060 [(set_attr "type" "arith")
1061 (set_attr "mode" "DI")
1062 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
1063 (const_int 4)
1064 (const_int 8)))])
1065
1066 (define_insn ""
1067 [(set (match_operand:DI 0 "register_operand" "=d")
1068 (plus:DI (reg:DI 29)
1069 (match_operand:DI 1 "small_int" "I")))]
1070 "TARGET_MIPS16 && TARGET_64BIT"
1071 "daddu\t%0,%$,%1"
1072 [(set_attr "type" "arith")
1073 (set_attr "mode" "DI")
1074 (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4" "")
1075 (const_int 4)
1076 (const_int 8)))])
1077
1078 (define_insn ""
1079 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1080 (plus:DI (match_operand:DI 1 "register_operand" "0,d,d")
1081 (match_operand:DI 2 "arith_operand" "Q,O,d")))]
1082 "TARGET_MIPS16 && TARGET_64BIT
1083 && (GET_CODE (operands[1]) != REG
1084 || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
1085 || M16_REG_P (REGNO (operands[1]))
1086 || REGNO (operands[1]) == ARG_POINTER_REGNUM
1087 || REGNO (operands[1]) == FRAME_POINTER_REGNUM
1088 || REGNO (operands[1]) == STACK_POINTER_REGNUM)
1089 && (GET_CODE (operands[2]) != REG
1090 || REGNO (operands[2]) >= FIRST_PSEUDO_REGISTER
1091 || M16_REG_P (REGNO (operands[2]))
1092 || REGNO (operands[2]) == ARG_POINTER_REGNUM
1093 || REGNO (operands[2]) == FRAME_POINTER_REGNUM
1094 || REGNO (operands[2]) == STACK_POINTER_REGNUM)"
1095 {
1096 if (REGNO (operands[0]) == REGNO (operands[1]))
1097 return "daddu\t%0,%2";
1098 else
1099 return "daddu\t%0,%1,%2";
1100 }
1101 [(set_attr "type" "arith")
1102 (set_attr "mode" "DI")
1103 (set_attr_alternative "length"
1104 [(if_then_else (match_operand:VOID 2 "m16_simm5_1" "")
1105 (const_int 4)
1106 (const_int 8))
1107 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
1108 (const_int 4)
1109 (const_int 8))
1110 (const_int 4)])])
1111
1112
1113 ;; On the mips16, we can sometimes split an add of a constant which is
1114 ;; a 4 byte instruction into two adds which are both 2 byte
1115 ;; instructions. There are two cases: one where we are adding a
1116 ;; constant plus a register to another register, and one where we are
1117 ;; simply adding a constant to a register.
1118
1119 (define_split
1120 [(set (match_operand:DI 0 "register_operand" "")
1121 (plus:DI (match_dup 0)
1122 (match_operand:DI 1 "const_int_operand" "")))]
1123 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1124 && GET_CODE (operands[0]) == REG
1125 && M16_REG_P (REGNO (operands[0]))
1126 && GET_CODE (operands[1]) == CONST_INT
1127 && ((INTVAL (operands[1]) > 0xf
1128 && INTVAL (operands[1]) <= 0xf + 0xf)
1129 || (INTVAL (operands[1]) < - 0x10
1130 && INTVAL (operands[1]) >= - 0x10 - 0x10))"
1131 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
1132 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
1133 {
1134 HOST_WIDE_INT val = INTVAL (operands[1]);
1135
1136 if (val >= 0)
1137 {
1138 operands[1] = GEN_INT (0xf);
1139 operands[2] = GEN_INT (val - 0xf);
1140 }
1141 else
1142 {
1143 operands[1] = GEN_INT (- 0x10);
1144 operands[2] = GEN_INT (val + 0x10);
1145 }
1146 })
1147
1148 (define_split
1149 [(set (match_operand:DI 0 "register_operand" "")
1150 (plus:DI (match_operand:DI 1 "register_operand" "")
1151 (match_operand:DI 2 "const_int_operand" "")))]
1152 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
1153 && GET_CODE (operands[0]) == REG
1154 && M16_REG_P (REGNO (operands[0]))
1155 && GET_CODE (operands[1]) == REG
1156 && M16_REG_P (REGNO (operands[1]))
1157 && REGNO (operands[0]) != REGNO (operands[1])
1158 && GET_CODE (operands[2]) == CONST_INT
1159 && ((INTVAL (operands[2]) > 0x7
1160 && INTVAL (operands[2]) <= 0x7 + 0xf)
1161 || (INTVAL (operands[2]) < - 0x8
1162 && INTVAL (operands[2]) >= - 0x8 - 0x10))"
1163 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
1164 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
1165 {
1166 HOST_WIDE_INT val = INTVAL (operands[2]);
1167
1168 if (val >= 0)
1169 {
1170 operands[2] = GEN_INT (0x7);
1171 operands[3] = GEN_INT (val - 0x7);
1172 }
1173 else
1174 {
1175 operands[2] = GEN_INT (- 0x8);
1176 operands[3] = GEN_INT (val + 0x8);
1177 }
1178 })
1179
1180 (define_insn "addsi3_internal_2"
1181 [(set (match_operand:DI 0 "register_operand" "=d,d")
1182 (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
1183 (match_operand:SI 2 "arith_operand" "d,Q"))))]
1184 "TARGET_64BIT && !TARGET_MIPS16"
1185 "@
1186 addu\t%0,%z1,%2
1187 addiu\t%0,%z1,%2"
1188 [(set_attr "type" "arith")
1189 (set_attr "mode" "SI")])
1190
1191 (define_insn ""
1192 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
1193 (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
1194 (match_operand:SI 2 "arith_operand" "Q,O,d"))))]
1195 "TARGET_MIPS16 && TARGET_64BIT"
1196 {
1197 if (REGNO (operands[0]) == REGNO (operands[1]))
1198 return "addu\t%0,%2";
1199 else
1200 return "addu\t%0,%1,%2";
1201 }
1202 [(set_attr "type" "arith")
1203 (set_attr "mode" "SI")
1204 (set_attr_alternative "length"
1205 [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
1206 (const_int 4)
1207 (const_int 8))
1208 (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
1209 (const_int 4)
1210 (const_int 8))
1211 (const_int 4)])])
1212 \f
1213 ;;
1214 ;; ....................
1215 ;;
1216 ;; SUBTRACTION
1217 ;;
1218 ;; ....................
1219 ;;
1220
1221 (define_insn "subdf3"
1222 [(set (match_operand:DF 0 "register_operand" "=f")
1223 (minus:DF (match_operand:DF 1 "register_operand" "f")
1224 (match_operand:DF 2 "register_operand" "f")))]
1225 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1226 "sub.d\t%0,%1,%2"
1227 [(set_attr "type" "fadd")
1228 (set_attr "mode" "DF")])
1229
1230 (define_insn "subsf3"
1231 [(set (match_operand:SF 0 "register_operand" "=f")
1232 (minus:SF (match_operand:SF 1 "register_operand" "f")
1233 (match_operand:SF 2 "register_operand" "f")))]
1234 "TARGET_HARD_FLOAT"
1235 "sub.s\t%0,%1,%2"
1236 [(set_attr "type" "fadd")
1237 (set_attr "mode" "SF")])
1238
1239 (define_expand "subsi3"
1240 [(set (match_operand:SI 0 "register_operand" "")
1241 (minus:SI (match_operand:SI 1 "register_operand" "")
1242 (match_operand:SI 2 "register_operand" "")))]
1243 ""
1244 "")
1245
1246 (define_insn "subsi3_internal"
1247 [(set (match_operand:SI 0 "register_operand" "=d")
1248 (minus:SI (match_operand:SI 1 "register_operand" "d")
1249 (match_operand:SI 2 "register_operand" "d")))]
1250 ""
1251 "subu\t%0,%z1,%2"
1252 [(set_attr "type" "arith")
1253 (set_attr "mode" "SI")])
1254
1255 (define_expand "subdi3"
1256 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
1257 (minus:DI (match_operand:DI 1 "register_operand" "d")
1258 (match_operand:DI 2 "register_operand" "d")))
1259 (clobber (match_dup 3))])]
1260 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
1261 {
1262 if (TARGET_64BIT)
1263 {
1264 emit_insn (gen_subdi3_internal_3 (operands[0], operands[1],
1265 operands[2]));
1266 DONE;
1267 }
1268
1269 operands[3] = gen_reg_rtx (SImode);
1270 })
1271
1272 (define_insn "subdi3_internal"
1273 [(set (match_operand:DI 0 "register_operand" "=d")
1274 (minus:DI (match_operand:DI 1 "register_operand" "d")
1275 (match_operand:DI 2 "register_operand" "d")))
1276 (clobber (match_operand:SI 3 "register_operand" "=d"))]
1277 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
1278 "sltu\t%3,%L1,%L2\;subu\t%L0,%L1,%L2\;subu\t%M0,%M1,%M2\;subu\t%M0,%M0,%3"
1279 [(set_attr "type" "darith")
1280 (set_attr "mode" "DI")
1281 (set_attr "length" "16")])
1282
1283 (define_split
1284 [(set (match_operand:DI 0 "register_operand" "")
1285 (minus:DI (match_operand:DI 1 "register_operand" "")
1286 (match_operand:DI 2 "register_operand" "")))
1287 (clobber (match_operand:SI 3 "register_operand" ""))]
1288 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
1289 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1290 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1291 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1292 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1293
1294 [(set (match_dup 3)
1295 (ltu:SI (subreg:SI (match_dup 1) 0)
1296 (subreg:SI (match_dup 2) 0)))
1297
1298 (set (subreg:SI (match_dup 0) 0)
1299 (minus:SI (subreg:SI (match_dup 1) 0)
1300 (subreg:SI (match_dup 2) 0)))
1301
1302 (set (subreg:SI (match_dup 0) 4)
1303 (minus:SI (subreg:SI (match_dup 1) 4)
1304 (subreg:SI (match_dup 2) 4)))
1305
1306 (set (subreg:SI (match_dup 0) 4)
1307 (minus:SI (subreg:SI (match_dup 0) 4)
1308 (match_dup 3)))]
1309 "")
1310
1311 (define_split
1312 [(set (match_operand:DI 0 "register_operand" "")
1313 (minus:DI (match_operand:DI 1 "register_operand" "")
1314 (match_operand:DI 2 "register_operand" "")))
1315 (clobber (match_operand:SI 3 "register_operand" ""))]
1316 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
1317 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
1318 && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
1319 && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))
1320 && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
1321
1322 [(set (match_dup 3)
1323 (ltu:SI (subreg:SI (match_dup 1) 4)
1324 (subreg:SI (match_dup 2) 4)))
1325
1326 (set (subreg:SI (match_dup 0) 4)
1327 (minus:SI (subreg:SI (match_dup 1) 4)
1328 (subreg:SI (match_dup 2) 4)))
1329
1330 (set (subreg:SI (match_dup 0) 0)
1331 (minus:SI (subreg:SI (match_dup 1) 0)
1332 (subreg:SI (match_dup 2) 0)))
1333
1334 (set (subreg:SI (match_dup 0) 0)
1335 (minus:SI (subreg:SI (match_dup 0) 0)
1336 (match_dup 3)))]
1337 "")
1338
1339 (define_insn "subdi3_internal_3"
1340 [(set (match_operand:DI 0 "register_operand" "=d")
1341 (minus:DI (match_operand:DI 1 "register_operand" "d")
1342 (match_operand:DI 2 "register_operand" "d")))]
1343 "TARGET_64BIT"
1344 "dsubu\t%0,%1,%2"
1345 [(set_attr "type" "darith")
1346 (set_attr "mode" "DI")])
1347
1348 (define_insn "subsi3_internal_2"
1349 [(set (match_operand:DI 0 "register_operand" "=d")
1350 (sign_extend:DI
1351 (minus:SI (match_operand:SI 1 "register_operand" "d")
1352 (match_operand:SI 2 "register_operand" "d"))))]
1353 "TARGET_64BIT"
1354 "subu\t%0,%1,%2"
1355 [(set_attr "type" "arith")
1356 (set_attr "mode" "DI")])
1357 \f
1358 ;;
1359 ;; ....................
1360 ;;
1361 ;; MULTIPLICATION
1362 ;;
1363 ;; ....................
1364 ;;
1365
1366 (define_expand "muldf3"
1367 [(set (match_operand:DF 0 "register_operand" "=f")
1368 (mult:DF (match_operand:DF 1 "register_operand" "f")
1369 (match_operand:DF 2 "register_operand" "f")))]
1370 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
1371 "")
1372
1373 (define_insn "muldf3_internal"
1374 [(set (match_operand:DF 0 "register_operand" "=f")
1375 (mult:DF (match_operand:DF 1 "register_operand" "f")
1376 (match_operand:DF 2 "register_operand" "f")))]
1377 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_4300_MUL_FIX"
1378 "mul.d\t%0,%1,%2"
1379 [(set_attr "type" "fmul")
1380 (set_attr "mode" "DF")])
1381
1382 ;; Early VR4300 silicon has a CPU bug where multiplies with certain
1383 ;; operands may corrupt immediately following multiplies. This is a
1384 ;; simple fix to insert NOPs.
1385
1386 (define_insn "muldf3_r4300"
1387 [(set (match_operand:DF 0 "register_operand" "=f")
1388 (mult:DF (match_operand:DF 1 "register_operand" "f")
1389 (match_operand:DF 2 "register_operand" "f")))]
1390 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_4300_MUL_FIX"
1391 "mul.d\t%0,%1,%2\;nop"
1392 [(set_attr "type" "fmul")
1393 (set_attr "mode" "DF")
1394 (set_attr "length" "8")])
1395
1396 (define_expand "mulsf3"
1397 [(set (match_operand:SF 0 "register_operand" "=f")
1398 (mult:SF (match_operand:SF 1 "register_operand" "f")
1399 (match_operand:SF 2 "register_operand" "f")))]
1400 "TARGET_HARD_FLOAT"
1401 "")
1402
1403 (define_insn "mulsf3_internal"
1404 [(set (match_operand:SF 0 "register_operand" "=f")
1405 (mult:SF (match_operand:SF 1 "register_operand" "f")
1406 (match_operand:SF 2 "register_operand" "f")))]
1407 "TARGET_HARD_FLOAT && !TARGET_4300_MUL_FIX"
1408 "mul.s\t%0,%1,%2"
1409 [(set_attr "type" "fmul")
1410 (set_attr "mode" "SF")])
1411
1412 ;; See muldf3_r4300.
1413
1414 (define_insn "mulsf3_r4300"
1415 [(set (match_operand:SF 0 "register_operand" "=f")
1416 (mult:SF (match_operand:SF 1 "register_operand" "f")
1417 (match_operand:SF 2 "register_operand" "f")))]
1418 "TARGET_HARD_FLOAT && TARGET_4300_MUL_FIX"
1419 "mul.s\t%0,%1,%2\;nop"
1420 [(set_attr "type" "fmul")
1421 (set_attr "mode" "SF")
1422 (set_attr "length" "8")])
1423
1424
1425 ;; ??? The R4000 (only) has a cpu bug. If a double-word shift executes while
1426 ;; a multiply is in progress, it may give an incorrect result. Avoid
1427 ;; this by keeping the mflo with the mult on the R4000.
1428
1429 (define_expand "mulsi3"
1430 [(set (match_operand:SI 0 "register_operand" "")
1431 (mult:SI (match_operand:SI 1 "register_operand" "")
1432 (match_operand:SI 2 "register_operand" "")))]
1433 ""
1434 {
1435 if (GENERATE_MULT3_SI || TARGET_MAD)
1436 emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
1437 else if (!TARGET_MIPS4000 || TARGET_MIPS16)
1438 emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
1439 else
1440 emit_insn (gen_mulsi3_r4000 (operands[0], operands[1], operands[2]));
1441 DONE;
1442 })
1443
1444 (define_insn "mulsi3_mult3"
1445 [(set (match_operand:SI 0 "register_operand" "=d,l")
1446 (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1447 (match_operand:SI 2 "register_operand" "d,d")))
1448 (clobber (match_scratch:SI 3 "=h,h"))
1449 (clobber (match_scratch:SI 4 "=l,X"))]
1450 "GENERATE_MULT3_SI
1451 || TARGET_MAD"
1452 {
1453 if (which_alternative == 1)
1454 return "mult\t%1,%2";
1455 if (TARGET_MAD
1456 || TARGET_MIPS5400
1457 || TARGET_MIPS5500
1458 || TARGET_MIPS7000
1459 || TARGET_MIPS9000
1460 || ISA_MIPS32
1461 || ISA_MIPS32R2
1462 || ISA_MIPS64)
1463 return "mul\t%0,%1,%2";
1464 return "mult\t%0,%1,%2";
1465 }
1466 [(set_attr "type" "imul")
1467 (set_attr "mode" "SI")])
1468
1469 ;; If a register gets allocated to LO, and we spill to memory, the reload
1470 ;; will include a move from LO to a GPR. Merge it into the multiplication
1471 ;; if it can set the GPR directly.
1472 ;;
1473 ;; Operand 0: LO
1474 ;; Operand 1: GPR (1st multiplication operand)
1475 ;; Operand 2: GPR (2nd multiplication operand)
1476 ;; Operand 3: HI
1477 ;; Operand 4: GPR (destination)
1478 (define_peephole2
1479 [(parallel
1480 [(set (match_operand:SI 0 "register_operand" "")
1481 (mult:SI (match_operand:SI 1 "register_operand" "")
1482 (match_operand:SI 2 "register_operand" "")))
1483 (clobber (match_operand:SI 3 "register_operand" ""))
1484 (clobber (scratch:SI))])
1485 (set (match_operand:SI 4 "register_operand" "")
1486 (match_dup 0))]
1487 "GENERATE_MULT3_SI
1488 && true_regnum (operands[0]) == LO_REGNUM
1489 && GP_REG_P (true_regnum (operands[4]))
1490 && peep2_reg_dead_p (2, operands[0])"
1491 [(parallel
1492 [(set (match_dup 4)
1493 (mult:SI (match_dup 1)
1494 (match_dup 2)))
1495 (clobber (match_dup 3))
1496 (clobber (match_dup 0))])])
1497
1498 (define_insn "mulsi3_internal"
1499 [(set (match_operand:SI 0 "register_operand" "=l")
1500 (mult:SI (match_operand:SI 1 "register_operand" "d")
1501 (match_operand:SI 2 "register_operand" "d")))
1502 (clobber (match_scratch:SI 3 "=h"))]
1503 "!TARGET_MIPS4000 || TARGET_MIPS16"
1504 "mult\t%1,%2"
1505 [(set_attr "type" "imul")
1506 (set_attr "mode" "SI")])
1507
1508 (define_insn "mulsi3_r4000"
1509 [(set (match_operand:SI 0 "register_operand" "=d")
1510 (mult:SI (match_operand:SI 1 "register_operand" "d")
1511 (match_operand:SI 2 "register_operand" "d")))
1512 (clobber (match_scratch:SI 3 "=h"))
1513 (clobber (match_scratch:SI 4 "=l"))]
1514 "TARGET_MIPS4000 && !TARGET_MIPS16"
1515 "mult\t%1,%2\;mflo\t%0"
1516 [(set_attr "type" "imul")
1517 (set_attr "mode" "SI")
1518 (set_attr "length" "8")])
1519
1520 ;; Multiply-accumulate patterns
1521
1522 ;; For processors that can copy the output to a general register:
1523 ;;
1524 ;; The all-d alternative is needed because the combiner will find this
1525 ;; pattern and then register alloc/reload will move registers around to
1526 ;; make them fit, and we don't want to trigger unnecessary loads to LO.
1527 ;;
1528 ;; The last alternative should be made slightly less desirable, but adding
1529 ;; "?" to the constraint is too strong, and causes values to be loaded into
1530 ;; LO even when that's more costly. For now, using "*d" mostly does the
1531 ;; trick.
1532 (define_insn "*mul_acc_si"
1533 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1534 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
1535 (match_operand:SI 2 "register_operand" "d,d,d"))
1536 (match_operand:SI 3 "register_operand" "0,l,*d")))
1537 (clobber (match_scratch:SI 4 "=h,h,h"))
1538 (clobber (match_scratch:SI 5 "=X,3,l"))
1539 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1540 "(TARGET_MIPS3900
1541 || ISA_HAS_MADD_MSUB)
1542 && !TARGET_MIPS16"
1543 {
1544 static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
1545 if (which_alternative == 2)
1546 return "#";
1547 if (ISA_HAS_MADD_MSUB && which_alternative != 0)
1548 return "#";
1549 return madd[which_alternative];
1550 }
1551 [(set_attr "type" "imadd,imadd,multi")
1552 (set_attr "mode" "SI")
1553 (set_attr "length" "4,4,8")])
1554
1555 ;; Split the above insn if we failed to get LO allocated.
1556 (define_split
1557 [(set (match_operand:SI 0 "register_operand" "")
1558 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1559 (match_operand:SI 2 "register_operand" ""))
1560 (match_operand:SI 3 "register_operand" "")))
1561 (clobber (match_scratch:SI 4 ""))
1562 (clobber (match_scratch:SI 5 ""))
1563 (clobber (match_scratch:SI 6 ""))]
1564 "reload_completed && !TARGET_DEBUG_D_MODE
1565 && GP_REG_P (true_regnum (operands[0]))
1566 && GP_REG_P (true_regnum (operands[3]))"
1567 [(parallel [(set (match_dup 6)
1568 (mult:SI (match_dup 1) (match_dup 2)))
1569 (clobber (match_dup 4))
1570 (clobber (match_dup 5))])
1571 (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))]
1572 "")
1573
1574 ;; Splitter to copy result of MADD to a general register
1575 (define_split
1576 [(set (match_operand:SI 0 "register_operand" "")
1577 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1578 (match_operand:SI 2 "register_operand" ""))
1579 (match_operand:SI 3 "register_operand" "")))
1580 (clobber (match_scratch:SI 4 ""))
1581 (clobber (match_scratch:SI 5 ""))
1582 (clobber (match_scratch:SI 6 ""))]
1583 "reload_completed && !TARGET_DEBUG_D_MODE
1584 && GP_REG_P (true_regnum (operands[0]))
1585 && true_regnum (operands[3]) == LO_REGNUM"
1586 [(parallel [(set (match_dup 3)
1587 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
1588 (match_dup 3)))
1589 (clobber (match_dup 4))
1590 (clobber (match_dup 5))
1591 (clobber (match_dup 6))])
1592 (set (match_dup 0) (match_dup 3))]
1593 "")
1594
1595 (define_insn "*macc"
1596 [(set (match_operand:SI 0 "register_operand" "=l,d")
1597 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1598 (match_operand:SI 2 "register_operand" "d,d"))
1599 (match_operand:SI 3 "register_operand" "0,l")))
1600 (clobber (match_scratch:SI 4 "=h,h"))
1601 (clobber (match_scratch:SI 5 "=X,3"))]
1602 "ISA_HAS_MACC"
1603 {
1604 if (which_alternative == 1)
1605 return "macc\t%0,%1,%2";
1606 else if (TARGET_MIPS5500)
1607 return "madd\t%1,%2";
1608 else
1609 return "macc\t%.,%1,%2";
1610 }
1611 [(set_attr "type" "imadd")
1612 (set_attr "mode" "SI")])
1613
1614 ;; Pattern generated by define_peephole2 below
1615 (define_insn "*macc2"
1616 [(set (match_operand:SI 0 "register_operand" "=l")
1617 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
1618 (match_operand:SI 2 "register_operand" "d"))
1619 (match_dup 0)))
1620 (set (match_operand:SI 3 "register_operand" "=d")
1621 (plus:SI (mult:SI (match_dup 1)
1622 (match_dup 2))
1623 (match_dup 0)))
1624 (clobber (match_scratch:SI 4 "=h"))]
1625 "ISA_HAS_MACC && reload_completed"
1626 "macc\t%3,%1,%2"
1627 [(set_attr "type" "imadd")
1628 (set_attr "mode" "SI")])
1629
1630 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
1631 ;;
1632 ;; Operand 0: LO
1633 ;; Operand 1: GPR (1st multiplication operand)
1634 ;; Operand 2: GPR (2nd multiplication operand)
1635 ;; Operand 3: HI
1636 ;; Operand 4: GPR (destination)
1637 (define_peephole2
1638 [(parallel
1639 [(set (match_operand:SI 0 "register_operand" "")
1640 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
1641 (match_operand:SI 2 "register_operand" ""))
1642 (match_dup 0)))
1643 (clobber (match_operand:SI 3 "register_operand" ""))
1644 (clobber (scratch:SI))])
1645 (set (match_operand:SI 4 "register_operand" "")
1646 (match_dup 0))]
1647 "ISA_HAS_MACC
1648 && true_regnum (operands[0]) == LO_REGNUM
1649 && GP_REG_P (true_regnum (operands[4]))"
1650 [(parallel [(set (match_dup 0)
1651 (plus:SI (mult:SI (match_dup 1)
1652 (match_dup 2))
1653 (match_dup 0)))
1654 (set (match_dup 4)
1655 (plus:SI (mult:SI (match_dup 1)
1656 (match_dup 2))
1657 (match_dup 0)))
1658 (clobber (match_dup 3))])]
1659 "")
1660
1661 ;; When we have a three-address multiplication instruction, it should
1662 ;; be faster to do a separate multiply and add, rather than moving
1663 ;; something into LO in order to use a macc instruction.
1664 ;;
1665 ;; This peephole needs a scratch register to cater for the case when one
1666 ;; of the multiplication operands is the same as the destination.
1667 ;;
1668 ;; Operand 0: GPR (scratch)
1669 ;; Operand 1: LO
1670 ;; Operand 2: GPR (addend)
1671 ;; Operand 3: GPR (destination)
1672 ;; Operand 4: GPR (1st multiplication operand)
1673 ;; Operand 5: GPR (2nd multiplication operand)
1674 ;; Operand 6: HI
1675 (define_peephole2
1676 [(match_scratch:SI 0 "d")
1677 (set (match_operand:SI 1 "register_operand" "")
1678 (match_operand:SI 2 "register_operand" ""))
1679 (match_dup 0)
1680 (parallel
1681 [(set (match_operand:SI 3 "register_operand" "")
1682 (plus:SI (mult:SI (match_operand:SI 4 "register_operand" "")
1683 (match_operand:SI 5 "register_operand" ""))
1684 (match_dup 1)))
1685 (clobber (match_operand:SI 6 "register_operand" ""))
1686 (clobber (match_dup 1))])]
1687 "ISA_HAS_MACC && GENERATE_MULT3_SI
1688 && true_regnum (operands[1]) == LO_REGNUM
1689 && peep2_reg_dead_p (2, operands[1])
1690 && GP_REG_P (true_regnum (operands[3]))"
1691 [(parallel [(set (match_dup 0)
1692 (mult:SI (match_dup 4)
1693 (match_dup 5)))
1694 (clobber (match_dup 6))
1695 (clobber (match_dup 1))])
1696 (set (match_dup 3)
1697 (plus:SI (match_dup 0)
1698 (match_dup 2)))]
1699 "")
1700
1701 ;; Same as above, except LO is the initial target of the macc.
1702 ;;
1703 ;; Operand 0: GPR (scratch)
1704 ;; Operand 1: LO
1705 ;; Operand 2: GPR (addend)
1706 ;; Operand 3: GPR (1st multiplication operand)
1707 ;; Operand 4: GPR (2nd multiplication operand)
1708 ;; Operand 5: HI
1709 ;; Operand 6: GPR (destination)
1710 (define_peephole2
1711 [(match_scratch:SI 0 "d")
1712 (set (match_operand:SI 1 "register_operand" "")
1713 (match_operand:SI 2 "register_operand" ""))
1714 (match_dup 0)
1715 (parallel
1716 [(set (match_dup 1)
1717 (plus:SI (mult:SI (match_operand:SI 3 "register_operand" "")
1718 (match_operand:SI 4 "register_operand" ""))
1719 (match_dup 1)))
1720 (clobber (match_operand:SI 5 "register_operand" ""))
1721 (clobber (scratch:SI))])
1722 (match_dup 0)
1723 (set (match_operand:SI 6 "register_operand" "")
1724 (match_dup 1))]
1725 "ISA_HAS_MACC && GENERATE_MULT3_SI
1726 && true_regnum (operands[1]) == LO_REGNUM
1727 && peep2_reg_dead_p (3, operands[1])
1728 && GP_REG_P (true_regnum (operands[6]))"
1729 [(parallel [(set (match_dup 0)
1730 (mult:SI (match_dup 3)
1731 (match_dup 4)))
1732 (clobber (match_dup 5))
1733 (clobber (match_dup 1))])
1734 (set (match_dup 6)
1735 (plus:SI (match_dup 0)
1736 (match_dup 2)))]
1737 "")
1738
1739 (define_insn "*mul_sub_si"
1740 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
1741 (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
1742 (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
1743 (match_operand:SI 3 "register_operand" "d,d,d"))))
1744 (clobber (match_scratch:SI 4 "=h,h,h"))
1745 (clobber (match_scratch:SI 5 "=X,1,l"))
1746 (clobber (match_scratch:SI 6 "=X,X,&d"))]
1747 "ISA_HAS_MADD_MSUB"
1748 "@
1749 msub\t%2,%3
1750 #
1751 #"
1752 [(set_attr "type" "imadd,multi,multi")
1753 (set_attr "mode" "SI")
1754 (set_attr "length" "4,8,8")])
1755
1756 ;; Split the above insn if we failed to get LO allocated.
1757 (define_split
1758 [(set (match_operand:SI 0 "register_operand" "")
1759 (minus:SI (match_operand:SI 1 "register_operand" "")
1760 (mult:SI (match_operand:SI 2 "register_operand" "")
1761 (match_operand:SI 3 "register_operand" ""))))
1762 (clobber (match_scratch:SI 4 ""))
1763 (clobber (match_scratch:SI 5 ""))
1764 (clobber (match_scratch:SI 6 ""))]
1765 "reload_completed && !TARGET_DEBUG_D_MODE
1766 && GP_REG_P (true_regnum (operands[0]))
1767 && GP_REG_P (true_regnum (operands[1]))"
1768 [(parallel [(set (match_dup 6)
1769 (mult:SI (match_dup 2) (match_dup 3)))
1770 (clobber (match_dup 4))
1771 (clobber (match_dup 5))])
1772 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))]
1773 "")
1774
1775 ;; Splitter to copy result of MSUB to a general register
1776 (define_split
1777 [(set (match_operand:SI 0 "register_operand" "")
1778 (minus:SI (match_operand:SI 1 "register_operand" "")
1779 (mult:SI (match_operand:SI 2 "register_operand" "")
1780 (match_operand:SI 3 "register_operand" ""))))
1781 (clobber (match_scratch:SI 4 ""))
1782 (clobber (match_scratch:SI 5 ""))
1783 (clobber (match_scratch:SI 6 ""))]
1784 "reload_completed && !TARGET_DEBUG_D_MODE
1785 && GP_REG_P (true_regnum (operands[0]))
1786 && true_regnum (operands[1]) == LO_REGNUM"
1787 [(parallel [(set (match_dup 1)
1788 (minus:SI (match_dup 1)
1789 (mult:SI (match_dup 2) (match_dup 3))))
1790 (clobber (match_dup 4))
1791 (clobber (match_dup 5))
1792 (clobber (match_dup 6))])
1793 (set (match_dup 0) (match_dup 1))]
1794 "")
1795
1796 (define_insn "*muls"
1797 [(set (match_operand:SI 0 "register_operand" "=l,d")
1798 (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
1799 (match_operand:SI 2 "register_operand" "d,d"))))
1800 (clobber (match_scratch:SI 3 "=h,h"))
1801 (clobber (match_scratch:SI 4 "=X,l"))]
1802 "ISA_HAS_MULS"
1803 "@
1804 muls\t$0,%1,%2
1805 muls\t%0,%1,%2"
1806 [(set_attr "type" "imul")
1807 (set_attr "mode" "SI")])
1808
1809 (define_insn "*msac"
1810 [(set (match_operand:SI 0 "register_operand" "=l,d")
1811 (minus:SI (match_operand:SI 1 "register_operand" "0,l")
1812 (mult:SI (match_operand:SI 2 "register_operand" "d,d")
1813 (match_operand:SI 3 "register_operand" "d,d"))))
1814 (clobber (match_scratch:SI 4 "=h,h"))
1815 (clobber (match_scratch:SI 5 "=X,1"))]
1816 "ISA_HAS_MSAC"
1817 {
1818 if (which_alternative == 1)
1819 return "msac\t%0,%2,%3";
1820 else if (TARGET_MIPS5500)
1821 return "msub\t%2,%3";
1822 else
1823 return "msac\t$0,%2,%3";
1824 }
1825 [(set_attr "type" "imadd")
1826 (set_attr "mode" "SI")])
1827
1828 (define_expand "muldi3"
1829 [(set (match_operand:DI 0 "register_operand" "")
1830 (mult:DI (match_operand:DI 1 "register_operand" "")
1831 (match_operand:DI 2 "register_operand" "")))]
1832 "TARGET_64BIT"
1833 {
1834 if (GENERATE_MULT3_DI || TARGET_MIPS4000)
1835 emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2]));
1836 else
1837 emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
1838 DONE;
1839 })
1840
1841 (define_insn "muldi3_internal"
1842 [(set (match_operand:DI 0 "register_operand" "=l")
1843 (mult:DI (match_operand:DI 1 "register_operand" "d")
1844 (match_operand:DI 2 "register_operand" "d")))
1845 (clobber (match_scratch:DI 3 "=h"))]
1846 "TARGET_64BIT && !TARGET_MIPS4000"
1847 "dmult\t%1,%2"
1848 [(set_attr "type" "imul")
1849 (set_attr "mode" "DI")])
1850
1851 (define_insn "muldi3_internal2"
1852 [(set (match_operand:DI 0 "register_operand" "=d")
1853 (mult:DI (match_operand:DI 1 "register_operand" "d")
1854 (match_operand:DI 2 "register_operand" "d")))
1855 (clobber (match_scratch:DI 3 "=h"))
1856 (clobber (match_scratch:DI 4 "=l"))]
1857 "TARGET_64BIT && (GENERATE_MULT3_DI || TARGET_MIPS4000)"
1858 {
1859 if (GENERATE_MULT3_DI)
1860 return "dmult\t%0,%1,%2";
1861 else
1862 return "dmult\t%1,%2\;mflo\t%0";
1863 }
1864 [(set_attr "type" "imul")
1865 (set_attr "mode" "DI")
1866 (set (attr "length")
1867 (if_then_else (ne (symbol_ref "GENERATE_MULT3_DI") (const_int 0))
1868 (const_int 4)
1869 (const_int 8)))])
1870
1871 ;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
1872
1873 (define_expand "mulsidi3"
1874 [(parallel
1875 [(set (match_operand:DI 0 "register_operand" "")
1876 (mult:DI
1877 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1878 (sign_extend:DI (match_operand:SI 2 "register_operand" ""))))
1879 (clobber (scratch:DI))
1880 (clobber (scratch:DI))
1881 (clobber (scratch:DI))])]
1882 ""
1883 {
1884 if (!TARGET_64BIT)
1885 {
1886 emit_insn (gen_mulsidi3_32bit (operands[0], operands[1], operands[2]));
1887 DONE;
1888 }
1889 })
1890
1891 (define_insn "mulsidi3_32bit"
1892 [(set (match_operand:DI 0 "register_operand" "=x")
1893 (mult:DI
1894 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
1895 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1896 "!TARGET_64BIT"
1897 "mult\t%1,%2"
1898 [(set_attr "type" "imul")
1899 (set_attr "mode" "SI")])
1900
1901 (define_insn_and_split "*mulsidi3_64bit"
1902 [(set (match_operand:DI 0 "register_operand" "=d")
1903 (mult:DI (match_operator:DI 1 "extend_operator"
1904 [(match_operand:SI 3 "register_operand" "d")])
1905 (match_operator:DI 2 "extend_operator"
1906 [(match_operand:SI 4 "register_operand" "d")])))
1907 (clobber (match_scratch:DI 5 "=l"))
1908 (clobber (match_scratch:DI 6 "=h"))
1909 (clobber (match_scratch:DI 7 "=d"))]
1910 "TARGET_64BIT && GET_CODE (operands[1]) == GET_CODE (operands[2])"
1911 "#"
1912 "&& reload_completed"
1913 [(parallel
1914 [(set (match_dup 5)
1915 (sign_extend:DI
1916 (mult:SI (match_dup 3)
1917 (match_dup 4))))
1918 (set (match_dup 6)
1919 (ashiftrt:DI
1920 (mult:DI (match_dup 1)
1921 (match_dup 2))
1922 (const_int 32)))])
1923
1924 ;; OP7 <- LO, OP0 <- HI
1925 (set (match_dup 7) (match_dup 5))
1926 (set (match_dup 0) (match_dup 6))
1927
1928 ;; Zero-extend OP7.
1929 (set (match_dup 7)
1930 (ashift:DI (match_dup 7)
1931 (const_int 32)))
1932 (set (match_dup 7)
1933 (lshiftrt:DI (match_dup 7)
1934 (const_int 32)))
1935
1936 ;; Shift OP0 into place.
1937 (set (match_dup 0)
1938 (ashift:DI (match_dup 0)
1939 (const_int 32)))
1940
1941 ;; OR the two halves together
1942 (set (match_dup 0)
1943 (ior:DI (match_dup 0)
1944 (match_dup 7)))]
1945 ""
1946 [(set_attr "type" "imul")
1947 (set_attr "mode" "SI")
1948 (set_attr "length" "24")])
1949
1950 (define_insn "*mulsidi3_64bit_parts"
1951 [(set (match_operand:DI 0 "register_operand" "=l")
1952 (sign_extend:DI
1953 (mult:SI (match_operand:SI 2 "register_operand" "d")
1954 (match_operand:SI 3 "register_operand" "d"))))
1955 (set (match_operand:DI 1 "register_operand" "=h")
1956 (ashiftrt:DI
1957 (mult:DI
1958 (match_operator:DI 4 "extend_operator" [(match_dup 2)])
1959 (match_operator:DI 5 "extend_operator" [(match_dup 3)]))
1960 (const_int 32)))]
1961 "TARGET_64BIT && GET_CODE (operands[4]) == GET_CODE (operands[5])"
1962 {
1963 if (GET_CODE (operands[4]) == SIGN_EXTEND)
1964 return "mult\t%2,%3";
1965 else
1966 return "multu\t%2,%3";
1967 }
1968 [(set_attr "type" "imul")
1969 (set_attr "mode" "SI")])
1970
1971 (define_expand "umulsidi3"
1972 [(parallel
1973 [(set (match_operand:DI 0 "register_operand" "")
1974 (mult:DI
1975 (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1976 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
1977 (clobber (scratch:DI))
1978 (clobber (scratch:DI))
1979 (clobber (scratch:DI))])]
1980 ""
1981 {
1982 if (!TARGET_64BIT)
1983 {
1984 emit_insn (gen_umulsidi3_32bit (operands[0], operands[1],
1985 operands[2]));
1986 DONE;
1987 }
1988 })
1989
1990 (define_insn "umulsidi3_32bit"
1991 [(set (match_operand:DI 0 "register_operand" "=x")
1992 (mult:DI
1993 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
1994 (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
1995 "!TARGET_64BIT"
1996 "multu\t%1,%2"
1997 [(set_attr "type" "imul")
1998 (set_attr "mode" "SI")])
1999
2000 ;; Widening multiply with negation.
2001 (define_insn "*muls_di"
2002 [(set (match_operand:DI 0 "register_operand" "=x")
2003 (neg:DI
2004 (mult:DI
2005 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2006 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
2007 "!TARGET_64BIT && ISA_HAS_MULS"
2008 "muls\t$0,%1,%2"
2009 [(set_attr "type" "imul")
2010 (set_attr "length" "4")
2011 (set_attr "mode" "SI")])
2012
2013 (define_insn "*umuls_di"
2014 [(set (match_operand:DI 0 "register_operand" "=x")
2015 (neg:DI
2016 (mult:DI
2017 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2018 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
2019 "!TARGET_64BIT && ISA_HAS_MULS"
2020 "mulsu\t$0,%1,%2"
2021 [(set_attr "type" "imul")
2022 (set_attr "length" "4")
2023 (set_attr "mode" "SI")])
2024
2025 (define_insn "*smsac_di"
2026 [(set (match_operand:DI 0 "register_operand" "=x")
2027 (minus:DI
2028 (match_operand:DI 3 "register_operand" "0")
2029 (mult:DI
2030 (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2031 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
2032 "!TARGET_64BIT && ISA_HAS_MSAC"
2033 {
2034 if (TARGET_MIPS5500)
2035 return "msub\t%1,%2";
2036 else
2037 return "msac\t$0,%1,%2";
2038 }
2039 [(set_attr "type" "imadd")
2040 (set_attr "length" "4")
2041 (set_attr "mode" "SI")])
2042
2043 (define_insn "*umsac_di"
2044 [(set (match_operand:DI 0 "register_operand" "=x")
2045 (minus:DI
2046 (match_operand:DI 3 "register_operand" "0")
2047 (mult:DI
2048 (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2049 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))))]
2050 "!TARGET_64BIT && ISA_HAS_MSAC"
2051 {
2052 if (TARGET_MIPS5500)
2053 return "msubu\t%1,%2";
2054 else
2055 return "msacu\t$0,%1,%2";
2056 }
2057 [(set_attr "type" "imadd")
2058 (set_attr "length" "4")
2059 (set_attr "mode" "SI")])
2060
2061 ;; _highpart patterns
2062 (define_expand "umulsi3_highpart"
2063 [(set (match_operand:SI 0 "register_operand" "")
2064 (truncate:SI
2065 (lshiftrt:DI
2066 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2067 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
2068 (const_int 32))))]
2069 ""
2070 {
2071 if (ISA_HAS_MULHI)
2072 emit_insn (gen_umulsi3_highpart_mulhi_internal (operands[0], operands[1],
2073 operands[2]));
2074 else
2075 emit_insn (gen_umulsi3_highpart_internal (operands[0], operands[1],
2076 operands[2]));
2077 DONE;
2078 })
2079
2080 (define_insn "umulsi3_highpart_internal"
2081 [(set (match_operand:SI 0 "register_operand" "=h")
2082 (truncate:SI
2083 (lshiftrt:DI
2084 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2085 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
2086 (const_int 32))))
2087 (clobber (match_scratch:SI 3 "=l"))]
2088 "!ISA_HAS_MULHI"
2089 "multu\t%1,%2"
2090 [(set_attr "type" "imul")
2091 (set_attr "mode" "SI")
2092 (set_attr "length" "4")])
2093
2094 (define_insn "umulsi3_highpart_mulhi_internal"
2095 [(set (match_operand:SI 0 "register_operand" "=h,d")
2096 (truncate:SI
2097 (lshiftrt:DI
2098 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2099 (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
2100 (const_int 32))))
2101 (clobber (match_scratch:SI 3 "=l,l"))
2102 (clobber (match_scratch:SI 4 "=X,h"))]
2103 "ISA_HAS_MULHI"
2104 "@
2105 multu\t%1,%2
2106 mulhiu\t%0,%1,%2"
2107 [(set_attr "type" "imul")
2108 (set_attr "mode" "SI")
2109 (set_attr "length" "4")])
2110
2111 (define_insn "umulsi3_highpart_neg_mulhi_internal"
2112 [(set (match_operand:SI 0 "register_operand" "=h,d")
2113 (truncate:SI
2114 (lshiftrt:DI
2115 (neg:DI
2116 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2117 (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
2118 (const_int 32))))
2119 (clobber (match_scratch:SI 3 "=l,l"))
2120 (clobber (match_scratch:SI 4 "=X,h"))]
2121 "ISA_HAS_MULHI"
2122 "@
2123 mulshiu\t%.,%1,%2
2124 mulshiu\t%0,%1,%2"
2125 [(set_attr "type" "imul")
2126 (set_attr "mode" "SI")
2127 (set_attr "length" "4")])
2128
2129 (define_expand "smulsi3_highpart"
2130 [(set (match_operand:SI 0 "register_operand" "")
2131 (truncate:SI
2132 (lshiftrt:DI
2133 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
2134 (sign_extend:DI (match_operand:SI 2 "register_operand" "")))
2135 (const_int 32))))]
2136 ""
2137 {
2138 if (ISA_HAS_MULHI)
2139 emit_insn (gen_smulsi3_highpart_mulhi_internal (operands[0], operands[1],
2140 operands[2]));
2141 else
2142 emit_insn (gen_smulsi3_highpart_internal (operands[0], operands[1],
2143 operands[2]));
2144 DONE;
2145 })
2146
2147 (define_insn "smulsi3_highpart_internal"
2148 [(set (match_operand:SI 0 "register_operand" "=h")
2149 (truncate:SI
2150 (lshiftrt:DI
2151 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2152 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
2153 (const_int 32))))
2154 (clobber (match_scratch:SI 3 "=l"))]
2155 "!ISA_HAS_MULHI"
2156 "mult\t%1,%2"
2157 [(set_attr "type" "imul")
2158 (set_attr "mode" "SI")
2159 (set_attr "length" "4")])
2160
2161 (define_insn "smulsi3_highpart_mulhi_internal"
2162 [(set (match_operand:SI 0 "register_operand" "=h,d")
2163 (truncate:SI
2164 (lshiftrt:DI
2165 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2166 (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d")))
2167 (const_int 32))))
2168 (clobber (match_scratch:SI 3 "=l,l"))
2169 (clobber (match_scratch:SI 4 "=X,h"))]
2170 "ISA_HAS_MULHI"
2171 "@
2172 mult\t%1,%2
2173 mulhi\t%0,%1,%2"
2174 [(set_attr "type" "imul")
2175 (set_attr "mode" "SI")
2176 (set_attr "length" "4")])
2177
2178 (define_insn "smulsi3_highpart_neg_mulhi_internal"
2179 [(set (match_operand:SI 0 "register_operand" "=h,d")
2180 (truncate:SI
2181 (lshiftrt:DI
2182 (neg:DI
2183 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d"))
2184 (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d"))))
2185 (const_int 32))))
2186 (clobber (match_scratch:SI 3 "=l,l"))
2187 (clobber (match_scratch:SI 4 "=X,h"))]
2188 "ISA_HAS_MULHI"
2189 "@
2190 mulshi\t%.,%1,%2
2191 mulshi\t%0,%1,%2"
2192 [(set_attr "type" "imul")
2193 (set_attr "mode" "SI")])
2194
2195 (define_insn "smuldi3_highpart"
2196 [(set (match_operand:DI 0 "register_operand" "=h")
2197 (truncate:DI
2198 (lshiftrt:TI
2199 (mult:TI
2200 (sign_extend:TI (match_operand:DI 1 "register_operand" "d"))
2201 (sign_extend:TI (match_operand:DI 2 "register_operand" "d")))
2202 (const_int 64))))
2203 (clobber (match_scratch:DI 3 "=l"))]
2204 "TARGET_64BIT"
2205 "dmult\t%1,%2"
2206 [(set_attr "type" "imul")
2207 (set_attr "mode" "DI")])
2208
2209 (define_insn "umuldi3_highpart"
2210 [(set (match_operand:DI 0 "register_operand" "=h")
2211 (truncate:DI
2212 (lshiftrt:TI
2213 (mult:TI
2214 (zero_extend:TI (match_operand:DI 1 "register_operand" "d"))
2215 (zero_extend:TI (match_operand:DI 2 "register_operand" "d")))
2216 (const_int 64))))
2217 (clobber (match_scratch:DI 3 "=l"))]
2218 "TARGET_64BIT"
2219 "dmultu\t%1,%2"
2220 [(set_attr "type" "imul")
2221 (set_attr "mode" "DI")])
2222
2223
2224 ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate
2225 ;; instruction. The HI/LO registers are used as a 64 bit accumulator.
2226
2227 (define_insn "madsi"
2228 [(set (match_operand:SI 0 "register_operand" "+l")
2229 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
2230 (match_operand:SI 2 "register_operand" "d"))
2231 (match_dup 0)))
2232 (clobber (match_scratch:SI 3 "=h"))]
2233 "TARGET_MAD"
2234 "mad\t%1,%2"
2235 [(set_attr "type" "imadd")
2236 (set_attr "mode" "SI")])
2237
2238 (define_insn "*umul_acc_di"
2239 [(set (match_operand:DI 0 "register_operand" "=x")
2240 (plus:DI
2241 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
2242 (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
2243 (match_operand:DI 3 "register_operand" "0")))]
2244 "(TARGET_MAD || ISA_HAS_MACC)
2245 && !TARGET_64BIT"
2246 {
2247 if (TARGET_MAD)
2248 return "madu\t%1,%2";
2249 else if (TARGET_MIPS5500)
2250 return "maddu\t%1,%2";
2251 else
2252 return "maccu\t%.,%1,%2";
2253 }
2254 [(set_attr "type" "imadd")
2255 (set_attr "mode" "SI")])
2256
2257
2258 (define_insn "*smul_acc_di"
2259 [(set (match_operand:DI 0 "register_operand" "=x")
2260 (plus:DI
2261 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
2262 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
2263 (match_operand:DI 3 "register_operand" "0")))]
2264 "(TARGET_MAD || ISA_HAS_MACC)
2265 && !TARGET_64BIT"
2266 {
2267 if (TARGET_MAD)
2268 return "mad\t%1,%2";
2269 else if (TARGET_MIPS5500)
2270 return "madd\t%1,%2";
2271 else
2272 return "macc\t%.,%1,%2";
2273 }
2274 [(set_attr "type" "imadd")
2275 (set_attr "mode" "SI")])
2276
2277 ;; Floating point multiply accumulate instructions.
2278
2279 (define_insn ""
2280 [(set (match_operand:DF 0 "register_operand" "=f")
2281 (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2282 (match_operand:DF 2 "register_operand" "f"))
2283 (match_operand:DF 3 "register_operand" "f")))]
2284 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2285 "madd.d\t%0,%3,%1,%2"
2286 [(set_attr "type" "fmadd")
2287 (set_attr "mode" "DF")])
2288
2289 (define_insn ""
2290 [(set (match_operand:SF 0 "register_operand" "=f")
2291 (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2292 (match_operand:SF 2 "register_operand" "f"))
2293 (match_operand:SF 3 "register_operand" "f")))]
2294 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2295 "madd.s\t%0,%3,%1,%2"
2296 [(set_attr "type" "fmadd")
2297 (set_attr "mode" "SF")])
2298
2299 (define_insn ""
2300 [(set (match_operand:DF 0 "register_operand" "=f")
2301 (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2302 (match_operand:DF 2 "register_operand" "f"))
2303 (match_operand:DF 3 "register_operand" "f")))]
2304 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2305 "msub.d\t%0,%3,%1,%2"
2306 [(set_attr "type" "fmadd")
2307 (set_attr "mode" "DF")])
2308
2309 (define_insn ""
2310 [(set (match_operand:SF 0 "register_operand" "=f")
2311 (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2312 (match_operand:SF 2 "register_operand" "f"))
2313 (match_operand:SF 3 "register_operand" "f")))]
2314
2315 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2316 "msub.s\t%0,%3,%1,%2"
2317 [(set_attr "type" "fmadd")
2318 (set_attr "mode" "SF")])
2319
2320 (define_insn ""
2321 [(set (match_operand:DF 0 "register_operand" "=f")
2322 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
2323 (match_operand:DF 2 "register_operand" "f"))
2324 (match_operand:DF 3 "register_operand" "f"))))]
2325 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2326 "nmadd.d\t%0,%3,%1,%2"
2327 [(set_attr "type" "fmadd")
2328 (set_attr "mode" "DF")])
2329
2330 (define_insn ""
2331 [(set (match_operand:SF 0 "register_operand" "=f")
2332 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
2333 (match_operand:SF 2 "register_operand" "f"))
2334 (match_operand:SF 3 "register_operand" "f"))))]
2335 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2336 "nmadd.s\t%0,%3,%1,%2"
2337 [(set_attr "type" "fmadd")
2338 (set_attr "mode" "SF")])
2339
2340 (define_insn ""
2341 [(set (match_operand:DF 0 "register_operand" "=f")
2342 (minus:DF (match_operand:DF 1 "register_operand" "f")
2343 (mult:DF (match_operand:DF 2 "register_operand" "f")
2344 (match_operand:DF 3 "register_operand" "f"))))]
2345 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FUSED_MADD"
2346 "nmsub.d\t%0,%1,%2,%3"
2347 [(set_attr "type" "fmadd")
2348 (set_attr "mode" "DF")])
2349
2350 (define_insn ""
2351 [(set (match_operand:SF 0 "register_operand" "=f")
2352 (minus:SF (match_operand:SF 1 "register_operand" "f")
2353 (mult:SF (match_operand:SF 2 "register_operand" "f")
2354 (match_operand:SF 3 "register_operand" "f"))))]
2355 "ISA_HAS_NMADD_NMSUB && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
2356 "nmsub.s\t%0,%1,%2,%3"
2357 [(set_attr "type" "fmadd")
2358 (set_attr "mode" "SF")])
2359 \f
2360 ;;
2361 ;; ....................
2362 ;;
2363 ;; DIVISION and REMAINDER
2364 ;;
2365 ;; ....................
2366 ;;
2367
2368 (define_expand "divdf3"
2369 [(set (match_operand:DF 0 "register_operand" "")
2370 (div:DF (match_operand:DF 1 "reg_or_const_float_1_operand" "")
2371 (match_operand:DF 2 "register_operand" "")))]
2372 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2373 {
2374 if (const_float_1_operand (operands[1], DFmode))
2375 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
2376 FAIL;
2377 })
2378
2379 ;; This pattern works around the early SB-1 rev2 core "F1" erratum:
2380 ;;
2381 ;; If an mfc1 or dmfc1 happens to access the floating point register
2382 ;; file at the same time a long latency operation (div, sqrt, recip,
2383 ;; sqrt) iterates an intermediate result back through the floating
2384 ;; point register file bypass, then instead returning the correct
2385 ;; register value the mfc1 or dmfc1 operation returns the intermediate
2386 ;; result of the long latency operation.
2387 ;;
2388 ;; The workaround is to insert an unconditional 'mov' from/to the
2389 ;; long latency op destination register.
2390
2391 (define_insn "*divdf3"
2392 [(set (match_operand:DF 0 "register_operand" "=f")
2393 (div:DF (match_operand:DF 1 "register_operand" "f")
2394 (match_operand:DF 2 "register_operand" "f")))]
2395 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2396 {
2397 if (TARGET_FIX_SB1)
2398 return "div.d\t%0,%1,%2\;mov.d\t%0,%0";
2399 else
2400 return "div.d\t%0,%1,%2";
2401 }
2402 [(set_attr "type" "fdiv")
2403 (set_attr "mode" "DF")
2404 (set (attr "length")
2405 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2406 (const_int 8)
2407 (const_int 4)))])
2408
2409
2410 ;; This pattern works around the early SB-1 rev2 core "F2" erratum:
2411 ;;
2412 ;; In certain cases, div.s and div.ps may have a rounding error
2413 ;; and/or wrong inexact flag.
2414 ;;
2415 ;; Therefore, we only allow div.s if not working around SB-1 rev2
2416 ;; errata, or if working around those errata and a slight loss of
2417 ;; precision is OK (i.e., flag_unsafe_math_optimizations is set).
2418 (define_expand "divsf3"
2419 [(set (match_operand:SF 0 "register_operand" "")
2420 (div:SF (match_operand:SF 1 "reg_or_const_float_1_operand" "")
2421 (match_operand:SF 2 "register_operand" "")))]
2422 "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2423 {
2424 if (const_float_1_operand (operands[1], SFmode))
2425 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
2426 FAIL;
2427 })
2428
2429 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2430 ;; "divdf3" comment for details).
2431 ;;
2432 ;; This pattern works around the early SB-1 rev2 core "F2" erratum (see
2433 ;; "divsf3" comment for details).
2434 (define_insn "*divsf3"
2435 [(set (match_operand:SF 0 "register_operand" "=f")
2436 (div:SF (match_operand:SF 1 "register_operand" "f")
2437 (match_operand:SF 2 "register_operand" "f")))]
2438 "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
2439 {
2440 if (TARGET_FIX_SB1)
2441 return "div.s\t%0,%1,%2\;mov.s\t%0,%0";
2442 else
2443 return "div.s\t%0,%1,%2";
2444 }
2445 [(set_attr "type" "fdiv")
2446 (set_attr "mode" "SF")
2447 (set (attr "length")
2448 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2449 (const_int 8)
2450 (const_int 4)))])
2451
2452 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2453 ;; "divdf3" comment for details).
2454 (define_insn ""
2455 [(set (match_operand:DF 0 "register_operand" "=f")
2456 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2457 (match_operand:DF 2 "register_operand" "f")))]
2458 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2459 {
2460 if (TARGET_FIX_SB1)
2461 return "recip.d\t%0,%2\;mov.d\t%0,%0";
2462 else
2463 return "recip.d\t%0,%2";
2464 }
2465 [(set_attr "type" "fdiv")
2466 (set_attr "mode" "DF")
2467 (set (attr "length")
2468 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2469 (const_int 8)
2470 (const_int 4)))])
2471
2472 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2473 ;; "divdf3" comment for details).
2474 (define_insn ""
2475 [(set (match_operand:SF 0 "register_operand" "=f")
2476 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2477 (match_operand:SF 2 "register_operand" "f")))]
2478 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2479 {
2480 if (TARGET_FIX_SB1)
2481 return "recip.s\t%0,%2\;mov.s\t%0,%0";
2482 else
2483 return "recip.s\t%0,%2";
2484 }
2485 [(set_attr "type" "fdiv")
2486 (set_attr "mode" "SF")
2487 (set (attr "length")
2488 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2489 (const_int 8)
2490 (const_int 4)))])
2491
2492 (define_insn "divmodsi4"
2493 [(set (match_operand:SI 0 "register_operand" "=l")
2494 (div:SI (match_operand:SI 1 "register_operand" "d")
2495 (match_operand:SI 2 "register_operand" "d")))
2496 (set (match_operand:SI 3 "register_operand" "=h")
2497 (mod:SI (match_dup 1)
2498 (match_dup 2)))]
2499 ""
2500 { return mips_output_division ("div\t$0,%1,%2", operands); }
2501 [(set_attr "type" "idiv")
2502 (set_attr "mode" "SI")])
2503
2504 (define_insn "divmoddi4"
2505 [(set (match_operand:DI 0 "register_operand" "=l")
2506 (div:DI (match_operand:DI 1 "register_operand" "d")
2507 (match_operand:DI 2 "register_operand" "d")))
2508 (set (match_operand:DI 3 "register_operand" "=h")
2509 (mod:DI (match_dup 1)
2510 (match_dup 2)))]
2511 "TARGET_64BIT"
2512 { return mips_output_division ("ddiv\t$0,%1,%2", operands); }
2513 [(set_attr "type" "idiv")
2514 (set_attr "mode" "DI")])
2515
2516 (define_insn "udivmodsi4"
2517 [(set (match_operand:SI 0 "register_operand" "=l")
2518 (udiv:SI (match_operand:SI 1 "register_operand" "d")
2519 (match_operand:SI 2 "register_operand" "d")))
2520 (set (match_operand:SI 3 "register_operand" "=h")
2521 (umod:SI (match_dup 1)
2522 (match_dup 2)))]
2523 ""
2524 { return mips_output_division ("divu\t$0,%1,%2", operands); }
2525 [(set_attr "type" "idiv")
2526 (set_attr "mode" "SI")])
2527
2528 (define_insn "udivmoddi4"
2529 [(set (match_operand:DI 0 "register_operand" "=l")
2530 (udiv:DI (match_operand:DI 1 "register_operand" "d")
2531 (match_operand:DI 2 "register_operand" "d")))
2532 (set (match_operand:DI 3 "register_operand" "=h")
2533 (umod:DI (match_dup 1)
2534 (match_dup 2)))]
2535 "TARGET_64BIT"
2536 { return mips_output_division ("ddivu\t$0,%1,%2", operands); }
2537 [(set_attr "type" "idiv")
2538 (set_attr "mode" "DI")])
2539 \f
2540 ;;
2541 ;; ....................
2542 ;;
2543 ;; SQUARE ROOT
2544 ;;
2545 ;; ....................
2546
2547 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2548 ;; "divdf3" comment for details).
2549 (define_insn "sqrtdf2"
2550 [(set (match_operand:DF 0 "register_operand" "=f")
2551 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2552 "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
2553 {
2554 if (TARGET_FIX_SB1)
2555 return "sqrt.d\t%0,%1\;mov.d\t%0,%0";
2556 else
2557 return "sqrt.d\t%0,%1";
2558 }
2559 [(set_attr "type" "fsqrt")
2560 (set_attr "mode" "DF")
2561 (set (attr "length")
2562 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2563 (const_int 8)
2564 (const_int 4)))])
2565
2566 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2567 ;; "divdf3" comment for details).
2568 (define_insn "sqrtsf2"
2569 [(set (match_operand:SF 0 "register_operand" "=f")
2570 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2571 "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
2572 {
2573 if (TARGET_FIX_SB1)
2574 return "sqrt.s\t%0,%1\;mov.s\t%0,%0";
2575 else
2576 return "sqrt.s\t%0,%1";
2577 }
2578 [(set_attr "type" "fsqrt")
2579 (set_attr "mode" "SF")
2580 (set (attr "length")
2581 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2582 (const_int 8)
2583 (const_int 4)))])
2584
2585 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2586 ;; "divdf3" comment for details).
2587 (define_insn ""
2588 [(set (match_operand:DF 0 "register_operand" "=f")
2589 (div:DF (match_operand:DF 1 "const_float_1_operand" "")
2590 (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
2591 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
2592 {
2593 if (TARGET_FIX_SB1)
2594 return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
2595 else
2596 return "rsqrt.d\t%0,%2";
2597 }
2598 [(set_attr "type" "frsqrt")
2599 (set_attr "mode" "DF")
2600 (set (attr "length")
2601 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2602 (const_int 8)
2603 (const_int 4)))])
2604
2605 ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
2606 ;; "divdf3" comment for details).
2607 (define_insn ""
2608 [(set (match_operand:SF 0 "register_operand" "=f")
2609 (div:SF (match_operand:SF 1 "const_float_1_operand" "")
2610 (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
2611 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
2612 {
2613 if (TARGET_FIX_SB1)
2614 return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
2615 else
2616 return "rsqrt.s\t%0,%2";
2617 }
2618 [(set_attr "type" "frsqrt")
2619 (set_attr "mode" "SF")
2620 (set (attr "length")
2621 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
2622 (const_int 8)
2623 (const_int 4)))])
2624 \f
2625 ;;
2626 ;; ....................
2627 ;;
2628 ;; ABSOLUTE VALUE
2629 ;;
2630 ;; ....................
2631
2632 ;; Do not use the integer abs macro instruction, since that signals an
2633 ;; exception on -2147483648 (sigh).
2634
2635 (define_insn "abssi2"
2636 [(set (match_operand:SI 0 "register_operand" "=d")
2637 (abs:SI (match_operand:SI 1 "register_operand" "d")))]
2638 "!TARGET_MIPS16"
2639 {
2640 operands[2] = const0_rtx;
2641
2642 if (REGNO (operands[0]) == REGNO (operands[1]))
2643 {
2644 if (GENERATE_BRANCHLIKELY)
2645 return "%(bltzl\t%1,1f\;subu\t%0,%z2,%0\n%~1:%)";
2646 else
2647 return "bgez\t%1,1f%#\;subu\t%0,%z2,%0\n%~1:";
2648 }
2649 else
2650 return "%(bgez\t%1,1f\;move\t%0,%1\;subu\t%0,%z2,%0\n%~1:%)";
2651 }
2652 [(set_attr "type" "multi")
2653 (set_attr "mode" "SI")
2654 (set_attr "length" "12")])
2655
2656 (define_insn "absdi2"
2657 [(set (match_operand:DI 0 "register_operand" "=d")
2658 (abs:DI (match_operand:DI 1 "register_operand" "d")))]
2659 "TARGET_64BIT && !TARGET_MIPS16"
2660 {
2661 unsigned int regno1;
2662 operands[2] = const0_rtx;
2663
2664 if (GET_CODE (operands[1]) == REG)
2665 regno1 = REGNO (operands[1]);
2666 else
2667 regno1 = REGNO (XEXP (operands[1], 0));
2668
2669 if (REGNO (operands[0]) == regno1)
2670 return "%(bltzl\t%1,1f\;dsubu\t%0,%z2,%0\n%~1:%)";
2671 else
2672 return "%(bgez\t%1,1f\;move\t%0,%1\;dsubu\t%0,%z2,%0\n%~1:%)";
2673 }
2674 [(set_attr "type" "multi")
2675 (set_attr "mode" "DI")
2676 (set_attr "length" "12")])
2677
2678 (define_insn "absdf2"
2679 [(set (match_operand:DF 0 "register_operand" "=f")
2680 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
2681 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2682 "abs.d\t%0,%1"
2683 [(set_attr "type" "fabs")
2684 (set_attr "mode" "DF")])
2685
2686 (define_insn "abssf2"
2687 [(set (match_operand:SF 0 "register_operand" "=f")
2688 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2689 "TARGET_HARD_FLOAT"
2690 "abs.s\t%0,%1"
2691 [(set_attr "type" "fabs")
2692 (set_attr "mode" "SF")])
2693 \f
2694 ;;
2695 ;; ....................
2696 ;;
2697 ;; FIND FIRST BIT INSTRUCTION
2698 ;;
2699 ;; ....................
2700 ;;
2701
2702 (define_insn "ffssi2"
2703 [(set (match_operand:SI 0 "register_operand" "=&d")
2704 (ffs:SI (match_operand:SI 1 "register_operand" "d")))
2705 (clobber (match_scratch:SI 2 "=&d"))
2706 (clobber (match_scratch:SI 3 "=&d"))]
2707 "!TARGET_MIPS16"
2708 {
2709 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2710 return "%(\
2711 move\t%0,%.\;\
2712 beq\t%1,%.,2f\n\
2713 %~1:\tand\t%2,%1,0x0001\;\
2714 addu\t%0,%0,1\;\
2715 beq\t%2,%.,1b\;\
2716 srl\t%1,%1,1\n\
2717 %~2:%)";
2718
2719 return "%(\
2720 move\t%0,%.\;\
2721 move\t%3,%1\;\
2722 beq\t%3,%.,2f\n\
2723 %~1:\tand\t%2,%3,0x0001\;\
2724 addu\t%0,%0,1\;\
2725 beq\t%2,%.,1b\;\
2726 srl\t%3,%3,1\n\
2727 %~2:%)";
2728 }
2729 [(set_attr "type" "multi")
2730 (set_attr "mode" "SI")
2731 (set_attr "length" "28")])
2732
2733 (define_insn "ffsdi2"
2734 [(set (match_operand:DI 0 "register_operand" "=&d")
2735 (ffs:DI (match_operand:DI 1 "register_operand" "d")))
2736 (clobber (match_scratch:DI 2 "=&d"))
2737 (clobber (match_scratch:DI 3 "=&d"))]
2738 "TARGET_64BIT && !TARGET_MIPS16"
2739 {
2740 if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
2741 return "%(\
2742 move\t%0,%.\;\
2743 beq\t%1,%.,2f\n\
2744 %~1:\tand\t%2,%1,0x0001\;\
2745 daddu\t%0,%0,1\;\
2746 beq\t%2,%.,1b\;\
2747 dsrl\t%1,%1,1\n\
2748 %~2:%)";
2749
2750 return "%(\
2751 move\t%0,%.\;\
2752 move\t%3,%1\;\
2753 beq\t%3,%.,2f\n\
2754 %~1:\tand\t%2,%3,0x0001\;\
2755 daddu\t%0,%0,1\;\
2756 beq\t%2,%.,1b\;\
2757 dsrl\t%3,%3,1\n\
2758 %~2:%)";
2759 }
2760 [(set_attr "type" "multi")
2761 (set_attr "mode" "DI")
2762 (set_attr "length" "28")])
2763 \f
2764 ;;
2765 ;; ...................
2766 ;;
2767 ;; Count leading zeroes.
2768 ;;
2769 ;; ...................
2770 ;;
2771
2772 (define_insn "clzsi2"
2773 [(set (match_operand:SI 0 "register_operand" "=d")
2774 (clz:SI (match_operand:SI 1 "register_operand" "d")))]
2775 "ISA_HAS_CLZ_CLO"
2776 "clz\t%0,%1"
2777 [(set_attr "type" "arith")
2778 (set_attr "mode" "SI")])
2779
2780 (define_insn "clzdi2"
2781 [(set (match_operand:DI 0 "register_operand" "=d")
2782 (clz:DI (match_operand:DI 1 "register_operand" "d")))]
2783 "ISA_HAS_DCLZ_DCLO"
2784 "dclz\t%0,%1"
2785 [(set_attr "type" "arith")
2786 (set_attr "mode" "DI")])
2787 \f
2788 ;;
2789 ;; ....................
2790 ;;
2791 ;; NEGATION and ONE'S COMPLEMENT
2792 ;;
2793 ;; ....................
2794
2795 (define_insn "negsi2"
2796 [(set (match_operand:SI 0 "register_operand" "=d")
2797 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
2798 ""
2799 {
2800 if (TARGET_MIPS16)
2801 return "neg\t%0,%1";
2802 else
2803 return "subu\t%0,%.,%1";
2804 }
2805 [(set_attr "type" "arith")
2806 (set_attr "mode" "SI")])
2807
2808 (define_expand "negdi2"
2809 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
2810 (neg:DI (match_operand:DI 1 "register_operand" "d")))
2811 (clobber (match_dup 2))])]
2812 "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
2813 {
2814 if (TARGET_64BIT)
2815 {
2816 emit_insn (gen_negdi2_internal_2 (operands[0], operands[1]));
2817 DONE;
2818 }
2819
2820 operands[2] = gen_reg_rtx (SImode);
2821 })
2822
2823 (define_insn "negdi2_internal"
2824 [(set (match_operand:DI 0 "register_operand" "=d")
2825 (neg:DI (match_operand:DI 1 "register_operand" "d")))
2826 (clobber (match_operand:SI 2 "register_operand" "=d"))]
2827 "! TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
2828 "subu\t%L0,%.,%L1\;subu\t%M0,%.,%M1\;sltu\t%2,%.,%L0\;subu\t%M0,%M0,%2"
2829 [(set_attr "type" "darith")
2830 (set_attr "mode" "DI")
2831 (set_attr "length" "16")])
2832
2833 (define_insn "negdi2_internal_2"
2834 [(set (match_operand:DI 0 "register_operand" "=d")
2835 (neg:DI (match_operand:DI 1 "register_operand" "d")))]
2836 "TARGET_64BIT && !TARGET_MIPS16"
2837 "dsubu\t%0,%.,%1"
2838 [(set_attr "type" "arith")
2839 (set_attr "mode" "DI")])
2840
2841 (define_insn "negdf2"
2842 [(set (match_operand:DF 0 "register_operand" "=f")
2843 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
2844 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
2845 "neg.d\t%0,%1"
2846 [(set_attr "type" "fneg")
2847 (set_attr "mode" "DF")])
2848
2849 (define_insn "negsf2"
2850 [(set (match_operand:SF 0 "register_operand" "=f")
2851 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2852 "TARGET_HARD_FLOAT"
2853 "neg.s\t%0,%1"
2854 [(set_attr "type" "fneg")
2855 (set_attr "mode" "SF")])
2856
2857 (define_insn "one_cmplsi2"
2858 [(set (match_operand:SI 0 "register_operand" "=d")
2859 (not:SI (match_operand:SI 1 "register_operand" "d")))]
2860 ""
2861 {
2862 if (TARGET_MIPS16)
2863 return "not\t%0,%1";
2864 else
2865 return "nor\t%0,%.,%1";
2866 }
2867 [(set_attr "type" "arith")
2868 (set_attr "mode" "SI")])
2869
2870 (define_insn "one_cmpldi2"
2871 [(set (match_operand:DI 0 "register_operand" "=d")
2872 (not:DI (match_operand:DI 1 "register_operand" "d")))]
2873 "TARGET_64BIT"
2874 {
2875 if (TARGET_MIPS16)
2876 return "not\t%0,%1";
2877 else
2878 return "nor\t%0,%.,%1";
2879 }
2880 [(set_attr "type" "darith")
2881 (set_attr "mode" "DI")])
2882 \f
2883 ;;
2884 ;; ....................
2885 ;;
2886 ;; LOGICAL
2887 ;;
2888 ;; ....................
2889 ;;
2890
2891 ;; Many of these instructions use trivial define_expands, because we
2892 ;; want to use a different set of constraints when TARGET_MIPS16.
2893
2894 (define_expand "andsi3"
2895 [(set (match_operand:SI 0 "register_operand" "=d,d")
2896 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2897 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2898 ""
2899 {
2900 if (TARGET_MIPS16)
2901 {
2902 operands[1] = force_reg (SImode, operands[1]);
2903 operands[2] = force_reg (SImode, operands[2]);
2904 }
2905 })
2906
2907 (define_insn ""
2908 [(set (match_operand:SI 0 "register_operand" "=d,d")
2909 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2910 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2911 "!TARGET_MIPS16"
2912 "@
2913 and\t%0,%1,%2
2914 andi\t%0,%1,%x2"
2915 [(set_attr "type" "arith")
2916 (set_attr "mode" "SI")])
2917
2918 (define_insn ""
2919 [(set (match_operand:SI 0 "register_operand" "=d")
2920 (and:SI (match_operand:SI 1 "register_operand" "%0")
2921 (match_operand:SI 2 "register_operand" "d")))]
2922 "TARGET_MIPS16"
2923 "and\t%0,%2"
2924 [(set_attr "type" "arith")
2925 (set_attr "mode" "SI")])
2926
2927 (define_expand "anddi3"
2928 [(set (match_operand:DI 0 "register_operand" "")
2929 (and:DI (match_operand:DI 1 "register_operand" "")
2930 (match_operand:DI 2 "uns_arith_operand" "")))]
2931 "TARGET_64BIT"
2932 {
2933 if (TARGET_MIPS16)
2934 {
2935 operands[1] = force_reg (DImode, operands[1]);
2936 operands[2] = force_reg (DImode, operands[2]);
2937 }
2938 })
2939
2940 (define_insn ""
2941 [(set (match_operand:DI 0 "register_operand" "=d,d")
2942 (and:DI (match_operand:DI 1 "register_operand" "d,d")
2943 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
2944 "TARGET_64BIT && !TARGET_MIPS16"
2945 "@
2946 and\t%0,%1,%2
2947 andi\t%0,%1,%x2"
2948 [(set_attr "type" "darith")
2949 (set_attr "mode" "DI")])
2950
2951 (define_insn ""
2952 [(set (match_operand:DI 0 "register_operand" "=d")
2953 (and:DI (match_operand:DI 1 "register_operand" "0")
2954 (match_operand:DI 2 "register_operand" "d")))]
2955 "TARGET_64BIT && TARGET_MIPS16"
2956 "and\t%0,%2"
2957 [(set_attr "type" "darith")
2958 (set_attr "mode" "DI")])
2959
2960 (define_expand "iorsi3"
2961 [(set (match_operand:SI 0 "register_operand" "=d,d")
2962 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2963 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2964 ""
2965 {
2966 if (TARGET_MIPS16)
2967 {
2968 operands[1] = force_reg (SImode, operands[1]);
2969 operands[2] = force_reg (SImode, operands[2]);
2970 }
2971 })
2972
2973 (define_insn ""
2974 [(set (match_operand:SI 0 "register_operand" "=d,d")
2975 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
2976 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
2977 "!TARGET_MIPS16"
2978 "@
2979 or\t%0,%1,%2
2980 ori\t%0,%1,%x2"
2981 [(set_attr "type" "arith")
2982 (set_attr "mode" "SI")])
2983
2984 (define_insn ""
2985 [(set (match_operand:SI 0 "register_operand" "=d")
2986 (ior:SI (match_operand:SI 1 "register_operand" "%0")
2987 (match_operand:SI 2 "register_operand" "d")))]
2988 "TARGET_MIPS16"
2989 "or\t%0,%2"
2990 [(set_attr "type" "arith")
2991 (set_attr "mode" "SI")])
2992
2993 (define_expand "iordi3"
2994 [(set (match_operand:DI 0 "register_operand" "")
2995 (ior:DI (match_operand:DI 1 "register_operand" "")
2996 (match_operand:DI 2 "uns_arith_operand" "")))]
2997 "TARGET_64BIT"
2998 {
2999 if (TARGET_MIPS16)
3000 {
3001 operands[1] = force_reg (DImode, operands[1]);
3002 operands[2] = force_reg (DImode, operands[2]);
3003 }
3004 })
3005
3006 (define_insn ""
3007 [(set (match_operand:DI 0 "register_operand" "=d,d")
3008 (ior:DI (match_operand:DI 1 "register_operand" "d,d")
3009 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
3010 "TARGET_64BIT && !TARGET_MIPS16"
3011 "@
3012 or\t%0,%1,%2
3013 ori\t%0,%1,%x2"
3014 [(set_attr "type" "darith")
3015 (set_attr "mode" "DI")])
3016
3017 (define_insn ""
3018 [(set (match_operand:DI 0 "register_operand" "=d")
3019 (ior:DI (match_operand:DI 1 "register_operand" "0")
3020 (match_operand:DI 2 "register_operand" "d")))]
3021 "TARGET_64BIT && TARGET_MIPS16"
3022 "or\t%0,%2"
3023 [(set_attr "type" "darith")
3024 (set_attr "mode" "DI")])
3025
3026 (define_expand "xorsi3"
3027 [(set (match_operand:SI 0 "register_operand" "=d,d")
3028 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3029 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3030 ""
3031 "")
3032
3033 (define_insn ""
3034 [(set (match_operand:SI 0 "register_operand" "=d,d")
3035 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
3036 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
3037 "!TARGET_MIPS16"
3038 "@
3039 xor\t%0,%1,%2
3040 xori\t%0,%1,%x2"
3041 [(set_attr "type" "arith")
3042 (set_attr "mode" "SI")])
3043
3044 (define_insn ""
3045 [(set (match_operand:SI 0 "register_operand" "=d,t,t")
3046 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%0,d,d")
3047 (match_operand:SI 2 "uns_arith_operand" "d,K,d")))]
3048 "TARGET_MIPS16"
3049 "@
3050 xor\t%0,%2
3051 cmpi\t%1,%2
3052 cmp\t%1,%2"
3053 [(set_attr "type" "arith")
3054 (set_attr "mode" "SI")
3055 (set_attr_alternative "length"
3056 [(const_int 4)
3057 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3058 (const_int 4)
3059 (const_int 8))
3060 (const_int 4)])])
3061
3062 (define_expand "xordi3"
3063 [(set (match_operand:DI 0 "register_operand" "")
3064 (xor:DI (match_operand:DI 1 "register_operand" "")
3065 (match_operand:DI 2 "uns_arith_operand" "")))]
3066 "TARGET_64BIT"
3067 {
3068 if (TARGET_MIPS16)
3069 {
3070 operands[1] = force_reg (DImode, operands[1]);
3071 operands[2] = force_reg (DImode, operands[2]);
3072 }
3073 })
3074
3075 (define_insn ""
3076 [(set (match_operand:DI 0 "register_operand" "=d,d")
3077 (xor:DI (match_operand:DI 1 "register_operand" "d,d")
3078 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
3079 "TARGET_64BIT && !TARGET_MIPS16"
3080 "@
3081 xor\t%0,%1,%2
3082 xori\t%0,%1,%x2"
3083 [(set_attr "type" "darith")
3084 (set_attr "mode" "DI")])
3085
3086 (define_insn ""
3087 [(set (match_operand:DI 0 "register_operand" "=d,t,t")
3088 (xor:DI (match_operand:DI 1 "register_operand" "%0,d,d")
3089 (match_operand:DI 2 "uns_arith_operand" "d,K,d")))]
3090 "TARGET_64BIT && TARGET_MIPS16"
3091 "@
3092 xor\t%0,%2
3093 cmpi\t%1,%2
3094 cmp\t%1,%2"
3095 [(set_attr "type" "arith")
3096 (set_attr "mode" "DI")
3097 (set_attr_alternative "length"
3098 [(const_int 4)
3099 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
3100 (const_int 4)
3101 (const_int 8))
3102 (const_int 4)])])
3103
3104 (define_insn "*norsi3"
3105 [(set (match_operand:SI 0 "register_operand" "=d")
3106 (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
3107 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
3108 "!TARGET_MIPS16"
3109 "nor\t%0,%z1,%z2"
3110 [(set_attr "type" "arith")
3111 (set_attr "mode" "SI")])
3112
3113 (define_insn "*nordi3"
3114 [(set (match_operand:DI 0 "register_operand" "=d")
3115 (and:DI (not:DI (match_operand:DI 1 "register_operand" "d"))
3116 (not:DI (match_operand:DI 2 "register_operand" "d"))))]
3117 "TARGET_64BIT && !TARGET_MIPS16"
3118 "nor\t%0,%z1,%z2"
3119 [(set_attr "type" "darith")
3120 (set_attr "mode" "DI")])
3121 \f
3122 ;;
3123 ;; ....................
3124 ;;
3125 ;; TRUNCATION
3126 ;;
3127 ;; ....................
3128
3129
3130
3131 (define_insn "truncdfsf2"
3132 [(set (match_operand:SF 0 "register_operand" "=f")
3133 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3134 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3135 "cvt.s.d\t%0,%1"
3136 [(set_attr "type" "fcvt")
3137 (set_attr "mode" "SF")])
3138
3139 ;; Integer truncation patterns. Truncating SImode values to smaller
3140 ;; modes is a no-op, as it is for most other GCC ports. Truncating
3141 ;; DImode values to SImode is not a no-op for TARGET_64BIT since we
3142 ;; need to make sure that the lower 32 bits are properly sign-extended
3143 ;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes
3144 ;; smaller than SImode is equivalent to two separate truncations:
3145 ;;
3146 ;; A B
3147 ;; DI ---> HI == DI ---> SI ---> HI
3148 ;; DI ---> QI == DI ---> SI ---> QI
3149 ;;
3150 ;; Step A needs a real instruction but step B does not.
3151
3152 (define_insn "truncdisi2"
3153 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
3154 (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
3155 "TARGET_64BIT"
3156 "@
3157 sll\t%0,%1,0
3158 sw\t%1,%0"
3159 [(set_attr "type" "darith,store")
3160 (set_attr "mode" "SI")
3161 (set_attr "extended_mips16" "yes,*")])
3162
3163 (define_insn "truncdihi2"
3164 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
3165 (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
3166 "TARGET_64BIT"
3167 "@
3168 sll\t%0,%1,0
3169 sh\t%1,%0"
3170 [(set_attr "type" "darith,store")
3171 (set_attr "mode" "SI")
3172 (set_attr "extended_mips16" "yes,*")])
3173
3174 (define_insn "truncdiqi2"
3175 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
3176 (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
3177 "TARGET_64BIT"
3178 "@
3179 sll\t%0,%1,0
3180 sb\t%1,%0"
3181 [(set_attr "type" "darith,store")
3182 (set_attr "mode" "SI")
3183 (set_attr "extended_mips16" "yes,*")])
3184
3185 ;; Combiner patterns to optimize shift/truncate combinations.
3186
3187 (define_insn ""
3188 [(set (match_operand:SI 0 "register_operand" "=d")
3189 (truncate:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
3190 (match_operand:DI 2 "small_int" "I"))))]
3191 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
3192 "dsra\t%0,%1,%2"
3193 [(set_attr "type" "darith")
3194 (set_attr "mode" "SI")])
3195
3196 (define_insn ""
3197 [(set (match_operand:SI 0 "register_operand" "=d")
3198 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
3199 (const_int 32))))]
3200 "TARGET_64BIT && !TARGET_MIPS16"
3201 "dsra\t%0,%1,32"
3202 [(set_attr "type" "darith")
3203 (set_attr "mode" "SI")])
3204
3205
3206 ;; Combiner patterns for truncate/sign_extend combinations. They use
3207 ;; the shift/truncate patterns above.
3208
3209 (define_insn_and_split ""
3210 [(set (match_operand:SI 0 "register_operand" "=d")
3211 (sign_extend:SI
3212 (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
3213 "TARGET_64BIT && !TARGET_MIPS16"
3214 "#"
3215 "&& reload_completed"
3216 [(set (match_dup 2)
3217 (ashift:DI (match_dup 1)
3218 (const_int 48)))
3219 (set (match_dup 0)
3220 (truncate:SI (ashiftrt:DI (match_dup 2)
3221 (const_int 48))))]
3222 { operands[2] = gen_lowpart (DImode, operands[0]); })
3223
3224 (define_insn_and_split ""
3225 [(set (match_operand:SI 0 "register_operand" "=d")
3226 (sign_extend:SI
3227 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
3228 "TARGET_64BIT && !TARGET_MIPS16"
3229 "#"
3230 "&& reload_completed"
3231 [(set (match_dup 2)
3232 (ashift:DI (match_dup 1)
3233 (const_int 56)))
3234 (set (match_dup 0)
3235 (truncate:SI (ashiftrt:DI (match_dup 2)
3236 (const_int 56))))]
3237 { operands[2] = gen_lowpart (DImode, operands[0]); })
3238
3239
3240 ;; Combiner patterns to optimize truncate/zero_extend combinations.
3241
3242 (define_insn ""
3243 [(set (match_operand:SI 0 "register_operand" "=d")
3244 (zero_extend:SI (truncate:HI
3245 (match_operand:DI 1 "register_operand" "d"))))]
3246 "TARGET_64BIT && !TARGET_MIPS16"
3247 "andi\t%0,%1,0xffff"
3248 [(set_attr "type" "darith")
3249 (set_attr "mode" "SI")])
3250
3251 (define_insn ""
3252 [(set (match_operand:SI 0 "register_operand" "=d")
3253 (zero_extend:SI (truncate:QI
3254 (match_operand:DI 1 "register_operand" "d"))))]
3255 "TARGET_64BIT && !TARGET_MIPS16"
3256 "andi\t%0,%1,0xff"
3257 [(set_attr "type" "darith")
3258 (set_attr "mode" "SI")])
3259
3260 (define_insn ""
3261 [(set (match_operand:HI 0 "register_operand" "=d")
3262 (zero_extend:HI (truncate:QI
3263 (match_operand:DI 1 "register_operand" "d"))))]
3264 "TARGET_64BIT && !TARGET_MIPS16"
3265 "andi\t%0,%1,0xff"
3266 [(set_attr "type" "darith")
3267 (set_attr "mode" "HI")])
3268 \f
3269 ;;
3270 ;; ....................
3271 ;;
3272 ;; ZERO EXTENSION
3273 ;;
3274 ;; ....................
3275
3276 ;; Extension insns.
3277 ;; Those for integer source operand are ordered widest source type first.
3278
3279 (define_insn_and_split "zero_extendsidi2"
3280 [(set (match_operand:DI 0 "register_operand" "=d")
3281 (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))]
3282 "TARGET_64BIT"
3283 "#"
3284 "&& reload_completed"
3285 [(set (match_dup 0)
3286 (ashift:DI (match_dup 1) (const_int 32)))
3287 (set (match_dup 0)
3288 (lshiftrt:DI (match_dup 0) (const_int 32)))]
3289 "operands[1] = gen_lowpart (DImode, operands[1]);"
3290 [(set_attr "type" "arith")
3291 (set_attr "mode" "DI")])
3292
3293 (define_insn "*zero_extendsidi2_mem"
3294 [(set (match_operand:DI 0 "register_operand" "=d")
3295 (zero_extend:DI (match_operand:SI 1 "memory_operand" "W")))]
3296 "TARGET_64BIT"
3297 "lwu\t%0,%1"
3298 [(set_attr "type" "load")
3299 (set_attr "mode" "DI")])
3300
3301 (define_expand "zero_extendhisi2"
3302 [(set (match_operand:SI 0 "register_operand" "")
3303 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3304 ""
3305 {
3306 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3307 {
3308 rtx op = gen_lowpart (SImode, operands[1]);
3309 rtx temp = force_reg (SImode, GEN_INT (0xffff));
3310
3311 emit_insn (gen_andsi3 (operands[0], op, temp));
3312 DONE;
3313 }
3314 })
3315
3316 (define_insn ""
3317 [(set (match_operand:SI 0 "register_operand" "=d,d")
3318 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
3319 "!TARGET_MIPS16"
3320 "@
3321 andi\t%0,%1,0xffff
3322 lhu\t%0,%1"
3323 [(set_attr "type" "arith,load")
3324 (set_attr "mode" "SI")
3325 (set_attr "length" "4,*")])
3326
3327 (define_insn ""
3328 [(set (match_operand:SI 0 "register_operand" "=d")
3329 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3330 "TARGET_MIPS16"
3331 "lhu\t%0,%1"
3332 [(set_attr "type" "load")
3333 (set_attr "mode" "SI")])
3334
3335 (define_expand "zero_extendhidi2"
3336 [(set (match_operand:DI 0 "register_operand" "")
3337 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
3338 "TARGET_64BIT"
3339 {
3340 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3341 {
3342 rtx op = gen_lowpart (DImode, operands[1]);
3343 rtx temp = force_reg (DImode, GEN_INT (0xffff));
3344
3345 emit_insn (gen_anddi3 (operands[0], op, temp));
3346 DONE;
3347 }
3348 })
3349
3350 (define_insn ""
3351 [(set (match_operand:DI 0 "register_operand" "=d,d")
3352 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
3353 "TARGET_64BIT && !TARGET_MIPS16"
3354 "@
3355 andi\t%0,%1,0xffff
3356 lhu\t%0,%1"
3357 [(set_attr "type" "arith,load")
3358 (set_attr "mode" "DI")
3359 (set_attr "length" "4,*")])
3360
3361 (define_insn ""
3362 [(set (match_operand:DI 0 "register_operand" "=d")
3363 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3364 "TARGET_64BIT && TARGET_MIPS16"
3365 "lhu\t%0,%1"
3366 [(set_attr "type" "load")
3367 (set_attr "mode" "DI")])
3368
3369 (define_expand "zero_extendqihi2"
3370 [(set (match_operand:HI 0 "register_operand" "")
3371 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3372 ""
3373 {
3374 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3375 {
3376 rtx op0 = gen_lowpart (SImode, operands[0]);
3377 rtx op1 = gen_lowpart (SImode, operands[1]);
3378 rtx temp = force_reg (SImode, GEN_INT (0xff));
3379
3380 emit_insn (gen_andsi3 (op0, op1, temp));
3381 DONE;
3382 }
3383 })
3384
3385 (define_insn ""
3386 [(set (match_operand:HI 0 "register_operand" "=d,d")
3387 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3388 "!TARGET_MIPS16"
3389 "@
3390 andi\t%0,%1,0x00ff
3391 lbu\t%0,%1"
3392 [(set_attr "type" "arith,load")
3393 (set_attr "mode" "HI")
3394 (set_attr "length" "4,*")])
3395
3396 (define_insn ""
3397 [(set (match_operand:HI 0 "register_operand" "=d")
3398 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3399 "TARGET_MIPS16"
3400 "lbu\t%0,%1"
3401 [(set_attr "type" "load")
3402 (set_attr "mode" "HI")])
3403
3404 (define_expand "zero_extendqisi2"
3405 [(set (match_operand:SI 0 "register_operand" "")
3406 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3407 ""
3408 {
3409 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3410 {
3411 rtx op = gen_lowpart (SImode, operands[1]);
3412 rtx temp = force_reg (SImode, GEN_INT (0xff));
3413
3414 emit_insn (gen_andsi3 (operands[0], op, temp));
3415 DONE;
3416 }
3417 })
3418
3419 (define_insn ""
3420 [(set (match_operand:SI 0 "register_operand" "=d,d")
3421 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3422 "!TARGET_MIPS16"
3423 "@
3424 andi\t%0,%1,0x00ff
3425 lbu\t%0,%1"
3426 [(set_attr "type" "arith,load")
3427 (set_attr "mode" "SI")
3428 (set_attr "length" "4,*")])
3429
3430 (define_insn ""
3431 [(set (match_operand:SI 0 "register_operand" "=d")
3432 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3433 "TARGET_MIPS16"
3434 "lbu\t%0,%1"
3435 [(set_attr "type" "load")
3436 (set_attr "mode" "SI")])
3437
3438 (define_expand "zero_extendqidi2"
3439 [(set (match_operand:DI 0 "register_operand" "")
3440 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
3441 "TARGET_64BIT"
3442 {
3443 if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
3444 {
3445 rtx op = gen_lowpart (DImode, operands[1]);
3446 rtx temp = force_reg (DImode, GEN_INT (0xff));
3447
3448 emit_insn (gen_anddi3 (operands[0], op, temp));
3449 DONE;
3450 }
3451 })
3452
3453 (define_insn ""
3454 [(set (match_operand:DI 0 "register_operand" "=d,d")
3455 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
3456 "TARGET_64BIT && !TARGET_MIPS16"
3457 "@
3458 andi\t%0,%1,0x00ff
3459 lbu\t%0,%1"
3460 [(set_attr "type" "arith,load")
3461 (set_attr "mode" "DI")
3462 (set_attr "length" "4,*")])
3463
3464 (define_insn ""
3465 [(set (match_operand:DI 0 "register_operand" "=d")
3466 (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3467 "TARGET_64BIT && TARGET_MIPS16"
3468 "lbu\t%0,%1"
3469 [(set_attr "type" "load")
3470 (set_attr "mode" "DI")])
3471 \f
3472 ;;
3473 ;; ....................
3474 ;;
3475 ;; SIGN EXTENSION
3476 ;;
3477 ;; ....................
3478
3479 ;; Extension insns.
3480 ;; Those for integer source operand are ordered widest source type first.
3481
3482 (define_insn "extendsidi2"
3483 [(set (match_operand:DI 0 "register_operand" "=d,d")
3484 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))]
3485 "TARGET_64BIT"
3486 "@
3487 sll\t%0,%1,0
3488 lw\t%0,%1"
3489 [(set_attr "type" "arith,load")
3490 (set_attr "mode" "DI")
3491 (set_attr "extended_mips16" "yes,*")])
3492
3493 ;; These patterns originally accepted general_operands, however, slightly
3494 ;; better code is generated by only accepting register_operands, and then
3495 ;; letting combine generate the lh and lb insns.
3496
3497 ;; These expanders originally put values in registers first. We split
3498 ;; all non-mem patterns after reload.
3499
3500 (define_expand "extendhidi2"
3501 [(set (match_operand:DI 0 "register_operand" "")
3502 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
3503 "TARGET_64BIT"
3504 "")
3505
3506 (define_insn "*extendhidi2"
3507 [(set (match_operand:DI 0 "register_operand" "=d")
3508 (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))]
3509 "TARGET_64BIT"
3510 "#")
3511
3512 (define_split
3513 [(set (match_operand:DI 0 "register_operand" "")
3514 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3515 "TARGET_64BIT && reload_completed"
3516 [(set (match_dup 0)
3517 (ashift:DI (match_dup 1) (const_int 48)))
3518 (set (match_dup 0)
3519 (ashiftrt:DI (match_dup 0) (const_int 48)))]
3520 "operands[1] = gen_lowpart (DImode, operands[1]);")
3521
3522 (define_insn "*extendhidi2_mem"
3523 [(set (match_operand:DI 0 "register_operand" "=d")
3524 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3525 "TARGET_64BIT"
3526 "lh\t%0,%1"
3527 [(set_attr "type" "load")
3528 (set_attr "mode" "DI")])
3529
3530 (define_expand "extendhisi2"
3531 [(set (match_operand:SI 0 "register_operand" "")
3532 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3533 ""
3534 {
3535 if (ISA_HAS_SEB_SEH)
3536 {
3537 emit_insn (gen_extendhisi2_hw (operands[0],
3538 force_reg (HImode, operands[1])));
3539 DONE;
3540 }
3541 })
3542
3543 (define_insn "*extendhisi2"
3544 [(set (match_operand:SI 0 "register_operand" "=d")
3545 (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))]
3546 ""
3547 "#")
3548
3549 (define_split
3550 [(set (match_operand:SI 0 "register_operand" "")
3551 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3552 "reload_completed"
3553 [(set (match_dup 0)
3554 (ashift:SI (match_dup 1) (const_int 16)))
3555 (set (match_dup 0)
3556 (ashiftrt:SI (match_dup 0) (const_int 16)))]
3557 "operands[1] = gen_lowpart (SImode, operands[1]);")
3558
3559 (define_insn "extendhisi2_mem"
3560 [(set (match_operand:SI 0 "register_operand" "=d")
3561 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3562 ""
3563 "lh\t%0,%1"
3564 [(set_attr "type" "load")
3565 (set_attr "mode" "SI")])
3566
3567 (define_insn "extendhisi2_hw"
3568 [(set (match_operand:SI 0 "register_operand" "=r")
3569 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
3570 "ISA_HAS_SEB_SEH"
3571 "seh\t%0,%1"
3572 [(set_attr "type" "arith")
3573 (set_attr "mode" "SI")])
3574
3575 (define_expand "extendqihi2"
3576 [(set (match_operand:HI 0 "register_operand" "")
3577 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3578 ""
3579 "")
3580
3581 (define_insn "*extendqihi2"
3582 [(set (match_operand:HI 0 "register_operand" "=d")
3583 (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))]
3584 ""
3585 "#")
3586
3587 (define_split
3588 [(set (match_operand:HI 0 "register_operand" "")
3589 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3590 "reload_completed"
3591 [(set (match_dup 0)
3592 (ashift:SI (match_dup 1) (const_int 24)))
3593 (set (match_dup 0)
3594 (ashiftrt:SI (match_dup 0) (const_int 24)))]
3595 "operands[0] = gen_lowpart (SImode, operands[0]);
3596 operands[1] = gen_lowpart (SImode, operands[1]);")
3597
3598 (define_insn "*extendqihi2_internal_mem"
3599 [(set (match_operand:HI 0 "register_operand" "=d")
3600 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3601 ""
3602 "lb\t%0,%1"
3603 [(set_attr "type" "load")
3604 (set_attr "mode" "SI")])
3605
3606
3607 (define_expand "extendqisi2"
3608 [(set (match_operand:SI 0 "register_operand" "")
3609 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
3610 ""
3611 {
3612 if (ISA_HAS_SEB_SEH)
3613 {
3614 emit_insn (gen_extendqisi2_hw (operands[0],
3615 force_reg (QImode, operands[1])));
3616 DONE;
3617 }
3618 })
3619
3620 (define_insn "*extendqisi2"
3621 [(set (match_operand:SI 0 "register_operand" "=d")
3622 (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))]
3623 ""
3624 "#")
3625
3626 (define_split
3627 [(set (match_operand:SI 0 "register_operand" "")
3628 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3629 "reload_completed"
3630 [(set (match_dup 0)
3631 (ashift:SI (match_dup 1) (const_int 24)))
3632 (set (match_dup 0)
3633 (ashiftrt:SI (match_dup 0) (const_int 24)))]
3634 "operands[1] = gen_lowpart (SImode, operands[1]);")
3635
3636 (define_insn "*extendqisi2_mem"
3637 [(set (match_operand:SI 0 "register_operand" "=d")
3638 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3639 ""
3640 "lb\t%0,%1"
3641 [(set_attr "type" "load")
3642 (set_attr "mode" "SI")])
3643
3644 (define_insn "extendqisi2_hw"
3645 [(set (match_operand:SI 0 "register_operand" "=r")
3646 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
3647 "ISA_HAS_SEB_SEH"
3648 "seb\t%0,%1"
3649 [(set_attr "type" "arith")
3650 (set_attr "mode" "SI")])
3651
3652 (define_expand "extendqidi2"
3653 [(set (match_operand:DI 0 "register_operand" "")
3654 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
3655 "TARGET_64BIT"
3656 "")
3657
3658 (define_insn "*extendqidi2"
3659 [(set (match_operand:DI 0 "register_operand" "=d")
3660 (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))]
3661 "TARGET_64BIT"
3662 "#")
3663
3664 (define_split
3665 [(set (match_operand:DI 0 "register_operand" "")
3666 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3667 "TARGET_64BIT && reload_completed"
3668 [(set (match_dup 0)
3669 (ashift:DI (match_dup 1) (const_int 56)))
3670 (set (match_dup 0)
3671 (ashiftrt:DI (match_dup 0) (const_int 56)))]
3672 "operands[1] = gen_lowpart (DImode, operands[1]);")
3673
3674 (define_insn "*extendqidi2_mem"
3675 [(set (match_operand:DI 0 "register_operand" "=d")
3676 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3677 "TARGET_64BIT"
3678 "lb\t%0,%1"
3679 [(set_attr "type" "load")
3680 (set_attr "mode" "DI")])
3681
3682 (define_insn "extendsfdf2"
3683 [(set (match_operand:DF 0 "register_operand" "=f")
3684 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
3685 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3686 "cvt.d.s\t%0,%1"
3687 [(set_attr "type" "fcvt")
3688 (set_attr "mode" "DF")])
3689 \f
3690 ;;
3691 ;; ....................
3692 ;;
3693 ;; CONVERSIONS
3694 ;;
3695 ;; ....................
3696
3697 (define_expand "fix_truncdfsi2"
3698 [(set (match_operand:SI 0 "register_operand" "=f")
3699 (fix:SI (match_operand:DF 1 "register_operand" "f")))]
3700 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3701 {
3702 if (!ISA_HAS_TRUNC_W)
3703 {
3704 emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1]));
3705 DONE;
3706 }
3707 })
3708
3709 (define_insn "fix_truncdfsi2_insn"
3710 [(set (match_operand:SI 0 "register_operand" "=f")
3711 (fix:SI (match_operand:DF 1 "register_operand" "f")))]
3712 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W"
3713 "trunc.w.d %0,%1"
3714 [(set_attr "type" "fcvt")
3715 (set_attr "mode" "DF")
3716 (set_attr "length" "4")])
3717
3718 (define_insn "fix_truncdfsi2_macro"
3719 [(set (match_operand:SI 0 "register_operand" "=f")
3720 (fix:SI (match_operand:DF 1 "register_operand" "f")))
3721 (clobber (match_scratch:DF 2 "=d"))]
3722 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W"
3723 {
3724 if (set_nomacro)
3725 return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro";
3726 else
3727 return "trunc.w.d %0,%1,%2";
3728 }
3729 [(set_attr "type" "fcvt")
3730 (set_attr "mode" "DF")
3731 (set_attr "length" "36")])
3732
3733 (define_expand "fix_truncsfsi2"
3734 [(set (match_operand:SI 0 "register_operand" "=f")
3735 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
3736 "TARGET_HARD_FLOAT"
3737 {
3738 if (!ISA_HAS_TRUNC_W)
3739 {
3740 emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1]));
3741 DONE;
3742 }
3743 })
3744
3745 (define_insn "fix_truncsfsi2_insn"
3746 [(set (match_operand:SI 0 "register_operand" "=f")
3747 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
3748 "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W"
3749 "trunc.w.s %0,%1"
3750 [(set_attr "type" "fcvt")
3751 (set_attr "mode" "DF")
3752 (set_attr "length" "4")])
3753
3754 (define_insn "fix_truncsfsi2_macro"
3755 [(set (match_operand:SI 0 "register_operand" "=f")
3756 (fix:SI (match_operand:SF 1 "register_operand" "f")))
3757 (clobber (match_scratch:SF 2 "=d"))]
3758 "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W"
3759 {
3760 if (set_nomacro)
3761 return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro";
3762 else
3763 return "trunc.w.s %0,%1,%2";
3764 }
3765 [(set_attr "type" "fcvt")
3766 (set_attr "mode" "DF")
3767 (set_attr "length" "36")])
3768
3769
3770 (define_insn "fix_truncdfdi2"
3771 [(set (match_operand:DI 0 "register_operand" "=f")
3772 (fix:DI (match_operand:DF 1 "register_operand" "f")))]
3773 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3774 "trunc.l.d %0,%1"
3775 [(set_attr "type" "fcvt")
3776 (set_attr "mode" "DF")
3777 (set_attr "length" "4")])
3778
3779
3780 (define_insn "fix_truncsfdi2"
3781 [(set (match_operand:DI 0 "register_operand" "=f")
3782 (fix:DI (match_operand:SF 1 "register_operand" "f")))]
3783 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3784 "trunc.l.s %0,%1"
3785 [(set_attr "type" "fcvt")
3786 (set_attr "mode" "SF")
3787 (set_attr "length" "4")])
3788
3789
3790 (define_insn "floatsidf2"
3791 [(set (match_operand:DF 0 "register_operand" "=f")
3792 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3793 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3794 "cvt.d.w\t%0,%1"
3795 [(set_attr "type" "fcvt")
3796 (set_attr "mode" "DF")
3797 (set_attr "length" "4")])
3798
3799
3800 (define_insn "floatdidf2"
3801 [(set (match_operand:DF 0 "register_operand" "=f")
3802 (float:DF (match_operand:DI 1 "register_operand" "f")))]
3803 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3804 "cvt.d.l\t%0,%1"
3805 [(set_attr "type" "fcvt")
3806 (set_attr "mode" "DF")
3807 (set_attr "length" "4")])
3808
3809
3810 (define_insn "floatsisf2"
3811 [(set (match_operand:SF 0 "register_operand" "=f")
3812 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3813 "TARGET_HARD_FLOAT"
3814 "cvt.s.w\t%0,%1"
3815 [(set_attr "type" "fcvt")
3816 (set_attr "mode" "SF")
3817 (set_attr "length" "4")])
3818
3819
3820 (define_insn "floatdisf2"
3821 [(set (match_operand:SF 0 "register_operand" "=f")
3822 (float:SF (match_operand:DI 1 "register_operand" "f")))]
3823 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT"
3824 "cvt.s.l\t%0,%1"
3825 [(set_attr "type" "fcvt")
3826 (set_attr "mode" "SF")
3827 (set_attr "length" "4")])
3828
3829
3830 (define_expand "fixuns_truncdfsi2"
3831 [(set (match_operand:SI 0 "register_operand" "")
3832 (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
3833 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
3834 {
3835 rtx reg1 = gen_reg_rtx (DFmode);
3836 rtx reg2 = gen_reg_rtx (DFmode);
3837 rtx reg3 = gen_reg_rtx (SImode);
3838 rtx label1 = gen_label_rtx ();
3839 rtx label2 = gen_label_rtx ();
3840 REAL_VALUE_TYPE offset;
3841
3842 real_2expN (&offset, 31);
3843
3844 if (reg1) /* turn off complaints about unreached code */
3845 {
3846 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3847 do_pending_stack_adjust ();
3848
3849 emit_insn (gen_cmpdf (operands[1], reg1));
3850 emit_jump_insn (gen_bge (label1));
3851
3852 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
3853 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3854 gen_rtx_LABEL_REF (VOIDmode, label2)));
3855 emit_barrier ();
3856
3857 emit_label (label1);
3858 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3859 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3860 (BITMASK_HIGH, SImode)));
3861
3862 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
3863 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3864
3865 emit_label (label2);
3866
3867 /* allow REG_NOTES to be set on last insn (labels don't have enough
3868 fields, and can't be used for REG_NOTES anyway). */
3869 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3870 DONE;
3871 }
3872 })
3873
3874
3875 (define_expand "fixuns_truncdfdi2"
3876 [(set (match_operand:DI 0 "register_operand" "")
3877 (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
3878 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3879 {
3880 rtx reg1 = gen_reg_rtx (DFmode);
3881 rtx reg2 = gen_reg_rtx (DFmode);
3882 rtx reg3 = gen_reg_rtx (DImode);
3883 rtx label1 = gen_label_rtx ();
3884 rtx label2 = gen_label_rtx ();
3885 REAL_VALUE_TYPE offset;
3886
3887 real_2expN (&offset, 63);
3888
3889 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
3890 do_pending_stack_adjust ();
3891
3892 emit_insn (gen_cmpdf (operands[1], reg1));
3893 emit_jump_insn (gen_bge (label1));
3894
3895 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
3896 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3897 gen_rtx_LABEL_REF (VOIDmode, label2)));
3898 emit_barrier ();
3899
3900 emit_label (label1);
3901 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1));
3902 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3903 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3904
3905 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2));
3906 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3907
3908 emit_label (label2);
3909
3910 /* allow REG_NOTES to be set on last insn (labels don't have enough
3911 fields, and can't be used for REG_NOTES anyway). */
3912 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3913 DONE;
3914 })
3915
3916
3917 (define_expand "fixuns_truncsfsi2"
3918 [(set (match_operand:SI 0 "register_operand" "")
3919 (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
3920 "TARGET_HARD_FLOAT"
3921 {
3922 rtx reg1 = gen_reg_rtx (SFmode);
3923 rtx reg2 = gen_reg_rtx (SFmode);
3924 rtx reg3 = gen_reg_rtx (SImode);
3925 rtx label1 = gen_label_rtx ();
3926 rtx label2 = gen_label_rtx ();
3927 REAL_VALUE_TYPE offset;
3928
3929 real_2expN (&offset, 31);
3930
3931 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3932 do_pending_stack_adjust ();
3933
3934 emit_insn (gen_cmpsf (operands[1], reg1));
3935 emit_jump_insn (gen_bge (label1));
3936
3937 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
3938 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3939 gen_rtx_LABEL_REF (VOIDmode, label2)));
3940 emit_barrier ();
3941
3942 emit_label (label1);
3943 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3944 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode
3945 (BITMASK_HIGH, SImode)));
3946
3947 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
3948 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
3949
3950 emit_label (label2);
3951
3952 /* allow REG_NOTES to be set on last insn (labels don't have enough
3953 fields, and can't be used for REG_NOTES anyway). */
3954 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3955 DONE;
3956 })
3957
3958
3959 (define_expand "fixuns_truncsfdi2"
3960 [(set (match_operand:DI 0 "register_operand" "")
3961 (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
3962 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
3963 {
3964 rtx reg1 = gen_reg_rtx (SFmode);
3965 rtx reg2 = gen_reg_rtx (SFmode);
3966 rtx reg3 = gen_reg_rtx (DImode);
3967 rtx label1 = gen_label_rtx ();
3968 rtx label2 = gen_label_rtx ();
3969 REAL_VALUE_TYPE offset;
3970
3971 real_2expN (&offset, 63);
3972
3973 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
3974 do_pending_stack_adjust ();
3975
3976 emit_insn (gen_cmpsf (operands[1], reg1));
3977 emit_jump_insn (gen_bge (label1));
3978
3979 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
3980 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
3981 gen_rtx_LABEL_REF (VOIDmode, label2)));
3982 emit_barrier ();
3983
3984 emit_label (label1);
3985 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1));
3986 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH));
3987 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32)));
3988
3989 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2));
3990 emit_insn (gen_iordi3 (operands[0], operands[0], reg3));
3991
3992 emit_label (label2);
3993
3994 /* allow REG_NOTES to be set on last insn (labels don't have enough
3995 fields, and can't be used for REG_NOTES anyway). */
3996 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
3997 DONE;
3998 })
3999 \f
4000 ;;
4001 ;; ....................
4002 ;;
4003 ;; DATA MOVEMENT
4004 ;;
4005 ;; ....................
4006
4007 ;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
4008
4009 (define_expand "extv"
4010 [(set (match_operand 0 "register_operand" "")
4011 (sign_extract (match_operand:QI 1 "memory_operand" "")
4012 (match_operand 2 "immediate_operand" "")
4013 (match_operand 3 "immediate_operand" "")))]
4014 "!TARGET_MIPS16"
4015 {
4016 if (mips_expand_unaligned_load (operands[0], operands[1],
4017 INTVAL (operands[2]),
4018 INTVAL (operands[3])))
4019 DONE;
4020 else
4021 FAIL;
4022 })
4023
4024 (define_expand "extzv"
4025 [(set (match_operand 0 "register_operand" "")
4026 (zero_extract (match_operand:QI 1 "memory_operand" "")
4027 (match_operand 2 "immediate_operand" "")
4028 (match_operand 3 "immediate_operand" "")))]
4029 "!TARGET_MIPS16"
4030 {
4031 if (mips_expand_unaligned_load (operands[0], operands[1],
4032 INTVAL (operands[2]),
4033 INTVAL (operands[3])))
4034 DONE;
4035 else
4036 FAIL;
4037 })
4038
4039 (define_expand "insv"
4040 [(set (zero_extract (match_operand:QI 0 "memory_operand" "")
4041 (match_operand 1 "immediate_operand" "")
4042 (match_operand 2 "immediate_operand" ""))
4043 (match_operand 3 "reg_or_0_operand" ""))]
4044 "!TARGET_MIPS16"
4045 {
4046 if (mips_expand_unaligned_store (operands[0], operands[3],
4047 INTVAL (operands[1]),
4048 INTVAL (operands[2])))
4049 DONE;
4050 else
4051 FAIL;
4052 })
4053
4054 ;; Unaligned word moves generated by the bit field patterns.
4055 ;;
4056 ;; As far as the rtl is concerned, both the left-part and right-part
4057 ;; instructions can access the whole field. However, the real operand
4058 ;; refers to just the first or the last byte (depending on endianness).
4059 ;; We therefore use two memory operands to each instruction, one to
4060 ;; describe the rtl effect and one to use in the assembly output.
4061
4062 (define_insn "mov_lwl"
4063 [(set (match_operand:SI 0 "register_operand" "=d")
4064 (unspec:SI [(match_operand:BLK 1 "general_operand" "m")
4065 (match_operand:QI 2 "general_operand" "m")]
4066 UNSPEC_LWL))]
4067 "!TARGET_MIPS16"
4068 "lwl\t%0,%2"
4069 [(set_attr "type" "load")
4070 (set_attr "mode" "SI")
4071 (set_attr "hazard" "none")])
4072
4073 (define_insn "mov_lwr"
4074 [(set (match_operand:SI 0 "register_operand" "=d")
4075 (unspec:SI [(match_operand:BLK 1 "general_operand" "m")
4076 (match_operand:QI 2 "general_operand" "m")
4077 (match_operand:SI 3 "register_operand" "0")]
4078 UNSPEC_LWR))]
4079 "!TARGET_MIPS16"
4080 "lwr\t%0,%2"
4081 [(set_attr "type" "load")
4082 (set_attr "mode" "SI")])
4083
4084
4085 (define_insn "mov_swl"
4086 [(set (match_operand:BLK 0 "memory_operand" "=m")
4087 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
4088 (match_operand:QI 2 "general_operand" "m")]
4089 UNSPEC_SWL))]
4090 "!TARGET_MIPS16"
4091 "swl\t%z1,%2"
4092 [(set_attr "type" "store")
4093 (set_attr "mode" "SI")])
4094
4095 (define_insn "mov_swr"
4096 [(set (match_operand:BLK 0 "memory_operand" "+m")
4097 (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")
4098 (match_operand:QI 2 "general_operand" "m")
4099 (match_dup 0)]
4100 UNSPEC_SWR))]
4101 "!TARGET_MIPS16"
4102 "swr\t%z1,%2"
4103 [(set_attr "type" "store")
4104 (set_attr "mode" "SI")])
4105
4106
4107 (define_insn "mov_ldl"
4108 [(set (match_operand:DI 0 "register_operand" "=d")
4109 (unspec:DI [(match_operand:BLK 1 "general_operand" "m")
4110 (match_operand:QI 2 "general_operand" "m")]
4111 UNSPEC_LDL))]
4112 "TARGET_64BIT && !TARGET_MIPS16"
4113 "ldl\t%0,%2"
4114 [(set_attr "type" "load")
4115 (set_attr "mode" "DI")])
4116
4117 (define_insn "mov_ldr"
4118 [(set (match_operand:DI 0 "register_operand" "=d")
4119 (unspec:DI [(match_operand:BLK 1 "general_operand" "m")
4120 (match_operand:QI 2 "general_operand" "m")
4121 (match_operand:DI 3 "register_operand" "0")]
4122 UNSPEC_LDR))]
4123 "TARGET_64BIT && !TARGET_MIPS16"
4124 "ldr\t%0,%2"
4125 [(set_attr "type" "load")
4126 (set_attr "mode" "DI")])
4127
4128
4129 (define_insn "mov_sdl"
4130 [(set (match_operand:BLK 0 "memory_operand" "=m")
4131 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
4132 (match_operand:QI 2 "general_operand" "m")]
4133 UNSPEC_SDL))]
4134 "TARGET_64BIT && !TARGET_MIPS16"
4135 "sdl\t%z1,%2"
4136 [(set_attr "type" "store")
4137 (set_attr "mode" "DI")])
4138
4139 (define_insn "mov_sdr"
4140 [(set (match_operand:BLK 0 "memory_operand" "+m")
4141 (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")
4142 (match_operand:QI 2 "general_operand" "m")
4143 (match_dup 0)]
4144 UNSPEC_SDR))]
4145 "TARGET_64BIT && !TARGET_MIPS16"
4146 "sdr\t%z1,%2"
4147 [(set_attr "type" "store")
4148 (set_attr "mode" "DI")])
4149
4150
4151 ;; Instructions for loading a relocation expression using "lui".
4152
4153 (define_insn "luisi"
4154 [(set (match_operand:SI 0 "register_operand" "=r")
4155 (unspec:SI [(match_operand 1 "const_arith_operand" "")] UNSPEC_HIGH))]
4156 ""
4157 "lui\t%0,%1"
4158 [(set_attr "type" "arith")])
4159
4160 (define_insn "luidi"
4161 [(set (match_operand:DI 0 "register_operand" "=r")
4162 (unspec:DI [(match_operand 1 "const_arith_operand" "")] UNSPEC_HIGH))]
4163 "TARGET_64BIT"
4164 "lui\t%0,%1"
4165 [(set_attr "type" "arith")])
4166
4167
4168 ;; Instructions for adding the low 16 bits of an address to a register.
4169 ;; Operand 2 is the address: print_operand works out which relocation
4170 ;; should be applied.
4171
4172 (define_insn "*lowsi"
4173 [(set (match_operand:SI 0 "register_operand" "=r")
4174 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
4175 (match_operand:SI 2 "immediate_operand" "")))]
4176 "!TARGET_MIPS16"
4177 "addiu\t%0,%1,%R2"
4178 [(set_attr "type" "arith")
4179 (set_attr "mode" "SI")])
4180
4181 (define_insn "*lowdi"
4182 [(set (match_operand:DI 0 "register_operand" "=r")
4183 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
4184 (match_operand:DI 2 "immediate_operand" "")))]
4185 "!TARGET_MIPS16 && TARGET_64BIT"
4186 "daddiu\t%0,%1,%R2"
4187 [(set_attr "type" "arith")
4188 (set_attr "mode" "DI")])
4189
4190 (define_insn "*lowsi_mips16"
4191 [(set (match_operand:SI 0 "register_operand" "=d")
4192 (lo_sum:SI (match_operand:SI 1 "register_operand" "0")
4193 (match_operand:SI 2 "immediate_operand" "")))]
4194 "TARGET_MIPS16"
4195 "addiu\t%0,%R2"
4196 [(set_attr "type" "arith")
4197 (set_attr "mode" "SI")
4198 (set_attr "length" "8")])
4199
4200 (define_insn "*lowdi_mips16"
4201 [(set (match_operand:DI 0 "register_operand" "=d")
4202 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
4203 (match_operand:DI 2 "immediate_operand" "")))]
4204 "TARGET_MIPS16 && TARGET_64BIT"
4205 "daddiu\t%0,%R2"
4206 [(set_attr "type" "arith")
4207 (set_attr "mode" "DI")
4208 (set_attr "length" "8")])
4209
4210 ;; 64-bit integer moves
4211
4212 ;; Unlike most other insns, the move insns can't be split with
4213 ;; different predicates, because register spilling and other parts of
4214 ;; the compiler, have memoized the insn number already.
4215
4216 (define_expand "movdi"
4217 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4218 (match_operand:DI 1 "" ""))]
4219 ""
4220 {
4221 if (mips_legitimize_move (DImode, operands[0], operands[1]))
4222 DONE;
4223
4224 /* If we are generating embedded PIC code, and we are referring to a
4225 symbol in the .text section, we must use an offset from the start
4226 of the function. */
4227 if (TARGET_EMBEDDED_PIC
4228 && (GET_CODE (operands[1]) == LABEL_REF
4229 || (GET_CODE (operands[1]) == SYMBOL_REF
4230 && ! SYMBOL_REF_FLAG (operands[1]))))
4231 {
4232 rtx temp;
4233
4234 temp = embedded_pic_offset (operands[1]);
4235 temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_reg (),
4236 force_reg (DImode, temp));
4237 emit_move_insn (operands[0], force_reg (DImode, temp));
4238 DONE;
4239 }
4240 })
4241
4242 ;; For mips16, we need a special case to handle storing $31 into
4243 ;; memory, since we don't have a constraint to match $31. This
4244 ;; instruction can be generated by save_restore_insns.
4245
4246 (define_insn ""
4247 [(set (match_operand:DI 0 "stack_operand" "=m")
4248 (reg:DI 31))]
4249 "TARGET_MIPS16 && TARGET_64BIT"
4250 "sd\t$31,%0"
4251 [(set_attr "type" "store")
4252 (set_attr "mode" "DI")])
4253
4254 (define_insn "movdi_internal"
4255 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*x,*B*C*D,*B*C*D,*d,*m")
4256 (match_operand:DI 1 "general_operand" "d,iF,m,d,J,*x,*d,*d,*m,*B*C*D,*B*C*D"))]
4257 "!TARGET_64BIT && !TARGET_MIPS16
4258 && (register_operand (operands[0], DImode)
4259 || register_operand (operands[1], DImode)
4260 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
4261 || operands[1] == CONST0_RTX (DImode))"
4262 { return mips_output_move (operands[0], operands[1]); }
4263 [(set_attr "type" "move,arith,load,store,hilo,hilo,hilo,xfer,load,xfer,store")
4264 (set_attr "mode" "DI")
4265 (set_attr "length" "8,16,*,*,8,8,8,8,*,8,*")])
4266
4267 (define_insn ""
4268 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4269 (match_operand:DI 1 "general_operand" "d,d,y,K,N,m,d,*x"))]
4270 "!TARGET_64BIT && TARGET_MIPS16
4271 && (register_operand (operands[0], DImode)
4272 || register_operand (operands[1], DImode))"
4273 { return mips_output_move (operands[0], operands[1]); }
4274 [(set_attr "type" "move,move,move,arith,arith,load,store,hilo")
4275 (set_attr "mode" "DI")
4276 (set_attr "length" "8,8,8,8,12,*,*,8")])
4277
4278 (define_insn "movdi_internal2"
4279 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*x,*d,*x,*B*C*D,*B*C*D,*d,*m")
4280 (match_operand:DI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*J,*x,*d,*d,*m,*B*C*D,*B*C*D"))]
4281 "TARGET_64BIT && !TARGET_MIPS16
4282 && (register_operand (operands[0], DImode)
4283 || register_operand (operands[1], DImode)
4284 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
4285 || operands[1] == CONST0_RTX (DImode))"
4286 { return mips_output_move (operands[0], operands[1]); }
4287 [(set_attr "type" "move,const,const,load,store,move,xfer,load,xfer,store,hilo,hilo,hilo,xfer,load,xfer,store")
4288 (set_attr "mode" "DI")
4289 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,8,*,8,*")])
4290
4291 (define_insn "*movdi_internal2_mips16"
4292 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m,*d")
4293 (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d,*x"))]
4294 "TARGET_64BIT && TARGET_MIPS16
4295 && (register_operand (operands[0], DImode)
4296 || register_operand (operands[1], DImode))"
4297 { return mips_output_move (operands[0], operands[1]); }
4298 [(set_attr "type" "move,move,move,arith,arith,const,load,store,hilo")
4299 (set_attr "mode" "DI")
4300 (set_attr_alternative "length"
4301 [(const_int 4)
4302 (const_int 4)
4303 (const_int 4)
4304 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
4305 (const_int 4)
4306 (const_int 8))
4307 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
4308 (const_int 8)
4309 (const_int 12))
4310 (const_string "*")
4311 (const_string "*")
4312 (const_string "*")
4313 (const_int 4)])])
4314
4315
4316 ;; On the mips16, we can split ld $r,N($r) into an add and a load,
4317 ;; when the original load is a 4 byte instruction but the add and the
4318 ;; load are 2 2 byte instructions.
4319
4320 (define_split
4321 [(set (match_operand:DI 0 "register_operand" "")
4322 (mem:DI (plus:DI (match_dup 0)
4323 (match_operand:DI 1 "const_int_operand" ""))))]
4324 "TARGET_64BIT && TARGET_MIPS16 && reload_completed
4325 && !TARGET_DEBUG_D_MODE
4326 && GET_CODE (operands[0]) == REG
4327 && M16_REG_P (REGNO (operands[0]))
4328 && GET_CODE (operands[1]) == CONST_INT
4329 && ((INTVAL (operands[1]) < 0
4330 && INTVAL (operands[1]) >= -0x10)
4331 || (INTVAL (operands[1]) >= 32 * 8
4332 && INTVAL (operands[1]) <= 31 * 8 + 0x8)
4333 || (INTVAL (operands[1]) >= 0
4334 && INTVAL (operands[1]) < 32 * 8
4335 && (INTVAL (operands[1]) & 7) != 0))"
4336 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
4337 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))]
4338 {
4339 HOST_WIDE_INT val = INTVAL (operands[1]);
4340
4341 if (val < 0)
4342 operands[2] = GEN_INT (0);
4343 else if (val >= 32 * 8)
4344 {
4345 int off = val & 7;
4346
4347 operands[1] = GEN_INT (0x8 + off);
4348 operands[2] = GEN_INT (val - off - 0x8);
4349 }
4350 else
4351 {
4352 int off = val & 7;
4353
4354 operands[1] = GEN_INT (off);
4355 operands[2] = GEN_INT (val - off);
4356 }
4357 })
4358
4359 ;; 32-bit Integer moves
4360
4361 ;; Unlike most other insns, the move insns can't be split with
4362 ;; different predicates, because register spilling and other parts of
4363 ;; the compiler, have memoized the insn number already.
4364
4365 (define_expand "movsi"
4366 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4367 (match_operand:SI 1 "" ""))]
4368 ""
4369 {
4370 if (mips_legitimize_move (SImode, operands[0], operands[1]))
4371 DONE;
4372
4373 /* If we are generating embedded PIC code, and we are referring to a
4374 symbol in the .text section, we must use an offset from the start
4375 of the function. */
4376 if (TARGET_EMBEDDED_PIC
4377 && (GET_CODE (operands[1]) == LABEL_REF
4378 || (GET_CODE (operands[1]) == SYMBOL_REF
4379 && ! SYMBOL_REF_FLAG (operands[1]))))
4380 {
4381 rtx temp;
4382
4383 temp = embedded_pic_offset (operands[1]);
4384 temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_reg (),
4385 force_reg (SImode, temp));
4386 emit_move_insn (operands[0], force_reg (SImode, temp));
4387 DONE;
4388 }
4389 })
4390
4391 ;; We can only store $ra directly into a small sp offset.
4392
4393 (define_insn ""
4394 [(set (match_operand:SI 0 "stack_operand" "=m")
4395 (reg:SI 31))]
4396 "TARGET_MIPS16"
4397 "sw\t$31,%0"
4398 [(set_attr "type" "store")
4399 (set_attr "mode" "SI")])
4400
4401 ;; The difference between these two is whether or not ints are allowed
4402 ;; in FP registers (off by default, use -mdebugh to enable).
4403
4404 (define_insn "movsi_internal"
4405 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*x,*d,*x,*B*C*D,*B*C*D,*d,*m")
4406 (match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,J,*x,*d,*d,*m,*B*C*D,*B*C*D"))]
4407 "!TARGET_MIPS16
4408 && (register_operand (operands[0], SImode)
4409 || register_operand (operands[1], SImode)
4410 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
4411 { return mips_output_move (operands[0], operands[1]); }
4412 [(set_attr "type" "move,const,const,load,store,move,xfer,load,xfer,store,xfer,xfer,hilo,hilo,hilo,xfer,load,xfer,store")
4413 (set_attr "mode" "SI")
4414 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,4,*,4,*")])
4415
4416 (define_insn ""
4417 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m,*d")
4418 (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d,*x"))]
4419 "TARGET_MIPS16
4420 && (register_operand (operands[0], SImode)
4421 || register_operand (operands[1], SImode))"
4422 { return mips_output_move (operands[0], operands[1]); }
4423 [(set_attr "type" "move,move,move,arith,arith,const,load,store,hilo")
4424 (set_attr "mode" "SI")
4425 (set_attr_alternative "length"
4426 [(const_int 4)
4427 (const_int 4)
4428 (const_int 4)
4429 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
4430 (const_int 4)
4431 (const_int 8))
4432 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
4433 (const_int 8)
4434 (const_int 12))
4435 (const_string "*")
4436 (const_string "*")
4437 (const_string "*")
4438 (const_int 4)])])
4439
4440 ;; On the mips16, we can split lw $r,N($r) into an add and a load,
4441 ;; when the original load is a 4 byte instruction but the add and the
4442 ;; load are 2 2 byte instructions.
4443
4444 (define_split
4445 [(set (match_operand:SI 0 "register_operand" "")
4446 (mem:SI (plus:SI (match_dup 0)
4447 (match_operand:SI 1 "const_int_operand" ""))))]
4448 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4449 && GET_CODE (operands[0]) == REG
4450 && M16_REG_P (REGNO (operands[0]))
4451 && GET_CODE (operands[1]) == CONST_INT
4452 && ((INTVAL (operands[1]) < 0
4453 && INTVAL (operands[1]) >= -0x80)
4454 || (INTVAL (operands[1]) >= 32 * 4
4455 && INTVAL (operands[1]) <= 31 * 4 + 0x7c)
4456 || (INTVAL (operands[1]) >= 0
4457 && INTVAL (operands[1]) < 32 * 4
4458 && (INTVAL (operands[1]) & 3) != 0))"
4459 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4460 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))]
4461 {
4462 HOST_WIDE_INT val = INTVAL (operands[1]);
4463
4464 if (val < 0)
4465 operands[2] = GEN_INT (0);
4466 else if (val >= 32 * 4)
4467 {
4468 int off = val & 3;
4469
4470 operands[1] = GEN_INT (0x7c + off);
4471 operands[2] = GEN_INT (val - off - 0x7c);
4472 }
4473 else
4474 {
4475 int off = val & 3;
4476
4477 operands[1] = GEN_INT (off);
4478 operands[2] = GEN_INT (val - off);
4479 }
4480 })
4481
4482 ;; On the mips16, we can split a load of certain constants into a load
4483 ;; and an add. This turns a 4 byte instruction into 2 2 byte
4484 ;; instructions.
4485
4486 (define_split
4487 [(set (match_operand:SI 0 "register_operand" "")
4488 (match_operand:SI 1 "const_int_operand" ""))]
4489 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4490 && GET_CODE (operands[0]) == REG
4491 && M16_REG_P (REGNO (operands[0]))
4492 && GET_CODE (operands[1]) == CONST_INT
4493 && INTVAL (operands[1]) >= 0x100
4494 && INTVAL (operands[1]) <= 0xff + 0x7f"
4495 [(set (match_dup 0) (match_dup 1))
4496 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
4497 {
4498 int val = INTVAL (operands[1]);
4499
4500 operands[1] = GEN_INT (0xff);
4501 operands[2] = GEN_INT (val - 0xff);
4502 })
4503
4504 ;; On the mips16, we can split a load of a negative constant into a
4505 ;; load and a neg. That's what mips_output_move will generate anyhow.
4506
4507 (define_split
4508 [(set (match_operand:SI 0 "register_operand" "")
4509 (match_operand:SI 1 "const_int_operand" ""))]
4510 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4511 && GET_CODE (operands[0]) == REG
4512 && M16_REG_P (REGNO (operands[0]))
4513 && GET_CODE (operands[1]) == CONST_INT
4514 && INTVAL (operands[1]) < 0
4515 && INTVAL (operands[1]) > - 0x8000"
4516 [(set (match_dup 0) (match_dup 1))
4517 (set (match_dup 0) (neg:SI (match_dup 0)))]
4518 { operands[1] = GEN_INT (- INTVAL (operands[1])); })
4519
4520 ;; This insn handles moving CCmode values. It's really just a
4521 ;; slightly simplified copy of movsi_internal2, with additional cases
4522 ;; to move a condition register to a general register and to move
4523 ;; between the general registers and the floating point registers.
4524
4525 (define_insn "movcc"
4526 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
4527 (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
4528 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4529 { return mips_output_move (operands[0], operands[1]); }
4530 [(set_attr "type" "move,move,load,store,xfer,xfer,move,load,store")
4531 (set_attr "mode" "SI")
4532 (set_attr "length" "8,4,*,*,4,4,4,*,*")])
4533
4534 ;; Reload condition code registers. reload_incc and reload_outcc
4535 ;; both handle moves from arbitrary operands into condition code
4536 ;; registers. reload_incc handles the more common case in which
4537 ;; a source operand is constrained to be in a condition-code
4538 ;; register, but has not been allocated to one.
4539 ;;
4540 ;; Sometimes, such as in movcc, we have a CCmode destination whose
4541 ;; constraints do not include 'z'. reload_outcc handles the case
4542 ;; when such an operand is allocated to a condition-code register.
4543 ;;
4544 ;; Note that reloads from a condition code register to some
4545 ;; other location can be done using ordinary moves. Moving
4546 ;; into a GPR takes a single movcc, moving elsewhere takes
4547 ;; two. We can leave these cases to the generic reload code.
4548 (define_expand "reload_incc"
4549 [(set (match_operand:CC 0 "fcc_register_operand" "=z")
4550 (match_operand:CC 1 "general_operand" ""))
4551 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
4552 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4553 {
4554 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4555 DONE;
4556 })
4557
4558 (define_expand "reload_outcc"
4559 [(set (match_operand:CC 0 "fcc_register_operand" "=z")
4560 (match_operand:CC 1 "register_operand" ""))
4561 (clobber (match_operand:TF 2 "register_operand" "=&f"))]
4562 "ISA_HAS_8CC && TARGET_HARD_FLOAT"
4563 {
4564 mips_emit_fcc_reload (operands[0], operands[1], operands[2]);
4565 DONE;
4566 })
4567
4568 ;; MIPS4 supports loading and storing a floating point register from
4569 ;; the sum of two general registers. We use two versions for each of
4570 ;; these four instructions: one where the two general registers are
4571 ;; SImode, and one where they are DImode. This is because general
4572 ;; registers will be in SImode when they hold 32 bit values, but,
4573 ;; since the 32 bit values are always sign extended, the [ls][wd]xc1
4574 ;; instructions will still work correctly.
4575
4576 ;; ??? Perhaps it would be better to support these instructions by
4577 ;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
4578 ;; these instructions can only be used to load and store floating
4579 ;; point registers, that would probably cause trouble in reload.
4580
4581 (define_insn ""
4582 [(set (match_operand:SF 0 "register_operand" "=f")
4583 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
4584 (match_operand:SI 2 "register_operand" "d"))))]
4585 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4586 "lwxc1\t%0,%1(%2)"
4587 [(set_attr "type" "load")
4588 (set_attr "mode" "SF")
4589 (set_attr "length" "4")])
4590
4591 (define_insn ""
4592 [(set (match_operand:SF 0 "register_operand" "=f")
4593 (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
4594 (match_operand:DI 2 "register_operand" "d"))))]
4595 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4596 "lwxc1\t%0,%1(%2)"
4597 [(set_attr "type" "load")
4598 (set_attr "mode" "SF")
4599 (set_attr "length" "4")])
4600
4601 (define_insn ""
4602 [(set (match_operand:DF 0 "register_operand" "=f")
4603 (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4604 (match_operand:SI 2 "register_operand" "d"))))]
4605 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4606 "ldxc1\t%0,%1(%2)"
4607 [(set_attr "type" "load")
4608 (set_attr "mode" "DF")
4609 (set_attr "length" "4")])
4610
4611 (define_insn ""
4612 [(set (match_operand:DF 0 "register_operand" "=f")
4613 (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4614 (match_operand:DI 2 "register_operand" "d"))))]
4615 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4616 "ldxc1\t%0,%1(%2)"
4617 [(set_attr "type" "load")
4618 (set_attr "mode" "DF")
4619 (set_attr "length" "4")])
4620
4621 (define_insn ""
4622 [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
4623 (match_operand:SI 2 "register_operand" "d")))
4624 (match_operand:SF 0 "register_operand" "f"))]
4625 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4626 "swxc1\t%0,%1(%2)"
4627 [(set_attr "type" "store")
4628 (set_attr "mode" "SF")
4629 (set_attr "length" "4")])
4630
4631 (define_insn ""
4632 [(set (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
4633 (match_operand:DI 2 "register_operand" "d")))
4634 (match_operand:SF 0 "register_operand" "f"))]
4635 "ISA_HAS_FP4 && TARGET_HARD_FLOAT"
4636 "swxc1\t%0,%1(%2)"
4637 [(set_attr "type" "store")
4638 (set_attr "mode" "SF")
4639 (set_attr "length" "4")])
4640
4641 (define_insn ""
4642 [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
4643 (match_operand:SI 2 "register_operand" "d")))
4644 (match_operand:DF 0 "register_operand" "f"))]
4645 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4646 "sdxc1\t%0,%1(%2)"
4647 [(set_attr "type" "store")
4648 (set_attr "mode" "DF")
4649 (set_attr "length" "4")])
4650
4651 (define_insn ""
4652 [(set (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
4653 (match_operand:DI 2 "register_operand" "d")))
4654 (match_operand:DF 0 "register_operand" "f"))]
4655 "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4656 "sdxc1\t%0,%1(%2)"
4657 [(set_attr "type" "store")
4658 (set_attr "mode" "DF")
4659 (set_attr "length" "4")])
4660
4661 ;; 16-bit Integer moves
4662
4663 ;; Unlike most other insns, the move insns can't be split with
4664 ;; different predicates, because register spilling and other parts of
4665 ;; the compiler, have memoized the insn number already.
4666 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4667
4668 (define_expand "movhi"
4669 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4670 (match_operand:HI 1 "general_operand" ""))]
4671 ""
4672 {
4673 if ((reload_in_progress | reload_completed) == 0
4674 && !register_operand (operands[0], HImode)
4675 && !register_operand (operands[1], HImode)
4676 && (TARGET_MIPS16
4677 || (GET_CODE (operands[1]) != CONST_INT
4678 || INTVAL (operands[1]) != 0)))
4679 {
4680 rtx temp = force_reg (HImode, operands[1]);
4681 emit_move_insn (operands[0], temp);
4682 DONE;
4683 }
4684 })
4685
4686 (define_insn "movhi_internal"
4687 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x,*d")
4688 (match_operand:HI 1 "general_operand" "d,IK,m,dJ,*f,*d,*f,*d,*x"))]
4689 "!TARGET_MIPS16
4690 && (register_operand (operands[0], HImode)
4691 || register_operand (operands[1], HImode)
4692 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
4693 "@
4694 move\t%0,%1
4695 li\t%0,%1
4696 lhu\t%0,%1
4697 sh\t%z1,%0
4698 mfc1\t%0,%1
4699 mtc1\t%1,%0
4700 mov.s\t%0,%1
4701 mt%0\t%1
4702 mf%1\t%0"
4703 [(set_attr "type" "move,arith,load,store,xfer,xfer,move,hilo,hilo")
4704 (set_attr "mode" "HI")
4705 (set_attr "length" "4,4,*,*,4,4,4,4,4")])
4706
4707 (define_insn ""
4708 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4709 (match_operand:HI 1 "general_operand" "d,d,y,K,N,m,d,*x"))]
4710 "TARGET_MIPS16
4711 && (register_operand (operands[0], HImode)
4712 || register_operand (operands[1], HImode))"
4713 "@
4714 move\t%0,%1
4715 move\t%0,%1
4716 move\t%0,%1
4717 li\t%0,%1
4718 li\t%0,%n1\;neg\t%0
4719 lhu\t%0,%1
4720 sh\t%1,%0
4721 mf%1\t%0"
4722 [(set_attr "type" "move,move,move,arith,arith,load,store,hilo")
4723 (set_attr "mode" "HI")
4724 (set_attr_alternative "length"
4725 [(const_int 4)
4726 (const_int 4)
4727 (const_int 4)
4728 (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
4729 (const_int 4)
4730 (const_int 8))
4731 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
4732 (const_int 8)
4733 (const_int 12))
4734 (const_string "*")
4735 (const_string "*")
4736 (const_int 4)])])
4737
4738
4739 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
4740 ;; when the original load is a 4 byte instruction but the add and the
4741 ;; load are 2 2 byte instructions.
4742
4743 (define_split
4744 [(set (match_operand:HI 0 "register_operand" "")
4745 (mem:HI (plus:SI (match_dup 0)
4746 (match_operand:SI 1 "const_int_operand" ""))))]
4747 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4748 && GET_CODE (operands[0]) == REG
4749 && M16_REG_P (REGNO (operands[0]))
4750 && GET_CODE (operands[1]) == CONST_INT
4751 && ((INTVAL (operands[1]) < 0
4752 && INTVAL (operands[1]) >= -0x80)
4753 || (INTVAL (operands[1]) >= 32 * 2
4754 && INTVAL (operands[1]) <= 31 * 2 + 0x7e)
4755 || (INTVAL (operands[1]) >= 0
4756 && INTVAL (operands[1]) < 32 * 2
4757 && (INTVAL (operands[1]) & 1) != 0))"
4758 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4759 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))]
4760 {
4761 HOST_WIDE_INT val = INTVAL (operands[1]);
4762
4763 if (val < 0)
4764 operands[2] = GEN_INT (0);
4765 else if (val >= 32 * 2)
4766 {
4767 int off = val & 1;
4768
4769 operands[1] = GEN_INT (0x7e + off);
4770 operands[2] = GEN_INT (val - off - 0x7e);
4771 }
4772 else
4773 {
4774 int off = val & 1;
4775
4776 operands[1] = GEN_INT (off);
4777 operands[2] = GEN_INT (val - off);
4778 }
4779 })
4780
4781 ;; 8-bit Integer moves
4782
4783 ;; Unlike most other insns, the move insns can't be split with
4784 ;; different predicates, because register spilling and other parts of
4785 ;; the compiler, have memoized the insn number already.
4786 ;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
4787
4788 (define_expand "movqi"
4789 [(set (match_operand:QI 0 "nonimmediate_operand" "")
4790 (match_operand:QI 1 "general_operand" ""))]
4791 ""
4792 {
4793 if ((reload_in_progress | reload_completed) == 0
4794 && !register_operand (operands[0], QImode)
4795 && !register_operand (operands[1], QImode)
4796 && (TARGET_MIPS16
4797 || (GET_CODE (operands[1]) != CONST_INT
4798 || INTVAL (operands[1]) != 0)))
4799 {
4800 rtx temp = force_reg (QImode, operands[1]);
4801 emit_move_insn (operands[0], temp);
4802 DONE;
4803 }
4804 })
4805
4806 (define_insn "movqi_internal"
4807 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x,*d")
4808 (match_operand:QI 1 "general_operand" "d,IK,m,dJ,*f,*d,*f,*d,*x"))]
4809 "!TARGET_MIPS16
4810 && (register_operand (operands[0], QImode)
4811 || register_operand (operands[1], QImode)
4812 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
4813 "@
4814 move\t%0,%1
4815 li\t%0,%1
4816 lbu\t%0,%1
4817 sb\t%z1,%0
4818 mfc1\t%0,%1
4819 mtc1\t%1,%0
4820 mov.s\t%0,%1
4821 mt%0\t%1
4822 mf%1\t%0"
4823 [(set_attr "type" "move,arith,load,store,xfer,xfer,move,hilo,hilo")
4824 (set_attr "mode" "QI")
4825 (set_attr "length" "4,4,*,*,4,4,4,4,4")])
4826
4827 (define_insn ""
4828 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
4829 (match_operand:QI 1 "general_operand" "d,d,y,K,N,m,d,*x"))]
4830 "TARGET_MIPS16
4831 && (register_operand (operands[0], QImode)
4832 || register_operand (operands[1], QImode))"
4833 "@
4834 move\t%0,%1
4835 move\t%0,%1
4836 move\t%0,%1
4837 li\t%0,%1
4838 li\t%0,%n1\;neg\t%0
4839 lbu\t%0,%1
4840 sb\t%1,%0
4841 mf%1\t%0"
4842 [(set_attr "type" "move,move,move,arith,arith,load,store,hilo")
4843 (set_attr "mode" "QI")
4844 (set_attr "length" "4,4,4,4,8,*,*,4")])
4845
4846 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
4847 ;; when the original load is a 4 byte instruction but the add and the
4848 ;; load are 2 2 byte instructions.
4849
4850 (define_split
4851 [(set (match_operand:QI 0 "register_operand" "")
4852 (mem:QI (plus:SI (match_dup 0)
4853 (match_operand:SI 1 "const_int_operand" ""))))]
4854 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
4855 && GET_CODE (operands[0]) == REG
4856 && M16_REG_P (REGNO (operands[0]))
4857 && GET_CODE (operands[1]) == CONST_INT
4858 && ((INTVAL (operands[1]) < 0
4859 && INTVAL (operands[1]) >= -0x80)
4860 || (INTVAL (operands[1]) >= 32
4861 && INTVAL (operands[1]) <= 31 + 0x7f))"
4862 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
4863 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))]
4864 {
4865 HOST_WIDE_INT val = INTVAL (operands[1]);
4866
4867 if (val < 0)
4868 operands[2] = GEN_INT (0);
4869 else
4870 {
4871 operands[1] = GEN_INT (0x7f);
4872 operands[2] = GEN_INT (val - 0x7f);
4873 }
4874 })
4875
4876 ;; 32-bit floating point moves
4877
4878 (define_expand "movsf"
4879 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4880 (match_operand:SF 1 "general_operand" ""))]
4881 ""
4882 {
4883 if ((reload_in_progress | reload_completed) == 0
4884 && !register_operand (operands[0], SFmode)
4885 && !nonmemory_operand (operands[1], SFmode))
4886 operands[1] = force_reg (SFmode, operands[1]);
4887 })
4888
4889 (define_insn "movsf_internal1"
4890 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4891 (match_operand:SF 1 "general_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))]
4892 "TARGET_HARD_FLOAT
4893 && (register_operand (operands[0], SFmode)
4894 || nonmemory_operand (operands[1], SFmode))"
4895 { return mips_output_move (operands[0], operands[1]); }
4896 [(set_attr "type" "move,xfer,load,store,xfer,xfer,move,load,store")
4897 (set_attr "mode" "SF")
4898 (set_attr "length" "4,4,*,*,4,4,4,*,*")])
4899
4900 (define_insn "movsf_internal2"
4901 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
4902 (match_operand:SF 1 "general_operand" " Gd,m,d"))]
4903 "TARGET_SOFT_FLOAT && !TARGET_MIPS16
4904 && (register_operand (operands[0], SFmode)
4905 || nonmemory_operand (operands[1], SFmode))"
4906 { return mips_output_move (operands[0], operands[1]); }
4907 [(set_attr "type" "move,load,store")
4908 (set_attr "mode" "SF")
4909 (set_attr "length" "4,*,*")])
4910
4911 (define_insn ""
4912 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
4913 (match_operand:SF 1 "nonimmediate_operand" "d,d,y,m,d"))]
4914 "TARGET_MIPS16
4915 && (register_operand (operands[0], SFmode)
4916 || register_operand (operands[1], SFmode))"
4917 { return mips_output_move (operands[0], operands[1]); }
4918 [(set_attr "type" "move,move,move,load,store")
4919 (set_attr "mode" "SF")
4920 (set_attr "length" "4,4,4,*,*")])
4921
4922
4923 ;; 64-bit floating point moves
4924
4925 (define_expand "movdf"
4926 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4927 (match_operand:DF 1 "general_operand" ""))]
4928 ""
4929 {
4930 if ((reload_in_progress | reload_completed) == 0
4931 && !register_operand (operands[0], DFmode)
4932 && !nonmemory_operand (operands[1], DFmode))
4933 operands[1] = force_reg (DFmode, operands[1]);
4934 })
4935
4936 (define_insn "movdf_internal1a"
4937 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4938 (match_operand:DF 1 "general_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4939 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
4940 && (register_operand (operands[0], DFmode)
4941 || nonmemory_operand (operands[1], DFmode))"
4942 { return mips_output_move (operands[0], operands[1]); }
4943 [(set_attr "type" "move,xfer,load,store,xfer,xfer,move,load,store")
4944 (set_attr "mode" "DF")
4945 (set_attr "length" "4,4,*,*,4,4,4,*,*")])
4946
4947 (define_insn "movdf_internal1b"
4948 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
4949 (match_operand:DF 1 "general_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
4950 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
4951 && (register_operand (operands[0], DFmode)
4952 || nonmemory_operand (operands[1], DFmode))"
4953 { return mips_output_move (operands[0], operands[1]); }
4954 [(set_attr "type" "move,xfer,load,store,xfer,xfer,move,load,store")
4955 (set_attr "mode" "DF")
4956 (set_attr "length" "4,8,*,*,8,8,8,*,*")])
4957
4958 (define_insn "movdf_internal2"
4959 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
4960 (match_operand:DF 1 "general_operand" "dG,m,dG,f,d,f"))]
4961 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
4962 && (register_operand (operands[0], DFmode)
4963 || nonmemory_operand (operands[1], DFmode))"
4964 { return mips_output_move (operands[0], operands[1]); }
4965 [(set_attr "type" "move,load,store,xfer,xfer,move")
4966 (set_attr "mode" "DF")
4967 (set_attr "length" "8,*,*,4,4,4")])
4968
4969 (define_insn ""
4970 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
4971 (match_operand:DF 1 "nonimmediate_operand" "d,d,y,m,d"))]
4972 "TARGET_MIPS16
4973 && (register_operand (operands[0], DFmode)
4974 || register_operand (operands[1], DFmode))"
4975 { return mips_output_move (operands[0], operands[1]); }
4976 [(set_attr "type" "move,move,move,load,store")
4977 (set_attr "mode" "DF")
4978 (set_attr "length" "8,8,8,*,*")])
4979
4980 (define_split
4981 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4982 (match_operand:DI 1 "general_operand" ""))]
4983 "reload_completed && !TARGET_64BIT
4984 && mips_split_64bit_move_p (operands[0], operands[1])"
4985 [(const_int 0)]
4986 {
4987 mips_split_64bit_move (operands[0], operands[1]);
4988 DONE;
4989 })
4990
4991 (define_split
4992 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4993 (match_operand:DF 1 "general_operand" ""))]
4994 "reload_completed && !TARGET_64BIT
4995 && mips_split_64bit_move_p (operands[0], operands[1])"
4996 [(const_int 0)]
4997 {
4998 mips_split_64bit_move (operands[0], operands[1]);
4999 DONE;
5000 })
5001
5002 ;; Patterns for loading or storing part of a paired floating point
5003 ;; register. We need them because odd-numbered floating-point registers
5004 ;; are not fully independent: see mips_split_64bit_move.
5005
5006 ;; Load the low word of operand 0 with operand 1.
5007 (define_insn "load_df_low"
5008 [(set (match_operand:DF 0 "register_operand" "=f,f")
5009 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
5010 UNSPEC_LOAD_DF_LOW))]
5011 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
5012 {
5013 operands[0] = mips_subword (operands[0], 0);
5014 return mips_output_move (operands[0], operands[1]);
5015 }
5016 [(set_attr "type" "xfer,load")
5017 (set_attr "mode" "SF")
5018 (set_attr "length" "4")])
5019
5020 ;; Load the high word of operand 0 from operand 1, preserving the value
5021 ;; in the low word.
5022 (define_insn "load_df_high"
5023 [(set (match_operand:DF 0 "register_operand" "=f,f")
5024 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
5025 (match_operand:DF 2 "register_operand" "0,0")]
5026 UNSPEC_LOAD_DF_HIGH))]
5027 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
5028 {
5029 operands[0] = mips_subword (operands[0], 1);
5030 return mips_output_move (operands[0], operands[1]);
5031 }
5032 [(set_attr "type" "xfer,load")
5033 (set_attr "mode" "SF")
5034 (set_attr "length" "4")])
5035
5036 ;; Store the high word of operand 1 in operand 0. The corresponding
5037 ;; low-word move is done in the normal way.
5038 (define_insn "store_df_high"
5039 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
5040 (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
5041 UNSPEC_STORE_DF_HIGH))]
5042 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
5043 {
5044 operands[1] = mips_subword (operands[1], 1);
5045 return mips_output_move (operands[0], operands[1]);
5046 }
5047 [(set_attr "type" "xfer,store")
5048 (set_attr "mode" "SF")
5049 (set_attr "length" "4")])
5050
5051 ;; The use of gp is hidden when not using explicit relocations.
5052 ;; This blockage instruction prevents the gp load from being
5053 ;; scheduled after an implicit use of gp. It also prevents
5054 ;; the load from being deleted as dead.
5055 (define_insn "loadgp_blockage"
5056 [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)]
5057 ""
5058 ""
5059 [(set_attr "type" "unknown")
5060 (set_attr "mode" "none")
5061 (set_attr "length" "0")])
5062
5063 ;; Emit a .cprestore directive, which expands to a single store instruction.
5064 ;; Note that we continue to use .cprestore for explicit reloc code so that
5065 ;; jals inside inlines asms will work correctly.
5066 (define_insn "cprestore"
5067 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
5068 UNSPEC_CPRESTORE)]
5069 ""
5070 ".cprestore\t%0"
5071 [(set_attr "type" "store")
5072 (set_attr "length" "4")])
5073 \f
5074 ;; Block moves, see mips.c for more details.
5075 ;; Argument 0 is the destination
5076 ;; Argument 1 is the source
5077 ;; Argument 2 is the length
5078 ;; Argument 3 is the alignment
5079
5080 (define_expand "movstrsi"
5081 [(parallel [(set (match_operand:BLK 0 "general_operand" "")
5082 (match_operand:BLK 1 "general_operand" ""))
5083 (use (match_operand:SI 2 "" ""))
5084 (use (match_operand:SI 3 "const_int_operand" ""))])]
5085 "!TARGET_MIPS16 && !TARGET_MEMCPY"
5086 {
5087 if (mips_expand_block_move (operands[0], operands[1], operands[2]))
5088 DONE;
5089 else
5090 FAIL;
5091 })
5092 \f
5093 ;;
5094 ;; ....................
5095 ;;
5096 ;; SHIFTS
5097 ;;
5098 ;; ....................
5099
5100 ;; Many of these instructions use trivial define_expands, because we
5101 ;; want to use a different set of constraints when TARGET_MIPS16.
5102
5103 (define_expand "ashlsi3"
5104 [(set (match_operand:SI 0 "register_operand" "=d")
5105 (ashift:SI (match_operand:SI 1 "register_operand" "d")
5106 (match_operand:SI 2 "arith_operand" "dI")))]
5107 ""
5108 {
5109 /* On the mips16, a shift of more than 8 is a four byte instruction,
5110 so, for a shift between 8 and 16, it is just as fast to do two
5111 shifts of 8 or less. If there is a lot of shifting going on, we
5112 may win in CSE. Otherwise combine will put the shifts back
5113 together again. This can be called by function_arg, so we must
5114 be careful not to allocate a new register if we've reached the
5115 reload pass. */
5116 if (TARGET_MIPS16
5117 && optimize
5118 && GET_CODE (operands[2]) == CONST_INT
5119 && INTVAL (operands[2]) > 8
5120 && INTVAL (operands[2]) <= 16
5121 && ! reload_in_progress
5122 && ! reload_completed)
5123 {
5124 rtx temp = gen_reg_rtx (SImode);
5125
5126 emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
5127 emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
5128 GEN_INT (INTVAL (operands[2]) - 8)));
5129 DONE;
5130 }
5131 })
5132
5133 (define_insn "ashlsi3_internal1"
5134 [(set (match_operand:SI 0 "register_operand" "=d")
5135 (ashift:SI (match_operand:SI 1 "register_operand" "d")
5136 (match_operand:SI 2 "arith_operand" "dI")))]
5137 "!TARGET_MIPS16"
5138 {
5139 if (GET_CODE (operands[2]) == CONST_INT)
5140 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5141
5142 return "sll\t%0,%1,%2";
5143 }
5144 [(set_attr "type" "arith")
5145 (set_attr "mode" "SI")])
5146
5147 (define_insn "ashlsi3_internal1_extend"
5148 [(set (match_operand:DI 0 "register_operand" "=d")
5149 (sign_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "d")
5150 (match_operand:SI 2 "arith_operand" "dI"))))]
5151 "TARGET_64BIT && !TARGET_MIPS16"
5152 {
5153 if (GET_CODE (operands[2]) == CONST_INT)
5154 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5155
5156 return "sll\t%0,%1,%2";
5157 }
5158 [(set_attr "type" "arith")
5159 (set_attr "mode" "DI")])
5160
5161
5162 (define_insn "ashlsi3_internal2"
5163 [(set (match_operand:SI 0 "register_operand" "=d,d")
5164 (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
5165 (match_operand:SI 2 "arith_operand" "d,I")))]
5166 "TARGET_MIPS16"
5167 {
5168 if (which_alternative == 0)
5169 return "sll\t%0,%2";
5170
5171 if (GET_CODE (operands[2]) == CONST_INT)
5172 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5173
5174 return "sll\t%0,%1,%2";
5175 }
5176 [(set_attr "type" "arith")
5177 (set_attr "mode" "SI")
5178 (set_attr_alternative "length"
5179 [(const_int 4)
5180 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
5181 (const_int 4)
5182 (const_int 8))])])
5183
5184 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5185
5186 (define_split
5187 [(set (match_operand:SI 0 "register_operand" "")
5188 (ashift:SI (match_operand:SI 1 "register_operand" "")
5189 (match_operand:SI 2 "const_int_operand" "")))]
5190 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5191 && GET_CODE (operands[2]) == CONST_INT
5192 && INTVAL (operands[2]) > 8
5193 && INTVAL (operands[2]) <= 16"
5194 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
5195 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
5196 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5197
5198 (define_expand "ashldi3"
5199 [(parallel [(set (match_operand:DI 0 "register_operand" "")
5200 (ashift:DI (match_operand:DI 1 "register_operand" "")
5201 (match_operand:SI 2 "arith_operand" "")))
5202 (clobber (match_dup 3))])]
5203 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
5204 {
5205 if (TARGET_64BIT)
5206 {
5207 /* On the mips16, a shift of more than 8 is a four byte
5208 instruction, so, for a shift between 8 and 16, it is just as
5209 fast to do two shifts of 8 or less. If there is a lot of
5210 shifting going on, we may win in CSE. Otherwise combine will
5211 put the shifts back together again. This can be called by
5212 function_arg, so we must be careful not to allocate a new
5213 register if we've reached the reload pass. */
5214 if (TARGET_MIPS16
5215 && optimize
5216 && GET_CODE (operands[2]) == CONST_INT
5217 && INTVAL (operands[2]) > 8
5218 && INTVAL (operands[2]) <= 16
5219 && ! reload_in_progress
5220 && ! reload_completed)
5221 {
5222 rtx temp = gen_reg_rtx (DImode);
5223
5224 emit_insn (gen_ashldi3_internal4 (temp, operands[1], GEN_INT (8)));
5225 emit_insn (gen_ashldi3_internal4 (operands[0], temp,
5226 GEN_INT (INTVAL (operands[2]) - 8)));
5227 DONE;
5228 }
5229
5230 emit_insn (gen_ashldi3_internal4 (operands[0], operands[1],
5231 operands[2]));
5232 DONE;
5233 }
5234
5235 operands[3] = gen_reg_rtx (SImode);
5236 })
5237
5238
5239 (define_insn "ashldi3_internal"
5240 [(set (match_operand:DI 0 "register_operand" "=&d")
5241 (ashift:DI (match_operand:DI 1 "register_operand" "d")
5242 (match_operand:SI 2 "register_operand" "d")))
5243 (clobber (match_operand:SI 3 "register_operand" "=d"))]
5244 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
5245 "sll\t%3,%2,26\;\
5246 bgez\t%3,1f%#\;\
5247 sll\t%M0,%L1,%2\;\
5248 %(b\t3f\;\
5249 move\t%L0,%.%)\
5250 \n\n\
5251 %~1:\;\
5252 %(beq\t%3,%.,2f\;\
5253 sll\t%M0,%M1,%2%)\
5254 \n\;\
5255 subu\t%3,%.,%2\;\
5256 srl\t%3,%L1,%3\;\
5257 or\t%M0,%M0,%3\n\
5258 %~2:\;\
5259 sll\t%L0,%L1,%2\n\
5260 %~3:"
5261 [(set_attr "type" "darith")
5262 (set_attr "mode" "SI")
5263 (set_attr "length" "48")])
5264
5265
5266 (define_insn "ashldi3_internal2"
5267 [(set (match_operand:DI 0 "register_operand" "=d")
5268 (ashift:DI (match_operand:DI 1 "register_operand" "d")
5269 (match_operand:SI 2 "small_int" "IJK")))
5270 (clobber (match_operand:SI 3 "register_operand" "=d"))]
5271 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5272 && (INTVAL (operands[2]) & 32) != 0"
5273 {
5274 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5275 return "sll\t%M0,%L1,%2\;move\t%L0,%.";
5276 }
5277 [(set_attr "type" "darith")
5278 (set_attr "mode" "DI")
5279 (set_attr "length" "8")])
5280
5281
5282 (define_split
5283 [(set (match_operand:DI 0 "register_operand" "")
5284 (ashift:DI (match_operand:DI 1 "register_operand" "")
5285 (match_operand:SI 2 "small_int" "")))
5286 (clobber (match_operand:SI 3 "register_operand" ""))]
5287 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
5288 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5289 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
5290 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
5291 && (INTVAL (operands[2]) & 32) != 0"
5292
5293 [(set (subreg:SI (match_dup 0) 4) (ashift:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
5294 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
5295
5296 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
5297
5298
5299 (define_split
5300 [(set (match_operand:DI 0 "register_operand" "")
5301 (ashift:DI (match_operand:DI 1 "register_operand" "")
5302 (match_operand:SI 2 "small_int" "")))
5303 (clobber (match_operand:SI 3 "register_operand" ""))]
5304 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
5305 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5306 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
5307 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
5308 && (INTVAL (operands[2]) & 32) != 0"
5309
5310 [(set (subreg:SI (match_dup 0) 0) (ashift:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
5311 (set (subreg:SI (match_dup 0) 4) (const_int 0))]
5312
5313 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
5314
5315
5316 (define_insn "ashldi3_internal3"
5317 [(set (match_operand:DI 0 "register_operand" "=d")
5318 (ashift:DI (match_operand:DI 1 "register_operand" "d")
5319 (match_operand:SI 2 "small_int" "IJK")))
5320 (clobber (match_operand:SI 3 "register_operand" "=d"))]
5321 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5322 && (INTVAL (operands[2]) & 63) < 32
5323 && (INTVAL (operands[2]) & 63) != 0"
5324 {
5325 int amount = INTVAL (operands[2]);
5326
5327 operands[2] = GEN_INT (amount & 31);
5328 operands[4] = GEN_INT ((-amount) & 31);
5329
5330 return "sll\t%M0,%M1,%2\;srl\t%3,%L1,%4\;or\t%M0,%M0,%3\;sll\t%L0,%L1,%2";
5331 }
5332 [(set_attr "type" "darith")
5333 (set_attr "mode" "DI")
5334 (set_attr "length" "16")])
5335
5336
5337 (define_split
5338 [(set (match_operand:DI 0 "register_operand" "")
5339 (ashift:DI (match_operand:DI 1 "register_operand" "")
5340 (match_operand:SI 2 "small_int" "")))
5341 (clobber (match_operand:SI 3 "register_operand" ""))]
5342 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
5343 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5344 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
5345 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
5346 && (INTVAL (operands[2]) & 63) < 32
5347 && (INTVAL (operands[2]) & 63) != 0"
5348
5349 [(set (subreg:SI (match_dup 0) 4)
5350 (ashift:SI (subreg:SI (match_dup 1) 4)
5351 (match_dup 2)))
5352
5353 (set (match_dup 3)
5354 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
5355 (match_dup 4)))
5356
5357 (set (subreg:SI (match_dup 0) 4)
5358 (ior:SI (subreg:SI (match_dup 0) 4)
5359 (match_dup 3)))
5360
5361 (set (subreg:SI (match_dup 0) 0)
5362 (ashift:SI (subreg:SI (match_dup 1) 0)
5363 (match_dup 2)))]
5364 {
5365 int amount = INTVAL (operands[2]);
5366 operands[2] = GEN_INT (amount & 31);
5367 operands[4] = GEN_INT ((-amount) & 31);
5368 })
5369
5370
5371 (define_split
5372 [(set (match_operand:DI 0 "register_operand" "")
5373 (ashift:DI (match_operand:DI 1 "register_operand" "")
5374 (match_operand:SI 2 "small_int" "")))
5375 (clobber (match_operand:SI 3 "register_operand" ""))]
5376 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
5377 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5378 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
5379 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
5380 && (INTVAL (operands[2]) & 63) < 32
5381 && (INTVAL (operands[2]) & 63) != 0"
5382
5383 [(set (subreg:SI (match_dup 0) 0)
5384 (ashift:SI (subreg:SI (match_dup 1) 0)
5385 (match_dup 2)))
5386
5387 (set (match_dup 3)
5388 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
5389 (match_dup 4)))
5390
5391 (set (subreg:SI (match_dup 0) 0)
5392 (ior:SI (subreg:SI (match_dup 0) 0)
5393 (match_dup 3)))
5394
5395 (set (subreg:SI (match_dup 0) 4)
5396 (ashift:SI (subreg:SI (match_dup 1) 4)
5397 (match_dup 2)))]
5398 {
5399 int amount = INTVAL (operands[2]);
5400 operands[2] = GEN_INT (amount & 31);
5401 operands[4] = GEN_INT ((-amount) & 31);
5402 })
5403
5404
5405 (define_insn "ashldi3_internal4"
5406 [(set (match_operand:DI 0 "register_operand" "=d")
5407 (ashift:DI (match_operand:DI 1 "register_operand" "d")
5408 (match_operand:SI 2 "arith_operand" "dI")))]
5409 "TARGET_64BIT && !TARGET_MIPS16"
5410 {
5411 if (GET_CODE (operands[2]) == CONST_INT)
5412 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5413
5414 return "dsll\t%0,%1,%2";
5415 }
5416 [(set_attr "type" "arith")
5417 (set_attr "mode" "DI")])
5418
5419 (define_insn ""
5420 [(set (match_operand:DI 0 "register_operand" "=d,d")
5421 (ashift:DI (match_operand:DI 1 "register_operand" "0,d")
5422 (match_operand:SI 2 "arith_operand" "d,I")))]
5423 "TARGET_64BIT && TARGET_MIPS16"
5424 {
5425 if (which_alternative == 0)
5426 return "dsll\t%0,%2";
5427
5428 if (GET_CODE (operands[2]) == CONST_INT)
5429 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5430
5431 return "dsll\t%0,%1,%2";
5432 }
5433 [(set_attr "type" "arith")
5434 (set_attr "mode" "DI")
5435 (set_attr_alternative "length"
5436 [(const_int 4)
5437 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
5438 (const_int 4)
5439 (const_int 8))])])
5440
5441
5442 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5443
5444 (define_split
5445 [(set (match_operand:DI 0 "register_operand" "")
5446 (ashift:DI (match_operand:DI 1 "register_operand" "")
5447 (match_operand:SI 2 "const_int_operand" "")))]
5448 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5449 && reload_completed
5450 && GET_CODE (operands[2]) == CONST_INT
5451 && INTVAL (operands[2]) > 8
5452 && INTVAL (operands[2]) <= 16"
5453 [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
5454 (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
5455 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5456
5457 (define_expand "ashrsi3"
5458 [(set (match_operand:SI 0 "register_operand" "=d")
5459 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
5460 (match_operand:SI 2 "arith_operand" "dI")))]
5461 ""
5462 {
5463 /* On the mips16, a shift of more than 8 is a four byte instruction,
5464 so, for a shift between 8 and 16, it is just as fast to do two
5465 shifts of 8 or less. If there is a lot of shifting going on, we
5466 may win in CSE. Otherwise combine will put the shifts back
5467 together again. */
5468 if (TARGET_MIPS16
5469 && optimize
5470 && GET_CODE (operands[2]) == CONST_INT
5471 && INTVAL (operands[2]) > 8
5472 && INTVAL (operands[2]) <= 16)
5473 {
5474 rtx temp = gen_reg_rtx (SImode);
5475
5476 emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
5477 emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
5478 GEN_INT (INTVAL (operands[2]) - 8)));
5479 DONE;
5480 }
5481 })
5482
5483 (define_insn "ashrsi3_internal1"
5484 [(set (match_operand:SI 0 "register_operand" "=d")
5485 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
5486 (match_operand:SI 2 "arith_operand" "dI")))]
5487 "!TARGET_MIPS16"
5488 {
5489 if (GET_CODE (operands[2]) == CONST_INT)
5490 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5491
5492 return "sra\t%0,%1,%2";
5493 }
5494 [(set_attr "type" "arith")
5495 (set_attr "mode" "SI")])
5496
5497 (define_insn "ashrsi3_internal2"
5498 [(set (match_operand:SI 0 "register_operand" "=d,d")
5499 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
5500 (match_operand:SI 2 "arith_operand" "d,I")))]
5501 "TARGET_MIPS16"
5502 {
5503 if (which_alternative == 0)
5504 return "sra\t%0,%2";
5505
5506 if (GET_CODE (operands[2]) == CONST_INT)
5507 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5508
5509 return "sra\t%0,%1,%2";
5510 }
5511 [(set_attr "type" "arith")
5512 (set_attr "mode" "SI")
5513 (set_attr_alternative "length"
5514 [(const_int 4)
5515 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
5516 (const_int 4)
5517 (const_int 8))])])
5518
5519
5520 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5521
5522 (define_split
5523 [(set (match_operand:SI 0 "register_operand" "")
5524 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
5525 (match_operand:SI 2 "const_int_operand" "")))]
5526 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5527 && GET_CODE (operands[2]) == CONST_INT
5528 && INTVAL (operands[2]) > 8
5529 && INTVAL (operands[2]) <= 16"
5530 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
5531 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
5532 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5533
5534 (define_expand "ashrdi3"
5535 [(parallel [(set (match_operand:DI 0 "register_operand" "")
5536 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
5537 (match_operand:SI 2 "arith_operand" "")))
5538 (clobber (match_dup 3))])]
5539 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
5540 {
5541 if (TARGET_64BIT)
5542 {
5543 /* On the mips16, a shift of more than 8 is a four byte
5544 instruction, so, for a shift between 8 and 16, it is just as
5545 fast to do two shifts of 8 or less. If there is a lot of
5546 shifting going on, we may win in CSE. Otherwise combine will
5547 put the shifts back together again. */
5548 if (TARGET_MIPS16
5549 && optimize
5550 && GET_CODE (operands[2]) == CONST_INT
5551 && INTVAL (operands[2]) > 8
5552 && INTVAL (operands[2]) <= 16)
5553 {
5554 rtx temp = gen_reg_rtx (DImode);
5555
5556 emit_insn (gen_ashrdi3_internal4 (temp, operands[1], GEN_INT (8)));
5557 emit_insn (gen_ashrdi3_internal4 (operands[0], temp,
5558 GEN_INT (INTVAL (operands[2]) - 8)));
5559 DONE;
5560 }
5561
5562 emit_insn (gen_ashrdi3_internal4 (operands[0], operands[1],
5563 operands[2]));
5564 DONE;
5565 }
5566
5567 operands[3] = gen_reg_rtx (SImode);
5568 })
5569
5570
5571 (define_insn "ashrdi3_internal"
5572 [(set (match_operand:DI 0 "register_operand" "=&d")
5573 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
5574 (match_operand:SI 2 "register_operand" "d")))
5575 (clobber (match_operand:SI 3 "register_operand" "=d"))]
5576 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
5577 "sll\t%3,%2,26\;\
5578 bgez\t%3,1f%#\;\
5579 sra\t%L0,%M1,%2\;\
5580 %(b\t3f\;\
5581 sra\t%M0,%M1,31%)\
5582 \n\n\
5583 %~1:\;\
5584 %(beq\t%3,%.,2f\;\
5585 srl\t%L0,%L1,%2%)\
5586 \n\;\
5587 subu\t%3,%.,%2\;\
5588 sll\t%3,%M1,%3\;\
5589 or\t%L0,%L0,%3\n\
5590 %~2:\;\
5591 sra\t%M0,%M1,%2\n\
5592 %~3:"
5593 [(set_attr "type" "darith")
5594 (set_attr "mode" "DI")
5595 (set_attr "length" "48")])
5596
5597
5598 (define_insn "ashrdi3_internal2"
5599 [(set (match_operand:DI 0 "register_operand" "=d")
5600 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
5601 (match_operand:SI 2 "small_int" "IJK")))
5602 (clobber (match_operand:SI 3 "register_operand" "=d"))]
5603 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && (INTVAL (operands[2]) & 32) != 0"
5604 {
5605 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5606 return "sra\t%L0,%M1,%2\;sra\t%M0,%M1,31";
5607 }
5608 [(set_attr "type" "darith")
5609 (set_attr "mode" "DI")
5610 (set_attr "length" "8")])
5611
5612
5613 (define_split
5614 [(set (match_operand:DI 0 "register_operand" "")
5615 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
5616 (match_operand:SI 2 "small_int" "")))
5617 (clobber (match_operand:SI 3 "register_operand" ""))]
5618 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
5619 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
5620 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
5621 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
5622 && (INTVAL (operands[2]) & 32) != 0"
5623
5624 [(set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
5625 (set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 4) (const_int 31)))]
5626
5627 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
5628
5629
5630 (define_split
5631 [(set (match_operand:DI 0 "register_operand" "")
5632 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
5633 (match_operand:SI 2 "small_int" "")))
5634 (clobber (match_operand:SI 3 "register_operand" ""))]
5635 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
5636 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
5637 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
5638 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
5639 && (INTVAL (operands[2]) & 32) != 0"
5640
5641 [(set (subreg:SI (match_dup 0) 4) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
5642 (set (subreg:SI (match_dup 0) 0) (ashiftrt:SI (subreg:SI (match_dup 1) 0) (const_int 31)))]
5643
5644 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
5645
5646
5647 (define_insn "ashrdi3_internal3"
5648 [(set (match_operand:DI 0 "register_operand" "=d")
5649 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
5650 (match_operand:SI 2 "small_int" "IJK")))
5651 (clobber (match_operand:SI 3 "register_operand" "=d"))]
5652 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5653 && (INTVAL (operands[2]) & 63) < 32
5654 && (INTVAL (operands[2]) & 63) != 0"
5655 {
5656 int amount = INTVAL (operands[2]);
5657
5658 operands[2] = GEN_INT (amount & 31);
5659 operands[4] = GEN_INT ((-amount) & 31);
5660
5661 return "srl\t%L0,%L1,%2\;sll\t%3,%M1,%4\;or\t%L0,%L0,%3\;sra\t%M0,%M1,%2";
5662 }
5663 [(set_attr "type" "darith")
5664 (set_attr "mode" "DI")
5665 (set_attr "length" "16")])
5666
5667
5668 (define_split
5669 [(set (match_operand:DI 0 "register_operand" "")
5670 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
5671 (match_operand:SI 2 "small_int" "")))
5672 (clobber (match_operand:SI 3 "register_operand" ""))]
5673 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
5674 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5675 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
5676 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
5677 && (INTVAL (operands[2]) & 63) < 32
5678 && (INTVAL (operands[2]) & 63) != 0"
5679
5680 [(set (subreg:SI (match_dup 0) 0)
5681 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
5682 (match_dup 2)))
5683
5684 (set (match_dup 3)
5685 (ashift:SI (subreg:SI (match_dup 1) 4)
5686 (match_dup 4)))
5687
5688 (set (subreg:SI (match_dup 0) 0)
5689 (ior:SI (subreg:SI (match_dup 0) 0)
5690 (match_dup 3)))
5691
5692 (set (subreg:SI (match_dup 0) 4)
5693 (ashiftrt:SI (subreg:SI (match_dup 1) 4)
5694 (match_dup 2)))]
5695 {
5696 int amount = INTVAL (operands[2]);
5697 operands[2] = GEN_INT (amount & 31);
5698 operands[4] = GEN_INT ((-amount) & 31);
5699 })
5700
5701
5702 (define_split
5703 [(set (match_operand:DI 0 "register_operand" "")
5704 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
5705 (match_operand:SI 2 "small_int" "")))
5706 (clobber (match_operand:SI 3 "register_operand" ""))]
5707 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
5708 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5709 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
5710 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
5711 && (INTVAL (operands[2]) & 63) < 32
5712 && (INTVAL (operands[2]) & 63) != 0"
5713
5714 [(set (subreg:SI (match_dup 0) 4)
5715 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
5716 (match_dup 2)))
5717
5718 (set (match_dup 3)
5719 (ashift:SI (subreg:SI (match_dup 1) 0)
5720 (match_dup 4)))
5721
5722 (set (subreg:SI (match_dup 0) 4)
5723 (ior:SI (subreg:SI (match_dup 0) 4)
5724 (match_dup 3)))
5725
5726 (set (subreg:SI (match_dup 0) 0)
5727 (ashiftrt:SI (subreg:SI (match_dup 1) 0)
5728 (match_dup 2)))]
5729 {
5730 int amount = INTVAL (operands[2]);
5731 operands[2] = GEN_INT (amount & 31);
5732 operands[4] = GEN_INT ((-amount) & 31);
5733 })
5734
5735
5736 (define_insn "ashrdi3_internal4"
5737 [(set (match_operand:DI 0 "register_operand" "=d")
5738 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
5739 (match_operand:SI 2 "arith_operand" "dI")))]
5740 "TARGET_64BIT && !TARGET_MIPS16"
5741 {
5742 if (GET_CODE (operands[2]) == CONST_INT)
5743 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5744
5745 return "dsra\t%0,%1,%2";
5746 }
5747 [(set_attr "type" "arith")
5748 (set_attr "mode" "DI")])
5749
5750 (define_insn ""
5751 [(set (match_operand:DI 0 "register_operand" "=d,d")
5752 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5753 (match_operand:SI 2 "arith_operand" "d,I")))]
5754 "TARGET_64BIT && TARGET_MIPS16"
5755 {
5756 if (GET_CODE (operands[2]) == CONST_INT)
5757 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5758
5759 return "dsra\t%0,%2";
5760 }
5761 [(set_attr "type" "arith")
5762 (set_attr "mode" "DI")
5763 (set_attr_alternative "length"
5764 [(const_int 4)
5765 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
5766 (const_int 4)
5767 (const_int 8))])])
5768
5769 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5770
5771 (define_split
5772 [(set (match_operand:DI 0 "register_operand" "")
5773 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
5774 (match_operand:SI 2 "const_int_operand" "")))]
5775 "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
5776 && reload_completed
5777 && GET_CODE (operands[2]) == CONST_INT
5778 && INTVAL (operands[2]) > 8
5779 && INTVAL (operands[2]) <= 16"
5780 [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
5781 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
5782 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5783
5784 (define_expand "lshrsi3"
5785 [(set (match_operand:SI 0 "register_operand" "=d")
5786 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
5787 (match_operand:SI 2 "arith_operand" "dI")))]
5788 ""
5789 {
5790 /* On the mips16, a shift of more than 8 is a four byte instruction,
5791 so, for a shift between 8 and 16, it is just as fast to do two
5792 shifts of 8 or less. If there is a lot of shifting going on, we
5793 may win in CSE. Otherwise combine will put the shifts back
5794 together again. */
5795 if (TARGET_MIPS16
5796 && optimize
5797 && GET_CODE (operands[2]) == CONST_INT
5798 && INTVAL (operands[2]) > 8
5799 && INTVAL (operands[2]) <= 16)
5800 {
5801 rtx temp = gen_reg_rtx (SImode);
5802
5803 emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
5804 emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
5805 GEN_INT (INTVAL (operands[2]) - 8)));
5806 DONE;
5807 }
5808 })
5809
5810 (define_insn "lshrsi3_internal1"
5811 [(set (match_operand:SI 0 "register_operand" "=d")
5812 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
5813 (match_operand:SI 2 "arith_operand" "dI")))]
5814 "!TARGET_MIPS16"
5815 {
5816 if (GET_CODE (operands[2]) == CONST_INT)
5817 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5818
5819 return "srl\t%0,%1,%2";
5820 }
5821 [(set_attr "type" "arith")
5822 (set_attr "mode" "SI")])
5823
5824 (define_insn "lshrsi3_internal2"
5825 [(set (match_operand:SI 0 "register_operand" "=d,d")
5826 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
5827 (match_operand:SI 2 "arith_operand" "d,I")))]
5828 "TARGET_MIPS16"
5829 {
5830 if (which_alternative == 0)
5831 return "srl\t%0,%2";
5832
5833 if (GET_CODE (operands[2]) == CONST_INT)
5834 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5835
5836 return "srl\t%0,%1,%2";
5837 }
5838 [(set_attr "type" "arith")
5839 (set_attr "mode" "SI")
5840 (set_attr_alternative "length"
5841 [(const_int 4)
5842 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
5843 (const_int 4)
5844 (const_int 8))])])
5845
5846
5847 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
5848
5849 (define_split
5850 [(set (match_operand:SI 0 "register_operand" "")
5851 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
5852 (match_operand:SI 2 "const_int_operand" "")))]
5853 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
5854 && GET_CODE (operands[2]) == CONST_INT
5855 && INTVAL (operands[2]) > 8
5856 && INTVAL (operands[2]) <= 16"
5857 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
5858 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5859 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
5860
5861 ;; If we load a byte on the mips16 as a bitfield, the resulting
5862 ;; sequence of instructions is too complicated for combine, because it
5863 ;; involves four instructions: a load, a shift, a constant load into a
5864 ;; register, and an and (the key problem here is that the mips16 does
5865 ;; not have and immediate). We recognize a shift of a load in order
5866 ;; to make it simple enough for combine to understand.
5867 ;;
5868 ;; The length here is the worst case: the length of the split version
5869 ;; will be more accurate.
5870 (define_insn_and_split ""
5871 [(set (match_operand:SI 0 "register_operand" "=d")
5872 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
5873 (match_operand:SI 2 "immediate_operand" "I")))]
5874 "TARGET_MIPS16"
5875 "#"
5876 ""
5877 [(set (match_dup 0) (match_dup 1))
5878 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
5879 ""
5880 [(set_attr "type" "load")
5881 (set_attr "mode" "SI")
5882 (set_attr "length" "16")])
5883
5884 (define_expand "lshrdi3"
5885 [(parallel [(set (match_operand:DI 0 "register_operand" "")
5886 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
5887 (match_operand:SI 2 "arith_operand" "")))
5888 (clobber (match_dup 3))])]
5889 "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
5890 {
5891 if (TARGET_64BIT)
5892 {
5893 /* On the mips16, a shift of more than 8 is a four byte
5894 instruction, so, for a shift between 8 and 16, it is just as
5895 fast to do two shifts of 8 or less. If there is a lot of
5896 shifting going on, we may win in CSE. Otherwise combine will
5897 put the shifts back together again. */
5898 if (TARGET_MIPS16
5899 && optimize
5900 && GET_CODE (operands[2]) == CONST_INT
5901 && INTVAL (operands[2]) > 8
5902 && INTVAL (operands[2]) <= 16)
5903 {
5904 rtx temp = gen_reg_rtx (DImode);
5905
5906 emit_insn (gen_lshrdi3_internal4 (temp, operands[1], GEN_INT (8)));
5907 emit_insn (gen_lshrdi3_internal4 (operands[0], temp,
5908 GEN_INT (INTVAL (operands[2]) - 8)));
5909 DONE;
5910 }
5911
5912 emit_insn (gen_lshrdi3_internal4 (operands[0], operands[1],
5913 operands[2]));
5914 DONE;
5915 }
5916
5917 operands[3] = gen_reg_rtx (SImode);
5918 })
5919
5920
5921 (define_insn "lshrdi3_internal"
5922 [(set (match_operand:DI 0 "register_operand" "=&d")
5923 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
5924 (match_operand:SI 2 "register_operand" "d")))
5925 (clobber (match_operand:SI 3 "register_operand" "=d"))]
5926 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
5927 "sll\t%3,%2,26\;\
5928 bgez\t%3,1f%#\;\
5929 srl\t%L0,%M1,%2\;\
5930 %(b\t3f\;\
5931 move\t%M0,%.%)\
5932 \n\n\
5933 %~1:\;\
5934 %(beq\t%3,%.,2f\;\
5935 srl\t%L0,%L1,%2%)\
5936 \n\;\
5937 subu\t%3,%.,%2\;\
5938 sll\t%3,%M1,%3\;\
5939 or\t%L0,%L0,%3\n\
5940 %~2:\;\
5941 srl\t%M0,%M1,%2\n\
5942 %~3:"
5943 [(set_attr "type" "darith")
5944 (set_attr "mode" "DI")
5945 (set_attr "length" "48")])
5946
5947
5948 (define_insn "lshrdi3_internal2"
5949 [(set (match_operand:DI 0 "register_operand" "=d")
5950 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
5951 (match_operand:SI 2 "small_int" "IJK")))
5952 (clobber (match_operand:SI 3 "register_operand" "=d"))]
5953 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5954 && (INTVAL (operands[2]) & 32) != 0"
5955 {
5956 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5957 return "srl\t%L0,%M1,%2\;move\t%M0,%.";
5958 }
5959 [(set_attr "type" "darith")
5960 (set_attr "mode" "DI")
5961 (set_attr "length" "8")])
5962
5963
5964 (define_split
5965 [(set (match_operand:DI 0 "register_operand" "")
5966 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
5967 (match_operand:SI 2 "small_int" "")))
5968 (clobber (match_operand:SI 3 "register_operand" ""))]
5969 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
5970 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5971 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
5972 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
5973 && (INTVAL (operands[2]) & 32) != 0"
5974
5975 [(set (subreg:SI (match_dup 0) 0) (lshiftrt:SI (subreg:SI (match_dup 1) 4) (match_dup 2)))
5976 (set (subreg:SI (match_dup 0) 4) (const_int 0))]
5977
5978 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
5979
5980
5981 (define_split
5982 [(set (match_operand:DI 0 "register_operand" "")
5983 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
5984 (match_operand:SI 2 "small_int" "")))
5985 (clobber (match_operand:SI 3 "register_operand" ""))]
5986 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
5987 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
5988 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
5989 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
5990 && (INTVAL (operands[2]) & 32) != 0"
5991
5992 [(set (subreg:SI (match_dup 0) 4) (lshiftrt:SI (subreg:SI (match_dup 1) 0) (match_dup 2)))
5993 (set (subreg:SI (match_dup 0) 0) (const_int 0))]
5994
5995 "operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);")
5996
5997
5998 (define_insn "lshrdi3_internal3"
5999 [(set (match_operand:DI 0 "register_operand" "=d")
6000 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
6001 (match_operand:SI 2 "small_int" "IJK")))
6002 (clobber (match_operand:SI 3 "register_operand" "=d"))]
6003 "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6004 && (INTVAL (operands[2]) & 63) < 32
6005 && (INTVAL (operands[2]) & 63) != 0"
6006 {
6007 int amount = INTVAL (operands[2]);
6008
6009 operands[2] = GEN_INT (amount & 31);
6010 operands[4] = GEN_INT ((-amount) & 31);
6011
6012 return "srl\t%L0,%L1,%2\;sll\t%3,%M1,%4\;or\t%L0,%L0,%3\;srl\t%M0,%M1,%2";
6013 }
6014 [(set_attr "type" "darith")
6015 (set_attr "mode" "DI")
6016 (set_attr "length" "16")])
6017
6018
6019 (define_split
6020 [(set (match_operand:DI 0 "register_operand" "")
6021 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6022 (match_operand:SI 2 "small_int" "")))
6023 (clobber (match_operand:SI 3 "register_operand" ""))]
6024 "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
6025 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6026 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6027 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6028 && (INTVAL (operands[2]) & 63) < 32
6029 && (INTVAL (operands[2]) & 63) != 0"
6030
6031 [(set (subreg:SI (match_dup 0) 0)
6032 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6033 (match_dup 2)))
6034
6035 (set (match_dup 3)
6036 (ashift:SI (subreg:SI (match_dup 1) 4)
6037 (match_dup 4)))
6038
6039 (set (subreg:SI (match_dup 0) 0)
6040 (ior:SI (subreg:SI (match_dup 0) 0)
6041 (match_dup 3)))
6042
6043 (set (subreg:SI (match_dup 0) 4)
6044 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
6045 (match_dup 2)))]
6046 {
6047 int amount = INTVAL (operands[2]);
6048 operands[2] = GEN_INT (amount & 31);
6049 operands[4] = GEN_INT ((-amount) & 31);
6050 })
6051
6052
6053 (define_split
6054 [(set (match_operand:DI 0 "register_operand" "")
6055 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6056 (match_operand:SI 2 "small_int" "")))
6057 (clobber (match_operand:SI 3 "register_operand" ""))]
6058 "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
6059 && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
6060 && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
6061 && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
6062 && (INTVAL (operands[2]) & 63) < 32
6063 && (INTVAL (operands[2]) & 63) != 0"
6064
6065 [(set (subreg:SI (match_dup 0) 4)
6066 (lshiftrt:SI (subreg:SI (match_dup 1) 4)
6067 (match_dup 2)))
6068
6069 (set (match_dup 3)
6070 (ashift:SI (subreg:SI (match_dup 1) 0)
6071 (match_dup 4)))
6072
6073 (set (subreg:SI (match_dup 0) 4)
6074 (ior:SI (subreg:SI (match_dup 0) 4)
6075 (match_dup 3)))
6076
6077 (set (subreg:SI (match_dup 0) 0)
6078 (lshiftrt:SI (subreg:SI (match_dup 1) 0)
6079 (match_dup 2)))]
6080 {
6081 int amount = INTVAL (operands[2]);
6082 operands[2] = GEN_INT (amount & 31);
6083 operands[4] = GEN_INT ((-amount) & 31);
6084 })
6085
6086
6087 (define_insn "lshrdi3_internal4"
6088 [(set (match_operand:DI 0 "register_operand" "=d")
6089 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
6090 (match_operand:SI 2 "arith_operand" "dI")))]
6091 "TARGET_64BIT && !TARGET_MIPS16"
6092 {
6093 if (GET_CODE (operands[2]) == CONST_INT)
6094 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6095
6096 return "dsrl\t%0,%1,%2";
6097 }
6098 [(set_attr "type" "arith")
6099 (set_attr "mode" "DI")])
6100
6101 (define_insn ""
6102 [(set (match_operand:DI 0 "register_operand" "=d,d")
6103 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
6104 (match_operand:SI 2 "arith_operand" "d,I")))]
6105 "TARGET_64BIT && TARGET_MIPS16"
6106 {
6107 if (GET_CODE (operands[2]) == CONST_INT)
6108 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6109
6110 return "dsrl\t%0,%2";
6111 }
6112 [(set_attr "type" "arith")
6113 (set_attr "mode" "DI")
6114 (set_attr_alternative "length"
6115 [(const_int 4)
6116 (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
6117 (const_int 4)
6118 (const_int 8))])])
6119
6120 (define_insn "rotrsi3"
6121 [(set (match_operand:SI 0 "register_operand" "=d")
6122 (rotatert:SI (match_operand:SI 1 "register_operand" "d")
6123 (match_operand:SI 2 "arith_operand" "dn")))]
6124 "ISA_HAS_ROTR_SI"
6125 {
6126 if (TARGET_SR71K && GET_CODE (operands[2]) != CONST_INT)
6127 return "rorv\t%0,%1,%2";
6128
6129 if ((GET_CODE (operands[2]) == CONST_INT)
6130 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 32))
6131 abort ();
6132
6133 return "ror\t%0,%1,%2";
6134 }
6135 [(set_attr "type" "arith")
6136 (set_attr "mode" "SI")])
6137
6138 (define_insn "rotrdi3"
6139 [(set (match_operand:DI 0 "register_operand" "=d")
6140 (rotatert:DI (match_operand:DI 1 "register_operand" "d")
6141 (match_operand:DI 2 "arith_operand" "dn")))]
6142 "ISA_HAS_ROTR_DI"
6143 {
6144 if (TARGET_SR71K)
6145 {
6146 if (GET_CODE (operands[2]) != CONST_INT)
6147 return "drorv\t%0,%1,%2";
6148
6149 if (INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) <= 63)
6150 return "dror32\t%0,%1,%2";
6151 }
6152
6153 if ((GET_CODE (operands[2]) == CONST_INT)
6154 && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 64))
6155 abort ();
6156
6157 return "dror\t%0,%1,%2";
6158 }
6159 [(set_attr "type" "arith")
6160 (set_attr "mode" "DI")])
6161
6162
6163 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
6164
6165 (define_split
6166 [(set (match_operand:DI 0 "register_operand" "")
6167 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
6168 (match_operand:SI 2 "const_int_operand" "")))]
6169 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
6170 && GET_CODE (operands[2]) == CONST_INT
6171 && INTVAL (operands[2]) > 8
6172 && INTVAL (operands[2]) <= 16"
6173 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
6174 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
6175 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
6176 \f
6177 ;;
6178 ;; ....................
6179 ;;
6180 ;; COMPARISONS
6181 ;;
6182 ;; ....................
6183
6184 ;; Flow here is rather complex:
6185 ;;
6186 ;; 1) The cmp{si,di,sf,df} routine is called. It deposits the
6187 ;; arguments into the branch_cmp array, and the type into
6188 ;; branch_type. No RTL is generated.
6189 ;;
6190 ;; 2) The appropriate branch define_expand is called, which then
6191 ;; creates the appropriate RTL for the comparison and branch.
6192 ;; Different CC modes are used, based on what type of branch is
6193 ;; done, so that we can constrain things appropriately. There
6194 ;; are assumptions in the rest of GCC that break if we fold the
6195 ;; operands into the branches for integer operations, and use cc0
6196 ;; for floating point, so we use the fp status register instead.
6197 ;; If needed, an appropriate temporary is created to hold the
6198 ;; of the integer compare.
6199
6200 (define_expand "cmpsi"
6201 [(set (cc0)
6202 (compare:CC (match_operand:SI 0 "register_operand" "")
6203 (match_operand:SI 1 "arith_operand" "")))]
6204 ""
6205 {
6206 branch_cmp[0] = operands[0];
6207 branch_cmp[1] = operands[1];
6208 branch_type = CMP_SI;
6209 DONE;
6210 })
6211
6212 (define_expand "tstsi"
6213 [(set (cc0)
6214 (match_operand:SI 0 "register_operand" ""))]
6215 ""
6216 {
6217 branch_cmp[0] = operands[0];
6218 branch_cmp[1] = const0_rtx;
6219 branch_type = CMP_SI;
6220 DONE;
6221 })
6222
6223 (define_expand "cmpdi"
6224 [(set (cc0)
6225 (compare:CC (match_operand:DI 0 "register_operand" "")
6226 (match_operand:DI 1 "arith_operand" "")))]
6227 "TARGET_64BIT"
6228 {
6229 branch_cmp[0] = operands[0];
6230 branch_cmp[1] = operands[1];
6231 branch_type = CMP_DI;
6232 DONE;
6233 })
6234
6235 (define_expand "tstdi"
6236 [(set (cc0)
6237 (match_operand:DI 0 "register_operand" ""))]
6238 "TARGET_64BIT"
6239 {
6240 branch_cmp[0] = operands[0];
6241 branch_cmp[1] = const0_rtx;
6242 branch_type = CMP_DI;
6243 DONE;
6244 })
6245
6246 (define_expand "cmpdf"
6247 [(set (cc0)
6248 (compare:CC (match_operand:DF 0 "register_operand" "")
6249 (match_operand:DF 1 "register_operand" "")))]
6250 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6251 {
6252 branch_cmp[0] = operands[0];
6253 branch_cmp[1] = operands[1];
6254 branch_type = CMP_DF;
6255 DONE;
6256 })
6257
6258 (define_expand "cmpsf"
6259 [(set (cc0)
6260 (compare:CC (match_operand:SF 0 "register_operand" "")
6261 (match_operand:SF 1 "register_operand" "")))]
6262 "TARGET_HARD_FLOAT"
6263 {
6264 branch_cmp[0] = operands[0];
6265 branch_cmp[1] = operands[1];
6266 branch_type = CMP_SF;
6267 DONE;
6268 })
6269 \f
6270 ;;
6271 ;; ....................
6272 ;;
6273 ;; CONDITIONAL BRANCHES
6274 ;;
6275 ;; ....................
6276
6277 ;; Conditional branches on floating-point equality tests.
6278
6279 (define_insn "branch_fp"
6280 [(set (pc)
6281 (if_then_else
6282 (match_operator:CC 0 "cmp_op"
6283 [(match_operand:CC 2 "register_operand" "z")
6284 (const_int 0)])
6285 (label_ref (match_operand 1 "" ""))
6286 (pc)))]
6287 "TARGET_HARD_FLOAT"
6288 {
6289 return mips_output_conditional_branch (insn,
6290 operands,
6291 /*two_operands_p=*/0,
6292 /*float_p=*/1,
6293 /*inverted_p=*/0,
6294 get_attr_length (insn));
6295 }
6296 [(set_attr "type" "branch")
6297 (set_attr "mode" "none")])
6298
6299 (define_insn "branch_fp_inverted"
6300 [(set (pc)
6301 (if_then_else
6302 (match_operator:CC 0 "cmp_op"
6303 [(match_operand:CC 2 "register_operand" "z")
6304 (const_int 0)])
6305 (pc)
6306 (label_ref (match_operand 1 "" ""))))]
6307 "TARGET_HARD_FLOAT"
6308 {
6309 return mips_output_conditional_branch (insn,
6310 operands,
6311 /*two_operands_p=*/0,
6312 /*float_p=*/1,
6313 /*inverted_p=*/1,
6314 get_attr_length (insn));
6315 }
6316 [(set_attr "type" "branch")
6317 (set_attr "mode" "none")])
6318
6319 ;; Conditional branches on comparisons with zero.
6320
6321 (define_insn "branch_zero"
6322 [(set (pc)
6323 (if_then_else
6324 (match_operator:SI 0 "cmp_op"
6325 [(match_operand:SI 2 "register_operand" "d")
6326 (const_int 0)])
6327 (label_ref (match_operand 1 "" ""))
6328 (pc)))]
6329 "!TARGET_MIPS16"
6330 {
6331 return mips_output_conditional_branch (insn,
6332 operands,
6333 /*two_operands_p=*/0,
6334 /*float_p=*/0,
6335 /*inverted_p=*/0,
6336 get_attr_length (insn));
6337 }
6338 [(set_attr "type" "branch")
6339 (set_attr "mode" "none")])
6340
6341 (define_insn "branch_zero_inverted"
6342 [(set (pc)
6343 (if_then_else
6344 (match_operator:SI 0 "cmp_op"
6345 [(match_operand:SI 2 "register_operand" "d")
6346 (const_int 0)])
6347 (pc)
6348 (label_ref (match_operand 1 "" ""))))]
6349 "!TARGET_MIPS16"
6350 {
6351 return mips_output_conditional_branch (insn,
6352 operands,
6353 /*two_operands_p=*/0,
6354 /*float_p=*/0,
6355 /*inverted_p=*/1,
6356 get_attr_length (insn));
6357 }
6358 [(set_attr "type" "branch")
6359 (set_attr "mode" "none")])
6360
6361 (define_insn "branch_zero_di"
6362 [(set (pc)
6363 (if_then_else
6364 (match_operator:DI 0 "cmp_op"
6365 [(match_operand:DI 2 "register_operand" "d")
6366 (const_int 0)])
6367 (label_ref (match_operand 1 "" ""))
6368 (pc)))]
6369 "!TARGET_MIPS16"
6370 {
6371 return mips_output_conditional_branch (insn,
6372 operands,
6373 /*two_operands_p=*/0,
6374 /*float_p=*/0,
6375 /*inverted_p=*/0,
6376 get_attr_length (insn));
6377 }
6378 [(set_attr "type" "branch")
6379 (set_attr "mode" "none")])
6380
6381 (define_insn "branch_zero_di_inverted"
6382 [(set (pc)
6383 (if_then_else
6384 (match_operator:DI 0 "cmp_op"
6385 [(match_operand:DI 2 "register_operand" "d")
6386 (const_int 0)])
6387 (pc)
6388 (label_ref (match_operand 1 "" ""))))]
6389 "!TARGET_MIPS16"
6390 {
6391 return mips_output_conditional_branch (insn,
6392 operands,
6393 /*two_operands_p=*/0,
6394 /*float_p=*/0,
6395 /*inverted_p=*/1,
6396 get_attr_length (insn));
6397 }
6398 [(set_attr "type" "branch")
6399 (set_attr "mode" "none")])
6400
6401 ;; Conditional branch on equality comparison.
6402
6403 (define_insn "branch_equality"
6404 [(set (pc)
6405 (if_then_else
6406 (match_operator:SI 0 "equality_op"
6407 [(match_operand:SI 2 "register_operand" "d")
6408 (match_operand:SI 3 "register_operand" "d")])
6409 (label_ref (match_operand 1 "" ""))
6410 (pc)))]
6411 "!TARGET_MIPS16"
6412 {
6413 return mips_output_conditional_branch (insn,
6414 operands,
6415 /*two_operands_p=*/1,
6416 /*float_p=*/0,
6417 /*inverted_p=*/0,
6418 get_attr_length (insn));
6419 }
6420 [(set_attr "type" "branch")
6421 (set_attr "mode" "none")])
6422
6423 (define_insn "branch_equality_di"
6424 [(set (pc)
6425 (if_then_else
6426 (match_operator:DI 0 "equality_op"
6427 [(match_operand:DI 2 "register_operand" "d")
6428 (match_operand:DI 3 "register_operand" "d")])
6429 (label_ref (match_operand 1 "" ""))
6430 (pc)))]
6431 "!TARGET_MIPS16"
6432 {
6433 return mips_output_conditional_branch (insn,
6434 operands,
6435 /*two_operands_p=*/1,
6436 /*float_p=*/0,
6437 /*inverted_p=*/0,
6438 get_attr_length (insn));
6439 }
6440 [(set_attr "type" "branch")
6441 (set_attr "mode" "none")])
6442
6443 (define_insn "branch_equality_inverted"
6444 [(set (pc)
6445 (if_then_else
6446 (match_operator:SI 0 "equality_op"
6447 [(match_operand:SI 2 "register_operand" "d")
6448 (match_operand:SI 3 "register_operand" "d")])
6449 (pc)
6450 (label_ref (match_operand 1 "" ""))))]
6451 "!TARGET_MIPS16"
6452 {
6453 return mips_output_conditional_branch (insn,
6454 operands,
6455 /*two_operands_p=*/1,
6456 /*float_p=*/0,
6457 /*inverted_p=*/1,
6458 get_attr_length (insn));
6459 }
6460 [(set_attr "type" "branch")
6461 (set_attr "mode" "none")])
6462
6463 (define_insn "branch_equality_di_inverted"
6464 [(set (pc)
6465 (if_then_else
6466 (match_operator:DI 0 "equality_op"
6467 [(match_operand:DI 2 "register_operand" "d")
6468 (match_operand:DI 3 "register_operand" "d")])
6469 (pc)
6470 (label_ref (match_operand 1 "" ""))))]
6471 "!TARGET_MIPS16"
6472 {
6473 return mips_output_conditional_branch (insn,
6474 operands,
6475 /*two_operands_p=*/1,
6476 /*float_p=*/0,
6477 /*inverted_p=*/1,
6478 get_attr_length (insn));
6479 }
6480 [(set_attr "type" "branch")
6481 (set_attr "mode" "none")])
6482
6483 ;; MIPS16 branches
6484
6485 (define_insn ""
6486 [(set (pc)
6487 (if_then_else (match_operator:SI 0 "equality_op"
6488 [(match_operand:SI 1 "register_operand" "d,t")
6489 (const_int 0)])
6490 (match_operand 2 "pc_or_label_operand" "")
6491 (match_operand 3 "pc_or_label_operand" "")))]
6492 "TARGET_MIPS16"
6493 {
6494 if (operands[2] != pc_rtx)
6495 {
6496 if (which_alternative == 0)
6497 return "b%C0z\t%1,%2";
6498 else
6499 return "bt%C0z\t%2";
6500 }
6501 else
6502 {
6503 if (which_alternative == 0)
6504 return "b%N0z\t%1,%3";
6505 else
6506 return "bt%N0z\t%3";
6507 }
6508 }
6509 [(set_attr "type" "branch")
6510 (set_attr "mode" "none")
6511 (set_attr "length" "8")])
6512
6513 (define_insn ""
6514 [(set (pc)
6515 (if_then_else (match_operator:DI 0 "equality_op"
6516 [(match_operand:DI 1 "register_operand" "d,t")
6517 (const_int 0)])
6518 (match_operand 2 "pc_or_label_operand" "")
6519 (match_operand 3 "pc_or_label_operand" "")))]
6520 "TARGET_MIPS16"
6521 {
6522 if (operands[2] != pc_rtx)
6523 {
6524 if (which_alternative == 0)
6525 return "b%C0z\t%1,%2";
6526 else
6527 return "bt%C0z\t%2";
6528 }
6529 else
6530 {
6531 if (which_alternative == 0)
6532 return "b%N0z\t%1,%3";
6533 else
6534 return "bt%N0z\t%3";
6535 }
6536 }
6537 [(set_attr "type" "branch")
6538 (set_attr "mode" "none")
6539 (set_attr "length" "8")])
6540
6541 (define_expand "bunordered"
6542 [(set (pc)
6543 (if_then_else (unordered:CC (cc0)
6544 (const_int 0))
6545 (label_ref (match_operand 0 "" ""))
6546 (pc)))]
6547 ""
6548 {
6549 gen_conditional_branch (operands, UNORDERED);
6550 DONE;
6551 })
6552
6553 (define_expand "bordered"
6554 [(set (pc)
6555 (if_then_else (ordered:CC (cc0)
6556 (const_int 0))
6557 (label_ref (match_operand 0 "" ""))
6558 (pc)))]
6559 ""
6560 {
6561 gen_conditional_branch (operands, ORDERED);
6562 DONE;
6563 })
6564
6565 (define_expand "bunlt"
6566 [(set (pc)
6567 (if_then_else (unlt:CC (cc0)
6568 (const_int 0))
6569 (label_ref (match_operand 0 "" ""))
6570 (pc)))]
6571 ""
6572 {
6573 gen_conditional_branch (operands, UNLT);
6574 DONE;
6575 })
6576
6577 (define_expand "bunge"
6578 [(set (pc)
6579 (if_then_else (unge:CC (cc0)
6580 (const_int 0))
6581 (label_ref (match_operand 0 "" ""))
6582 (pc)))]
6583 ""
6584 {
6585 gen_conditional_branch (operands, UNGE);
6586 DONE;
6587 })
6588
6589 (define_expand "buneq"
6590 [(set (pc)
6591 (if_then_else (uneq:CC (cc0)
6592 (const_int 0))
6593 (label_ref (match_operand 0 "" ""))
6594 (pc)))]
6595 ""
6596 {
6597 gen_conditional_branch (operands, UNEQ);
6598 DONE;
6599 })
6600
6601 (define_expand "bltgt"
6602 [(set (pc)
6603 (if_then_else (ltgt:CC (cc0)
6604 (const_int 0))
6605 (label_ref (match_operand 0 "" ""))
6606 (pc)))]
6607 ""
6608 {
6609 gen_conditional_branch (operands, LTGT);
6610 DONE;
6611 })
6612
6613 (define_expand "bunle"
6614 [(set (pc)
6615 (if_then_else (unle:CC (cc0)
6616 (const_int 0))
6617 (label_ref (match_operand 0 "" ""))
6618 (pc)))]
6619 ""
6620 {
6621 gen_conditional_branch (operands, UNLE);
6622 DONE;
6623 })
6624
6625 (define_expand "bungt"
6626 [(set (pc)
6627 (if_then_else (ungt:CC (cc0)
6628 (const_int 0))
6629 (label_ref (match_operand 0 "" ""))
6630 (pc)))]
6631 ""
6632 {
6633 gen_conditional_branch (operands, UNGT);
6634 DONE;
6635 })
6636
6637 (define_expand "beq"
6638 [(set (pc)
6639 (if_then_else (eq:CC (cc0)
6640 (const_int 0))
6641 (label_ref (match_operand 0 "" ""))
6642 (pc)))]
6643 ""
6644 {
6645 gen_conditional_branch (operands, EQ);
6646 DONE;
6647 })
6648
6649 (define_expand "bne"
6650 [(set (pc)
6651 (if_then_else (ne:CC (cc0)
6652 (const_int 0))
6653 (label_ref (match_operand 0 "" ""))
6654 (pc)))]
6655 ""
6656 {
6657 gen_conditional_branch (operands, NE);
6658 DONE;
6659 })
6660
6661 (define_expand "bgt"
6662 [(set (pc)
6663 (if_then_else (gt:CC (cc0)
6664 (const_int 0))
6665 (label_ref (match_operand 0 "" ""))
6666 (pc)))]
6667 ""
6668 {
6669 gen_conditional_branch (operands, GT);
6670 DONE;
6671 })
6672
6673 (define_expand "bge"
6674 [(set (pc)
6675 (if_then_else (ge:CC (cc0)
6676 (const_int 0))
6677 (label_ref (match_operand 0 "" ""))
6678 (pc)))]
6679 ""
6680 {
6681 gen_conditional_branch (operands, GE);
6682 DONE;
6683 })
6684
6685 (define_expand "blt"
6686 [(set (pc)
6687 (if_then_else (lt:CC (cc0)
6688 (const_int 0))
6689 (label_ref (match_operand 0 "" ""))
6690 (pc)))]
6691 ""
6692 {
6693 gen_conditional_branch (operands, LT);
6694 DONE;
6695 })
6696
6697 (define_expand "ble"
6698 [(set (pc)
6699 (if_then_else (le:CC (cc0)
6700 (const_int 0))
6701 (label_ref (match_operand 0 "" ""))
6702 (pc)))]
6703 ""
6704 {
6705 gen_conditional_branch (operands, LE);
6706 DONE;
6707 })
6708
6709 (define_expand "bgtu"
6710 [(set (pc)
6711 (if_then_else (gtu:CC (cc0)
6712 (const_int 0))
6713 (label_ref (match_operand 0 "" ""))
6714 (pc)))]
6715 ""
6716 {
6717 gen_conditional_branch (operands, GTU);
6718 DONE;
6719 })
6720
6721 (define_expand "bgeu"
6722 [(set (pc)
6723 (if_then_else (geu:CC (cc0)
6724 (const_int 0))
6725 (label_ref (match_operand 0 "" ""))
6726 (pc)))]
6727 ""
6728 {
6729 gen_conditional_branch (operands, GEU);
6730 DONE;
6731 })
6732
6733 (define_expand "bltu"
6734 [(set (pc)
6735 (if_then_else (ltu:CC (cc0)
6736 (const_int 0))
6737 (label_ref (match_operand 0 "" ""))
6738 (pc)))]
6739 ""
6740 {
6741 gen_conditional_branch (operands, LTU);
6742 DONE;
6743 })
6744
6745 (define_expand "bleu"
6746 [(set (pc)
6747 (if_then_else (leu:CC (cc0)
6748 (const_int 0))
6749 (label_ref (match_operand 0 "" ""))
6750 (pc)))]
6751 ""
6752 {
6753 gen_conditional_branch (operands, LEU);
6754 DONE;
6755 })
6756 \f
6757 ;;
6758 ;; ....................
6759 ;;
6760 ;; SETTING A REGISTER FROM A COMPARISON
6761 ;;
6762 ;; ....................
6763
6764 (define_expand "seq"
6765 [(set (match_operand:SI 0 "register_operand" "=d")
6766 (eq:SI (match_dup 1)
6767 (match_dup 2)))]
6768 ""
6769 {
6770 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
6771 FAIL;
6772
6773 /* set up operands from compare. */
6774 operands[1] = branch_cmp[0];
6775 operands[2] = branch_cmp[1];
6776
6777 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
6778 {
6779 gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
6780 DONE;
6781 }
6782
6783 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
6784 operands[2] = force_reg (SImode, operands[2]);
6785
6786 /* fall through and generate default code */
6787 })
6788
6789
6790 (define_insn "seq_si_zero"
6791 [(set (match_operand:SI 0 "register_operand" "=d")
6792 (eq:SI (match_operand:SI 1 "register_operand" "d")
6793 (const_int 0)))]
6794 "!TARGET_MIPS16"
6795 "sltu\t%0,%1,1"
6796 [(set_attr "type" "arith")
6797 (set_attr "mode" "SI")])
6798
6799 (define_insn ""
6800 [(set (match_operand:SI 0 "register_operand" "=t")
6801 (eq:SI (match_operand:SI 1 "register_operand" "d")
6802 (const_int 0)))]
6803 "TARGET_MIPS16"
6804 "sltu\t%1,1"
6805 [(set_attr "type" "arith")
6806 (set_attr "mode" "SI")])
6807
6808 (define_insn "seq_di_zero"
6809 [(set (match_operand:DI 0 "register_operand" "=d")
6810 (eq:DI (match_operand:DI 1 "register_operand" "d")
6811 (const_int 0)))]
6812 "TARGET_64BIT && !TARGET_MIPS16"
6813 "sltu\t%0,%1,1"
6814 [(set_attr "type" "arith")
6815 (set_attr "mode" "DI")])
6816
6817 (define_insn ""
6818 [(set (match_operand:DI 0 "register_operand" "=t")
6819 (eq:DI (match_operand:DI 1 "register_operand" "d")
6820 (const_int 0)))]
6821 "TARGET_64BIT && TARGET_MIPS16"
6822 "sltu\t%1,1"
6823 [(set_attr "type" "arith")
6824 (set_attr "mode" "DI")])
6825
6826 (define_insn "seq_si"
6827 [(set (match_operand:SI 0 "register_operand" "=d,d")
6828 (eq:SI (match_operand:SI 1 "register_operand" "%d,d")
6829 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
6830 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6831 "@
6832 xor\t%0,%1,%2\;sltu\t%0,%0,1
6833 xori\t%0,%1,%2\;sltu\t%0,%0,1"
6834 [(set_attr "type" "arith")
6835 (set_attr "mode" "SI")
6836 (set_attr "length" "8")])
6837
6838 (define_split
6839 [(set (match_operand:SI 0 "register_operand" "")
6840 (eq:SI (match_operand:SI 1 "register_operand" "")
6841 (match_operand:SI 2 "uns_arith_operand" "")))]
6842 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
6843 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
6844 [(set (match_dup 0)
6845 (xor:SI (match_dup 1)
6846 (match_dup 2)))
6847 (set (match_dup 0)
6848 (ltu:SI (match_dup 0)
6849 (const_int 1)))]
6850 "")
6851
6852 (define_insn "seq_di"
6853 [(set (match_operand:DI 0 "register_operand" "=d,d")
6854 (eq:DI (match_operand:DI 1 "register_operand" "%d,d")
6855 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
6856 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6857 "@
6858 xor\t%0,%1,%2\;sltu\t%0,%0,1
6859 xori\t%0,%1,%2\;sltu\t%0,%0,1"
6860 [(set_attr "type" "arith")
6861 (set_attr "mode" "DI")
6862 (set_attr "length" "8")])
6863
6864 (define_split
6865 [(set (match_operand:DI 0 "register_operand" "")
6866 (eq:DI (match_operand:DI 1 "register_operand" "")
6867 (match_operand:DI 2 "uns_arith_operand" "")))]
6868 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
6869 && !TARGET_MIPS16
6870 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
6871 [(set (match_dup 0)
6872 (xor:DI (match_dup 1)
6873 (match_dup 2)))
6874 (set (match_dup 0)
6875 (ltu:DI (match_dup 0)
6876 (const_int 1)))]
6877 "")
6878
6879 ;; On the mips16 the default code is better than using sltu.
6880
6881 (define_expand "sne"
6882 [(set (match_operand:SI 0 "register_operand" "=d")
6883 (ne:SI (match_dup 1)
6884 (match_dup 2)))]
6885 "!TARGET_MIPS16"
6886 {
6887 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
6888 FAIL;
6889
6890 /* set up operands from compare. */
6891 operands[1] = branch_cmp[0];
6892 operands[2] = branch_cmp[1];
6893
6894 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE)
6895 {
6896 gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
6897 DONE;
6898 }
6899
6900 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
6901 operands[2] = force_reg (SImode, operands[2]);
6902
6903 /* fall through and generate default code */
6904 })
6905
6906 (define_insn "sne_si_zero"
6907 [(set (match_operand:SI 0 "register_operand" "=d")
6908 (ne:SI (match_operand:SI 1 "register_operand" "d")
6909 (const_int 0)))]
6910 "!TARGET_MIPS16"
6911 "sltu\t%0,%.,%1"
6912 [(set_attr "type" "arith")
6913 (set_attr "mode" "SI")])
6914
6915 (define_insn "sne_di_zero"
6916 [(set (match_operand:DI 0 "register_operand" "=d")
6917 (ne:DI (match_operand:DI 1 "register_operand" "d")
6918 (const_int 0)))]
6919 "TARGET_64BIT && !TARGET_MIPS16"
6920 "sltu\t%0,%.,%1"
6921 [(set_attr "type" "arith")
6922 (set_attr "mode" "DI")])
6923
6924 (define_insn "sne_si"
6925 [(set (match_operand:SI 0 "register_operand" "=d,d")
6926 (ne:SI (match_operand:SI 1 "register_operand" "%d,d")
6927 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
6928 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6929 "@
6930 xor\t%0,%1,%2\;sltu\t%0,%.,%0
6931 xori\t%0,%1,%x2\;sltu\t%0,%.,%0"
6932 [(set_attr "type" "arith")
6933 (set_attr "mode" "SI")
6934 (set_attr "length" "8")])
6935
6936 (define_split
6937 [(set (match_operand:SI 0 "register_operand" "")
6938 (ne:SI (match_operand:SI 1 "register_operand" "")
6939 (match_operand:SI 2 "uns_arith_operand" "")))]
6940 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
6941 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
6942 [(set (match_dup 0)
6943 (xor:SI (match_dup 1)
6944 (match_dup 2)))
6945 (set (match_dup 0)
6946 (gtu:SI (match_dup 0)
6947 (const_int 0)))]
6948 "")
6949
6950 (define_insn "sne_di"
6951 [(set (match_operand:DI 0 "register_operand" "=d,d")
6952 (ne:DI (match_operand:DI 1 "register_operand" "%d,d")
6953 (match_operand:DI 2 "uns_arith_operand" "d,K")))]
6954 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
6955 "@
6956 xor\t%0,%1,%2\;sltu\t%0,%.,%0
6957 xori\t%0,%1,%x2\;sltu\t%0,%.,%0"
6958 [(set_attr "type" "arith")
6959 (set_attr "mode" "DI")
6960 (set_attr "length" "8")])
6961
6962 (define_split
6963 [(set (match_operand:DI 0 "register_operand" "")
6964 (ne:DI (match_operand:DI 1 "register_operand" "")
6965 (match_operand:DI 2 "uns_arith_operand" "")))]
6966 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
6967 && !TARGET_MIPS16
6968 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
6969 [(set (match_dup 0)
6970 (xor:DI (match_dup 1)
6971 (match_dup 2)))
6972 (set (match_dup 0)
6973 (gtu:DI (match_dup 0)
6974 (const_int 0)))]
6975 "")
6976
6977 (define_expand "sgt"
6978 [(set (match_operand:SI 0 "register_operand" "=d")
6979 (gt:SI (match_dup 1)
6980 (match_dup 2)))]
6981 ""
6982 {
6983 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
6984 FAIL;
6985
6986 /* set up operands from compare. */
6987 operands[1] = branch_cmp[0];
6988 operands[2] = branch_cmp[1];
6989
6990 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
6991 {
6992 gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
6993 DONE;
6994 }
6995
6996 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
6997 operands[2] = force_reg (SImode, operands[2]);
6998
6999 /* fall through and generate default code */
7000 })
7001
7002 (define_insn "sgt_si"
7003 [(set (match_operand:SI 0 "register_operand" "=d")
7004 (gt:SI (match_operand:SI 1 "register_operand" "d")
7005 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
7006 "!TARGET_MIPS16"
7007 "slt\t%0,%z2,%1"
7008 [(set_attr "type" "arith")
7009 (set_attr "mode" "SI")])
7010
7011 (define_insn ""
7012 [(set (match_operand:SI 0 "register_operand" "=t")
7013 (gt:SI (match_operand:SI 1 "register_operand" "d")
7014 (match_operand:SI 2 "register_operand" "d")))]
7015 "TARGET_MIPS16"
7016 "slt\t%2,%1"
7017 [(set_attr "type" "arith")
7018 (set_attr "mode" "SI")])
7019
7020 (define_insn "sgt_di"
7021 [(set (match_operand:DI 0 "register_operand" "=d")
7022 (gt:DI (match_operand:DI 1 "register_operand" "d")
7023 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
7024 "TARGET_64BIT && !TARGET_MIPS16"
7025 "slt\t%0,%z2,%1"
7026 [(set_attr "type" "arith")
7027 (set_attr "mode" "DI")])
7028
7029 (define_insn ""
7030 [(set (match_operand:DI 0 "register_operand" "=d")
7031 (gt:DI (match_operand:DI 1 "register_operand" "d")
7032 (match_operand:DI 2 "register_operand" "d")))]
7033 "TARGET_64BIT && TARGET_MIPS16"
7034 "slt\t%2,%1"
7035 [(set_attr "type" "arith")
7036 (set_attr "mode" "DI")])
7037
7038 (define_expand "sge"
7039 [(set (match_operand:SI 0 "register_operand" "=d")
7040 (ge:SI (match_dup 1)
7041 (match_dup 2)))]
7042 ""
7043 {
7044 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7045 FAIL;
7046
7047 /* set up operands from compare. */
7048 operands[1] = branch_cmp[0];
7049 operands[2] = branch_cmp[1];
7050
7051 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7052 {
7053 gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
7054 DONE;
7055 }
7056
7057 /* fall through and generate default code */
7058 })
7059
7060 (define_insn "sge_si"
7061 [(set (match_operand:SI 0 "register_operand" "=d")
7062 (ge:SI (match_operand:SI 1 "register_operand" "d")
7063 (match_operand:SI 2 "arith_operand" "dI")))]
7064 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7065 "slt\t%0,%1,%2\;xori\t%0,%0,0x0001"
7066 [(set_attr "type" "arith")
7067 (set_attr "mode" "SI")
7068 (set_attr "length" "8")])
7069
7070 (define_split
7071 [(set (match_operand:SI 0 "register_operand" "")
7072 (ge:SI (match_operand:SI 1 "register_operand" "")
7073 (match_operand:SI 2 "arith_operand" "")))]
7074 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
7075 [(set (match_dup 0)
7076 (lt:SI (match_dup 1)
7077 (match_dup 2)))
7078 (set (match_dup 0)
7079 (xor:SI (match_dup 0)
7080 (const_int 1)))]
7081 "")
7082
7083 (define_insn "sge_di"
7084 [(set (match_operand:DI 0 "register_operand" "=d")
7085 (ge:DI (match_operand:DI 1 "register_operand" "d")
7086 (match_operand:DI 2 "arith_operand" "dI")))]
7087 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7088 "slt\t%0,%1,%2\;xori\t%0,%0,0x0001"
7089 [(set_attr "type" "arith")
7090 (set_attr "mode" "DI")
7091 (set_attr "length" "8")])
7092
7093 (define_split
7094 [(set (match_operand:DI 0 "register_operand" "")
7095 (ge:DI (match_operand:DI 1 "register_operand" "")
7096 (match_operand:DI 2 "arith_operand" "")))]
7097 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7098 && !TARGET_MIPS16"
7099 [(set (match_dup 0)
7100 (lt:DI (match_dup 1)
7101 (match_dup 2)))
7102 (set (match_dup 0)
7103 (xor:DI (match_dup 0)
7104 (const_int 1)))]
7105 "")
7106
7107 (define_expand "slt"
7108 [(set (match_operand:SI 0 "register_operand" "=d")
7109 (lt:SI (match_dup 1)
7110 (match_dup 2)))]
7111 ""
7112 {
7113 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7114 FAIL;
7115
7116 /* set up operands from compare. */
7117 operands[1] = branch_cmp[0];
7118 operands[2] = branch_cmp[1];
7119
7120 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7121 {
7122 gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
7123 DONE;
7124 }
7125
7126 /* fall through and generate default code */
7127 })
7128
7129 (define_insn "slt_si"
7130 [(set (match_operand:SI 0 "register_operand" "=d")
7131 (lt:SI (match_operand:SI 1 "register_operand" "d")
7132 (match_operand:SI 2 "arith_operand" "dI")))]
7133 "!TARGET_MIPS16"
7134 "slt\t%0,%1,%2"
7135 [(set_attr "type" "arith")
7136 (set_attr "mode" "SI")])
7137
7138 (define_insn ""
7139 [(set (match_operand:SI 0 "register_operand" "=t,t")
7140 (lt:SI (match_operand:SI 1 "register_operand" "d,d")
7141 (match_operand:SI 2 "arith_operand" "d,I")))]
7142 "TARGET_MIPS16"
7143 "slt\t%1,%2"
7144 [(set_attr "type" "arith")
7145 (set_attr "mode" "SI")
7146 (set_attr_alternative "length"
7147 [(const_int 4)
7148 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
7149 (const_int 4)
7150 (const_int 8))])])
7151
7152 (define_insn "slt_di"
7153 [(set (match_operand:DI 0 "register_operand" "=d")
7154 (lt:DI (match_operand:DI 1 "register_operand" "d")
7155 (match_operand:DI 2 "arith_operand" "dI")))]
7156 "TARGET_64BIT && !TARGET_MIPS16"
7157 "slt\t%0,%1,%2"
7158 [(set_attr "type" "arith")
7159 (set_attr "mode" "DI")])
7160
7161 (define_insn ""
7162 [(set (match_operand:DI 0 "register_operand" "=t,t")
7163 (lt:DI (match_operand:DI 1 "register_operand" "d,d")
7164 (match_operand:DI 2 "arith_operand" "d,I")))]
7165 "TARGET_64BIT && TARGET_MIPS16"
7166 "slt\t%1,%2"
7167 [(set_attr "type" "arith")
7168 (set_attr "mode" "DI")
7169 (set_attr_alternative "length"
7170 [(const_int 4)
7171 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
7172 (const_int 4)
7173 (const_int 8))])])
7174
7175 (define_expand "sle"
7176 [(set (match_operand:SI 0 "register_operand" "=d")
7177 (le:SI (match_dup 1)
7178 (match_dup 2)))]
7179 ""
7180 {
7181 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7182 FAIL;
7183
7184 /* set up operands from compare. */
7185 operands[1] = branch_cmp[0];
7186 operands[2] = branch_cmp[1];
7187
7188 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7189 {
7190 gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
7191 DONE;
7192 }
7193
7194 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
7195 operands[2] = force_reg (SImode, operands[2]);
7196
7197 /* fall through and generate default code */
7198 })
7199
7200 (define_insn "sle_si_const"
7201 [(set (match_operand:SI 0 "register_operand" "=d")
7202 (le:SI (match_operand:SI 1 "register_operand" "d")
7203 (match_operand:SI 2 "small_int" "I")))]
7204 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7205 {
7206 operands[2] = GEN_INT (INTVAL (operands[2])+1);
7207 return "slt\t%0,%1,%2";
7208 }
7209 [(set_attr "type" "arith")
7210 (set_attr "mode" "SI")])
7211
7212 (define_insn ""
7213 [(set (match_operand:SI 0 "register_operand" "=t")
7214 (le:SI (match_operand:SI 1 "register_operand" "d")
7215 (match_operand:SI 2 "small_int" "I")))]
7216 "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7217 {
7218 operands[2] = GEN_INT (INTVAL (operands[2])+1);
7219 return "slt\t%1,%2";
7220 }
7221 [(set_attr "type" "arith")
7222 (set_attr "mode" "SI")
7223 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
7224 (const_int 4)
7225 (const_int 8)))])
7226
7227 (define_insn "sle_di_const"
7228 [(set (match_operand:DI 0 "register_operand" "=d")
7229 (le:DI (match_operand:DI 1 "register_operand" "d")
7230 (match_operand:DI 2 "small_int" "I")))]
7231 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7232 {
7233 operands[2] = GEN_INT (INTVAL (operands[2])+1);
7234 return "slt\t%0,%1,%2";
7235 }
7236 [(set_attr "type" "arith")
7237 (set_attr "mode" "DI")])
7238
7239 (define_insn ""
7240 [(set (match_operand:DI 0 "register_operand" "=t")
7241 (le:DI (match_operand:DI 1 "register_operand" "d")
7242 (match_operand:DI 2 "small_int" "I")))]
7243 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7244 {
7245 operands[2] = GEN_INT (INTVAL (operands[2])+1);
7246 return "slt\t%1,%2";
7247 }
7248 [(set_attr "type" "arith")
7249 (set_attr "mode" "DI")
7250 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
7251 (const_int 4)
7252 (const_int 8)))])
7253
7254 (define_insn "sle_si_reg"
7255 [(set (match_operand:SI 0 "register_operand" "=d")
7256 (le:SI (match_operand:SI 1 "register_operand" "d")
7257 (match_operand:SI 2 "register_operand" "d")))]
7258 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7259 "slt\t%0,%z2,%1\;xori\t%0,%0,0x0001"
7260 [(set_attr "type" "arith")
7261 (set_attr "mode" "SI")
7262 (set_attr "length" "8")])
7263
7264 (define_split
7265 [(set (match_operand:SI 0 "register_operand" "")
7266 (le:SI (match_operand:SI 1 "register_operand" "")
7267 (match_operand:SI 2 "register_operand" "")))]
7268 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
7269 [(set (match_dup 0)
7270 (lt:SI (match_dup 2)
7271 (match_dup 1)))
7272 (set (match_dup 0)
7273 (xor:SI (match_dup 0)
7274 (const_int 1)))]
7275 "")
7276
7277 (define_insn "sle_di_reg"
7278 [(set (match_operand:DI 0 "register_operand" "=d")
7279 (le:DI (match_operand:DI 1 "register_operand" "d")
7280 (match_operand:DI 2 "register_operand" "d")))]
7281 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7282 "slt\t%0,%z2,%1\;xori\t%0,%0,0x0001"
7283 [(set_attr "type" "arith")
7284 (set_attr "mode" "DI")
7285 (set_attr "length" "8")])
7286
7287 (define_split
7288 [(set (match_operand:DI 0 "register_operand" "")
7289 (le:DI (match_operand:DI 1 "register_operand" "")
7290 (match_operand:DI 2 "register_operand" "")))]
7291 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7292 && !TARGET_MIPS16"
7293 [(set (match_dup 0)
7294 (lt:DI (match_dup 2)
7295 (match_dup 1)))
7296 (set (match_dup 0)
7297 (xor:DI (match_dup 0)
7298 (const_int 1)))]
7299 "")
7300
7301 (define_expand "sgtu"
7302 [(set (match_operand:SI 0 "register_operand" "=d")
7303 (gtu:SI (match_dup 1)
7304 (match_dup 2)))]
7305 ""
7306 {
7307 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7308 FAIL;
7309
7310 /* set up operands from compare. */
7311 operands[1] = branch_cmp[0];
7312 operands[2] = branch_cmp[1];
7313
7314 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7315 {
7316 gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
7317 DONE;
7318 }
7319
7320 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
7321 operands[2] = force_reg (SImode, operands[2]);
7322
7323 /* fall through and generate default code */
7324 })
7325
7326 (define_insn "sgtu_si"
7327 [(set (match_operand:SI 0 "register_operand" "=d")
7328 (gtu:SI (match_operand:SI 1 "register_operand" "d")
7329 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
7330 "!TARGET_MIPS16"
7331 "sltu\t%0,%z2,%1"
7332 [(set_attr "type" "arith")
7333 (set_attr "mode" "SI")])
7334
7335 (define_insn ""
7336 [(set (match_operand:SI 0 "register_operand" "=t")
7337 (gtu:SI (match_operand:SI 1 "register_operand" "d")
7338 (match_operand:SI 2 "register_operand" "d")))]
7339 "TARGET_MIPS16"
7340 "sltu\t%2,%1"
7341 [(set_attr "type" "arith")
7342 (set_attr "mode" "SI")])
7343
7344 (define_insn "sgtu_di"
7345 [(set (match_operand:DI 0 "register_operand" "=d")
7346 (gtu:DI (match_operand:DI 1 "register_operand" "d")
7347 (match_operand:DI 2 "reg_or_0_operand" "dJ")))]
7348 "TARGET_64BIT && !TARGET_MIPS16"
7349 "sltu\t%0,%z2,%1"
7350 [(set_attr "type" "arith")
7351 (set_attr "mode" "DI")])
7352
7353 (define_insn ""
7354 [(set (match_operand:DI 0 "register_operand" "=t")
7355 (gtu:DI (match_operand:DI 1 "register_operand" "d")
7356 (match_operand:DI 2 "register_operand" "d")))]
7357 "TARGET_64BIT && TARGET_MIPS16"
7358 "sltu\t%2,%1"
7359 [(set_attr "type" "arith")
7360 (set_attr "mode" "DI")])
7361
7362 (define_expand "sgeu"
7363 [(set (match_operand:SI 0 "register_operand" "=d")
7364 (geu:SI (match_dup 1)
7365 (match_dup 2)))]
7366 ""
7367 {
7368 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7369 FAIL;
7370
7371 /* set up operands from compare. */
7372 operands[1] = branch_cmp[0];
7373 operands[2] = branch_cmp[1];
7374
7375 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7376 {
7377 gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
7378 DONE;
7379 }
7380
7381 /* fall through and generate default code */
7382 })
7383
7384 (define_insn "sgeu_si"
7385 [(set (match_operand:SI 0 "register_operand" "=d")
7386 (geu:SI (match_operand:SI 1 "register_operand" "d")
7387 (match_operand:SI 2 "arith_operand" "dI")))]
7388 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7389 "sltu\t%0,%1,%2\;xori\t%0,%0,0x0001"
7390 [(set_attr "type" "arith")
7391 (set_attr "mode" "SI")
7392 (set_attr "length" "8")])
7393
7394 (define_split
7395 [(set (match_operand:SI 0 "register_operand" "")
7396 (geu:SI (match_operand:SI 1 "register_operand" "")
7397 (match_operand:SI 2 "arith_operand" "")))]
7398 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
7399 [(set (match_dup 0)
7400 (ltu:SI (match_dup 1)
7401 (match_dup 2)))
7402 (set (match_dup 0)
7403 (xor:SI (match_dup 0)
7404 (const_int 1)))]
7405 "")
7406
7407 (define_insn "sgeu_di"
7408 [(set (match_operand:DI 0 "register_operand" "=d")
7409 (geu:DI (match_operand:DI 1 "register_operand" "d")
7410 (match_operand:DI 2 "arith_operand" "dI")))]
7411 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7412 "sltu\t%0,%1,%2\;xori\t%0,%0,0x0001"
7413 [(set_attr "type" "arith")
7414 (set_attr "mode" "DI")
7415 (set_attr "length" "8")])
7416
7417 (define_split
7418 [(set (match_operand:DI 0 "register_operand" "")
7419 (geu:DI (match_operand:DI 1 "register_operand" "")
7420 (match_operand:DI 2 "arith_operand" "")))]
7421 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7422 && !TARGET_MIPS16"
7423 [(set (match_dup 0)
7424 (ltu:DI (match_dup 1)
7425 (match_dup 2)))
7426 (set (match_dup 0)
7427 (xor:DI (match_dup 0)
7428 (const_int 1)))]
7429 "")
7430
7431 (define_expand "sltu"
7432 [(set (match_operand:SI 0 "register_operand" "=d")
7433 (ltu:SI (match_dup 1)
7434 (match_dup 2)))]
7435 ""
7436 {
7437 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7438 FAIL;
7439
7440 /* set up operands from compare. */
7441 operands[1] = branch_cmp[0];
7442 operands[2] = branch_cmp[1];
7443
7444 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7445 {
7446 gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
7447 DONE;
7448 }
7449
7450 /* fall through and generate default code */
7451 })
7452
7453 (define_insn "sltu_si"
7454 [(set (match_operand:SI 0 "register_operand" "=d")
7455 (ltu:SI (match_operand:SI 1 "register_operand" "d")
7456 (match_operand:SI 2 "arith_operand" "dI")))]
7457 "!TARGET_MIPS16"
7458 "sltu\t%0,%1,%2"
7459 [(set_attr "type" "arith")
7460 (set_attr "mode" "SI")])
7461
7462 (define_insn ""
7463 [(set (match_operand:SI 0 "register_operand" "=t,t")
7464 (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
7465 (match_operand:SI 2 "arith_operand" "d,I")))]
7466 "TARGET_MIPS16"
7467 "sltu\t%1,%2"
7468 [(set_attr "type" "arith")
7469 (set_attr "mode" "SI")
7470 (set_attr_alternative "length"
7471 [(const_int 4)
7472 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
7473 (const_int 4)
7474 (const_int 8))])])
7475
7476 (define_insn "sltu_di"
7477 [(set (match_operand:DI 0 "register_operand" "=d")
7478 (ltu:DI (match_operand:DI 1 "register_operand" "d")
7479 (match_operand:DI 2 "arith_operand" "dI")))]
7480 "TARGET_64BIT && !TARGET_MIPS16"
7481 "sltu\t%0,%1,%2"
7482 [(set_attr "type" "arith")
7483 (set_attr "mode" "DI")])
7484
7485 (define_insn ""
7486 [(set (match_operand:DI 0 "register_operand" "=t,t")
7487 (ltu:DI (match_operand:DI 1 "register_operand" "d,d")
7488 (match_operand:DI 2 "arith_operand" "d,I")))]
7489 "TARGET_64BIT && TARGET_MIPS16"
7490 "sltu\t%1,%2"
7491 [(set_attr "type" "arith")
7492 (set_attr "mode" "DI")
7493 (set_attr_alternative "length"
7494 [(const_int 4)
7495 (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
7496 (const_int 4)
7497 (const_int 8))])])
7498
7499 (define_expand "sleu"
7500 [(set (match_operand:SI 0 "register_operand" "=d")
7501 (leu:SI (match_dup 1)
7502 (match_dup 2)))]
7503 ""
7504 {
7505 if (branch_type != CMP_SI && (!TARGET_64BIT || branch_type != CMP_DI))
7506 FAIL;
7507
7508 /* set up operands from compare. */
7509 operands[1] = branch_cmp[0];
7510 operands[2] = branch_cmp[1];
7511
7512 if (TARGET_64BIT || !TARGET_DEBUG_C_MODE || TARGET_MIPS16)
7513 {
7514 gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
7515 DONE;
7516 }
7517
7518 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
7519 operands[2] = force_reg (SImode, operands[2]);
7520
7521 /* fall through and generate default code */
7522 })
7523
7524 (define_insn "sleu_si_const"
7525 [(set (match_operand:SI 0 "register_operand" "=d")
7526 (leu:SI (match_operand:SI 1 "register_operand" "d")
7527 (match_operand:SI 2 "small_int" "I")))]
7528 "!TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7529 {
7530 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
7531 return "sltu\t%0,%1,%2";
7532 }
7533 [(set_attr "type" "arith")
7534 (set_attr "mode" "SI")])
7535
7536 (define_insn ""
7537 [(set (match_operand:SI 0 "register_operand" "=t")
7538 (leu:SI (match_operand:SI 1 "register_operand" "d")
7539 (match_operand:SI 2 "small_int" "I")))]
7540 "TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7541 {
7542 operands[2] = GEN_INT (INTVAL (operands[2])+1);
7543 return "sltu\t%1,%2";
7544 }
7545 [(set_attr "type" "arith")
7546 (set_attr "mode" "SI")
7547 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
7548 (const_int 4)
7549 (const_int 8)))])
7550
7551 (define_insn "sleu_di_const"
7552 [(set (match_operand:DI 0 "register_operand" "=d")
7553 (leu:DI (match_operand:DI 1 "register_operand" "d")
7554 (match_operand:DI 2 "small_int" "I")))]
7555 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7556 {
7557 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
7558 return "sltu\t%0,%1,%2";
7559 }
7560 [(set_attr "type" "arith")
7561 (set_attr "mode" "DI")])
7562
7563 (define_insn ""
7564 [(set (match_operand:DI 0 "register_operand" "=t")
7565 (leu:DI (match_operand:DI 1 "register_operand" "d")
7566 (match_operand:DI 2 "small_int" "I")))]
7567 "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767"
7568 {
7569 operands[2] = GEN_INT (INTVAL (operands[2])+1);
7570 return "sltu\t%1,%2";
7571 }
7572 [(set_attr "type" "arith")
7573 (set_attr "mode" "DI")
7574 (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
7575 (const_int 4)
7576 (const_int 8)))])
7577
7578 (define_insn "sleu_si_reg"
7579 [(set (match_operand:SI 0 "register_operand" "=d")
7580 (leu:SI (match_operand:SI 1 "register_operand" "d")
7581 (match_operand:SI 2 "register_operand" "d")))]
7582 "TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7583 "sltu\t%0,%z2,%1\;xori\t%0,%0,0x0001"
7584 [(set_attr "type" "arith")
7585 (set_attr "mode" "SI")
7586 (set_attr "length" "8")])
7587
7588 (define_split
7589 [(set (match_operand:SI 0 "register_operand" "")
7590 (leu:SI (match_operand:SI 1 "register_operand" "")
7591 (match_operand:SI 2 "register_operand" "")))]
7592 "TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
7593 [(set (match_dup 0)
7594 (ltu:SI (match_dup 2)
7595 (match_dup 1)))
7596 (set (match_dup 0)
7597 (xor:SI (match_dup 0)
7598 (const_int 1)))]
7599 "")
7600
7601 (define_insn "sleu_di_reg"
7602 [(set (match_operand:DI 0 "register_operand" "=d")
7603 (leu:DI (match_operand:DI 1 "register_operand" "d")
7604 (match_operand:DI 2 "register_operand" "d")))]
7605 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16"
7606 "sltu\t%0,%z2,%1\;xori\t%0,%0,0x0001"
7607 [(set_attr "type" "arith")
7608 (set_attr "mode" "DI")
7609 (set_attr "length" "8")])
7610
7611 (define_split
7612 [(set (match_operand:DI 0 "register_operand" "")
7613 (leu:DI (match_operand:DI 1 "register_operand" "")
7614 (match_operand:DI 2 "register_operand" "")))]
7615 "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
7616 && !TARGET_MIPS16"
7617 [(set (match_dup 0)
7618 (ltu:DI (match_dup 2)
7619 (match_dup 1)))
7620 (set (match_dup 0)
7621 (xor:DI (match_dup 0)
7622 (const_int 1)))]
7623 "")
7624 \f
7625 ;;
7626 ;; ....................
7627 ;;
7628 ;; FLOATING POINT COMPARISONS
7629 ;;
7630 ;; ....................
7631
7632 (define_insn "sunordered_df"
7633 [(set (match_operand:CC 0 "register_operand" "=z")
7634 (unordered:CC (match_operand:DF 1 "register_operand" "f")
7635 (match_operand:DF 2 "register_operand" "f")))]
7636 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7637 "c.un.d\t%Z0%1,%2"
7638 [(set_attr "type" "fcmp")
7639 (set_attr "mode" "FPSW")])
7640
7641 (define_insn "sunlt_df"
7642 [(set (match_operand:CC 0 "register_operand" "=z")
7643 (unlt:CC (match_operand:DF 1 "register_operand" "f")
7644 (match_operand:DF 2 "register_operand" "f")))]
7645 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7646 "c.ult.d\t%Z0%1,%2"
7647 [(set_attr "type" "fcmp")
7648 (set_attr "mode" "FPSW")])
7649
7650 (define_insn "suneq_df"
7651 [(set (match_operand:CC 0 "register_operand" "=z")
7652 (uneq:CC (match_operand:DF 1 "register_operand" "f")
7653 (match_operand:DF 2 "register_operand" "f")))]
7654 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7655 "c.ueq.d\t%Z0%1,%2"
7656 [(set_attr "type" "fcmp")
7657 (set_attr "mode" "FPSW")])
7658
7659 (define_insn "sunle_df"
7660 [(set (match_operand:CC 0 "register_operand" "=z")
7661 (unle:CC (match_operand:DF 1 "register_operand" "f")
7662 (match_operand:DF 2 "register_operand" "f")))]
7663 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7664 "c.ule.d\t%Z0%1,%2"
7665 [(set_attr "type" "fcmp")
7666 (set_attr "mode" "FPSW")])
7667
7668 (define_insn "seq_df"
7669 [(set (match_operand:CC 0 "register_operand" "=z")
7670 (eq:CC (match_operand:DF 1 "register_operand" "f")
7671 (match_operand:DF 2 "register_operand" "f")))]
7672 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7673 "c.eq.d\t%Z0%1,%2"
7674 [(set_attr "type" "fcmp")
7675 (set_attr "mode" "FPSW")])
7676
7677 (define_insn "slt_df"
7678 [(set (match_operand:CC 0 "register_operand" "=z")
7679 (lt:CC (match_operand:DF 1 "register_operand" "f")
7680 (match_operand:DF 2 "register_operand" "f")))]
7681 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7682 "c.lt.d\t%Z0%1,%2"
7683 [(set_attr "type" "fcmp")
7684 (set_attr "mode" "FPSW")])
7685
7686 (define_insn "sle_df"
7687 [(set (match_operand:CC 0 "register_operand" "=z")
7688 (le:CC (match_operand:DF 1 "register_operand" "f")
7689 (match_operand:DF 2 "register_operand" "f")))]
7690 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7691 "c.le.d\t%Z0%1,%2"
7692 [(set_attr "type" "fcmp")
7693 (set_attr "mode" "FPSW")])
7694
7695 (define_insn "sgt_df"
7696 [(set (match_operand:CC 0 "register_operand" "=z")
7697 (gt:CC (match_operand:DF 1 "register_operand" "f")
7698 (match_operand:DF 2 "register_operand" "f")))]
7699 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7700 "c.lt.d\t%Z0%2,%1"
7701 [(set_attr "type" "fcmp")
7702 (set_attr "mode" "FPSW")])
7703
7704 (define_insn "sge_df"
7705 [(set (match_operand:CC 0 "register_operand" "=z")
7706 (ge:CC (match_operand:DF 1 "register_operand" "f")
7707 (match_operand:DF 2 "register_operand" "f")))]
7708 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
7709 "c.le.d\t%Z0%2,%1"
7710 [(set_attr "type" "fcmp")
7711 (set_attr "mode" "FPSW")])
7712
7713 (define_insn "sunordered_sf"
7714 [(set (match_operand:CC 0 "register_operand" "=z")
7715 (unordered:CC (match_operand:SF 1 "register_operand" "f")
7716 (match_operand:SF 2 "register_operand" "f")))]
7717 "TARGET_HARD_FLOAT"
7718 "c.un.s\t%Z0%1,%2"
7719 [(set_attr "type" "fcmp")
7720 (set_attr "mode" "FPSW")])
7721
7722 (define_insn "sunlt_sf"
7723 [(set (match_operand:CC 0 "register_operand" "=z")
7724 (unlt:CC (match_operand:SF 1 "register_operand" "f")
7725 (match_operand:SF 2 "register_operand" "f")))]
7726 "TARGET_HARD_FLOAT"
7727 "c.ult.s\t%Z0%1,%2"
7728 [(set_attr "type" "fcmp")
7729 (set_attr "mode" "FPSW")])
7730
7731 (define_insn "suneq_sf"
7732 [(set (match_operand:CC 0 "register_operand" "=z")
7733 (uneq:CC (match_operand:SF 1 "register_operand" "f")
7734 (match_operand:SF 2 "register_operand" "f")))]
7735 "TARGET_HARD_FLOAT"
7736 "c.ueq.s\t%Z0%1,%2"
7737 [(set_attr "type" "fcmp")
7738 (set_attr "mode" "FPSW")])
7739
7740 (define_insn "sunle_sf"
7741 [(set (match_operand:CC 0 "register_operand" "=z")
7742 (unle:CC (match_operand:SF 1 "register_operand" "f")
7743 (match_operand:SF 2 "register_operand" "f")))]
7744 "TARGET_HARD_FLOAT"
7745 "c.ule.s\t%Z0%1,%2"
7746 [(set_attr "type" "fcmp")
7747 (set_attr "mode" "FPSW")])
7748
7749 (define_insn "seq_sf"
7750 [(set (match_operand:CC 0 "register_operand" "=z")
7751 (eq:CC (match_operand:SF 1 "register_operand" "f")
7752 (match_operand:SF 2 "register_operand" "f")))]
7753 "TARGET_HARD_FLOAT"
7754 "c.eq.s\t%Z0%1,%2"
7755 [(set_attr "type" "fcmp")
7756 (set_attr "mode" "FPSW")])
7757
7758 (define_insn "slt_sf"
7759 [(set (match_operand:CC 0 "register_operand" "=z")
7760 (lt:CC (match_operand:SF 1 "register_operand" "f")
7761 (match_operand:SF 2 "register_operand" "f")))]
7762 "TARGET_HARD_FLOAT"
7763 "c.lt.s\t%Z0%1,%2"
7764 [(set_attr "type" "fcmp")
7765 (set_attr "mode" "FPSW")])
7766
7767 (define_insn "sle_sf"
7768 [(set (match_operand:CC 0 "register_operand" "=z")
7769 (le:CC (match_operand:SF 1 "register_operand" "f")
7770 (match_operand:SF 2 "register_operand" "f")))]
7771 "TARGET_HARD_FLOAT"
7772 "c.le.s\t%Z0%1,%2"
7773 [(set_attr "type" "fcmp")
7774 (set_attr "mode" "FPSW")])
7775
7776 (define_insn "sgt_sf"
7777 [(set (match_operand:CC 0 "register_operand" "=z")
7778 (gt:CC (match_operand:SF 1 "register_operand" "f")
7779 (match_operand:SF 2 "register_operand" "f")))]
7780 "TARGET_HARD_FLOAT"
7781 "c.lt.s\t%Z0%2,%1"
7782 [(set_attr "type" "fcmp")
7783 (set_attr "mode" "FPSW")])
7784
7785 (define_insn "sge_sf"
7786 [(set (match_operand:CC 0 "register_operand" "=z")
7787 (ge:CC (match_operand:SF 1 "register_operand" "f")
7788 (match_operand:SF 2 "register_operand" "f")))]
7789 "TARGET_HARD_FLOAT"
7790 "c.le.s\t%Z0%2,%1"
7791 [(set_attr "type" "fcmp")
7792 (set_attr "mode" "FPSW")])
7793 \f
7794 ;;
7795 ;; ....................
7796 ;;
7797 ;; UNCONDITIONAL BRANCHES
7798 ;;
7799 ;; ....................
7800
7801 ;; Unconditional branches.
7802
7803 (define_insn "jump"
7804 [(set (pc)
7805 (label_ref (match_operand 0 "" "")))]
7806 "!TARGET_MIPS16"
7807 {
7808 if (flag_pic && ! TARGET_EMBEDDED_PIC)
7809 {
7810 if (get_attr_length (insn) <= 8)
7811 return "%*b\t%l0%/";
7812 else
7813 {
7814 output_asm_insn (mips_output_load_label (), operands);
7815 return "%*jr\t%@%/%]";
7816 }
7817 }
7818 else
7819 return "%*j\t%l0%/";
7820 }
7821 [(set_attr "type" "jump")
7822 (set_attr "mode" "none")
7823 (set (attr "length")
7824 ;; we can't use `j' when emitting non-embedded PIC, so we emit
7825 ;; branch, if it's in range, or load the address of the branch
7826 ;; target into $at in a PIC-compatible way and then jump to it.
7827 (if_then_else
7828 (ior (eq (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC")
7829 (const_int 0))
7830 (lt (abs (minus (match_dup 0)
7831 (plus (pc) (const_int 4))))
7832 (const_int 131072)))
7833 (const_int 4) (const_int 16)))])
7834
7835 ;; We need a different insn for the mips16, because a mips16 branch
7836 ;; does not have a delay slot.
7837
7838 (define_insn ""
7839 [(set (pc)
7840 (label_ref (match_operand 0 "" "")))]
7841 "TARGET_MIPS16"
7842 "b\t%l0"
7843 [(set_attr "type" "branch")
7844 (set_attr "mode" "none")
7845 (set_attr "length" "8")])
7846
7847 (define_expand "indirect_jump"
7848 [(set (pc) (match_operand 0 "register_operand" "d"))]
7849 ""
7850 {
7851 rtx dest;
7852
7853 dest = operands[0];
7854 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
7855 operands[0] = copy_to_mode_reg (Pmode, dest);
7856
7857 if (!(Pmode == DImode))
7858 emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
7859 else
7860 emit_jump_insn (gen_indirect_jump_internal2 (operands[0]));
7861
7862 DONE;
7863 })
7864
7865 (define_insn "indirect_jump_internal1"
7866 [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
7867 "!(Pmode == DImode)"
7868 "%*j\t%0%/"
7869 [(set_attr "type" "jump")
7870 (set_attr "mode" "none")])
7871
7872 (define_insn "indirect_jump_internal2"
7873 [(set (pc) (match_operand:DI 0 "register_operand" "d"))]
7874 "Pmode == DImode"
7875 "%*j\t%0%/"
7876 [(set_attr "type" "jump")
7877 (set_attr "mode" "none")])
7878
7879 (define_expand "tablejump"
7880 [(set (pc)
7881 (match_operand 0 "register_operand" "d"))
7882 (use (label_ref (match_operand 1 "" "")))]
7883 ""
7884 {
7885 if (TARGET_MIPS16)
7886 {
7887 if (GET_MODE (operands[0]) != HImode)
7888 abort ();
7889 if (!(Pmode == DImode))
7890 emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
7891 else
7892 emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
7893 DONE;
7894 }
7895
7896 if (GET_MODE (operands[0]) != ptr_mode)
7897 abort ();
7898
7899 if (TARGET_GPWORD)
7900 operands[0] = expand_binop (ptr_mode, add_optab, operands[0],
7901 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN);
7902
7903 if (Pmode == SImode)
7904 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
7905 else
7906 emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
7907 DONE;
7908 })
7909
7910 (define_insn "tablejump_internal1"
7911 [(set (pc)
7912 (match_operand:SI 0 "register_operand" "d"))
7913 (use (label_ref (match_operand 1 "" "")))]
7914 ""
7915 "%*j\t%0%/"
7916 [(set_attr "type" "jump")
7917 (set_attr "mode" "none")])
7918
7919 (define_insn "tablejump_internal2"
7920 [(set (pc)
7921 (match_operand:DI 0 "register_operand" "d"))
7922 (use (label_ref (match_operand 1 "" "")))]
7923 "TARGET_64BIT"
7924 "%*j\t%0%/"
7925 [(set_attr "type" "jump")
7926 (set_attr "mode" "none")])
7927
7928 (define_expand "tablejump_mips161"
7929 [(set (pc) (plus:SI (sign_extend:SI
7930 (match_operand:HI 0 "register_operand" "d"))
7931 (label_ref:SI (match_operand 1 "" ""))))]
7932 "TARGET_MIPS16 && !(Pmode == DImode)"
7933 {
7934 rtx t1, t2, t3;
7935
7936 t1 = gen_reg_rtx (SImode);
7937 t2 = gen_reg_rtx (SImode);
7938 t3 = gen_reg_rtx (SImode);
7939 emit_insn (gen_extendhisi2 (t1, operands[0]));
7940 emit_move_insn (t2, gen_rtx_LABEL_REF (SImode, operands[1]));
7941 emit_insn (gen_addsi3 (t3, t1, t2));
7942 emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
7943 DONE;
7944 })
7945
7946 (define_expand "tablejump_mips162"
7947 [(set (pc) (plus:DI (sign_extend:DI
7948 (match_operand:HI 0 "register_operand" "d"))
7949 (label_ref:DI (match_operand 1 "" ""))))]
7950 "TARGET_MIPS16 && Pmode == DImode"
7951 {
7952 rtx t1, t2, t3;
7953
7954 t1 = gen_reg_rtx (DImode);
7955 t2 = gen_reg_rtx (DImode);
7956 t3 = gen_reg_rtx (DImode);
7957 emit_insn (gen_extendhidi2 (t1, operands[0]));
7958 emit_move_insn (t2, gen_rtx_LABEL_REF (DImode, operands[1]));
7959 emit_insn (gen_adddi3 (t3, t1, t2));
7960 emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
7961 DONE;
7962 })
7963
7964 ;; Implement a switch statement when generating embedded PIC code.
7965 ;; Switches are implemented by `tablejump' when not using -membedded-pic.
7966
7967 (define_expand "casesi"
7968 [(set (match_dup 5)
7969 (minus:SI (match_operand:SI 0 "register_operand" "")
7970 (match_operand:SI 1 "const_int_operand" "")))
7971 (set (cc0)
7972 (compare:CC (match_dup 5)
7973 (match_operand:SI 2 "arith_operand" "")))
7974 (set (pc)
7975 (if_then_else (gtu (cc0)
7976 (const_int 0))
7977 (label_ref (match_operand 4 "" ""))
7978 (pc)))
7979 (parallel
7980 [(set (pc)
7981 (mem:SI (plus:SI (mult:SI (match_dup 5)
7982 (const_int 4))
7983 (label_ref (match_operand 3 "" "")))))
7984 (clobber (match_scratch:SI 6 ""))
7985 (clobber (reg:SI 31))])]
7986 "TARGET_EMBEDDED_PIC"
7987 {
7988 rtx index;
7989
7990 /* If the index is too large, go to the default label. */
7991 index = expand_binop (SImode, sub_optab, operands[0],
7992 operands[1], 0, 0, OPTAB_WIDEN);
7993 emit_insn (gen_cmpsi (index, operands[2]));
7994 emit_insn (gen_bgtu (operands[4]));
7995
7996 /* Do the PIC jump. */
7997 if (Pmode != DImode)
7998 emit_jump_insn (gen_casesi_internal (index, operands[3],
7999 gen_reg_rtx (SImode)));
8000 else
8001 emit_jump_insn (gen_casesi_internal_di (index, operands[3],
8002 gen_reg_rtx (DImode)));
8003
8004 DONE;
8005 })
8006
8007 ;; An embedded PIC switch statement looks like this:
8008 ;; bal $LS1
8009 ;; sll $reg,$index,2
8010 ;; $LS1:
8011 ;; addu $reg,$reg,$31
8012 ;; lw $reg,$L1-$LS1($reg)
8013 ;; addu $reg,$reg,$31
8014 ;; j $reg
8015 ;; $L1:
8016 ;; .word case1-$LS1
8017 ;; .word case2-$LS1
8018 ;; ...
8019
8020 (define_insn "casesi_internal"
8021 [(set (pc)
8022 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
8023 (const_int 4))
8024 (label_ref (match_operand 1 "" "")))))
8025 (clobber (match_operand:SI 2 "register_operand" "=d"))
8026 (clobber (reg:SI 31))]
8027 "TARGET_EMBEDDED_PIC"
8028 "%(bal\t%S1\;sll\t%2,%0,2\n%~%S1:\;addu\t%2,%2,$31%)\;\
8029 lw\t%2,%1-%S1(%2)\;addu\t%2,%2,$31\;%*j\t%2%/"
8030 [(set_attr "type" "jump")
8031 (set_attr "mode" "none")
8032 (set_attr "length" "24")])
8033
8034 ;; This code assumes that the table index will never be >= 29 bits wide,
8035 ;; which allows the 'sign extend' from SI to DI be a no-op.
8036 (define_insn "casesi_internal_di"
8037 [(set (pc)
8038 (mem:DI (plus:DI (sign_extend:DI
8039 (mult:SI (match_operand:SI 0 "register_operand" "d")
8040 (const_int 8)))
8041 (label_ref (match_operand 1 "" "")))))
8042 (clobber (match_operand:DI 2 "register_operand" "=d"))
8043 (clobber (reg:DI 31))]
8044 "TARGET_EMBEDDED_PIC"
8045 "%(bal\t%S1\;sll\t%2,%0,3\n%~%S1:\;daddu\t%2,%2,$31%)\;\
8046 ld\t%2,%1-%S1(%2)\;daddu\t%2,%2,$31\;%*j\t%2%/"
8047 [(set_attr "type" "jump")
8048 (set_attr "mode" "none")
8049 (set_attr "length" "24")])
8050
8051 ;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
8052 ;; While it is possible to either pull it off the stack (in the
8053 ;; o32 case) or recalculate it given t9 and our target label,
8054 ;; it takes 3 or 4 insns to do so.
8055
8056 (define_expand "builtin_setjmp_setup"
8057 [(use (match_operand 0 "register_operand" ""))]
8058 "TARGET_ABICALLS"
8059 {
8060 rtx addr;
8061
8062 addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3);
8063 emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx);
8064 DONE;
8065 })
8066
8067 ;; Restore the gp that we saved above. Despite the earlier comment, it seems
8068 ;; that older code did recalculate the gp from $25. Continue to jump through
8069 ;; $25 for compatibility (we lose nothing by doing so).
8070
8071 (define_expand "builtin_longjmp"
8072 [(use (match_operand 0 "register_operand" "r"))]
8073 "TARGET_ABICALLS"
8074 {
8075 /* The elements of the buffer are, in order: */
8076 int W = GET_MODE_SIZE (Pmode);
8077 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
8078 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W));
8079 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W));
8080 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W));
8081 rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
8082 /* Use gen_raw_REG to avoid being given pic_offset_table_rtx.
8083 The target is bound to be using $28 as the global pointer
8084 but the current function might not be. */
8085 rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM);
8086
8087 /* This bit is similar to expand_builtin_longjmp except that it
8088 restores $gp as well. */
8089 emit_move_insn (hard_frame_pointer_rtx, fp);
8090 emit_move_insn (pv, lab);
8091 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
8092 emit_move_insn (gp, gpv);
8093 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
8094 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8095 emit_insn (gen_rtx_USE (VOIDmode, gp));
8096 emit_indirect_jump (pv);
8097 DONE;
8098 })
8099 \f
8100 ;;
8101 ;; ....................
8102 ;;
8103 ;; Function prologue/epilogue
8104 ;;
8105 ;; ....................
8106 ;;
8107
8108 (define_expand "prologue"
8109 [(const_int 1)]
8110 ""
8111 {
8112 mips_expand_prologue ();
8113 DONE;
8114 })
8115
8116 ;; Block any insns from being moved before this point, since the
8117 ;; profiling call to mcount can use various registers that aren't
8118 ;; saved or used to pass arguments.
8119
8120 (define_insn "blockage"
8121 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
8122 ""
8123 ""
8124 [(set_attr "type" "unknown")
8125 (set_attr "mode" "none")
8126 (set_attr "length" "0")])
8127
8128 (define_expand "epilogue"
8129 [(const_int 2)]
8130 ""
8131 {
8132 mips_expand_epilogue (false);
8133 DONE;
8134 })
8135
8136 (define_expand "sibcall_epilogue"
8137 [(const_int 2)]
8138 ""
8139 {
8140 mips_expand_epilogue (true);
8141 DONE;
8142 })
8143
8144 ;; Trivial return. Make it look like a normal return insn as that
8145 ;; allows jump optimizations to work better.
8146
8147 (define_insn "return"
8148 [(return)]
8149 "mips_can_use_return_insn ()"
8150 "%*j\t$31%/"
8151 [(set_attr "type" "jump")
8152 (set_attr "mode" "none")])
8153
8154 ;; Normal return.
8155
8156 (define_insn "return_internal"
8157 [(use (match_operand 0 "pmode_register_operand" ""))
8158 (return)]
8159 ""
8160 "%*j\t%0%/"
8161 [(set_attr "type" "jump")
8162 (set_attr "mode" "none")])
8163
8164 ;; When generating embedded PIC code we need to get the address of the
8165 ;; current function. This specialized instruction does just that.
8166
8167 (define_insn "get_fnaddr"
8168 [(set (match_operand 0 "register_operand" "=d")
8169 (unspec [(match_operand 1 "" "")] UNSPEC_GET_FNADDR))
8170 (clobber (reg:SI 31))]
8171 "TARGET_EMBEDDED_PIC
8172 && GET_CODE (operands[1]) == SYMBOL_REF"
8173 "%($LF%= = . + 8\;bal\t$LF%=\;nop;la\t%0,%1-$LF%=%)\;addu\t%0,%0,$31"
8174 [(set_attr "type" "call")
8175 (set_attr "mode" "none")
8176 (set_attr "length" "20")])
8177
8178 ;; This is used in compiling the unwind routines.
8179 (define_expand "eh_return"
8180 [(use (match_operand 0 "general_operand" ""))]
8181 ""
8182 {
8183 enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
8184
8185 if (GET_MODE (operands[0]) != gpr_mode)
8186 operands[0] = convert_to_mode (gpr_mode, operands[0], 0);
8187 if (TARGET_64BIT)
8188 emit_insn (gen_eh_set_lr_di (operands[0]));
8189 else
8190 emit_insn (gen_eh_set_lr_si (operands[0]));
8191
8192 DONE;
8193 })
8194
8195 ;; Clobber the return address on the stack. We can't expand this
8196 ;; until we know where it will be put in the stack frame.
8197
8198 (define_insn "eh_set_lr_si"
8199 [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
8200 (clobber (match_scratch:SI 1 "=&d"))]
8201 "! TARGET_64BIT"
8202 "#")
8203
8204 (define_insn "eh_set_lr_di"
8205 [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN)
8206 (clobber (match_scratch:DI 1 "=&d"))]
8207 "TARGET_64BIT"
8208 "#")
8209
8210 (define_split
8211 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
8212 (clobber (match_scratch 1 ""))]
8213 "reload_completed && !TARGET_DEBUG_D_MODE"
8214 [(const_int 0)]
8215 {
8216 mips_set_return_address (operands[0], operands[1]);
8217 DONE;
8218 })
8219
8220 (define_insn "exception_receiver"
8221 [(set (reg:SI 28)
8222 (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))]
8223 "TARGET_ABICALLS && (mips_abi == ABI_32 || mips_abi == ABI_O64)"
8224 {
8225 operands[0] = pic_offset_table_rtx;
8226 operands[1] = mips_gp_save_slot ();
8227 return mips_output_move (operands[0], operands[1]);
8228 }
8229 [(set_attr "type" "load")
8230 (set_attr "length" "8")])
8231 \f
8232 ;;
8233 ;; ....................
8234 ;;
8235 ;; FUNCTION CALLS
8236 ;;
8237 ;; ....................
8238
8239 ;; Sibling calls. All these patterns use jump instructions.
8240
8241 ;; If TARGET_SIBCALLS, call_insn_operand will only accept constant
8242 ;; addresses if a direct jump is acceptable. Since the 'S' constraint
8243 ;; is defined in terms of call_insn_operand, the same is true of the
8244 ;; constraints.
8245
8246 ;; When we use an indirect jump, we need a register that will be
8247 ;; preserved by the epilogue. Since TARGET_ABICALLS forces us to
8248 ;; use $25 for this purpose -- and $25 is never clobbered by the
8249 ;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
8250
8251 (define_expand "sibcall"
8252 [(parallel [(call (match_operand 0 "" "")
8253 (match_operand 1 "" ""))
8254 (use (match_operand 2 "" "")) ;; next_arg_reg
8255 (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx
8256 "TARGET_SIBCALLS"
8257 {
8258 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
8259 DONE;
8260 })
8261
8262 (define_insn "sibcall_internal"
8263 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S"))
8264 (match_operand 1 "" ""))]
8265 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
8266 "@
8267 %*jr\t%0%/
8268 %*j\t%0%/"
8269 [(set_attr "type" "call")])
8270
8271 (define_expand "sibcall_value"
8272 [(parallel [(set (match_operand 0 "" "")
8273 (call (match_operand 1 "" "")
8274 (match_operand 2 "" "")))
8275 (use (match_operand 3 "" ""))])] ;; next_arg_reg
8276 "TARGET_SIBCALLS"
8277 {
8278 mips_expand_call (operands[0], XEXP (operands[1], 0),
8279 operands[2], operands[3], true);
8280 DONE;
8281 })
8282
8283 (define_insn "sibcall_value_internal"
8284 [(set (match_operand 0 "register_operand" "=df,df")
8285 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
8286 (match_operand 2 "" "")))]
8287 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
8288 "@
8289 %*jr\t%1%/
8290 %*j\t%1%/"
8291 [(set_attr "type" "call")])
8292
8293 (define_insn "sibcall_value_multiple_internal"
8294 [(set (match_operand 0 "register_operand" "=df,df")
8295 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
8296 (match_operand 2 "" "")))
8297 (set (match_operand 3 "register_operand" "=df,df")
8298 (call (mem:SI (match_dup 1))
8299 (match_dup 2)))]
8300 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
8301 "@
8302 %*jr\t%1%/
8303 %*j\t%1%/"
8304 [(set_attr "type" "call")])
8305
8306 (define_expand "call"
8307 [(parallel [(call (match_operand 0 "" "")
8308 (match_operand 1 "" ""))
8309 (use (match_operand 2 "" "")) ;; next_arg_reg
8310 (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx
8311 ""
8312 {
8313 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
8314 DONE;
8315 })
8316
8317 ;; This instruction directly corresponds to an assembly-language "jal".
8318 ;; There are four cases:
8319 ;;
8320 ;; - -mno-abicalls:
8321 ;; Both symbolic and register destinations are OK. The pattern
8322 ;; always expands to a single mips instruction.
8323 ;;
8324 ;; - -mabicalls/-mno-explicit-relocs:
8325 ;; Again, both symbolic and register destinations are OK.
8326 ;; The call is treated as a multi-instruction black box.
8327 ;;
8328 ;; - -mabicalls/-mexplicit-relocs with n32 or n64:
8329 ;; Only "jal $25" is allowed. This expands to a single "jalr $25"
8330 ;; instruction.
8331 ;;
8332 ;; - -mabicalls/-mexplicit-relocs with o32 or o64:
8333 ;; Only "jal $25" is allowed. The call is actually two instructions:
8334 ;; "jalr $25" followed by an insn to reload $gp.
8335 ;;
8336 ;; In the last case, we can generate the individual instructions with
8337 ;; a define_split. There are several things to be wary of:
8338 ;;
8339 ;; - We can't expose the load of $gp before reload. If we did,
8340 ;; it might get removed as dead, but reload can introduce new
8341 ;; uses of $gp by rematerializing constants.
8342 ;;
8343 ;; - We shouldn't restore $gp after calls that never return.
8344 ;; It isn't valid to insert instructions between a noreturn
8345 ;; call and the following barrier.
8346 ;;
8347 ;; - The splitter deliberately changes the liveness of $gp. The unsplit
8348 ;; instruction preserves $gp and so have no effect on its liveness.
8349 ;; But once we generate the separate insns, it becomes obvious that
8350 ;; $gp is not live on entry to the call.
8351 ;;
8352 ;; ??? The operands[2] = insn check is a hack to make the original insn
8353 ;; available to the splitter.
8354 (define_insn_and_split "call_internal"
8355 [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
8356 (match_operand 1 "" ""))
8357 (clobber (reg:SI 31))]
8358 ""
8359 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%0%/"; }
8360 "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
8361 [(const_int 0)]
8362 {
8363 emit_call_insn (gen_call_split (operands[0], operands[1]));
8364 if (!find_reg_note (operands[2], REG_NORETURN, 0))
8365 emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ());
8366 DONE;
8367 }
8368 [(set_attr "jal" "indirect,direct")
8369 (set_attr "extended_mips16" "no,yes")])
8370
8371 (define_insn "call_split"
8372 [(call (mem:SI (match_operand 0 "call_insn_operand" "c"))
8373 (match_operand 1 "" ""))
8374 (clobber (reg:SI 31))
8375 (clobber (reg:SI 28))]
8376 "TARGET_SPLIT_CALLS"
8377 "%*jalr\t%0%/"
8378 [(set_attr "type" "call")])
8379
8380 (define_expand "call_value"
8381 [(parallel [(set (match_operand 0 "" "")
8382 (call (match_operand 1 "" "")
8383 (match_operand 2 "" "")))
8384 (use (match_operand 3 "" ""))])] ;; next_arg_reg
8385 ""
8386 {
8387 mips_expand_call (operands[0], XEXP (operands[1], 0),
8388 operands[2], operands[3], false);
8389 DONE;
8390 })
8391
8392 ;; See comment for call_internal.
8393 (define_insn_and_split "call_value_internal"
8394 [(set (match_operand 0 "register_operand" "=df,df")
8395 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
8396 (match_operand 2 "" "")))
8397 (clobber (reg:SI 31))]
8398 ""
8399 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
8400 "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
8401 [(const_int 0)]
8402 {
8403 emit_call_insn (gen_call_value_split (operands[0], operands[1],
8404 operands[2]));
8405 if (!find_reg_note (operands[3], REG_NORETURN, 0))
8406 emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ());
8407 DONE;
8408 }
8409 [(set_attr "jal" "indirect,direct")
8410 (set_attr "extended_mips16" "no,yes")])
8411
8412 (define_insn "call_value_split"
8413 [(set (match_operand 0 "register_operand" "=df")
8414 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
8415 (match_operand 2 "" "")))
8416 (clobber (reg:SI 31))
8417 (clobber (reg:SI 28))]
8418 "TARGET_SPLIT_CALLS"
8419 "%*jalr\t%1%/"
8420 [(set_attr "type" "call")])
8421
8422 ;; See comment for call_internal.
8423 (define_insn_and_split "call_value_multiple_internal"
8424 [(set (match_operand 0 "register_operand" "=df,df")
8425 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
8426 (match_operand 2 "" "")))
8427 (set (match_operand 3 "register_operand" "=df,df")
8428 (call (mem:SI (match_dup 1))
8429 (match_dup 2)))
8430 (clobber (reg:SI 31))]
8431 ""
8432 { return TARGET_SPLIT_CALLS ? "#" : "%*jal\t%1%/"; }
8433 "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
8434 [(const_int 0)]
8435 {
8436 emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
8437 operands[2], operands[3]));
8438 if (!find_reg_note (operands[4], REG_NORETURN, 0))
8439 emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ());
8440 DONE;
8441 }
8442 [(set_attr "jal" "indirect,direct")
8443 (set_attr "extended_mips16" "no,yes")])
8444
8445 (define_insn "call_value_multiple_split"
8446 [(set (match_operand 0 "register_operand" "=df")
8447 (call (mem:SI (match_operand 1 "call_insn_operand" "c"))
8448 (match_operand 2 "" "")))
8449 (set (match_operand 3 "register_operand" "=df")
8450 (call (mem:SI (match_dup 1))
8451 (match_dup 2)))
8452 (clobber (reg:SI 31))
8453 (clobber (reg:SI 28))]
8454 "TARGET_SPLIT_CALLS"
8455 "%*jalr\t%1%/"
8456 [(set_attr "type" "call")])
8457
8458 ;; Call subroutine returning any type.
8459
8460 (define_expand "untyped_call"
8461 [(parallel [(call (match_operand 0 "" "")
8462 (const_int 0))
8463 (match_operand 1 "" "")
8464 (match_operand 2 "" "")])]
8465 ""
8466 {
8467 int i;
8468
8469 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
8470
8471 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8472 {
8473 rtx set = XVECEXP (operands[2], 0, i);
8474 emit_move_insn (SET_DEST (set), SET_SRC (set));
8475 }
8476
8477 emit_insn (gen_blockage ());
8478 DONE;
8479 })
8480 \f
8481 ;;
8482 ;; ....................
8483 ;;
8484 ;; MISC.
8485 ;;
8486 ;; ....................
8487 ;;
8488
8489
8490 (define_expand "prefetch"
8491 [(prefetch (match_operand 0 "address_operand" "")
8492 (match_operand 1 "const_int_operand" "")
8493 (match_operand 2 "const_int_operand" ""))]
8494 "ISA_HAS_PREFETCH"
8495 {
8496 if (symbolic_operand (operands[0], GET_MODE (operands[0])))
8497 operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
8498 })
8499
8500 (define_insn "prefetch_si_address"
8501 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
8502 (match_operand:SI 3 "const_int_operand" "I"))
8503 (match_operand:SI 1 "const_int_operand" "n")
8504 (match_operand:SI 2 "const_int_operand" "n"))]
8505 "ISA_HAS_PREFETCH && Pmode == SImode"
8506 { return mips_emit_prefetch (operands); }
8507 [(set_attr "type" "prefetch")])
8508
8509 (define_insn "prefetch_indexed_si"
8510 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
8511 (match_operand:SI 3 "register_operand" "r"))
8512 (match_operand:SI 1 "const_int_operand" "n")
8513 (match_operand:SI 2 "const_int_operand" "n"))]
8514 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == SImode"
8515 { return mips_emit_prefetch (operands); }
8516 [(set_attr "type" "prefetchx")])
8517
8518 (define_insn "prefetch_si"
8519 [(prefetch (match_operand:SI 0 "register_operand" "r")
8520 (match_operand:SI 1 "const_int_operand" "n")
8521 (match_operand:SI 2 "const_int_operand" "n"))]
8522 "ISA_HAS_PREFETCH && Pmode == SImode"
8523 {
8524 operands[3] = const0_rtx;
8525 return mips_emit_prefetch (operands);
8526 }
8527 [(set_attr "type" "prefetch")])
8528
8529 (define_insn "prefetch_di_address"
8530 [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
8531 (match_operand:DI 3 "const_int_operand" "I"))
8532 (match_operand:DI 1 "const_int_operand" "n")
8533 (match_operand:DI 2 "const_int_operand" "n"))]
8534 "ISA_HAS_PREFETCH && Pmode == DImode"
8535 { return mips_emit_prefetch (operands); }
8536 [(set_attr "type" "prefetch")])
8537
8538 (define_insn "prefetch_indexed_di"
8539 [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
8540 (match_operand:DI 3 "register_operand" "r"))
8541 (match_operand:DI 1 "const_int_operand" "n")
8542 (match_operand:DI 2 "const_int_operand" "n"))]
8543 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && Pmode == DImode"
8544 { return mips_emit_prefetch (operands); }
8545 [(set_attr "type" "prefetchx")])
8546
8547 (define_insn "prefetch_di"
8548 [(prefetch (match_operand:DI 0 "register_operand" "r")
8549 (match_operand:DI 1 "const_int_operand" "n")
8550 (match_operand:DI 2 "const_int_operand" "n"))]
8551 "ISA_HAS_PREFETCH && Pmode == DImode"
8552 {
8553 operands[3] = const0_rtx;
8554 return mips_emit_prefetch (operands);
8555 }
8556 [(set_attr "type" "prefetch")])
8557
8558 (define_insn "nop"
8559 [(const_int 0)]
8560 ""
8561 "%(nop%)"
8562 [(set_attr "type" "nop")
8563 (set_attr "mode" "none")])
8564
8565 ;; Like nop, but commented out when outside a .set noreorder block.
8566 (define_insn "hazard_nop"
8567 [(const_int 1)]
8568 ""
8569 {
8570 if (set_noreorder)
8571 return "nop";
8572 else
8573 return "#nop";
8574 }
8575 [(set_attr "type" "arith")])
8576 \f
8577 ;; MIPS4 Conditional move instructions.
8578
8579 (define_insn ""
8580 [(set (match_operand:SI 0 "register_operand" "=d,d")
8581 (if_then_else:SI
8582 (match_operator 4 "equality_op"
8583 [(match_operand:SI 1 "register_operand" "d,d")
8584 (const_int 0)])
8585 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
8586 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
8587 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
8588 "@
8589 mov%B4\t%0,%z2,%1
8590 mov%b4\t%0,%z3,%1"
8591 [(set_attr "type" "condmove")
8592 (set_attr "mode" "SI")])
8593
8594 (define_insn ""
8595 [(set (match_operand:SI 0 "register_operand" "=d,d")
8596 (if_then_else:SI
8597 (match_operator 4 "equality_op"
8598 [(match_operand:DI 1 "register_operand" "d,d")
8599 (const_int 0)])
8600 (match_operand:SI 2 "reg_or_0_operand" "dJ,0")
8601 (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))]
8602 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
8603 "@
8604 mov%B4\t%0,%z2,%1
8605 mov%b4\t%0,%z3,%1"
8606 [(set_attr "type" "condmove")
8607 (set_attr "mode" "SI")])
8608
8609 (define_insn ""
8610 [(set (match_operand:SI 0 "register_operand" "=d,d")
8611 (if_then_else:SI
8612 (match_operator 3 "equality_op" [(match_operand:CC 4
8613 "register_operand"
8614 "z,z")
8615 (const_int 0)])
8616 (match_operand:SI 1 "reg_or_0_operand" "dJ,0")
8617 (match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
8618 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
8619 "@
8620 mov%T3\t%0,%z1,%4
8621 mov%t3\t%0,%z2,%4"
8622 [(set_attr "type" "condmove")
8623 (set_attr "mode" "SI")])
8624
8625 (define_insn ""
8626 [(set (match_operand:DI 0 "register_operand" "=d,d")
8627 (if_then_else:DI
8628 (match_operator 4 "equality_op"
8629 [(match_operand:SI 1 "register_operand" "d,d")
8630 (const_int 0)])
8631 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
8632 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
8633 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
8634 "@
8635 mov%B4\t%0,%z2,%1
8636 mov%b4\t%0,%z3,%1"
8637 [(set_attr "type" "condmove")
8638 (set_attr "mode" "DI")])
8639
8640 (define_insn ""
8641 [(set (match_operand:DI 0 "register_operand" "=d,d")
8642 (if_then_else:DI
8643 (match_operator 4 "equality_op"
8644 [(match_operand:DI 1 "register_operand" "d,d")
8645 (const_int 0)])
8646 (match_operand:DI 2 "reg_or_0_operand" "dJ,0")
8647 (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))]
8648 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
8649 "@
8650 mov%B4\t%0,%z2,%1
8651 mov%b4\t%0,%z3,%1"
8652 [(set_attr "type" "condmove")
8653 (set_attr "mode" "DI")])
8654
8655 (define_insn ""
8656 [(set (match_operand:DI 0 "register_operand" "=d,d")
8657 (if_then_else:DI
8658 (match_operator 3 "equality_op" [(match_operand:CC 4
8659 "register_operand"
8660 "z,z")
8661 (const_int 0)])
8662 (match_operand:DI 1 "reg_or_0_operand" "dJ,0")
8663 (match_operand:DI 2 "reg_or_0_operand" "0,dJ")))]
8664 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT"
8665 "@
8666 mov%T3\t%0,%z1,%4
8667 mov%t3\t%0,%z2,%4"
8668 [(set_attr "type" "condmove")
8669 (set_attr "mode" "DI")])
8670
8671 (define_insn ""
8672 [(set (match_operand:SF 0 "register_operand" "=f,f")
8673 (if_then_else:SF
8674 (match_operator 4 "equality_op"
8675 [(match_operand:SI 1 "register_operand" "d,d")
8676 (const_int 0)])
8677 (match_operand:SF 2 "register_operand" "f,0")
8678 (match_operand:SF 3 "register_operand" "0,f")))]
8679 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
8680 "@
8681 mov%B4.s\t%0,%2,%1
8682 mov%b4.s\t%0,%3,%1"
8683 [(set_attr "type" "condmove")
8684 (set_attr "mode" "SF")])
8685
8686 (define_insn ""
8687 [(set (match_operand:SF 0 "register_operand" "=f,f")
8688 (if_then_else:SF
8689 (match_operator 4 "equality_op"
8690 [(match_operand:DI 1 "register_operand" "d,d")
8691 (const_int 0)])
8692 (match_operand:SF 2 "register_operand" "f,0")
8693 (match_operand:SF 3 "register_operand" "0,f")))]
8694 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
8695 "@
8696 mov%B4.s\t%0,%2,%1
8697 mov%b4.s\t%0,%3,%1"
8698 [(set_attr "type" "condmove")
8699 (set_attr "mode" "SF")])
8700
8701 (define_insn ""
8702 [(set (match_operand:SF 0 "register_operand" "=f,f")
8703 (if_then_else:SF
8704 (match_operator 3 "equality_op" [(match_operand:CC 4
8705 "register_operand"
8706 "z,z")
8707 (const_int 0)])
8708 (match_operand:SF 1 "register_operand" "f,0")
8709 (match_operand:SF 2 "register_operand" "0,f")))]
8710 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
8711 "@
8712 mov%T3.s\t%0,%1,%4
8713 mov%t3.s\t%0,%2,%4"
8714 [(set_attr "type" "condmove")
8715 (set_attr "mode" "SF")])
8716
8717 (define_insn ""
8718 [(set (match_operand:DF 0 "register_operand" "=f,f")
8719 (if_then_else:DF
8720 (match_operator 4 "equality_op"
8721 [(match_operand:SI 1 "register_operand" "d,d")
8722 (const_int 0)])
8723 (match_operand:DF 2 "register_operand" "f,0")
8724 (match_operand:DF 3 "register_operand" "0,f")))]
8725 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8726 "@
8727 mov%B4.d\t%0,%2,%1
8728 mov%b4.d\t%0,%3,%1"
8729 [(set_attr "type" "condmove")
8730 (set_attr "mode" "DF")])
8731
8732 (define_insn ""
8733 [(set (match_operand:DF 0 "register_operand" "=f,f")
8734 (if_then_else:DF
8735 (match_operator 4 "equality_op"
8736 [(match_operand:DI 1 "register_operand" "d,d")
8737 (const_int 0)])
8738 (match_operand:DF 2 "register_operand" "f,0")
8739 (match_operand:DF 3 "register_operand" "0,f")))]
8740 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8741 "@
8742 mov%B4.d\t%0,%2,%1
8743 mov%b4.d\t%0,%3,%1"
8744 [(set_attr "type" "condmove")
8745 (set_attr "mode" "DF")])
8746
8747 (define_insn ""
8748 [(set (match_operand:DF 0 "register_operand" "=f,f")
8749 (if_then_else:DF
8750 (match_operator 3 "equality_op" [(match_operand:CC 4
8751 "register_operand"
8752 "z,z")
8753 (const_int 0)])
8754 (match_operand:DF 1 "register_operand" "f,0")
8755 (match_operand:DF 2 "register_operand" "0,f")))]
8756 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8757 "@
8758 mov%T3.d\t%0,%1,%4
8759 mov%t3.d\t%0,%2,%4"
8760 [(set_attr "type" "condmove")
8761 (set_attr "mode" "DF")])
8762
8763 ;; These are the main define_expand's used to make conditional moves.
8764
8765 (define_expand "movsicc"
8766 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
8767 (set (match_operand:SI 0 "register_operand" "")
8768 (if_then_else:SI (match_dup 5)
8769 (match_operand:SI 2 "reg_or_0_operand" "")
8770 (match_operand:SI 3 "reg_or_0_operand" "")))]
8771 "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
8772 {
8773 gen_conditional_move (operands);
8774 DONE;
8775 })
8776
8777 (define_expand "movdicc"
8778 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
8779 (set (match_operand:DI 0 "register_operand" "")
8780 (if_then_else:DI (match_dup 5)
8781 (match_operand:DI 2 "reg_or_0_operand" "")
8782 (match_operand:DI 3 "reg_or_0_operand" "")))]
8783 "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
8784 {
8785 gen_conditional_move (operands);
8786 DONE;
8787 })
8788
8789 (define_expand "movsfcc"
8790 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
8791 (set (match_operand:SF 0 "register_operand" "")
8792 (if_then_else:SF (match_dup 5)
8793 (match_operand:SF 2 "register_operand" "")
8794 (match_operand:SF 3 "register_operand" "")))]
8795 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
8796 {
8797 gen_conditional_move (operands);
8798 DONE;
8799 })
8800
8801 (define_expand "movdfcc"
8802 [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
8803 (set (match_operand:DF 0 "register_operand" "")
8804 (if_then_else:DF (match_dup 5)
8805 (match_operand:DF 2 "register_operand" "")
8806 (match_operand:DF 3 "register_operand" "")))]
8807 "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
8808 {
8809 gen_conditional_move (operands);
8810 DONE;
8811 })
8812 \f
8813 ;;
8814 ;; ....................
8815 ;;
8816 ;; mips16 inline constant tables
8817 ;;
8818 ;; ....................
8819 ;;
8820
8821 (define_insn "consttable_qi"
8822 [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "=g")]
8823 UNSPEC_CONSTTABLE_QI)]
8824 "TARGET_MIPS16"
8825 {
8826 assemble_integer (operands[0], 1, BITS_PER_UNIT, 1);
8827 return "";
8828 }
8829 [(set_attr "type" "unknown")
8830 (set_attr "mode" "QI")
8831 (set_attr "length" "8")])
8832
8833 (define_insn "consttable_hi"
8834 [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "=g")]
8835 UNSPEC_CONSTTABLE_HI)]
8836 "TARGET_MIPS16"
8837 {
8838 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
8839 return "";
8840 }
8841 [(set_attr "type" "unknown")
8842 (set_attr "mode" "HI")
8843 (set_attr "length" "8")])
8844
8845 (define_insn "consttable_si"
8846 [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "=g")]
8847 UNSPEC_CONSTTABLE_SI)]
8848 "TARGET_MIPS16"
8849 {
8850 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
8851 return "";
8852 }
8853 [(set_attr "type" "unknown")
8854 (set_attr "mode" "SI")
8855 (set_attr "length" "8")])
8856
8857 (define_insn "consttable_di"
8858 [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "=g")]
8859 UNSPEC_CONSTTABLE_DI)]
8860 "TARGET_MIPS16"
8861 {
8862 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
8863 return "";
8864 }
8865 [(set_attr "type" "unknown")
8866 (set_attr "mode" "DI")
8867 (set_attr "length" "16")])
8868
8869 (define_insn "consttable_sf"
8870 [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "=g")]
8871 UNSPEC_CONSTTABLE_SF)]
8872 "TARGET_MIPS16"
8873 {
8874 REAL_VALUE_TYPE d;
8875
8876 if (GET_CODE (operands[0]) != CONST_DOUBLE)
8877 abort ();
8878 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
8879 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
8880 return "";
8881 }
8882 [(set_attr "type" "unknown")
8883 (set_attr "mode" "SF")
8884 (set_attr "length" "8")])
8885
8886 (define_insn "consttable_df"
8887 [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "=g")]
8888 UNSPEC_CONSTTABLE_DF)]
8889 "TARGET_MIPS16"
8890 {
8891 REAL_VALUE_TYPE d;
8892
8893 if (GET_CODE (operands[0]) != CONST_DOUBLE)
8894 abort ();
8895 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
8896 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
8897 return "";
8898 }
8899 [(set_attr "type" "unknown")
8900 (set_attr "mode" "DF")
8901 (set_attr "length" "16")])
8902
8903 (define_insn "align_2"
8904 [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_2)]
8905 "TARGET_MIPS16"
8906 ".align 1"
8907 [(set_attr "type" "unknown")
8908 (set_attr "mode" "HI")
8909 (set_attr "length" "8")])
8910
8911 (define_insn "align_4"
8912 [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_4)]
8913 "TARGET_MIPS16"
8914 ".align 2"
8915 [(set_attr "type" "unknown")
8916 (set_attr "mode" "SI")
8917 (set_attr "length" "8")])
8918
8919 (define_insn "align_8"
8920 [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_8)]
8921 "TARGET_MIPS16"
8922 ".align 3"
8923 [(set_attr "type" "unknown")
8924 (set_attr "mode" "DI")
8925 (set_attr "length" "12")])
8926 \f
8927 ;;
8928 ;; ....................
8929 ;;
8930 ;; mips16 peepholes
8931 ;;
8932 ;; ....................
8933 ;;
8934
8935 ;; On the mips16, reload will sometimes decide that a pseudo register
8936 ;; should go into $24, and then later on have to reload that register.
8937 ;; When that happens, we get a load of a general register followed by
8938 ;; a move from the general register to $24 followed by a branch.
8939 ;; These peepholes catch the common case, and fix it to just use the
8940 ;; general register for the branch.
8941
8942 (define_peephole
8943 [(set (match_operand:SI 0 "register_operand" "=t")
8944 (match_operand:SI 1 "register_operand" "d"))
8945 (set (pc)
8946 (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
8947 (const_int 0)])
8948 (match_operand 3 "pc_or_label_operand" "")
8949 (match_operand 4 "pc_or_label_operand" "")))]
8950 "TARGET_MIPS16
8951 && GET_CODE (operands[0]) == REG
8952 && REGNO (operands[0]) == 24
8953 && dead_or_set_p (insn, operands[0])
8954 && GET_CODE (operands[1]) == REG
8955 && M16_REG_P (REGNO (operands[1]))"
8956 {
8957 if (operands[3] != pc_rtx)
8958 return "b%C2z\t%1,%3";
8959 else
8960 return "b%N2z\t%1,%4";
8961 }
8962 [(set_attr "type" "branch")
8963 (set_attr "mode" "none")
8964 (set_attr "length" "8")])
8965
8966 (define_peephole
8967 [(set (match_operand:DI 0 "register_operand" "=t")
8968 (match_operand:DI 1 "register_operand" "d"))
8969 (set (pc)
8970 (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
8971 (const_int 0)])
8972 (match_operand 3 "pc_or_label_operand" "")
8973 (match_operand 4 "pc_or_label_operand" "")))]
8974 "TARGET_MIPS16 && TARGET_64BIT
8975 && GET_CODE (operands[0]) == REG
8976 && REGNO (operands[0]) == 24
8977 && dead_or_set_p (insn, operands[0])
8978 && GET_CODE (operands[1]) == REG
8979 && M16_REG_P (REGNO (operands[1]))"
8980 {
8981 if (operands[3] != pc_rtx)
8982 return "b%C2z\t%1,%3";
8983 else
8984 return "b%N2z\t%1,%4";
8985 }
8986 [(set_attr "type" "branch")
8987 (set_attr "mode" "none")
8988 (set_attr "length" "8")])
8989
8990 ;; We can also have the reverse reload: reload will spill $24 into
8991 ;; another register, and then do a branch on that register when it
8992 ;; could have just stuck with $24.
8993
8994 (define_peephole
8995 [(set (match_operand:SI 0 "register_operand" "=d")
8996 (match_operand:SI 1 "register_operand" "t"))
8997 (set (pc)
8998 (if_then_else (match_operator:SI 2 "equality_op" [(match_dup 0)
8999 (const_int 0)])
9000 (match_operand 3 "pc_or_label_operand" "")
9001 (match_operand 4 "pc_or_label_operand" "")))]
9002 "TARGET_MIPS16
9003 && GET_CODE (operands[1]) == REG
9004 && REGNO (operands[1]) == 24
9005 && GET_CODE (operands[0]) == REG
9006 && M16_REG_P (REGNO (operands[0]))
9007 && dead_or_set_p (insn, operands[0])"
9008 {
9009 if (operands[3] != pc_rtx)
9010 return "bt%C2z\t%3";
9011 else
9012 return "bt%N2z\t%4";
9013 }
9014 [(set_attr "type" "branch")
9015 (set_attr "mode" "none")
9016 (set_attr "length" "8")])
9017
9018 (define_peephole
9019 [(set (match_operand:DI 0 "register_operand" "=d")
9020 (match_operand:DI 1 "register_operand" "t"))
9021 (set (pc)
9022 (if_then_else (match_operator:DI 2 "equality_op" [(match_dup 0)
9023 (const_int 0)])
9024 (match_operand 3 "pc_or_label_operand" "")
9025 (match_operand 4 "pc_or_label_operand" "")))]
9026 "TARGET_MIPS16 && TARGET_64BIT
9027 && GET_CODE (operands[1]) == REG
9028 && REGNO (operands[1]) == 24
9029 && GET_CODE (operands[0]) == REG
9030 && M16_REG_P (REGNO (operands[0]))
9031 && dead_or_set_p (insn, operands[0])"
9032 {
9033 if (operands[3] != pc_rtx)
9034 return "bt%C2z\t%3";
9035 else
9036 return "bt%N2z\t%4";
9037 }
9038 [(set_attr "type" "branch")
9039 (set_attr "mode" "none")
9040 (set_attr "length" "8")])