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