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